From 3fe0b7545b2ba0ea35ac8a8741f89aaf0d4aeccd Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 12 Jan 2017 21:16:57 -0600 Subject: [PATCH 001/392] Fix some bugs --- src/vid_nv_riva128.c | 112 ++++--------------------------------------- 1 file changed, 9 insertions(+), 103 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 421cf3e5d..9d2c51f75 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -301,14 +301,6 @@ static uint32_t riva128_pgraph_do_blend(uint32_t factor, uint32_t dst, uint32_t return ((dst * (0x100 - factor)) + (src * factor)) >> 6; } -static uint8_t riva128_pgraph_draw_point(int offset, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - svga->vram[(riva128->pgraph.speedhack.point_y[offset] * riva128->pfb.width) + riva128->pgraph.speedhack.point_x[offset]] = riva128->pgraph.speedhack.point_color; -} - static uint8_t riva128_pmc_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -1091,101 +1083,6 @@ static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) return riva128->pramin[ramht_base + (hash * 8)]; } -/*static void riva128_pgraph_point_exec_method_speedhack(int offset, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - switch(offset) - { - case 0x0104: - { - //NOTIFY - if(!(riva128->pgraph.invalid & 0x10000)) - { - if(riva128->pgraph.notify & 0x10000) - { - riva128_pgraph_invalid_interrupt(12, riva128); - riva128->pgraph.fifo_enable = 0; - } - } - - if(!(riva128->pgraph.invalid & 0x10000) && !(riva128->pgraph.invalid & 0x10)) - { - riva128->pgraph.notify |= 1 << 16; - riva128->pgraph.notify |= (val & 0xf) << 20; - } - break; - } - case 0x0304: - { - //COLOR - riva128->pgraph.speedhack.point_color = val; - break; - } - case 0x0400 ... 0x47c: - { - riva128->pgraph.speedhack.point_x[(offset & 0x7c) >> 2] = val & 0xffff; - riva128->pgraph.speedhack.point_y[(offset & 0x7c) >> 2] = val >> 16; - riva128_pgraph_draw_point((offset & 0x7c) >> 2, riva128); - break; - } - break; - } -} - -static void riva128_pgraph_gdi_exec_method_speedhack(int offset, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - switch(offset) - { - case 0x0104: - { - //NOTIFY - if(!(riva128->pgraph.invalid & 0x10000)) - { - if(riva128->pgraph.notify & 0x10000) - { - riva128_pgraph_invalid_interrupt(12, riva128); - riva128->pgraph.fifo_enable = 0; - } - } - - if(!(riva128->pgraph.invalid & 0x10000) && !(riva128->pgraph.invalid & 0x10)) - { - riva128->pgraph.notify |= 1 << 16; - riva128->pgraph.notify |= (val & 0xf) << 20; - } - break; - } - } -} - -static void riva128_pgraph_exec_method_speedhack(int subchanid, int offset, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 PGRAPH executing method %04X with object class on subchannel %01X %04X:%08X\n", offset, riva128->pgraph.obj_class[subchanid], subchanid, val, CS, cpu_state.pc); - - switch(riva128->pgraph.obj_class[subchanid]) - { - case 0x08: - { - //NV1_POINT - riva128_pgraph_point_exec_method_speedhack(offset, val, riva128); - break; - } - case 0x0c: - { - //NV3_GDI - riva128_pgraph_gdi_exec_method_speedhack(offset, val, riva128); - break; - } - } -}*/ - static void riva128_puller_exec_method(int chanid, int subchanid, int offset, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -1338,6 +1235,9 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) case 0x300000 ... 0x30ffff: if(riva128->card_id >= 0x04) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; break; + case 0x400000 ... 0x401fff: + ret = riva128_pgraph_read(addr, riva128); + break; case 0x6013b4 ... 0x6013b5: case 0x6013d4 ... 0x6013d5: case 0x0c03c2 ... 0x0c03c5: case 0x0c03cc ... 0x0c03cf: ret = riva128_in(addr & 0xfff, riva128); break; @@ -1409,9 +1309,15 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 0x002000 ... 0x002fff: riva128_pfifo_write(addr, val, riva128); break; + case 0x009000 ... 0x009fff: + riva128_ptimer_write(addr, val, riva128); + break; case 0x100000 ... 0x100fff: riva128_pfb_write(addr, val, riva128); break; + case 0x400000 ... 0x401fff: + riva128_pgraph_write(addr, val, riva128); + break; case 0x680000 ... 0x680fff: riva128_pramdac_write(addr, val, riva128); break; From 1ef1b459a7f5bdc70b0d5d9510f55f4c1504d017 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 12 Jan 2017 21:50:18 -0600 Subject: [PATCH 002/392] Add even MORE bullshit to RIVA 128 context switching --- src/vid_nv_riva128.c | 73 ++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 9d2c51f75..23dd513d6 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -978,6 +978,14 @@ static void riva128_pgraph_invalid_interrupt(int num, void *p) riva128_pgraph_interrupt(0, riva128); } +static void riva128_pgraph_volatile_reset(void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + + //TODO +} + static uint8_t riva128_pramdac_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -1088,44 +1096,49 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; pclog("RIVA 128 Puller executing method %04X on channel %01X[%01X] %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc); - - if(offset < 0x100) + + if(riva128->card_id == 0x03) { - if(offset == 0) + uint32_t tmp = riva128_ramht_lookup(val, riva128); + riva128->pgraph.instance = (tmp & 0xffff) << 4; + unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; + unsigned new_subc = subchanid & 7; + if((old_subc != new_subc) || !offset) { - if(riva128->card_id == 0x03) + uint32_t tmp_ctx = riva128->pramin[riva128->pgraph.instance]; + if(!offset) riva128->pgraph.ctx_cache[new_subc][0] = tmp_ctx & 0x3ff3f71f; + riva128->pgraph.ctx_user &= 0x1fe000; + riva128->pgraph.ctx_user |= tmp & 0x1f0000; + riva128->pgraph.ctx_user |= new_subc << 13; + if(riva128->pgraph.debug[1] & 0x100000) riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[new_subc][0]; + if(riva128->pgraph.debug[2] & 0x10000000) { - uint32_t tmp = riva128_ramht_lookup(val, riva128); - riva128->pgraph.instance = (tmp & 0xffff) << 4; - riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.instance]; - riva128->pgraph.ctx_user = (chanid << 24) | (tmp & 0x1f0000) | (subchanid << 13); + riva128_pgraph_volatile_reset(riva128); + riva128->pgraph.debug[1] |= 1; } - else if(riva128->card_id >= 0x04 && riva128->card_id < 0x10) + else riva128->pgraph.debug[1] &= ~1; + if(riva128->pgraph.notify & 0x10000) { - riva128->pgraph.ctx_switch[3] = (riva128_ramht_lookup(val, riva128) & 0xffff) << 4; - riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.ctx_switch[3]]; - riva128->pgraph.ctx_switch[1] = riva128->pgraph.ctx_cache[subchanid][1] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 4]; - riva128->pgraph.ctx_switch[2] = riva128->pgraph.ctx_cache[subchanid][2] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 8]; - riva128->pgraph.ctx_user = (chanid << 24) | (subchanid << 13); - } - else if(riva128->card_id >= 0x10 && riva128->card_id < 0x40) - { - riva128->pgraph.ctx_switch[3] = (riva128_ramht_lookup(val, riva128) & 0xffff) << 4; - riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[subchanid][0] = riva128->pramin[riva128->pgraph.ctx_switch[3]]; - riva128->pgraph.ctx_switch[1] = riva128->pgraph.ctx_cache[subchanid][1] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 4]; - riva128->pgraph.ctx_switch[2] = riva128->pgraph.ctx_cache[subchanid][2] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 8]; - riva128->pgraph.ctx_switch[4] = riva128->pgraph.ctx_cache[subchanid][4] = riva128->pramin[riva128->pgraph.ctx_switch[3] + 12]; - riva128->pgraph.ctx_user = (chanid << 24) | (subchanid << 13); + riva128_pgraph_invalid_interrupt(16, riva128); + riva128->pgraph.fifo_enable = 0; } } - } - if(riva128->pgraph.pgraph_speedhack) - { - } - else - { - pclog("RIVA 128 That was a bad idea, turning off the PGRAPH speedhack.\n"); + if(!riva128->pgraph.invalid && (((riva128->pgraph.debug[3] >> 20) & 3) == 3) && offset) + { + riva128_pgraph_invalid_interrupt(4, riva128); + riva128->pgraph.fifo_enable = 0; + } + + unsigned new_class = (tmp >> 16) & 0x1f; + if(riva128->pgraph.debug[1] & 0x10000 && ((riva128->pgraph.instance >> 4)) != riva128->pgraph.ctx_switch[3] && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104) + { + riva128->pgraph.ctx_switch[3] = riva128->pgraph.instance >> 4; + riva128->pgraph.ctx_switch[1] = riva128->pramin[riva128->pgraph.instance + 4] & 0xffff; + riva128->pgraph.notify &= 0xf10000; + riva128->pgraph.notify |= (riva128->pramin[riva128->pgraph.instance + 4] >> 16) & 0xffff; + riva128->pgraph.ctx_switch[2] = riva128->pramin[riva128->pgraph.instance + 8] & 0x1ffff; + } } } From b249e107a18ea7334293918b4bba564c7f45dad0 Mon Sep 17 00:00:00 2001 From: basic2004 Date: Mon, 16 Jan 2017 04:07:47 +0900 Subject: [PATCH 003/392] Update sound_sb.c I solved OPL3 problem on SB Pro V2, SB16, AWE32. This was defined 388h-389h only, so plays like OPL2. OPL3 will plays correctly if this defined 388h-38bh. --- src/sound_sb.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index 2c8f72335..23597e67e 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -1,4 +1,4 @@ - +#include #include "ibm.h" #include "device.h" #include "sound_emu8k.h" @@ -468,7 +468,7 @@ void *sb_pro_v2_init() sb_mixer_init(&sb->mixer); io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); @@ -495,7 +495,7 @@ void *sb_16_init() sb_mixer_init(&sb->mixer); io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); @@ -538,7 +538,7 @@ void *sb_awe32_init() sb_mixer_init(&sb->mixer); io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); From d76396947275321489287f3e6887b5edaa6dd78b Mon Sep 17 00:00:00 2001 From: basic2004 Date: Mon, 16 Jan 2017 04:17:14 +0900 Subject: [PATCH 004/392] CMS/Game Blaster pitch correction This patch make more accurate CMS emulation like actual GameBlaster. Original works of this patch from https://www.vogons.org/viewtopic.php?f=41&t=38350 for DOSBox, thanks to them. --- src/sound_cms.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sound_cms.c b/src/sound_cms.c index f38f46f9c..93a2aab1f 100644 --- a/src/sound_cms.c +++ b/src/sound_cms.c @@ -7,6 +7,8 @@ #include "sound.h" #include "sound_cms.h" +#define MASTER_CLOCK 7159090 + typedef struct cms_t { int addrs[2]; @@ -37,9 +39,9 @@ void cms_update(cms_t *cms) { switch (cms->noisetype[c >> 1][c & 1]) { - case 0: cms->noisefreq[c >> 1][c & 1] = 31250; break; - case 1: cms->noisefreq[c >> 1][c & 1] = 15625; break; - case 2: cms->noisefreq[c >> 1][c & 1] = 7812; break; + case 0: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/256; break; + case 1: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/512; break; + case 2: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/1024; break; case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break; } } @@ -124,14 +126,14 @@ void cms_write(uint16_t addr, uint8_t val, void *p) case 0x0B: case 0x0C: case 0x0D: voice = cms->addrs[chip] & 7; cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; - cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); break; case 0x10: case 0x11: case 0x12: /*Octave*/ voice = (cms->addrs[chip] & 3) << 1; cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); - cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); - cms->freq[chip][voice + 1] = (15625 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); + cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + cms->freq[chip][voice + 1] = (MASTER_CLOCK/512 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); break; case 0x16: /*Noise*/ cms->noisetype[chip][0] = val & 3; From 4f7fd842298ffaec0fe77b3451c5477b2be979ea Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 16 Jan 2017 01:49:19 +0100 Subject: [PATCH 005/392] Overhauled and unified CD-ROM emulation; Four CD-ROM drives are now emulated; ATAPI DMA is now emulated; Unified CD-ROM pass through to host drive handling; Applied all (applicable) mainline PCem commits. --- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 5 +- src/buslogic.c | 269 ++-- src/cdrom-ioctl.c | 1155 +++++++-------- src/cdrom-ioctl.h | 6 +- src/cdrom-iso.c | 414 ++++-- src/cdrom-iso.h | 10 +- src/cdrom-null.c | 93 +- src/cdrom-null.h | 6 +- src/cdrom.c | 2867 ++++++++++++++++++++++++++++++++++++++ src/cdrom.h | 219 ++- src/codegen_ops_x86-64.h | 208 ++- src/codegen_ops_x86.h | 6 +- src/codegen_x86-64.h | 2 +- src/disc_86f.c | 128 +- src/dma.c | 29 +- src/fdc.c | 125 +- src/ibm.h | 4 - src/ide.c | 2170 ++++++++--------------------- src/ide.h | 41 +- src/model.c | 27 +- src/mouse.h | 2 + src/ne2000.c | 2 + src/pc.c | 239 +++- src/pc.rc | 185 ++- src/piix.c | 47 +- src/resources.h | 206 ++- src/scsi.c | 19 +- src/scsi.h | 68 +- src/scsi_cdrom.c | 1677 ---------------------- src/sound.c | 130 +- src/sound_cms.c | 14 +- src/soundopenal.c | 19 +- src/vid_nv_riva128.c | 2 +- src/vid_voodoo.c | 11 +- src/win-config.c | 6 +- src/win-hdconf.c | 46 +- src/win.c | 596 ++++---- src/x86_ops_i686.h | 14 + src/x87_ops.h | 2 +- src/x87_ops_misc.h | 9 + 41 files changed, 5953 insertions(+), 5129 deletions(-) create mode 100644 src/cdrom.c delete mode 100644 src/scsi_cdrom.c diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc210da6e..20e97c053 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -4,13 +4,13 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom-ioctl.o cdrom-iso.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ - scat.o scsi.o scsi_cdrom.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ + scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index a42aa3cc4..e1d682087 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -4,13 +4,13 @@ CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom-ioctl.o cdrom-iso.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ - scat.o scsi.o scsi_cdrom.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ + scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ @@ -33,7 +33,6 @@ LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lws 86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) strip "86Box64.exe" - peflags --bigaddr=false 86Box64.exe all : 86Box64.exe diff --git a/src/buslogic.c b/src/buslogic.c index 229b4baef..5d263c8ae 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -3,6 +3,7 @@ */ /*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/ +#include #include #include #include @@ -517,12 +518,13 @@ int scsi_base = 0x330; int scsi_dma = 6; int scsi_irq = 11; -int buslogic_do_log = 0; +int buslogic_do_log = 1; static void BuslogicStartMailbox(Buslogic_t *Buslogic); void BuslogicLog(const char *format, ...) { +#ifdef ENABLE_BUSLOGIC_LOG if (buslogic_do_log) { va_list ap; @@ -531,6 +533,7 @@ void BuslogicLog(const char *format, ...) va_end(ap); fflush(stdout); } +#endif } static void BuslogicClearInterrupt(Buslogic_t *Buslogic) @@ -678,6 +681,8 @@ static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bit) { + uint32_t DataPointer, DataLength; + if (Is24bit) { DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer); @@ -728,8 +733,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer); - SCSIDevices[scsi_cdrom_id].InitLength = DataToTransfer; - SCSIDevices[scsi_cdrom_id].CmdBuffer[SCSIDevices[scsi_cdrom_id].pos++] = SCSIDevices[scsi_cdrom_id].InitLength; + SCSIDevices[BuslogicRequests->TargetID].InitLength = DataToTransfer; + SCSIDevices[BuslogicRequests->TargetID].CmdBuffer[SCSIDevices[BuslogicRequests->TargetID].pos++] = SCSIDevices[BuslogicRequests->TargetID].InitLength; //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //checking its length, so do this procedure for both no read/write commands. @@ -754,7 +759,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - DMAPageRead(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, DataToTransfer); + DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, DataToTransfer); } ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); @@ -765,14 +770,26 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { uint32_t Address = DataPointer; - SCSIDevices[scsi_cdrom_id].InitLength = DataLength; - SCSIDevices[scsi_cdrom_id].CmdBuffer[SCSIDevices[scsi_cdrom_id].pos++] = SCSIDevices[scsi_cdrom_id].InitLength; + SCSIDevices[BuslogicRequests->TargetID].InitLength = DataLength; + SCSIDevices[BuslogicRequests->TargetID].CmdBuffer[SCSIDevices[BuslogicRequests->TargetID].pos++] = SCSIDevices[BuslogicRequests->TargetID].InitLength; - DMAPageRead(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, SCSIDevices[scsi_cdrom_id].InitLength); + DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID].InitLength); } } } +uint32_t BuslogicGetDataLength(BuslogicRequests_t *BuslogicRequests) +{ + if (BuslogicRequests->Is24bit) + { + return ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength); + } + else + { + return BuslogicRequests->CmdBlock.new.DataLength; + } +} + void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) { if (BuslogicRequests->Is24bit) @@ -822,7 +839,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - DMAPageWrite(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, DataToTransfer); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, DataToTransfer); } ScatterGatherAddrCurrent += ScatterGatherRead * (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); @@ -832,11 +849,11 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { uint32_t Address = DataPointer; - DMAPageWrite(Address, SCSIDevices[scsi_cdrom_id].CmdBuffer, SCSIDevices[scsi_cdrom_id].InitLength); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID].InitLength); } } - SCSIDevices[scsi_cdrom_id].InitLength = 0; + SCSIDevices[BuslogicRequests->TargetID].InitLength = 0; } uint8_t BuslogicRead(uint16_t Port, void *p) @@ -885,8 +902,29 @@ uint8_t BuslogicRead(uint16_t Port, void *p) return Temp; } +int buslogic_scsi_drive_is_cdrom(uint8_t id) +{ + if (scsi_cdrom_drives[id] >= CDROM_NUM) + { + return 0; + } + else + { + if (cdrom_drives[scsi_cdrom_drives[id]].enabled && cdrom_drives[scsi_cdrom_drives[id]].bus_type && (cdrom_drives[scsi_cdrom_drives[id]].bus_mode & 2)) + { + return 1; + } + else + { + return 0; + } + } +} + void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) { + int i = 0; + Buslogic_t *Buslogic = (Buslogic_t *)p; BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); @@ -910,7 +948,13 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 1: if ((Val == 0x02) && (Buslogic->Command == 0xFF)) { - SCSICallback[scsi_cdrom_id] = 1; + for (i = 0; i < CDROM_NUM; i++) + { + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id)) + { + SCSICallback[cdrom_drives[i].scsi_device_id] = 1; + } + } break; } @@ -1047,10 +1091,10 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x0A: - if (scsi_cdrom_id < 8) + for (i = 0; i < 8; i++) { - if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM) - Buslogic->DataBuf[scsi_cdrom_id] = 1; + if (buslogic_scsi_drive_is_cdrom(i)) + Buslogic->DataBuf[i] = 1; Buslogic->DataBuf[7] = 0; Buslogic->DataReplyLeft = 8; @@ -1091,10 +1135,10 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x23: - if (scsi_cdrom_id >= 8) + for (i = 0; i < 8; i++) { - if (SCSIDevices[scsi_cdrom_id].LunType == SCSI_CDROM) - Buslogic->DataBuf[scsi_cdrom_id] = 1; + if (buslogic_scsi_drive_is_cdrom(i)) + Buslogic->DataBuf[i] = 1; Buslogic->DataReplyLeft = 8; } @@ -1337,7 +1381,7 @@ static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) { if (RequestSenseLength == 0) RequestSenseLength = 14; - else if (RequestSenseLength == 1) + else if ((RequestSenseLength >= 1) && (RequestSenseLength < 8)) RequestSenseLength = 0; BuslogicLog("Request Sense length %i\n", RequestSenseLength); @@ -1376,7 +1420,8 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress); - DMAPageWrite(SenseBufferAddress, BuslogicRequests->RequestSenseBuffer, SenseLength); + // DMAPageWrite(SenseBufferAddress, BuslogicRequests->RequestSenseBuffer, SenseLength); + DMAPageWrite(SenseBufferAddress, cdrom[BuslogicRequests->TargetID].sense, SenseLength); } //Free the sense buffer when needed. free(BuslogicRequests->RequestSenseBuffer); @@ -1387,6 +1432,11 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; uint8_t Id, Lun; + uint8_t cdrom_id; + uint8_t cdrom_phase; + + uint32_t temp = 0; + //Fetch data from the Command Control Block. DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32)); @@ -1399,8 +1449,10 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, BuslogicLog("Scanning SCSI Target ID %i\n", Id); //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. - if (Id == scsi_cdrom_id && Lun == 0) + if (buslogic_scsi_drive_is_cdrom(Id) && Lun == 0) { + cdrom_id = scsi_cdrom_drives[Id]; + BuslogicLog("SCSI Target ID %i detected and working\n", Id); BuslogicRequests->CCBPointer = CCBPointer; @@ -1425,60 +1477,17 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, //This not ready/unit attention stuff below is only for the Buslogic! //The Adaptec one is in scsi_cdrom.c. - if (scsi_model) + if (!cdrom_drives[cdrom_id].check_on_execution) { if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND)) { - if (cdrom->medium_changed()) + if (!cdrom_pre_execution_check(cdrom_id, BuslogicRequests->CmdBlock.common.Cdb)) { - pclog("Media changed\n"); - SCSICDROM_Insert(); - } - - if (!cdrom->ready() && SCSISense.UnitAttention) - { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - SCSISense.UnitAttention = 0; - } - - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (SCSISense.UnitAttention == 1) - { - SCSISense.UnitAttention = 2; - if (!(SCSICommandTable[BuslogicRequests->CmdBlock.common.Cdb[0]] & ALLOW_UA)) - { - SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSICallback[Id]=50*SCSI_TIME; - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - return; - } - } - else if (SCSISense.UnitAttention == 2) - { - if (BuslogicRequests->CmdBlock.common.Cdb[0]!=GPCMD_REQUEST_SENSE) - { - SCSISense.UnitAttention = 0; - } - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - clear the UNIT ATTENTION condition if it's set. */ - if (BuslogicRequests->CmdBlock.common.Cdb[0]!=GPCMD_REQUEST_SENSE) - { - SCSIClearSense(BuslogicRequests->CmdBlock.common.Cdb[0], 0); - } - - /* Next it's time for NOT READY. */ - if ((SCSICommandTable[BuslogicRequests->CmdBlock.common.Cdb[0]] & CHECK_READY) && !cdrom->ready()) - { - pclog("Not ready\n"); - SCSISenseCodeError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); SCSIStatus = SCSI_STATUS_CHECK_CONDITION; SCSICallback[Id]=50*SCSI_TIME; + SCSIDevices[BuslogicRequests->TargetID].InitLength = 0; + if (BuslogicRequests->RequestSenseBuffer) + BuslogicSenseBufferFree(BuslogicRequests, 1); BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); return; } @@ -1488,61 +1497,73 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, //First, get the data buffer otherwise putting it after the //exec function results into not getting read/write commands right and //failing to detect the device. - - if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) - { - SCSIRead(Id, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength); - } - else if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) - { - SCSIWrite(Id, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength); - } - + + /* Note by Tohka: After looking at the code, both functions do a copy of one part of the buffer to another, + with no purpose, whatsoever, and then end up with SCSIDevices.pos being equal to the InitLength. + SCSIReadData does not use pos at all, and the write code does, but in a useless way, therefore that + variable is going away. + All I am going to do at this point is zero the buffer. + Also, instead of directly calling SCSIReadData from here, this will be modified to call the CD-ROM + callback for the correct CD-ROM drive, and make that call SCSIReadData. + Since the new code will have the target ID and LUN inside the cdrom struct, as well as a copy of the Cdb + and the InitLength (in cdrom[id].request_length), it can be called from there and do everything needed. */ + + memset(SCSIDevices[Id].CmdBuffer, 0, 390144); + //Finally, execute the SCSI command immediately and get the transfer length. SCSIPhase = SCSI_PHASE_COMMAND; - SCSIExecCommand(Id, SCSIDevices[Id].CmdBuffer, BuslogicRequests->CmdBlock.common.Cdb); - SCSIGetLength(Id, &SCSIDevices[Id].InitLength); - - if (SCSIPhase == SCSI_PHASE_DATAIN) + cdrom_command(cdrom_id, BuslogicRequests->CmdBlock.common.Cdb); + // SCSIDevices[Id].InitLength = cdrom[cdrom_id].0; + // SCSIGetLength(Id, &SCSIDevices[Id].InitLength); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + if (SCSIStatus == SCSI_STATUS_OK) { - SCSIReadData(Id, BuslogicRequests->CmdBlock.common.Cdb, SCSIDevices[Id].CmdBuffer, SCSIDevices[Id].InitLength); - } - else if (SCSIPhase == SCSI_PHASE_DATAOUT) - { - if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_MODE_SELECT_6 || - BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_MODE_SELECT_10) + cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); + if (cdrom_phase == 2) { - //Mode Sense/Select stuff - if ((SCSIDevices[Id].pos >= prefix_len+4) && (page_flags[page_current] & PAGE_CHANGEABLE)) - { - mode_pages_in[page_current][SCSIDevices[Id].pos - prefix_len - 4] = SCSIDevices[Id].CmdBuffer[SCSIDevices[Id].pos - 2]; - mode_pages_in[page_current][SCSIDevices[Id].pos - prefix_len - 3] = SCSIDevices[Id].CmdBuffer[SCSIDevices[Id].pos - 1]; - } + /* Command completed - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + else + { + /* Command first phase complete - call the callback to execute the second phase. */ + cdrom_phase_callback(cdrom_id); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + /* Command second phase complete - call the callback to complete the command. */ + cdrom_phase_callback(cdrom_id); } } - + else + { + /* Error (Check Condition) - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + SCSICallback[Id] = cdrom[cdrom_id].callback; + BuslogicDataBufferFree(BuslogicRequests); if (BuslogicRequests->RequestSenseBuffer) - BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); + BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); } pclog("Request complete\n"); - pclog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, SCSISense.SenseKey, SCSISense.Asc, SCSISense.Ascq); + pclog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); - if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES || BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { + temp = BuslogicGetDataLength(BuslogicRequests); + temp -= SCSIDevices[Id].InitLength; + if (BuslogicRequests->Is24bit) { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, SCSIDevices[Id].InitLength); + U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, temp); BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); } else { - BuslogicRequests->CmdBlock.new.DataLength = SCSIDevices[Id].InitLength; + BuslogicRequests->CmdBlock.new.DataLength = temp; BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); } } @@ -1634,17 +1655,37 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic) } } -void BuslogicCommandCallback(void *p) +void BuslogicCommandCallback(int Id, void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; - SCSICallback[scsi_cdrom_id] = 0; + SCSICallback[Id] = 0; if (Buslogic->MailboxCount) { BuslogicStartMailbox(Buslogic); } } +void BuslogicCommandCallback0(void *p) +{ + BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, p); +} + +void BuslogicCommandCallback1(void *p) +{ + BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, p); +} + +void BuslogicCommandCallback2(void *p) +{ + BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, p); +} + +void BuslogicCommandCallback3(void *p) +{ + BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, p); +} + void *BuslogicInit() { Buslogic_t *Buslogic = malloc(sizeof(Buslogic_t)); @@ -1654,7 +1695,29 @@ void *BuslogicInit() Buslogic->DmaChannel = scsi_dma; io_sethandler(scsi_base, 0x0004, BuslogicRead, NULL, NULL, BuslogicWrite, NULL, NULL, Buslogic); - timer_add(BuslogicCommandCallback, &SCSICallback[scsi_cdrom_id], &SCSICallback[scsi_cdrom_id], Buslogic); + + build_scsi_cdrom_map(); + + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id)) + { + SCSIDevices[cdrom_drives[0].scsi_device_id].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id], &SCSICallback[cdrom_drives[0].scsi_device_id], Buslogic); + } + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id)) + { + SCSIDevices[cdrom_drives[1].scsi_device_id].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id], &SCSICallback[cdrom_drives[1].scsi_device_id], Buslogic); + } + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id)) + { + SCSIDevices[cdrom_drives[2].scsi_device_id].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id], &SCSICallback[cdrom_drives[2].scsi_device_id], Buslogic); + } + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id)) + { + SCSIDevices[cdrom_drives[3].scsi_device_id].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id], &SCSICallback[cdrom_drives[3].scsi_device_id], Buslogic); + } BuslogicLog("Buslogic on port 0x%04X\n", scsi_base); diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 37197b51f..12d8662ae 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -3,6 +3,7 @@ */ /*Win32 CD-ROM support via IOCTL*/ +#define WINVER 0x0600 #include #include #include "ntddcdrm.h" @@ -10,26 +11,24 @@ #include "ibm.h" #include "cdrom.h" #include "cdrom-ioctl.h" +#include "scsi.h" -int cdrom_drive; -int old_cdrom_drive; +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) static CDROM ioctl_cdrom; -static uint32_t last_block = 0; -uint32_t cdrom_capacity = 0; -static int ioctl_inited = 0; -static char ioctl_path[8]; -void ioctl_close(void); -static HANDLE hIOCTL; -static CDROM_TOC toc; -static int tocvalid = 0; +typedef struct +{ + HANDLE hIOCTL; + CDROM_TOC toc; +} cdrom_ioctl_windows_t; + +cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; // #define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)-150) /* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) enum { @@ -38,82 +37,92 @@ enum CD_PAUSED }; -static int ioctl_cd_state = CD_STOPPED; -static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; +int cdrom_ioctl_do_log = 1; -#define BUF_SIZE 32768 -static int16_t cd_buffer[BUF_SIZE]; -static int cd_buflen = 0; -void ioctl_audio_callback(int16_t *output, int len) +void cdrom_ioctl_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_LOG + if (cdrom_ioctl_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void ioctl_audio_callback(uint8_t id, int16_t *output, int len) { RAW_READ_INFO in; DWORD count; // return; -// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (ioctl_cd_state != CD_PLAYING) +// cdrom_ioctl_log("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); + if (cdrom_ioctl[id].cd_state != CD_PLAYING) { memset(output, 0, len * 2); return; } - while (cd_buflen < len) + while (cdrom_ioctl[id].cd_buflen < len) { - if (ioctl_cd_pos < ioctl_cd_end) + if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) { - in.DiskOffset.LowPart = (ioctl_cd_pos - 150) * 2048; + in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; - ioctl_open(0); -// pclog("Read to %i\n", cd_buflen); - if (!DeviceIoControl(hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &cd_buffer[cd_buflen], 2352, &count, NULL)) + ioctl_open(id, 0); +// cdrom_ioctl_log("Read to %i\n", cd_buflen); + if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) { -// pclog("DeviceIoControl returned false\n"); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; +// cdrom_ioctl_log("DeviceIoControl returned false\n"); + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; } else { -// pclog("DeviceIoControl returned true\n"); - ioctl_cd_pos++; - cd_buflen += (2352 / 2); +// cdrom_ioctl_log("DeviceIoControl returned true\n"); + cdrom[id].seek_pos++; + cdrom_ioctl[id].cd_buflen += (2352 / 2); } - ioctl_close(); + ioctl_close(id); } else { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; } } - memcpy(output, cd_buffer, len * 2); + memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); // for (c = 0; c < BUF_SIZE - len; c++) // cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; -// pclog("Done %i\n", GetTickCount()); + memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); + cdrom_ioctl[id].cd_buflen -= len; +// cdrom_ioctl_log("Done %i\n", GetTickCount()); } -void ioctl_audio_stop() +void ioctl_audio_stop(uint8_t id) { - ioctl_cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_state = CD_STOPPED; } -static int get_track_nr(uint32_t pos) +static int get_track_nr(uint8_t id, uint32_t pos) { int c; int track = 0; - if (!tocvalid) + if (!cdrom_ioctl[id].tocvalid) return 0; - for (c = toc.FirstTrack; c < toc.LastTrack; c++) + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) { - uint32_t track_address = toc.TrackData[c].Address[3] + - (toc.TrackData[c].Address[2] * 75) + - (toc.TrackData[c].Address[1] * 75 * 60); + uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); if (track_address <= pos) track = c; @@ -121,145 +130,142 @@ static int get_track_nr(uint32_t pos) return track; } -static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) +static uint32_t get_track_msf(uint8_t id, uint32_t track_no) { - if (!cdrom_drive) return; - // pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) + int c; + int track = 0; + + if (!cdrom_ioctl[id].tocvalid) + return 0; + + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; + if (c == track_no) + { + return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); + } + } + return 0xffffffff; +} + +static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdrom_drives[id].host_drive) return; + // cdrom_ioctl_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + uint32_t start_msf = get_track_msf(id, pos); + uint32_t end_msf = get_track_msf(id, len); + if (start_msf == 0xffffffff) + { + return; + } + if (end_msf == 0xffffffff) + { + return; + } + int m = (start_msf >> 16) & 0xff; + int s = (start_msf >> 8) & 0xff; + int f = start_msf & 0xff; pos = MSFtoLBA(m, s, f); + m = (end_msf >> 16) & 0xff; + s = (end_msf >> 8) & 0xff; + f = end_msf & 0xff; + len = MSFtoLBA(m, s, f); + } + else if (ismsf == 1) + { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_ioctl_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + m = (len >> 16) & 0xff; s = (len >> 8) & 0xff; f = len & 0xff; len = MSFtoLBA(m, s, f); - // pclog("MSF - pos = %08X len = %08X\n", pos, len); + // cdrom_ioctl_log("MSF - pos = %08X len = %08X\n", pos, len); } - else - len += pos; - ioctl_cd_pos = pos;// + 150; - ioctl_cd_end = len;// + 150; - if (ioctl_cd_pos < 150) + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_ioctl_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos;// + 150; + cdrom_ioctl[id].cd_end = len;// + 150; + if (cdrom[id].seek_pos < 150) { /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - ioctl_cd_pos = 150; + cdrom[id].seek_pos = 150; } - ioctl_cd_state = CD_PLAYING; - // pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len); -/* CDROM_PLAY_AUDIO_MSF msf; - long size; - BOOL b; - if (ismsf) - { - msf.StartingF=pos&0xFF; - msf.StartingS=(pos>>8)&0xFF; - msf.StartingM=(pos>>16)&0xFF; - msf.EndingF=len&0xFF; - msf.EndingS=(len>>8)&0xFF; - msf.EndingM=(len>>16)&0xFF; - } - else - { - msf.StartingF=(uint8_t)(addr%75); addr/=75; - msf.StartingS=(uint8_t)(addr%60); addr/=60; - msf.StartingM=(uint8_t)(addr); - addr=pos+len+150; - msf.EndingF=(uint8_t)(addr%75); addr/=75; - msf.EndingS=(uint8_t)(addr%60); addr/=60; - msf.EndingM=(uint8_t)(addr); - } - ioctl_open(0); - b = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF,&msf,sizeof(msf),NULL,0,&size,NULL); - pclog("DeviceIoControl returns %i\n", (int) b); - ioctl_close();*/ + cdrom_ioctl[id].cd_state = CD_PLAYING; + // cdrom_ioctl_log("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len); } -static void ioctl_pause(void) +static void ioctl_pause(uint8_t id) { - if (!cdrom_drive) return; - if (ioctl_cd_state == CD_PLAYING) - ioctl_cd_state = CD_PAUSED; -// ioctl_open(0); -// DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO,NULL,0,NULL,0,&size,NULL); -// ioctl_close(); + if (!cdrom_drives[id].host_drive) return; + if (cdrom_ioctl[id].cd_state == CD_PLAYING) + cdrom_ioctl[id].cd_state = CD_PAUSED; } -static void ioctl_resume(void) +static void ioctl_resume(uint8_t id) { - if (!cdrom_drive) return; - if (ioctl_cd_state == CD_PAUSED) - ioctl_cd_state = CD_PLAYING; -// ioctl_open(0); -// DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO,NULL,0,NULL,0,&size,NULL); -// ioctl_close(); + if (!cdrom_drives[id].host_drive) return; + if (cdrom_ioctl[id].cd_state == CD_PAUSED) + cdrom_ioctl[id].cd_state = CD_PLAYING; } -static void ioctl_stop(void) +static void ioctl_stop(uint8_t id) { - if (!cdrom_drive) return; - ioctl_cd_state = CD_STOPPED; -// ioctl_open(0); -// DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO,NULL,0,NULL,0,&size,NULL); -// ioctl_close(); + if (!cdrom_drives[id].host_drive) return; + cdrom_ioctl[id].cd_state = CD_STOPPED; } -static void ioctl_seek(uint32_t pos) -{ - if (!cdrom_drive) return; - // ioctl_cd_state = CD_STOPPED; - // pclog("Seek %08X\n", pos); - ioctl_cd_pos = pos; - ioctl_cd_state = CD_STOPPED; -/* pos+=150; - CDROM_SEEK_AUDIO_MSF msf; - msf.F=(uint8_t)(pos%75); pos/=75; - msf.S=(uint8_t)(pos%60); pos/=60; - msf.M=(uint8_t)(pos); -// pclog("Seek to %02i:%02i:%02i\n",msf.M,msf.S,msf.F); - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_SEEK_AUDIO_MSF,&msf,sizeof(msf),NULL,0,&size,NULL); - ioctl_close();*/ -} - -static int ioctl_ready(void) +static int ioctl_ready(uint8_t id) { long size; int temp; CDROM_TOC ltoc; -// pclog("Ready? %i\n",cdrom_drive); - if (!cdrom_drive) return 0; - ioctl_open(0); - temp=DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,<oc,sizeof(ltoc),&size,NULL); - ioctl_close(); + // cdrom_ioctl_log("Ready? %i\n",cdrom_drives[id].host_drive); + if (!cdrom_drives[id].host_drive) return 0; + ioctl_open(id, 0); + temp=DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,<oc,sizeof(ltoc),&size,NULL); + ioctl_close(id); if (!temp) return 0; - //pclog("ioctl_ready(): Drive opened successfully\n"); - //if ((cdrom_drive != old_cdrom_drive)) pclog("Drive has changed\n"); - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != toc.TrackData[toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != toc.TrackData[toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != toc.TrackData[toc.LastTrack].Address[3]) || - !tocvalid || (cdrom_drive != old_cdrom_drive)) + // cdrom_ioctl_log("ioctl_ready(): Drive opened successfully\n"); + // if ((cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) cdrom_ioctl_log("Drive has changed\n"); + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || + !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { - //pclog("ioctl_ready(): Disc or drive changed\n"); - ioctl_cd_state = CD_STOPPED; - /* pclog("Not ready %02X %02X %02X %02X %02X %02X %i\n",ltoc.TrackData[ltoc.LastTrack].Address[1],ltoc.TrackData[ltoc.LastTrack].Address[2],ltoc.TrackData[ltoc.LastTrack].Address[3], - toc.TrackData[ltoc.LastTrack].Address[1], toc.TrackData[ltoc.LastTrack].Address[2], toc.TrackData[ltoc.LastTrack].Address[3],tocvalid);*/ - // atapi_discchanged(); -/* ioctl_open(0); - temp=DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&toc,sizeof(toc),&size,NULL); - ioctl_close();*/ - if (cdrom_drive != old_cdrom_drive) - old_cdrom_drive = cdrom_drive; - return 1; + // cdrom_ioctl_log("ioctl_ready(): Disc or drive changed\n"); + // cdrom_ioctl_log("ioctl_ready(): Stopped\n"); + cdrom_ioctl[id].cd_state = CD_STOPPED; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; } -// pclog("IOCTL says ready\n"); -// pclog("ioctl_ready(): All is good\n"); + // cdrom_ioctl_log("ioctl_ready(): All is good\n"); return 1; } -static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) { int len=4; long size; @@ -267,86 +273,77 @@ static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, i uint32_t temp; CDROM_TOC lbtoc; int lb=0; - if (!cdrom_drive) return 0; - ioctl_cd_state = CD_STOPPED; - // pclog("ioctl_readtoc(): IOCtl state now CD_STOPPED\n"); - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&lbtoc,sizeof(lbtoc),&size,NULL); - ioctl_close(); - tocvalid=1; + if (!cdrom_drives[id].host_drive) return 0; + cdrom_ioctl[id].cd_state = CD_STOPPED; + // cdrom_ioctl_log("ioctl_readtoc(): IOCtl state now CD_STOPPED\n"); + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&lbtoc,sizeof(lbtoc),&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; for (c=d;c<=lbtoc.LastTrack;c++) { uint32_t address; - address = MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); + address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); if (address > lb) lb = address; } return lb; } -static int ioctl_medium_changed(void) +static int ioctl_medium_changed(uint8_t id) { long size; int temp; CDROM_TOC ltoc; - if (!cdrom_drive) return 0; /* This will be handled by the not ready handler instead. */ - ioctl_open(0); - temp=DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,<oc,sizeof(ltoc),&size,NULL); - ioctl_close(); + if (!cdrom_drives[id].host_drive) return 0; /* This will be handled by the not ready handler instead. */ + ioctl_open(id, 0); + temp=DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,<oc,sizeof(ltoc),&size,NULL); + ioctl_close(id); if (!temp) return 0; /* Drive empty, a not ready handler matter, not disc change. */ - if (!tocvalid || (cdrom_drive != old_cdrom_drive)) + if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { - ioctl_cd_state = CD_STOPPED; - toc = ltoc; - tocvalid = 1; - if (cdrom_drive != old_cdrom_drive) - old_cdrom_drive = cdrom_drive; - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); - if (cdrom_drive == old_cdrom_drive) - { - return 1; - } - else - { - return 0; - } + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; } else { - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != toc.TrackData[toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != toc.TrackData[toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != toc.TrackData[toc.LastTrack].Address[3])) + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) { - ioctl_cd_state = CD_STOPPED; - toc = ltoc; - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; /* TOC mismatches. */ } } return 0; /* None of the above, return 0. */ } -static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) +static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; long size; int pos=0; - if (!cdrom_drive) return 0; + if (!cdrom_drives[id].host_drive) return 0; insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); - ioctl_close(); + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); + ioctl_close(id); - if (ioctl_cd_state == CD_PLAYING || ioctl_cd_state == CD_PAUSED) - { - uint32_t cdpos = ioctl_cd_pos; - int track = get_track_nr(cdpos); - uint32_t track_address = toc.TrackData[track].Address[3] + - (toc.TrackData[track].Address[2] * 75) + - (toc.TrackData[track].Address[1] * 75 * 60); + if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) + { + uint32_t cdpos = cdrom[id].seek_pos; + int track = get_track_nr(id, cdpos); + uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); b[pos++] = sub.CurrentPosition.Control; b[pos++] = track + 1; @@ -380,7 +377,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) b[pos++] = cdpos & 0xff; } - if (ioctl_cd_state == CD_PLAYING) return 0x11; + if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; return 0x12; } @@ -413,46 +410,43 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) return 0x13; } -static void ioctl_eject(void) +static void ioctl_eject(uint8_t id) { long size; - if (!cdrom_drive) return; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(); + if (!cdrom_drives[id].host_drive) return; + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); } -static void ioctl_load(void) +static void ioctl_load(uint8_t id) { long size; - if (!cdrom_drive) return; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(); - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + if (!cdrom_drives[id].host_drive) return; + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); } -static int is_track_audio(uint32_t pos) +static int is_track_audio(uint8_t id, uint32_t pos) { int c; int control = 0; - if (!tocvalid) + if (!cdrom_ioctl[id].tocvalid) return 0; - // for (c = toc.FirstTrack; c <= toc.LastTrack; c++) - for (c = 0; c <= toc.LastTrack; c++) + for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) { - uint32_t track_address = MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); - - // pclog("Track address: %i (%02X%02X%02X%02X), Position: %i\n", track_address, toc.TrackData[c].Address[0], toc.TrackData[c].Address[1], toc.TrackData[c].Address[2], toc.TrackData[c].Address[3], pos); + uint32_t track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); if (track_address <= pos) - control = toc.TrackData[c].Control; + control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; } - // pclog("Control: %i\n", control); + // cdrom_ioctl_log("Control: %i\n", control); if ((control & 0xd) == 0) { return 1; @@ -467,7 +461,7 @@ static int is_track_audio(uint32_t pos) } } -static int ioctl_is_track_audio(uint32_t pos, int ismsf) +static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) { if (ismsf) { @@ -480,196 +474,183 @@ static int ioctl_is_track_audio(uint32_t pos, int ismsf) { pos += 150; } - return is_track_audio(pos); + return is_track_audio(id, pos); } -static int SCSICommand(const UCHAR *cdb, UCHAR *buf, uint32_t len) +/* 00, 08, 10, 18, 20, 28, 30, 38 */ +int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ + { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ + 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ + -296, -296, 2048, 2048, 24, -296, 2064, 2352 }, /* C0-F8 */ + { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ + -296, -296, 2336, 2336, 24, -296, 2352, 2352 }, /* C0-F8 */ + { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ + 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2072, 2352 }, /* C0-F8 */ + { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2352, 2352 } /* C0-F8 */ + }; + +static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf); + +static void cdrom_illegal_mode(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; + cdrom_ascq = 0; +} + +struct sptd_with_sense +{ + SCSI_PASS_THROUGH s; + ULONG Filler; + UCHAR sense[32]; + UCHAR data[64512]; +} sptd; + +static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) { HANDLE fh; DWORD ioctl_bytes; DWORD out_size; int ioctl_rv = 0; - UCHAR tbuf[65536]; - struct sptd_with_sense - { - SCSI_PASS_THROUGH_DIRECT s; - UCHAR sense[128]; - } sptd; + int sector_type = 0; + int temp_len = 0; + SCSISense.SenseKey = 0; + SCSISense.Asc = 0; + SCSISense.Ascq = 0; + + *len = 0; memset(&sptd, 0, sizeof(sptd)); - sptd.s.Length = sizeof(sptd.s); - // sptd.s.CdbLength = sizeof(cdb); + sptd.s.Length = sizeof(SCSI_PASS_THROUGH); sptd.s.CdbLength = 12; sptd.s.DataIn = SCSI_IOCTL_DATA_IN; - sptd.s.TimeOutValue = 30; - sptd.s.DataBuffer = tbuf; - sptd.s.DataTransferLength = len; - sptd.s.SenseInfoLength = sizeof(sptd.sense); - sptd.s.SenseInfoOffset = offsetof(struct sptd_with_sense, sense); - - // memcpy(sptd.s.Cdb, cdb, sizeof(cdb)); + sptd.s.TimeOutValue = 80 * 60; + goto bypass_check; + if (no_length_check) goto bypass_check; + switch (cdb[0]) + { + case 0x08: + case 0x28: + case 0xa8: + /* READ (6), READ (10), READ (12) */ + sptd.s.DataTransferLength = 2048 * cdrom[id].requested_blocks; + break; + case 0xb9: + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) + { + sector_type = ioctl_get_sector_data_type(id, 0, cdb[3], cdb[4], cdb[5], 1); + if (sector_type == 0) + { + cdrom_illegal_mode(id); + return 1; + } + } + goto common_handler; + case 0xbe: + /* READ CD MSF, READ CD */ + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) + { + sector_type = ioctl_get_sector_data_type(id, cdb[2], cdb[3], cdb[4], cdb[5], 0); + if (sector_type == 0) + { + cdrom_illegal_mode(id); + return 1; + } + } +common_handler: + temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; + if ((cdb[9] & 6) == 2) + { + temp_len += 294; + } + else if ((cdb[9] & 6) == 4) + { + temp_len += 296; + } + if ((cdb[10] & 7) == 1) + { + temp_len += 96; + } + else if ((cdb[10] & 7) == 2) + { + temp_len += 16; + } + else if ((cdb[10] & 7) == 4) + { + temp_len += 96; + } + if (temp_len <= 0) + { + cdrom_illegal_mode(id); + return 1; + } + sptd.s.DataTransferLength = temp_len * cdrom[id].requested_blocks; + break; + default: +bypass_check: + /* Other commands */ + sptd.s.DataTransferLength = 64512; + break; + } + sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; + sptd.s.SenseInfoLength = 32; + sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; + memcpy(sptd.s.Cdb, cdb, 12); - ioctl_rv = DeviceIoControl(hIOCTL, IOCTL_SCSI_PASS_THROUGH_DIRECT, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); - memcpy(buf, sptd.s.DataBuffer, len); + ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); + + if (sptd.s.SenseInfoLength) + { + cdrom_sense_key = sptd.sense[2]; + cdrom_asc = sptd.sense[12]; + cdrom_ascq = sptd.sense[13]; + } + + cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); + cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); + cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); + cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); + cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); + *len = sptd.s.DataTransferLength; + if (sptd.s.DataTransferLength != 0) + { + memcpy(buf, sptd.data, sptd.s.DataTransferLength); + } return ioctl_rv; } -static void ioctl_read_capacity(uint8_t *b) +static void ioctl_read_capacity(uint8_t id, uint8_t *b) { + int len = 0; + const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; UCHAR buf[16]; - ioctl_open(0); + ioctl_open(id, 0); - SCSICommand(cdb, buf, 16); - - memcpy(b, buf, 8); - - ioctl_close(); -} - -static void ioctl_read_subchannel(uint8_t *in_cdb, uint8_t *b) -{ - const UCHAR cdb[12]; - UCHAR buf[24]; - - ioctl_open(0); - - memcpy(cdb, in_cdb, 12); - SCSICommand(cdb, buf, 24); - - memcpy(b, buf, 24); - - ioctl_close(); -} - -static void ioctl_read_header(uint8_t *in_cdb, uint8_t *b) -{ - const UCHAR cdb[12]; - UCHAR buf[16]; - - ioctl_open(0); - - memcpy(cdb, in_cdb, 12); - SCSICommand(cdb, buf, 16); - - memcpy(b, buf, 8); - - ioctl_close(); -} - -static int ioctl_read_track_information(uint8_t *in_cdb, uint8_t *b) -{ - int maxlen = 0; - int len = 0; - - int ret = 0; - - const UCHAR cdb[12]; - UCHAR buf[65536]; - - maxlen = in_cdb[7]; - maxlen <<= 8; - maxlen |= in_cdb[8]; - - ioctl_open(0); - - memcpy(cdb, in_cdb, 12); - ret = SCSICommand(cdb, buf, 65535); - - if (!ret) - { - return 0; - } - - len = buf[0]; - len <<= 8; - len |= buf[1]; - len += 2; - - if (len > maxlen) - { - len = maxlen; - buf[0] = ((maxlen - 2) >> 8) * 0xff; - buf[1] = (maxlen - 2) & 0xff; - } + SCSICommand(id, cdb, buf, &len, 1); memcpy(b, buf, len); - ioctl_close(); - - return 1; -} - -static void ioctl_read_disc_information(uint8_t *b) -{ - const UCHAR cdb[] = { 0x51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - UCHAR buf[68]; - - ioctl_open(0); - - SCSICommand(cdb, buf, 68); - - memcpy(b, buf, 34); - - ioctl_close(); -} - -static int SCSIReadCommon(const UCHAR *cdb_0, const UCHAR *cdb_1, const UCHAR *cdb_2, const UCHAR *cdb_4, uint8_t *b, UCHAR *buf) -{ - int ioctl_rv; - - ioctl_open(0); - - /* Fill the buffer with zeroes. */ - memset(b, 0, 2856); - - ioctl_rv = SCSICommand(cdb_0, buf, 2856); - memcpy(b, buf, 2648); - - /* Next, try to read RAW subchannel data. */ - ioctl_rv += SCSICommand(cdb_1, buf, 2856); - memcpy(b + 2648, buf + 2648, 96); - - /* Next, try to read Q subchannel data. */ - ioctl_rv += SCSICommand(cdb_2, buf, 2856); - memcpy(b + 2648 + 96, buf + 2648, 16); - - /* Next, try to read R - W subchannel data. */ - ioctl_rv += SCSICommand(cdb_4, buf, 2856); - memcpy(b + 2648 + 96 + 16, buf + 2648, 96); - - ioctl_close(); - - // pclog("rv: %i\n", ioctl_rv); - - return ioctl_rv; -} - -/* Direct SCSI read in MSF mode. */ -static int SCSIReadMSF(uint8_t *b, int sector) -{ - const UCHAR cdb_0[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 0, 0 }; - const UCHAR cdb_1[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 1, 0 }; - const UCHAR cdb_2[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 2, 0 }; - const UCHAR cdb_4[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0xFC, 4, 0 }; - UCHAR buf[2856]; - - return SCSIReadCommon(cdb_0, cdb_1, cdb_2, cdb_4, b, buf); -} - -/* Direct SCSI read in LBA mode. */ -static void SCSIRead(uint8_t *b, int sector) -{ - const UCHAR cdb_0[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 0, 0 }; - const UCHAR cdb_1[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 1, 0 }; - const UCHAR cdb_2[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 2, 0 }; - const UCHAR cdb_4[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0xFC, 4, 0 }; - UCHAR buf[2856]; - - SCSIReadCommon(cdb_0, cdb_1, cdb_2, cdb_4, b, buf); - return; + ioctl_close(id); } static uint32_t msf_to_lba32(int lba) @@ -680,15 +661,17 @@ static uint32_t msf_to_lba32(int lba) return (m * 60 * 75) + (s * 75) + f; } -static int ioctl_get_type(UCHAR *cdb, UCHAR *buf) +static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) { int i = 0; int ioctl_rv = 0; + + int len = 0; for (i = 2; i <= 5; i++) { cdb[1] = i << 2; - ioctl_rv = SCSICommand(cdb, buf, 2352); + ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ if (ioctl_rv) { return i; @@ -697,32 +680,32 @@ static int ioctl_get_type(UCHAR *cdb, UCHAR *buf) return 0; } -static int ioctl_sector_data_type(int sector, int ismsf) +static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) { int ioctl_rv = 0; const UCHAR cdb_lba[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0x10, 0, 0 }; const UCHAR cdb_msf[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0x10, 0, 0 }; UCHAR buf[2352]; - ioctl_open(0); + ioctl_open(id, 0); - if (ioctl_is_track_audio(sector, ismsf)) + if (ioctl_is_track_audio(id, sector, ismsf)) { return 1; } if (ismsf) { - ioctl_rv = ioctl_get_type(cdb_msf, buf); + ioctl_rv = ioctl_get_type(id, cdb_msf, buf); } else { - ioctl_rv = ioctl_get_type(cdb_lba, buf); + ioctl_rv = ioctl_get_type(id, cdb_lba, buf); } if (ioctl_rv) { - ioctl_close(); + ioctl_close(id); return ioctl_rv; } @@ -731,247 +714,75 @@ static int ioctl_sector_data_type(int sector, int ismsf) sector = msf_to_lba32(sector); if (sector < 150) { - ioctl_close(); + ioctl_close(id); return 0; } sector -= 150; - ioctl_rv = ioctl_get_type(cdb_lba, buf); + ioctl_rv = ioctl_get_type(id, cdb_lba, buf); } - ioctl_close(); + ioctl_close(id); return ioctl_rv; } -static void ioctl_readsector_raw(uint8_t *b, int sector, int ismsf) +static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) { - if (!cdrom_drive) return; - if (ioctl_cd_state == CD_PLAYING) - return; - - if (ismsf) - { - if (!SCSIReadMSF(b, sector)) - { - sector = msf_to_lba32(sector); - if (sector < 150) - { - memset(b, 0, 2856); - return; - } - sector -= 150; - SCSIRead(b, sector); - } - } - else - { - SCSIRead(b, sector); - } + int sector = b3; + sector |= ((uint32_t) b2) << 8; + sector |= ((uint32_t) b1) << 16; + sector |= ((uint32_t) b0) << 24; + return ioctl_sector_data_type(id, sector, ismsf); } -static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +static void ioctl_validate_toc(uint8_t id) { - int len=4; - long size; - int c,d; - uint32_t temp; - if (!cdrom_drive) return 0; - ioctl_cd_state = CD_STOPPED; - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&toc,sizeof(toc),&size,NULL); - ioctl_close(); - tocvalid=1; -// pclog("Read TOC done! %i\n",single); - b[2]=toc.FirstTrack; - b[3]=toc.LastTrack; - d=0; - for (c=0;c<=toc.LastTrack;c++) - { - if (toc.TrackData[c].TrackNumber>=starttrack) - { - d=c; - break; - } - } - b[2]=toc.TrackData[c].TrackNumber; - last_block = 0; - for (c=d;c<=toc.LastTrack;c++) - { - uint32_t address; - if ((len+8)>maxlen) break; -// pclog("Len %i max %i Track %02X - %02X %02X %i %i %i %i %08X\n",len,maxlen,toc.TrackData[c].TrackNumber,toc.TrackData[c].Adr,toc.TrackData[c].Control,toc.TrackData[c].Address[0],toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3],MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3])); - b[len++]=0; /*Reserved*/ - b[len++]=(toc.TrackData[c].Adr<<4)|toc.TrackData[c].Control; - b[len++]=toc.TrackData[c].TrackNumber; - b[len++]=0; /*Reserved*/ - address = MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); - if (address > last_block) - last_block = address; - - if (msf) - { - b[len++]=toc.TrackData[c].Address[0]; - b[len++]=toc.TrackData[c].Address[1]; - b[len++]=toc.TrackData[c].Address[2]; - b[len++]=toc.TrackData[c].Address[3]; - } - else - { - temp=MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); - b[len++]=temp>>24; - b[len++]=temp>>16; - b[len++]=temp>>8; - b[len++]=temp; - } - if (single) break; - } - if (len > maxlen) - { - len = maxlen; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); -/* pclog("Table of Contents (%i bytes) : \n",size); - pclog("First track - %02X\n",toc.FirstTrack); - pclog("Last track - %02X\n",toc.LastTrack); - for (c=0;c<=toc.LastTrack;c++) - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n",c,toc.TrackData[c].TrackNumber,toc.TrackData[c].Control,toc.TrackData[c].Adr,toc.TrackData[c].Address[0],toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]); - for (c=0;c<=toc.LastTrack;c++) - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n",c,toc.TrackData[c].TrackNumber,toc.TrackData[c].Control,toc.TrackData[c].Adr,MSFtoLBA(toc.TrackData[c].Address[1],toc.TrackData[c].Address[2],toc.TrackData[c].Address[3]));*/ - return len; -} - -static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) -{ - int len=4; - int size; - uint32_t temp; - CDROM_READ_TOC_EX toc_ex; - CDROM_TOC_SESSION_DATA toc; - if (!cdrom_drive) return 0; - ioctl_cd_state = CD_STOPPED; - memset(&toc_ex,0,sizeof(toc_ex)); - memset(&toc,0,sizeof(toc)); - toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_SESSION; - toc_ex.Msf=msf; - toc_ex.SessionTrack=0; - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); - ioctl_close(); -// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",size,toc.Length[0],toc.Length[1],toc.FirstCompleteSession,toc.LastCompleteSession,toc.TrackData[0].Adr,toc.TrackData[0].Control,toc.TrackData[0].TrackNumber); - b[2]=toc.FirstCompleteSession; - b[3]=toc.LastCompleteSession; - b[len++]=0; /*Reserved*/ - b[len++]=(toc.TrackData[0].Adr<<4)|toc.TrackData[0].Control; - b[len++]=toc.TrackData[0].TrackNumber; - b[len++]=0; /*Reserved*/ - if (msf) - { - b[len++]=toc.TrackData[0].Address[0]; - b[len++]=toc.TrackData[0].Address[1]; - b[len++]=toc.TrackData[0].Address[2]; - b[len++]=toc.TrackData[0].Address[3]; - } - else - { - temp=MSFtoLBA(toc.TrackData[0].Address[1],toc.TrackData[0].Address[2],toc.TrackData[0].Address[3]); - b[len++]=temp>>24; - b[len++]=temp>>16; - b[len++]=temp>>8; - b[len++]=temp; - } - - if (len > maxlen) - { - len = maxlen; - } - b[0] = ((len - 2) >> 8) & 0xff; - b[1] = (len - 2) & 0xff; - return len; -} - -static void ioctl_readtoc_raw(uint8_t *b, int msf, int maxlen) -{ - UCHAR cdb[12]; - UCHAR buf[65536]; - - int len = 0; - - ioctl_open(0); - - cdb[0] = 0x43; - cdb[1] = msf ? 2 : 0; - cdb[2] = 2; - cdb[3] = cdb[4] = cdb[5] = cdb[6] = 0; - cdb[7] = (maxlen >> 8) & 0xff; - cdb[8] = maxlen & 0xff; - cdb[9] = cdb[10] = cdb[11] = 0; - - SCSICommand(cdb, buf, 65535); - - len = buf[0]; - len <<= 8; - len |= buf[1]; - len += 2; - - memcpy(b, buf, len); - - ioctl_close(); -} - -#if 0 -static int ioctl_readtoc_raw(unsigned char *b, int maxlen) -{ - int len=4; - int size; - uint32_t temp; - int i; - int BytesRead = 0; - CDROM_READ_TOC_EX toc_ex; - CDROM_TOC_FULL_TOC_DATA toc; - if (!cdrom_drive) return 0; - ioctl_cd_state = CD_STOPPED; - memset(&toc_ex,0,sizeof(toc_ex)); - memset(&toc,0,sizeof(toc)); - toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_FULL_TOC; - toc_ex.Msf=1; - toc_ex.SessionTrack=0; - ioctl_open(0); - DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); - ioctl_close(); -// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",size,toc.Length[0],toc.Length[1],toc.FirstCompleteSession,toc.LastCompleteSession,toc.TrackData[0].Adr,toc.TrackData[0].Control,toc.TrackData[0].TrackNumber); - b[2]=toc.FirstCompleteSession; - b[3]=toc.LastCompleteSession; - - size -= sizeof(CDROM_TOC_FULL_TOC_DATA); - size /= sizeof(toc.Descriptors[0]); - - for (i = 0; i <= size; i++) + long size; + if (!cdrom_drives[id].host_drive) { - b[len++]=toc.Descriptors[i].SessionNumber; - b[len++]=(toc.Descriptors[i].Adr<<4)|toc.Descriptors[i].Control; - b[len++]=0; - b[len++]=toc.Descriptors[i].Reserved1; /*Reserved*/ - b[len++]=toc.Descriptors[i].MsfExtra[0]; - b[len++]=toc.Descriptors[i].MsfExtra[1]; - b[len++]=toc.Descriptors[i].MsfExtra[2]; - b[len++]=toc.Descriptors[i].Zero; - b[len++]=toc.Descriptors[i].Msf[0]; - b[len++]=toc.Descriptors[i].Msf[1]; - b[len++]=toc.Descriptors[i].Msf[2]; + return; } - - b[0] = (len >> 8) & 0xff; - b[1] = len & 0xff; - - return len; + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; } -#endif -static uint32_t ioctl_size() +UCHAR buf[64512]; + +static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) +{ + const UCHAR cdb[12]; + + int ret; + + if (cdb[0] == 0x43) + { + /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ + ioctl_validate_toc(id); + } + + ioctl_open(id, 0); + + memcpy(cdb, in_cdb, 12); + ret = SCSICommand(id, cdb, buf, len, 0); + + memcpy(b, buf, *len); + + cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + + ioctl_close(id); + + cdrom_ioctl_log("IOCTL Returned value: %i\n", ret); + + return ret; +} + +static uint32_t ioctl_size(uint8_t id) { uint8_t capacity_buffer[8]; uint32_t capacity = 0; - ioctl_read_capacity(capacity_buffer); + ioctl_read_capacity(id, capacity_buffer); capacity = ((uint32_t) capacity_buffer[0]) << 24; capacity |= ((uint32_t) capacity_buffer[1]) << 16; capacity |= ((uint32_t) capacity_buffer[2]) << 8; @@ -980,12 +791,12 @@ static uint32_t ioctl_size() // return cdrom_capacity; } -static int ioctl_status() +static int ioctl_status(uint8_t id) { - if (!(ioctl_ready) && (cdrom_drive <= 0)) + if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) return CD_STATUS_EMPTY; - switch(ioctl_cd_state) + switch(cdrom_ioctl[id].cd_state) { case CD_PLAYING: return CD_STATUS_PLAYING; @@ -996,87 +807,81 @@ static int ioctl_status() } } -void ioctl_reset() +void ioctl_reset(uint8_t id) { CDROM_TOC ltoc; int temp; long size; - if (!cdrom_drive) + if (!cdrom_drives[id].host_drive) { - tocvalid = 0; + cdrom_ioctl[id].tocvalid = 0; return; } - ioctl_open(0); - temp = DeviceIoControl(hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(); + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); - toc = ltoc; - tocvalid = 1; + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; } -int ioctl_open(char d) +int ioctl_open(uint8_t id, char d) { -// char s[8]; - if (!ioctl_inited) - { - sprintf(ioctl_path,"\\\\.\\%c:",d); - // pclog("Path is %s\n",ioctl_path); - tocvalid=0; - } -// pclog("Opening %s\n",ioctl_path); - // hIOCTL = CreateFile(/*"\\\\.\\g:"*/ioctl_path,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); - hIOCTL = CreateFile(ioctl_path, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (!hIOCTL) + // char s[8]; + if (!cdrom_ioctl[id].ioctl_inited) { - //fatal("IOCTL"); - } - cdrom=&ioctl_cdrom; - if (!ioctl_inited) - { - ioctl_inited=1; - CloseHandle(hIOCTL); - hIOCTL = NULL; - } - return 0; + sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); + // cdrom_ioctl_log("Path is %s\n",ioctl_path); + cdrom_ioctl[id].tocvalid=0; + } + // cdrom_ioctl_log("Opening %s\n",ioctl_path); + cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (!cdrom_ioctl_windows[id].hIOCTL) + { + // fatal("IOCTL"); + } + cdrom_drives[id].handler = &ioctl_cdrom; + if (!cdrom_ioctl[id].ioctl_inited) + { + cdrom_ioctl[id].ioctl_inited=1; + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; + } + return 0; } -void ioctl_close(void) +void ioctl_close(uint8_t id) { - if (hIOCTL) - { - CloseHandle(hIOCTL); - hIOCTL = NULL; - } + if (cdrom_ioctl_windows[id].hIOCTL) + { + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; + } } -static void ioctl_exit(void) +static void ioctl_exit(uint8_t id) { - ioctl_stop(); - ioctl_inited=0; - tocvalid=0; + ioctl_stop(id); + cdrom_ioctl[id].ioctl_inited=0; + cdrom_ioctl[id].tocvalid=0; } static CDROM ioctl_cdrom= { ioctl_ready, ioctl_medium_changed, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, + ioctl_audio_callback, + ioctl_audio_stop, + NULL, + NULL, + NULL, ioctl_getcurrentsubchannel, - ioctl_read_capacity, - ioctl_read_subchannel, - ioctl_read_header, - ioctl_read_disc_information, - ioctl_read_track_information, + ioctl_pass_through, ioctl_sector_data_type, - ioctl_readsector_raw, + NULL, ioctl_playaudio, - ioctl_seek, ioctl_load, ioctl_eject, ioctl_pause, diff --git a/src/cdrom-ioctl.h b/src/cdrom-ioctl.h index 3c1f54981..e39f12ddf 100644 --- a/src/cdrom-ioctl.h +++ b/src/cdrom-ioctl.h @@ -9,9 +9,9 @@ extern uint32_t cdrom_capacity; -extern int ioctl_open(char d); -extern void ioctl_reset(); +extern int ioctl_open(uint8_t id, char d); +extern void ioctl_reset(uint8_t id); -extern void ioctl_close(void); +extern void ioctl_close(uint8_t id); #endif /* ! CDROM_IOCTL_H */ diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index 7847f81af..bb3d7c361 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -10,104 +10,71 @@ static CDROM iso_cdrom; -uint32_t last_block = 0; -static uint64_t image_size = 0; -static int iso_inited = 0; -char iso_path[1024]; -void iso_close(void); -static FILE* iso_image; -static int iso_changed = 0; +int cdrom_iso_do_log = 1; -static uint32_t lba = 0; +void cdrom_iso_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_ISO_LOG + if (cdrom_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} -static uint32_t iso_cd_pos = 0, iso_cd_end = 0; +void iso_close(uint8_t id); -void iso_audio_callback(int16_t *output, int len) +void iso_audio_callback(uint8_t id, int16_t *output, int len) { memset(output, 0, len * 2); return; } -void iso_audio_stop() +void iso_audio_stop(uint8_t id) { - // pclog("iso_audio_stop stub\n"); + // cdrom_iso_log("iso_audio_stop stub\n"); } -static int get_track_nr(uint32_t pos) +static int iso_ready(uint8_t id) { - // pclog("get_track_nr stub\n"); - return 0; -} - -static void iso_playaudio(uint32_t pos, uint32_t len, int ismsf) -{ - // pclog("iso_playaudio stub\n"); - return; -} - -static void iso_pause(void) -{ - // pclog("iso_pause stub\n"); - return; -} - -static void iso_resume(void) -{ - // pclog("iso_resume stub\n"); - return; -} - -static void iso_stop(void) -{ - // pclog("iso_stop stub\n"); - return; -} - -static void iso_seek(uint32_t pos) -{ - // pclog("iso_seek stub\n"); - lba = pos; - return; -} - -static int iso_ready(void) -{ - if (strlen(iso_path) == 0) + if (strlen(cdrom_iso[id].iso_path) == 0) { return 0; } - if (old_cdrom_drive != cdrom_drive) + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) { - // old_cdrom_drive = cdrom_drive; return 1; } - if (iso_changed) + if (cdrom_iso[id].iso_changed) { - iso_changed = 0; + cdrom_iso[id].iso_changed = 0; return 1; } return 1; } -/* Always return 0, because there is no way to change the ISO without unmounting and remounting it. */ -static int iso_medium_changed(void) +static int iso_medium_changed(uint8_t id) { - if (strlen(iso_path) == 0) + if (strlen(cdrom_iso[id].iso_path) == 0) { return 0; } - if (old_cdrom_drive != cdrom_drive) + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) { - old_cdrom_drive = cdrom_drive; + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; return 1; } - if (iso_changed) + if (cdrom_iso[id].iso_changed) { - iso_changed = 0; + cdrom_iso[id].iso_changed = 0; return 1; } @@ -122,11 +89,11 @@ static void lba_to_msf(uint8_t *buf, int lba) buf[2] = lba % 75; } -static uint8_t iso_getcurrentsubchannel(uint8_t *b, int msf) +static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { long size; int pos=0; - if (strlen(iso_path) == 0) + if (strlen(cdrom_iso[id].iso_path) == 0) { return 0; } @@ -135,7 +102,7 @@ static uint8_t iso_getcurrentsubchannel(uint8_t *b, int msf) b[pos++]=0; b[pos++]=0; - int32_t temp = lba; + int32_t temp = cdrom[id].seek_pos; if (msf) { memset(&(b[pos]), 0, 8); @@ -156,48 +123,35 @@ static uint8_t iso_getcurrentsubchannel(uint8_t *b, int msf) b[pos++] = temp; } - return 0x13; + return 0x15; } -static void iso_eject(void) +static void iso_eject(uint8_t id) { - // pclog("iso_eject stub\n"); + // cdrom_iso_log("iso_eject stub\n"); } -static void iso_load(void) +static void iso_load(uint8_t id) { - // pclog("iso_load stub\n"); + // cdrom_iso_log("iso_load stub\n"); } -static int iso_sector_data_type(int sector, int ismsf) +static int iso_sector_data_type(uint8_t id, int sector, int ismsf) { return 2; /* Always Mode 1 */ } -static void iso_readsector_raw(uint8_t *b, int sector, int ismsf) +static void iso_readsector(uint8_t id, uint8_t *b, int sector) { uint32_t temp; uint64_t file_pos = sector; - if (!cdrom_drive) return; + if (!cdrom_drives[id].host_drive) return; file_pos <<= 11; memset(b, 0, 2856); - if (ismsf) - { - int m = (sector >> 16) & 0xff; - int s = (sector >> 8) & 0xff; - int f = sector & 0xff; - sector = (m * 60 * 75) + (s * 75) + f; - if (sector < 150) - { - memset(b, 0, 2856); - return; - } - sector -= 150; - } - iso_image = fopen(iso_path, "rb"); - fseeko64(iso_image, file_pos, SEEK_SET); - fread(b + 16, 2048, 1, iso_image); - fclose(iso_image); + cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); + fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); + fclose(cdrom_iso[id].iso_image); /* sync bytes */ b[0] = 0; @@ -213,7 +167,185 @@ static void iso_readsector_raw(uint8_t *b, int sector, int ismsf) memset(b, 0, 392); } -static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single) +typedef struct __attribute__((packed)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((packed)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((packed)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2352]; +} sector_data_t; + +typedef struct __attribute__((packed)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((packed)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; + +static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + int real_sector_type; + uint8_t *b; + uint8_t *temp_b; + int is_audio; + int real_pos; + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + memset(cdrom_sector_buffer.buffer, 0, 2856); + + if ((cdrom_sector_type == 1) || (cdrom_sector_type > 2)) + { + if (cdrom_sector_type == 1) + { + cdrom_iso_log("CD-ROM %i: Attempting to read an audio sector from an ISO\n", id); + } + if (cdrom_sector_type >= 2) + { + cdrom_iso_log("CD-ROM %i: Attempting to read a non-mode 1 data sector from an ISO\n", id); + } + return 0; + } + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_iso_log("CD-ROM %i: 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_iso_log("CD-ROM %i: Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_iso_log("CD-ROM %i: Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_iso_log("CD-ROM %i: EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + iso_readsector(id, cdrom_sector_buffer.buffer, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + if (cdrom_sector_flags & 0x20) /* Header */ + { + memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + if (cdrom_sector_flags & 0x10) /* User data */ + { + memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + + cdrom_iso_log("CD-ROM sector size: %i (%i, %i) [%04X]\n", cdrom_sector_size, cdrom_sector_type, real_sector_type, cdrom_sector_flags); + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); + cdrom_sector_size += 96; + } + + memcpy(buffer, b, cdrom_sector_size); + + *len = cdrom_sector_size; + + return 1; +} + +static int iso_readtoc(uint8_t id, unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single) { uint8_t *q; int len; @@ -245,16 +377,16 @@ static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, i *q++ = 0x16; /* ADR, control */ *q++ = 0xaa; /* track number */ *q++ = 0; /* reserved */ - last_block = image_size >> 11; + cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; if (msf) { *q++ = 0; /* reserved */ - lba_to_msf(q, last_block); + lba_to_msf(q, cdrom_iso[id].last_block); q += 3; } else { - *q++ = last_block >> 24; - *q++ = last_block >> 16; - *q++ = last_block >> 8; - *q++ = last_block; + *q++ = cdrom_iso[id].last_block >> 24; + *q++ = cdrom_iso[id].last_block >> 16; + *q++ = cdrom_iso[id].last_block >> 8; + *q++ = cdrom_iso[id].last_block; } len = q - buf; if (len > maxlen) @@ -266,7 +398,7 @@ static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, i return len; } -static int iso_readtoc_session(unsigned char *buf, int msf, int maxlen) +static int iso_readtoc_session(uint8_t id, unsigned char *buf, int msf, int maxlen) { uint8_t *q; @@ -290,7 +422,7 @@ static int iso_readtoc_session(unsigned char *buf, int msf, int maxlen) return 12; } -static int iso_readtoc_raw(unsigned char *buf, int msf, int maxlen) +static int iso_readtoc_raw(uint8_t id, unsigned char *buf, int msf, int maxlen) { uint8_t *q; int len; @@ -330,20 +462,20 @@ static int iso_readtoc_raw(unsigned char *buf, int msf, int maxlen) *q++ = 0; /* min */ *q++ = 0; /* sec */ *q++ = 0; /* frame */ - last_block = image_size >> 11; + cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; /* this is raw, must be msf */ if (msf) { *q++ = 0; /* reserved */ - lba_to_msf(q, last_block); + lba_to_msf(q, cdrom_iso[id].last_block); q += 3; } else { - *q++ = (last_block >> 24) & 0xff; - *q++ = (last_block >> 16) & 0xff; - *q++ = (last_block >> 8) & 0xff; - *q++ = last_block & 0xff; + *q++ = (cdrom_iso[id].last_block >> 24) & 0xff; + *q++ = (cdrom_iso[id].last_block >> 16) & 0xff; + *q++ = (cdrom_iso[id].last_block >> 8) & 0xff; + *q++ = cdrom_iso[id].last_block & 0xff; } *q++ = 1; /* session number */ @@ -378,72 +510,71 @@ static int iso_readtoc_raw(unsigned char *buf, int msf, int maxlen) return len; } -static uint32_t iso_size() +static uint32_t iso_size(uint8_t id) { uint64_t iso_size; - iso_image = fopen(iso_path, "rb"); - fseeko64(iso_image, 0, SEEK_END); - iso_size = ftello64(iso_image); + cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + fseeko64(cdrom_iso[id].iso_image, 0, SEEK_END); + iso_size = ftello64(cdrom_iso[id].iso_image); iso_size >>= 11; - fclose(iso_image); + fclose(cdrom_iso[id].iso_image); return (uint32_t) (iso_size); } -static int iso_status() +static int iso_status(uint8_t id) { - if (!(iso_ready()) && (cdrom_drive != 200)) return CD_STATUS_EMPTY; + if (!(iso_ready(id)) && (cdrom_drives[id].host_drive != 200)) return CD_STATUS_EMPTY; return CD_STATUS_DATA_ONLY; } -void iso_reset() +void iso_reset(uint8_t id) { } -int iso_open(char *fn) +int iso_open(uint8_t id, char *fn) { struct stat st; - if (strcmp(fn, iso_path) != 0) + if (strcmp(fn, cdrom_iso[id].iso_path) != 0) { - iso_changed = 1; + cdrom_iso[id].iso_changed = 1; } /* Make sure iso_changed stays when changing from ISO to another ISO. */ - if (!iso_inited && (cdrom_drive != 200)) iso_changed = 0; - if (!iso_inited || iso_changed) + if (!cdrom_iso[id].iso_inited && (cdrom_drives[id].host_drive != 200)) cdrom_iso[id].iso_changed = 0; + if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) { - sprintf(iso_path, "%s", fn); - // pclog("Path is %s\n", iso_path); + sprintf(cdrom_iso[id].iso_path, "%s", fn); + // cdrom_iso_log("Path is %s\n", cdrom_iso[id].iso_path); } - iso_image = fopen(iso_path, "rb"); - cdrom = &iso_cdrom; - if (!iso_inited || iso_changed) + cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + cdrom_drives[id].handler = &iso_cdrom; + if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) { - if (!iso_inited) iso_inited = 1; - fclose(iso_image); + if (!cdrom_iso[id].iso_inited) cdrom_iso[id].iso_inited = 1; + fclose(cdrom_iso[id].iso_image); } - stat(iso_path, &st); - image_size = st.st_size; + stat(cdrom_iso[id].iso_path, &st); + cdrom_iso[id].image_size = st.st_size; return 0; } -void iso_close(void) +void iso_close(uint8_t id) { - if (iso_image) fclose(iso_image); - memset(iso_path, 0, 1024); + if (cdrom_iso[id].iso_image) fclose(cdrom_iso[id].iso_image); + memset(cdrom_iso[id].iso_path, 0, 1024); } -static void iso_exit(void) +static void iso_exit(uint8_t id) { - // iso_stop(); - iso_inited = 0; + cdrom_iso[id].iso_inited = 0; } -static int iso_is_track_audio(uint32_t pos, int ismsf) +static int iso_is_track_audio(uint8_t id, uint32_t pos, int ismsf) { return 0; } @@ -452,26 +583,23 @@ static CDROM iso_cdrom = { iso_ready, iso_medium_changed, + NULL, + NULL, iso_readtoc, iso_readtoc_session, iso_readtoc_raw, iso_getcurrentsubchannel, NULL, - NULL, - NULL, - NULL, - NULL, iso_sector_data_type, iso_readsector_raw, - iso_playaudio, - iso_seek, + NULL, iso_load, iso_eject, - iso_pause, - iso_resume, + NULL, + NULL, iso_size, iso_status, iso_is_track_audio, - iso_stop, + NULL, iso_exit }; diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h index 4dbcfca2e..c16ea0ebb 100644 --- a/src/cdrom-iso.h +++ b/src/cdrom-iso.h @@ -7,13 +7,9 @@ /* this header file lists the functions provided by various platform specific cdrom-ioctl files */ -extern uint32_t last_block; - -extern char iso_path[1024]; +extern int iso_open(uint8_t id, char *fn); +extern void iso_reset(uint8_t id); -extern int iso_open(char *fn); -extern void iso_reset(); - -extern void iso_close(void); +extern void iso_close(uint8_t id); #endif /* ! CDROM_ISO_H */ diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 76ec0ab3c..6e886ed27 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -5,121 +5,97 @@ #include "cdrom.h" #include "cdrom-ioctl.h" -int cdrom_drive; - static CDROM null_cdrom; -void cdrom_null_audio_callback(int16_t *output, int len) -{ - memset(output, 0, len * 2); -} - -void cdrom_null_audio_stop() -{ -} - -static void null_playaudio(uint32_t pos, uint32_t len, int ismsf) -{ -} - -static void null_pause(void) -{ -} - -static void null_resume(void) -{ -} - -static void null_stop(void) -{ -} - -static void null_seek(uint32_t pos) -{ -} - -static int null_ready(void) +static int null_ready(uint8_t id) { return 0; } /* Always return 0, the contents of a null CD-ROM drive never change. */ -static int null_medium_changed(void) +static int null_medium_changed(uint8_t id) { return 0; } -static uint8_t null_getcurrentsubchannel(uint8_t *b, int msf) +static uint8_t null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { return 0x13; } -static void null_eject(void) +static void null_eject(uint8_t id) { } -static void null_load(void) +static void null_load(uint8_t id) { } -static int null_sector_data_type(int sector, int ismsf) +static int null_sector_data_type(uint8_t id, int sector, int ismsf) { return 0; } -static void null_readsector_raw(uint8_t *b, int sector, int ismsf) +static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) { + *len = 0; + return 0; } -static int null_read_track_information(uint8_t *in_cdb, uint8_t *b) +static int null_read_track_information(uint8_t id, uint8_t *in_cdb, uint8_t *b) { return 0; } -static int null_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +static int null_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { return 0; } -static int null_readtoc_session(unsigned char *b, int msf, int maxlen) +static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) { return 0; } -static int null_readtoc_raw(unsigned char *b, int msf, int maxlen) +static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) { return 0; } -static uint32_t null_size() +static uint32_t null_size(uint8_t id) { return 0; } -static int null_status() +static int null_status(uint8_t id) { return CD_STATUS_EMPTY; } -void cdrom_null_reset() +void cdrom_null_reset(uint8_t id) { } -int cdrom_null_open(char d) +int cdrom_null_open(uint8_t id, char d) { - cdrom = &null_cdrom; + cdrom_drives[id].handler = &null_cdrom; return 0; } -void null_close(void) +void null_close(uint8_t id) { } -static void null_exit(void) +static void null_exit(uint8_t id) { } -static int null_is_track_audio(uint32_t pos, int ismsf) +static int null_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + return 0; +} + +static int null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) { return 0; } @@ -128,26 +104,23 @@ static CDROM null_cdrom = { null_ready, null_medium_changed, + NULL, + NULL, null_readtoc, null_readtoc_session, null_readtoc_raw, null_getcurrentsubchannel, - NULL, - NULL, - NULL, - NULL, - NULL, + null_pass_through, null_sector_data_type, null_readsector_raw, - null_playaudio, - null_seek, + NULL, null_load, null_eject, - null_pause, - null_resume, + NULL, + NULL, null_size, null_status, null_is_track_audio, - null_stop, + NULL, null_exit }; diff --git a/src/cdrom-null.h b/src/cdrom-null.h index 6900f3d23..7cc595089 100644 --- a/src/cdrom-null.h +++ b/src/cdrom-null.h @@ -7,8 +7,8 @@ /* this header file lists the functions provided by various platform specific cdrom-ioctl files */ -extern int cdrom_null_open(char d); -extern void cdrom_null_reset(); -extern void null_close(); +extern int cdrom_null_open(uint8_t id, char d); +extern void cdrom_null_reset(uint8_t id); +extern void null_close(uint8_t id); #endif /* ! CDROM_IOCTL_H */ diff --git a/src/cdrom.c b/src/cdrom.c new file mode 100644 index 000000000..da0f2b65a --- /dev/null +++ b/src/cdrom.c @@ -0,0 +1,2867 @@ +/* CD-ROM emulation, used by both ATAPI and SCSI */ + +#include +#include +#include + +#include "86box.h" +#include "cdrom.h" +#include "ibm.h" +#include "ide.h" +#include "scsi.h" +#include "timer.h" + +/* Bits of 'status' */ +#define ERR_STAT 0x01 +#define DRQ_STAT 0x08 /* Data request */ +#define DSC_STAT 0x10 +#define SERVICE_STAT 0x10 +#define READY_STAT 0x40 +#define BUSY_STAT 0x80 + +/* Bits of 'error' */ +#define ABRT_ERR 0x04 /* Command aborted */ +#define MCR_ERR 0x08 /* Media change request */ + +#define MODE_SELECT_PHASE_IDLE 0 +#define MODE_SELECT_PHASE_HEADER 1 +#define MODE_SELECT_PHASE_PAGE_HEADER 2 +#define MODE_SELECT_PHASE_PAGE 3 + +cdrom_t cdrom[CDROM_NUM]; +cdrom_drive_t cdrom_drives[CDROM_NUM]; +uint8_t atapi_cdrom_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +uint8_t scsi_cdrom_drives[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + +static struct __attribute__((__packed__)) +{ + uint8_t opcode; + uint8_t polled; + uint8_t reserved2[2]; + uint8_t class; + uint8_t reserved3[2]; + uint16_t len; + uint8_t control; +} *gesn_cdb; + +static struct __attribute__((__packed__)) +{ + uint16_t len; + uint8_t notification_class; + uint8_t supported_events; +} *gesn_event_header; + +/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ +uint8_t cdrom_command_flags[0x100] = +{ + [GPCMD_TEST_UNIT_READY] = IMPLEMENTED | CHECK_READY | NONDATA, + [GPCMD_REZERO_UNIT] = IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, + [GPCMD_REQUEST_SENSE] = IMPLEMENTED | ALLOW_UA, + [GPCMD_READ_6] = IMPLEMENTED | CHECK_READY, + [GPCMD_SEEK_6] = IMPLEMENTED | CHECK_READY | NONDATA, + [GPCMD_INQUIRY] = IMPLEMENTED | ALLOW_UA, + [GPCMD_VERIFY_6] = IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, + [GPCMD_MODE_SELECT_6] = IMPLEMENTED, + [GPCMD_MODE_SENSE_6] = IMPLEMENTED, + [GPCMD_START_STOP_UNIT] = IMPLEMENTED | CHECK_READY, + [GPCMD_PREVENT_REMOVAL] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_CDROM_CAPACITY] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_10] = IMPLEMENTED | CHECK_READY, + [GPCMD_SEEK_10] = IMPLEMENTED | CHECK_READY | NONDATA, + [GPCMD_VERIFY_10] = IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, + [GPCMD_READ_SUBCHANNEL] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_TOC_PMA_ATIP] = IMPLEMENTED | CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + NOTE: The ATAPI reference says otherwise, but I think this is a question of + interpreting things right - the UNIT ATTENTION condition we have here + is a tradition from not ready to ready, by definition the drive + eventually becomes ready, make the condition go away. */ + [GPCMD_READ_HEADER] = IMPLEMENTED | CHECK_READY, + [GPCMD_PLAY_AUDIO_10] = IMPLEMENTED | CHECK_READY, + [GPCMD_GET_CONFIGURATION] = IMPLEMENTED | ALLOW_UA, + [GPCMD_PLAY_AUDIO_MSF] = IMPLEMENTED | CHECK_READY, + [GPCMD_PLAY_AUDIO_TRACK_INDEX] = IMPLEMENTED | CHECK_READY, + [GPCMD_GET_EVENT_STATUS_NOTIFICATION] = IMPLEMENTED | ALLOW_UA, + [GPCMD_PAUSE_RESUME] = IMPLEMENTED | CHECK_READY, + [GPCMD_STOP_PLAY_SCAN] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_DISC_INFORMATION] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_TRACK_INFORMATION] = IMPLEMENTED | CHECK_READY, + [GPCMD_MODE_SELECT_10] = IMPLEMENTED, + [GPCMD_MODE_SENSE_10] = IMPLEMENTED, + [GPCMD_PLAY_AUDIO_12] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_12] = IMPLEMENTED | CHECK_READY, + [GPCMD_READ_DVD_STRUCTURE] = IMPLEMENTED | CHECK_READY, + [GPCMD_VERIFY_12] = IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, + [GPCMD_PLAY_CD_OLD] = IMPLEMENTED | CHECK_READY | ATAPI_ONLY, + [GPCMD_READ_CD_OLD] = IMPLEMENTED | CHECK_READY | ATAPI_ONLY, + [GPCMD_READ_CD_MSF] = IMPLEMENTED | CHECK_READY, + [GPCMD_SCAN] = IMPLEMENTED | CHECK_READY, + [GPCMD_SET_SPEED] = IMPLEMENTED, + [GPCMD_PLAY_CD] = IMPLEMENTED | CHECK_READY, + [GPCMD_MECHANISM_STATUS] = IMPLEMENTED, + [GPCMD_READ_CD] = IMPLEMENTED | CHECK_READY, + [GPCMD_SEND_DVD_STRUCTURE] = IMPLEMENTED | CHECK_READY, + [GPCMD_SCAN_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, + [GPCMD_SET_SPEED_ALT] = IMPLEMENTED | SCSI_ONLY +}; + +uint8_t cdrom_mode_sense_page_flags[CDROM_NUM][0x40] = +{ + { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, + [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, + [GPMODE_ALL_PAGES] = IMPLEMENTED }, + { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, + [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, + [GPMODE_ALL_PAGES] = IMPLEMENTED }, + { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, + [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, + [GPMODE_ALL_PAGES] = IMPLEMENTED }, + { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_PAGE] = IMPLEMENTED, + [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, + [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, + [GPMODE_ALL_PAGES] = IMPLEMENTED } +}; + +const uint8_t cdrom_mode_sense_pages_default[CDROM_NUM][0x40][0x40] = +{ + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } +}; + +uint8_t cdrom_mode_sense_pages_changeable[CDROM_NUM][0x40][0x40] = +{ + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } +}; + +uint8_t cdrom_mode_sense_pages_saved[CDROM_NUM][0x40][0x40] = +{ + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } +}; + +int cdrom_do_log = 1; + +void cdrom_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_LOG + if (cdrom_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +int cdrom_mode_select_terminate(uint8_t id, int force); + +int find_cdrom_for_channel(uint8_t channel) +{ + uint8_t i = 0; + + for (i = 0; i < CDROM_NUM; i++) + { + if (!cdrom_drives[i].bus_type && (cdrom_drives[i].ide_channel == channel)) + { + return i; + } + } + return 0xff; +} + +void cdrom_init(int id, int cdb_len_setting, int bus_type); + +void build_atapi_cdrom_map() +{ + uint8_t i = 0; + + memset(atapi_cdrom_drives, 0xff, 8); + + for (i = 0; i < 8; i++) + { + atapi_cdrom_drives[i] = find_cdrom_for_channel(i); + if (atapi_cdrom_drives[i] != 0xff) + { + cdrom_init(atapi_cdrom_drives[i], 12, 0); + } + } +} + +int find_cdrom_for_scsi_id(uint8_t scsi_id) +{ + uint8_t i = 0; + + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type && (cdrom_drives[i].scsi_device_id == scsi_id)) + { + return i; + } + } + return 0xff; +} + +void build_scsi_cdrom_map() +{ + uint8_t i = 0; + + memset(scsi_cdrom_drives, 0xff, 16); + + for (i = 0; i < 16; i++) + { + scsi_cdrom_drives[i] = find_cdrom_for_scsi_id(i); + if (scsi_cdrom_drives[i] != 0xff) + { + cdrom_init(scsi_cdrom_drives[i], 12, 1); + } + } +} + +void cdrom_set_cdb_len(int id, int cdb_len) +{ + cdrom[id].cdb_len = cdb_len; +} + +void cdrom_reset_cdb_len(int id) +{ + cdrom[id].cdb_len = cdrom[id].cdb_len_setting ? 16 : 12; +} + +void cdrom_set_signature(int id) +{ + cdrom[id].phase = 1; + cdrom[id].request_length = 0xEB14; +} + +void cdrom_init(int id, int cdb_len_setting, int bus_type) +{ + if (id >= CDROM_NUM) + { + return; + } + memset(&(cdrom[id]), 0, sizeof(cdrom_t)); + cdrom[id].requested_blocks = 1; + if (cdb_len_setting <= 1) + { + cdrom[id].cdb_len_setting = cdb_len_setting; + } + cdrom_reset_cdb_len(id); + cdrom_mode_select_terminate(id, 1); + cdrom[id].cd_status = CD_STATUS_EMPTY; + cdrom[id].sense[0] = 0xf0; + cdrom[id].sense[7] = 10; + cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : 3; + if (!cdrom_drives[id].bus_type) + { + cdrom_set_signature(id); + cdrom_drives[id].check_on_execution = 1; + cdrom_drives[id].max_blocks_at_once = 1; + } + else + { + cdrom_drives[id].check_on_execution = scsi_model ? 0 : 1; + cdrom_drives[id].max_blocks_at_once = 85; + } + cdrom[id].status = READY_STAT | DSC_STAT; + cdrom[id].pos = 0; + cdrom[id].packet_status = 0xff; + cdrom_sense_key = cdrom_asc = cdrom_ascq = cdrom[id].unit_attention = 0; + cdrom[id].cdb_len_setting = 0; + cdrom[id].cdb_len = 12; +} + +int cdrom_supports_pio(int id) +{ + return (cdrom_drives[id].bus_mode & 1); +} + +int cdrom_supports_dma(int id) +{ + return (cdrom_drives[id].bus_mode & 2); +} + +/* Returns: 0 for none, 1 for PIO, 2 for DMA. */ +int cdrom_current_mode(int id) +{ + if (!cdrom_supports_pio(id) && !cdrom_supports_dma(id)) + { + return 0; + } + if (cdrom_supports_pio(id) && !cdrom_supports_dma(id)) + { + return 1; + } + if (!cdrom_supports_pio(id) && cdrom_supports_dma(id)) + { + return 2; + } + if (cdrom_supports_pio(id) && cdrom_supports_dma(id)) + { + return (cdrom[id].features & 1) ? 2 : 1; + } +} + +/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ +int cdrom_CDROM_PHASE_to_scsi(uint8_t id) +{ + if (cdrom[id].status & ERR_STAT) + { + return SCSI_STATUS_CHECK_CONDITION; + } + else + { + return SCSI_STATUS_OK; + } +} + +/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ +int cdrom_atapi_phase_to_scsi(uint8_t id) +{ + if (cdrom[id].status & 8) + { + switch (cdrom[id].phase & 3) + { + case 0: + return 0; + case 1: + return 2; + case 2: + return 1; + case 3: + return 7; + } + } + else + { + if ((cdrom[id].phase & 3) == 3) + { + return 3; + } + else + { + /* Translate reserved ATAPI phase to reserved SCSI phase. */ + return 4; + } + } +} + +int cdrom_lba_to_msf_accurate(int lba) +{ + int temp_pos; + int m, s, f; + + temp_pos = lba + 150; + f = temp_pos % 75; + temp_pos -= f; + temp_pos /= 75; + s = temp_pos % 60; + temp_pos -= s; + temp_pos /= 60; + m = temp_pos; + + return ((m << 16) | (s << 8) | f); +} + +uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel) +{ + return cdrom_mode_sense_pages_saved[id][GPMODE_CDROM_AUDIO_PAGE][channel ? 10 : 8]; +} + +uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel) +{ + return cdrom_mode_sense_pages_saved[id][GPMODE_CDROM_AUDIO_PAGE][channel ? 11 : 9]; +} + +void cdrom_mode_sense_load(uint8_t id) +{ + FILE *f; + switch(id) + { + case 0: + f = fopen(nvr_concat("cdrom_1_mode_sense.bin"), "rb"); + break; + case 1: + f = fopen(nvr_concat("cdrom_2_mode_sense.bin"), "rb"); + break; + case 2: + f = fopen(nvr_concat("cdrom_3_mode_sense.bin"), "rb"); + break; + case 3: + f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "rb"); + break; + } + if (!f) + { + return; + } + fread(cdrom_mode_sense_pages_saved[id][GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); + fclose(f); +} + +void cdrom_mode_sense_save(uint8_t id) +{ + FILE *f; + switch(id) + { + case 0: + f = fopen(nvr_concat("cdrom_1_mode_sense.bin"), "wb"); + break; + case 1: + f = fopen(nvr_concat("cdrom_2_mode_sense.bin"), "wb"); + break; + case 2: + f = fopen(nvr_concat("cdrom_3_mode_sense.bin"), "wb"); + break; + case 3: + f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "wb"); + break; + } + if (!f) + { + return; + } + fwrite(cdrom_mode_sense_pages_saved[id][GPMODE_CDROM_AUDIO_PAGE], 1, 0x10, f); + fclose(f); +} + +int cdrom_mode_select_init(uint8_t id, uint8_t command, uint16_t pl_length, uint8_t do_save) +{ + switch(command) + { + case GPCMD_MODE_SELECT_6: + cdrom[id].current_page_len = 4; + break; + case GPCMD_MODE_SELECT_10: + cdrom[id].current_page_len = 8; + break; + default: + cdrom_log("CD-ROM %i: Attempting to initialize MODE SELECT with unrecognized command: %02X\n", id, command); + return -1; + } + if (pl_length == 0) + { + cdrom_log("CD-ROM %i: Attempting to initialize MODE SELECT with zero parameter list length: %02X\n", id, command); + return -2; + } + cdrom[id].current_page_pos = 0; + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_HEADER; + cdrom[id].total_length = pl_length; + cdrom[id].written_length = 0; + cdrom[id].do_page_save = do_save; + return 1; +} + +int cdrom_mode_select_terminate(uint8_t id, int force) +{ + if (((cdrom[id].written_length >= cdrom[id].total_length) || force) && (cdrom[id].mode_select_phase != MODE_SELECT_PHASE_IDLE)) + { + cdrom_log("CD-ROM %i: MODE SELECT terminate: %i\n", id, force); + if (!force && cdrom[id].do_page_save && (cdrom_mode_sense_pages_default[id][cdrom[id].current_page_pos][0] & 0x80)) + { + cdrom_mode_sense_save(id); + } + cdrom[id].current_page_pos = cdrom[id].current_page_len = 0; + cdrom[id].total_length = cdrom[id].written_length = 0; + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_IDLE; + if (force) + { + cdrom_mode_sense_load(id); + } + return 1; + } + else + { + return 0; + } +} + +int cdrom_mode_select_header(uint8_t id) +{ + cdrom[id].current_page_pos++; + if (cdrom[id].current_page_pos >= cdrom[id].current_page_len) + { + cdrom[id].current_page_pos = 0; + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER; + } + return 1; +} + +static void cdrom_invalid_field_pl(uint8_t id); + +int cdrom_mode_select_page_header(uint8_t id, uint8_t val) +{ + if (cdrom[id].current_page_pos == 0) + { + cdrom[id].current_page_code = val & 0x3f; + if (cdrom_mode_sense_page_flags[id][cdrom[id].current_page_code] != IMPLEMENTED) + { + cdrom_log("CD-ROM %i: Trying to modify an unimplemented page: %02X\n", id, cdrom[id].current_page_code); + cdrom_mode_select_terminate(id, 1); + cdrom_invalid_field_pl(id); + } + cdrom[id].current_page_pos++; + } + else if (cdrom[id].current_page_pos == 1) + { + cdrom[id].current_page_pos = 0; + cdrom[id].current_page_len = val; + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_PAGE; + } + return 1; +} + +int cdrom_mode_select_page(uint8_t id, uint8_t val) +{ + if (cdrom_mode_sense_pages_changeable[id][cdrom[id].current_page_code][cdrom[id].current_page_pos + 2] != 0xFF) + { + if (val != cdrom_mode_sense_pages_saved[id][cdrom[id].current_page_code][cdrom[id].current_page_pos + 2]) + { + /* Trying to change an unchangeable value. */ + cdrom_log("CD-ROM %i: Trying to change an unchangeable value: [%02X][%02X] = %02X (new: %02X)\n", id, cdrom[id].current_page_code, cdrom[id].current_page_pos + 2, cdrom_mode_sense_pages_saved[id][cdrom[id].current_page_code][cdrom[id].current_page_pos + 2], val); + cdrom_mode_select_terminate(id, 1); + cdrom_invalid_field_pl(id); + return 0; + } + } + else + { + if (cdrom[id].current_page_code == 0xE) + { + if ((cdrom[id].current_page_pos == 6) || (cdrom[id].current_page_pos == 8)) + { + if (val > 3) + { + /* Trying to set an unsupported audio channel. */ + cdrom_log("CD-ROM %i: Trying to set an unsupported value: [%02X][%02X] = %02X (new: %02X)\n", id, cdrom[id].current_page_code, cdrom[id].current_page_pos, cdrom_mode_sense_pages_saved[id][cdrom[id].current_page_code][cdrom[id].current_page_pos + 2], val); + return 0; + } + } + } + cdrom_mode_sense_pages_saved[id][cdrom[id].current_page_code][cdrom[id].current_page_pos + 2] = val; + } + cdrom[id].current_page_pos++; + if (cdrom[id].current_page_pos >= cdrom[id].current_page_len) + { + cdrom[id].current_page_pos = 0; + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER; + } + return 1; +} + +static void cdrom_command_complete(uint8_t id); + +int cdrom_mode_select_write(uint8_t id, uint8_t val) +{ + int ret = 0; + int ret2 = 0; + + if (id > CDROM_NUM) + { + cdrom_log("MODE SELECT: attempted write to wrong CD-ROM drive\n", val); + return -6; + } + + if (cdrom[id].total_length == 0) + { + cdrom_log("CD-ROM %i: MODE SELECT: attempted write when not initialized (%02X)\n", id, val); + return -3; + } + + cdrom[id].written_length++; + + switch (cdrom[id].mode_select_phase) + { + case MODE_SELECT_PHASE_IDLE: + cdrom_log("CD-ROM %i: MODE SELECT idle (%02X)\n", id, val); + ret = 1; + break; + case MODE_SELECT_PHASE_HEADER: + cdrom_log("CD-ROM %i: MODE SELECT header (%02X)\n", id, val); + ret = cdrom_mode_select_header(id); + break; + case MODE_SELECT_PHASE_PAGE_HEADER: + cdrom_log("CD-ROM %i: MODE SELECT page header (%02X)\n", id, val); + ret = cdrom_mode_select_page_header(id, val); + break; + case MODE_SELECT_PHASE_PAGE: + cdrom_log("CD-ROM %i: MODE SELECT page (%02X)\n", id, val); + ret = cdrom_mode_select_page(id, val); + break; + default: + cdrom_log("CD-ROM %i: MODE SELECT unknown phase (%02X)\n", id, val); + ret = -4; + break; + } + + /* On termination, override the return value, but only if it is 1. */ + ret2 = cdrom_mode_select_terminate(id, 0); + if (ret2) + { + cdrom_command_complete(id); + } + if (ret2 && (ret == 1)) + { + ret = -5; + } + + return ret; +} + +/*SCSI Mode Sense 6/10*/ +uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) +{ + switch (page_control) + { + case 0: + case 3: + return cdrom_mode_sense_pages_saved[id][page][pos]; + break; + case 1: + return cdrom_mode_sense_pages_changeable[id][page][pos]; + break; + case 2: + return cdrom_mode_sense_pages_default[id][page][pos]; + break; + } +} + +uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type) +{ + uint8_t page_control = (type >> 6) & 3; + + int i = 0; + int j = 0; + + uint8_t msplen; + + type &= 0x3f; + + for (i = 0; i < 0x40; i++) + { + if ((type == GPMODE_ALL_PAGES) || (type == i)) + { + if (cdrom_mode_sense_page_flags[id][i] == IMPLEMENTED) + { + buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 0); + msplen = cdrom_mode_sense_read(id, page_control, i, 1); + buf[pos++] = msplen; + cdrom_log("CD-ROM %i: MODE SENSE: Page [%02X] length %i\n", id, i, msplen); + for (j = 0; j < msplen; j++) + { + buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 2 + j); + } + } + } + } + + return pos; +} + +void cdrom_update_request_length(uint8_t id, int len, int block_len) +{ + /* For media access commands, make sure the requested DRQ length matches the block length. */ + switch (cdrom[id].current_cdb[0]) + { + case 0x08: + case 0x28: + case 0xa8: + case 0xb9: + case 0xbe: + if (cdrom[id].request_length < block_len) + { + cdrom[id].request_length = block_len; + } + /* Make sure we respect the limit of how many blocks we can transfer at once. */ + if (cdrom[id].requested_blocks > cdrom_drives[id].max_blocks_at_once) + { + cdrom[id].requested_blocks = cdrom_drives[id].max_blocks_at_once; + } + cdrom[id].block_total = (cdrom[id].requested_blocks * block_len); + if (len > cdrom[id].block_total) + { + len = cdrom[id].block_total; + } + if (cdrom[id].packet_len == 0) + { + cdrom[id].packet_len = cdrom[id].sector_len * block_len; + } + cdrom_log("Packet length now: %i (%i * %i)\n", cdrom[id].packet_len, cdrom[id].sector_len, block_len); + break; + default: + cdrom[id].packet_len = len; + break; + } + /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ + if ((cdrom[id].request_length & 1) && (cdrom[id].request_length < len)) + { + cdrom[id].request_length &= 0xfffe; + } + /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ + if (len <= cdrom[id].request_length) + { + cdrom[id].request_length = len; + } + return; +} + +static int cdrom_is_media_access(uint8_t id) +{ + switch (cdrom[id].current_cdb[0]) + { + case 0x08: + case 0x28: + case 0xa8: + case 0xb9: + case 0xbe: + return 1; + default: + return 0; + } +} + +static void cdrom_command_common(uint8_t id) +{ + cdrom[id].status = BUSY_STAT; + cdrom[id].phase = 1; + cdrom[id].pos = 0; + cdrom[id].callback = 60 * CDROM_TIME; +} + +static void cdrom_command_complete(uint8_t id) +{ + cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom_command_common(id); +} + +static void cdrom_command_read(uint8_t id) +{ + cdrom[id].packet_status = CDROM_PHASE_DATA_IN; + cdrom_command_common(id); + cdrom[id].total_read = 0; +} + +static void cdrom_command_read_dma(uint8_t id) +{ + cdrom[id].packet_status = CDROM_PHASE_DATA_IN_DMA; + cdrom_command_common(id); + cdrom[id].total_read = 0; +} + +static void cdrom_command_write(uint8_t id) +{ + cdrom[id].packet_status = CDROM_PHASE_DATA_OUT; + cdrom_command_common(id); +} + +static void cdrom_command_write_dma(uint8_t id) +{ + cdrom[id].packet_status = CDROM_PHASE_DATA_OUT_DMA; + cdrom_command_common(id); +} + +static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) +{ + cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, cdrom[id].current_cdb[0], len, block_len, alloc_len, direction, cdrom[id].request_length); + cdrom[id].pos=0; + if (alloc_len >= 0) + { + if (alloc_len < len) + { + len = alloc_len; + } + } + if ((len == 0) || (cdrom_current_mode(id) == 0)) + { + cdrom_command_complete(id); + } + else + { + if (cdrom_current_mode(id) == 2) + { + if (cdrom_drives[id].bus_type) + { + if (cdrom_is_media_access(id)) + { + SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len; + } + else + { + SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len; + } + } + if (direction == 0) + { + cdrom_command_read_dma(id); + } + else + { + cdrom_command_write_dma(id); + } + } + else + { + cdrom_update_request_length(id, len, block_len); + if (direction == 0) + { + cdrom_command_read(id); + } + else + { + cdrom_command_write(id); + } + } + } + + cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", id, cdrom[id].packet_status, cdrom[id].request_length, cdrom[id].packet_len, cdrom[id].pos, cdrom[id].phase); +} + +static void cdrom_sense_clear(int id, int command, int ignore_ua) +{ + if ((cdrom_sense_key == SENSE_UNIT_ATTENTION) || ignore_ua) + { + cdrom[id].previous_command = command; + cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; + } +} + +static void cdrom_cmd_error(uint8_t id) +{ + cdrom[id].error = ((cdrom_sense_key & 0xf) << 4) | ABRT_ERR; + if (cdrom[id].unit_attention) + { + cdrom[id].error |= MCR_ERR; + } + cdrom[id].status = READY_STAT | ERR_STAT; + cdrom[id].phase = 3; + cdrom[id].packet_status = 0x80; + cdrom[id].callback = 50 * CDROM_TIME; +} + +static void cdrom_unit_attention(uint8_t id) +{ + cdrom[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + if (cdrom[id].unit_attention) + { + cdrom[id].error |= MCR_ERR; + } + cdrom[id].status = READY_STAT | ERR_STAT; + cdrom[id].phase = 3; + cdrom[id].packet_status = 0x80; + cdrom[id].callback = 50 * CDROM_TIME; +} + +static void cdrom_not_ready(uint8_t id) +{ + cdrom_sense_key = SENSE_NOT_READY; + cdrom_asc = ASC_MEDIUM_NOT_PRESENT; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + +static void cdrom_illegal_opcode(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_ILLEGAL_OPCODE; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + +static void cdrom_lba_out_of_range(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_LBA_OUT_OF_RANGE; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + +static void cdrom_invalid_field(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_INV_FIELD_IN_CMD_PACKET; + cdrom_ascq = 0; + cdrom_cmd_error(id); + cdrom[id].status = 0x53; +} + +static void cdrom_invalid_field_pl(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_INV_FIELD_IN_PARAMETER_LIST; + cdrom_ascq = 0; + cdrom_cmd_error(id); + cdrom[id].status = 0x53; +} + +static void cdrom_illegal_mode(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + +static void cdrom_incompatible_format(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_INCOMPATIBLE_FORMAT; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + +static void cdrom_data_phase_error(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_DATA_PHASE_ERROR; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + +static int cdrom_pass_through(uint8_t id, int *len) +{ + int ret = 0; + uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; + + ret = cdrom_drives[id].handler->pass_through(id, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos, len); + cdrom_log("CD-ROM %i: Data from pass through: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + cdrom_log("CD-ROM %i: Returned value: %i\n", id, ret); + + if (!ret) + { + /* Command failed with OS error code, return illegal opcode. */ + cdrom_log("CD-ROM %i: Command failed with OS error code, return illegal opcode.\n", id); + cdrom_illegal_opcode(id); + return 0; + } + else + { + if ((cdrom_sense_key != 0) || (cdrom_asc != 0) || (cdrom_ascq != 0)) + { + /* Command failed with sense, error with that sense. */ + cdrom_log("CD-ROM %i: Command failed with sense, error with that sense.\n", id); + cdrom_cmd_error(id); + return 0; + } + else + { + /* Command was performed successfully. */ + cdrom_log("CD-ROM %i: Command was performed successfully.\n", id); + return 1; + } + } +} + +int cdrom_update_cdb(uint8_t id) +{ + int temp = 0; + + switch(cdrom[id].current_cdb[0]) + { + case GPCMD_READ_6: + cdrom[id].current_cdb[1] = (cdrom[id].sector_pos >> 16) & 0xff; + cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 8) & 0xff; + cdrom[id].current_cdb[3] = cdrom[id].sector_pos & 0xff; + break; + + case GPCMD_READ_10: + cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff; + cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff; + cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff; + cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff; + cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 8) & 0xff; + cdrom[id].current_cdb[8] = cdrom[id].requested_blocks & 0xff; + break; + + case GPCMD_READ_12: + cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff; + cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff; + cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff; + cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff; + cdrom[id].current_cdb[6] = (cdrom[id].requested_blocks >> 24) & 0xff; + cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 16) & 0xff; + cdrom[id].current_cdb[8] = (cdrom[id].requested_blocks >> 8) & 0xff; + cdrom[id].current_cdb[9] = cdrom[id].requested_blocks & 0xff; + break; + + case GPCMD_READ_CD_MSF: + temp = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos); + cdrom[id].current_cdb[3] = (temp >> 16) & 0xff; + cdrom[id].current_cdb[4] = (temp >> 8) & 0xff; + cdrom[id].current_cdb[5] = temp & 0xff; + + temp = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos + cdrom[id].requested_blocks - 1); + cdrom[id].current_cdb[6] = (temp >> 16) & 0xff; + cdrom[id].current_cdb[7] = (temp >> 8) & 0xff; + cdrom[id].current_cdb[8] = temp & 0xff; + break; + + case GPCMD_READ_CD: + cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff; + cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff; + cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff; + cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff; + cdrom[id].current_cdb[6] = (cdrom[id].requested_blocks >> 16) & 0xff; + cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 8) & 0xff; + cdrom[id].current_cdb[8] = cdrom[id].requested_blocks & 0xff; + break; + } +} + +int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) +{ + uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; + + int ret = 0; + int cdsize = 0; + + int i = 0; + + if (cdrom_drives[id].handler->pass_through) + { + cdsize = cdrom_drives[id].handler->size(id); + + ret = cdrom_pass_through(id, len); + cdrom[id].data_pos += *len; + + if (!ret) + { + return 0; + } + + if (cdrom[id].sector_pos > (cdsize - 1)) + { + // cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); + cdrom_lba_out_of_range(id); + return 0; + } + + cdrom[id].old_len = *len; + } + else + { + if (cdrom[id].sector_pos > (cdrom_drives[id].handler->size(id) - 1)) + { + // cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); + cdrom_lba_out_of_range(id); + return 0; + } + + cdrom[id].old_len = 0; + + for (i = 0; i < cdrom[id].requested_blocks; i++) + { + ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos, msf, type, flags, len); + + cdrom[id].data_pos += *len; + cdrom[id].old_len += *len; + + if (!ret) + { + cdrom_illegal_mode(id); + return 0; + } + } + + cdrom_log("CD-ROM %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + } + + return 1; +} + +int cdrom_read_blocks(uint8_t id, int *len, int first_batch) +{ + int i = 0; + int ret = 0; + + int msf = 0; + + int type = 0; + int flags = 0; + + if (cdrom[id].current_cdb[0] == 0xb9) + { + msf = 1; + } + + if ((cdrom[id].current_cdb[0] == 0xb9) || (cdrom[id].current_cdb[0] == 0xbe)) + { + type = (cdrom[id].current_cdb[1] >> 2) & 7; + flags = cdrom[id].current_cdb[9] || (((uint32_t) cdrom[id].current_cdb[10]) << 8); + } + else + { + type = 2; + flags = 0x10; + } + + cdrom[id].data_pos = 0; + + if (!cdrom[id].sector_len) + { + cdrom_command_complete(id); + return 0; + } + + cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos); + + cdrom_update_cdb(id); + + ret = cdrom_read_data(id, msf, type, flags, len); + + cdrom_log("Read %i bytes of blocks...\n", *len); + + if (!ret || ((cdrom[id].old_len != *len) && !first_batch)) + { + if ((cdrom[id].old_len != *len) && !first_batch) + { + cdrom_illegal_mode(id); + } + + return 0; + } + + cdrom[id].sector_pos += cdrom[id].requested_blocks; + cdrom[id].sector_len -= cdrom[id].requested_blocks; + + return 1; +} + +/*SCSI Get Configuration*/ +uint8_t cdrom_set_profile(uint8_t *buf, uint8_t *index, uint16_t profile) +{ + uint8_t *buf_profile = buf + 12; /* start of profiles */ + + buf_profile += ((*index) * 4); /* start of indexed profile */ + buf_profile[0] = (profile >> 8) & 0xff; + buf_profile[1] = profile & 0xff; + buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7])); + + /* each profile adds 4 bytes to the response */ + (*index)++; + buf[11] += 4; /* Additional Length */ + + return 4; +} + +/*SCSI Read DVD Structure*/ +static int cdrom_read_dvd_structure(uint8_t id, int format, const uint8_t *packet, uint8_t *buf) +{ + int layer = packet[6]; + uint64_t total_sectors; + + switch (format) + { + case 0x00: /* Physical format information */ + total_sectors = (uint64_t) cdrom_drives[id].handler->size(id); + + if (layer != 0) + { + cdrom_invalid_field(id); + return 0; + } + + total_sectors >>= 2; + if (total_sectors == 0) + { + // return -ASC_MEDIUM_NOT_PRESENT; + cdrom_not_ready(id); + return 0; + } + + buf[4] = 1; /* DVD-ROM, part version 1 */ + buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ + buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ + buf[7] = 0; /* default densities */ + + /* FIXME: 0x30000 per spec? */ + buf[8] = buf[9] = buf[10] = buf[11] = 0; /* start sector */ + buf[12] = (total_sectors >> 24) & 0xff; /* end sector */ + buf[13] = (total_sectors >> 16) & 0xff; + buf[14] = (total_sectors >> 8) & 0xff; + buf[15] = total_sectors & 0xff; + + buf[16] = (total_sectors >> 24) & 0xff; /* l0 end sector */ + buf[17] = (total_sectors >> 16) & 0xff; + buf[18] = (total_sectors >> 8) & 0xff; + buf[19] = total_sectors & 0xff; + + /* Size of buffer, not including 2 byte size field */ + buf[0] = ((2048 +2 ) >> 8) & 0xff; + buf[1] = (2048 + 2) & 0xff; + + /* 2k data + 4 byte header */ + return (2048 + 4); + + case 0x01: /* DVD copyright information */ + buf[4] = 0; /* no copyright data */ + buf[5] = 0; /* no region restrictions */ + + /* Size of buffer, not including 2 byte size field */ + buf[0] = ((4 + 2) >> 8) & 0xff; + buf[1] = (4 + 2) & 0xff; + + /* 4 byte header + 4 byte data */ + return (4 + 4); + + case 0x03: /* BCA information - invalid field for no BCA info */ + cdrom_invalid_field(id); + return 0; + + case 0x04: /* DVD disc manufacturing information */ + /* Size of buffer, not including 2 byte size field */ + buf[0] = ((2048 + 2) >> 8) & 0xff; + buf[1] = (2048 + 2) & 0xff; + + /* 2k data + 4 byte header */ + return (2048 + 4); + + case 0xff: + /* + * This lists all the command capabilities above. Add new ones + * in order and update the length and buffer return values. + */ + + buf[4] = 0x00; /* Physical format */ + buf[5] = 0x40; /* Not writable, is readable */ + buf[6] = ((2048 + 4) >> 8) & 0xff; + buf[7] = (2048 + 4) & 0xff; + + buf[8] = 0x01; /* Copyright info */ + buf[9] = 0x40; /* Not writable, is readable */ + buf[10] = ((4 + 4) >> 8) & 0xff; + buf[11] = (4 + 4) & 0xff; + + buf[12] = 0x03; /* BCA info */ + buf[13] = 0x40; /* Not writable, is readable */ + buf[14] = ((188 + 4) >> 8) & 0xff; + buf[15] = (188 + 4) & 0xff; + + buf[16] = 0x04; /* Manufacturing info */ + buf[17] = 0x40; /* Not writable, is readable */ + buf[18] = ((2048 + 4) >> 8) & 0xff; + buf[19] = (2048 + 4) & 0xff; + + /* Size of buffer, not including 2 byte size field */ + buf[6] = ((16 + 2) >> 8) & 0xff; + buf[7] = (16 + 2) & 0xff; + + /* data written + 4 byte header */ + return (16 + 4); + + default: /* TODO: formats beyond DVD-ROM requires */ + cdrom_invalid_field(id); + return 0; + } +} + +/*SCSI Get Event Status Notification*/ +static uint32_t cdrom_get_event_status(uint8_t id, uint8_t *buffer) +{ + uint8_t event_code, media_status = 0; + + if (buffer[5]) + { + media_status = MS_TRAY_OPEN; + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } + } + else + { + media_status = MS_MEDIA_PRESENT; + } + + event_code = MEC_NO_CHANGE; + if (media_status != MS_TRAY_OPEN) + { + if (!buffer[4]) + { + event_code = MEC_NEW_MEDIA; + cdrom_drives[id].handler->load(id); + } + else if (buffer[4]==2) + { + event_code = MEC_EJECT_REQUESTED; + cdrom_drives[id].handler->eject(id); + } + } + + buffer[4] = event_code; + buffer[5] = media_status; + buffer[6] = 0; + buffer[7] = 0; + + return 8; +} + +void cdrom_insert(uint8_t id) +{ + cdrom[id].unit_attention = 1; +} + +/*SCSI Sense Initialization*/ +void cdrom_sense_code_ok(uint8_t id) +{ + cdrom_sense_key = SENSE_NONE; + cdrom_asc = 0; + cdrom_ascq = 0; +} + +int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) +{ + int ready = 0; + + if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED)) + { + cdrom_log("CD-ROM %i: Attempting to unknown command %02X over %s\n", id, cdb[0], cdrom_drives[id].bus_type ? "SCSI" : "ATAPI"); + cdrom_illegal_opcode(id); + return 0; + } + + if (!cdrom_drives[id].bus_type && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) + { + cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", id, cdb[0]); + cdrom_illegal_opcode(id); + return 0; + } + + if (cdrom_drives[id].bus_type && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) + { + cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", id, cdb[0]); + cdrom_illegal_opcode(id); + return 0; + } + + if (cdrom_drives[id].handler->medium_changed(id)) + { + // cdrom_log("CD-ROM %i: Medium has changed...\n", id); + cdrom_insert(id); + } + + ready = cdrom_drives[id].handler->ready(id); + + if (!ready && cdrom[id].unit_attention) + { + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + cdrom[id].unit_attention = 0; + } + + /* If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. */ + if (cdrom[id].unit_attention == 1) + { + // cdrom_log("CD-ROM %i: Unit attention now 2\n", id); + cdrom[id].unit_attention = 2; + if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) + { + cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); + cdrom_unit_attention(id); + return 0; + } + } + else if (cdrom[id].unit_attention == 2) + { + if (cdb[0] != GPCMD_REQUEST_SENSE) + { + // cdrom_log("CD-ROM %i: Unit attention now 0\n", id); + cdrom[id].unit_attention = 0; + } + } + + /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* + the UNIT ATTENTION condition if it's set. */ + if (cdb[0] != GPCMD_REQUEST_SENSE) + { + cdrom_sense_clear(id, cdb[0], 1); + } + + /* Next it's time for NOT READY. */ + if ((cdrom_command_flags[cdb[0]] & CHECK_READY) && !ready) + { + cdrom_log("CD-ROM %i: Not ready (%02X)\n", id, cdb[0]); + cdrom_not_ready(id); + return 0; + } + + cdrom_log("CD-ROM %i: Continuing with command\n", id); + + return 1; +} + +void cdrom_clear_callback(uint8_t channel) +{ + uint8_t id = atapi_cdrom_drives[channel]; + + if (id <= CDROM_NUM) + { + cdrom[id].callback = 0; + } +} + +static void cdrom_seek(uint8_t id, uint32_t pos) +{ + // cdrom_log("CD-ROM %i: Seek %08X\n", id, pos); + cdrom[id].seek_pos = pos; + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } +} + +static void cdrom_rezero(uint8_t id) +{ + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } + cdrom[id].sector_pos = cdrom[id].sector_len = 0; + cdrom_seek(id, 0); +} + +void cdrom_reset(uint8_t id) +{ + cdrom_rezero(id); + cdrom[id].status = 0; + cdrom[id].callback = 0; + cdrom[id].packet_status = 0xff; + cdrom[id].unit_attention = 0; +} + +void cdrom_command(uint8_t id, uint8_t *cdb) +{ + uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; + uint8_t rcdmode = 0; + int c; + int len; + int msf; + int pos=0; + unsigned char temp; + uint32_t size; + uint8_t page_code; + int max_len; + int used_len; + unsigned idx = 0; + unsigned size_idx; + unsigned preamble_len; + int toc_format; + int temp_command; + int alloc_length; + int completed; + uint8_t index = 0; + int media; + int format; + int ret; + int real_pos; + int track = 0; + int ready = 0; + uint8_t device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; + uint8_t device_identify_ex[14] = { '8', '6', 'B', '_', 'C', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + + if (cdrom_drives[id].bus_type) + { + cdrom[id].status &= ~ERR_STAT; + } + + cdrom[id].packet_len = 0; + cdrom[id].request_pos = 0; + + device_identify[6] = id + 0x30; + + device_identify_ex[6] = id + 0x30; + device_identify_ex[9] = emulator_version[0]; + device_identify_ex[11] = emulator_version[2]; + device_identify_ex[12] = emulator_version[3]; + + cdrom[id].data_pos = 0; + + memcpy(cdrom[id].current_cdb, cdb, cdrom[id].cdb_len); + + cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention); + cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); +#if 0 + + int CdbLength; + for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++) + { + cdrom_log("CD-ROM %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); + } +#endif + + msf = cdb[1] & 2; + cdrom[id].sector_len = 0; + + /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ + if (cdrom_drives[id].check_on_execution) + { + if (cdrom_pre_execution_check(id, cdb) == 0) + { + return; + } + } + + cdrom[id].prev_status = cdrom[id].cd_status; + cdrom[id].cd_status = cdrom_drives[id].handler->status(id); + if (((cdrom[id].prev_status == CD_STATUS_PLAYING) || (cdrom[id].prev_status == CD_STATUS_PAUSED)) && ((cdrom[id].cd_status != CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_PAUSED))) + { + completed = 1; + } + else + { + completed = 0; + } + + switch (cdb[0]) + { + case GPCMD_TEST_UNIT_READY: + cdrom_command_complete(id); + break; + + case GPCMD_REZERO_UNIT: + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } + cdrom[id].sector_pos = cdrom[id].sector_len = 0; + cdrom_seek(id, 0); + break; + + case GPCMD_REQUEST_SENSE: /* Used by ROS 4+ */ + alloc_length = cdb[4]; + temp_command = cdb[0]; + + /*Will return 18 bytes of 0*/ + if (alloc_length != 0) + { + memset(cdbufferb, 0, alloc_length); + memcpy(cdbufferb, cdrom[id].sense, alloc_length); + } + + cdbufferb[0] = 0x70; + + if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && completed) + { + cdbufferb[2]=SENSE_ILLEGAL_REQUEST; + cdbufferb[12]=ASC_AUDIO_PLAY_OPERATION; + cdbufferb[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; + } + else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED)) + { + cdbufferb[2]=SENSE_ILLEGAL_REQUEST; + cdbufferb[12]=ASC_AUDIO_PLAY_OPERATION; + cdbufferb[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + } + else + { + if (cdrom[id].unit_attention) + { + cdbufferb[2]=SENSE_UNIT_ATTENTION; + cdbufferb[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; + cdbufferb[13]=0; + } + } + + // cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]); + + if (cdbufferb[2] == SENSE_UNIT_ATTENTION) + { + /* If the last remaining sense is unit attention, clear + that condition. */ + cdrom[id].unit_attention = 0; + } + + /* Clear the sense stuff as per the spec. */ + cdrom_sense_clear(id, temp_command, 0); + + cdrom_data_command_finish(id, 18, 18, alloc_length, 0); + break; + + case GPCMD_SET_SPEED: + case GPCMD_SET_SPEED_ALT: + cdrom_command_complete(id); + break; + + case GPCMD_MECHANISM_STATUS: + len = (cdbufferb[7] << 16) | (cdbufferb[8] << 8) | cdbufferb[9]; + + memset(cdbufferb, 0, 8); + cdbufferb[5] = 1; + + cdrom_data_command_finish(id, 8, 8, len, 0); + break; + + case GPCMD_READ_TOC_PMA_ATIP: + cdrom[id].toctimes++; + + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + } + else + { + toc_format = cdb[2] & 0xf; + + if (toc_format == 0) + { + toc_format = (cdb[9] >> 6) & 3; + } + + len = cdb[8] + (cdb[7] << 8); + + switch (toc_format) + { + case 0: /*Normal*/ + len = cdrom_drives[id].handler->readtoc(id, cdbufferb, cdb[6], msf, len, 0); + break; + case 1: /*Multi session*/ + len = cdrom_drives[id].handler->readtoc_session(id, cdbufferb, msf, len); + cdbufferb[0] = 0; cdbufferb[1] = 0xA; + break; + case 2: /*Raw*/ + len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, len); + break; + default: + cdrom_invalid_field(id); + return; + } + } + + cdrom_data_command_finish(id, len, len, len, 0); + // cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); + return; + + case GPCMD_READ_CD_OLD: + cdrom[id].current_cdb[0] = 0xbe; /* IMPORTANT: Convert the command to new read CD for pass through purposes. */ + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + case GPCMD_READ_CD: + case GPCMD_READ_CD_MSF: + switch(cdb[0]) + { + case GPCMD_READ_6: + cdrom[id].sector_len = cdb[4]; + cdrom[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + msf = 0; + break; + case GPCMD_READ_10: + cdrom[id].sector_len = (cdb[7] << 8) | cdb[8]; + cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + cdrom_log("CD-ROM %i: Length: %i, LBA: %i\n", id, cdrom[id].sector_len, cdrom[id].sector_pos); + msf = 0; + break; + case GPCMD_READ_12: + cdrom[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + cdrom[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + msf = 0; + break; + case GPCMD_READ_CD_MSF: + // cdrom_log("CD-ROM %i: Read CD MSF: Start MSF %02X%02X%02X End MSF %02X%02X%02X Flags %02X\n", id, cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); + cdrom[id].sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); + cdrom[id].sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); + + cdrom[id].sector_len -= cdrom[id].sector_pos; + cdrom[id].sector_len++; + msf = 1; + break; + case GPCMD_READ_CD_OLD: + case GPCMD_READ_CD: + // cdrom_log("CD-ROM %i: Read CD: Start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n", id, cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); + cdrom[id].sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + + msf = 0; + break; + } + + if (!cdrom[id].sector_len) + { + // cdrom_log("CD-ROM %i: All done - callback set\n", id); + cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom[id].callback = 20 * CDROM_TIME; + break; + } + + max_len = cdrom[id].sector_len; + if (cdrom_drives[id].bus_type) + { + cdrom[id].requested_blocks = max_len; + } + else + { + cdrom[id].requested_blocks = 1; + } + + ret = cdrom_read_blocks(id, &alloc_length, 1); + if (!ret) + { + return; + } + + cdrom[id].packet_len = max_len * alloc_length; + cdrom_data_command_finish(id, alloc_length * cdrom[id].requested_blocks, alloc_length, alloc_length * cdrom[id].requested_blocks, 0); + cdrom[id].all_blocks_total = cdrom[id].block_total; + if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) + { + readflash=1; + } + return; + + case GPCMD_READ_HEADER: + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + } + else + { + cdrom[id].sector_len = (cdb[7] << 8) | cdb[8]; + cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4]<<8) | cdb[5]; + if (msf) + { + real_pos = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos); + } + else + { + real_pos = cdrom[id].sector_pos; + } + cdbufferb[0] = 1; /*2048 bytes user data*/ + cdbufferb[1] = cdbufferb[2] = cdbufferb[3] = 0; + cdbufferb[4] = (real_pos >> 24); + cdbufferb[5] = ((real_pos >> 16) & 0xff); + cdbufferb[6] = ((real_pos >> 8) & 0xff); + cdbufferb[7] = real_pos & 0xff; + + len = 8; + } + + cdrom_data_command_finish(id, len, len, len, 0); + return; + + case GPCMD_MODE_SENSE_6: + case GPCMD_MODE_SENSE_10: + if (cdb[0] == GPCMD_MODE_SENSE_6) + { + len = cdb[4]; + } + else + { + len = (cdb[8] | (cdb[7] << 8)); + } + + if (!(cdrom_mode_sense_page_flags[id][cdb[2] & 0x3F] & IMPLEMENTED)) + { + cdrom_invalid_field(id); + return; + } + + memset(cdbufferb, 0, len); + alloc_length = len; + + if (cdb[0] == GPCMD_MODE_SENSE_6) + { + len = cdrom_mode_sense(id, cdbufferb, 4, cdb[2]); + cdbufferb[0] = len - 1; + cdbufferb[1] = 3; /*120mm data CD-ROM*/ + if (len > alloc_length) + { + len = alloc_length; + } + } + else + { + len = cdrom_mode_sense(id, cdbufferb, 8, cdb[2]); + if (len > alloc_length) + { + len = alloc_length; + } + cdbufferb[0]=(len - 2) >> 8; + cdbufferb[1]=(len - 2) & 255; + cdbufferb[2] = 3; /*120mm data CD-ROM*/ + if (len > alloc_length) + { + len = alloc_length; + } + } + + cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", id, cdb[2]); + + cdrom_data_command_finish(id, len, len, alloc_length, 0); + return; + + case GPCMD_MODE_SELECT_6: + case GPCMD_MODE_SELECT_10: + if (cdb[0] == GPCMD_MODE_SELECT_6) + { + len = cdb[4]; + } + else + { + len = (cdb[7] << 8) | cdb[8]; + } + + ret = cdrom_mode_select_init(id, cdb[0], len, cdb[1] & 1); + + cdrom_data_command_finish(id, len, len, len, 1); + return; + + case GPCMD_GET_CONFIGURATION: + temp_command = cdb[0]; + /* XXX: could result in alignment problems in some architectures */ + len = (cdb[7] << 8) | cdb[8]; + alloc_length = len; + + index = 0; + + /* only feature 0 is supported */ + if (cdb[2] != 0 || cdb[3] != 0) + { + cdrom_invalid_field(id); + return; + } + + /* + * XXX: avoid overflow for io_buffer if len is bigger than + * the size of that buffer (dimensioned to max number of + * sectors to transfer at once) + * + * Only a problem if the feature/profiles grow. + */ + if (alloc_length > 512) /* XXX: assume 1 sector */ + { + alloc_length = 512; + } + + memset(cdbufferb, 0, alloc_length); + /* + * the number of sectors from the media tells us which profile + * to use as current. 0 means there is no media + */ + if (len > CD_MAX_SECTORS) + { + cdbufferb[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; + cdbufferb[7] = MMC_PROFILE_DVD_ROM & 0xff; + } + else if (len <= CD_MAX_SECTORS) + { + cdbufferb[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; + cdbufferb[7] = MMC_PROFILE_CD_ROM & 0xff; + } + cdbufferb[10] = 0x02 | 0x01; /* persistent and current */ + alloc_length = 12; /* headers: 8 + 4 */ + alloc_length += cdrom_set_profile(cdbufferb, &index, MMC_PROFILE_DVD_ROM); + alloc_length += cdrom_set_profile(cdbufferb, &index, MMC_PROFILE_CD_ROM); + cdbufferb[0] = ((alloc_length - 4) >> 24) & 0xff; + cdbufferb[1] = ((alloc_length - 4) >> 16) & 0xff; + cdbufferb[2] = ((alloc_length - 4) >> 8) & 0xff; + cdbufferb[3] = (alloc_length - 4) & 0xff; + + cdrom_data_command_finish(id, len, len, alloc_length, 0); + break; + + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + gesn_cdb = (void *) cdb; + gesn_event_header = (void *) cdbufferb; + + /* It is fine by the MMC spec to not support async mode operations. */ + if (!(gesn_cdb->polled & 0x01)) + { + /* asynchronous mode */ + /* Only polling is supported, asynchronous mode is not. */ + cdrom_invalid_field(id); + return; + } + + /* polling mode operation */ + + /* + * These are the supported events. + * + * We currently only support requests of the 'media' type. + * Notification class requests and supported event classes are bitmasks, + * but they are built from the same values as the "notification class" + * field. + */ + gesn_event_header->supported_events = 1 << GESN_MEDIA; + + /* + * We use |= below to set the class field; other bits in this byte + * are reserved now but this is useful to do if we have to use the + * reserved fields later. + */ + gesn_event_header->notification_class = 0; + + /* + * Responses to requests are to be based on request priority. The + * notification_class_request_type enum above specifies the + * priority: upper elements are higher prio than lower ones. + */ + if (gesn_cdb->class & (1 << GESN_MEDIA)) + { + gesn_event_header->notification_class |= GESN_MEDIA; + used_len = cdrom_get_event_status(id, cdbufferb); + } + else + { + gesn_event_header->notification_class = 0x80; /* No event available */ + used_len = sizeof(*gesn_event_header); + } + gesn_event_header->len = used_len - sizeof(*gesn_event_header); + + cdrom_data_command_finish(id, used_len, used_len, used_len, 0); + break; + + case GPCMD_READ_DISC_INFORMATION: + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + } + else + { + memset(cdbufferb, 0, 34); + memset(cdbufferb, 1, 9); + cdbufferb[0] = 0; + cdbufferb[1] = 32; + cdbufferb[2] = 0xe; /* last session complete, disc finalized */ + cdbufferb[7] = 0x20; /* unrestricted use */ + cdbufferb[8] = 0x00; /* CD-ROM */ + + len=34; + } + + cdrom_data_command_finish(id, len, len, alloc_length, 0); + break; + + case GPCMD_READ_TRACK_INFORMATION: + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + + track = ((uint32_t) cdb[2]) << 24; + track |= ((uint32_t) cdb[3]) << 16; + track |= ((uint32_t) cdb[4]) << 8; + track |= (uint32_t) cdb[5]; + + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + } + else + { + if (((cdb[1] & 0x03) != 1) || (track != 1)) + { + cdrom_invalid_field(id); + return; + } + + len = 36; + + memset(cdbufferb, 0, 36); + cdbufferb[1] = 34; + cdbufferb[2] = 1; /* track number (LSB) */ + cdbufferb[3] = 1; /* session number (LSB) */ + cdbufferb[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ + cdbufferb[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ + cdbufferb[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ + cdbufferb[24] = (cdrom_drives[id].handler->size(id) >> 24) & 0xff; /* track size */ + cdbufferb[25] = (cdrom_drives[id].handler->size(id) >> 16) & 0xff; /* track size */ + cdbufferb[26] = (cdrom_drives[id].handler->size(id) >> 8) & 0xff; /* track size */ + cdbufferb[27] = cdrom_drives[id].handler->size(id) & 0xff; /* track size */ + + if (len > max_len) + { + len = max_len; + cdbufferb[0] = ((max_len - 2) >> 8) & 0xff; + cdbufferb[1] = (max_len - 2) & 0xff; + } + } + + cdrom_data_command_finish(id, len, len, alloc_length, 0); + break; + + case GPCMD_PLAY_AUDIO_10: + case GPCMD_PLAY_AUDIO_12: + case GPCMD_PLAY_AUDIO_MSF: + case GPCMD_PLAY_AUDIO_TRACK_INDEX: + switch(cdb[0]) + { + case GPCMD_PLAY_AUDIO_10: + msf = 0; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[7] << 8) | cdb[8]; + break; + case GPCMD_PLAY_AUDIO_12: + msf = 0; + pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[6] << 24) | (cdb[7] << 16) | (cdb[8] << 8) | cdb[9]; + break; + case GPCMD_PLAY_AUDIO_MSF: + /* This is apparently deprecated in the ATAPI spec, and apparently + has been since 1995 (!). Hence I'm having to guess most of it. */ + msf = 1; + pos = (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; + break; + case GPCMD_PLAY_AUDIO_TRACK_INDEX: + msf = 2; + pos = (cdb[4] << 8) | cdb[5]; + len = (cdb[7] << 8) | cdb[8]; + break; + } + + if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || + !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) + { + cdrom_illegal_mode(id); + break; + } + + if (cdrom_drives[id].handler->playaudio) + { + cdrom_drives[id].handler->playaudio(id, pos, len, msf); + } + else + { + cdrom_illegal_mode(id); + break; + } + + cdrom_command_complete(id); + break; + + case GPCMD_READ_SUBCHANNEL: + cdrom_log("CD-ROM %i: Getting page %i\n", id, cdb[3]); + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + cdrom_log("CD-ROM %i: Audio status: %i\n", id, temp); + switch(cdrom[id].cd_status) + { + case CD_STATUS_PLAYING: + cdbufferb[1] = 0x11; + break; + case CD_STATUS_PAUSED: + cdbufferb[1] = 0x12; + break; + default: + if (completed) + { + cdbufferb[1] = 0x13; + } + else + { + cdbufferb[1] = 0x15; + } + break; + } + } + else + { + if (cdb[3] > 3) + { + // cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", id, cdb[3]); + cdrom_invalid_field(id); + return; + } + + switch(cdb[3]) + { + case 0: + alloc_length = 4; + break; + case 1: + alloc_length = 16; + break; + default: + alloc_length = 24; + break; + } + + memset(cdbufferb, 24, 0); + pos = 0; + cdbufferb[pos++] = 0; + cdbufferb[pos++] = 0; /*Audio status*/ + cdbufferb[pos++] = 0; cdbufferb[pos++] = 0; /*Subchannel length*/ + cdbufferb[pos++] = cdb[3] & 3; /*Format code*/ + if ((temp & 3) == 1) + { + cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); + if (((cdbufferb[1] == 0x13) && !completed) || (cd_status == CD_STATUS_DATA_ONLY)) + { + cdbufferb[1] = 0x15; + } + } + if (!(cdb[2] & 0x40) || ((cdb[3] & 3) == 0)) + { + len = 4; + } + else + { + len = alloc_length; + } + } + + cdrom_data_command_finish(id, len, len, len, 0); + break; + + case GPCMD_READ_DVD_STRUCTURE: + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + } + else + { + len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + alloc_length = len; + + if (cdb[7] < 0xff) + { + if (len <= CD_MAX_SECTORS) + { + cdrom_incompatible_format(id); + return; + } + else + { + cdrom_invalid_field(id); + return; + } + } + + memset(cdbufferb, 0, (alloc_length > 256 * 512 + 4) ? (256 * 512 + 4) : alloc_length); + + switch (cdb[7]) + { + case 0x00 ... 0x7f: + case 0xff: + if (cdb[1] == 0) + { + ret = cdrom_read_dvd_structure(id, format, cdb, cdbufferb); + + /* if (!ret) + { + cdrom_cmd_error(id, SENSE_ILLEGAL_REQUEST, -ret, 0); + } + else */ + if (ret) + { + cdrom_data_command_finish(id, len, len, alloc_length, 0); + } + return; + } + /* TODO: BD support, fall through for now */ + + /* Generic disk structures */ + case 0x80: /* TODO: AACS volume identifier */ + case 0x81: /* TODO: AACS media serial number */ + case 0x82: /* TODO: AACS media identifier */ + case 0x83: /* TODO: AACS media key block */ + case 0x90: /* TODO: List of recognized format layers */ + case 0xc0: /* TODO: Write protection status */ + default: + cdrom_invalid_field(id); + return; + } + } + break; + + case GPCMD_START_STOP_UNIT: + switch(cdbufferb[4] & 3) + { + case 0: /* Stop the disc. */ + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } + break; + case 1: /* Start the disc and read the TOC. */ + cdrom_drives[id].handler->medium_changed(id); /* This causes a TOC reload. */ + break; + case 2: /* Eject the disc if possible. */ + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } +#ifndef __unix + win_cdrom_eject(id); +#endif + break; + case 3: /* Load the disc (close tray). */ +#ifndef __unix + win_cdrom_reload(id); +#else + cdrom_drives[id].handler->load(id); +#endif + break; + } + + cdrom_command_complete(id); + break; + + case GPCMD_INQUIRY: + if (cdb[1] & 1) + { + preamble_len = 4; + size_idx = 3; + + cdbufferb[idx++] = 05; + cdbufferb[idx++] = cdb[2]; + cdbufferb[idx++] = 0; + + idx++; + + switch (cdb[2]) + { + case 0x00: + cdbufferb[idx++] = 0x00; + cdbufferb[idx++] = 0x83; + break; + case 0x83: + if (idx + 24 > max_len) + { + cdrom_data_phase_error(id); + return; + } + + cdbufferb[idx++] = 0x02; + cdbufferb[idx++] = 0x00; + cdbufferb[idx++] = 0x00; + cdbufferb[idx++] = 20; + ide_padstr8(cdbufferb + idx, 20, "53R141"); /* Serial */ + idx += 20; + + if (idx + 72 > cdb[4]) + { + goto atapi_out; + } + cdbufferb[idx++] = 0x02; + cdbufferb[idx++] = 0x01; + cdbufferb[idx++] = 0x00; + cdbufferb[idx++] = 68; + ide_padstr8(cdbufferb + idx, 8, "86Box"); /* Vendor */ + idx += 8; + ide_padstr8(cdbufferb + idx, 40, device_identify_ex); /* Product */ + idx += 40; + ide_padstr8(cdbufferb + idx, 20, "53R141"); /* Product */ + idx += 20; + break; + default: + cdrom_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + cdrom_invalid_field(id); + return; + } + } + else + { + preamble_len = 5; + size_idx = 4; + + memset(cdbufferb, 0, 8); + cdbufferb[0] = 5; /*CD-ROM*/ + cdbufferb[1] = 0x80; /*Removable*/ + cdbufferb[3] = 0x21; + cdbufferb[4] = 31; + + ide_padstr8(cdbufferb + 8, 8, "86Box"); /* Vendor */ + ide_padstr8(cdbufferb + 16, 16, device_identify); /* Product */ + ide_padstr8(cdbufferb + 32, 4, emulator_version); /* Revision */ + idx = 36; + } + +atapi_out: + cdbufferb[size_idx] = idx - preamble_len; + len=idx; + + cdrom_data_command_finish(id, len, len, cdb[4], 0); + break; + + case GPCMD_PREVENT_REMOVAL: + cdrom_command_complete(id); + break; + + case GPCMD_PAUSE_RESUME: + if (cdb[8] & 1) + { + if (cdrom_drives[id].handler->resume) + { + cdrom_drives[id].handler->resume(id); + } + else + { + cdrom_illegal_mode(id); + break; + } + } + else + { + if (cdrom_drives[id].handler->pause) + { + cdrom_drives[id].handler->pause(id); + } + else + { + cdrom_illegal_mode(id); + break; + } + } + cdrom_command_complete(id); + break; + + case GPCMD_SEEK_6: + case GPCMD_SEEK_10: + switch(cdb[0]) + { + case GPCMD_SEEK_6: + pos = (cdb[2] << 8) | cdb[3]; + break; + case GPCMD_SEEK_10: + pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; + break; + } + cdrom_seek(id, pos); + cdrom_command_complete(id); + break; + + case GPCMD_READ_CDROM_CAPACITY: + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, &len); + if (!ret) + { + return; + } + } + else + { + size = cdrom_drives[id].handler->size(id) - 1; /* IMPORTANT: What's returned is the last LBA block. */ + memset(cdbufferb, 0, 8); + cdbufferb[0] = (size >> 24) & 0xff; + cdbufferb[1] = (size >> 16) & 0xff; + cdbufferb[2] = (size >> 8) & 0xff; + cdbufferb[3] = size & 0xff; + cdbufferb[6] = 8; /* 2048 = 0x0800 */ + len = 8; + } + + cdrom_data_command_finish(id, len, len, len, 0); + break; + + case GPCMD_STOP_PLAY_SCAN: + if (cdrom_drives[id].handler->stop) + { + cdrom_drives[id].handler->stop(id); + } + else + { + cdrom_illegal_mode(id); + break; + } + cdrom_command_complete(id); + break; + + default: + cdrom_illegal_opcode(id); + break; + } + + // cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", cdrom[id].phase, cdrom[id].request_length); +} + +/* This is for block reads. */ +int cdrom_block_check(uint8_t id) +{ + int alloc_length = 0; + int ret = 0; + + /* If this is a media access command, and we hit the end of the block but not the entire length, + read the next block. */ + if (cdrom_is_media_access(id)) + { + /* We have finished the current block. */ + cdrom_log("CD-ROM %i: %i bytes total read, %i bytes all total\n", cdrom[id].total_read, cdrom[id].all_blocks_total); + if (cdrom[id].total_read >= cdrom[id].all_blocks_total) + { + cdrom_log("CD-ROM %i: %i bytes read, current block finished\n", id, cdrom[id].total_read); + /* Read the next block. */ + ret = cdrom_read_blocks(id, &alloc_length, 0); + if (!ret) + { + /* Return value is 0 - an error has occurred. */ + cdrom_log("CD-ROM %i: %i bytes read, error while reading blocks\n", id, cdrom[id].total_read); + cdrom[id].status = BUSY_STAT | (cdrom[id].status & ERR_STAT); + return 0; + } + else + { + /* Return value is 1 - sectors have been read successfully. */ + cdrom[id].pos = 0; + cdrom[id].all_blocks_total += cdrom[id].block_total; + cdrom_log("CD-ROM %i: %i bytes read, next block(s) read successfully, %i bytes are still left\n", id, cdrom[id].total_read, cdrom[id].all_blocks_total - cdrom[id].total_read); + return 1; + } + } + else + { + /* Blocks not exhausted, tell the host to check for buffer length. */ + cdrom_log("CD-ROM %i: Blocks not yet finished\n", id); + return 1; + } + } + else + { + /* Not a media access command, ALWAYS do the callback. */ + cdrom_log("CD-ROM %i: Not a media access command\n", id); + return 1; + } +} + +/* This is the general ATAPI callback. */ +void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ +{ + int ret = 0; + int old_pos = 0; + + if (!cdrom_drives[id].bus_type) + { + cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); + ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); + } + + cdrom[id].status = BUSY_STAT; + + if (cdrom[id].total_read >= cdrom[id].packet_len) + { + cdrom_log("CD-ROM %i: %i bytes read, command done\n", id, cdrom[id].total_read); + + cdrom[id].pos = cdrom[id].request_pos = 0; + cdrom_command_complete(id); + } + else + { + cdrom_log("CD-ROM %i: %i bytes read, %i bytes are still left\n", id, cdrom[id].total_read, cdrom[id].packet_len - cdrom[id].total_read); + + /* Make sure to keep pos, and reset request_pos to 0. */ + /* Also make sure to not reset total_read. */ + old_pos = cdrom[id].pos; + cdrom[id].packet_status = CDROM_PHASE_DATA_IN; + cdrom_command_common(id); + cdrom[id].pos = old_pos; + cdrom[id].request_pos = 0; + } +} + +/* 0 = Continue transfer; 1 = Continue transfer, IRQ; -1 = Terminate transfer; -2 = Terminate transfer with error */ +int cdrom_mode_select_return(uint8_t id, int ret) +{ + switch(ret) + { + case 0: + /* Invalid field in parameter list. */ + cdrom_invalid_field_pl(id); + return -2; + case 1: + /* Successful, more data needed. */ + if (cdrom[id].pos >= (cdrom[id].packet_len + 2)) + { + cdrom[id].pos = 0; + cdrom_command_write(id); + return 1; + } + return 0; + case 2: + /* Successful, more data needed, second byte not yet processed. */ + return 0; + case -3: + /* Not initialized. */ + case -4: + /* Unknown phase. */ + cdrom_illegal_opcode(id); + return -2; + case -6: + /* Command terminated successfully. */ + cdrom_command_complete(id); + return -1; + } +} + +int cdrom_phase_callback(uint8_t id); + +int cdrom_read_from_ide_dma(uint8_t channel) +{ + uint8_t *cdbufferb; + + uint8_t id = atapi_cdrom_drives[channel]; + + cdbufferb = (uint8_t *) cdrom[id].buffer; + + if (id > CDROM_NUM) + { + return 0; + } + + if (ide_bus_master_write) + { + if (ide_bus_master_write(channel >> 1, cdbufferb, cdrom[id].request_length)) + { + cdrom_data_phase_error(id); + cdrom_phase_callback(id); + return 0; + } + else + { + return 1; + } + } +} + +int cdrom_read_from_scsi_dma(uint8_t scsi_id) +{ + uint8_t *cdbufferb; + + uint8_t id = scsi_cdrom_drives[scsi_id]; + + cdbufferb = (uint8_t *) cdrom[id].buffer; + + if (id > CDROM_NUM) + { + return 0; + } + + cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength); + memcpy(cdbufferb, SCSIDevices[scsi_id].CmdBuffer, SCSIDevices[scsi_id].InitLength); + return 1; +} + +int cdrom_read_from_dma(uint8_t id) +{ + uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; + + int i = 0; + int ret = 0; + + if (cdrom_drives[id].bus_type) + { + ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id); + } + else + { + ret = cdrom_read_from_ide_dma(cdrom_drives[id].ide_channel); + } + + if (!ret) + { + return 0; + } + + for (i = 0; i < cdrom[id].request_length; i++) + { + ret = cdrom_mode_select_write(id, cdbufferb[i]); + ret = cdrom_mode_select_return(id, ret); + if (ret == -1) + { + return 1; + } + else if (ret == -2) + { + cdrom_phase_callback(id); + return 0; + } + } +} + +int cdrom_write_to_ide_dma(uint8_t channel) +{ + uint8_t *cdbufferb; + + uint8_t id = atapi_cdrom_drives[channel]; + + cdbufferb = (uint8_t *) cdrom[id].buffer; + + if (id > CDROM_NUM) + { + return 0; + } + + if (ide_bus_master_read) + { + if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].request_length)) + { + cdrom_data_phase_error(id); + cdrom_phase_callback(id); + return 0; + } + else + { + return 1; + } + } +} + +int cdrom_write_to_scsi_dma(uint8_t scsi_id) +{ + uint8_t *cdbufferb; + + uint8_t id = scsi_cdrom_drives[scsi_id]; + + cdbufferb = (uint8_t *) cdrom[id].buffer; + + if (id > CDROM_NUM) + { + return 0; + } + + cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength); + memcpy(SCSIDevices[scsi_id].CmdBuffer, cdbufferb, SCSIDevices[scsi_id].InitLength); + cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]); + cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id].CmdBuffer[0], SCSIDevices[scsi_id].CmdBuffer[1], SCSIDevices[scsi_id].CmdBuffer[2], SCSIDevices[scsi_id].CmdBuffer[3], SCSIDevices[scsi_id].CmdBuffer[4], SCSIDevices[scsi_id].CmdBuffer[5], SCSIDevices[scsi_id].CmdBuffer[6], SCSIDevices[scsi_id].CmdBuffer[7]); + return 1; +} + +int cdrom_write_to_dma(uint8_t id) +{ + int ret = 0; + + if (cdrom_drives[id].bus_type) + { + ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id); + } + else + { + ret = cdrom_write_to_ide_dma(cdrom_drives[id].ide_channel); + } + + if (!ret) + { + return 0; + } + + return 1; +} + +/* If the result is 1, issue an IRQ, otherwise not. */ +int cdrom_phase_callback(uint8_t id) +{ + switch(cdrom[id].packet_status) + { + case CDROM_PHASE_IDLE: + // cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); + cdrom[id].pos=0; + cdrom[id].phase = 1; + cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); + return 0; + case CDROM_PHASE_COMMAND: + // cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); + cdrom[id].status = BUSY_STAT | (cdrom[id].status &ERR_STAT); + memcpy(cdrom[id].atapi_cdb, (uint8_t *) cdrom[id].buffer, cdrom[id].cdb_len); + cdrom_command(id, cdrom[id].atapi_cdb); + return 0; + case CDROM_PHASE_COMPLETE: + // cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); + cdrom[id].status = READY_STAT; + cdrom[id].phase = 3; + return 1; + case CDROM_PHASE_DATA_OUT: + // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); + cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); + cdrom[id].phase = 0; + return 1; + case CDROM_PHASE_DATA_OUT_DMA: + // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); + cdrom_read_from_dma(id); + cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom[id].status = READY_STAT; + cdrom[id].phase = 3; + return 1; + case CDROM_PHASE_DATA_IN: + // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); + cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); + cdrom[id].phase = 2; + return 1; + case CDROM_PHASE_DATA_IN_DMA: + // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); + cdrom_write_to_dma(id); + cdrom[id].packet_status = CDROM_PHASE_COMPLETE; + cdrom[id].status = READY_STAT; + cdrom[id].phase = 3; + return 1; + case CDROM_PHASE_ERROR: + // cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); + cdrom[id].status = READY_STAT | ERR_STAT; + cdrom[id].phase = 3; + return 1; + } +} + +uint32_t cdrom_read(uint8_t channel) +{ + uint8_t id = atapi_cdrom_drives[channel]; + + uint16_t temp = 0; + int ret = 0; + + if (id > CDROM_NUM) + { + return 0; + } + + temp = cdrom[id].buffer[cdrom[id].pos >> 1]; + + cdrom[id].pos += 2; + cdrom[id].request_pos += 2; + + if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) + { + cdrom[id].total_read += 2; + ret = cdrom_block_check(id); + /* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */ + if (ret) + { + cdrom_log("CD-ROM %i: Return value is 1\n", id); + if (cdrom[id].request_pos >= cdrom[id].request_length) + { + /* Time for a DRQ. */ + cdrom_log("CD-ROM %i: Issuing read callback\n", id); + cdrom_callback(id); + } + else + { + cdrom_log("CD-ROM %i: Doing nothing\n", id); + } + } + else + { + cdrom_log("CD-ROM %i: Return value is 0\n", id); + } + cdrom_log("CD-ROM %i: Returning: %04X (buffer position: %i, request position: %i, total: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos, cdrom[id].total_read); + return temp; + } + else + { + cdrom_log("CD-ROM %i: Returning zero (buffer position: %i, request position: %i, total: %i)\n", id, cdrom[id].pos, cdrom[id].request_pos, cdrom[id].total_read); + return 0; + } +} + +/* If the result is 1, issue an IRQ, otherwise not. */ +int cdrom_write(uint8_t channel, uint16_t val) +{ + uint8_t id = atapi_cdrom_drives[channel]; + + int ret = 0; + + if (id > CDROM_NUM) + { + return 0; + } + + cdrom[id].buffer[cdrom[id].pos >> 1] = val; + cdrom[id].pos += 2; + + if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT) + { + ret = cdrom_mode_select_write(id, val & 0xff); + if (ret == 1) + { + ret = 2; + } + cdrom_mode_select_return(id, ret); + /* Make sure to not do another write, if it has terminated. */ + if (ret != -6) + { + cdrom_mode_select_write(id, val >> 8); + if (cdrom_mode_select_return(id, ret) == 1) + { + return 0; + } + } + return 0; + } + else if (cdrom[id].packet_status == CDROM_PHASE_IDLE) + { + if (cdrom[id].pos >= cdrom[id].cdb_len) + { + cdrom[id].pos=0; + cdrom[id].status = BUSY_STAT; + cdrom[id].packet_status = CDROM_PHASE_COMMAND; + timer_process(); + cdrom_phase_callback(id); + timer_update_outstanding(); + } + return 0; + } +} diff --git a/src/cdrom.h b/src/cdrom.h index e8103e5ca..f03fb7854 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -2,34 +2,203 @@ #define __CDROM_H__ /*CD-ROM stuff*/ +#define CDROM_NUM 4 + +#define CDROM_PHASE_IDLE 0 +#define CDROM_PHASE_COMMAND 1 +#define CDROM_PHASE_COMPLETE 2 +#define CDROM_PHASE_DATA_IN 3 +#define CDROM_PHASE_DATA_IN_DMA 4 +#define CDROM_PHASE_DATA_OUT 5 +#define CDROM_PHASE_DATA_OUT_DMA 6 +#define CDROM_PHASE_ERROR 0x80 + +#define BUF_SIZE 32768 + +#define CDROM_ISO 200 + +#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) +#define CDROM_TIME (5 * 100 * (1 << TIMER_SHIFT)) + typedef struct CDROM { - int (*ready)(void); - int (*medium_changed)(void); - int (*readtoc)(uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); - int (*readtoc_session)(uint8_t *b, int msf, int maxlen); - int (*readtoc_raw)(uint8_t *b, int msf, int maxlen); - uint8_t (*getcurrentsubchannel)(uint8_t *b, int msf); - void (*read_capacity)(uint8_t *b); - void (*read_subchannel)(uint8_t *in_cdb, uint8_t *b); - void (*read_header)(uint8_t *in_cdb, uint8_t *b); - void (*read_disc_information)(uint8_t *b); - int (*read_track_information)(uint8_t *in_cdb, uint8_t *b); - int (*sector_data_type)(int sector, int ismsf); - void (*readsector_raw)(uint8_t *b, int sector, int ismsf); - void (*playaudio)(uint32_t pos, uint32_t len, int ismsf); - void (*seek)(uint32_t pos); - void (*load)(void); - void (*eject)(void); - void (*pause)(void); - void (*resume)(void); - uint32_t (*size)(void); - int (*status)(void); - int (*is_track_audio)(uint32_t pos, int ismsf); - void (*stop)(void); - void (*exit)(void); + int (*ready)(uint8_t id); + int (*medium_changed)(uint8_t id); + void (*audio_callback)(uint8_t id, int16_t *output, int len); + void (*audio_stop)(uint8_t id); + int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); + int (*readtoc_session)(uint8_t id, uint8_t *b, int msf, int maxlen); + int (*readtoc_raw)(uint8_t id, uint8_t *b, int msf, int maxlen); + uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); + int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len); + int (*sector_data_type)(uint8_t id, int sector, int ismsf); + int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); + void (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf); + void (*load)(uint8_t id); + void (*eject)(uint8_t id); + void (*pause)(uint8_t id); + void (*resume)(uint8_t id); + uint32_t (*size)(uint8_t id); + int (*status)(uint8_t id); + int (*is_track_audio)(uint8_t id, uint32_t pos, int ismsf); + void (*stop)(uint8_t id); + void (*exit)(uint8_t id); } CDROM; -extern CDROM *cdrom; +typedef struct __attribute__((__packed__)) +{ + uint8_t previous_command; + int toctimes; + + int is_dma; + + int requested_blocks; /* This will be set to something other than 1 when block reads are implemented. */ + + int current_page_code; + int current_page_len; + + int current_page_pos; + + int mode_select_phase; + + int total_length; + int written_length; + + int do_page_save; + + uint8_t error; + uint8_t features; + uint16_t request_length; + uint8_t status; + uint8_t phase; + + uint32_t sector_pos; + uint32_t sector_len; + + uint32_t packet_len; + int packet_status; + + uint8_t atapi_cdb[16]; + uint8_t current_cdb[16]; + + uint32_t pos; + + int callback; + + int data_pos; + + int cdb_len_setting; + int cdb_len; + + int cd_status; + int prev_status; + + int unit_attention; + uint8_t sense[18]; + + int request_pos; + + uint16_t buffer[390144]; + + int times; + + uint32_t seek_pos; + + int total_read; + + int block_total; + int all_blocks_total; + + int old_len; +} cdrom_t; + +extern cdrom_t cdrom[CDROM_NUM]; + +typedef struct __attribute__((__packed__)) +{ + int enabled; + + int max_blocks_at_once; + + CDROM *handler; + + int host_drive; + int prev_host_drive; + + uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + uint8_t bus_mode; /* Bit 0 = PIO suported; + Bit 1 = DMA supportd. */ + + uint8_t check_on_execution; /* 0 = Not Ready/Unit Attention checkeck is performed on the controller's side before command execution; + 1 = Not Ready/Unit Attention checkeck is performed on command execution. */ + + uint8_t ide_channel; + + uint8_t scsi_device_id; + + uint8_t sound_on; +} cdrom_drive_t; + +extern cdrom_drive_t cdrom_drives[CDROM_NUM]; + +extern uint8_t atapi_cdrom_drives[8]; + +extern uint8_t scsi_cdrom_drives[16]; + +extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); +extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); +extern void (*ide_bus_master_set_irq)(int channel); + +typedef struct +{ + uint32_t last_block; + uint64_t image_size; + int iso_inited; + char iso_path[1024]; + FILE* iso_image; + int iso_changed; + + uint32_t cd_pos; + uint32_t cd_end; +} cdrom_iso_t; + +cdrom_iso_t cdrom_iso[CDROM_NUM]; + +typedef struct +{ + uint32_t last_block; + uint32_t cdrom_capacity; + int ioctl_inited; + char ioctl_path[8]; + int tocvalid; + int cd_state; + uint32_t cd_end; + int16_t cd_buffer[BUF_SIZE]; + int cd_buflen; +} cdrom_ioctl_t; + +void ioctl_close(uint8_t id); + +cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; + +uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel); +uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel); +void build_atapi_cdrom_map(); +void build_scsi_cdrom_map(); +int cdrom_CDROM_PHASE_to_scsi(uint8_t id); +int cdrom_atapi_phase_to_scsi(uint8_t id); +void cdrom_command(uint8_t id, uint8_t *cdb); +int cdrom_phase_callback(uint8_t id); +uint32_t cdrom_read(uint8_t channel); +int cdrom_write(uint8_t channel, uint16_t val); +int cdrom_lba_to_msf_accurate(int lba); +void cdrom_reset(uint8_t id); +void cdrom_set_signature(int id); + +#define cdrom_sense_error cdrom[id].sense[0] +#define cdrom_sense_key cdrom[id].sense[2] +#define cdrom_asc cdrom[id].sense[12] +#define cdrom_ascq cdrom[id].sense[12] +#define cdrom_drive cdrom_drives[id].host_drive #endif \ No newline at end of file diff --git a/src/codegen_ops_x86-64.h b/src/codegen_ops_x86-64.h index 452241e81..8573ab495 100644 --- a/src/codegen_ops_x86-64.h +++ b/src/codegen_ops_x86-64.h @@ -3188,6 +3188,8 @@ static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { + uint8_t *jump1; + if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { addbyte(0x83); /*CMP flags_res, 0*/ @@ -3203,10 +3205,8 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(0xc0); addbyte(0x75); /*JNZ +*/ } - if (not) - addbyte(12+2+2+7+5+(timing_bt ? 8 : 0)); - else - addbyte(12+2+2); + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); CALL_FUNC(CF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); @@ -3215,6 +3215,9 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no else addbyte(0x74); /*JZ +*/ addbyte(7+5+(timing_bt ? 4 : 0)); + + if (!not) + *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); addbyte(cpu_state_offset(pc)); @@ -3228,6 +3231,8 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (not) + *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; } static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) @@ -3268,6 +3273,7 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { + uint8_t *jump1; if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { addbyte(0x83); /*CMP flags_res, 0*/ @@ -3283,11 +3289,8 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(0xc0); addbyte(0x75); /*JNZ +*/ } - if (not) - addbyte(12+2+3+12+2+3+2+2+7+5+(timing_bt ? 8 : 0)); - else - addbyte(12+2+3+12+2+3+2+2); - + jump1 = &codeblock[block_current].data[block_pos]; + addbyte(0); CALL_FUNC(NF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); @@ -3307,6 +3310,8 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no else addbyte(0x74); /*JZ +*/ addbyte(7+5+(timing_bt ? 4 : 0)); + if (!not) + *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); addbyte(cpu_state_offset(pc)); @@ -3320,6 +3325,8 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + if (not) + *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; } static int LOAD_VAR_W(uintptr_t addr) @@ -5241,7 +5248,7 @@ static void LOAD_EA() static void MEM_CHECK_WRITE(x86seg *seg) { - uint8_t *jump1, *jump2; + uint8_t *jump1, *jump2, *jump3; CHECK_SEG_WRITE(seg); @@ -5264,15 +5271,27 @@ static void MEM_CHECK_WRITE(x86seg *seg) /*seg = ESI, addr = EAX*/ + if (IS_32_ADDR(&cr0)) + { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t)&cr0); + addbyte(0); + } + else + { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t)&cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); addbyte(0x3c); addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)&cr0); - addbyte(0); addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); @@ -5284,17 +5303,32 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xfe); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(10); - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)writelookup2); - addbyte(-1); + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + if (IS_32_ADDR(writelookup2)) + { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t)writelookup2); + addbyte(-1); + } + else + { + addbyte(0x48); /*MOV RCX, writelookup2*/ + addbyte(0xb9); + addquad((uint64_t)writelookup2); + addbyte(0x83); /*CMP [RCX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf9); + addbyte(-1); + } addbyte(0x75); /*JNE +*/ jump2 = &codeblock[block_current].data[block_pos]; addbyte(0); // addbyte(0xc3); /*RET*/ - + + *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); @@ -5358,15 +5392,27 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) /*seg = ESI, addr = EAX*/ + if (IS_32_ADDR(&cr0)) + { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t)&cr0); + addbyte(0); + } + else + { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t)&cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); addbyte(0x3c); addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)&cr0); - addbyte(0); addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); @@ -5387,19 +5433,42 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xee); addbyte(12); - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)writelookup2); - addbyte(-1); + if (IS_32_ADDR(writelookup2)) + { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t)writelookup2); + addbyte(-1); + } + else + { + addbyte(0x48); /*MOV RAX, writelookup2*/ + addbyte(0xb8); + addquad((uint64_t)writelookup2); + addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf8); + addbyte(-1); + } addbyte(0x74); /*JE +*/ jump2 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)writelookup2); - addbyte(-1); + if (IS_32_ADDR(writelookup2)) + { + addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t)writelookup2); + addbyte(-1); + } + else + { + addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ + addbyte(0x3c); + addbyte(0xf0); + addbyte(-1); + } addbyte(0x75); /*JNE +*/ jump3 = &codeblock[block_current].data[block_pos]; addbyte(0); @@ -5460,15 +5529,27 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) /*seg = ESI, addr = EAX*/ + if (IS_32_ADDR(&cr0)) + { + addbyte(0x83); /*CMP cr0, 0*/ + addbyte(0x3c); + addbyte(0x25); + addlong((uint32_t)&cr0); + addbyte(0); + } + else + { + addbyte(0x48); /*MOV RDI, &cr0*/ + addbyte(0xbf); + addquad((uint64_t)&cr0); + addbyte(0x83); /*CMPL [RDI], 0*/ + addbyte(0x3f); + addbyte(0); + } addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); addbyte(0x3c); addbyte(0x30); - addbyte(0x83); /*CMP cr0, 0*/ - addbyte(0x3c); - addbyte(0x25); - addlong((uint32_t)&cr0); - addbyte(0); addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); @@ -5489,19 +5570,42 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xee); addbyte(12); - addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ - addbyte(0x3c); - addbyte(0xfd); - addlong((uint32_t)writelookup2); - addbyte(-1); + if (IS_32_ADDR(writelookup2)) + { + addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t)writelookup2); + addbyte(-1); + } + else + { + addbyte(0x48); /*MOV RAX, writelookup2*/ + addbyte(0xb8); + addquad((uint64_t)writelookup2); + addbyte(0x83); /*CMP [RAX+RDI*8], -1*/ + addbyte(0x3c); + addbyte(0xf8); + addbyte(-1); + } addbyte(0x74); /*JE slowpath*/ jump2 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ - addbyte(0x3c); - addbyte(0xf5); - addlong((uint32_t)writelookup2); - addbyte(-1); + if (IS_32_ADDR(writelookup2)) + { + addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ + addbyte(0x3c); + addbyte(0xfd); + addlong((uint32_t)writelookup2); + addbyte(-1); + } + else + { + addbyte(0x83); /*CMP [RAX+RSI*8], -1*/ + addbyte(0x3c); + addbyte(0xf0); + addbyte(-1); + } addbyte(0x75); /*JNE +*/ jump3 = &codeblock[block_current].data[block_pos]; addbyte(0); diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index ac6111669..30c013856 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -3460,13 +3460,13 @@ static void MMX_ENTER() addbyte(0x45); addbyte(cpu_state_offset(ismmx)); addbyte(1); - addbyte(0x8b); /*MOV TOP, EAX*/ + addbyte(0x89); /*MOV TOP, EAX*/ addbyte(0x45); addbyte(cpu_state_offset(TOP)); - addbyte(0x8b); /*MOV tag, EAX*/ + addbyte(0x89); /*MOV tag, EAX*/ addbyte(0x45); addbyte(cpu_state_offset(tag[0])); - addbyte(0x8b); /*MOV tag+4, EAX*/ + addbyte(0x89); /*MOV tag+4, EAX*/ addbyte(0x45); addbyte(cpu_state_offset(tag[4])); diff --git a/src/codegen_x86-64.h b/src/codegen_x86-64.h index e8cd97015..648a30342 100644 --- a/src/codegen_x86-64.h +++ b/src/codegen_x86-64.h @@ -10,7 +10,7 @@ #define BLOCK_EXIT_OFFSET 0x7e0 #define BLOCK_GPF_OFFSET (BLOCK_EXIT_OFFSET - 20) -#define BLOCK_MAX 1650 +#define BLOCK_MAX 1620 enum { diff --git a/src/disc_86f.c b/src/disc_86f.c index cfc898a52..17ae7dfcd 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -203,6 +203,22 @@ static struct __attribute__((packed)) uint32_t dma_over; } d86f[FDD_NUM]; +int d86f_do_log = 1; + +void d86f_log(const char *format, ...) +{ +#ifdef ENABLE_D86F_LOG + if (d86f_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + static void d86f_setupcrc(uint16_t poly) { int c = 256, bc; @@ -1107,7 +1123,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_ { find->sync_marks++; find->sync_pos = d86f[drive].track_pos; - // pclog("Sync marks: %i\n", find->sync_marks); + // d86f_log("Sync marks: %i\n", find->sync_marks); return; } @@ -1120,7 +1136,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_ disc_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc)); find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; find->sync_pos = 0xFFFFFFFF; - // pclog("AM found (%04X) (%02X)\n", req_am, d86f[drive].state); + // d86f_log("AM found (%04X) (%02X)\n", req_am, d86f[drive].state); d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; d86f[drive].state++; return; @@ -1143,7 +1159,7 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_ else { /* Not skip mode, process the sector anyway. */ - // pclog("Wrong AM found (%04X) (%02X)\n", other_am, d86f[drive].state); + // d86f_log("Wrong AM found (%04X) (%02X)\n", other_am, d86f[drive].state); fdc_set_wrong_am(); d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; d86f[drive].state++; @@ -1247,12 +1263,12 @@ void d86f_read_sector_id(int drive, int side, int match) else { /* CRC is valid. */ - // pclog("Sector ID found: %08X; Requested: %08X\n", d86f[drive].last_sector.dword, d86f[drive].req_sector.dword); + // d86f_log("Sector ID found: %08X; Requested: %08X\n", d86f[drive].last_sector.dword, d86f[drive].req_sector.dword); d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; d86f[drive].id_found++; if ((d86f[drive].last_sector.dword == d86f[drive].req_sector.dword) || !match) { - // pclog("ID read (%02X)\n", d86f[drive].state); + // d86f_log("ID read (%02X)\n", d86f[drive].state); d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n); if (d86f[drive].state == STATE_02_READ_ID) { @@ -1274,12 +1290,12 @@ void d86f_read_sector_id(int drive, int side, int match) { if (d86f[drive].last_sector.id.c == 0xFF) { - // pclog("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].error_condition |= 8; } else { - // pclog("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].error_condition |= 0x10; } } @@ -1385,7 +1401,7 @@ void d86f_read_sector_data(int drive, int side) if (read_status == -1) { d86f[drive].dma_over++; - // pclog("DMA over now: %i\n", d86f[drive].dma_over); + // d86f_log("DMA over now: %i\n", d86f[drive].dma_over); } } } @@ -1403,7 +1419,7 @@ void d86f_read_sector_data(int drive, int side) /* We've got the data. */ if (d86f[drive].dma_over > 1) { - // pclog("DMA overrun while reading data!\n"); + // d86f_log("DMA overrun while reading data!\n"); d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; d86f[drive].error_condition = 0; d86f[drive].state = STATE_IDLE; @@ -1417,7 +1433,7 @@ void d86f_read_sector_data(int drive, int side) } else { - // pclog("Bytes over DMA: %i\n", d86f[drive].dma_over); + // d86f_log("Bytes over DMA: %i\n", d86f[drive].dma_over); } if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state != STATE_02_READ_DATA)) @@ -1490,7 +1506,7 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) { /* We're in the data field of the sector, use a CRC byte. */ d86f[drive].current_byte[side] = d86f[drive].calc_crc.bytes[(d86f[drive].data_find.bytes_obtained & 1)]; - // pclog("BO: %04X (%02X)\n", d86f[drive].data_find.bytes_obtained, d86f[drive].current_byte[side]); + // d86f_log("BO: %04X (%02X)\n", d86f[drive].data_find.bytes_obtained, d86f[drive].current_byte[side]); } d86f[drive].current_bit[side] = (15 - (d86f[drive].data_find.bits_obtained & 15)) >> 1; @@ -1574,7 +1590,7 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) { if (d86f[drive].dma_over > 1) { - // pclog("DMA overrun while writing data!\n"); + // d86f_log("DMA overrun while writing data!\n"); d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; d86f[drive].error_condition = 0; d86f[drive].state = STATE_IDLE; @@ -1611,7 +1627,7 @@ void d86f_advance_bit(int drive, int side) if (d86f[drive].state != STATE_IDLE) { d86f[drive].index_count++; - // pclog("Index count now: %i\n", d86f[drive].index_count); + // d86f_log("Index count now: %i\n", d86f[drive].index_count); } } } @@ -1721,7 +1737,7 @@ void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_ d86f[drive].state = STATE_IDLE; d86f_handler[drive].writeback(drive); - // pclog("Format finished (%i) (%i)!\n", d86f[drive].track_pos, sc); + // d86f_log("Format finished (%i) (%i)!\n", d86f[drive].track_pos, sc); d86f[drive].error_condition = 0; d86f[drive].datac = 0; fdc_sector_finishread(); @@ -1784,11 +1800,11 @@ void d86f_format_track(int drive, int side) data = 0; } d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = data & 0xff; - // pclog("format_sector_id[%i] = %i\n", d86f[drive].datac, d86f[drive].format_sector_id.byte_array[d86f[drive].datac]); + // d86f_log("format_sector_id[%i] = %i\n", d86f[drive].datac, d86f[drive].format_sector_id.byte_array[d86f[drive].datac]); if (d86f[drive].datac == 3) { fdc_stop_id_request(); - // pclog("Formatting sector: %08X (%i) (%i)...\n", d86f[drive].format_sector_id.dword, d86f[drive].track_pos, sc); + // d86f_log("Formatting sector: %08X (%i) (%i)...\n", d86f[drive].format_sector_id.dword, d86f[drive].track_pos, sc); } } case FMT_PRETRK_SYNC: @@ -1881,7 +1897,7 @@ void d86f_format_track(int drive, int side) if ((d86f[drive].index_count) && (d86f[drive].format_state < FMT_SECTOR_ID_SYNC) || (d86f[drive].format_state > FMT_SECTOR_GAP3)) { - // pclog("Format finished regularly\n"); + // d86f_log("Format finished regularly\n"); d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); return; } @@ -1903,7 +1919,7 @@ void d86f_format_track(int drive, int side) case FMT_POSTTRK_CHECK: if (d86f[drive].index_count) { - // pclog("Format finished with delay\n"); + // d86f_log("Format finished with delay\n"); d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); return; } @@ -1945,10 +1961,10 @@ void d86f_poll(int drive) { if (!d86f_can_read_address(drive)) { - /* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) pclog("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive)); - if (!fdd_can_read_medium(real_drive(drive))) pclog("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive)); - if (fdc_is_mfm() != d86f_is_mfm(drive)) pclog("[%i, %i] Encoding mismatch\n", drive, side); - if (d86f_get_encoding(drive) > 1) pclog("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */ + /* if (fdc_get_bitcell_period() != d86f_get_bitcell_period(drive)) d86f_log("[%i, %i] Bitcell period mismatch (%i != %i)\n", drive, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive)); + if (!fdd_can_read_medium(real_drive(drive))) d86f_log("[%i, %i] Drive can not read medium (hole = %01X)\n", drive, side, d86f_hole(drive)); + if (fdc_is_mfm() != d86f_is_mfm(drive)) d86f_log("[%i, %i] Encoding mismatch\n", drive, side); + if (d86f_get_encoding(drive) > 1) d86f_log("[%i, %i] Image encoding (%s) not FM or MFM\n", drive, side, (d86f_get_encoding(drive) == 2) ? "M2FM" : "GCR"); */ d86f[drive].state = STATE_SECTOR_NOT_FOUND; } @@ -2081,7 +2097,7 @@ void d86f_poll(int drive) if (d86f_wrong_densel(drive) && (d86f[drive].state != STATE_IDLE)) { - // pclog("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].state = STATE_IDLE; fdc_noidam(); return; @@ -2093,7 +2109,7 @@ void d86f_poll(int drive) { case STATE_0A_FIND_ID: case STATE_SECTOR_NOT_FOUND: - // pclog("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].state = STATE_IDLE; fdc_noidam(); break; @@ -2104,7 +2120,7 @@ void d86f_poll(int drive) case STATE_05_FIND_DATA: case STATE_09_FIND_DATA: case STATE_0C_FIND_DATA: - // pclog("[State: %02X] [Side %i] No data address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] No data address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].state = STATE_IDLE; fdc_nodataam(); break; @@ -2128,24 +2144,24 @@ void d86f_poll(int drive) { if ((d86f[drive].error_condition & 0x18) == 0x08) { - // pclog("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_badcylinder(); } if ((d86f[drive].error_condition & 0x10) == 0x10) { - // pclog("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_wrongcylinder(); } } else { - // pclog("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_nosector(); } } else { - // pclog("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); + // d86f_log("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_noidam(); } break; @@ -2580,7 +2596,7 @@ void d86f_seek(int drive, int track) void d86f_write_track(int drive, int side, uint16_t *da0, uint16_t *sa0) { - // pclog("Pos: %08X\n", ftell(d86f[drive].f)); + // d86f_log("Pos: %08X\n", ftell(d86f[drive].f)); fwrite(&(d86f[drive].side_flags[side]), 1, 2, d86f[drive].f); @@ -2598,7 +2614,7 @@ void d86f_write_track(int drive, int side, uint16_t *da0, uint16_t *sa0) fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, d86f[drive].f); - // pclog("Pos: %08X\n", ftell(d86f[drive].f)); + // d86f_log("Pos: %08X\n", ftell(d86f[drive].f)); } int d86f_get_track_table_size(int drive) @@ -2639,9 +2655,9 @@ void d86f_writeback(int drive) fread(header, 1, header_size, d86f[drive].f); fseek(d86f[drive].f, 8, SEEK_SET); - // pclog("PosEx: %08X\n", ftell(d86f[drive].f)); + // d86f_log("PosEx: %08X\n", ftell(d86f[drive].f)); fwrite(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f); - // pclog("PosEx: %08X\n", ftell(d86f[drive].f)); + // d86f_log("PosEx: %08X\n", ftell(d86f[drive].f)); if (!fdd_doublestep_40(drive)) { @@ -2681,14 +2697,14 @@ void d86f_writeback(int drive) } if (d86f[drive].track_offset[logical_track]) { - // pclog("Writing track...\n"); + // d86f_log("Writing track...\n"); fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET); d86f_write_track(drive, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]); } } } - // pclog("Position: %08X\n", ftell(d86f[drive].f)); + // d86f_log("Position: %08X\n", ftell(d86f[drive].f)); if (d86f[drive].is_compressed) { @@ -2715,7 +2731,7 @@ void d86f_writeback(int drive) // ret = d86f_zlib(cf, d86f[drive].f, 0); if (!ret) { - pclog("86F: Error compressing file\n"); + d86f_log("86F: Error compressing file\n"); } fwrite(d86f[drive].outbuf, 1, ret, cf); @@ -2772,7 +2788,7 @@ void d86f_writeback(int drive) } #endif - // pclog("d86f_writeback(): %08X\n", d86f[drive].track_offset[track]); + // d86f_log("d86f_writeback(): %08X\n", d86f[drive].track_offset[track]); } void d86f_stop(int drive) @@ -2782,7 +2798,7 @@ void d86f_stop(int drive) int d86f_common_command(int drive, int sector, int track, int side, int rate, int sector_size) { - // pclog("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side); + d86f_log("d86f_common_command (drive %i): fdc_period=%i img_period=%i rate=%i sector=%i track=%i side=%i\n", drive, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), rate, sector, track, side); d86f[drive].req_sector.id.c = track; d86f[drive].req_sector.id.h = side; @@ -2802,7 +2818,7 @@ int d86f_common_command(int drive, int sector, int track, int side, int rate, in if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { - // pclog("Wrong side!\n"); + // d86f_log("Wrong side!\n"); fdc_noidam(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -2863,11 +2879,11 @@ void d86f_comparesector(int drive, int sector, int track, int side, int rate, in void d86f_readaddress(int drive, int side, int rate) { - // pclog("Reading sector ID on drive %i...\n", drive); + // d86f_log("Reading sector ID on drive %i...\n", drive); if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { - // pclog("Trying to access the second side of a single-sided disk\n"); + // d86f_log("Trying to access the second side of a single-sided disk\n"); fdc_noidam(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -2949,7 +2965,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) if (d86f[drive].cur_track > 256) { - // pclog("Track above 256\n"); + // d86f_log("Track above 256\n"); fdc_writeprotect(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -2979,7 +2995,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) } } - // pclog("Formatting track %i side %i\n", track, side); + // d86f_log("Formatting track %i side %i\n", track, side); d86f[drive].fill = fill; @@ -3071,7 +3087,7 @@ void d86f_load(int drive, char *fn) if ((magic != 0x46423638) && (magic != 0x66623638)) { /* File is not of the valid format, abort. */ - pclog("86F: Unrecognized magic bytes: %08X\n", magic); + d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); fclose(d86f[drive].f); return; } @@ -3083,22 +3099,22 @@ void d86f_load(int drive, char *fn) /* File is not of a recognized format version, abort. */ if (d86f[drive].version == 0x0063) { - pclog("86F: File has emulator-internal version 0.99, this version is not valid in a file\n"); + d86f_log("86F: File has emulator-internal version 0.99, this version is not valid in a file\n"); } else if ((d86f[drive].version >= 0x0100) && (d86f[drive].version < D86FVER)) { - pclog("86F: No longer supported development file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); + d86f_log("86F: No longer supported development file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); } else { - pclog("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); + d86f_log("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); } fclose(d86f[drive].f); return; } else { - pclog("86F: Recognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); + d86f_log("86F: Recognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); } fread(&(d86f[drive].disk_flags), 2, 1, d86f[drive].f); @@ -3128,7 +3144,7 @@ void d86f_load(int drive, char *fn) if (crc64 != read_crc64) { - pclog("86F: CRC64 error\n"); + d86f_log("86F: CRC64 error\n"); fclose(d86f[drive].f); return; } @@ -3145,7 +3161,7 @@ void d86f_load(int drive, char *fn) d86f[drive].f = fopen(temp_file_name, "wb"); if (!d86f[drive].f) { - pclog("86F: Unable to create temporary decompressed file\n"); + d86f_log("86F: Unable to create temporary decompressed file\n"); return; } @@ -3175,7 +3191,7 @@ void d86f_load(int drive, char *fn) if (!temp) { - pclog("86F: Error decompressing file\n"); + d86f_log("86F: Error decompressing file\n"); remove(temp_file_name); return; } @@ -3186,7 +3202,7 @@ void d86f_load(int drive, char *fn) if (d86f[drive].disk_flags & 0x100) { /* Zoned disk. */ - pclog("86F: Disk is zoned (Apple or Sony)\n"); + d86f_log("86F: Disk is zoned (Apple or Sony)\n"); fclose(d86f[drive].f); if (d86f[drive].is_compressed) { @@ -3198,7 +3214,7 @@ void d86f_load(int drive, char *fn) if (d86f[drive].disk_flags & 0x600) { /* Zone type is not 0 but the disk is fixed-RPM. */ - pclog("86F: Disk is fixed-RPM but zone type is not 0\n"); + d86f_log("86F: Disk is fixed-RPM but zone type is not 0\n"); fclose(d86f[drive].f); if (d86f[drive].is_compressed) { @@ -3234,7 +3250,7 @@ void d86f_load(int drive, char *fn) if (!(d86f[drive].track_offset[0])) { /* File has no track 0 side 0, abort. */ - pclog("86F: No Track 0 side 0\n"); + d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); return; } @@ -3242,7 +3258,7 @@ void d86f_load(int drive, char *fn) if ((d86f_get_sides(drive) == 2) && !(d86f[drive].track_offset[1])) { /* File is 2-sided but has no track 0 side 1, abort. */ - pclog("86F: No Track 0 side 0\n"); + d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); return; } @@ -3306,7 +3322,7 @@ void d86f_load(int drive, char *fn) d86f_common_handlers(drive); drives[drive].format = d86f_format; - pclog("86F: Disk is %scompressed and %s surface description data\n", d86f[drive].is_compressed ? "" : "not ", d86f_has_surface_desc(drive) ? "has" : "does not have"); + d86f_log("86F: Disk is %scompressed and %s surface description data\n", d86f[drive].is_compressed ? "" : "not ", d86f_has_surface_desc(drive) ? "has" : "does not have"); } void d86f_init() diff --git a/src/dma.c b/src/dma.c index 969ffca34..d61e22cc3 100644 --- a/src/dma.c +++ b/src/dma.c @@ -565,34 +565,39 @@ int dma_channel_write(int channel, uint16_t val) return 0; } +#if 0 static uint32_t PageLengthReadWrite(uint32_t PhysAddress, uint32_t TotalSize) { uint32_t LengthSize; uint32_t Page; Page = PhysAddress & 4095; - LengthSize = (Page + 4096) - PhysAddress; - if (LengthSize > TotalSize) - LengthSize = TotalSize; - return LengthSize; + if ((Page + TotalSize - 1) >= 4096) + { + TotalSize = 4096 - Page; + } + + return TotalSize; } +#endif //DMA Bus Master Page Read/Write void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize) { - uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); - memcpy(DataRead, &ram[PhysAddress], PageLen); - DataRead -= PageLen; - TotalSize += PageLen; + // uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); + memcpy(DataRead, &ram[PhysAddress], TotalSize); + // DataRead -= PageLen; + DataRead -= TotalSize; } void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize) { - uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); - memcpy(&ram[PhysAddress], DataWrite, PageLen); - DataWrite -= PageLen; - TotalSize += PageLen; + // uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); + memcpy(&ram[PhysAddress], DataWrite, TotalSize); + mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); + // DataWrite -= PageLen; + DataWrite -= TotalSize; } int dma_mode(int channel) diff --git a/src/fdc.c b/src/fdc.c index 8760285bd..cf4bd3413 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -115,6 +115,23 @@ int discmodified[4]; int discrate[4]; int discint; + +int fdc_do_log = 1; + +void fdc_log(const char *format, ...) +{ +#ifdef ENABLE_FDC_LOG + if (fdc_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + void fdc_reset() { fdc.stat=0x80; @@ -128,7 +145,7 @@ void fdc_reset() fdc.rate = 2; // fdc_update_rate(); } -// pclog("Reset FDC\n"); +// fdc_log("Reset FDC\n"); } sector_id_t fdc_get_read_track_sector() @@ -282,7 +299,7 @@ void fdc_fifo_buf_advance() { fdc.fifobufpos++; } - // pclog("FIFO buffer position = %02X\n", fdc.fifobufpos); + // fdc_log("FIFO buffer position = %02X\n", fdc.fifobufpos); } void fdc_fifo_buf_write(int val) @@ -305,7 +322,7 @@ static void fdc_int() { if (fdc.dor & 8) { - // pclog("FDC interrupt!\n"); + // fdc_log("FDC interrupt!\n"); picint(1 << 6); fdc.fintr = 1; } @@ -321,7 +338,7 @@ static void fdc_watchdog_poll(void *p) fdc->watchdog_timer += 1000 * TIMER_USEC; else { -// pclog("Watchdog timed out\n"); +// fdc_log("Watchdog timed out\n"); fdc->watchdog_timer = 0; if (fdc->dor & 0x20) @@ -460,7 +477,7 @@ void fdc_update_rate(int drive) } fdc.bitcell_period = 1000000 / bit_rate*2; /*Bitcell period in ns*/ - // pclog("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); + // fdc_log("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); } int fdc_get_bit_rate() @@ -573,7 +590,7 @@ void fdc_implied_seek() void fdc_write(uint16_t addr, uint8_t val, void *priv) { -// pclog("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready); +// fdc_log("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready); int drive, i, drive_num; int seek_time, seek_time_base; @@ -591,7 +608,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.watchdog_timer = 1000 * TIMER_USEC; fdc.watchdog_count = 1000; picintc(1 << 6); -// pclog("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC); +// fdc_log("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC); } if ((val & 0x80) && !(fdc.dor & 0x80)) { @@ -686,10 +703,10 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.perp &= 0xfc; fdc_reset(); } - // pclog("DSR now: %02X\n", val); + // fdc_log("DSR now: %02X\n", val); return; case 5: /*Command register*/ - // pclog("CMD now: %02X\n", val); + // fdc_log("CMD now: %02X\n", val); if ((fdc.stat & 0xf0) == 0xb0) { if (fdc.pcjr || !fdc.fifo) @@ -705,8 +722,8 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) break; } // if (fdc.inread) -// rpclog("c82c711_fdc_write : writing while inread! %02X\n", val); -// rpclog("Write command reg %i %i\n",fdc.pnum, fdc.ptot); +// rfdc_log("c82c711_fdc_write : writing while inread! %02X\n", val); +// rfdc_log("Write command reg %i %i\n",fdc.pnum, fdc.ptot); if (fdc.pnum==fdc.ptot) { // if ((fdc.stat & 0x10) || !fdc.stat) @@ -723,7 +740,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.command=val; fdc.stat |= 0x10; - // pclog("Starting FDC command %02X\n",fdc.command); + fdc_log("Starting FDC command %02X\n",fdc.command); switch (fdc.command&0x1F) { case 1: /*Mode*/ @@ -793,7 +810,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.stat |= 0x90; break; case 8: /*Sense interrupt status*/ - // if (!fdc.fintr && !fdc_reset_stat) pclog("Attempted SENSE INTERRUPT STATUS without FINTR\n"); + // if (!fdc.fintr && !fdc_reset_stat) fdc_log("Attempted SENSE INTERRUPT STATUS without FINTR\n"); if (!fdc.fintr && !fdc_reset_stat) goto bad_command; // printf("Sense interrupt status %i\n",curdrive); fdc.lastdrive = fdc.drive; @@ -898,7 +915,7 @@ bad_command: } if (fdc.pnum==fdc.ptot) { - // pclog("Got all params %02X\n", fdc.command); + fdc_log("Got all params %02X\n", fdc.command); discint=fdc.command&0x1F; timer_process(); disctime = 1024 * (1 << TIMER_SHIFT); @@ -921,7 +938,7 @@ bad_command: fdc.read_track_sector.id.n = fdc.params[4]; fdc_implied_seek(); fdc.rw_track = fdc.params[1]; -// pclog("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc.sector, fdc.eot[fdc.drive]); +// fdc_log("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc.sector, fdc.eot[fdc.drive]); disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); if (fdc.pcjr || !fdc.dma) { @@ -955,7 +972,7 @@ bad_command: fdc.perp &= 0xfc; fdc.perp |= (fdc.params[0] & 0x03); } - // pclog("PERPENDICULAR: Set to: %02X\n", fdc.perp); + // fdc_log("PERPENDICULAR: Set to: %02X\n", fdc.perp); disctime = 0; return; @@ -1039,11 +1056,11 @@ bad_command: fdc.dtl = fdc.params[7]; fdc_implied_seek(); fdc.rw_track = fdc.params[1]; - // pclog("Reading sector (drive %i) (%i) (%i %i %i %i) (%i %i %i)\n", fdc.drive, fdc.params[0], fdc.params[1], fdc.params[2], fdc.params[3], fdc.params[4], fdc.params[5], fdc.params[6], fdc.params[7]); + fdc_log("Reading sector (drive %i) (%i) (%i %i %i %i) (%i %i %i)\n", fdc.drive, fdc.params[0], fdc.params[1], fdc.params[2], fdc.params[3], fdc.params[4], fdc.params[5], fdc.params[6], fdc.params[7]); if (((dma_mode(2) & 0x0C) == 0x00) && !fdc.pcjr && fdc.dma) { /* DMA is in verify mode, treat this like a VERIFY command. */ - // pclog("Verify-mode read!\n"); + fdc_log("Verify-mode read!\n"); fdc.tc = 1; fdc.deleted |= 2; } @@ -1103,12 +1120,12 @@ bad_command: fdc.gap = fdc.params[3]; fdc.dtl = 4000000; fdc.format_sectors = fdc.params[2]; - // pclog("Formatting with %i sectors per track\n", fdc.format_sectors); + // fdc_log("Formatting with %i sectors per track\n", fdc.format_sectors); fdc.format_n = fdc.params[1]; fdc.format_state = 1; fdc.pos = 0; fdc.stat = 0x10; - // pclog("FDC FORMAT: %02X %02X %02X %02X %02X\n", fdc.params[0], fdc.params[1], fdc.params[2], fdc.params[3], fdc.params[4]); + // fdc_log("FDC FORMAT: %02X %02X %02X %02X %02X\n", fdc.params[0], fdc.params[1], fdc.params[2], fdc.params[3], fdc.params[4]); break; case 0xf: /*Seek*/ @@ -1181,7 +1198,7 @@ bad_command: } else { - // pclog("Seeking to track %i...\n", fdc.params[1]); + fdc_log("Seeking to track %i...\n", fdc.params[1]); seek_time = ((int) (fdc.params[1] - fdc.pcn[fdc.params[0] & 3])) * seek_time_base * TIMER_USEC; if ((fdc.params[1] - fdc.pcn[fdc.params[0] & 3]) == 0) @@ -1233,7 +1250,7 @@ bad_command: case 7: if (!AT) return; fdc.rate=val&3; - // pclog("Rate now: %i\n", val & 3); + // fdc_log("Rate now: %i\n", val & 3); disc_3f7=val; return; @@ -1271,7 +1288,7 @@ uint8_t fdc_read(uint16_t addr, void *priv) break; case 2: temp = fdc.dor; - // pclog("Read DOR: %02X\n", fdc.dor); + // fdc_log("Read DOR: %02X\n", fdc.dor); break; case 3: drive = real_drive(fdc.dor & 3); @@ -1301,7 +1318,7 @@ uint8_t fdc_read(uint16_t addr, void *priv) return 0; } temp=fdc.stat; - // pclog("Read MSR: %02X\n", fdc.stat); + // fdc_log("Read MSR: %02X\n", fdc.stat); break; case 5: /*Data*/ fdc.stat&=~0x80; @@ -1313,15 +1330,15 @@ uint8_t fdc_read(uint16_t addr, void *priv) { temp = fdc_fifo_buf_read(); } - // pclog("Read DAT: %02X\n", temp); + // fdc_log("Read DAT: %02X\n", temp); break; } if (paramstogo) { paramstogo--; temp=fdc.res[10 - paramstogo]; - // pclog("Read result: %02X\n", temp); -// pclog("Read param %i %02X\n",10-paramstogo,temp); + // fdc_log("Read result: %02X\n", temp); +// fdc_log("Read param %i %02X\n",10-paramstogo,temp); if (!paramstogo) { fdc.stat=0x80; @@ -1339,7 +1356,7 @@ uint8_t fdc_read(uint16_t addr, void *priv) fdc.stat = 0x80; lastbyte=0; temp=fdc.dat; - // pclog("Read DAT: %02X\n", temp); + // fdc_log("Read DAT: %02X\n", temp); fdc.data_ready = 0; } /* What the heck is this even doing?! */ @@ -1363,7 +1380,7 @@ uint8_t fdc_read(uint16_t addr, void *priv) { temp |= 0x7F; } - // pclog("Read CCR: %02X\n", temp); + // fdc_log("Read CCR: %02X\n", temp); // printf("- DC %i %02X %02X %i %i - ",fdc.dor & 3, fdc.dor, 0x10 << (fdc.dor & 3), discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]); // discchanged[fdc.dor&1]=0; break; @@ -1457,14 +1474,14 @@ void fdc_callback() int old_sector = 0; int bad_end = 0; disctime = 0; -// pclog("fdc_callback %i %i\n", discint, disctime); +// fdc_log("fdc_callback %i %i\n", discint, disctime); // if (fdc.inread) -// rpclog("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins); +// rfdc_log("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins); switch (discint) { case -3: /*End of command with interrupt*/ // if (output) printf("EOC - interrupt!\n"); -//rpclog("EOC\n"); +//rfdc_log("EOC\n"); fdc_int(); fdc.stat = (fdc.stat & 0xf) | 0x80; return; @@ -1472,7 +1489,7 @@ void fdc_callback() fdc.stat = (fdc.stat & 0xf) | 0x80; return; case -1: /*Reset*/ -//rpclog("Reset\n"); +//rfdc_log("Reset\n"); fdc_int(); fdc.fintr = 0; memset(fdc.pcn, 0, 4); @@ -1487,7 +1504,7 @@ void fdc_callback() readflash = 1; fdc.eot[fdc.drive]--; fdc.read_track_sector.id.r++; -// pclog("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); +// fdc_log("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); if (!fdc.eot[fdc.drive] || fdc.tc) { fdc_poll_readwrite_finish(2); @@ -1531,7 +1548,7 @@ void fdc_callback() case 0x19: /*Scan low or equal*/ case 0x1C: /*Verify*/ case 0x1D: /*Scan high or equal*/ -// rpclog("Read data %i\n", fdc.tc); +// rfdc_log("Read data %i\n", fdc.tc); if ((discint == 0x11) || (discint == 0x19) || (discint == 0x1D)) { compare = 1; @@ -1687,7 +1704,7 @@ void fdc_callback() return; case 8: /*Sense interrupt status*/ -// pclog("Sense interrupt status %i\n", fdc_reset_stat); +// fdc_log("Sense interrupt status %i\n", fdc_reset_stat); fdc.stat = (fdc.stat & 0xf) | 0xd0; @@ -1718,7 +1735,7 @@ void fdc_callback() fdc.res[10] = fdc.pcn[fdc.res[9] & 3]; - // pclog("SENSE INTERRUPT STATUS: Results %02X %02X, ST0 %02X\n", fdc.res[9], fdc.res[10], fdc.st0); + // fdc_log("SENSE INTERRUPT STATUS: Results %02X %02X, ST0 %02X\n", fdc.res[9], fdc.res[10], fdc.st0); paramstogo = 2; discint = 0; @@ -1726,7 +1743,7 @@ void fdc_callback() return; case 0x0d: /*Format track*/ -// rpclog("Format\n"); +// rfdc_log("Format\n"); if (fdc.format_state == 1) { // ioc_fiq(IOC_FIQ_DISC_DATA); @@ -1737,7 +1754,7 @@ void fdc_callback() } else if (fdc.format_state == 2) { - // pclog("Format next stage track %i head %i n %i is_mfm %i gap %i sc %i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc_get_format_n(), fdc_is_mfm(), fdc_get_gap(), fdc_get_format_sectors()); + // fdc_log("Format next stage track %i head %i n %i is_mfm %i gap %i sc %i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc_get_format_n(), fdc_is_mfm(), fdc_get_gap(), fdc_get_format_sectors()); disc_format(fdc.drive, fdc.head, fdc.rate, fdc.params[4]); fdc.format_state = 3; } @@ -1768,7 +1785,7 @@ void fdc_callback() disctime = 2048 * (1 << TIMER_SHIFT); timer_update_outstanding(); fdc.stat = 0x80 | (1 << fdc.drive); -// pclog("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); +// fdc_log("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); return; case 0x0e: /*Dump registers*/ fdc.stat = (fdc.stat & 0xf) | 0xd0; @@ -1807,8 +1824,8 @@ void fdc_callback() fdc.pretrk = fdc.params[2]; fdc.fifo = (fdc.params[1] & 0x20) ? 0 : 1; fdc.tfifo = (fdc.params[1] & 0xF) + 1; - // pclog("CONFIGURE (%02X, %02X, %02X)\n", fdc.params[0], fdc.params[1], fdc.params[2]); - // pclog("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo); + // fdc_log("CONFIGURE (%02X, %02X, %02X)\n", fdc.params[0], fdc.params[1], fdc.params[2]); + // fdc_log("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo); fdc.stat = 0x80; disctime = 0; // picint(0x40); @@ -1840,7 +1857,7 @@ void fdc_callback() case 0xfc: /*Invalid*/ fdc.dat = fdc.st0 = 0x80; -// pclog("Inv!\n"); +// fdc_log("Inv!\n"); //picint(0x40); fdc.stat = (fdc.stat & 0xf) | 0xd0; // fdc.stat|=0xC0; @@ -1922,7 +1939,7 @@ int fdc_data(uint8_t data) if (fdc.data_ready) { fdc_overrun(); -// pclog("Overrun\n"); +// fdc_log("Overrun\n"); return -1; } @@ -1983,7 +2000,7 @@ void fdc_finishread() { fdc.inread = 0; // disctime = 200 * TIMER_USEC; -// rpclog("fdc_finishread\n"); +// rfdc_log("fdc_finishread\n"); } void fdc_track_finishread(int condition) @@ -1992,7 +2009,7 @@ void fdc_track_finishread(int condition) fdc.satisfying_sectors |= condition; fdc.inread = 0; fdc_callback(); -// rpclog("fdc_finishread\n"); +// rfdc_log("fdc_finishread\n"); } void fdc_sector_finishcompare(int satisfying) @@ -2001,7 +2018,7 @@ void fdc_sector_finishcompare(int satisfying) fdc.satisfying_sectors++; fdc.inread = 0; fdc_callback(); -// rpclog("fdc_finishread\n"); +// rfdc_log("fdc_finishread\n"); } void fdc_sector_finishread() @@ -2009,7 +2026,7 @@ void fdc_sector_finishread() fdc.stat = 0x10; fdc.inread = 0; fdc_callback(); -// rpclog("fdc_finishread\n"); +// rfdc_log("fdc_finishread\n"); } #if 0 @@ -2017,7 +2034,7 @@ void fdc_notfound() { fdc_error(5, 0); -// rpclog("c82c711_fdc_notfound\n"); +// rfdc_log("c82c711_fdc_notfound\n"); } #endif @@ -2050,14 +2067,14 @@ void fdc_datacrcerror() { fdc_error(0x20, 0x20); -// rpclog("c82c711_fdc_datacrcerror\n"); +// rfdc_log("c82c711_fdc_datacrcerror\n"); } void fdc_headercrcerror() { fdc_error(0x20, 0); -// rpclog("c82c711_fdc_headercrcerror\n"); +// rfdc_log("c82c711_fdc_headercrcerror\n"); } void fdc_wrongcylinder() @@ -2084,7 +2101,7 @@ int fdc_getdata(int last) if (fdc.written) { fdc_overrun(); -// pclog("Overrun\n"); +// fdc_log("Overrun\n"); return -1; } if (fdc.pcjr || !fdc.fifo) @@ -2129,7 +2146,7 @@ int fdc_getdata(int last) void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2) { - // pclog("SectorID %i %i %i %i\n", track, side, sector, size); + // fdc_log("SectorID %i %i %i %i\n", track, side, sector, size); fdc_int(); fdc.stat=0xD0; fdc.res[4]=(fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.drive; @@ -2145,7 +2162,7 @@ void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uin void fdc_indexpulse() { // ioc_irqa(IOC_IRQA_DISC_INDEX); -// rpclog("c82c711_fdc_indexpulse\n"); +// rfdc_log("c82c711_fdc_indexpulse\n"); } void fdc_init() diff --git a/src/ibm.h b/src/ibm.h index 02779a5ba..d9dffeec3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -535,11 +535,7 @@ int keybsenddelay; /*CD-ROM*/ -extern int cdrom_drive; -extern int old_cdrom_drive; extern int idecallback[4]; -extern int cdrom_enabled; -extern int scsi_cdrom_enabled; #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 diff --git a/src/ide.c b/src/ide.c index 6aa901a1c..7e641a3e4 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1,9 +1,6 @@ /* Copyright holders: Sarah Walker, Tenshi, SA1988 see COPYING for more details */ -#define CDROM_ISO 200 -#define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) - #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _GNU_SOURCE @@ -16,6 +13,7 @@ #include #include "86box.h" +#include "cdrom.h" #include "ibm.h" #include "io.h" #include "pic.h" @@ -66,18 +64,14 @@ #define WIN_READ_NATIVE_MAX 0xF8 /** Evaluate to non-zero if the currently selected drive is an ATAPI device */ -#define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) +// #define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) #define ATAPI_STATUS_IDLE 0 #define ATAPI_STATUS_COMMAND 1 #define ATAPI_STATUS_COMPLETE 2 -#define ATAPI_STATUS_DATA 3 -#define ATAPI_STATUS_PACKET_REQ 4 -#define ATAPI_STATUS_PACKET_RECEIVED 5 -#define ATAPI_STATUS_READCD 6 -#define ATAPI_STATUS_REQ_SENSE 7 +#define ATAPI_STATUS_DATA_IN 3 +#define ATAPI_STATUS_DATA_OUT 4 #define ATAPI_STATUS_ERROR 0x80 -#define ATAPI_STATUS_ERROR_2 0x81 enum { @@ -123,59 +117,60 @@ uint64_t hdt[128][3] = { { 306, 4, 17 }, { 615, 2, 17 }, { 306, 4, 26 }, { { 1930, 4, 62 }, { 967, 16, 31 }, { 1013, 10, 63 }, { 1218, 15, 36 }, { 654, 16, 63 }, { 659, 16, 63 }, { 702, 16, 63 }, { 1002, 13, 63 }, /* 112-119 */ { 854, 16, 63 }, { 987, 16, 63 }, { 995, 16, 63 }, { 1024, 16, 63 }, { 1036, 16, 63 }, { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } }; /* 119-127 */ -typedef struct IDE -{ - int type; - int board; - uint8_t atastat; - uint8_t error; - int secount,sector,cylinder,head,drive,cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; - int packlen; - int spt,hpc; - int tracks; - int packetstatus; - uint8_t asc; - int reset; - FILE *hdfile; - uint16_t buffer[65536]; - int irqstat; - int service; - int lba; - uint32_t lba_addr; - int skip512; - int blocksize, blockcount; - uint16_t dma_identify_data[3]; - int hdi,base; - int hdc_num; -} IDE; - IDE ide_drives[IDE_NUM]; IDE *ext_ide; char ide_fn[IDE_NUM][512]; -int (*ide_bus_master_read_sector)(int channel, uint8_t *data); -int (*ide_bus_master_write_sector)(int channel, uint8_t *data); +int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); +int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); void (*ide_bus_master_set_irq)(int channel); -static void callnonreadcd(IDE *ide); -static void callreadcd(IDE *ide); +static void atapi_callback(IDE *ide); static void atapicommand(int ide_board); int idecallback[4] = {0, 0, 0, 0}; int cur_ide[4]; -int atapi_command = 0; +int ide_do_log = 1; -int atapi_cdrom_channel = 2; +void ide_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_LOG + if (ide_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} uint8_t getstat(IDE *ide) { return ide->atastat; } +int ide_drive_is_cdrom(IDE *ide) +{ + if (atapi_cdrom_drives[ide->channel] >= CDROM_NUM) + { + return 0; + } + else + { + if (cdrom_drives[atapi_cdrom_drives[ide->channel]].enabled && !cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_mode & 1)) + { + return 1; + } + else + { + return 0; + } + } +} + int image_is_hdi(const char *s) { int i, len; @@ -210,12 +205,12 @@ static inline void ide_irq_raise(IDE *ide) return; } - // pclog("Raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); + // ide_log("Raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); if (!(ide->fdisk&2)) { picint(1 << ide_irq[ide->board]); - // if (ide->board && !ide->irqstat) pclog("IDE_IRQ_RAISE\n"); + // if (ide->board && !ide->irqstat) ide_log("IDE_IRQ_RAISE\n"); if (ide->board < 2) { @@ -228,17 +223,17 @@ static inline void ide_irq_raise(IDE *ide) ide->irqstat=1; ide->service=1; - // pclog("raising interrupt %i\n", 14 + ide->board); + // ide_log("raising interrupt %i\n", 14 + ide->board); } -static inline void ide_irq_lower(IDE *ide) +void ide_irq_lower(IDE *ide) { if ((ide->board > 3) || !(ide->irqstat)) { return; } - // pclog("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); + // ide_log("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); picintc(1 << ide_irq[ide->board]); ide->irqstat=0; @@ -258,7 +253,7 @@ void ide_irq_update(IDE *ide) mask = ide_irq[ide->board]; mask &= 7; - // pclog("Updating IRQ %i (%i) (board %i)\n", ide_irq[ide->board], mask, ide->board); + // ide_log("Updating IRQ %i (%i) (board %i)\n", ide_irq[ide->board], mask, ide->board); pending = (pic2.pend | pic2.ins); pending &= (1 << mask); @@ -309,8 +304,7 @@ ide_padstr(char *str, const char *src, int len) * this length will be padded with spaces. * @param src Source string */ -static void -ide_padstr8(uint8_t *buf, int buf_size, const char *src) +void ide_padstr8(uint8_t *buf, int buf_size, const char *src) { int i; @@ -333,6 +327,10 @@ ide_padstr8(uint8_t *buf, int buf_size, const char *src) static void ide_identify(IDE *ide) { int c, h, s; + uint8_t device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; + + device_identify[6] = ide->channel + 0x30; + ide_log("IDE Identify: %s\n", device_identify); memset(ide->buffer, 0, 512); @@ -347,7 +345,7 @@ static void ide_identify(IDE *ide) ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "86BoxHD", 40); /* Model */ + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[20] = 3; /*Buffer type*/ ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ @@ -386,13 +384,27 @@ static void ide_identify(IDE *ide) static void ide_atapi_identify(IDE *ide) { memset(ide->buffer, 0, 512); + uint8_t device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; + uint8_t cdrom_id = atapi_cdrom_drives[ide->channel]; + + device_identify[6] = cdrom_id + 0x30; + ide_log("ATAPI Identify: %s\n", device_identify); ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ - ide_padstr((char *) (ide->buffer + 27), "86BoxCD", 40); /* Model */ + ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ + + if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) + { + ide->buffer[49] |= 0x100; /* DMA supported */ + ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[62] = ide->dma_identify_data[0]; + ide->buffer[63] = ide->dma_identify_data[1]; + ide->buffer[88] = ide->dma_identify_data[2]; + } } /* @@ -531,19 +543,51 @@ static void loadhd(IDE *ide, int d, const char *fn) void ide_set_signature(IDE *ide) { - ide->secount=1; + uint8_t cdrom_id = atapi_cdrom_drives[cur_ide[ide->board]]; ide->sector=1; ide->head=0; - ide->cylinder=(IDE_DRIVE_IS_CDROM(ide) ? 0xEB14 : ((ide->type == IDE_HDD) ? 0 : 0xFFFF)); - if (ide->type == IDE_HDD) + if (ide_drive_is_cdrom(ide)) { - ide->drive = 0; + cdrom_set_signature(cdrom_id); } + else + { + ide->secount=1; + ide->cylinder=((ide->type == IDE_HDD) ? 0 : 0xFFFF); + if (ide->type == IDE_HDD) + { + ide->drive = 0; + } + } +} + +int ide_cdrom_is_pio_only(IDE *ide) +{ + uint8_t cdrom_id = atapi_cdrom_drives[cur_ide[ide->board]]; + if (!ide_drive_is_cdrom(ide)) + { + return 0; + } + if (cdrom_drives[cdrom_id].bus_mode & 2) + { + return 0; + } + return 1; } int ide_set_features(IDE *ide) { - uint8_t val = ide->secount & 7; + uint8_t cdrom_id = cur_ide[ide->board]; + uint8_t val = 0; + + if (ide_drive_is_cdrom(ide)) + { + val = cdrom[cdrom_id].phase & 7; + } + else + { + val = ide->secount & 7; + } if (ide->type == IDE_NONE) return 0; @@ -578,7 +622,7 @@ int ide_set_features(IDE *ide) ide->dma_identify_data[2] = 0x3f; break; case 2: - if ((ide->type == IDE_CDROM) || (ide->board >= 2)) + if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) { return 0; } @@ -587,7 +631,7 @@ int ide_set_features(IDE *ide) ide->dma_identify_data[2] = 0x3f; break; case 4: - if ((ide->type == IDE_CDROM) || (ide->board >= 2)) + if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) { return 0; } @@ -624,32 +668,34 @@ void ide_set_sector(IDE *ide, int64_t sector_num) void resetide(void) { int d; + + build_atapi_cdrom_map(); /* Close hard disk image files (if previously open) */ for (d = 0; d < IDE_NUM; d++) { + ide_drives[d].channel = d; ide_drives[d].type = IDE_NONE; if (ide_drives[d].hdfile != NULL) { fclose(ide_drives[d].hdfile); ide_drives[d].hdfile = NULL; } + if (ide_drive_is_cdrom(&ide_drives[d])) + { + cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT; + } ide_drives[d].atastat = READY_STAT | DSC_STAT; ide_drives[d].service = 0; ide_drives[d].board = d >> 1; } - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= 0xFD; /* Clear changed flag for CDROM AUDIO mode page. */ - memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ - idecallback[0]=idecallback[1]=0; idecallback[2]=idecallback[3]=0; for (d = 0; d < IDE_NUM; d++) { - ide_drives[d].packetstatus = 0xFF; - - if ((atapi_cdrom_channel == d) && cdrom_enabled && !scsi_cdrom_enabled) + if (ide_drive_is_cdrom(&ide_drives[d])) { ide_drives[d].type = IDE_CDROM; } @@ -674,85 +720,67 @@ void resetide(void) { cur_ide[d] = d << 1; } - - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; - - SCSISense.UnitAttention = 0; } -int idetimes=0; +int idetimes = 0; + void writeidew(int ide_board, uint16_t val) { + int ret = 0; IDE *ide = &ide_drives[cur_ide[ide_board]]; #if 0 - if (ide->type == IDE_CDROM) + if (ide_drive_is_cdrom(ide)) { - pclog("CD-ROM write data: %04X\n", val); + ide_log("CD-ROM write data: %04X\n", val); } #endif - /* Some software issue excess writes after the 12 bytes required by the command, this will have all of them ignored. */ - if (ide->packetstatus && (ide->packetstatus != ATAPI_STATUS_PACKET_REQ)) - { - return; - } - - // pclog("Write IDEw %04X\n",val); + // ide_log("Write IDEw %04X\n",val); ide->buffer[ide->pos >> 1] = val; - ide->pos+=2; + ide->pos += 2; - if (ide->packetstatus == ATAPI_STATUS_PACKET_REQ) + if (ide->command == WIN_PACKETCMD) { - if ((ide->pos>=prefix_len+4) && (page_flags[page_current] & PAGE_CHANGEABLE)) + if (!ide_drive_is_cdrom(ide)) { - mode_pages_in[page_current][ide->pos - prefix_len - 4] = ((uint8_t *) ide->buffer)[ide->pos - 2]; - mode_pages_in[page_current][ide->pos - prefix_len - 3] = ((uint8_t *) ide->buffer)[ide->pos - 1]; + return; } - if (ide->pos>=(ide->packlen+2)) + + if (cdrom_write(cur_ide[ide_board], val)) { - ide->packetstatus = ATAPI_STATUS_PACKET_RECEIVED; + ide_irq_raise(ide); + } + + if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) + { + idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; + } + return; + } + else + { + if (ide->pos>=512) + { + ide->pos=0; + ide->atastat = BUSY_STAT; timer_process(); - idecallback[ide_board]=6*IDE_TIME; + if (ide->command == WIN_WRITE_MULTIPLE) + { + callbackide(ide_board); + } + else + { + idecallback[ide_board]=6*IDE_TIME; + } timer_update_outstanding(); - // pclog("Packet over!\n"); - ide_irq_lower(ide); } - return; - } - else if (ide->packetstatus == ATAPI_STATUS_PACKET_RECEIVED) - { - return; - } - else if (ide->command == WIN_PACKETCMD && ide->pos>=0xC) - { - ide->pos=0; - ide->atastat = BUSY_STAT; - ide->packetstatus = ATAPI_STATUS_COMMAND; - timer_process(); - callbackide(ide_board); - timer_update_outstanding(); - } - else if (ide->pos>=512) - { - ide->pos=0; - ide->atastat = BUSY_STAT; - timer_process(); - if (ide->command == WIN_WRITE_MULTIPLE) - { - callbackide(ide_board); - } - else - { - idecallback[ide_board]=6*IDE_TIME; - } - timer_update_outstanding(); } } void writeidel(int ide_board, uint32_t val) { - // pclog("WriteIDEl %08X\n", val); + // ide_log("WriteIDEl %08X\n", val); writeidew(ide_board, val); writeidew(ide_board, val >> 16); } @@ -762,7 +790,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) IDE *ide = &ide_drives[cur_ide[ide_board]]; IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; - // pclog("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, cpu_state.pc, ins); + ide_log("WriteIDE %04X %02X from %04X(%08X):%08X %i\n", addr, val, CS, cs, cpu_state.pc, ins); addr|=0x90; addr&=0xFFF7; @@ -774,14 +802,47 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) writeidew(ide_board, val | (val << 8)); return; - case 0x1F1: /* Features */ - ide->cylprecomp = val; - ide_other->cylprecomp = val; + /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ + case 0x1F1: /* Features */ + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].features = val; + } + else + { + ide->cylprecomp = val; + } + + if (ide_drive_is_cdrom(ide_other)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].features = val; + } + else + { + ide_other->cylprecomp = val; + } return; case 0x1F2: /* Sector count */ - ide->secount = val; - ide_other->secount = val; + if (ide_drive_is_cdrom(ide)) + { + ide_log("Sector count write: %i\n", val); + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase = val; + } + else + { + ide->secount = val; + } + + if (ide_drive_is_cdrom(ide_other)) + { + ide_log("Other sector count write: %i\n", val); + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].phase = val; + } + else + { + ide_other->secount = val; + } return; case 0x1F3: /* Sector */ @@ -792,17 +853,51 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) return; case 0x1F4: /* Cylinder low */ - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - ide_other->cylinder = (ide_other->cylinder&0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF00; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= val; + } + else + { + ide->cylinder = (ide->cylinder & 0xFF00) | val; + ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); + } + + if (ide_drive_is_cdrom(ide_other)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF00; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= val; + } + else + { + ide_other->cylinder = (ide_other->cylinder&0xFF00) | val; + ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); + } return; case 0x1F5: /* Cylinder high */ - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= (val << 8); + } + else + { + ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); + ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); + } + + if (ide_drive_is_cdrom(ide_other)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF; + cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= (val << 8); + } + else + { + ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); + ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); + } return; case 0x1F6: /* Drive/Head */ @@ -820,13 +915,21 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide->cylinder = ide_other->cylinder = 0; ide->reset = ide_other->reset = 0; - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { - ide->cylinder=0xEB14; + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]].error = 1; + cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]].request_length = 0xEB14; + cdrom[atapi_cdrom_drives[ide->channel]].callback = 0; } - if (IDE_DRIVE_IS_CDROM(ide_other)) + if (ide_drive_is_cdrom(ide_other)) { - ide_other->cylinder=0xEB14; + cdrom[atapi_cdrom_drives[ide_other->channel]].status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide_other->channel]].error = 1; + cdrom[atapi_cdrom_drives[ide_other->channel]].phase = 1; + cdrom[atapi_cdrom_drives[ide_other->channel]].request_length = 0xEB14; + cdrom[atapi_cdrom_drives[ide_other->channel]].callback = 0; } idecallback[ide_board] = 0; @@ -851,40 +954,59 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case 0x1F7: /* Command register */ if (ide->type == IDE_NONE) { + if (val == WIN_SRST) + { + callbackide(ide_board); + } ide->error=1; return; } #if 0 - if (ide->type == IDE_CDROM) + if (ide_drive_is_cdrom(ide_other)) { - pclog("Write CD-ROM ATA command: %02X\n", val); + ide_log("Write CD-ROM ATA command: %02X\n", val); } #endif ide_irq_lower(ide); ide->command=val; - // pclog("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); + // ide_log("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); ide->error=0; switch (val) { case WIN_SRST: /* ATAPI Device Reset */ - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { - ide->atastat = BUSY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; } else { ide->atastat = READY_STAT; } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 100*IDE_TIME; + } idecallback[ide_board]=100*IDE_TIME; timer_update_outstanding(); return; case WIN_RESTORE: case WIN_SEEK: - ide->atastat = READY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT; + } + else + { + ide->atastat = READY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 100*IDE_TIME; + } idecallback[ide_board]=100*IDE_TIME; timer_update_outstanding(); return; @@ -900,14 +1022,25 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_READ: case WIN_READ_NORETRY: case WIN_READ_DMA: - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } idecallback[ide_board]=200*IDE_TIME; timer_update_outstanding(); return; case WIN_WRITE_MULTIPLE: - if (!ide->blocksize && (ide->type != IDE_CDROM)) + if (!ide->blocksize && !ide_drive_is_cdrom(ide)) { fatal("Write_MULTIPLE - blocksize = 0\n"); } @@ -915,33 +1048,83 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_WRITE: case WIN_WRITE_NORETRY: - ide->atastat = DRQ_STAT | DSC_STAT | READY_STAT; - ide->pos=0; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT | DSC_STAT | READY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; + } + else + { + ide->atastat = DRQ_STAT | DSC_STAT | READY_STAT; + ide->pos=0; + } return; case WIN_WRITE_DMA: - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } idecallback[ide_board]=200*IDE_TIME; timer_update_outstanding(); return; case WIN_VERIFY: case WIN_VERIFY_ONCE: - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } idecallback[ide_board]=200*IDE_TIME; timer_update_outstanding(); return; case WIN_FORMAT: - ide->atastat = DRQ_STAT; - ide->pos=0; + if (ide_drive_is_cdrom(ide)) + { + // cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT; + // cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; + goto ide_bad_command; + } + else + { + ide->atastat = DRQ_STAT; + ide->pos=0; + } return; case WIN_SPECIFY: /* Initialize Drive Parameters */ - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; + } idecallback[ide_board]=30*IDE_TIME; timer_update_outstanding(); return; @@ -953,8 +1136,19 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_STANDBYNOW1: case WIN_SETIDLE1: /* Idle */ case WIN_CHECKPOWERMODE1: - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; + } idecallback[ide_board]=30*IDE_TIME; timer_update_outstanding(); return; @@ -962,34 +1156,53 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_IDENTIFY: /* Identify Device */ case WIN_SET_FEATURES: case WIN_READ_NATIVE_MAX: - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } idecallback[ide_board]=200*IDE_TIME; timer_update_outstanding(); return; case WIN_PACKETCMD: /* ATAPI Packet */ -#if 0 - ide->packetstatus = ATAPI_STATUS_IDLE; - ide->atastat = BUSY_STAT; - timer_process(); - // idecallback[ide_board]=1;//30*IDE_TIME; - idecallback[ide_board]=30*IDE_TIME; - timer_update_outstanding(); - ide->pos=0; -#endif - /* Skip the command callbackwait, and process immediately. */ - ide->packetstatus = ATAPI_STATUS_IDLE; - readcdmode=0; - ide->pos=0; - ide->secount = 1; - ide->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT); + /* Skip the command callback wait, and process immediately. */ + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].packet_status = CDROM_PHASE_IDLE; + cdrom[atapi_cdrom_drives[ide->channel]].pos=0; + cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]].status & ERR_STAT); + } + else + { + ide->pos=0; + ide->secount = 1; + ide->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT); + } return; case 0xF0: default: - ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; +ide_bad_command: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]].error = ABRT_ERR; + } + else + { + ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + } ide_irq_raise(ide); return; } @@ -999,6 +1212,10 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) if ((ide->fdisk & 4) && !(val&4) && (ide->type != IDE_NONE || ide_other->type != IDE_NONE)) { timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 500*IDE_TIME; + } idecallback[ide_board]=500*IDE_TIME; timer_update_outstanding(); @@ -1010,8 +1227,12 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) { ide->reset = 1; } + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } ide->atastat = ide_other->atastat = BUSY_STAT; - // pclog("IDE Reset %i\n", ide_board); + // ide_log("IDE Reset %i\n", ide_board); } ide->fdisk = ide_other->fdisk = val; ide_irq_update(ide); @@ -1025,6 +1246,8 @@ uint8_t readide(int ide_board, uint16_t addr) IDE *ide = &ide_drives[cur_ide[ide_board]]; uint8_t temp; uint16_t tempw; + + uint8_t temp2; addr|=0x90; addr&=0xFFF7; @@ -1045,7 +1268,10 @@ uint8_t readide(int ide_board, uint16_t addr) tempw = readidew(ide_board); temp = tempw & 0xff; break; - + + /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), + Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), + and Bit 0 = ILI (illegal length indication). */ case 0x1F1: /* Error */ if (ide->type == IDE_NONE) { @@ -1053,10 +1279,30 @@ uint8_t readide(int ide_board, uint16_t addr) } else { - temp = ide->error; + if (ide_drive_is_cdrom(ide)) + { + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].error; + } + else + { + temp = ide->error; + } } break; + /* For ATAPI: + Bit 0: Command or Data: + Data if clear, Command if set; + Bit 1: I/OB + Direction: + To device if set; + From device if clear. + IO DRQ CoD + 0 1 1 Ready to accept command packet + 1 1 1 Message - ready to send message to host + 1 1 0 Data to host + 0 1 0 Data from host + 1 0 1 Status. */ case 0x1F2: /* Sector count */ if (ide->type == IDE_NONE) { @@ -1064,7 +1310,14 @@ uint8_t readide(int ide_board, uint16_t addr) } else { - temp = (uint8_t)ide->secount; + if (ide_drive_is_cdrom(ide)) + { + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase; + } + else + { + temp = ide->secount; + } } break; @@ -1086,7 +1339,14 @@ uint8_t readide(int ide_board, uint16_t addr) } else { - temp = (uint8_t)(ide->cylinder&0xFF); + if (ide_drive_is_cdrom(ide)) + { + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length & 0xff; + } + else + { + temp = ide->cylinder & 0xff; + } } break; @@ -1097,7 +1357,14 @@ uint8_t readide(int ide_board, uint16_t addr) } else { - temp = (uint8_t)(ide->cylinder>>8); + if (ide_drive_is_cdrom(ide)) + { + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length >> 8; + } + else + { + temp = ide->cylinder >> 8; + } } break; @@ -1112,12 +1379,14 @@ uint8_t readide(int ide_board, uint16_t addr) } break; + /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is + DF (drive fault). */ case 0x1F7: /* Status */ ide_irq_lower(ide); - if (ide->type == IDE_CDROM) + if (ide_drive_is_cdrom(ide)) { - temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - // pclog("Read CD-ROM status: %02X\n", temp); + temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + // ide_log("Read CD-ROM status: %02X\n", temp); } else { @@ -1131,9 +1400,10 @@ uint8_t readide(int ide_board, uint16_t addr) temp = DSC_STAT; break; } - if (ide->type == IDE_CDROM) + if (ide_drive_is_cdrom(ide)) { - temp = (ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); + // ide_log("Read CD-ROM alternate status: %02X\n", temp); } else { @@ -1141,65 +1411,82 @@ uint8_t readide(int ide_board, uint16_t addr) } break; } - // /* if (ide_board) */ pclog("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,cpu_state.pc,ide_board); + /* if (ide_board) */ ide_log("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,cpu_state.pc,ide_board); return temp; // fatal("Bad IDE read %04X\n", addr); } +uint8_t cdb[16]; + +int old_len = 0; + +int total_read = 0; + +int block_total = 0; +int all_blocks_total = 0; + uint16_t readidew(int ide_board) { IDE *ide = &ide_drives[cur_ide[ide_board]]; uint16_t temp; - + temp = ide->buffer[ide->pos >> 1]; - ide->pos+=2; - if ((ide->command == WIN_PACKETCMD) && ((ide->packetstatus == ATAPI_STATUS_REQ_SENSE) || (ide->packetstatus==8))) + ide->pos += 2; + + if (ide->command == WIN_PACKETCMD) { - callnonreadcd(ide); - return temp; + if (!ide_drive_is_cdrom(ide)) + { + ide_log("Drive not CD-ROM (position: %i)\n", ide->pos); + return 0; + } + temp = cdrom_read(cur_ide[ide_board]); + if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) + { + idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; + } } - if ((ide->pos>=512 && ide->command != WIN_PACKETCMD) || (ide->command == WIN_PACKETCMD && ide->pos>=ide->packlen)) + if (ide->pos>=512 && ide->command != WIN_PACKETCMD) { ide->pos=0; - if (ide->command == WIN_PACKETCMD)// && ide.packetstatus==6) + ide->atastat = READY_STAT | DSC_STAT; + if (ide_drive_is_cdrom(ide)) { - callreadcd(ide); + // cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].pos = 0; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE; } - else + ide->packetstatus = ATAPI_STATUS_IDLE; + if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) { - ide->atastat = READY_STAT | DSC_STAT; - ide->packetstatus = ATAPI_STATUS_IDLE; - if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) { - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) + ide_next_sector(ide); + ide->atastat = BUSY_STAT; + timer_process(); + if (ide->command == WIN_READ_MULTIPLE) { - ide_next_sector(ide); - ide->atastat = BUSY_STAT; - timer_process(); - if (ide->command == WIN_READ_MULTIPLE) - { - callbackide(ide_board); - } - else - { - idecallback[ide_board]=6*IDE_TIME; - } - timer_update_outstanding(); + callbackide(ide_board); } + else + { + idecallback[ide_board]=6*IDE_TIME; + } + timer_update_outstanding(); } } } - // pclog("Read IDEw %04X\n",temp); + // ide_log("Read IDEw %04X\n",temp); return temp; } uint32_t readidel(int ide_board) { uint16_t temp; - // pclog("Read IDEl %i\n", ide_board); + // ide_log("Read IDEl %i\n", ide_board); temp = readidew(ide_board); return temp | (readidew(ide_board) << 16); } @@ -1214,9 +1501,15 @@ void callbackide(int ide_board) int c; ext_ide = ide; int64_t snum; + int cdrom_id; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback = 0; + } + if (ide->command==0x30) times30++; - // /*if (ide_board) */pclog("CALLBACK %02X %i %i %i\n",ide->command,times30,ide->reset,cur_ide[ide_board]); + /*if (ide_board) */ide_log("CALLBACK %02X %i %i %i\n",ide->command,times30,ide->reset,cur_ide[ide_board]); if (ide->reset) { @@ -1228,30 +1521,44 @@ void callbackide(int ide_board) ide->cylinder = ide_other->cylinder = 0; ide->reset = ide_other->reset = 0; - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { - ide->cylinder=0xEB14; - cdrom->stop(); + cdrom_id = atapi_cdrom_drives[cur_ide[ide_board]]; + cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id].error = 1; + cdrom[cdrom_id].phase = 1; + cdrom[cdrom_id].request_length=0xEB14; + if (cdrom_drives[cdrom_id].handler->stop) + { + cdrom_drives[cdrom_id].handler->stop(cdrom_id); + } } if (ide->type == IDE_NONE) { ide->cylinder=0xFFFF; - cdrom->stop(); } - if (IDE_DRIVE_IS_CDROM(ide_other)) + if (ide_drive_is_cdrom(ide_other)) { - ide_other->cylinder=0xEB14; - cdrom->stop(); + cdrom_id = atapi_cdrom_drives[cur_ide[ide_board] ^ 1]; + cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id].error = 1; + cdrom[cdrom_id].phase = 1; + cdrom[cdrom_id].request_length=0xEB14; + if (cdrom_drives[cdrom_id].handler->stop) + { + cdrom_drives[cdrom_id].handler->stop(cdrom_id); + } } if (ide_other->type == IDE_NONE) { ide_other->cylinder=0xFFFF; - cdrom->stop(); } - // pclog("Reset callback\n"); + // ide_log("Reset callback\n"); return; } + cdrom_id = atapi_cdrom_drives[cur_ide[ide_board]]; + switch (ide->command) { /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, @@ -1262,12 +1569,12 @@ void callbackide(int ide_board) ide->secount = ide->sector = 1; ide_set_signature(ide); - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { - ide->atastat = 0; + cdrom_reset(cdrom_id); } ide_irq_raise(ide); - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { ide->service = 0; } @@ -1275,19 +1582,26 @@ void callbackide(int ide_board) case WIN_RESTORE: case WIN_SEEK: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } case WIN_NOP: case WIN_STANDBYNOW1: case WIN_SETIDLE1: - ide->atastat = READY_STAT | DSC_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + } + else + { + ide->atastat = READY_STAT | DSC_STAT; + } ide_irq_raise(ide); return; case WIN_CHECKPOWERMODE1: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -1298,7 +1612,7 @@ void callbackide(int ide_board) case WIN_READ: case WIN_READ_NORETRY: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { ide_set_signature(ide); goto abort_cmd; @@ -1316,7 +1630,7 @@ void callbackide(int ide_board) return; case WIN_READ_DMA: - if (IDE_DRIVE_IS_CDROM(ide) || (ide->board >= 2)) + if (ide_drive_is_cdrom(ide) || (ide->board >= 2)) { goto abort_cmd; } @@ -1325,9 +1639,9 @@ void callbackide(int ide_board) fread(ide->buffer, 512, 1, ide->hdfile); ide->pos=0; - if (ide_bus_master_read_sector) + if (ide_bus_master_read) { - if (ide_bus_master_read_sector(ide_board, (uint8_t *)ide->buffer)) + if (ide_bus_master_read(ide_board, (uint8_t *)ide->buffer, 512)) { idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ } @@ -1360,7 +1674,7 @@ void callbackide(int ide_board) command has been executed or when Read Multiple commands are disabled, the Read Multiple operation is rejected with an Aborted Com- mand error. */ - if (IDE_DRIVE_IS_CDROM(ide) || !ide->blocksize) + if (ide_drive_is_cdrom(ide) || !ide->blocksize) { goto abort_cmd; } @@ -1372,7 +1686,7 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; if (!ide->blockcount) { - // pclog("Read multiple int\n"); + // ide_log("Read multiple int\n"); ide_irq_raise(ide); } ide->blockcount++; @@ -1386,7 +1700,7 @@ void callbackide(int ide_board) case WIN_WRITE: case WIN_WRITE_NORETRY: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -1410,14 +1724,14 @@ void callbackide(int ide_board) return; case WIN_WRITE_DMA: - if (IDE_DRIVE_IS_CDROM(ide) || (ide_board >= 2)) + if (ide_drive_is_cdrom(ide) || (ide_board >= 2)) { goto abort_cmd; } - if (ide_bus_master_write_sector) + if (ide_bus_master_write) { - if (ide_bus_master_write_sector(ide_board, (uint8_t *)ide->buffer)) + if (ide_bus_master_write(ide_board, (uint8_t *)ide->buffer, 512)) { idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ } @@ -1448,7 +1762,7 @@ void callbackide(int ide_board) return; case WIN_WRITE_MULTIPLE: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -1478,7 +1792,7 @@ void callbackide(int ide_board) case WIN_VERIFY: case WIN_VERIFY_ONCE: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -1489,12 +1803,12 @@ void callbackide(int ide_board) return; case WIN_FORMAT: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } addr = ide_get_sector(ide) * 512; - // pclog("Format cyl %i head %i offset %08X %08X %08X secount %i\n",ide.cylinder,ide.head,addr,addr>>32,addr,ide.secount); + // ide_log("Format cyl %i head %i offset %08X %08X %08X secount %i\n",ide.cylinder,ide.head,addr,addr>>32,addr,ide.secount); fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); memset(ide->buffer, 0, 512); for (c=0;csecount;c++) @@ -1511,9 +1825,9 @@ void callbackide(int ide_board) ide_set_signature(ide); ide->error=1; /*No error detected*/ - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { - ide->atastat = 0; + cdrom[cdrom_id].status = 0; } else { @@ -1523,7 +1837,7 @@ void callbackide(int ide_board) return; case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -1534,25 +1848,26 @@ void callbackide(int ide_board) return; case WIN_PIDENTIFY: /* Identify Packet Device */ - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { ide_atapi_identify(ide); - ide->pos=0; - ide->error=0; - ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; + ide->pos = 0; + cdrom[cdrom_id].pos = 0; + cdrom[cdrom_id].error = 0; + cdrom[cdrom_id].status = DRQ_STAT | READY_STAT | DSC_STAT; ide_irq_raise(ide); return; } goto abort_cmd; case WIN_SET_MULTIPLE_MODE: - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } ide->blocksize = ide->secount; ide->atastat = READY_STAT | DSC_STAT; - // pclog("Set multiple mode - %i\n", ide->blocksize); + // ide_log("Set multiple mode - %i\n", ide->blocksize); ide_irq_raise(ide); return; @@ -1561,12 +1876,19 @@ void callbackide(int ide_board) { goto abort_cmd; } - ide->atastat = READY_STAT | DSC_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + } + else + { + ide->atastat = READY_STAT | DSC_STAT; + } ide_irq_raise(ide); return; case WIN_READ_NATIVE_MAX: - if (ide->type != IDE_HDD) + if ((ide->type != IDE_HDD) || ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -1584,7 +1906,7 @@ void callbackide(int ide_board) ide_set_signature(ide); goto abort_cmd; } - if (IDE_DRIVE_IS_CDROM(ide)) + if (ide_drive_is_cdrom(ide)) { ide_set_signature(ide); goto abort_cmd; @@ -1599,83 +1921,34 @@ void callbackide(int ide_board) return; case WIN_PACKETCMD: /* ATAPI Packet */ - if (!IDE_DRIVE_IS_CDROM(ide)) + if (!ide_drive_is_cdrom(ide)) { goto abort_cmd; } - if (ide->packetstatus == ATAPI_STATUS_IDLE) + if (cdrom_phase_callback(atapi_cdrom_drives[cur_ide[ide_board]])) { - // pclog("ATAPI_STATUS_IDLE\n"); - readcdmode=0; - ide->pos=0; - ide->secount = 1; - ide->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT); - } - else if (ide->packetstatus == ATAPI_STATUS_COMMAND) - { - // pclog("ATAPI_STATUS_COMMAND\n"); - ide->atastat = BUSY_STAT|(ide->atastat&ERR_STAT); - atapicommand(ide_board); - } - else if (ide->packetstatus == ATAPI_STATUS_COMPLETE) - { - // pclog("ATAPI_STATUS_COMPLETE\n"); - ide->atastat = READY_STAT; - ide->secount=3; - ide_irq_raise(ide); - } - else if (ide->packetstatus == ATAPI_STATUS_DATA) - { - // pclog("ATAPI_STATUS_DATA\n"); - ide->atastat = READY_STAT|DRQ_STAT|(ide->atastat&ERR_STAT); - ide_irq_raise(ide); - ide->packetstatus=0xFF; - } - else if (ide->packetstatus == ATAPI_STATUS_PACKET_REQ) - { - // pclog("ATAPI_STATUS_PACKET_REQ\n"); - ide->atastat = 0x58 | (ide->atastat & ERR_STAT); - ide_irq_raise(ide); - ide->pos=2; - } - else if (ide->packetstatus == ATAPI_STATUS_PACKET_RECEIVED) - { - // pclog("ATAPI_STATUS_PACKET_RECEIVED\n"); - atapicommand(ide_board); - } - else if (ide->packetstatus == ATAPI_STATUS_READCD) /*READ CD callback*/ - { - // pclog("ATAPI_STATUS_READCD\n"); - ide->atastat = DRQ_STAT|(ide->atastat&ERR_STAT); - ide_irq_raise(ide); - } - else if (ide->packetstatus == ATAPI_STATUS_REQ_SENSE) /*REQUEST SENSE callback #1*/ - { - // pclog("ATAPI_STATUS_REQ_SENSE\n"); - ide->atastat = 0x58 | (ide->atastat & ERR_STAT); - ide_irq_raise(ide); - } - else if (ide->packetstatus == ATAPI_STATUS_ERROR) /*Error callback*/ - { - // pclog("ATAPI_STATUS_ERROR\n"); - ide->atastat = READY_STAT | ERR_STAT; - ide_irq_raise(ide); - } - else if (ide->packetstatus == ATAPI_STATUS_ERROR_2) /*Error callback with atastat already set - needed for the disc change stuff.*/ - { - // pclog("ATAPI_STATUS_ERROR_2\n"); - ide->atastat = ERR_STAT; ide_irq_raise(ide); } + idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; + ide_log("IDE callback now: %i\n", idecallback[ide_board]); return; } abort_cmd: ide->command = 0; - ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - ide->pos = 0; + if (ide_drive_is_cdrom(ide)) + { + cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[cdrom_id].error = ABRT_ERR; + cdrom[cdrom_id].pos = 0; + } + else + { + ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + ide->pos = 0; + } ide_irq_raise(ide); } @@ -1703,1253 +1976,6 @@ void ide_callback_qua() callbackide(3); } -/*ATAPI CD-ROM emulation*/ -uint8_t atapi_prev; -int toctimes=0; - -void atapi_command_send_init(IDE *ide, uint8_t command, int req_length, int alloc_length) -{ - if (ide->cylinder == 0xffff) - { - ide->cylinder = 0xfffe; - } - - if ((ide->cylinder & 1) && !(alloc_length <= ide->cylinder)) - { - ide->cylinder--; - } - - if (alloc_length < 0) - { - fatal("Allocation length < 0\n"); - } - if (alloc_length == 0) - { - alloc_length = ide->cylinder; - } - - /* No atastat setting: PCem actually emulates the callback cycle. */ - if (alloc_length != 0) - { - ide->secount = 2; - } - - // no bytes transferred yet - ide->pos = 0; - - if ((ide->cylinder > req_length) || (ide->cylinder == 0)) - { - ide->cylinder = req_length; - } - if (ide->cylinder > alloc_length) - { - ide->cylinder = alloc_length; - } -} - -static void atapi_command_ready(int ide_board, int packlen) -{ - IDE *ide = &ide_drives[cur_ide[ide_board]]; - ide->packetstatus = ATAPI_STATUS_REQ_SENSE; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=packlen; -} - -static void atapi_sense_clear(int command, int ignore_ua) -{ - if ((SCSISense.SenseKey == SENSE_UNIT_ATTENTION) || ignore_ua) - { - atapi_prev=command; - SCSISense.SenseKey=0; - SCSISense.Asc=0; - SCSISense.Ascq=0; - } -} - -void atapi_cmd_error(IDE *ide, uint8_t sensekey, uint8_t asc, uint8_t ascq) -{ - ide->error = (sensekey << 4) | ABRT_ERR; - if (SCSISense.UnitAttention) - { - ide->error |= MCR_ERR; - } - ide->atastat = READY_STAT | ERR_STAT; - ide->secount = (ide->secount & ~7) | 3; - ide->packetstatus = 0x80; - idecallback[ide->board]=50*IDE_TIME; -} - -static void atapi_not_ready(IDE *ide) -{ - SCSISense.SenseKey = SENSE_NOT_READY; - SCSISense.Asc = ASC_MEDIUM_NOT_PRESENT; - SCSISense.Ascq = 0; - atapi_cmd_error(ide, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); -} - -static void atapi_illegal_opcode(IDE *ide) -{ - SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST; - SCSISense.Asc = ASC_ILLEGAL_OPCODE; - SCSISense.Ascq = 0; - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE, 0); -} - -static void atapi_invalid_field(IDE *ide) -{ - SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST; - SCSISense.Asc = ASC_INV_FIELD_IN_CMD_PACKET; - SCSISense.Ascq = 0; - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0); - ide->atastat = 0x53; -} - -static void atapi_illegal_mode(IDE *ide) -{ - SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST; - SCSISense.Asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - SCSISense.Ascq = 0; - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0); -} - -static void atapi_incompatible_format(IDE *ide) -{ - SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST; - SCSISense.Asc = ASC_INCOMPATIBLE_FORMAT; - SCSISense.Ascq = 0; - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_INCOMPATIBLE_FORMAT, 0); -} - -static void atapi_data_phase_error(IDE *ide) -{ - SCSISense.SenseKey = SENSE_ILLEGAL_REQUEST; - SCSISense.Asc = ASC_DATA_PHASE_ERROR; - SCSISense.Ascq = 0; - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, ASC_DATA_PHASE_ERROR, 0); -} - -static void atapicommand(int ide_board) -{ - IDE *ide = &ide_drives[cur_ide[ide_board]]; - uint8_t *idebufferb = (uint8_t *) ide->buffer; - uint8_t rcdmode = 0; - int c; - int len; - int msf; - int pos=0; - unsigned char temp; - uint32_t size; - uint8_t page_code; - int max_len; - unsigned idx = 0; - unsigned size_idx; - unsigned preamble_len; - int toc_format; - int temp_command; - int alloc_length; - int completed; - uint8_t index = 0; - int media; - int format; - int ret; - int real_pos; - int track = 0; - uint8_t cdb[12]; - -#if 0 - pclog("ATAPI command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n",idebufferb[0],SCSISense.SenseKey,SCSISense.Asc,SCSISense.Ascq,ins,SCSISense.UnitAttention); - - int CdbLength; - for (CdbLength = 1; CdbLength < 12; CdbLength++) - { - pclog("ATAPI CDB[%d] = 0x%02X\n", CdbLength, idebufferb[CdbLength]); - } -#endif - - memcpy(cdb, idebufferb, 12); - - msf=idebufferb[1]&2; - SectorLen=0; - - if (cdrom->medium_changed()) - { - // pclog("Medium has changed...\n"); - SCSICDROM_Insert(); - } - - if (!cdrom->ready() && SCSISense.UnitAttention) - { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - SCSISense.UnitAttention = 0; - } - - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (SCSISense.UnitAttention == 1) - { - // pclog("Unit attention now 2\n"); - SCSISense.UnitAttention = 2; - if (!(SCSICommandTable[idebufferb[0]] & ALLOW_UA)) - { - // pclog("UNIT ATTENTION: Command not allowed to pass through\n"); - atapi_cmd_error(ide, SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); - return; - } - } - else if (SCSISense.UnitAttention == 2) - { - if (idebufferb[0]!=GPCMD_REQUEST_SENSE) - { - // pclog("Unit attention now 0\n"); - SCSISense.UnitAttention = 0; - } - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - the UNIT ATTENTION condition if it's set. */ - if (idebufferb[0]!=GPCMD_REQUEST_SENSE) - { - atapi_sense_clear(idebufferb[0], 1); - } - - /* Next it's time for NOT READY. */ - if ((SCSICommandTable[idebufferb[0]] & CHECK_READY) && !cdrom->ready()) - { - atapi_not_ready(ide); - return; - } - - // pclog("Continuing with command\n"); - - prev_status = cd_status; - cd_status = cdrom->status(); - if (((prev_status == CD_STATUS_PLAYING) || (prev_status == CD_STATUS_PAUSED)) && ((cd_status != CD_STATUS_PLAYING) && (cd_status != CD_STATUS_PAUSED))) - { - completed = 1; - } - else - { - completed = 0; - } - - switch (idebufferb[0]) - { - case GPCMD_TEST_UNIT_READY: - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_REQUEST_SENSE: /* Used by ROS 4+ */ - alloc_length = idebufferb[4]; - temp_command = idebufferb[0]; - - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) - { - memset(idebufferb, 0, alloc_length); - } - - idebufferb[0]=0x80|0x70; - - if ((SCSISense.SenseKey > 0) && ((cd_status < CD_STATUS_PLAYING) || (cd_status == CD_STATUS_STOPPED))) - { - if (completed) - { - idebufferb[2]=SENSE_ILLEGAL_REQUEST; - idebufferb[12]=ASC_AUDIO_PLAY_OPERATION; - idebufferb[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } - else - { - idebufferb[2]=SCSISense.SenseKey; - idebufferb[12]=SCSISense.Asc; - idebufferb[13]=SCSISense.Ascq; - } - } - else if ((SCSISense.SenseKey == 0) && (cd_status >= CD_STATUS_PLAYING) && (cd_status != CD_STATUS_STOPPED)) - { - idebufferb[2]=SENSE_ILLEGAL_REQUEST; - idebufferb[12]=ASC_AUDIO_PLAY_OPERATION; - idebufferb[13]=(cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; - } - else - { - if (SCSISense.UnitAttention) - { - idebufferb[2]=SENSE_UNIT_ATTENTION; - idebufferb[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - idebufferb[13]=0; - } - } - - // pclog("Reporting sense: %02X %02X %02X\n", idebufferb[2], idebufferb[12], idebufferb[13]); - - idebufferb[7]=10; - - if (idebufferb[2] == SENSE_UNIT_ATTENTION) - { - /* If the last remaining sense is unit attention, clear - that condition. */ - SCSISense.UnitAttention = 0; - } - - /* Clear the sense stuff as per the spec. */ - atapi_sense_clear(temp_command, 0); - - if (alloc_length == 0) - { - // pclog("REQUEST SENSE - empty allocation\n"); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - else - { - atapi_command_send_init(ide, temp_command, 18, alloc_length); - atapi_command_ready(ide_board, 18); - } - break; - - case GPCMD_SET_SPEED: - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_MECHANISM_STATUS: - len=(idebufferb[7]<<16)|(idebufferb[8]<<8)|idebufferb[9]; - - memset(idebufferb, 0, 8); - idebufferb[5] = 1; - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - else - { - atapi_command_send_init(ide, cdb[0], 8, alloc_length); - atapi_command_ready(ide_board, 8); - } - break; - - case GPCMD_READ_TOC_PMA_ATIP: - toctimes++; - toc_format = idebufferb[2] & 0xf; - - if (toc_format == 0) - { - toc_format = (idebufferb[9]>>6) & 3; - } - - switch (toc_format) - { - case 0: /*Normal*/ - len=idebufferb[8]+(idebufferb[7]<<8); - len=cdrom->readtoc(idebufferb,idebufferb[6],msf,len,0); - break; - case 1: /*Multi session*/ - len=idebufferb[8]+(idebufferb[7]<<8); - len=cdrom->readtoc_session(idebufferb,msf,len); - idebufferb[0]=0; idebufferb[1]=0xA; - break; - case 2: /*Raw*/ - len=idebufferb[8]+(idebufferb[7]<<8); - len=cdrom->readtoc_raw(idebufferb,msf,len); - break; - default: - atapi_invalid_field(ide); - return; - } - - ide->packetstatus = ATAPI_STATUS_DATA; - ide->cylinder=len; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=len; - // pclog("READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", toc_format, ide->cylinder, idebufferb[1]); - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - return; - - case GPCMD_READ_CD: - case GPCMD_READ_CD_MSF: - // pclog("Read CD : start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n",idebufferb[2],idebufferb[3],idebufferb[4],idebufferb[5],idebufferb[6],idebufferb[7],idebufferb[8],idebufferb[9]); - if (idebufferb[0] == GPCMD_READ_CD_MSF) - { - SectorLBA=MSFtoLBA(idebufferb[3],idebufferb[4],idebufferb[5]); - SectorLen=MSFtoLBA(idebufferb[6],idebufferb[7],idebufferb[8]); - - SectorLen -= SectorLBA; - SectorLen++; - - cdrom_sector_ismsf = 1; - } - else - { - SectorLen=(idebufferb[6]<<16)|(idebufferb[7]<<8)|idebufferb[8]; - SectorLBA=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - - cdrom_sector_ismsf = 0; - } - - cdrom_sector_type = (idebufferb[1] >> 2) & 7; - cdrom_sector_flags = idebufferb[9] || (((uint32_t) idebufferb[10]) << 8); - - if (SectorLBA > (cdrom->size() - 1)) - { - // pclog("Trying to read beyond the end of disc\n"); - atapi_invalid_field(ide); - break; - } - - ret = cdrom_read_data(idebufferb); - - if (!ret) - { - atapi_invalid_field(ide); - break; - } - - readflash=1; - - SectorLBA++; - SectorLen--; - if (SectorLen >= 0) - { - ide->packetstatus = ATAPI_STATUS_READCD; - } - else - { - ide->packetstatus = ATAPI_STATUS_DATA; - } - ide->cylinder=cdrom_sector_size; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=cdrom_sector_size; - return; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - // pclog("Read 10 : start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n",idebufferb[2],idebufferb[3],idebufferb[4],idebufferb[5],idebufferb[6],idebufferb[7],idebufferb[8],idebufferb[9]); - cdrom_sector_ismsf = 0; - - if (idebufferb[0] == GPCMD_READ_6) - { - SectorLen=idebufferb[4]; - SectorLBA=((((uint32_t) idebufferb[1]) & 0x1f)<<16)|(((uint32_t) idebufferb[2])<<8)|((uint32_t) idebufferb[3]); - } - else if (idebufferb[0] == GPCMD_READ_10) - { - SectorLen=(idebufferb[7]<<8)|idebufferb[8]; - SectorLBA=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - } - else - { - SectorLen=(((uint32_t) idebufferb[6])<<24)|(((uint32_t) idebufferb[7])<<16)|(((uint32_t) idebufferb[8])<<8)|((uint32_t) idebufferb[9]); - SectorLBA=(((uint32_t) idebufferb[2])<<24)|(((uint32_t) idebufferb[3])<<16)|(((uint32_t) idebufferb[4])<<8)|((uint32_t) idebufferb[5]); - } - - // pclog("Reading sector: %i, length: %i\n", SectorLen, SectorLBA); - - if (SectorLBA > (cdrom->size() - 1)) - { - // pclog("Trying to read beyond the end of disc\n"); - atapi_invalid_field(ide); - break; - } - - if (!SectorLen) - { - // pclog("All done - callback set\n"); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=20*IDE_TIME; - break; - } - - cdrom_sector_type = 6; - cdrom_sector_flags = 0x10; - - ret = cdrom_read_data(idebufferb); - - if (!ret) - { - atapi_invalid_field(ide); - break; - } - - readflash=1; - SectorLBA++; - SectorLen--; - if (SectorLen >= 0) - { - ide->packetstatus = ATAPI_STATUS_READCD; - } - else - { - ide->packetstatus = ATAPI_STATUS_DATA; - } - ide->cylinder=2048; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=2048; - return; - - case GPCMD_READ_HEADER: - if (cdrom->read_header) - { - cdrom->read_header(idebufferb, idebufferb); - } - else - { - SectorLen=(idebufferb[7]<<8)|idebufferb[8]; - SectorLBA=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - if (msf) - { - real_pos = cdrom_LBAtoMSF_accurate(ide); - } - else - { - real_pos = SectorLBA; - } - idebufferb[4] = (real_pos >> 24); - idebufferb[5] = ((real_pos >> 16) & 0xff); - idebufferb[6] = ((real_pos >> 8) & 0xff); - idebufferb[7] = real_pos & 0xff; - idebufferb[0]=1; /*2048 bytes user data*/ - idebufferb[1]=idebufferb[2]=idebufferb[3]=0; - } - - len = 8; - ide->packetstatus = ATAPI_STATUS_DATA; - ide->cylinder=8; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=8; - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - temp_command = idebufferb[0]; - - if (temp_command == GPCMD_MODE_SENSE_6) - { - len=idebufferb[4]; - } - else - { - len=(idebufferb[8]|(idebufferb[7]<<8)); - } - - temp=idebufferb[2] & 0x3F; - - memset(idebufferb, 0, len); - alloc_length = len; - - if (!(mode_sense_pages[temp] & IMPLEMENTED)) - { - atapi_invalid_field(ide); - return; - } - - if (temp_command == GPCMD_MODE_SENSE_6) - { - len = SCSICDROMModeSense(idebufferb,4,temp); - if (len > alloc_length) - { - len = alloc_length; - } - idebufferb[0] = len - 1; - idebufferb[1]=3; /*120mm data CD-ROM*/ - } - else - { - len = SCSICDROMModeSense(idebufferb,8,temp); - if (len > alloc_length) - { - len = alloc_length; - } - idebufferb[0]=(len - 2)>>8; - idebufferb[1]=(len - 2)&255; - idebufferb[2]=3; /*120mm data CD-ROM*/ - } - - atapi_command_send_init(ide, temp_command, len, alloc_length); - - atapi_command_ready(ide_board, len); - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - return; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (ide->packetstatus == ATAPI_STATUS_PACKET_RECEIVED) - { - ide->atastat = READY_STAT; - ide->secount=3; - // pclog("Recieve data packet!\n"); - ide_irq_raise(ide); - ide->packetstatus=0xFF; - ide->pos=0; - } - else - { - if (idebufferb[0] == GPCMD_MODE_SELECT_6) - { - len=idebufferb[4]; - prefix_len = 6; - } - else - { - len=(idebufferb[7]<<8)|idebufferb[8]; - prefix_len = 10; - } - page_current = idebufferb[2]; - if (page_flags[page_current] & PAGE_CHANGEABLE) - { - page_flags[page_current] |= PAGE_CHANGED; - } - ide->packetstatus = ATAPI_STATUS_PACKET_REQ; - ide->cylinder=len; - ide->secount=0; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=len; - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - } - return; - - case GPCMD_GET_CONFIGURATION: - temp_command = idebufferb[0]; - /* XXX: could result in alignment problems in some architectures */ - len = (idebufferb[7]<<8)|idebufferb[8]; - alloc_length = len; - - index = 0; - - /* only feature 0 is supported */ - if (idebufferb[2] != 0 || idebufferb[3] != 0) - { - atapi_invalid_field(ide); - return; - } - - /* - * XXX: avoid overflow for io_buffer if len is bigger than - * the size of that buffer (dimensioned to max number of - * sectors to transfer at once) - * - * Only a problem if the feature/profiles grow. - */ - if (alloc_length > 512) /* XXX: assume 1 sector */ - { - alloc_length = 512; - } - - memset(idebufferb, 0, alloc_length); - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (len > CD_MAX_SECTORS) - { - idebufferb[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; - idebufferb[7] = MMC_PROFILE_DVD_ROM & 0xff; - } - else if (len <= CD_MAX_SECTORS) - { - idebufferb[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; - idebufferb[7] = MMC_PROFILE_CD_ROM & 0xff; - } - idebufferb[10] = 0x02 | 0x01; /* persistent and current */ - alloc_length = 12; /* headers: 8 + 4 */ - alloc_length += SCSICDROMSetProfile(idebufferb, &index, MMC_PROFILE_DVD_ROM); - alloc_length += SCSICDROMSetProfile(idebufferb, &index, MMC_PROFILE_CD_ROM); - idebufferb[0] = ((alloc_length-4) >> 24) & 0xff; - idebufferb[1] = ((alloc_length-4) >> 16) & 0xff; - idebufferb[2] = ((alloc_length-4) >> 8) & 0xff; - idebufferb[3] = (alloc_length-4) & 0xff; - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - else - { - atapi_command_send_init(ide, temp_command, len, alloc_length); - atapi_command_ready(ide_board, len); - } - break; - - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - gesn_cdb = (void *)idebufferb; - gesn_event_header = (void *)idebufferb; - - /* It is fine by the MMC spec to not support async mode operations. */ - if (!(gesn_cdb->polled & 0x01)) - { /* asynchronous mode */ - /* Only polling is supported, asynchronous mode is not. */ - atapi_invalid_field(ide); - return; - } - - /* polling mode operation */ - - /* - * These are the supported events. - * - * We currently only support requests of the 'media' type. - * Notification class requests and supported event classes are bitmasks, - * but they are built from the same values as the "notification class" - * field. - */ - gesn_event_header->supported_events = 1 << GESN_MEDIA; - - /* - * We use |= below to set the class field; other bits in this byte - * are reserved now but this is useful to do if we have to use the - * reserved fields later. - */ - gesn_event_header->notification_class = 0; - - /* - * Responses to requests are to be based on request priority. The - * notification_class_request_type enum above specifies the - * priority: upper elements are higher prio than lower ones. - */ - if (gesn_cdb->class & (1 << GESN_MEDIA)) - { - gesn_event_header->notification_class |= GESN_MEDIA; - used_len = SCSICDROMEventStatus(idebufferb); - } - else - { - gesn_event_header->notification_class = 0x80; /* No event available */ - used_len = sizeof(*gesn_event_header); - } - gesn_event_header->len = used_len - sizeof(*gesn_event_header); - - atapi_command_send_init(ide, cdb[0], used_len, used_len); - atapi_command_ready(ide_board, used_len); - break; - - case GPCMD_READ_DISC_INFORMATION: - if (cdrom->read_disc_information) - { - cdrom->read_disc_information(idebufferb); - } - else - { - memset(idebufferb, 0, 34); - memset(idebufferb, 1, 9); - idebufferb[0] = 0; - idebufferb[1] = 32; - idebufferb[2] = 0xe; /* last session complete, disc finalized */ - idebufferb[7] = 0x20; /* unrestricted use */ - idebufferb[8] = 0x00; /* CD-ROM */ - } - - len=34; - if (len > alloc_length) - { - len = alloc_length; - } - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - else - { - ide->packetstatus = ATAPI_STATUS_DATA; - ide->secount=2; - ide->cylinder=len; - ide->pos=0; - ide->packlen=len; - idecallback[ide_board]=60*IDE_TIME; - } - break; - - case GPCMD_READ_TRACK_INFORMATION: - max_len = idebufferb[7]; - max_len <<= 8; - max_len |= idebufferb[8]; - - track = ((uint32_t) idebufferb[2]) << 24; - track |= ((uint32_t) idebufferb[3]) << 16; - track |= ((uint32_t) idebufferb[4]) << 8; - track |= (uint32_t) idebufferb[5]; - - if (cdrom->read_track_information) - { - ret = cdrom->read_track_information(idebufferb, idebufferb); - - if (!ret) - { - atapi_invalid_field(ide); - return; - } - - len = idebufferb[0]; - len <<= 8; - len |= idebufferb[1]; - len += 2; - } - else - { - if (((idebufferb[1] & 0x03) != 1) || (track != 1)) - { - atapi_invalid_field(ide); - return; - } - - len = 36; - - memset(idebufferb, 0, 36); - idebufferb[1] = 34; - idebufferb[2] = 1; /* track number (LSB) */ - idebufferb[3] = 1; /* session number (LSB) */ - idebufferb[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ - idebufferb[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ - idebufferb[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ - idebufferb[24] = (cdrom->size() >> 24) & 0xff; /* track size */ - idebufferb[25] = (cdrom->size() >> 16) & 0xff; /* track size */ - idebufferb[26] = (cdrom->size() >> 8) & 0xff; /* track size */ - idebufferb[27] = cdrom->size() & 0xff; /* track size */ - } - - if (len > max_len) - { - len = max_len; - idebufferb[0] = ((max_len - 2) >> 8) & 0xff; - idebufferb[1] = (max_len - 2) & 0xff; - } - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - else - { - ide->packetstatus = ATAPI_STATUS_DATA; - ide->cylinder=len; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=60*IDE_TIME; - ide->packlen=len; - } - break; - - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_12: - case GPCMD_PLAY_AUDIO_MSF: - if (idebufferb[0] == GPCMD_PLAY_AUDIO_10) - { - pos=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - len=(idebufferb[7]<<8)|idebufferb[8]; - } - else if (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) - { - /* This is apparently deprecated in the ATAPI spec, and apparently - has been since 1995 (!). Hence I'm having to guess most of it. */ - pos=(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - len=(idebufferb[6]<<16)|(idebufferb[7]<<8)|idebufferb[8]; - } - else - { - pos=(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - len=(idebufferb[7]<<16)|(idebufferb[8]<<8)|idebufferb[9]; - } - - if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cd_status <= CD_STATUS_DATA_ONLY) || - !cdrom->is_track_audio(pos, (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) - { - atapi_illegal_mode(ide); - break; - } - - cdrom->playaudio(pos, len, (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_READ_SUBCHANNEL: - if (idebufferb[3] > 3) - { - // pclog("Read subchannel check condition %02X\n",idebufferb[3]); - atapi_invalid_field(ide); - break; - } - - switch(idebufferb[3]) - { - case 0: - alloc_length = 4; - break; - case 1: - alloc_length = 16; - break; - default: - alloc_length = 24; - break; - } - - if (cdrom->read_subchannel) - { - cdrom->read_subchannel(idebufferb, idebufferb); - len = alloc_length; - } - else - { - temp = idebufferb[3] & 3; - temp |= (idebufferb[2] & 0x40); - memset(idebufferb, 24, 0); - pos = 0; - idebufferb[pos++]=0; - idebufferb[pos++]=0; /*Audio status*/ - idebufferb[pos++]=0; idebufferb[pos++]=0; /*Subchannel length*/ - idebufferb[pos++]=temp & 3; /*Format code*/ - if ((temp & 3) == 1) - { - idebufferb[1]=cdrom->getcurrentsubchannel(&idebufferb[5],msf); - } - if (!(temp & 0x40) || ((temp & 3) == 0)) - { - len=4; - } - else - { - len = alloc_length; - } - } - ide->packetstatus = ATAPI_STATUS_DATA; - ide->cylinder=len; - ide->secount=2; - ide->pos=0; - idecallback[ide_board]=1000*IDE_TIME; - ide->packlen=len; - break; - - case GPCMD_READ_DVD_STRUCTURE: - temp_command = idebufferb[0]; - media = idebufferb[1]; - format = idebufferb[7]; - - len = (((uint32_t) idebufferb[6])<<24)|(((uint32_t) idebufferb[7])<<16)|(((uint32_t) idebufferb[8])<<8)|((uint32_t) idebufferb[9]); - alloc_length = len; - - if (format < 0xff) - { - if (len <= CD_MAX_SECTORS) - { - atapi_incompatible_format(ide); - break; - } - else - { - atapi_invalid_field(ide); - return; - } - } - - memset(idebufferb, 0, (alloc_length > 256 * 512 + 4) ? (256 * 512 + 4) : alloc_length); - - switch (format) - { - case 0x00 ... 0x7f: - case 0xff: - - if (media == 0) - { - ret = SCSICDROMReadDVDStructure(format, idebufferb, idebufferb); - - if (ret < 0) - { - atapi_cmd_error(ide, SENSE_ILLEGAL_REQUEST, -ret, 0); - } - else - { - atapi_command_send_init(ide, temp_command, len, alloc_length); - atapi_command_ready(ide_board, len); - } - break; - } - /* TODO: BD support, fall through for now */ - - /* Generic disk structures */ - case 0x80: /* TODO: AACS volume identifier */ - case 0x81: /* TODO: AACS media serial number */ - case 0x82: /* TODO: AACS media identifier */ - case 0x83: /* TODO: AACS media key block */ - case 0x90: /* TODO: List of recognized format layers */ - case 0xc0: /* TODO: Write protection status */ - default: - atapi_invalid_field(ide); - return; - } - break; - - case GPCMD_START_STOP_UNIT: - switch(idebufferb[4] & 3) - { - case 0: /* Stop the disc. */ - cdrom->stop(); - break; - case 1: /* Start the disc and read the TOC. */ - cdrom->medium_changed(); /* This causes a TOC reload. */ - break; - case 2: /* Eject the disc if possible. */ - cdrom->stop(); -#ifndef __unix - win_cdrom_eject(); -#endif - break; - case 3: /* Load the disc (close tray). */ -#ifndef __unix - win_cdrom_reload(); -#else - cdrom->load(); -#endif - break; - } - - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_INQUIRY: - page_code = idebufferb[2]; - max_len = idebufferb[4]; - alloc_length = max_len; - temp_command = idebufferb[0]; - - if (idebufferb[1] & 1) - { - preamble_len = 4; - size_idx = 3; - - idebufferb[idx++] = 05; - idebufferb[idx++] = page_code; - idebufferb[idx++] = 0; - - idx++; - - switch (page_code) - { - case 0x00: - idebufferb[idx++] = 0x00; - idebufferb[idx++] = 0x83; - break; - case 0x83: - if (idx + 24 > max_len) - { - atapi_data_phase_error(ide); - return; - } - - idebufferb[idx++] = 0x02; - idebufferb[idx++] = 0x00; - idebufferb[idx++] = 0x00; - idebufferb[idx++] = 20; - ide_padstr8(idebufferb + idx, 20, "53R141"); /* Serial */ - idx += 20; - - if (idx + 72 > max_len) - { - goto atapi_out; - } - idebufferb[idx++] = 0x02; - idebufferb[idx++] = 0x01; - idebufferb[idx++] = 0x00; - idebufferb[idx++] = 68; - ide_padstr8(idebufferb + idx, 8, "86Box"); /* Vendor */ - idx += 8; - ide_padstr8(idebufferb + idx, 40, "86BoxCD v1.0"); /* Product */ - idx += 40; - ide_padstr8(idebufferb + idx, 20, "53R141"); /* Product */ - idx += 20; - break; - default: - atapi_invalid_field(ide); - return; - } - } - else - { - preamble_len = 5; - size_idx = 4; - - memset(idebufferb, 0, 8); - idebufferb[0] = 5; /*CD-ROM*/ - idebufferb[1] = 0x80; /*Removable*/ - idebufferb[3] = 0x21; - idebufferb[4] = 31; - - ide_padstr8(idebufferb + 8, 8, "86Box"); /* Vendor */ - ide_padstr8(idebufferb + 16, 16, "86BoxCD"); /* Product */ - ide_padstr8(idebufferb + 32, 4, emulator_version); /* Revision */ - idx = 36; - } - -atapi_out: - idebufferb[size_idx] = idx - preamble_len; - len=idx; - if (len > alloc_length) - { - len = alloc_length; - } - - if (len == 0) - { - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - } - else - { - atapi_command_send_init(ide, temp_command, len, alloc_length); - atapi_command_ready(ide_board, len); - } - break; - - case GPCMD_PREVENT_REMOVAL: - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_PAUSE_RESUME: - if (idebufferb[8] & 1) - { - cdrom->resume(); - } - else - { - cdrom->pause(); - } - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - if (idebufferb[0] == GPCMD_SEEK_6) - { - pos=(idebufferb[2]<<8)|idebufferb[3]; - } - else - { - pos=(idebufferb[2]<<24)|(idebufferb[3]<<16)|(idebufferb[4]<<8)|idebufferb[5]; - } - cdrom->seek(pos); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - case GPCMD_READ_CDROM_CAPACITY: - atapi_command_send_init(ide, temp_command, 8, 8); - if (cdrom->read_capacity) - { - cdrom->read_capacity(idebufferb); - } - else - { - size = cdrom->size() - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(idebufferb, 0, 8); - idebufferb[0] = (size >> 24) & 0xff; - idebufferb[1] = (size >> 16) & 0xff; - idebufferb[2] = (size >> 8) & 0xff; - idebufferb[3] = size & 0xff; - idebufferb[6] = 8; /* 2048 = 0x0800 */ - } - len=8; - atapi_command_ready(ide_board, len); - break; - - case GPCMD_STOP_PLAY_SCAN: - cdrom->stop(); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide_board]=50*IDE_TIME; - break; - - default: - atapi_illegal_opcode(ide); - break; - } - - // pclog("SCSI phase: %02X, length: %i\n", ide->secount, ide->cylinder); -} - -static void callnonreadcd(IDE *ide) /* Callabck for non-Read CD commands */ -{ - ide_irq_lower(ide); - if (ide->pos >= ide->packlen) - { - // pclog("Command finished, setting callback\n"); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide->board]=20*IDE_TIME; - } - else - { - // pclog("Command not finished, keep sending data\n"); - ide->atastat = BUSY_STAT; - ide->packetstatus = ATAPI_STATUS_REQ_SENSE; - ide->cylinder=2; - ide->secount=2; - idecallback[ide->board]=60*IDE_TIME; - } -} - -static void callreadcd(IDE *ide) -{ - int ret; - - ide_irq_lower(ide); - if (SectorLen<=0) - { - // pclog("All done - callback set\n"); - ide->packetstatus = ATAPI_STATUS_COMPLETE; - idecallback[ide->board]=20*IDE_TIME; - return; - } - // pclog("Continue readcd! %i blocks left\n",SectorLen); - // pclog("Reading sector: %i, length: %i\n", SectorLen, SectorLBA); - ide->atastat = BUSY_STAT; - - ret = cdrom_read_data((uint8_t *) ide->buffer); - readflash=1; - - SectorLBA++; - SectorLen--; - ide->packetstatus = ATAPI_STATUS_READCD; - ide->cylinder=cdrom_sector_size; - ide->secount=2; - ide->pos=0; - idecallback[ide->board]=60*IDE_TIME; - ide->packlen=cdrom_sector_size; -} - - void ide_write_pri(uint16_t addr, uint8_t val, void *priv) { writeide(0, addr, val); @@ -3120,15 +2146,15 @@ void ide_init() { ide_pri_enable(); ide_sec_enable(); - ide_bus_master_read_sector = ide_bus_master_write_sector = NULL; + ide_bus_master_read = ide_bus_master_write = NULL; timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); } -void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel)) +void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)) { - ide_bus_master_read_sector = read_sector; - ide_bus_master_write_sector = write_sector; + ide_bus_master_read = read; + ide_bus_master_write = write; ide_bus_master_set_irq = set_irq; } diff --git a/src/ide.h b/src/ide.h index c25fa5ce5..0bd0fcac0 100644 --- a/src/ide.h +++ b/src/ide.h @@ -4,7 +4,35 @@ #ifndef __IDE__ #define __IDE__ -struct IDE; +typedef struct IDE +{ + int type; + int board; + uint8_t atastat; + uint8_t error; + int secount,sector,cylinder,head,drive,cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; + int packlen; + int spt,hpc; + int tracks; + int packetstatus; + uint8_t asc; + int reset; + FILE *hdfile; + uint16_t buffer[65536]; + int irqstat; + int service; + int lba; + int channel; + uint32_t lba_addr; + int skip512; + int blocksize, blockcount; + uint16_t dma_identify_data[3]; + int hdi,base; + int hdc_num; +} IDE; extern void writeide(int ide_board, uint16_t addr, uint8_t val); extern void writeidew(int ide_board, uint16_t val); @@ -23,7 +51,7 @@ extern void ide_pri_disable(); extern void ide_sec_disable(); extern void ide_ter_disable(); extern void ide_qua_disable(); -extern void ide_set_bus_master(int (*read_sector)(int channel, uint8_t *data), int (*write_sector)(int channel, uint8_t *data), void (*set_irq)(int channel)); +extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)); extern int ideboard; @@ -34,6 +62,13 @@ extern int idecallback[4]; extern char ide_fn[IDE_NUM][512]; -extern int atapi_cdrom_channel; +void ide_irq_lower(IDE *ide); + +IDE ide_drives[IDE_NUM]; + +void ide_padstr8(uint8_t *buf, int buf_size, const char *src); + +void win_cdrom_eject(uint8_t id); +void win_cdrom_reload(uint8_t id); #endif //__IDE__ diff --git a/src/model.c b/src/model.c index 1b9868484..64562f7a2 100644 --- a/src/model.c +++ b/src/model.c @@ -1,7 +1,11 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ +#include +#include + #include "ibm.h" +#include "cdrom.h" #include "cpu.h" #include "mem.h" #include "model.h" @@ -403,11 +407,28 @@ void at_opti495_init() opti495_init(); } +void secondary_ide_check() +{ + int i = 0; + int secondary_cdroms = 0; + + for (i = 0; i < CDROM_NUM; i++) + { + if ((cdrom_drives[i].ide_channel >= 2) && (cdrom_drives[i].ide_channel <= 3) && !cdrom_drives[i].bus_type) + { + secondary_cdroms++; + } + if (!secondary_cdroms) ide_sec_disable(); + } +} + void at_ali1429_init() { + at_init(); ali1429_init(); - if (atapi_cdrom_channel <= 1) ide_sec_disable(); + + secondary_ide_check(); } /* void at_um8881f_init() @@ -422,7 +443,7 @@ void at_dtk486_init() at_init(); memregs_init(); sis85c471_init(); - if (atapi_cdrom_channel <= 1) ide_sec_disable(); + secondary_ide_check(); } void at_sis496_init() @@ -464,7 +485,7 @@ void at_586mc1_init() i430lx_init(); sio_init(1); device_add(&intel_flash_bxt_device); - if (atapi_cdrom_channel <= 1) ide_sec_disable(); + secondary_ide_check(); } void at_plato_init() diff --git a/src/mouse.h b/src/mouse.h index 29a19b78e..c91cf25ff 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -10,6 +10,8 @@ int mouse_get_type(int mouse); #define MOUSE_TYPE_AMSTRAD 2 #define MOUSE_TYPE_OLIM24 3 +#define MOUSE_TYPE_IF_MASK 3 + #define MOUSE_TYPE_3BUTTON (1 << 31) typedef struct diff --git a/src/ne2000.c b/src/ne2000.c index 961bff795..ca393b274 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -249,6 +249,7 @@ int ne2000_do_log = 0; void ne2000_log(const char *format, ...) { +#ifdef ENABLE_NE2000_LOG if (ne2000_do_log) { va_list ap; @@ -257,6 +258,7 @@ void ne2000_log(const char *format, ...) va_end(ap); fflush(stdout); } +#endif } static void ne2000_setirq(ne2000_t *ne2000, int irq) diff --git a/src/pc.c b/src/pc.c index 7e7a9e4e2..13408d206 100644 --- a/src/pc.c +++ b/src/pc.c @@ -9,6 +9,7 @@ #include "device.h" #include "ali1429.h" +#include "cdrom.h" #include "cdrom-ioctl.h" #include "disc.h" #include "mem.h" @@ -59,8 +60,6 @@ int window_w, window_h, window_x, window_y, window_remember; int start_in_fullscreen = 0; -int scsi_cdrom_enabled; -int cdrom_enabled; int CPUID; int vid_resize, vid_api; @@ -207,7 +206,7 @@ void initpc(int argc, char *argv[]) { char *p; char *config_file = NULL; - int c; + int c, i; FILE *ff; // allegro_init(); get_executable_name(pcempath,511); @@ -271,6 +270,41 @@ void initpc(int argc, char *argv[]) device_init(); timer_reset(); + + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type) + { + SCSIReset(cdrom_drives[i].scsi_device_id); + } + + if (cdrom_drives[i].host_drive == 0) + { + cdrom_null_open(i, cdrom_drives[i].host_drive); + } + else + { + if (cdrom_drives[i].host_drive == 200) + { + ff = fopen(cdrom_iso[i].iso_path, "rb"); + if (ff) + { + fclose(ff); + iso_open(i, cdrom_iso[i].iso_path); + } + else + { + cdrom_drives[i].host_drive = 0; + cdrom_null_open(i, cdrom_drives[i].host_drive); + } + } + else + { + ioctl_open(i, cdrom_drives[i].host_drive); + } + } + } + sound_reset(); fdc_init(); disc_init(); @@ -294,41 +328,13 @@ void initpc(int argc, char *argv[]) //loadfont(); loadnvr(); sound_init(); + resetide(); - if (buslogic_enabled) - { - SCSIReset(scsi_cdrom_id); - device_add(&BuslogicDevice); - } - - if ((cdrom_drive == -1) || (cdrom_drive == 0)) - cdrom_null_open(cdrom_drive); - else + if (buslogic_enabled) { - if (cdrom_drive == 200) - { - ff = fopen(iso_path, "rb"); - if (ff) - { - fclose(ff); - iso_open(iso_path); - } - else - { -#if __unix - cdrom_drive = -1; -#else - cdrom_drive = 0; -#endif - cdrom_null_open(cdrom_drive); - } - } - else - { - ioctl_open(cdrom_drive); - } - } - + device_add(&BuslogicDevice); + } + pit_reset(); /* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); ali1429_reset(); @@ -336,18 +342,23 @@ void initpc(int argc, char *argv[]) // pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); shadowbios=0; - if ((cdrom_drive == -1) || (cdrom_drive == 0)) - cdrom_null_reset(); - else + for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drive == 200) + if (cdrom_drives[i].host_drive == 0) + { + cdrom_null_reset(i); + } + else + { + if (cdrom_drives[i].host_drive == 200) { - iso_reset(); + iso_reset(i); } else { - ioctl_reset(); + ioctl_reset(i); } + } } } @@ -384,6 +395,8 @@ void resetpc_cad() void resetpchard() { + int i = 0; + savenvr(); saveconfig(); @@ -436,13 +449,19 @@ void resetpchard() device_add(&voodoo_device); pc_reset(); - resetide(); - - if (buslogic_enabled) + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type) { - SCSIReset(scsi_cdrom_id); - device_add(&BuslogicDevice); + SCSIReset(cdrom_drives[i].scsi_device_id); } + } + + resetide(); + if (buslogic_enabled) + { + device_add(&BuslogicDevice); + } loadnvr(); @@ -459,18 +478,23 @@ void resetpchard() // output=3; - if ((cdrom_drive == -1) || (cdrom_drive == 0)) - cdrom_null_reset(); - else + for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drive == 200) + if (cdrom_drives[i].host_drive == 0) + { + cdrom_null_reset(i); + } + else + { + if (cdrom_drives[i].host_drive == 200) { - iso_reset(); + iso_reset(i); } else { - ioctl_reset(); + ioctl_reset(i); } + } } } @@ -601,7 +625,11 @@ void speedchanged() void closepc() { - cdrom->exit(); + int i = 0; + for (i = 0; i < CDROM_NUM; i++) + { + cdrom_drives[i].handler->exit(i); + } // ioctl_close(); dumppic(); // output=7; @@ -701,19 +729,54 @@ void loadconfig(char *fn) if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - cdrom_drive = config_get_int(NULL, "cdrom_drive", 0); - old_cdrom_drive = cdrom_drive; - cdrom_enabled = config_get_int(NULL, "cdrom_enabled", 0); + cdrom_drives[0].host_drive = config_get_int(NULL, "cdrom_1_host_drive", 0); + cdrom_drives[0].prev_host_drive = cdrom_drives[0].host_drive; + cdrom_drives[0].enabled = config_get_int(NULL, "cdrom_1_enabled", 0); + cdrom_drives[0].sound_on = config_get_int(NULL, "cdrom_1_sound_on", 1); + cdrom_drives[0].bus_type = config_get_int(NULL, "cdrom_1_bus_type", 0); + cdrom_drives[0].ide_channel = config_get_int(NULL, "cdrom_1_ide_channel", 2); + cdrom_drives[0].scsi_device_id = config_get_int(NULL, "cdrom_1_scsi_device_id", 2); - atapi_cdrom_channel = config_get_int(NULL, "atapi_cdrom_channel", 2); + p = (char *)config_get_string(NULL, "cdrom_1_iso_path", ""); + if (p) strcpy(cdrom_iso[0].iso_path, p); + else strcpy(cdrom_iso[0].iso_path, ""); + + cdrom_drives[1].host_drive = config_get_int(NULL, "cdrom_2_host_drive", 0); + cdrom_drives[1].prev_host_drive = cdrom_drives[1].host_drive; + cdrom_drives[1].enabled = config_get_int(NULL, "cdrom_2_enabled", 0); + cdrom_drives[1].sound_on = config_get_int(NULL, "cdrom_2_sound_on", 1); + cdrom_drives[1].bus_type = config_get_int(NULL, "cdrom_2_bus_type", 0); + cdrom_drives[1].ide_channel = config_get_int(NULL, "cdrom_2_ide_channel", 3); + cdrom_drives[1].scsi_device_id = config_get_int(NULL, "cdrom_2_scsi_device_id", 3); + + p = (char *)config_get_string(NULL, "cdrom_2_iso_path", ""); + if (p) strcpy(cdrom_iso[1].iso_path, p); + else strcpy(cdrom_iso[1].iso_path, ""); + + cdrom_drives[2].host_drive = config_get_int(NULL, "cdrom_3_host_drive", 0); + cdrom_drives[2].prev_host_drive = cdrom_drives[2].host_drive; + cdrom_drives[2].enabled = config_get_int(NULL, "cdrom_3_enabled", 0); + cdrom_drives[2].sound_on = config_get_int(NULL, "cdrom_3_sound_on", 1); + cdrom_drives[2].bus_type = config_get_int(NULL, "cdrom_3_bus_type", 0); + cdrom_drives[2].ide_channel = config_get_int(NULL, "cdrom_3_ide_channel", 4); + cdrom_drives[2].scsi_device_id = config_get_int(NULL, "cdrom_3_scsi_device_id", 4); + + p = (char *)config_get_string(NULL, "cdrom_3_iso_path", ""); + if (p) strcpy(cdrom_iso[2].iso_path, p); + else strcpy(cdrom_iso[2].iso_path, ""); + + cdrom_drives[3].host_drive = config_get_int(NULL, "cdrom_4_host_drive", 0); + cdrom_drives[3].prev_host_drive = cdrom_drives[3].host_drive; + cdrom_drives[3].enabled = config_get_int(NULL, "cdrom_4_enabled", 0); + cdrom_drives[3].sound_on = config_get_int(NULL, "cdrom_4_sound_on", 1); + cdrom_drives[3].bus_type = config_get_int(NULL, "cdrom_4_bus_type", 0); + cdrom_drives[3].ide_channel = config_get_int(NULL, "cdrom_4_ide_channel", 5); + cdrom_drives[3].scsi_device_id = config_get_int(NULL, "cdrom_4_scsi_device_id", 5); + + p = (char *)config_get_string(NULL, "cdrom_4_iso_path", ""); + if (p) strcpy(cdrom_iso[3].iso_path, p); + else strcpy(cdrom_iso[3].iso_path, ""); - scsi_cdrom_enabled = config_get_int(NULL, "scsi_cdrom_enabled", 0); - scsi_cdrom_id = config_get_int(NULL, "scsi_cdrom_id", 3); - - p = (char *)config_get_string(NULL, "cdrom_path", ""); - if (p) strcpy(iso_path, p); - else strcpy(iso_path, ""); - vid_resize = config_get_int(NULL, "vid_resize", 0); vid_api = config_get_int(NULL, "vid_api", 0); video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); @@ -881,15 +944,43 @@ void saveconfig() config_set_string(NULL, "disc_4", discfns[3]); config_set_int(NULL, "disc_4_writeprot", ui_writeprot[3]); config_set_int(NULL, "mem_size", mem_size); - config_set_int(NULL, "cdrom_drive", cdrom_drive); - config_set_int(NULL, "cdrom_enabled", cdrom_enabled); - - config_set_int(NULL, "atapi_cdrom_channel", atapi_cdrom_channel); - - config_set_int(NULL, "scsi_cdrom_enabled", scsi_cdrom_enabled); - config_set_int(NULL, "scsi_cdrom_id", scsi_cdrom_id); - - config_set_string(NULL, "cdrom_path", iso_path); + + config_set_int(NULL, "cdrom_1_host_drive", cdrom_drives[0].host_drive); + config_set_int(NULL, "cdrom_1_enabled", cdrom_drives[0].enabled); + config_set_int(NULL, "cdrom_1_sound_on", cdrom_drives[0].sound_on); + config_set_int(NULL, "cdrom_1_bus_type", cdrom_drives[0].bus_type); + config_set_int(NULL, "cdrom_1_ide_channel", cdrom_drives[0].ide_channel); + config_set_int(NULL, "cdrom_1_scsi_device_id", cdrom_drives[0].scsi_device_id); + + config_set_string(NULL, "cdrom_1_iso_path", cdrom_iso[0].iso_path); + + config_set_int(NULL, "cdrom_2_host_drive", cdrom_drives[1].host_drive); + config_set_int(NULL, "cdrom_2_enabled", cdrom_drives[1].enabled); + config_set_int(NULL, "cdrom_2_sound_on", cdrom_drives[1].sound_on); + config_set_int(NULL, "cdrom_2_bus_type", cdrom_drives[1].bus_type); + config_set_int(NULL, "cdrom_2_ide_channel", cdrom_drives[1].ide_channel); + config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id); + + config_set_string(NULL, "cdrom_2_iso_path", cdrom_iso[1].iso_path); + + config_set_int(NULL, "cdrom_3_host_drive", cdrom_drives[2].host_drive); + config_set_int(NULL, "cdrom_3_enabled", cdrom_drives[2].enabled); + config_set_int(NULL, "cdrom_3_sound_on", cdrom_drives[2].sound_on); + config_set_int(NULL, "cdrom_3_bus_type", cdrom_drives[2].bus_type); + config_set_int(NULL, "cdrom_3_ide_channel", cdrom_drives[2].ide_channel); + config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id); + + config_set_string(NULL, "cdrom_3_iso_path", cdrom_iso[2].iso_path); + + config_set_int(NULL, "cdrom_4_host_drive", cdrom_drives[3].host_drive); + config_set_int(NULL, "cdrom_4_enabled", cdrom_drives[3].enabled); + config_set_int(NULL, "cdrom_4_sound_on", cdrom_drives[3].sound_on); + config_set_int(NULL, "cdrom_4_bus_type", cdrom_drives[3].bus_type); + config_set_int(NULL, "cdrom_4_ide_channel", cdrom_drives[3].ide_channel); + config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id); + + config_set_string(NULL, "cdrom_4_iso_path", cdrom_iso[3].iso_path); + config_set_int(NULL, "vid_resize", vid_resize); config_set_int(NULL, "vid_api", vid_api); config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); diff --git a/src/pc.rc b/src/pc.rc index fcb8741dc..65d8c4acf 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -35,15 +35,172 @@ BEGIN MENUITEM "E&ject FDD 4", IDM_EJECT_4 MENUITEM SEPARATOR MENUITEM "&Configure hard discs...",IDM_HDCONF - POPUP "C&D-ROM" + POPUP "C&D-ROM 1" BEGIN - MENUITEM "&Enabled", IDM_CDROM_ENABLED - MENUITEM "&SCSI", IDM_CDROM_SCSI + MENUITEM "&Enabled", IDM_CDROM_1_ENABLED + MENUITEM "S&ound enabled", IDM_CDROM_1_SOUND_ON MENUITEM SEPARATOR - MENUITEM "E&mpty",IDM_CDROM_EMPTY - MENUITEM "&Reload previous disc",IDM_CDROM_RELOAD + MENUITEM "&SCSI", IDM_CDROM_1_SCSI MENUITEM SEPARATOR - MENUITEM "&ISO...",IDM_CDROM_ISO + MENUITEM "E&mpty",IDM_CDROM_1_EMPTY + MENUITEM "&Reload previous disc",IDM_CDROM_1_RELOAD + MENUITEM SEPARATOR + POPUP "&IDE channel..." + BEGIN + MENUITEM "&C:",IDM_CDROM_1_C + MENUITEM "&D:",IDM_CDROM_1_D + MENUITEM "&E:",IDM_CDROM_1_E + MENUITEM "&F:",IDM_CDROM_1_F + MENUITEM "&G:",IDM_CDROM_1_G + MENUITEM "&H:",IDM_CDROM_1_H + MENUITEM "&I:",IDM_CDROM_1_I + MENUITEM "&J:",IDM_CDROM_1_J + END + POPUP "S&CSI ID..." + BEGIN + MENUITEM "&0",IDM_CDROM_1_0 + MENUITEM "&1",IDM_CDROM_1_1 + MENUITEM "&2",IDM_CDROM_1_2 + MENUITEM "&3",IDM_CDROM_1_3 + MENUITEM "&4",IDM_CDROM_1_4 + MENUITEM "&5",IDM_CDROM_1_5 + MENUITEM "&6",IDM_CDROM_1_6 + MENUITEM "&8",IDM_CDROM_1_8 + MENUITEM "&9",IDM_CDROM_1_9 + MENUITEM "10",IDM_CDROM_1_10 + MENUITEM "11",IDM_CDROM_1_11 + MENUITEM "12",IDM_CDROM_1_12 + MENUITEM "13",IDM_CDROM_1_13 + MENUITEM "14",IDM_CDROM_1_14 + MENUITEM "15",IDM_CDROM_1_15 + END + MENUITEM SEPARATOR + MENUITEM "&ISO...",IDM_CDROM_1_ISO + END + POPUP "CD-&ROM 2" + BEGIN + MENUITEM "&Enabled", IDM_CDROM_2_ENABLED + MENUITEM "S&ound enabled", IDM_CDROM_2_SOUND_ON + MENUITEM SEPARATOR + MENUITEM "&SCSI", IDM_CDROM_2_SCSI + MENUITEM SEPARATOR + MENUITEM "E&mpty",IDM_CDROM_2_EMPTY + MENUITEM "&Reload previous disc",IDM_CDROM_2_RELOAD + MENUITEM SEPARATOR + POPUP "&IDE channel..." + BEGIN + MENUITEM "&C:",IDM_CDROM_2_C + MENUITEM "&D:",IDM_CDROM_2_D + MENUITEM "&E:",IDM_CDROM_2_E + MENUITEM "&F:",IDM_CDROM_2_F + MENUITEM "&G:",IDM_CDROM_2_G + MENUITEM "&H:",IDM_CDROM_2_H + MENUITEM "&I:",IDM_CDROM_2_I + MENUITEM "&J:",IDM_CDROM_2_J + END + POPUP "S&CSI ID..." + BEGIN + MENUITEM "&0",IDM_CDROM_2_0 + MENUITEM "&1",IDM_CDROM_2_1 + MENUITEM "&2",IDM_CDROM_2_2 + MENUITEM "&3",IDM_CDROM_2_3 + MENUITEM "&4",IDM_CDROM_2_4 + MENUITEM "&5",IDM_CDROM_2_5 + MENUITEM "&6",IDM_CDROM_2_6 + MENUITEM "&8",IDM_CDROM_2_8 + MENUITEM "&9",IDM_CDROM_2_9 + MENUITEM "10",IDM_CDROM_2_10 + MENUITEM "11",IDM_CDROM_2_11 + MENUITEM "12",IDM_CDROM_2_12 + MENUITEM "13",IDM_CDROM_2_13 + MENUITEM "14",IDM_CDROM_2_14 + MENUITEM "15",IDM_CDROM_2_15 + END + MENUITEM SEPARATOR + MENUITEM "&ISO...",IDM_CDROM_2_ISO + END + POPUP "CD-R&OM 3" + BEGIN + MENUITEM "&Enabled", IDM_CDROM_3_ENABLED + MENUITEM "S&ound enabled", IDM_CDROM_3_SOUND_ON + MENUITEM SEPARATOR + MENUITEM "&SCSI", IDM_CDROM_3_SCSI + MENUITEM SEPARATOR + MENUITEM "E&mpty",IDM_CDROM_3_EMPTY + MENUITEM "&Reload previous disc",IDM_CDROM_3_RELOAD + MENUITEM SEPARATOR + POPUP "&IDE channel..." + BEGIN + MENUITEM "&C:",IDM_CDROM_3_C + MENUITEM "&D:",IDM_CDROM_3_D + MENUITEM "&E:",IDM_CDROM_3_E + MENUITEM "&F:",IDM_CDROM_3_F + MENUITEM "&G:",IDM_CDROM_3_G + MENUITEM "&H:",IDM_CDROM_3_H + MENUITEM "&I:",IDM_CDROM_3_I + MENUITEM "&J:",IDM_CDROM_3_J + END + POPUP "S&CSI ID..." + BEGIN + MENUITEM "&0",IDM_CDROM_3_0 + MENUITEM "&1",IDM_CDROM_3_1 + MENUITEM "&2",IDM_CDROM_3_2 + MENUITEM "&3",IDM_CDROM_3_3 + MENUITEM "&4",IDM_CDROM_3_4 + MENUITEM "&5",IDM_CDROM_3_5 + MENUITEM "&6",IDM_CDROM_3_6 + MENUITEM "&8",IDM_CDROM_3_8 + MENUITEM "&9",IDM_CDROM_3_9 + MENUITEM "10",IDM_CDROM_3_10 + MENUITEM "11",IDM_CDROM_3_11 + MENUITEM "12",IDM_CDROM_3_12 + MENUITEM "13",IDM_CDROM_3_13 + MENUITEM "14",IDM_CDROM_3_14 + MENUITEM "15",IDM_CDROM_3_15 + END + MENUITEM SEPARATOR + MENUITEM "&ISO...",IDM_CDROM_3_ISO + END + POPUP "CD-RO&M 4" + BEGIN + MENUITEM "&Enabled", IDM_CDROM_4_ENABLED + MENUITEM "S&ound enabled", IDM_CDROM_4_SOUND_ON + MENUITEM SEPARATOR + MENUITEM "&SCSI", IDM_CDROM_4_SCSI + MENUITEM "E&mpty",IDM_CDROM_4_EMPTY + MENUITEM "&Reload previous disc",IDM_CDROM_4_RELOAD + MENUITEM SEPARATOR + POPUP "&IDE channel..." + BEGIN + MENUITEM "&C:",IDM_CDROM_4_C + MENUITEM "&D:",IDM_CDROM_4_D + MENUITEM "&E:",IDM_CDROM_4_E + MENUITEM "&F:",IDM_CDROM_4_F + MENUITEM "&G:",IDM_CDROM_4_G + MENUITEM "&H:",IDM_CDROM_4_H + MENUITEM "&I:",IDM_CDROM_4_I + MENUITEM "&J:",IDM_CDROM_4_J + END + POPUP "S&CSI ID..." + BEGIN + MENUITEM "&0",IDM_CDROM_4_0 + MENUITEM "&1",IDM_CDROM_4_1 + MENUITEM "&2",IDM_CDROM_4_2 + MENUITEM "&3",IDM_CDROM_4_3 + MENUITEM "&4",IDM_CDROM_4_4 + MENUITEM "&5",IDM_CDROM_4_5 + MENUITEM "&6",IDM_CDROM_4_6 + MENUITEM "&8",IDM_CDROM_4_8 + MENUITEM "&9",IDM_CDROM_4_9 + MENUITEM "10",IDM_CDROM_4_10 + MENUITEM "11",IDM_CDROM_4_11 + MENUITEM "12",IDM_CDROM_4_12 + MENUITEM "13",IDM_CDROM_4_13 + MENUITEM "14",IDM_CDROM_4_14 + MENUITEM "15",IDM_CDROM_4_15 + END + MENUITEM SEPARATOR + MENUITEM "&ISO...",IDM_CDROM_4_ISO END POPUP "E&xtra IDE controllers" BEGIN @@ -218,8 +375,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_CFILE,7 + 136, C_BASE, 16, 14 PUSHBUTTON "New",IDC_CNEW,7 + 152, C_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTC, 7 + 176, C_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_CHDD, 7+207, C_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_CCDROM, 7+207, C_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_C_SPT,15,C_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_C_HPC,48,C_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_C_CYL,81,C_BASE+16,28,12, WS_DISABLED @@ -233,8 +388,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_DFILE,7 + 136, D_BASE, 16, 14 PUSHBUTTON "New",IDC_DNEW,7 + 152, D_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTD, 7 + 176, D_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_DHDD, 7+207, D_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_DCDROM, 7+207, D_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_D_SPT,15,D_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_D_HPC,48,D_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_D_CYL,81,D_BASE+16,28,12, WS_DISABLED @@ -248,8 +401,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_EFILE,7 + 136, E_BASE, 16, 14 PUSHBUTTON "New",IDC_ENEW,7 + 152, E_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTE, 7 + 176, E_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_EHDD, 7+207, E_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_ECDROM, 7+207, E_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_E_SPT,15,E_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_E_HPC,48,E_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_E_CYL,81,E_BASE+16,28,12, WS_DISABLED @@ -263,8 +414,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_FFILE,7 + 136, F_BASE, 16, 14 PUSHBUTTON "New",IDC_FNEW,7 + 152, F_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTF, 7 + 176, F_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_FHDD, 7+207, F_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_FCDROM, 7+207, F_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_F_SPT,15,F_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_F_HPC,48,F_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_F_CYL,81,F_BASE+16,28,12, WS_DISABLED @@ -278,8 +427,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_GFILE,7 + 136, G_BASE, 16, 14 PUSHBUTTON "New",IDC_GNEW,7 + 152, G_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTG, 7 + 176, G_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_GHDD, 7+207, G_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_GCDROM, 7+207, G_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_G_SPT,15,G_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_G_HPC,48,G_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_G_CYL,81,G_BASE+16,28,12, WS_DISABLED @@ -293,8 +440,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_HFILE,7 + 136, H_BASE, 16, 14 PUSHBUTTON "New",IDC_HNEW,7 + 152, H_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTH, 7 + 176, H_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_HHDD, 7+207, H_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_HCDROM, 7+207, H_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_H_SPT,15,H_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_H_HPC,48,H_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_H_CYL,81,H_BASE+16,28,12, WS_DISABLED @@ -308,8 +453,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_IFILE,7 + 136, I_BASE, 16, 14 PUSHBUTTON "New",IDC_INEW,7 + 152, I_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTI, 7 + 176, I_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_IHDD, 7+207, I_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_ICDROM, 7+207, I_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_I_SPT,15,I_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_I_HPC,48,I_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_I_CYL,81,I_BASE+16,28,12, WS_DISABLED @@ -323,8 +466,6 @@ HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT PUSHBUTTON "...",IDC_JFILE,7 + 136, J_BASE, 16, 14 PUSHBUTTON "New",IDC_JNEW,7 + 152, J_BASE, 24, 14 PUSHBUTTON "Eject", IDC_EJECTJ, 7 + 176, J_BASE, 24, 14 - RADIOBUTTON "Hard drive", IDC_JHDD, 7+207, J_BASE, 53, 12 , WS_TABSTOP - RADIOBUTTON "CD-ROM", IDC_JCDROM, 7+207, J_BASE+16, 53, 12 , WS_TABSTOP EDITTEXT IDC_EDIT_J_SPT,15,J_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_J_HPC,48,J_BASE+16,16,12, WS_DISABLED EDITTEXT IDC_EDIT_J_CYL,81,J_BASE+16,28,12, WS_DISABLED diff --git a/src/piix.c b/src/piix.c index e1e41814c..ce3e33b0d 100644 --- a/src/piix.c +++ b/src/piix.c @@ -396,21 +396,21 @@ uint8_t piix_bus_master_read(uint16_t port, void *priv) return 0xff; } -int piix_bus_master_sector_read(int channel, uint8_t *data) +int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) { int transferred = 0; if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ - while (transferred < 512) + while (transferred < transfer_length) { - if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Read count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) + fatal("DMA on channel %i - Read count less than transfer_length! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); - mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+511); + mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + transfer_length - 1); - if (piix_busmaster[channel].count < (512 - transferred)) + if (piix_busmaster[channel].count < (transfer_length - transferred)) { // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); memcpy(&ram[piix_busmaster[channel].addr], data + transferred, piix_busmaster[channel].count); @@ -421,11 +421,11 @@ int piix_bus_master_sector_read(int channel, uint8_t *data) } else { -// pclog("Transferring larger - %i bytes\n", 512 - transferred); - memcpy(&ram[piix_busmaster[channel].addr], data + transferred, 512 - transferred); - piix_busmaster[channel].addr += (512 - transferred); - piix_busmaster[channel].count -= (512 - transferred); - transferred += (512 - transferred); +// pclog("Transferring larger - %i bytes\n", transfer_length - transferred); + memcpy(&ram[piix_busmaster[channel].addr], data + transferred, transfer_length - transferred); + piix_busmaster[channel].addr += (transfer_length - transferred); + piix_busmaster[channel].count -= (transfer_length - transferred); + transferred += (transfer_length - transferred); } // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); @@ -444,19 +444,20 @@ int piix_bus_master_sector_read(int channel, uint8_t *data) } return 0; } -int piix_bus_master_sector_write(int channel, uint8_t *data) + +int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) { int transferred = 0; if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ - while (transferred < 512) + while (transferred < transfer_length) { - if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Write count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) + fatal("DMA on channel %i - Write count less than transfer_length! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); - if (piix_busmaster[channel].count < (512 - transferred)) + if (piix_busmaster[channel].count < (transfer_length - transferred)) { // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); memcpy(data + transferred, &ram[piix_busmaster[channel].addr], piix_busmaster[channel].count); @@ -467,11 +468,11 @@ int piix_bus_master_sector_write(int channel, uint8_t *data) } else { -// pclog("Transferring larger - %i bytes\n", 512 - transferred); - memcpy(data + transferred, &ram[piix_busmaster[channel].addr], 512 - transferred); - piix_busmaster[channel].addr += (512 - transferred); - piix_busmaster[channel].count -= (512 - transferred); - transferred += (512 - transferred); +// pclog("Transferring larger - %i bytes\n", transfer_length - transferred); + memcpy(data + transferred, &ram[piix_busmaster[channel].addr], transfer_length - transferred); + piix_busmaster[channel].addr += (transfer_length - transferred); + piix_busmaster[channel].count -= (transfer_length - transferred); + transferred += (transfer_length - transferred); } // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); @@ -620,7 +621,7 @@ void piix_init(int card) piix_type = 1; - ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq); + ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, piix_bus_master_set_irq); io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL); @@ -641,7 +642,7 @@ void piix3_init(int card) piix_type = 3; - ide_set_bus_master(piix_bus_master_sector_read, piix_bus_master_sector_write, piix_bus_master_set_irq); + ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, piix_bus_master_set_irq); io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL); diff --git a/src/resources.h b/src/resources.h index 864b12330..dbcaa228f 100644 --- a/src/resources.h +++ b/src/resources.h @@ -35,44 +35,158 @@ #define IDM_EJECT_4 40082 #define IDM_DISC_3_WP 40083 #define IDM_DISC_4_WP 40084 -#define IDM_CDROM_ISO 40100 -#define IDM_CDROM_RELOAD 40101 -#define IDM_CDROM_EMPTY 40200 -#define IDM_CDROM_REAL 40200 -#define IDM_CDROM_ENABLED 40300 -#define IDM_CDROM_SCSI 40400 -#define IDM_IDE_TER_ENABLED 40500 -#define IDM_IDE_TER_IRQ9 40501 -#define IDM_IDE_TER_IRQ10 40502 -#define IDM_IDE_TER_IRQ11 40503 -#define IDM_IDE_TER_IRQ12 40504 -#define IDM_IDE_TER_IRQ14 40505 -#define IDM_IDE_TER_IRQ15 40506 -#define IDM_IDE_QUA_ENABLED 40507 -#define IDM_IDE_QUA_IRQ9 40508 -#define IDM_IDE_QUA_IRQ10 40509 -#define IDM_IDE_QUA_IRQ11 40510 -#define IDM_IDE_QUA_IRQ12 40511 -#define IDM_IDE_QUA_IRQ14 40512 -#define IDM_IDE_QUA_IRQ15 40513 -#define IDM_SCSI_ENABLED 40600 -#define IDM_SCSI_MODEL0 40601 -#define IDM_SCSI_MODEL1 40602 -#define IDM_SCSI_BASE130 40603 -#define IDM_SCSI_BASE134 40604 -#define IDM_SCSI_BASE230 40605 -#define IDM_SCSI_BASE234 40606 -#define IDM_SCSI_BASE330 40607 -#define IDM_SCSI_BASE334 40608 -#define IDM_SCSI_IRQ9 40609 -#define IDM_SCSI_IRQ10 40610 -#define IDM_SCSI_IRQ11 40611 -#define IDM_SCSI_IRQ12 40612 -#define IDM_SCSI_IRQ14 40613 -#define IDM_SCSI_IRQ15 40614 -#define IDM_SCSI_DMA5 40615 -#define IDM_SCSI_DMA6 40616 -#define IDM_SCSI_DMA7 40617 +#define IDM_CDROM_1_ISO 40100 +#define IDM_CDROM_1_RELOAD 40101 +#define IDM_CDROM_1_EMPTY 40200 +#define IDM_CDROM_1_REAL 40200 +#define IDM_CDROM_1_ENABLED 40300 +#define IDM_CDROM_1_SOUND_ON 40400 +#define IDM_CDROM_1_SCSI 40500 +#define IDM_CDROM_1_C 40600 +#define IDM_CDROM_1_D 40601 +#define IDM_CDROM_1_E 40602 +#define IDM_CDROM_1_F 40603 +#define IDM_CDROM_1_G 40604 +#define IDM_CDROM_1_H 40605 +#define IDM_CDROM_1_I 40606 +#define IDM_CDROM_1_J 40607 +#define IDM_CDROM_1_0 40700 +#define IDM_CDROM_1_1 40701 +#define IDM_CDROM_1_2 40702 +#define IDM_CDROM_1_3 40703 +#define IDM_CDROM_1_4 40704 +#define IDM_CDROM_1_5 40705 +#define IDM_CDROM_1_6 40706 +#define IDM_CDROM_1_8 40708 +#define IDM_CDROM_1_9 40709 +#define IDM_CDROM_1_10 40710 +#define IDM_CDROM_1_11 40711 +#define IDM_CDROM_1_12 40712 +#define IDM_CDROM_1_13 40713 +#define IDM_CDROM_1_14 40714 +#define IDM_CDROM_1_15 40715 +#define IDM_CDROM_2_ISO 41100 +#define IDM_CDROM_2_RELOAD 41101 +#define IDM_CDROM_2_EMPTY 41200 +#define IDM_CDROM_2_REAL 41200 +#define IDM_CDROM_2_ENABLED 41300 +#define IDM_CDROM_2_SOUND_ON 41400 +#define IDM_CDROM_2_SCSI 41500 +#define IDM_CDROM_2_C 41600 +#define IDM_CDROM_2_D 41601 +#define IDM_CDROM_2_E 41602 +#define IDM_CDROM_2_F 41603 +#define IDM_CDROM_2_G 41604 +#define IDM_CDROM_2_H 41605 +#define IDM_CDROM_2_I 41606 +#define IDM_CDROM_2_J 41607 +#define IDM_CDROM_2_0 41700 +#define IDM_CDROM_2_1 41701 +#define IDM_CDROM_2_2 41702 +#define IDM_CDROM_2_3 41703 +#define IDM_CDROM_2_4 41704 +#define IDM_CDROM_2_5 41705 +#define IDM_CDROM_2_6 41706 +#define IDM_CDROM_2_8 41708 +#define IDM_CDROM_2_9 41709 +#define IDM_CDROM_2_10 41710 +#define IDM_CDROM_2_11 41711 +#define IDM_CDROM_2_12 41712 +#define IDM_CDROM_2_13 41713 +#define IDM_CDROM_2_14 41714 +#define IDM_CDROM_2_15 41715 +#define IDM_CDROM_3_ISO 42100 +#define IDM_CDROM_3_RELOAD 42101 +#define IDM_CDROM_3_EMPTY 42200 +#define IDM_CDROM_3_REAL 42200 +#define IDM_CDROM_3_ENABLED 42300 +#define IDM_CDROM_3_SOUND_ON 42400 +#define IDM_CDROM_3_SCSI 42500 +#define IDM_CDROM_3_C 42600 +#define IDM_CDROM_3_D 42601 +#define IDM_CDROM_3_E 42602 +#define IDM_CDROM_3_F 42603 +#define IDM_CDROM_3_G 42604 +#define IDM_CDROM_3_H 42605 +#define IDM_CDROM_3_I 42606 +#define IDM_CDROM_3_J 42607 +#define IDM_CDROM_3_0 42700 +#define IDM_CDROM_3_1 42701 +#define IDM_CDROM_3_2 42702 +#define IDM_CDROM_3_3 42703 +#define IDM_CDROM_3_4 42704 +#define IDM_CDROM_3_5 42705 +#define IDM_CDROM_3_6 42706 +#define IDM_CDROM_3_8 42708 +#define IDM_CDROM_3_9 42709 +#define IDM_CDROM_3_10 42710 +#define IDM_CDROM_3_11 42711 +#define IDM_CDROM_3_12 42712 +#define IDM_CDROM_3_13 42713 +#define IDM_CDROM_3_14 42714 +#define IDM_CDROM_3_15 42715 +#define IDM_CDROM_4_ISO 43100 +#define IDM_CDROM_4_RELOAD 43101 +#define IDM_CDROM_4_EMPTY 43200 +#define IDM_CDROM_4_REAL 43200 +#define IDM_CDROM_4_ENABLED 43300 +#define IDM_CDROM_4_SOUND_ON 43400 +#define IDM_CDROM_4_SCSI 43500 +#define IDM_CDROM_4_C 43600 +#define IDM_CDROM_4_D 43601 +#define IDM_CDROM_4_E 43602 +#define IDM_CDROM_4_F 43603 +#define IDM_CDROM_4_G 43604 +#define IDM_CDROM_4_H 43605 +#define IDM_CDROM_4_I 43606 +#define IDM_CDROM_4_J 43607 +#define IDM_CDROM_4_0 43700 +#define IDM_CDROM_4_1 43701 +#define IDM_CDROM_4_2 43702 +#define IDM_CDROM_4_3 43703 +#define IDM_CDROM_4_4 43704 +#define IDM_CDROM_4_5 43705 +#define IDM_CDROM_4_6 43706 +#define IDM_CDROM_4_8 43708 +#define IDM_CDROM_4_9 43709 +#define IDM_CDROM_4_10 43710 +#define IDM_CDROM_4_11 43711 +#define IDM_CDROM_4_12 43712 +#define IDM_CDROM_4_13 43713 +#define IDM_CDROM_4_14 43714 +#define IDM_CDROM_4_15 43715 +#define IDM_IDE_TER_ENABLED 44000 +#define IDM_IDE_TER_IRQ9 44009 +#define IDM_IDE_TER_IRQ10 44010 +#define IDM_IDE_TER_IRQ11 44011 +#define IDM_IDE_TER_IRQ12 44012 +#define IDM_IDE_TER_IRQ14 44014 +#define IDM_IDE_TER_IRQ15 44015 +#define IDM_IDE_QUA_ENABLED 44020 +#define IDM_IDE_QUA_IRQ9 44029 +#define IDM_IDE_QUA_IRQ10 44030 +#define IDM_IDE_QUA_IRQ11 44031 +#define IDM_IDE_QUA_IRQ12 44032 +#define IDM_IDE_QUA_IRQ14 44033 +#define IDM_IDE_QUA_IRQ15 44035 +#define IDM_SCSI_ENABLED 45000 +#define IDM_SCSI_MODEL0 45100 +#define IDM_SCSI_MODEL1 45101 +#define IDM_SCSI_BASE130 45200 + 0x130 +#define IDM_SCSI_BASE134 45200 + 0x134 +#define IDM_SCSI_BASE230 45200 + 0x230 +#define IDM_SCSI_BASE234 45200 + 0x234 +#define IDM_SCSI_BASE330 45200 + 0x330 +#define IDM_SCSI_BASE334 45200 + 0x334 +#define IDM_SCSI_IRQ9 45309 +#define IDM_SCSI_IRQ10 45310 +#define IDM_SCSI_IRQ11 45311 +#define IDM_SCSI_IRQ12 45312 +#define IDM_SCSI_IRQ14 45314 +#define IDM_SCSI_IRQ15 45315 +#define IDM_SCSI_DMA5 45405 +#define IDM_SCSI_DMA6 45406 +#define IDM_SCSI_DMA7 45407 #define IDC_COMBO1 1000 #define IDC_COMBOVID 1001 @@ -113,8 +227,6 @@ #define IDC_EDITC 1050 #define IDC_CFILE 1060 #define IDC_CNEW 1070 -#define IDC_CHDD 1080 -#define IDC_CCDROM 1090 #define IDC_EDIT_C_SPT 1200 #define IDC_EDIT_C_HPC 1210 #define IDC_EDIT_C_CYL 1220 @@ -125,8 +237,6 @@ #define IDC_EDITD 1051 #define IDC_DFILE 1061 #define IDC_DNEW 1071 -#define IDC_DHDD 1081 -#define IDC_DCDROM 1091 #define IDC_EDIT_D_SPT 1201 #define IDC_EDIT_D_HPC 1211 #define IDC_EDIT_D_CYL 1221 @@ -137,8 +247,6 @@ #define IDC_EDITE 1052 #define IDC_EFILE 1062 #define IDC_ENEW 1072 -#define IDC_EHDD 1082 -#define IDC_ECDROM 1092 #define IDC_EDIT_E_SPT 1202 #define IDC_EDIT_E_HPC 1212 #define IDC_EDIT_E_CYL 1222 @@ -149,8 +257,6 @@ #define IDC_EDITF 1053 #define IDC_FFILE 1063 #define IDC_FNEW 1073 -#define IDC_FHDD 1083 -#define IDC_FCDROM 1093 #define IDC_EDIT_F_SPT 1203 #define IDC_EDIT_F_HPC 1213 #define IDC_EDIT_F_CYL 1223 @@ -161,8 +267,6 @@ #define IDC_EDITG 1054 #define IDC_GFILE 1064 #define IDC_GNEW 1074 -#define IDC_GHDD 1084 -#define IDC_GCDROM 1094 #define IDC_EDIT_G_SPT 1204 #define IDC_EDIT_G_HPC 1214 #define IDC_EDIT_G_CYL 1224 @@ -173,8 +277,6 @@ #define IDC_EDITH 1055 #define IDC_HFILE 1065 #define IDC_HNEW 1075 -#define IDC_HHDD 1085 -#define IDC_HCDROM 1095 #define IDC_EDIT_H_SPT 1205 #define IDC_EDIT_H_HPC 1215 #define IDC_EDIT_H_CYL 1225 @@ -185,8 +287,6 @@ #define IDC_EDITI 1056 #define IDC_IFILE 1066 #define IDC_INEW 1076 -#define IDC_IHDD 1086 -#define IDC_ICDROM 1096 #define IDC_EDIT_I_SPT 1206 #define IDC_EDIT_I_HPC 1216 #define IDC_EDIT_I_CYL 1226 @@ -197,8 +297,6 @@ #define IDC_EDITJ 1057 #define IDC_JFILE 1067 #define IDC_JNEW 1077 -#define IDC_JHDD 1087 -#define IDC_JCDROM 1097 #define IDC_EDIT_J_SPT 1207 #define IDC_EDIT_J_HPC 1217 #define IDC_EDIT_J_CYL 1227 diff --git a/src/scsi.c b/src/scsi.c index 539c50791..5f709815d 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -13,6 +13,9 @@ #include "timer.h" +uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; +uint8_t SCSIStatus = SCSI_STATUS_OK; + int SCSICallback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint8_t scsi_cdrom_id = 3; /*common setting*/ @@ -22,6 +25,7 @@ void SCSIGetLength(uint8_t id, int *datalen) *datalen = SCSIDevices[id].CmdBufferLength; } +#if 0 //Execute SCSI command void SCSIExecCommand(uint8_t id, uint8_t *buffer, uint8_t *cdb) { @@ -72,25 +76,22 @@ void SCSIWrite(uint8_t Id, uint8_t *srcbuf, uint8_t *dstbuf, uint32_t len_size) } } ///// +#endif //Initialization function for the SCSI layer void SCSIReset(uint8_t Id) { - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= 0xFD; /* Clear changed flag for CDROM AUDIO mode page. */ - memset(mode_pages_in[GPMODE_CDROM_AUDIO_PAGE], 0, 256); /* Clear the page itself. */ + uint8_t cdrom_id = scsi_cdrom_drives[Id]; - SCSICallback[Id]=0; - - if (cdrom_enabled && scsi_cdrom_enabled) + if (buslogic_scsi_drive_is_cdrom(Id)) { + SCSICallback[cdrom_id]=0; + + cdrom_reset(cdrom_id); SCSIDevices[Id].LunType = SCSI_CDROM; } else { SCSIDevices[Id].LunType = SCSI_NONE; } - - page_flags[GPMODE_CDROM_AUDIO_PAGE] &= ~PAGE_CHANGED; - - SCSISense.UnitAttention = 0; } diff --git a/src/scsi.h b/src/scsi.h index 44a3ddfd7..e59d5b60a 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -12,10 +12,12 @@ /* SCSI Commands */ #define GPCMD_TEST_UNIT_READY 0x00 +#define GPCMD_REZERO_UNIT 0x01 #define GPCMD_REQUEST_SENSE 0x03 #define GPCMD_READ_6 0x08 #define GPCMD_SEEK_6 0x0b #define GPCMD_INQUIRY 0x12 +#define GPCMD_VERIFY_6 0x13 #define GPCMD_MODE_SELECT_6 0x15 #define GPCMD_MODE_SENSE_6 0x1a #define GPCMD_START_STOP_UNIT 0x1b @@ -23,12 +25,14 @@ #define GPCMD_READ_CDROM_CAPACITY 0x25 #define GPCMD_READ_10 0x28 #define GPCMD_SEEK_10 0x2b +#define GPCMD_VERIFY_10 0x2f #define GPCMD_READ_SUBCHANNEL 0x42 #define GPCMD_READ_TOC_PMA_ATIP 0x43 #define GPCMD_READ_HEADER 0x44 #define GPCMD_PLAY_AUDIO_10 0x45 #define GPCMD_GET_CONFIGURATION 0x46 #define GPCMD_PLAY_AUDIO_MSF 0x47 +#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 #define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a #define GPCMD_PAUSE_RESUME 0x4b #define GPCMD_STOP_PLAY_SCAN 0x4e @@ -39,12 +43,18 @@ #define GPCMD_PLAY_AUDIO_12 0xa5 #define GPCMD_READ_12 0xa8 #define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ +#define GPCMD_VERIFY_12 0xaf +#define GPCMD_PLAY_CD_OLD 0xb4 +#define GPCMD_READ_CD_OLD 0xb8 #define GPCMD_READ_CD_MSF 0xb9 +#define GPCMD_SCAN 0xba #define GPCMD_SET_SPEED 0xbb #define GPCMD_PLAY_CD 0xbc #define GPCMD_MECHANISM_STATUS 0xbd #define GPCMD_READ_CD 0xbe #define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ +#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ +#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ /* Mode page codes for mode sense/set */ #define GPMODE_R_W_ERROR_PAGE 0x01 @@ -66,7 +76,9 @@ /* SCSI Additional Sense Codes */ #define ASC_AUDIO_PLAY_OPERATION 0x00 #define ASC_ILLEGAL_OPCODE 0x20 +#define ASC_LBA_OUT_OF_RANGE 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 +#define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 #define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 #define ASC_INCOMPATIBLE_FORMAT 0x30 #define ASC_MEDIUM_NOT_PRESENT 0x3a @@ -79,7 +91,7 @@ /* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). Not that it means anything */ -#define CDROM_SPEED 706 +#define CDROM_SPEED 706 /* 0x2C2 */ /* Some generally useful CD-ROM information */ #define CD_MINS 75 /* max. minutes per CD */ @@ -144,14 +156,15 @@ #define MMC_PROFILE_HDDVD_RW_DL 0x005A #define MMC_PROFILE_INVALID 0xFFFF +#define SCSI_ONLY 32 +#define ATAPI_ONLY 16 +#define IMPLEMENTED 8 #define NONDATA 4 #define CHECK_READY 2 #define ALLOW_UA 1 extern uint8_t SCSICommandTable[0x100]; -#define IMPLEMENTED 1 - extern uint8_t mode_sense_pages[0x40]; extern int readcdmode; @@ -197,47 +210,6 @@ extern int prev_status; #define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) -typedef struct __attribute__((packed)) -{ - uint8_t user_data[2048]; - uint8_t ecc[288]; -} m1_data_t; - -typedef struct __attribute__((packed)) -{ - uint8_t sub_header[8]; - uint8_t user_data[2328]; -} m2_data_t; - -typedef union __attribute__((packed)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2352]; -} sector_data_t; - -typedef struct __attribute__((packed)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((packed)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -extern sector_buffer_t cdrom_sector_buffer; - -extern int cdrom_sector_type, cdrom_sector_flags; -extern int cdrom_sector_size, cdrom_sector_ismsf; - #define SCSI_PHASE_DATAOUT ( 0 ) #define SCSI_PHASE_DATAIN ( 1 ) #define SCSI_PHASE_COMMAND ( 2 ) @@ -250,7 +222,7 @@ extern int cdrom_sector_size, cdrom_sector_ismsf; struct { uint32_t pos; - uint8_t CmdBuffer[512*512]; + uint8_t CmdBuffer[390144]; uint32_t CmdBufferLength; int LunType; uint32_t InitLength; @@ -266,6 +238,10 @@ void SCSICDROM_Insert(); int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); int cdrom_LBAtoMSF_accurate(); -int cdrom_read_data(uint8_t *buffer); +// int cdrom_read_data(uint8_t *buffer); + +int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save); +int mode_select_terminate(int force); +int mode_select_write(uint8_t val); #endif \ No newline at end of file diff --git a/src/scsi_cdrom.c b/src/scsi_cdrom.c deleted file mode 100644 index 1528fea91..000000000 --- a/src/scsi_cdrom.c +++ /dev/null @@ -1,1677 +0,0 @@ -/* Copyright holders: SA1988, Tenshi - see COPYING for more details -*/ -/*SCSI CD-ROM emulation*/ -#include -#include -#include "86box.h" -#include "ibm.h" - -#include "cdrom.h" -#include "scsi.h" - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_type, cdrom_sector_flags; -int cdrom_sector_size, cdrom_sector_ismsf; - -uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; -uint8_t SCSIStatus = SCSI_STATUS_OK; - -/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ -uint8_t SCSICommandTable[0x100] = -{ - [GPCMD_TEST_UNIT_READY] = CHECK_READY | NONDATA, - [GPCMD_REQUEST_SENSE] = ALLOW_UA, - [GPCMD_READ_6] = CHECK_READY, - [GPCMD_SEEK_6] = CHECK_READY | NONDATA, - [GPCMD_INQUIRY] = ALLOW_UA, - [GPCMD_MODE_SELECT_6] = 0, - [GPCMD_MODE_SENSE_6] = 0, - [GPCMD_START_STOP_UNIT] = CHECK_READY, - [GPCMD_PREVENT_REMOVAL] = CHECK_READY, - [GPCMD_READ_CDROM_CAPACITY] = CHECK_READY, - [GPCMD_READ_10] = CHECK_READY, - [GPCMD_SEEK_10] = CHECK_READY | NONDATA, - [GPCMD_READ_SUBCHANNEL] = CHECK_READY, - [GPCMD_READ_TOC_PMA_ATIP] = CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - [GPCMD_READ_HEADER] = CHECK_READY, - [GPCMD_PLAY_AUDIO_10] = CHECK_READY, - [GPCMD_GET_CONFIGURATION] = ALLOW_UA, - [GPCMD_PLAY_AUDIO_MSF] = CHECK_READY, - [GPCMD_GET_EVENT_STATUS_NOTIFICATION] = ALLOW_UA, - [GPCMD_PAUSE_RESUME] = CHECK_READY, - [GPCMD_STOP_PLAY_SCAN] = CHECK_READY, - [GPCMD_READ_DISC_INFORMATION] = CHECK_READY, - [GPCMD_READ_TRACK_INFORMATION] = CHECK_READY, - [GPCMD_MODE_SELECT_10] = 0, - [GPCMD_MODE_SENSE_10] = 0, - [GPCMD_PLAY_AUDIO_12] = CHECK_READY, - [GPCMD_READ_12] = CHECK_READY, - [GPCMD_READ_DVD_STRUCTURE] = CHECK_READY, - [GPCMD_READ_CD_MSF] = CHECK_READY, - [GPCMD_SET_SPEED] = 0, - [GPCMD_PLAY_CD] = CHECK_READY, - [GPCMD_MECHANISM_STATUS] = 0, - [GPCMD_READ_CD] = CHECK_READY, - [GPCMD_SEND_DVD_STRUCTURE] = CHECK_READY -}; - -uint8_t mode_sense_pages[0x40] = -{ - [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, - [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, - [GPMODE_ALL_PAGES] = IMPLEMENTED -}; - -uint8_t page_flags[256] = -{ - [GPMODE_R_W_ERROR_PAGE] = 0, - [GPMODE_CDROM_PAGE] = 0, - [GPMODE_CDROM_AUDIO_PAGE] = PAGE_CHANGEABLE, - [GPMODE_CAPABILITIES_PAGE] = 0, -}; - -CDROM *cdrom; - -int readcdmode = 0; - -uint8_t mode_pages_in[256][256]; -uint8_t prefix_len; -uint8_t page_current; - -/*SCSI Sense Initialization*/ -void SCSISenseCodeOk(void) -{ - SCSISense.SenseKey=SENSE_NONE; - SCSISense.Asc=0; - SCSISense.Ascq=0; -} - -void SCSISenseCodeError(uint8_t SenseKey, uint8_t Asc, uint8_t Ascq) -{ - SCSISense.SenseKey=SenseKey; - SCSISense.Asc=Asc; - SCSISense.Ascq=Ascq; - SCSIPhase = SCSI_PHASE_STATUS; /* This *HAS* to be done, SCSIPhase is the same thing that ATAPI returns in IDE sector count, so after any error, - status phase (3) is correct. */ -} - -static void -ScsiPadStr8(uint8_t *buf, int buf_size, const char *src) -{ - int i; - - for (i = 0; i < buf_size; i++) { - if (*src != '\0') { - buf[i] = *src++; - } else { - buf[i] = ' '; - } - } -} - -uint32_t SCSIGetCDChannel(int channel) -{ - return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 8 : 6] : (channel + 1); -} - -uint32_t SCSIGetCDVolume(int channel) -{ - // return ((page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) && (mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 8 : 6] != 0)) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 9 : 7] : 0xFF; - return (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) ? mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][channel ? 9 : 7] : 0xFF; -} - -/*SCSI Mode Sense 6/10*/ -uint32_t SCSICDROMModeSense(uint8_t *buf, uint32_t pos, uint8_t type) -{ - if (type==GPMODE_ALL_PAGES || type==GPMODE_R_W_ERROR_PAGE) - { - /* &01 - Read error recovery */ - buf[pos++] = GPMODE_R_W_ERROR_PAGE; - buf[pos++] = 6; /* Page length */ - buf[pos++] = 0; /* Error recovery parameters */ - buf[pos++] = 5; /* Read retry count */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - } - - if (type==GPMODE_ALL_PAGES || type==GPMODE_CDROM_PAGE) - { - /* &0D - CD-ROM Parameters */ - buf[pos++] = GPMODE_CDROM_PAGE; - buf[pos++] = 6; /* Page length */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 1; /* Inactivity time multiplier *NEEDED BY RISCOS* value is a guess */ - buf[pos++] = 0; buf[pos++] = 60; /* MSF settings */ - buf[pos++] = 0; buf[pos++] = 75; /* MSF settings */ - } - - if (type==GPMODE_ALL_PAGES || type==GPMODE_CDROM_AUDIO_PAGE) - { - /* &0e - CD-ROM Audio Control Parameters */ - buf[pos++] = GPMODE_CDROM_AUDIO_PAGE; - buf[pos++] = 0xE; /* Page length */ - if (page_flags[GPMODE_CDROM_AUDIO_PAGE] & PAGE_CHANGED) - { - int i; - for (i = 0; i < 14; i++) - { - buf[pos++] = mode_pages_in[GPMODE_CDROM_AUDIO_PAGE][i]; - } - } - else - { - buf[pos++] = 4; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; buf[pos++] = 75; /* Logical audio block per second */ - buf[pos++] = 1; /* CDDA Output Port 0 Channel Selection */ - buf[pos++] = 0xFF; /* CDDA Output Port 0 Volume */ - buf[pos++] = 2; /* CDDA Output Port 1 Channel Selection */ - buf[pos++] = 0xFF; /* CDDA Output Port 1 Volume */ - buf[pos++] = 0; /* CDDA Output Port 2 Channel Selection */ - buf[pos++] = 0; /* CDDA Output Port 2 Volume */ - buf[pos++] = 0; /* CDDA Output Port 3 Channel Selection */ - buf[pos++] = 0; /* CDDA Output Port 3 Volume */ - } - } - - if (type==GPMODE_ALL_PAGES || type==GPMODE_CAPABILITIES_PAGE) - { -// pclog("Capabilities page\n"); - /* &2A - CD-ROM capabilities and mechanical status */ - buf[pos++] = GPMODE_CAPABILITIES_PAGE; - buf[pos++] = 0x12; /* Page length */ - buf[pos++] = 0; buf[pos++] = 0; /* CD-R methods */ - buf[pos++] = 1; /* Supports audio play, not multisession */ - buf[pos++] = 0; /* Some other stuff not supported */ - buf[pos++] = 0; /* Some other stuff not supported (lock state + eject) */ - buf[pos++] = 0; /* Some other stuff not supported */ - buf[pos++] = (uint8_t) (CDROM_SPEED >> 8); - buf[pos++] = (uint8_t) CDROM_SPEED; /* Maximum speed */ - buf[pos++] = 0; buf[pos++] = 2; /* Number of audio levels - on and off only */ - buf[pos++] = 0; buf[pos++] = 0; /* Buffer size - none */ - buf[pos++] = (uint8_t) (CDROM_SPEED >> 8); - buf[pos++] = (uint8_t) CDROM_SPEED; /* Current speed */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Drive digital format */ - buf[pos++] = 0; /* Reserved */ - buf[pos++] = 0; /* Reserved */ - } - - return pos; -} - -/*SCSI Get Configuration*/ -uint8_t SCSICDROMSetProfile(uint8_t *buf, uint8_t *index, uint16_t profile) -{ - uint8_t *buf_profile = buf + 12; /* start of profiles */ - - buf_profile += ((*index) * 4); /* start of indexed profile */ - buf_profile[0] = (profile >> 8) & 0xff; - buf_profile[1] = profile & 0xff; - buf_profile[2] = ((buf_profile[0] == buf[6]) && (buf_profile[1] == buf[7])); - - /* each profile adds 4 bytes to the response */ - (*index)++; - buf[11] += 4; /* Additional Length */ - - return 4; -} - -/*SCSI Read DVD Structure*/ -int SCSICDROMReadDVDStructure(int format, const uint8_t *packet, uint8_t *buf) -{ - switch (format) { - case 0x0: /* Physical format information */ - { - int layer = packet[6]; - uint64_t total_sectors; - total_sectors = (uint64_t) cdrom->size(); - - if (layer != 0) - return -ASC_INV_FIELD_IN_CMD_PACKET; - - total_sectors >>= 2; - if (total_sectors == 0) - return -ASC_MEDIUM_NOT_PRESENT; - - buf[4] = 1; /* DVD-ROM, part version 1 */ - buf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ - buf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ - buf[7] = 0; /* default densities */ - - /* FIXME: 0x30000 per spec? */ - buf[8] = buf[9] = buf[10] = buf[11] = 0; /* start sector */ - buf[12] = (total_sectors >> 24) & 0xff; /* end sector */ - buf[13] = (total_sectors >> 16) & 0xff; - buf[14] = (total_sectors >> 8) & 0xff; - buf[15] = total_sectors & 0xff; - - buf[16] = (total_sectors >> 24) & 0xff; /* l0 end sector */ - buf[17] = (total_sectors >> 16) & 0xff; - buf[18] = (total_sectors >> 8) & 0xff; - buf[19] = total_sectors & 0xff; - - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((2048+2)>>8)&0xff; - buf[1] = (2048+2)&0xff; - - /* 2k data + 4 byte header */ - return (2048 + 4); - } - - case 0x01: /* DVD copyright information */ - buf[4] = 0; /* no copyright data */ - buf[5] = 0; /* no region restrictions */ - - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((4+2)>>8)&0xff; - buf[1] = (4+2)&0xff; - - /* 4 byte header + 4 byte data */ - return (4 + 4); - - case 0x03: /* BCA information - invalid field for no BCA info */ - return -ASC_INV_FIELD_IN_CMD_PACKET; - - case 0x04: /* DVD disc manufacturing information */ - /* Size of buffer, not including 2 byte size field */ - buf[0] = ((2048+2)>>8)&0xff; - buf[1] = (2048+2)&0xff; - - /* 2k data + 4 byte header */ - return (2048 + 4); - - case 0xff: - /* - * This lists all the command capabilities above. Add new ones - * in order and update the length and buffer return values. - */ - - buf[4] = 0x00; /* Physical format */ - buf[5] = 0x40; /* Not writable, is readable */ - buf[6] = ((2048+4)>>8)&0xff; - buf[7] = (2048+4)&0xff; - - buf[8] = 0x01; /* Copyright info */ - buf[9] = 0x40; /* Not writable, is readable */ - buf[10] = ((4+4)>>8)&0xff; - buf[11] = (4+4)&0xff; - - buf[12] = 0x03; /* BCA info */ - buf[13] = 0x40; /* Not writable, is readable */ - buf[14] = ((188+4)>>8)&0xff; - buf[15] = (188+4)&0xff; - - buf[16] = 0x04; /* Manufacturing info */ - buf[17] = 0x40; /* Not writable, is readable */ - buf[18] = ((2048+4)>>8)&0xff; - buf[19] = (2048+4)&0xff; - - /* Size of buffer, not including 2 byte size field */ - buf[6] = ((16+2)>>8)&0xff; - buf[7] = (16+2)&0xff; - - /* data written + 4 byte header */ - return (16 + 4); - - default: /* TODO: formats beyond DVD-ROM requires */ - return -ASC_INV_FIELD_IN_CMD_PACKET; - } -} - -/*SCSI Get Event Status Notification*/ -uint32_t SCSICDROMEventStatus(uint8_t *buffer) -{ - uint8_t event_code, media_status = 0; - - if (buffer[5]) - { - media_status = MS_TRAY_OPEN; - cdrom->stop(); - } - else - { - media_status = MS_MEDIA_PRESENT; - } - - event_code = MEC_NO_CHANGE; - if (media_status != MS_TRAY_OPEN) - { - if (!buffer[4]) - { - event_code = MEC_NEW_MEDIA; - cdrom->load(); - } - else if (buffer[4]==2) - { - event_code = MEC_EJECT_REQUESTED; - cdrom->eject(); - } - } - - buffer[4] = event_code; - buffer[5] = media_status; - buffer[6] = 0; - buffer[7] = 0; - - return 8; -} - -void SCSICDROM_Insert() -{ - SCSISense.UnitAttention=1; -} - -int cd_status = CD_STATUS_EMPTY; -int prev_status; - -static uint8_t ScsiPrev; -static int SenseCompleted; - -int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type) -{ - if ((cdrom_sector_flags & 0x06) == 0x02) - { - /* Add error flags. */ - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); - cdrom_sector_size += 294; - } - else if ((cdrom_sector_flags & 0x06) == 0x04) - { - /* Add error flags. */ - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); - cdrom_sector_size += 296; - } - else if ((cdrom_sector_flags & 0x06) == 0x06) - { - // pclog("Invalid error flags\n"); - return 0; - } - - /* if (real_sector_type == 1) - { */ - if ((cdrom_sector_flags & 0x700) == 0x100) - { - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); - cdrom_sector_size += 96; - } - else if ((cdrom_sector_flags & 0x700) == 0x200) - { - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); - cdrom_sector_size += 16; - } - else if ((cdrom_sector_flags & 0x700) == 0x400) - { - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); - cdrom_sector_size += 96; - } - else if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - // pclog("Invalid subchannel data flags\n"); - return 0; - } - // } - - // pclog("CD-ROM sector size after processing: %i (%i, %i) [%04X]\n", cdrom_sector_size, cdrom_sector_type, real_sector_type, cdrom_sector_flags); - - return cdrom_sector_size; -} - -int cdrom_LBAtoMSF_accurate() -{ - int temp_pos; - int m, s, f; - - temp_pos = SectorLBA + 150; - f = temp_pos % 75; - temp_pos -= f; - temp_pos /= 75; - s = temp_pos % 60; - temp_pos -= s; - temp_pos /= 60; - m = temp_pos; - - return ((m << 16) | (s << 8) | f); -} - -int cdrom_read_data(uint8_t *buffer) -{ - int real_sector_type; - uint8_t *b; - uint8_t *temp_b; - int is_audio; - int real_pos; - - b = temp_b = buffer; - - if (cdrom_sector_ismsf) - { - real_pos = cdrom_LBAtoMSF_accurate(); - } - else - { - real_pos = SectorLBA; - } - - memset(cdrom_sector_buffer.buffer, 0, 2856); - - // is_audio = cdrom->is_track_audio(real_pos, cdrom_sector_ismsf); - real_sector_type = cdrom->sector_data_type(real_pos, cdrom_sector_ismsf); - // pclog("Sector type: %i\n", real_sector_type); - - if ((cdrom_sector_type > 0) && (cdrom_sector_type < 6)) - { - if (real_sector_type != cdrom_sector_type) - { - return 0; - } - } - else if (cdrom_sector_type == 6) - { - /* READ (6), READ (10), READ (12) */ - if ((real_sector_type != 2) && (real_sector_type != 4)) - { - return 0; - } - } - - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - return 0; - } - - cdrom->readsector_raw(cdrom_sector_buffer.buffer, real_pos, cdrom_sector_ismsf); - - if (real_sector_type == 1) - { - memcpy(b, cdrom_sector_buffer.buffer, 2352); - cdrom_sector_size = 2352; - } - else - { - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - return 0; - } - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - if (cdrom_sector_flags & 0x20) /* Header */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - if (real_sector_type == 2) - { - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - } - else if (real_sector_type == 3) - { - /* Mode 2 sector, non-XA mode. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 2328); - cdrom_sector_size += 8; - temp_b += 8; - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2328); - cdrom_sector_size += 2328; - temp_b += 2328; - } - } - else if (real_sector_type == 4) - { - /* Mode 2 sector, XA Form 1 mode */ - if ((cdrom_sector_flags & 0xf0) == 0x30) - { - return 0; - } - if (((cdrom_sector_flags & 0xf8) >= 0xa8) && ((cdrom_sector_flags & 0xf8) <= 0xd8)) - { - return 0; - } - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - if ((cdrom_sector_flags & 0xf0) == 0x10) - { - /* The data is alone, include sub-header. */ - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2040); - cdrom_sector_size += 2040; - temp_b += 2040; - } - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data + 2040, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - } - else if (real_sector_type == 5) - { - /* Mode 2 sector, XA Form 2 mode */ - if ((cdrom_sector_flags & 0xf0) == 0x30) - { - return 0; - } - if (((cdrom_sector_flags & 0xf8) >= 0xa8) || ((cdrom_sector_flags & 0xf8) <= 0xd8)) - { - return 0; - } - /* Mode 2 sector, XA Form 1 mode */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.sub_header, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m2_data.user_data, 2328); - cdrom_sector_size += 2328; - temp_b += 2328; - } - } - else - { - return 0; - } - } - - pclog("CD-ROM sector size: %i (%i, %i) [%04X]\n", cdrom_sector_size, cdrom_sector_type, real_sector_type, cdrom_sector_flags); - return cdrom_add_error_and_subchannel(b, real_sector_type); -} - -void SCSIClearSense(uint8_t Command, uint8_t IgnoreUA) -{ - if ((SCSISense.SenseKey == SENSE_UNIT_ATTENTION) || IgnoreUA) - { - pclog("Sense cleared\n"); - ScsiPrev=Command; - SCSISenseCodeOk(); - } -} - -struct -{ - uint8_t opcode; - uint8_t polled; - uint8_t reserved2[2]; - uint8_t class; - uint8_t reserved3[2]; - uint16_t len; - uint8_t control; -} *gesn_cdb; - -struct -{ - uint16_t len; - uint8_t notification_class; - uint8_t supported_events; -} *gesn_event_header; - -static int SCSICDROM_TOC(uint8_t id, uint8_t *cdb) -{ - int TocFormat; - - TocFormat = cdb[2] & 0xf; - if (TocFormat == 0) - TocFormat = (cdb[9]>>6) & 3; - - return TocFormat; -} - -void SCSICDROM_Command(uint8_t id, uint8_t *cmdbuffer, uint8_t *cdb) -{ - int len; - int pos=0; - int DVDRet; - uint8_t Index = 0; - int real_pos; - int msf; - uint32_t Size; - unsigned Idx = 0; - unsigned SizeIndex; - unsigned PreambleLen; - unsigned char Temp; - int max_length = 0; - int track = 0; - int ret = 0; - - msf = cdb[1] & 2; - - //The not ready/unit attention stuff below is only for the Adaptec! - //The Buslogic one is located in buslogic.c. - - if (!scsi_model) - { - if (cdrom->medium_changed()) - { - pclog("Media changed\n"); - SCSICDROM_Insert(); - } - - if (!cdrom->ready() && SCSISense.UnitAttention) - { - /* If the drive is not ready, there is no reason to keep the - UNIT ATTENTION condition present, as we only use it to mark - disc changes. */ - SCSISense.UnitAttention = 0; - } - - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (SCSISense.UnitAttention == 1) - { - SCSISense.UnitAttention = 2; - if (!(SCSICommandTable[cdb[0]] & ALLOW_UA)) - { - SCSISenseCodeError(SENSE_UNIT_ATTENTION, ASC_MEDIUM_MAY_HAVE_CHANGED, 0); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSICallback[id]=50*SCSI_TIME; - return; - } - } - else if (SCSISense.UnitAttention == 2) - { - if (cdb[0]!=GPCMD_REQUEST_SENSE) - { - SCSISense.UnitAttention = 0; - } - } - - /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* - clear the UNIT ATTENTION condition if it's set. */ - if (cdb[0]!=GPCMD_REQUEST_SENSE) - { - SCSIClearSense(cdb[0], 0); - } - - /* Next it's time for NOT READY. */ - if ((SCSICommandTable[cdb[0]] & CHECK_READY) && !cdrom->ready()) - { - pclog("Not ready\n"); - SCSISenseCodeError(SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT, 0); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSICallback[id]=50*SCSI_TIME; - return; - } - } - - prev_status = cd_status; - cd_status = cdrom->status(); - if (((prev_status == CD_STATUS_PLAYING) || (prev_status == CD_STATUS_PAUSED)) && ((cd_status != CD_STATUS_PLAYING) && (cd_status != CD_STATUS_PAUSED))) - { - SenseCompleted = 1; - } - else - { - SenseCompleted = 0; - } - - switch (cdb[0]) - { - case GPCMD_TEST_UNIT_READY: - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_REQUEST_SENSE: - len = cdb[4]; - - /*Will return 18 bytes of 0*/ - memset(cmdbuffer,0,512); - - cmdbuffer[0]=0x80|0x70; - - if ((SCSISense.SenseKey > 0) || (cd_status < CD_STATUS_PLAYING)) - { - if (SenseCompleted) - { - cmdbuffer[2]=SENSE_ILLEGAL_REQUEST; - cmdbuffer[12]=ASC_AUDIO_PLAY_OPERATION; - cmdbuffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } - else - { - cmdbuffer[2]=SCSISense.SenseKey; - cmdbuffer[12]=SCSISense.Asc; - cmdbuffer[13]=SCSISense.Ascq; - } - } - else if ((SCSISense.SenseKey == 0) && (cd_status >= CD_STATUS_PLAYING) && (cd_status != CD_STATUS_STOPPED)) - { - cmdbuffer[2]=SENSE_ILLEGAL_REQUEST; - cmdbuffer[12]=ASC_AUDIO_PLAY_OPERATION; - cmdbuffer[13]=(cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; - } - else - { - if (SCSISense.UnitAttention) - { - cmdbuffer[2]=SENSE_UNIT_ATTENTION; - cmdbuffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - cmdbuffer[13]=0; - } - } - - cmdbuffer[7]=10; - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - - if (cmdbuffer[2] == SENSE_UNIT_ATTENTION) - { - /* If the last remaining sense is unit attention, clear - that condition. */ - SCSISense.UnitAttention = 0; - } - - /* Clear the sense stuff as per the spec. */ - ScsiPrev=cdb[0]; - if (cdrom->ready()) - SCSISenseCodeOk(); - return; - - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - cdrom_sector_ismsf = 0; - - if (cdb[0] == GPCMD_READ_6) - { - SectorLen=cdb[4]; - SectorLBA=((((uint32_t) cdb[1]) & 0x1f)<<16)|(((uint32_t) cdb[2])<<8)|((uint32_t) cdb[3]); - } - else if (cdb[0] == GPCMD_READ_10) - { - SectorLen=(cdb[7]<<8)|cdb[8]; - SectorLBA=(cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - } - else - { - SectorLen=(((uint32_t) cdb[6])<<24)|(((uint32_t) cdb[7])<<16)|(((uint32_t) cdb[8])<<8)|((uint32_t) cdb[9]); - SectorLBA=(((uint32_t) cdb[2])<<24)|(((uint32_t) cdb[3])<<16)|(((uint32_t) cdb[4])<<8)|((uint32_t) cdb[5]); - } - - if (SectorLBA > (cdrom->size() - 1)) - { - pclog("Trying to read beyond the end of disc\n"); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0); - SCSICallback[id]=50*SCSI_TIME; - break; - } - - if (!SectorLen) - { - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=20*SCSI_TIME; - break; - } - - cdrom_sector_type = 6; - cdrom_sector_flags = 0x10; - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = SectorLen * 2048; - - SCSIDMAResetPosition(id); - return; - - case GPCMD_SEEK_6: - case GPCMD_SEEK_10: - if (cdb[0] == GPCMD_SEEK_6) - { - pos = ((((uint32_t) cdb[1]) & 0x1f)<<16)|(((uint32_t) cdb[2])<<8)|((uint32_t) cdb[3]); - } - else - { - pos = (cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - } - cdrom->seek(pos); - - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_INQUIRY: - max_length = cdb[4]; - len = max_length; - - if (cdb[1] & 1) - { - PreambleLen = 4; - SizeIndex = 3; - - cmdbuffer[Idx++] = 05; - cmdbuffer[Idx++] = cdb[2]; - cmdbuffer[Idx++] = 0; - - Idx++; - - switch (cdb[2]) - { - case 0x00: - cmdbuffer[Idx++] = 0x00; - cmdbuffer[Idx++] = 0x83; - break; - - case 0x83: - if (Idx + 24 > max_length) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_DATA_PHASE_ERROR, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - cmdbuffer[Idx++] = 0x02; - cmdbuffer[Idx++] = 0x00; - cmdbuffer[Idx++] = 0x00; - cmdbuffer[Idx++] = 20; - ScsiPadStr8(cmdbuffer + Idx, 20, "53R141"); /* Serial */ - Idx += 20; - - if (Idx + 72 > max_length) - { - goto SCSIOut; - } - cmdbuffer[Idx++] = 0x02; - cmdbuffer[Idx++] = 0x01; - cmdbuffer[Idx++] = 0x00; - cmdbuffer[Idx++] = 68; - ScsiPadStr8(cmdbuffer + Idx, 8, "86Box"); /* Vendor */ - Idx += 8; - ScsiPadStr8(cmdbuffer + Idx, 40, "86BoxCD 1.00"); /* Product */ - Idx += 40; - ScsiPadStr8(cmdbuffer + Idx, 20, "53R141"); /* Product */ - Idx += 20; - break; - - default: - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - } - else - { - PreambleLen = 5; - SizeIndex = 4; - - cmdbuffer[0] = 0x05; /*CD-ROM*/ - cmdbuffer[1] = 0x80; /*Removable*/ - cmdbuffer[2] = 0; - cmdbuffer[3] = 0x21; - cmdbuffer[4] = 31; - cmdbuffer[5] = 0; - cmdbuffer[6] = 0; - cmdbuffer[7] = 0; - ScsiPadStr8(cmdbuffer + 8, 8, "86Box"); /* Vendor */ - ScsiPadStr8(cmdbuffer + 16, 16, "86BoxCD"); /* Product */ - ScsiPadStr8(cmdbuffer + 32, 4, emulator_version); /* Revision */ - - Idx = 36; - } - -SCSIOut: - cmdbuffer[SizeIndex] = Idx - PreambleLen; - len=Idx; - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_MODE_SELECT_6: - case GPCMD_MODE_SELECT_10: - if (cdb[0] == GPCMD_MODE_SELECT_6) - { - len = cdb[4]; - prefix_len = 6; - } - else - { - len = (cdb[7]<<8)|cdb[8]; - prefix_len = 10; - } - - page_current = cdb[2]; - if (page_flags[page_current] & PAGE_CHANGEABLE) - page_flags[GPMODE_CDROM_AUDIO_PAGE] |= PAGE_CHANGED; - - SCSIPhase = SCSI_PHASE_DATAOUT; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - return; - - case GPCMD_MODE_SENSE_6: - case GPCMD_MODE_SENSE_10: - if (cdb[0] == GPCMD_MODE_SENSE_6) - len = cdb[4]; - else - len = (cdb[7]<<8)|cdb[8]; - - Temp = cdb[2] & 0x3F; - - memset(cmdbuffer, 0, len); - - if (!(mode_sense_pages[cdb[2] & 0x3f] & IMPLEMENTED)) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - - if (cdb[0] == GPCMD_MODE_SENSE_6) - { - len = SCSICDROMModeSense(cmdbuffer, 4, Temp); - cmdbuffer[0] = len - 1; - cmdbuffer[1] = 3; /*120mm data CD-ROM*/ - } - else - { - len = SCSICDROMModeSense(cmdbuffer, 8, Temp); - cmdbuffer[0] = (len - 2)>>8; - cmdbuffer[1] = (len - 2)&255; - cmdbuffer[2] = 3; /*120mm data CD-ROM*/ - } - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - return; - - case GPCMD_START_STOP_UNIT: - switch(cdb[4] & 3) - { - case 0: /* Stop the disc. */ - cdrom->stop(); - break; - case 1: /* Start the disc and read the TOC. */ - cdrom->medium_changed(); /* This causes a TOC reload. */ - break; - case 2: /* Eject the disc if possible. */ - cdrom->stop(); -#ifndef __unix - win_cdrom_eject(); -#endif - break; - case 3: /* Load the disc (close tray). */ -#ifndef __unix - win_cdrom_reload(); -#else - cdrom->load(); -#endif - break; - } - - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_PREVENT_REMOVAL: - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_READ_CDROM_CAPACITY: - if (cdrom->read_capacity) - { - cdrom->read_capacity(cmdbuffer); - } - else - { - Size = cdrom->size() - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(cmdbuffer, 0, 8); - cmdbuffer[0] = (Size >> 24) & 0xff; - cmdbuffer[1] = (Size >> 16) & 0xff; - cmdbuffer[2] = (Size >> 8) & 0xff; - cmdbuffer[3] = Size & 0xff; - cmdbuffer[6] = 8; /* 2048 = 0x0800 */ - } - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = 8; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_READ_SUBCHANNEL: - if (cdb[3] > 3) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - break; - } - - switch(cdb[3]) - { - case 0: - Temp = 4; - break; - case 1: - Temp = 16; - break; - default: - Temp = 24; - break; - } - - if (cdrom->read_subchannel) - { - cdrom->read_subchannel(cdb, cmdbuffer); - len = Temp; - } - else - { - memset(cmdbuffer, 24, 0); - pos = 0; - cmdbuffer[pos++]=0; - cmdbuffer[pos++]=0; /*Audio status*/ - cmdbuffer[pos++]=0; cmdbuffer[pos++]=0; /*Subchannel length*/ - cmdbuffer[pos++]=cdb[3]; /*Format code*/ - if (!(cdb[2] & 0x40) || (cdb[3] == 0)) - { - len = 4; - } - else - { - len = Temp; - } - if (cdb[3] == 1) - { - cmdbuffer[1]=cdrom->getcurrentsubchannel(&cmdbuffer[5],msf); - } - } - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=1000*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_READ_TOC_PMA_ATIP: - switch (SCSICDROM_TOC(id, cdb)) - { - case 0: /*Normal*/ - len = cdb[8]|(cdb[7]<<8); - len = cdrom->readtoc(cmdbuffer, cdb[6], msf, len, 0); - break; - - case 1: /*Multi session*/ - len = cdb[8]|(cdb[7]<<8); - len = cdrom->readtoc_session(cmdbuffer, msf, len); - cmdbuffer[0] = 0; - cmdbuffer[1] = 0xA; - break; - - case 2: /*Raw*/ - len = cdb[8]|(cdb[7]<<8); - len = cdrom->readtoc_raw(cmdbuffer, msf, len); - break; - - default: - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - return; - - case GPCMD_READ_HEADER: - if (cdrom->read_header) - { - cdrom->read_header(cdb, cmdbuffer); - } - else - { - SectorLen=(cdb[7]<<8)|cdb[8]; - SectorLBA=(cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - if (msf) - { - real_pos = cdrom_LBAtoMSF_accurate(); - } - else - { - real_pos = SectorLBA; - } - cmdbuffer[4] = (real_pos >> 24); - cmdbuffer[5] = ((real_pos >> 16) & 0xff); - cmdbuffer[6] = ((real_pos >> 8) & 0xff); - cmdbuffer[7] = real_pos & 0xff; - cmdbuffer[0]=1; /*2048 bytes user data*/ - cmdbuffer[1]=cmdbuffer[2]=cmdbuffer[3]=0; - } - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = 8; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_PLAY_AUDIO_10: - case GPCMD_PLAY_AUDIO_MSF: - case GPCMD_PLAY_AUDIO_12: - if (cdb[0] == GPCMD_PLAY_AUDIO_10) - { - pos = (cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - len = (cdb[7]<<8)|cdb[8]; - } - else if (cdb[0] == GPCMD_PLAY_AUDIO_MSF) - { - pos = (cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - len = (cdb[6]<<16)|(cdb[7]<<8)|cdb[8]; - } - else - { - pos = (cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - len = (cdb[7]<<16)|(cdb[8]<<8)|cdb[9]; - } - - if ((cdrom_drive < 1) || (cdrom_drive == 200) || (cd_status <= CD_STATUS_DATA_ONLY) || - !cdrom->is_track_audio(pos, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) - { - pclog("Invalid mode for this track\n"); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_MODE_FOR_THIS_TRACK, 0x00); - SCSICallback[id]=50*SCSI_TIME; - break; - } - - cdrom->playaudio(pos, len, (cdb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0); - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_GET_CONFIGURATION: - len = (cdb[7]<<8)|cdb[8]; - - Index = 0; - - /* only feature 0 is supported */ - if (cdb[2] != 0 || cdb[3] != 0) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - - /* - * XXX: avoid overflow for io_buffer if length is bigger than - * the size of that buffer (dimensioned to max number of - * sectors to transfer at once) - * - * Only a problem if the feature/profiles grow. - */ - if (len > 512) /* XXX: assume 1 sector */ - len = 512; - - memset(cmdbuffer, 0, len); - /* - * the number of sectors from the media tells us which profile - * to use as current. 0 means there is no media - */ - if (len > CD_MAX_SECTORS ) - { - cmdbuffer[6] = (MMC_PROFILE_DVD_ROM >> 8) & 0xff; - cmdbuffer[7] = MMC_PROFILE_DVD_ROM & 0xff; - } - else if (len <= CD_MAX_SECTORS) - { - cmdbuffer[6] = (MMC_PROFILE_CD_ROM >> 8) & 0xff; - cmdbuffer[7] = MMC_PROFILE_CD_ROM & 0xff; - } - cmdbuffer[10] = 0x02 | 0x01; /* persistent and current */ - len = 12; /* headers: 8 + 4 */ - len += SCSICDROMSetProfile(cmdbuffer, &Index, MMC_PROFILE_DVD_ROM); - len += SCSICDROMSetProfile(cmdbuffer, &Index, MMC_PROFILE_CD_ROM); - cmdbuffer[0] = ((len-4) >> 24) & 0xff; - cmdbuffer[1] = ((len-4) >> 16) & 0xff; - cmdbuffer[2] = ((len-4) >> 8) & 0xff; - cmdbuffer[3] = (len-4) & 0xff; - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_GET_EVENT_STATUS_NOTIFICATION: - gesn_cdb = (void *)cdb; - gesn_event_header = (void *)cmdbuffer; - - /* It is fine by the MMC spec to not support async mode operations */ - if (!(gesn_cdb->polled & 0x01)) - { /* asynchronous mode */ - /* Only pollign is supported, asynchronous mode is not. */ - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - - /* polling mode operation */ - - /* - * These are the supported events. - * - * We currently only support requests of the 'media' type. - * Notification class requests and supported event classes are bitmasks, - * but they are built from the same values as the "notification class" - * field. - */ - gesn_event_header->supported_events = 1 << GESN_MEDIA; - - /* - * We use |= below to set the class field; other bits in this byte - * are reserved now but this is useful to do if we have to use the - * reserved fields later. - */ - gesn_event_header->notification_class = 0; - - /* - * Responses to requests are to be based on request priority. The - * notification_class_request_type enum above specifies the - * priority: upper elements are higher prio than lower ones. - */ - if (gesn_cdb->class & (1 << GESN_MEDIA)) - { - gesn_event_header->notification_class |= GESN_MEDIA; - len = SCSICDROMEventStatus(cmdbuffer); - } - else - { - gesn_event_header->notification_class = 0x80; /* No event available */ - SCSIDevices[id].CmdBufferLength = sizeof(*gesn_event_header); - } - gesn_event_header->len = len - sizeof(*gesn_event_header); - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_PAUSE_RESUME: - if (cdb[8]&1) cdrom->resume(); - else cdrom->pause(); - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_STOP_PLAY_SCAN: - cdrom->stop(); - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_READ_DISC_INFORMATION: - if (cdrom->read_disc_information) - { - cdrom->read_disc_information(cmdbuffer); - } - else - { - cmdbuffer[1] = 32; - cmdbuffer[2] = 0xe; /* last session complete, disc finalized */ - cmdbuffer[3] = 1; /* first track on disc */ - cmdbuffer[4] = 1; /* # of sessions */ - cmdbuffer[5] = 1; /* first track of last session */ - cmdbuffer[6] = 1; /* last track of last session */ - cmdbuffer[7] = 0x20; /* unrestricted use */ - cmdbuffer[8] = 0x00; /* CD-ROM */ - } - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = 34; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_READ_TRACK_INFORMATION: - max_length = cdb[7]; - max_length <<= 8; - max_length |= cdb[8]; - - track = ((uint32_t) cdb[2]) << 24; - track |= ((uint32_t) cdb[3]) << 16; - track |= ((uint32_t) cdb[4]) << 8; - track |= (uint32_t) cdb[5]; - - if (cdrom->read_track_information) - { - ret = cdrom->read_track_information(cdb, cmdbuffer); - - if (!ret) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - - len = cmdbuffer[0]; - len <<= 8; - len |= cmdbuffer[1]; - len += 2; - } - else - { - if (((cdb[1] & 0x03) != 1) || (track != 1)) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - - len = 36; - cmdbuffer[1] = 34; - cmdbuffer[2] = 1; /* track number (LSB) */ - cmdbuffer[3] = 1; /* session number (LSB) */ - cmdbuffer[5] = (0 << 5) | (0 << 4) | (4 << 0); /* not damaged, primary copy, data track */ - cmdbuffer[6] = (0 << 7) | (0 << 6) | (0 << 5) | (0 << 6) | (1 << 0); /* not reserved track, not blank, not packet writing, not fixed packet, data mode 1 */ - cmdbuffer[7] = (0 << 1) | (0 << 0); /* last recorded address not valid, next recordable address not valid */ - cmdbuffer[8] = 0; /* track start address is 0 */ - cmdbuffer[24] = (cdrom->size() >> 24) & 0xff; /* track size */ - cmdbuffer[25] = (cdrom->size() >> 16) & 0xff; /* track size */ - cmdbuffer[26] = (cdrom->size() >> 8) & 0xff; /* track size */ - cmdbuffer[27] = cdrom->size() & 0xff; /* track size */ - cmdbuffer[32] = 0; /* track number (MSB) */ - cmdbuffer[33] = 0; /* session number (MSB) */ - } - - if (len > max_length) - { - len = max_length; - cmdbuffer[0] = ((max_length - 2) >> 8) & 0xff; - cmdbuffer[1] = (max_length - 2) & 0xff; - } - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - break; - - case GPCMD_READ_DVD_STRUCTURE: - len = (cdb[6]<<24)|(cdb[7]<<16)|(cdb[8]<<8)|cdb[9]; - - if (cdb[7] < 0xff) - { - if (len <= CD_MAX_SECTORS) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INCOMPATIBLE_FORMAT, 0x00); - SCSICallback[id]=50*SCSI_TIME; - break; - } - else - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - } - - memset(cmdbuffer, 0, len > 256 * 512 + 4 ? 256 * 512 + 4 : len); - - switch (cdb[7]) - { - case 0x00 ... 0x7f: - case 0xff: - if (cdb[1] == 0) - { - DVDRet = SCSICDROMReadDVDStructure(cdb[7], cdb, cmdbuffer); - - if (DVDRet < 0) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, -DVDRet, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - else - { - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = len; - - SCSIDMAResetPosition(id); - } - break; - } - /* TODO: BD support, fall through for now */ - - /* Generic disk structures */ - case 0x80: /* TODO: AACS volume identifier */ - case 0x81: /* TODO: AACS media serial number */ - case 0x82: /* TODO: AACS media identifier */ - case 0x83: /* TODO: AACS media key block */ - case 0x90: /* TODO: List of recognized format layers */ - case 0xc0: /* TODO: Write protection status */ - default: - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - return; - } - break; - - case GPCMD_READ_CD_MSF: - case GPCMD_READ_CD: - if (cdb[0] == GPCMD_READ_CD_MSF) - { - SectorLBA=MSFtoLBA(cdb[3],cdb[4],cdb[5]); - SectorLen=MSFtoLBA(cdb[6],cdb[7],cdb[8]); - - SectorLen -= SectorLBA; - SectorLen++; - - cdrom_sector_ismsf = 1; - } - else - { - SectorLen=(cdb[6]<<16)|(cdb[7]<<8)|cdb[8]; - SectorLBA=(cdb[2]<<24)|(cdb[3]<<16)|(cdb[4]<<8)|cdb[5]; - - cdrom_sector_ismsf = 0; - } - - if (SectorLBA > (cdrom->size() - 1)) - { - //pclog("Trying to read beyond the end of disc\n"); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0); - SCSICallback[id]=50*SCSI_TIME; - break; - } - - cdrom_sector_type = (cdb[1] >> 2) & 7; - cdrom_sector_flags = cdb[9] || ((cdb[10]) << 8); - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = SectorLen * cdrom_sector_size; - - SCSIDMAResetPosition(id); - return; - - case GPCMD_SET_SPEED: - SCSIPhase = SCSI_PHASE_STATUS; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=50*SCSI_TIME; - break; - - case GPCMD_MECHANISM_STATUS: - cmdbuffer[0] = 0; - cmdbuffer[1] = 0; - cmdbuffer[2] = 0; - cmdbuffer[3] = 0; - cmdbuffer[4] = 0; - cmdbuffer[5] = 1; - cmdbuffer[6] = 0; - cmdbuffer[7] = 0; - - SCSIPhase = SCSI_PHASE_DATAIN; - SCSIStatus = SCSI_STATUS_OK; - SCSICallback[id]=60*SCSI_TIME; - SCSIDevices[id].CmdBufferLength = 8; - - SCSIDMAResetPosition(id); - break; - } - - -} - -void SCSICDROM_ReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) -{ - int read_length = 0; - - switch (cdb[0]) - { - case GPCMD_READ_6: - case GPCMD_READ_10: - case GPCMD_READ_12: - case GPCMD_READ_CD_MSF: - case GPCMD_READ_CD: - pclog("Total data length requested: %d\n", datalen); - while (datalen > 0) - { - read_length = cdrom_read_data(data); //Fill the buffer the data it needs - if (!read_length) - { - pclog("Invalid read\n"); - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSISenseCodeError(SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET, 0x00); - SCSICallback[id]=50*SCSI_TIME; - break; - } - else - { - //Continue reading data until the sector length is 0. - data += read_length; - datalen -= read_length; - } - - pclog("True LBA: %d, buffer half: %d\n", SectorLBA, SectorLen * cdrom_sector_size); - - SectorLBA++; - SectorLen--; - - if (SectorLen == 0) - break; - } - break; - } -} diff --git a/src/sound.c b/src/sound.c index 54d1bf032..97ee72733 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1,6 +1,10 @@ +#include #include #include + +#include "cdrom.h" #include "ibm.h" + #include "device.h" #include "filters.h" @@ -89,7 +93,8 @@ int sound_pos_global = 0; int soundon = 1; -static int16_t cd_buffer[CD_BUFLEN * 2]; +static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; +static float cd_out_buffer[CD_BUFLEN * 2]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; static unsigned int cd_vol_l, cd_vol_r; @@ -102,62 +107,81 @@ void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) static void sound_cd_thread(void *param) { + int i = 0; + while (1) { - int c; + int c, has_audio; thread_wait_event(sound_cd_event, -1); - ioctl_audio_callback(cd_buffer, CD_BUFLEN*2); - if (soundon) - { - int32_t audio_vol_l = SCSIGetCDVolume(0); - int32_t audio_vol_r = SCSIGetCDVolume(1); - int channel_select[2]; + for (c = 0; c < CD_BUFLEN*2; c += 2) + { + cd_out_buffer[c] = 0; + cd_out_buffer[c+1] = 0; + } + for (i = 0; i < CDROM_NUM; i++) + { + has_audio = 0; + if (cdrom_drives[i].handler->audio_callback) + { + cdrom_drives[i].handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2); + has_audio = cdrom_drives[i].sound_on; + } + if (soundon && has_audio) + { + int32_t audio_vol_l = cdrom_mode_sense_get_volume(i, 0); + int32_t audio_vol_r = cdrom_mode_sense_get_volume(i, 1); + int channel_select[2]; + + channel_select[0] = cdrom_mode_sense_get_channel(i, 0); + channel_select[1] = cdrom_mode_sense_get_channel(i, 1); - channel_select[0] = SCSIGetCDChannel(0); - channel_select[1] = SCSIGetCDChannel(1); - - for (c = 0; c < CD_BUFLEN*2; c += 2) - { - int32_t cd_buffer_temp[2] = {0, 0}; + for (c = 0; c < CD_BUFLEN*2; c += 2) + { + int32_t cd_buffer_temp[2] = {0, 0}; + + /*First, adjust input from drive according to ATAPI/SCSI volume.*/ + cd_buffer[i][c] = ((int32_t)cd_buffer[i][c] * audio_vol_l) / 255; + cd_buffer[i][c+1] = ((int32_t)cd_buffer[i][c+1] * audio_vol_r) / 255; + + /*Apply ATAPI channel select*/ + if (channel_select[0] & 1) + cd_buffer_temp[0] += cd_buffer[i][c]; + if (channel_select[0] & 2) + cd_buffer_temp[1] += cd_buffer[i][c]; + if (channel_select[1] & 1) + cd_buffer_temp[0] += cd_buffer[i][c+1]; + if (channel_select[1] & 2) + cd_buffer_temp[1] += cd_buffer[i][c+1]; - /*First, adjust input from drive according to ATAPI/SCSI volume.*/ - cd_buffer[c] = ((int32_t)cd_buffer[c] * audio_vol_l) / 255; - cd_buffer[c+1] = ((int32_t)cd_buffer[c+1] * audio_vol_r) / 255; + /*Apply sound card CD volume*/ + cd_buffer_temp[0] = (cd_buffer_temp[0] * (int)cd_vol_l) / 65535; + cd_buffer_temp[1] = (cd_buffer_temp[1] * (int)cd_vol_r) / 65535; - /*Apply ATAPI channel select*/ - if (channel_select[0] & 1) - cd_buffer_temp[0] += cd_buffer[c]; - if (channel_select[0] & 2) - cd_buffer_temp[1] += cd_buffer[c]; - if (channel_select[1] & 1) - cd_buffer_temp[0] += cd_buffer[c+1]; - if (channel_select[1] & 2) - cd_buffer_temp[1] += cd_buffer[c+1]; - - /*Apply sound card CD volume*/ - cd_buffer_temp[0] = (cd_buffer_temp[0] * (int)cd_vol_l) / 65535; - cd_buffer_temp[1] = (cd_buffer_temp[1] * (int)cd_vol_r) / 65535; + if (cd_buffer_temp[0] > 32767) + cd_buffer_temp[0] = 32767; + if (cd_buffer_temp[0] < -32768) + cd_buffer_temp[0] = -32768; + if (cd_buffer_temp[1] > 32767) + cd_buffer_temp[1] = 32767; + if (cd_buffer_temp[1] < -32768) + cd_buffer_temp[1] = -32768; - if (cd_buffer_temp[0] > 32767) - cd_buffer_temp[0] = 32767; - if (cd_buffer_temp[0] < -32768) - cd_buffer_temp[0] = -32768; - if (cd_buffer_temp[1] > 32767) - cd_buffer_temp[1] = 32767; - if (cd_buffer_temp[1] < -32768) - cd_buffer_temp[1] = -32768; + cd_buffer[i][c] = cd_buffer_temp[0]; + cd_buffer[i][c+1] = cd_buffer_temp[1]; - cd_buffer[c] = cd_buffer_temp[0]; - cd_buffer[c+1] = cd_buffer_temp[1]; - } + cd_out_buffer[c] += ((float) cd_buffer[i][c]) / 32768.0; + cd_out_buffer[c+1] += ((float) cd_buffer[i][c+1]) / 32768.0; + } - givealbuffer_cd(cd_buffer); - } + } + } + givealbuffer_cd(cd_out_buffer); } } static int32_t *outbuffer; +static float *outbuffer_ex; void sound_init() { @@ -165,6 +189,7 @@ void sound_init() inital(); outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int32_t)); + outbuffer_ex = malloc(SOUNDBUFLEN * 2 * sizeof(float)); sound_cd_event = thread_create_event(); sound_cd_thread_h = thread_create(sound_cd_thread, NULL); @@ -205,8 +230,13 @@ void sound_poll(void *priv) if (!soundf) soundf=fopen("sound.pcm","wb"); fwrite(buf16,(SOUNDBUFLEN)*2*2,1,soundf);*/ + + for (c = 0; c < SOUNDBUFLEN * 2; c++) + { + outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; + } - if (soundon) givealbuffer(outbuffer); + if (soundon) givealbuffer(outbuffer_ex); thread_set_event(sound_cd_event); @@ -221,10 +251,20 @@ void sound_speed_changed() void sound_reset() { + int i = 0; + timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL); sound_handlers_num = 0; sound_set_cd_volume(65535, 65535); - ioctl_audio_stop(); + + for (i = 0; i < CDROM_NUM; i++) + { + pclog("Resetting audio for CD-ROM %i...\n", i); + if (cdrom_drives[i].handler->audio_stop) + { + cdrom_drives[i].handler->audio_stop(i); + } + } } diff --git a/src/sound_cms.c b/src/sound_cms.c index f38f46f9c..93a2aab1f 100644 --- a/src/sound_cms.c +++ b/src/sound_cms.c @@ -7,6 +7,8 @@ #include "sound.h" #include "sound_cms.h" +#define MASTER_CLOCK 7159090 + typedef struct cms_t { int addrs[2]; @@ -37,9 +39,9 @@ void cms_update(cms_t *cms) { switch (cms->noisetype[c >> 1][c & 1]) { - case 0: cms->noisefreq[c >> 1][c & 1] = 31250; break; - case 1: cms->noisefreq[c >> 1][c & 1] = 15625; break; - case 2: cms->noisefreq[c >> 1][c & 1] = 7812; break; + case 0: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/256; break; + case 1: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/512; break; + case 2: cms->noisefreq[c >> 1][c & 1] = MASTER_CLOCK/1024; break; case 3: cms->noisefreq[c >> 1][c & 1] = cms->freq[c >> 1][(c & 1) * 3]; break; } } @@ -124,14 +126,14 @@ void cms_write(uint16_t addr, uint8_t val, void *p) case 0x0B: case 0x0C: case 0x0D: voice = cms->addrs[chip] & 7; cms->latch[chip][voice] = (cms->latch[chip][voice] & 0x700) | val; - cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); break; case 0x10: case 0x11: case 0x12: /*Octave*/ voice = (cms->addrs[chip] & 3) << 1; cms->latch[chip][voice] = (cms->latch[chip][voice] & 0xFF) | ((val & 7) << 8); cms->latch[chip][voice + 1] = (cms->latch[chip][voice + 1] & 0xFF) | ((val & 0x70) << 4); - cms->freq[chip][voice] = (15625 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); - cms->freq[chip][voice + 1] = (15625 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); + cms->freq[chip][voice] = (MASTER_CLOCK/512 << (cms->latch[chip][voice] >> 8)) / (511 - (cms->latch[chip][voice] & 255)); + cms->freq[chip][voice + 1] = (MASTER_CLOCK/512 << (cms->latch[chip][voice + 1] >> 8)) / (511 - (cms->latch[chip][voice + 1] & 255)); break; case 0x16: /*Noise*/ cms->noisetype[chip][0] = val & 3; diff --git a/src/soundopenal.c b/src/soundopenal.c index 78f81ed87..29173b75b 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -5,6 +5,7 @@ #ifdef USE_OPENAL #include #include +#include #endif #include "ibm.h" #include "sound.h" @@ -84,7 +85,7 @@ void inital() { #ifdef USE_OPENAL int c; - int16_t buf[BUFLEN*2]; + float buf[BUFLEN*2]; // printf("1\n"); check(); @@ -118,8 +119,8 @@ void inital() // printf("5\n"); for (c = 0; c < 4; c++) { - alBufferData(buffers[c], AL_FORMAT_STEREO16, buf, BUFLEN*2*2, FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*2, CD_FREQ); + alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); } alSourceQueueBuffers(source[0], 4, buffers); @@ -135,7 +136,7 @@ void inital() #endif } -void givealbuffer(int32_t *buf) +void givealbuffer(float *buf) { #ifdef USE_OPENAL int16_t buf16[BUFLEN*2]; @@ -174,7 +175,7 @@ void givealbuffer(int32_t *buf) // printf("U "); check(); - for (c=0;c> 16) & 0x1f; - if(riva128->pgraph.debug[1] & 0x10000 && ((riva128->pgraph.instance >> 4)) != riva128->pgraph.ctx_switch[3] && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104) + if((riva128->pgraph.debug[1] & 0x10000) && ((riva128->pgraph.instance >> 4) != riva128->pgraph.ctx_switch[3]) && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104)) { riva128->pgraph.ctx_switch[3] = riva128->pgraph.instance >> 4; riva128->pgraph.ctx_switch[1] = riva128->pramin[riva128->pgraph.instance + 4] & 0xffff; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index d84de678d..3306a3fc3 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -190,6 +190,7 @@ typedef struct texture_t volatile int refcount, refcount_r[2]; int is16; uint32_t palette_checksum; + uint32_t addr_start, addr_end; uint32_t *data; } texture_t; @@ -1466,8 +1467,10 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) else voodoo->texture_cache[tmu][c].palette_checksum = 0; - addr = voodoo->texture_cache[tmu][c].base + texture_offset[lod_min] * (voodoo->texture_cache[tmu][c].is16 ? 2 : 1); - addr_end = voodoo->texture_cache[tmu][c].base + texture_offset[lod_max+1] * (voodoo->texture_cache[tmu][c].is16 ? 2 : 1); + addr = voodoo->params.tex_base[tmu][lod_min]; + addr_end = voodoo->params.tex_base[tmu][lod_max+1]; + voodoo->texture_cache[tmu][c].addr_start = addr; + voodoo->texture_cache[tmu][c].addr_end = addr_end; for (; addr <= addr_end; addr += (1 << TEX_DIRTY_SHIFT)) voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT] = 1; @@ -1488,8 +1491,8 @@ static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) { int lod_min = (voodoo->texture_cache[tmu][c].tLOD >> 2) & 15; int lod_max = (voodoo->texture_cache[tmu][c].tLOD >> 8) & 15; - int addr_start = voodoo->texture_cache[tmu][c].base + texture_offset[lod_min] * (voodoo->texture_cache[tmu][c].is16 ? 2 : 1); - int addr_end = voodoo->texture_cache[tmu][c].base + texture_offset[lod_max+1] * (voodoo->texture_cache[tmu][c].is16 ? 2 : 1); + int addr_start = voodoo->texture_cache[tmu][c].addr_start; + int addr_end = voodoo->texture_cache[tmu][c].addr_end; if (dirty_addr >= (addr_start & voodoo->texture_mask & ~0x3ff) && dirty_addr < (((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff)) { diff --git a/src/win-config.c b/src/win-config.c index c542134ea..3badfebd5 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -32,11 +32,11 @@ static int settings_network_to_list[20], settings_list_to_network[20]; static int mouse_valid(int type, int model) { - if (type == MOUSE_TYPE_PS2 && !(models[model].flags & MODEL_PS2)) + if ((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2 && !(models[model].flags & MODEL_PS2)) return 0; - if (type == MOUSE_TYPE_AMSTRAD && !(models[model].flags & MODEL_AMSTRAD)) + if ((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD && !(models[model].flags & MODEL_AMSTRAD)) return 0; - if (type == MOUSE_TYPE_OLIM24 && !(models[model].flags & MODEL_OLIM24)) + if ((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24 && !(models[model].flags & MODEL_OLIM24)) return 0; return 1; } diff --git a/src/win-hdconf.c b/src/win-hdconf.c index cc09df282..8ab21591e 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -19,20 +19,6 @@ static uint64_t hd_new_spt, hd_new_hpc, hd_new_cyl; static int hd_new_hdi; static int new_cdrom_channel; -static void update_hdd_cdrom(HWND hdlg) -{ - HWND h; - int drive_num = 0; - - for (drive_num = 0; drive_num < IDE_NUM; drive_num++) - { - h = GetDlgItem(hdlg, IDC_CHDD + drive_num); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == drive_num) ? 0 : 1, 0); - h = GetDlgItem(hdlg, IDC_CCDROM + drive_num); - SendMessage(h, BM_SETCHECK, (new_cdrom_channel == drive_num) ? 1 : 0, 0); - } -} - int hdnew_no_update = 0; hard_disk_t hdnew_temp_hd; @@ -556,16 +542,13 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR hd_changed = 0; - new_cdrom_channel = atapi_cdrom_channel; - - update_hdd_cdrom(hdlg); return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: - if (hd_changed || atapi_cdrom_channel != new_cdrom_channel) + if (hd_changed) { if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) == IDOK) { @@ -586,8 +569,6 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR hdc[drive_num] = hd[drive_num]; } - atapi_cdrom_channel = new_cdrom_channel; - saveconfig(); resetpchard(); @@ -645,31 +626,6 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR drive_num = LOWORD(wParam) % 10; hdconf_edit_boxes(hdlg, drive_num, &(hd[drive_num])); return TRUE; - - case IDC_CHDD: - case IDC_DHDD: - case IDC_EHDD: - case IDC_FHDD: - case IDC_GHDD: - case IDC_HHDD: - case IDC_IHDD: - case IDC_JHDD: - if (new_cdrom_channel == (LOWORD(wParam) - IDC_CCDROM)) - new_cdrom_channel = -1; - update_hdd_cdrom(hdlg); - return TRUE; - - case IDC_CCDROM: - case IDC_DCDROM: - case IDC_ECDROM: - case IDC_FCDROM: - case IDC_GCDROM: - case IDC_HCDROM: - case IDC_ICDROM: - case IDC_JCDROM: - new_cdrom_channel = LOWORD(wParam) - IDC_CCDROM; - update_hdd_cdrom(hdlg); - return TRUE; } break; diff --git a/src/win.c b/src/win.c index c8ea78941..0fbb3f8fb 100644 --- a/src/win.c +++ b/src/win.c @@ -320,23 +320,27 @@ void thread_destroy_event(event_t *_event) static void initmenu(void) { - int c; - HMENU m; + int i, c; + HMENU dm, m; char s[32]; - m=GetSubMenu(menu,1); /*Disc*/ - m=GetSubMenu(m,17); /*CD-ROM*/ + dm=GetSubMenu(menu,1); /*Disc*/ - /* Loop through each Windows drive letter and test to see if - it's a CDROM */ - for (c='A';c<='Z';c++) - { - sprintf(s,"%c:\\",c); - if (GetDriveType(s)==DRIVE_CDROM) - { - sprintf(s, "Host CD/DVD Drive (%c:)", c); - AppendMenu(m,MF_STRING,IDM_CDROM_REAL+c,s); - } - } + for (i = 0; i < CDROM_NUM; i++) + { + m=GetSubMenu(dm,17+i); /*CD-ROM*/ + + /* Loop through each Windows drive letter and test to see if + it's a CDROM */ + for (c='A';c<='Z';c++) + { + sprintf(s,"%c:\\",c); + if (GetDriveType(s)==DRIVE_CDROM) + { + sprintf(s, "Host CD/DVD Drive (%c:)", c); + AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+c+(i * 1000),s); + } + } + } } void get_executable_name(char *s, int size) @@ -515,6 +519,28 @@ static void process_command_line() argv[argc] = NULL; } +int valid_models[2] = { 0, 1 }; +int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; +int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; +int valid_dma_channels[3] = { 5, 6, 7 }; +int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; + +int find_in_array(int *array, int val, int len, int menu_base) +{ + int i = 0; + int temp = 0; + for (i = 0; i < len; i++) + { + CheckMenuItem(menu, menu_base + array[i], MF_UNCHECKED); + if (array[i] == val) + { + temp = 1; + } + } + return temp; +} + HANDLE hinstAcc; int WINAPI WinMain (HINSTANCE hThisInstance, @@ -526,7 +552,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HWND hwnd; /* This is the handle for our window */ MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ - int c, d, bRet; + int c, d, e, bRet; char emulator_title[200]; LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ @@ -621,210 +647,90 @@ int WINAPI WinMain (HINSTANCE hThisInstance, // pclog("Checking CD-ROM menu item...\n"); /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ - if (cdrom_enabled) - CheckMenuItem(menu, IDM_CDROM_ENABLED, MF_CHECKED); + for (e = 0; e < CDROM_NUM; e++) + { + if (cdrom_drives[e].enabled) + CheckMenuItem(menu, IDM_CDROM_1_ENABLED + (e * 1000), MF_CHECKED); - if (scsi_cdrom_enabled) - CheckMenuItem(menu, IDM_CDROM_SCSI, MF_CHECKED); + if (cdrom_drives[e].sound_on) + CheckMenuItem(menu, IDM_CDROM_1_SOUND_ON + (e * 1000), MF_CHECKED); + + if (cdrom_drives[e].bus_type) + CheckMenuItem(menu, IDM_CDROM_1_SCSI + (e * 1000), MF_CHECKED); + + if (!find_in_array(valid_ide_channels, cdrom_drives[e].ide_channel, 8, IDM_CDROM_1_C + (e * 1000))) + { + fatal("Tertiary IDE controller: Invalid IRQ\n"); + } + + CheckMenuItem(menu, IDM_CDROM_1_C + (e * 1000) + cdrom_drives[e].ide_channel, MF_CHECKED); + + if (!find_in_array(valid_scsi_ids, cdrom_drives[e].scsi_device_id, 15, IDM_CDROM_1_0 + (e * 1000))) + { + fatal("Tertiary IDE controller: Invalid IRQ\n"); + } + + CheckMenuItem(menu, IDM_CDROM_1_0 + (e * 1000) + cdrom_drives[e].scsi_device_id, MF_CHECKED); + + if (cdrom_drives[e].host_drive == 200) + { + CheckMenuItem(menu, IDM_CDROM_1_ISO + (e * 1000), MF_CHECKED); + } + else + { + CheckMenuItem(menu, IDM_CDROM_1_REAL + (e * 1000) + cdrom_drives[e].host_drive, MF_CHECKED); + } + } if (ide_enable[2]) CheckMenuItem(menu, IDM_IDE_TER_ENABLED, MF_CHECKED); - CheckMenuItem(menu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); + if (!find_in_array(valid_irqs, ide_irq[2], 6, IDM_IDE_TER_IRQ9 - 9)) + { + fatal("Tertiary IDE controller: Invalid IRQ\n"); + } - if (ide_irq[2] == 9) - { - CheckMenuItem(menu, IDM_IDE_TER_IRQ9, MF_CHECKED); - } - else if (ide_irq[2] == 10) - { - CheckMenuItem(menu, IDM_IDE_TER_IRQ10, MF_CHECKED); - } - else if (ide_irq[2] == 11) - { - CheckMenuItem(menu, IDM_IDE_TER_IRQ11, MF_CHECKED); - } - else if (ide_irq[2] == 12) - { - CheckMenuItem(menu, IDM_IDE_TER_IRQ12, MF_CHECKED); - } - else if (ide_irq[2] == 14) - { - CheckMenuItem(menu, IDM_IDE_TER_IRQ14, MF_CHECKED); - } - else if (ide_irq[2] == 15) - { - CheckMenuItem(menu, IDM_IDE_TER_IRQ15, MF_CHECKED); - } - else - { - fatal("Unrecognized tertiary IDE controller IRQ\n"); - } + CheckMenuItem(menu, IDM_IDE_TER_IRQ9 - 9 + ide_irq[2], MF_CHECKED); if (ide_enable[3]) CheckMenuItem(menu, IDM_IDE_QUA_ENABLED, MF_CHECKED); - CheckMenuItem(menu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); - CheckMenuItem(menu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); + if (!find_in_array(valid_irqs, ide_irq[3], 6, IDM_IDE_QUA_IRQ9 - 9)) + { + fatal("Quaternary IDE controller: Invalid IRQ\n"); + } - if (ide_irq[3] == 9) - { - CheckMenuItem(menu, IDM_IDE_QUA_IRQ9, MF_CHECKED); - } - else if (ide_irq[3] == 10) - { - CheckMenuItem(menu, IDM_IDE_QUA_IRQ10, MF_CHECKED); - } - else if (ide_irq[3] == 11) - { - CheckMenuItem(menu, IDM_IDE_QUA_IRQ11, MF_CHECKED); - } - else if (ide_irq[3] == 12) - { - CheckMenuItem(menu, IDM_IDE_QUA_IRQ12, MF_CHECKED); - } - else if (ide_irq[3] == 14) - { - CheckMenuItem(menu, IDM_IDE_QUA_IRQ14, MF_CHECKED); - } - else if (ide_irq[3] == 15) - { - CheckMenuItem(menu, IDM_IDE_QUA_IRQ15, MF_CHECKED); - } - else - { - fatal("Unrecognized quaternary IDE controller IRQ\n"); - } + CheckMenuItem(menu, IDM_IDE_QUA_IRQ9 - 9 + ide_irq[3], MF_CHECKED); if (buslogic_enabled) CheckMenuItem(menu, IDM_SCSI_ENABLED, MF_CHECKED); - CheckMenuItem(menu, IDM_SCSI_MODEL0, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_MODEL1, MF_UNCHECKED); - - if (scsi_model == 0) + if (!find_in_array(valid_models, scsi_model, 2, IDM_SCSI_MODEL0)) { - CheckMenuItem(menu, IDM_SCSI_MODEL0, MF_CHECKED); - } - else if (scsi_model == 1) - { - CheckMenuItem(menu, IDM_SCSI_MODEL1, MF_CHECKED); - } - else - { - fatal("Unrecognized SCSI model\n"); + fatal("SCSI controller: Invalid model\n"); } - CheckMenuItem(menu, IDM_SCSI_BASE130, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_BASE134, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_BASE230, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_BASE234, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_BASE330, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_BASE334, MF_UNCHECKED); + CheckMenuItem(menu, IDM_SCSI_MODEL0 + scsi_model, MF_CHECKED); - if (scsi_base == 0x130) + if (!find_in_array(valid_bases, scsi_base, 6, IDM_SCSI_BASE130 - 0x130)) { - CheckMenuItem(menu, IDM_SCSI_BASE130, MF_CHECKED); - } - else if (scsi_base == 0x134) - { - CheckMenuItem(menu, IDM_SCSI_BASE134, MF_CHECKED); - } - else if (scsi_base == 0x230) - { - CheckMenuItem(menu, IDM_SCSI_BASE230, MF_CHECKED); - } - else if (scsi_base == 0x234) - { - CheckMenuItem(menu, IDM_SCSI_BASE234, MF_CHECKED); - } - else if (scsi_base == 0x330) - { - CheckMenuItem(menu, IDM_SCSI_BASE330, MF_CHECKED); - } - else if (scsi_base == 0x334) - { - CheckMenuItem(menu, IDM_SCSI_BASE334, MF_CHECKED); - } - else - { - fatal("Unrecognized SCSI base address\n"); + fatal("SCSI controller: Invalid base address\n"); } - CheckMenuItem(menu, IDM_SCSI_IRQ9, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_IRQ10, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_IRQ11, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_IRQ12, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_IRQ14, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_IRQ15, MF_UNCHECKED); + CheckMenuItem(menu, IDM_SCSI_BASE130 - 0x130 + scsi_base, MF_CHECKED); - if (scsi_irq == 9) + if (!find_in_array(valid_irqs, scsi_irq, 6, IDM_SCSI_IRQ9 - 9)) { - CheckMenuItem(menu, IDM_SCSI_IRQ9, MF_CHECKED); + fatal("SCSI controller: Invalid IRQ\n"); } - else if (scsi_irq == 10) + CheckMenuItem(menu, IDM_SCSI_IRQ9 - 9 + scsi_irq, MF_CHECKED); + + if (!find_in_array(valid_dma_channels, scsi_dma, 3, IDM_SCSI_DMA5 - 5)) { - CheckMenuItem(menu, IDM_SCSI_IRQ10, MF_CHECKED); - } - else if (scsi_irq == 11) - { - CheckMenuItem(menu, IDM_SCSI_IRQ11, MF_CHECKED); - } - else if (scsi_irq == 12) - { - CheckMenuItem(menu, IDM_SCSI_IRQ12, MF_CHECKED); - } - else if (scsi_irq == 14) - { - CheckMenuItem(menu, IDM_SCSI_IRQ14, MF_CHECKED); - } - else if (scsi_irq == 15) - { - CheckMenuItem(menu, IDM_SCSI_IRQ15, MF_CHECKED); - } - else - { - fatal("Unrecognized SCSI IRQ\n"); + fatal("SCSI controller: Invalid DMA channel\n"); } - CheckMenuItem(menu, IDM_SCSI_DMA5, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_DMA6, MF_UNCHECKED); - CheckMenuItem(menu, IDM_SCSI_DMA7, MF_UNCHECKED); - - if (scsi_dma == 5) - { - CheckMenuItem(menu, IDM_SCSI_DMA5, MF_CHECKED); - } - else if (scsi_dma == 6) - { - CheckMenuItem(menu, IDM_SCSI_DMA6, MF_CHECKED); - } - else if (scsi_dma == 7) - { - CheckMenuItem(menu, IDM_SCSI_DMA7, MF_CHECKED); - } - else - { - fatal("Unrecognized SCSI DMA address\n"); - } - - if (cdrom_drive == 200) - { - CheckMenuItem(menu, IDM_CDROM_ISO, MF_CHECKED); - } - else - { - CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); - } + CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED); CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); @@ -1138,18 +1044,18 @@ LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); } -void cdrom_close(void) +void cdrom_close(uint8_t id) { - switch (cdrom_drive) + switch (cdrom_drives[id].host_drive) { case 0: - null_close(); + null_close(id); break; default: - ioctl_close(); + ioctl_close(id); break; case 200: - iso_close(); + iso_close(id); break; } } @@ -1312,73 +1218,90 @@ void video_toggle_option(HMENU hmenu, int *val, int id) saveconfig(); } -void win_cdrom_eject() +void win_cdrom_eject(uint8_t id) { HMENU hmenu; hmenu=GetMenu(ghwnd); - if (cdrom_drive == 0) + if (cdrom_drives[id].host_drive == 0) { /* Switch from empty to empty. Do nothing. */ return; } - cdrom->exit(); - cdrom_close(); - cdrom_null_open(0); - if (cdrom_enabled) + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + cdrom_null_open(id, 0); + if (cdrom_drives[id].enabled) { /* Signal disc change to the emulated machine. */ - SCSICDROM_Insert(); + cdrom_insert(id); } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - old_cdrom_drive = cdrom_drive; - cdrom_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (id * 1000) + cdrom_drive, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (id * 1000), MF_UNCHECKED); + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].host_drive=0; + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (id * 1000), MF_CHECKED); saveconfig(); } -void win_cdrom_reload() +void win_cdrom_reload(uint8_t id) { HMENU hmenu; hmenu=GetMenu(ghwnd); int new_cdrom_drive; - if ((cdrom_drive == old_cdrom_drive) || (old_cdrom_drive == 0) || (cdrom_drive != 0)) + if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) { /* Switch from empty to empty. Do nothing. */ return; } - if (old_cdrom_drive == 200) + cdrom_close(id); + if (cdrom_drives[id].prev_host_drive == 200) { - iso_open(iso_path); - if (cdrom_enabled) + iso_open(id, cdrom_iso[id].iso_path); + if (cdrom_drives[id].enabled) { /* Signal disc change to the emulated machine. */ - SCSICDROM_Insert(); + cdrom_insert(id); } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - // CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - cdrom_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (id * 1000), MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (id * 1000), MF_CHECKED); saveconfig(); } else { - new_cdrom_drive = old_cdrom_drive; - ioctl_open(new_cdrom_drive); - if (cdrom_enabled) + new_cdrom_drive = cdrom_drives[id].prev_host_drive; + ioctl_open(id, new_cdrom_drive); + if (cdrom_drives[id].enabled) { /* Signal disc change to the emulated machine. */ - SCSICDROM_Insert(); + cdrom_insert(id); } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (id * 1000), MF_UNCHECKED); cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (id * 1000) + cdrom_drives[id].host_drive, MF_CHECKED); saveconfig(); } } +int convert_cdrom_id(int original_id) +{ + int i = 0; + + if (original_id >= (CDROM_NUM * 1000)) + { + return 0; + } + + for (i = 0; i < CDROM_NUM; i++) + { + if (original_id == (i * 1000)) + { + return i; + } + } + return 0; +} + LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HMENU hmenu; @@ -1386,6 +1309,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM uint32_t ri_size = 0; char temp_iso_path[1024]; int new_cdrom_drive; + int cdrom_id = 0; + int menu_sub_param = 0; // pclog("Message %i %08X\n",message,message); switch (message) { @@ -1598,61 +1523,88 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM pause = 0; break; -#if 0 - case IDM_CDROM_DISABLED: - if (cdrom_enabled) - { - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - break; - } - if (!cdrom_enabled) - { - /* Switching from disabled to disabled. Do nothing. */ - break; - } - cdrom->exit(); - cdrom_close(); - cdrom_null_open(0); - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_CHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - old_cdrom_drive = cdrom_drive; - cdrom_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_UNCHECKED); - if (cdrom_enabled) - { - pause = 1; - Sleep(100); - cdrom_enabled = 0; - saveconfig(); - resetpchard(); - pause = 0; - } - break; -#endif - case IDM_CDROM_ENABLED: + case IDM_CDROM_1_ENABLED: + case IDM_CDROM_2_ENABLED: + case IDM_CDROM_3_ENABLED: + case IDM_CDROM_4_ENABLED: + cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_ENABLED); if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) { break; } pause = 1; Sleep(100); - cdrom_enabled ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_ENABLED, cdrom_enabled ? MF_CHECKED : MF_UNCHECKED); + cdrom_drives[cdrom_id].enabled ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_1_ENABLED + (cdrom_id * 1000), cdrom_drives[cdrom_id].enabled ? MF_CHECKED : MF_UNCHECKED); saveconfig(); resetpchard(); pause = 0; break; - case IDM_CDROM_SCSI: + case IDM_CDROM_1_SOUND_ON: + case IDM_CDROM_2_SOUND_ON: + case IDM_CDROM_3_SOUND_ON: + case IDM_CDROM_4_SOUND_ON: + cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_SOUND_ON); + Sleep(100); + cdrom_drives[cdrom_id].sound_on ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_1_SOUND_ON + (cdrom_id * 1000), cdrom_drives[cdrom_id].enabled ? MF_CHECKED : MF_UNCHECKED); + saveconfig(); + break; + + case IDM_CDROM_1_SCSI: + case IDM_CDROM_2_SCSI: + case IDM_CDROM_3_SCSI: + case IDM_CDROM_4_SCSI: + cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_SCSI); if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) { break; } pause = 1; Sleep(100); - scsi_cdrom_enabled ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_SCSI, scsi_cdrom_enabled ? MF_CHECKED : MF_UNCHECKED); + cdrom_drives[cdrom_id].bus_type ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_1_SCSI + (cdrom_id * 1000), cdrom_drives[cdrom_id].bus_type ? MF_CHECKED : MF_UNCHECKED); + saveconfig(); + resetpchard(); + pause = 0; + break; + + case IDM_CDROM_1_C ... IDM_CDROM_1_H: + case IDM_CDROM_2_C ... IDM_CDROM_2_H: + case IDM_CDROM_3_C ... IDM_CDROM_3_H: + case IDM_CDROM_4_C ... IDM_CDROM_4_H: + menu_sub_param = LOWORD(wParam) % 100; + cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_C); + if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) + { + break; + } + pause = 1; + Sleep(100); + CheckMenuItem(hmenu, IDM_CDROM_1_C + (cdrom_id * 1000) + cdrom_drives[cdrom_id].ide_channel, MF_UNCHECKED); + cdrom_drives[cdrom_id].ide_channel = menu_sub_param; + CheckMenuItem(hmenu, IDM_CDROM_1_C + (cdrom_id * 1000) + cdrom_drives[cdrom_id].ide_channel, MF_CHECKED); + saveconfig(); + resetpchard(); + pause = 0; + break; + + case IDM_CDROM_1_0 ... IDM_CDROM_1_15: + case IDM_CDROM_2_0 ... IDM_CDROM_2_15: + case IDM_CDROM_3_0 ... IDM_CDROM_3_15: + case IDM_CDROM_4_0 ... IDM_CDROM_4_15: + menu_sub_param = LOWORD(wParam) % 100; + cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_0); + if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) + { + break; + } + pause = 1; + Sleep(100); + CheckMenuItem(hmenu, IDM_CDROM_1_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_id, MF_UNCHECKED); + cdrom_drives[cdrom_id].scsi_device_id = menu_sub_param; + CheckMenuItem(hmenu, IDM_CDROM_1_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_id, MF_CHECKED); saveconfig(); resetpchard(); pause = 0; @@ -1816,7 +1768,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM scsi_set_dma(hmenu, 7, IDM_SCSI_DMA7); break; - case IDM_CDROM_EMPTY: + case IDM_CDROM_1_EMPTY: + case IDM_CDROM_2_EMPTY: + case IDM_CDROM_3_EMPTY: + case IDM_CDROM_4_EMPTY: + cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_EMPTY); + win_cdrom_eject(cdrom_id); +#if 0 if (cdrom_drive == 0) { /* Switch from empty to empty. Do nothing. */ @@ -1836,93 +1794,79 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM cdrom_drive=0; CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED); saveconfig(); +#endif break; - case IDM_CDROM_RELOAD: - win_cdrom_reload(); + case IDM_CDROM_1_RELOAD: + case IDM_CDROM_2_RELOAD: + case IDM_CDROM_3_RELOAD: + case IDM_CDROM_4_RELOAD: + cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_RELOAD); + win_cdrom_reload(cdrom_id); break; - case IDM_CDROM_ISO: - if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",iso_path)) + case IDM_CDROM_1_ISO: + case IDM_CDROM_2_ISO: + case IDM_CDROM_3_ISO: + case IDM_CDROM_4_ISO: + cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_ISO); + if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",cdrom_iso[cdrom_id].iso_path)) { - /* if (!cdrom_enabled) - { - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - break; - } */ - old_cdrom_drive = cdrom_drive; + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; strcpy(temp_iso_path, openfilestring); - // if ((strcmp(iso_path, temp_iso_path) == 0) && (cdrom_drive == 200) && cdrom_enabled) - if ((strcmp(iso_path, temp_iso_path) == 0) && (cdrom_drive == 200)) + if ((strcmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) { /* Switching from ISO to the same ISO. Do nothing. */ break; } - cdrom->exit(); - cdrom_close(); - iso_open(temp_iso_path); - if (cdrom_enabled) + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + iso_open(cdrom_id, temp_iso_path); + if (cdrom_drives[cdrom_id].enabled) { /* Signal disc change to the emulated machine. */ - SCSICDROM_Insert(); + cdrom_insert(cdrom_id); } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - // CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - cdrom_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (cdrom_id * 1000), MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (cdrom_id * 1000) + cdrom_drives[cdrom_id].host_drive, MF_UNCHECKED); + } + cdrom_drives[cdrom_id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (cdrom_id * 1000), MF_CHECKED); saveconfig(); - /* if (!cdrom_enabled) - { - pause = 1; - Sleep(100); - cdrom_enabled = 1; - saveconfig(); - resetpchard(); - pause = 0; - } */ } break; default: - if (LOWORD(wParam)>IDM_CDROM_REAL && LOWORD(wParam)<(IDM_CDROM_REAL+100)) + menu_sub_param = LOWORD(wParam) % 100; + cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_REAL); + if ((LOWORD(wParam) > IDM_CDROM_1_REAL + (cdrom_id * 1000)) && (LOWORD(wParam) < (IDM_CDROM_1_REAL + (cdrom_id * 1000) + 100))) { - /* if (!cdrom_enabled) - { - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - break; - } */ - new_cdrom_drive = LOWORD(wParam)-IDM_CDROM_REAL; - // if ((cdrom_drive == new_cdrom_drive) && cdrom_enabled) - if (cdrom_drive == new_cdrom_drive) + new_cdrom_drive = menu_sub_param; + if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) { /* Switching to the same drive. Do nothing. */ break; } - old_cdrom_drive = cdrom_drive; - cdrom->exit(); - cdrom_close(); - ioctl_open(new_cdrom_drive); - if (cdrom_enabled) + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + ioctl_open(cdrom_id, new_cdrom_drive); + if (cdrom_drives[cdrom_id].enabled) { /* Signal disc change to the emulated machine. */ - SCSICDROM_Insert(); + cdrom_insert(cdrom_id); } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - // CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (cdrom_id * 1000), MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (cdrom_id * 1000) + cdrom_drives[cdrom_id].host_drive, MF_UNCHECKED); + } + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (cdrom_id * 1000), MF_UNCHECKED); + cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (cdrom_id * 1000) + cdrom_drives[cdrom_id].host_drive, MF_CHECKED); saveconfig(); - /* if (!cdrom_enabled) - { - pause = 1; - Sleep(100); - cdrom_enabled = 1; - saveconfig(); - resetpchard(); - pause = 0; - } */ } break; } diff --git a/src/x86_ops_i686.h b/src/x86_ops_i686.h index 9afb0e5f0..74f8a7810 100644 --- a/src/x86_ops_i686.h +++ b/src/x86_ops_i686.h @@ -301,6 +301,13 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; + cpu_state.npxc = 0x37F; + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + cpu_state.npxs = 0; + *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); if(cpu_state.abrt) pclog("FXSAVE: abrt != 0\n"); @@ -477,6 +484,13 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.eaaddr = old_eaaddr; + cpu_state.npxc = 0x37F; + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + cpu_state.npxs = 0; + *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); if(cpu_state.abrt) pclog("FXSAVE: abrt != 0\n"); diff --git a/src/x87_ops.h b/src/x87_ops.h index 637c09968..704d0afca 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -41,7 +41,7 @@ static inline void x87_set_mmx() static inline void x87_emms() { - *cpu_state.tag = 0x0303030303030303ll; + *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; cpu_state.ismmx = 0; } diff --git a/src/x87_ops_misc.h b/src/x87_ops_misc.h index ea31c74e0..178261fd5 100644 --- a/src/x87_ops_misc.h +++ b/src/x87_ops_misc.h @@ -36,6 +36,7 @@ static int opFINIT(uint32_t fetchdat) cpu_state.npxs = 0; *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; cpu_state.TOP = 0; + cpu_state.ismmx = 0; CLOCK_CYCLES(17); return 0; } @@ -282,6 +283,14 @@ static int FSAVE() } break; } + + cpu_state.npxc = 0x37F; + cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); + cpu_state.npxs = 0; + *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + cpu_state.TOP = 0; + cpu_state.ismmx = 0; + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); return cpu_state.abrt; } From 7608f1604f994fa45de8e54c46901e3cbde20e14 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 16 Jan 2017 06:21:34 +0100 Subject: [PATCH 006/392] Attempt to fix BusLogic scatter gather by increasing source buffer position after every read. --- src/buslogic.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/buslogic.c b/src/buslogic.c index 5d263c8ae..6cd9b318b 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -792,6 +792,8 @@ uint32_t BuslogicGetDataLength(BuslogicRequests_t *BuslogicRequests) void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) { + uint32_t sg_buffer_pos = 0; + if (BuslogicRequests->Is24bit) { DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer); @@ -839,7 +841,8 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, DataToTransfer); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; } ScatterGatherAddrCurrent += ScatterGatherRead * (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); From 74ca5233fbc55b94b1feaa28e56a5118a328e466 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 16 Jan 2017 17:35:45 +0100 Subject: [PATCH 007/392] Sound Blaster 16 and AWE32 now respect the base address for all the applicable I/O handlers. --- src/sound_sb.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sound_sb.c b/src/sound_sb.c index 23597e67e..ca7b0b6c4 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -493,10 +493,10 @@ void *sb_16_init() sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); sb_mixer_init(&sb->mixer); - io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); + io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); @@ -536,10 +536,10 @@ void *sb_awe32_init() sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); sb_dsp_setdma16(&sb->dsp, device_get_config_int("dma16")); sb_mixer_init(&sb->mixer); - io_sethandler(0x0220, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0228, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr + 8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); - io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); + io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); emu8k_init(&sb->emu8k, onboard_ram); From 8a16c015b9d9d610da2db96890098278f08de064 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 16 Jan 2017 19:37:10 +0100 Subject: [PATCH 008/392] Added "sleep 10" before and after strip in the makefile, in order to wait for the retarded Windows file locking mechanism to unlock the executable. --- src/Makefile.mingw | 2 ++ src/Makefile.mingw64 | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 20e97c053..639c9012d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -32,7 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) + sleep 10 strip "86Box.exe" + sleep 10 all : 86Box.exe diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index e1d682087..c7814d533 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -32,7 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lws 86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) + sleep 10 strip "86Box64.exe" + sleep 10 all : 86Box64.exe From a15a8ac57d8af18ad002a58d318657d5b91c6c61 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 16 Jan 2017 21:06:38 +0100 Subject: [PATCH 009/392] BusLogic scatter/gather now processes 1 more block if the data length is not divisible by the length of a scatter/gather block. --- src/buslogic.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 6cd9b318b..87634a0ec 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -821,9 +821,16 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) uint32_t ScatterGatherRead; uint32_t ScatterEntry; SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherLeft = DataLength / (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t ScatterGatherReqSize = (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t ScatterGatherLeft = DataLength / ScatterGatherReqSize; + uint32_t ScatterGatherLength = (ScatterGatherLeft * ScatterGatherReqSize); uint32_t ScatterGatherAddrCurrent = DataPointer; - + + if (DataLength > ScatterGatherLength) + { + ScatterGatherLeft++; + } + do { ScatterGatherRead = (ScatterGatherLeft < ELEMENTS(ScatterGatherBuffer)) From 7e54cc443688212a85f6b0ef0c00c5c1ecb3f9cd Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 00:01:59 +0100 Subject: [PATCH 010/392] Two instances of the IDE code setting the error register did not set it in the cdrom struct if drive is CD-ROM, now they do, fixes CD-ROM booting on the Intel Advanced/ATX and possibly other things; Fixed IDE and ATAPI 8-bit data reads and writes by rewriting the IDE and CD-ROM PIO data read and write code so that the base code is now 8-bit; Added some compiler directives that if set, will enable togglable logging and log breakpoints; Empty IDE channels now always report a status of 0x10 rather than 0x20, and do it on port 3F6h/376h/36Eh/3EEh too, fixes OAKCDROM.SYS infinite loop when hitting an empty IDE channel. --- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/buslogic.c | 2 +- src/cdrom.c | 87 ++++++++++++---------- src/cdrom.h | 4 +- src/disc_86f.c | 3 +- src/fdc.c | 2 +- src/ibm.h | 9 +++ src/ide.c | 169 +++++++++++++++++++++++++------------------ src/ne2000.c | 1 + src/pc.rc | 24 ++++++ src/resources.h | 11 +++ src/win.c | 47 ++++++++++++ 13 files changed, 247 insertions(+), 116 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 639c9012d..f7032d7d0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -50,4 +50,4 @@ clean : $(CPP) $(CFLAGS) -c $< pc.res: pc.rc - $(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff + $(WINDRES) $(RFLAGS) -i pc.rc --input-format=rc -o pc.res -O coff diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index c7814d533..9a3243143 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -50,4 +50,4 @@ clean : $(CPP) $(CFLAGS) -c $< pc.res: pc.rc - $(WINDRES) -i pc.rc --input-format=rc -o pc.res -O coff + $(WINDRES) $(RFLAGS) -i pc.rc --input-format=rc -o pc.res -O coff diff --git a/src/buslogic.c b/src/buslogic.c index 87634a0ec..f0948bc4c 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -518,7 +518,7 @@ int scsi_base = 0x330; int scsi_dma = 6; int scsi_irq = 11; -int buslogic_do_log = 1; +int buslogic_do_log = 0; static void BuslogicStartMailbox(Buslogic_t *Buslogic); diff --git a/src/cdrom.c b/src/cdrom.c index da0f2b65a..55b652e9e 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1,8 +1,10 @@ /* CD-ROM emulation, used by both ATAPI and SCSI */ +#include #include #include #include +#include #include "86box.h" #include "cdrom.h" @@ -188,7 +190,7 @@ uint8_t cdrom_mode_sense_pages_saved[CDROM_NUM][0x40][0x40] = [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; -int cdrom_do_log = 1; +int cdrom_do_log = 0; void cdrom_log(const char *format, ...) { @@ -732,11 +734,6 @@ void cdrom_update_request_length(uint8_t id, int len, int block_len) { len = cdrom[id].block_total; } - if (cdrom[id].packet_len == 0) - { - cdrom[id].packet_len = cdrom[id].sector_len * block_len; - } - cdrom_log("Packet length now: %i (%i * %i)\n", cdrom[id].packet_len, cdrom[id].sector_len, block_len); break; default: cdrom[id].packet_len = len; @@ -1065,6 +1062,7 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) int cdsize = 0; int i = 0; + int temp_len = 0; if (cdrom_drives[id].handler->pass_through) { @@ -1097,13 +1095,16 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) } cdrom[id].old_len = 0; + *len = 0; for (i = 0; i < cdrom[id].requested_blocks; i++) { - ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos, msf, type, flags, len); + ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos, msf, type, flags, &temp_len); - cdrom[id].data_pos += *len; - cdrom[id].old_len += *len; + cdrom[id].data_pos += temp_len; + cdrom[id].old_len += temp_len; + + *len += temp_len; if (!ret) { @@ -1514,6 +1515,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { cdrom[id].status &= ~ERR_STAT; } + else + { + cdrom[id].error = 0; + } cdrom[id].packet_len = 0; cdrom[id].request_pos = 0; @@ -1755,7 +1760,14 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } cdrom[id].packet_len = max_len * alloc_length; - cdrom_data_command_finish(id, alloc_length * cdrom[id].requested_blocks, alloc_length, alloc_length * cdrom[id].requested_blocks, 0); + if (cdrom[id].requested_blocks > 1) + { + cdrom_data_command_finish(id, alloc_length, alloc_length / cdrom[id].requested_blocks, alloc_length, 0); + } + else + { + cdrom_data_command_finish(id, alloc_length, alloc_length, alloc_length, 0); + } cdrom[id].all_blocks_total = cdrom[id].block_total; if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) { @@ -2650,13 +2662,13 @@ int cdrom_write_to_ide_dma(uint8_t channel) uint8_t id = atapi_cdrom_drives[channel]; - cdbufferb = (uint8_t *) cdrom[id].buffer; - if (id > CDROM_NUM) { return 0; } + cdbufferb = (uint8_t *) cdrom[id].buffer; + if (ide_bus_master_read) { if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].request_length)) @@ -2678,13 +2690,13 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id) uint8_t id = scsi_cdrom_drives[scsi_id]; - cdbufferb = (uint8_t *) cdrom[id].buffer; - if (id > CDROM_NUM) { return 0; } + cdbufferb = (uint8_t *) cdrom[id].buffer; + cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength); memcpy(SCSIDevices[scsi_id].CmdBuffer, cdbufferb, SCSIDevices[scsi_id].InitLength); cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]); @@ -2767,11 +2779,15 @@ int cdrom_phase_callback(uint8_t id) } } -uint32_t cdrom_read(uint8_t channel) +/* Reimplement as 8-bit due to reimplementation of IDE data read and write. */ +uint8_t cdrom_read(uint8_t channel) { + uint8_t *cdbufferb; + uint8_t id = atapi_cdrom_drives[channel]; - uint16_t temp = 0; + // uint16_t temp = 0; + uint8_t temp = 0; int ret = 0; if (id > CDROM_NUM) @@ -2779,14 +2795,16 @@ uint32_t cdrom_read(uint8_t channel) return 0; } - temp = cdrom[id].buffer[cdrom[id].pos >> 1]; + cdbufferb = (uint8_t *) cdrom[id].buffer; - cdrom[id].pos += 2; - cdrom[id].request_pos += 2; + temp = cdbufferb[cdrom[id].pos]; + + cdrom[id].pos++; + cdrom[id].request_pos++; if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) { - cdrom[id].total_read += 2; + cdrom[id].total_read++; ret = cdrom_block_check(id); /* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */ if (ret) @@ -2817,9 +2835,11 @@ uint32_t cdrom_read(uint8_t channel) } } -/* If the result is 1, issue an IRQ, otherwise not. */ -int cdrom_write(uint8_t channel, uint16_t val) +/* Reimplement as 8-bit due to reimplementation of IDE data read and write. */ +void cdrom_write(uint8_t channel, uint8_t val) { + uint8_t *cdbufferb; + uint8_t id = atapi_cdrom_drives[channel]; int ret = 0; @@ -2829,27 +2849,16 @@ int cdrom_write(uint8_t channel, uint16_t val) return 0; } - cdrom[id].buffer[cdrom[id].pos >> 1] = val; - cdrom[id].pos += 2; + cdbufferb = (uint8_t *) cdrom[id].buffer; + + cdbufferb[cdrom[id].pos] = val; + cdrom[id].pos++; if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT) { - ret = cdrom_mode_select_write(id, val & 0xff); - if (ret == 1) - { - ret = 2; - } + ret = cdrom_mode_select_write(id, val); cdrom_mode_select_return(id, ret); - /* Make sure to not do another write, if it has terminated. */ - if (ret != -6) - { - cdrom_mode_select_write(id, val >> 8); - if (cdrom_mode_select_return(id, ret) == 1) - { - return 0; - } - } - return 0; + return; } else if (cdrom[id].packet_status == CDROM_PHASE_IDLE) { diff --git a/src/cdrom.h b/src/cdrom.h index f03fb7854..571b955d8 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -189,8 +189,8 @@ int cdrom_CDROM_PHASE_to_scsi(uint8_t id); int cdrom_atapi_phase_to_scsi(uint8_t id); void cdrom_command(uint8_t id, uint8_t *cdb); int cdrom_phase_callback(uint8_t id); -uint32_t cdrom_read(uint8_t channel); -int cdrom_write(uint8_t channel, uint16_t val); +uint8_t cdrom_read(uint8_t channel); +int cdrom_write(uint8_t channel, uint8_t val); int cdrom_lba_to_msf_accurate(int lba); void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); diff --git a/src/disc_86f.c b/src/disc_86f.c index 17ae7dfcd..af9d5d58c 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -203,7 +204,7 @@ static struct __attribute__((packed)) uint32_t dma_over; } d86f[FDD_NUM]; -int d86f_do_log = 1; +int d86f_do_log = 0; void d86f_log(const char *format, ...) { diff --git a/src/fdc.c b/src/fdc.c index cf4bd3413..e310d5e17 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -116,7 +116,7 @@ int discrate[4]; int discint; -int fdc_do_log = 1; +int fdc_do_log = 0; void fdc_log(const char *format, ...) { diff --git a/src/ibm.h b/src/ibm.h index d9dffeec3..061602145 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -596,3 +596,12 @@ int mem_a20_state; void fatal(const char *format, ...); extern int scsi_model, scsi_base, scsi_irq, scsi_dma; + +#ifdef ENABLE_LOG_TOGGLES +extern int buslogic_do_log; +extern int cdrom_do_log; +extern int d86f_do_log; +extern int fdc_do_log; +extern int ide_do_log; +extern int ne2000_do_log; +#endif diff --git a/src/ide.c b/src/ide.c index 7e641a3e4..68c01684b 100644 --- a/src/ide.c +++ b/src/ide.c @@ -6,8 +6,10 @@ #define _GNU_SOURCE #include #include -#include +#include #include +#include +#include #include #include @@ -134,11 +136,11 @@ int idecallback[4] = {0, 0, 0, 0}; int cur_ide[4]; -int ide_do_log = 1; +int ide_do_log = 0; void ide_log(const char *format, ...) { -#ifdef ENABLE_CDROM_LOG +#ifdef ENABLE_IDE_LOG if (ide_do_log) { va_list ap; @@ -724,10 +726,12 @@ void resetide(void) int idetimes = 0; -void writeidew(int ide_board, uint16_t val) +void ide_write_data(int ide_board, uint8_t val) { int ret = 0; IDE *ide = &ide_drives[cur_ide[ide_board]]; + + uint8_t *idebufferb = (uint8_t *) ide->buffer; #if 0 if (ide_drive_is_cdrom(ide)) @@ -737,8 +741,8 @@ void writeidew(int ide_board, uint16_t val) #endif // ide_log("Write IDEw %04X\n",val); - ide->buffer[ide->pos >> 1] = val; - ide->pos += 2; + idebufferb[ide->pos] = val; + ide->pos++; if (ide->command == WIN_PACKETCMD) { @@ -778,6 +782,13 @@ void writeidew(int ide_board, uint16_t val) } } +void writeidew(int ide_board, uint16_t val) +{ + // ide_log("WriteIDEw %04X\n", val); + ide_write_data(ide_board, val); + ide_write_data(ide_board, val >> 8); +} + void writeidel(int ide_board, uint32_t val) { // ide_log("WriteIDEl %08X\n", val); @@ -799,7 +810,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) switch (addr) { case 0x1F0: /* Data */ - writeidew(ide_board, val | (val << 8)); + ide_write_data(ide_board, val); return; /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ @@ -954,11 +965,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case 0x1F7: /* Command register */ if (ide->type == IDE_NONE) { - if (val == WIN_SRST) - { - callbackide(ide_board); - } ide->error=1; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].error = 1; + } return; } #if 0 @@ -972,6 +983,10 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) // ide_log("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); ide->error=0; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].error = 0; + } switch (val) { case WIN_SRST: /* ATAPI Device Reset */ @@ -1241,6 +1256,66 @@ ide_bad_command: // fatal("Bad IDE write %04X %02X\n", addr, val); } +uint8_t ide_read_data(int ide_board) +{ + IDE *ide = &ide_drives[cur_ide[ide_board]]; + uint8_t temp; + + uint8_t *idebufferb = (uint8_t *) ide->buffer; + + temp = idebufferb[ide->pos]; + + ide->pos++; + + if (ide->command == WIN_PACKETCMD) + { + if (!ide_drive_is_cdrom(ide)) + { + ide_log("Drive not CD-ROM (position: %i)\n", ide->pos); + return 0; + } + temp = cdrom_read(cur_ide[ide_board]); + if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) + { + idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; + } + } + if (ide->pos>=512 && ide->command != WIN_PACKETCMD) + { + ide->pos=0; + ide->atastat = READY_STAT | DSC_STAT; + if (ide_drive_is_cdrom(ide)) + { + // cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].pos = 0; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE; + } + ide->packetstatus = ATAPI_STATUS_IDLE; + if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) + { + ide->secount = (ide->secount - 1) & 0xff; + if (ide->secount) + { + ide_next_sector(ide); + ide->atastat = BUSY_STAT; + timer_process(); + if (ide->command == WIN_READ_MULTIPLE) + { + callbackide(ide_board); + } + else + { + idecallback[ide_board]=6*IDE_TIME; + } + timer_update_outstanding(); + } + } + } + + // ide_log("Read IDEw %04X\n",temp); + return temp; +} + uint8_t readide(int ide_board, uint16_t addr) { IDE *ide = &ide_drives[cur_ide[ide_board]]; @@ -1252,21 +1327,23 @@ uint8_t readide(int ide_board, uint16_t addr) addr|=0x90; addr&=0xFFF7; - if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7)) + if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7 || addr == 0x3f6)) { - if (addr == 0x1f7) + if ((addr == 0x1f7) || (addr == 0x3f6)) { /* This is apparently required for an empty ID channel. */ - return 0x20; + ide_log("Reading port %04X on empty IDE channel, returning 0x20...\n", addr); + // return 0x20; + return DSC_STAT; } + ide_log("Reading port %04X on empty IDE channel, returning zero...\n", addr); return 0; } switch (addr) { case 0x1F0: /* Data */ - tempw = readidew(ide_board); - temp = tempw & 0xff; + return ide_read_data(ide_board); break; /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), @@ -1427,60 +1504,12 @@ int all_blocks_total = 0; uint16_t readidew(int ide_board) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; - uint16_t temp; - - temp = ide->buffer[ide->pos >> 1]; - - ide->pos += 2; - - if (ide->command == WIN_PACKETCMD) - { - if (!ide_drive_is_cdrom(ide)) - { - ide_log("Drive not CD-ROM (position: %i)\n", ide->pos); - return 0; - } - temp = cdrom_read(cur_ide[ide_board]); - if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) - { - idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; - } - } - if (ide->pos>=512 && ide->command != WIN_PACKETCMD) - { - ide->pos=0; - ide->atastat = READY_STAT | DSC_STAT; - if (ide_drive_is_cdrom(ide)) - { - // cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].pos = 0; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE; - } - ide->packetstatus = ATAPI_STATUS_IDLE; - if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) - { - ide->secount = (ide->secount - 1) & 0xff; - if (ide->secount) - { - ide_next_sector(ide); - ide->atastat = BUSY_STAT; - timer_process(); - if (ide->command == WIN_READ_MULTIPLE) - { - callbackide(ide_board); - } - else - { - idecallback[ide_board]=6*IDE_TIME; - } - timer_update_outstanding(); - } - } - } - - // ide_log("Read IDEw %04X\n",temp); - return temp; + uint16_t temp = 0; + uint16_t temp2 = 0; + temp = ide_read_data(ide_board); + temp2 = ide_read_data(ide_board); + temp2 <<= 8; + return (temp | temp2); } uint32_t readidel(int ide_board) diff --git a/src/ne2000.c b/src/ne2000.c index ca393b274..3694a06e7 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -17,6 +17,7 @@ // Peter Grehan (grehan@iprg.nokia.com) coded all of this // NE2000/ether stuff. //#include "vl.h" +#include #include #include #include diff --git a/src/pc.rc b/src/pc.rc index 65d8c4acf..925da15fc 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -292,11 +292,35 @@ BEGIN MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END MENUITEM "&Status", IDM_STATUS +#ifdef ENABLE_LOG_TOGGLES + MENUITEM SEPARATOR + MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC + MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM + MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F + MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC + MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE + MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 +#endif +#ifdef ENABLE_LOG_BREAKPOINT + MENUITEM SEPARATOR + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +#endif END END MainAccel ACCELERATORS BEGIN +#ifdef ENABLE_LOG_TOGGLES + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY + VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_LOG_BREAKPOINT + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY +#endif VK_F11, IDM_VID_SCREENSHOT, CONTROL, VIRTKEY VK_F12, IDM_FILE_RESET_CAD, CONTROL, VIRTKEY END diff --git a/src/resources.h b/src/resources.h index dbcaa228f..931b5a8b0 100644 --- a/src/resources.h +++ b/src/resources.h @@ -187,6 +187,17 @@ #define IDM_SCSI_DMA5 45405 #define IDM_SCSI_DMA6 45406 #define IDM_SCSI_DMA7 45407 +#ifdef ENABLE_LOG_TOGGLES +#define IDM_LOG_BUSLOGIC 51200 +#define IDM_LOG_CDROM 51201 +#define IDM_LOG_D86F 51202 +#define IDM_LOG_FDC 51203 +#define IDM_LOG_IDE 51204 +#define IDM_LOG_NE2000 51205 +#endif +#ifdef ENABLE_LOG_BREAKPOINT +#define IDM_LOG_BREAKPOINT 51206 +#endif #define IDC_COMBO1 1000 #define IDC_COMBOVID 1001 diff --git a/src/win.c b/src/win.c index 0fbb3f8fb..ccfc70858 100644 --- a/src/win.c +++ b/src/win.c @@ -732,6 +732,15 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED); +#ifdef ENABLE_LOG_TOGGLES + CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif + CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_FLASH, enable_flash ? MF_CHECKED : MF_UNCHECKED); @@ -1500,6 +1509,44 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM take_screenshot(); break; +#ifdef ENABLE_LOG_TOGGLES + case IDM_LOG_BUSLOGIC: + buslogic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); + break; + + case IDM_LOG_CDROM: + cdrom_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); + break; + + case IDM_LOG_D86F: + d86f_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); + break; + + case IDM_LOG_FDC: + fdc_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); + break; + + case IDM_LOG_IDE: + ide_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); + break; + + case IDM_LOG_NE2000: + ne2000_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_LOG_BREAKPOINT + case IDM_LOG_BREAKPOINT: + pclog("---- LOG BREAKPOINT ----\n"); + break; +#endif + case IDM_CONFIG_LOAD: pause = 1; if (!getfile(hwnd, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "")) From 082c4e9ff8f86fa8a51b76911e4b6428f1f8b671 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 00:04:49 +0100 Subject: [PATCH 011/392] Fixed some compile-breaking errors. --- src/cdrom.c | 4 ++-- src/cdrom.h | 2 +- src/ide.c | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index 55b652e9e..bf5d7da7c 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2846,7 +2846,7 @@ void cdrom_write(uint8_t channel, uint8_t val) if (id > CDROM_NUM) { - return 0; + return; } cdbufferb = (uint8_t *) cdrom[id].buffer; @@ -2871,6 +2871,6 @@ void cdrom_write(uint8_t channel, uint8_t val) cdrom_phase_callback(id); timer_update_outstanding(); } - return 0; + return; } } diff --git a/src/cdrom.h b/src/cdrom.h index 571b955d8..032e2978d 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -190,7 +190,7 @@ int cdrom_atapi_phase_to_scsi(uint8_t id); void cdrom_command(uint8_t id, uint8_t *cdb); int cdrom_phase_callback(uint8_t id); uint8_t cdrom_read(uint8_t channel); -int cdrom_write(uint8_t channel, uint8_t val); +void cdrom_write(uint8_t channel, uint8_t val); int cdrom_lba_to_msf_accurate(int lba); void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); diff --git a/src/ide.c b/src/ide.c index 68c01684b..8484cec95 100644 --- a/src/ide.c +++ b/src/ide.c @@ -751,10 +751,7 @@ void ide_write_data(int ide_board, uint8_t val) return; } - if (cdrom_write(cur_ide[ide_board], val)) - { - ide_irq_raise(ide); - } + cdrom_write(cur_ide[ide_board], val); if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) { From 70cd63784b42c2b9a1788e82e1c04b9b96eee69b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 00:52:12 +0100 Subject: [PATCH 012/392] Changed data transfer length for media access command passthough and buffer size to 65536 in cdrom_ioctl.c, fixes transfers of larger files using the BusLogic. --- src/cdrom-ioctl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 12d8662ae..3f87f4798 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -514,7 +514,7 @@ struct sptd_with_sense SCSI_PASS_THROUGH s; ULONG Filler; UCHAR sense[32]; - UCHAR data[64512]; + UCHAR data[65536]; } sptd; static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) @@ -602,7 +602,7 @@ common_handler: default: bypass_check: /* Other commands */ - sptd.s.DataTransferLength = 64512; + sptd.s.DataTransferLength = 65536; break; } sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; @@ -748,7 +748,7 @@ static void ioctl_validate_toc(uint8_t id) cdrom_ioctl[id].tocvalid=1; } -UCHAR buf[64512]; +UCHAR buf[65536]; static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) { From 2c0b3112be9254eb4376488848303663c14e3aeb Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 01:02:08 +0100 Subject: [PATCH 013/392] Applied mainline PCem commit: Fixed Mach64 1 bpp source data alignment - fixes font rendering in Windows NT. --- src/vid_ati_mach64.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 27bf01adb..1ed70ee5e 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -111,6 +111,8 @@ typedef struct mach64_t uint32_t gui_traj_cntl; + uint32_t host_cntl; + uint32_t mem_cntl; uint32_t ovr_clr; @@ -243,6 +245,11 @@ enum DST_24_ROT_EN = 0x80 }; +enum +{ + HOST_BYTE_ALIGN = (1 << 0) +}; + void mach64_write(uint32_t addr, uint8_t val, void *priv); uint8_t mach64_read(uint32_t addr, void *priv); void mach64_updatemapping(mach64_t *mach64); @@ -661,6 +668,10 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val mach64_blit(val, 8, mach64); break; + case 0x240: case 0x241: case 0x242: case 0x243: + WRITE8(addr, mach64->host_cntl, val); + break; + case 0x280: case 0x281: case 0x282: case 0x283: WRITE8(addr, mach64->pat_reg0, val); break; @@ -725,6 +736,10 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val break; case 0x333: WRITE8(addr - 3, mach64->pat_cntl, val & 7); + if (val & 0x10) + mach64->host_cntl |= HOST_BYTE_ALIGN; + else + mach64->host_cntl &= ~HOST_BYTE_ALIGN; break; } } @@ -1336,8 +1351,17 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mach64->dst_y_x = (mach64->dst_y_x & 0xfff0000) | ((mach64->dst_y_x + (mach64->dst_height_width & 0x1fff)) & 0xfff); return; } - if (mach64->accel.source_host) - return; + if (mach64->host_cntl & HOST_BYTE_ALIGN) + { + if (mach64->accel.source_mix == MONO_SRC_HOST) + { + if (mach64->dp_pix_width & DP_BYTE_PIX_ORDER) + cpu_dat >>= (count & 7); + else + cpu_dat <<= (count & 7); + count &= ~7; + } + } } } break; @@ -1770,6 +1794,11 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->src_cntl); break; + case 0x240: case 0x241: case 0x242: case 0x243: + mach64_wait_fifo_idle(mach64); + READ8(addr, mach64->host_cntl); + break; + case 0x280: case 0x281: case 0x282: case 0x283: mach64_wait_fifo_idle(mach64); READ8(addr, mach64->pat_reg0); From 1802f8ea50b7235df41dd955c3d49c8661717fa8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 01:14:37 +0100 Subject: [PATCH 014/392] Status is now hardwired to 0x30 instead of 0x10 for empty IDE channels. --- src/ide.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ide.c b/src/ide.c index 8484cec95..4d24a1314 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1329,9 +1329,9 @@ uint8_t readide(int ide_board, uint16_t addr) if ((addr == 0x1f7) || (addr == 0x3f6)) { /* This is apparently required for an empty ID channel. */ - ide_log("Reading port %04X on empty IDE channel, returning 0x20...\n", addr); + ide_log("Reading port %04X on empty IDE channel, returning 0x30...\n", addr); // return 0x20; - return DSC_STAT; + return 0x20 | DSC_STAT; } ide_log("Reading port %04X on empty IDE channel, returning zero...\n", addr); return 0; From ec2fe42e1f5c07803b0c145686d7b8b9875ab7ed Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Mon, 16 Jan 2017 21:15:15 -0600 Subject: [PATCH 015/392] Reformatted nVidia code --- src/vid_nv_riva128.c | 4537 ++++++++++++++++++++++++------------------ 1 file changed, 2547 insertions(+), 1990 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index ce1bd680e..d3a94bf31 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -18,197 +18,197 @@ typedef struct riva128_t { - mem_mapping_t linear_mapping; - mem_mapping_t ramin_mapping; - mem_mapping_t mmio_mapping; + mem_mapping_t linear_mapping; + mem_mapping_t ramin_mapping; + mem_mapping_t mmio_mapping; - rom_t bios_rom; + rom_t bios_rom; - svga_t svga; + svga_t svga; - uint8_t card_id; - int is_nv3t; + uint8_t card_id; + int is_nv3t; - uint16_t vendor_id; - uint16_t device_id; + uint16_t vendor_id; + uint16_t device_id; - uint32_t linear_base, linear_size; + uint32_t linear_base, linear_size; - uint16_t rma_addr; + uint16_t rma_addr; - uint8_t pci_regs[256]; + uint8_t pci_regs[256]; - int memory_size; + int memory_size; - uint8_t ext_regs_locked; + uint8_t ext_regs_locked; - uint8_t read_bank; - uint8_t write_bank; + uint8_t read_bank; + uint8_t write_bank; - struct - { - uint32_t intr; - uint32_t intr_en; - uint32_t intr_line; - uint32_t enable; - } pmc; - - struct - { - uint32_t intr; - uint32_t intr_en; - } pbus; - - struct - { - uint32_t intr; - uint32_t intr_en; - - uint32_t ramht; - uint32_t ramht_addr; - uint32_t ramht_size; - - uint32_t ramfc; - uint32_t ramfc_addr; - - uint32_t ramro; - uint32_t ramro_addr; - uint32_t ramro_size; - - uint16_t chan_mode; - uint16_t chan_dma; - uint16_t chan_size; //0 = 1024, 1 = 512 - struct { - uint32_t dmaput; - uint32_t dmaget; - } channels[16]; - + uint32_t intr; + uint32_t intr_en; + uint32_t intr_line; + uint32_t enable; + } pmc; + struct { - int chanid; - int push_enabled; - } caches[2]; - + uint32_t intr; + uint32_t intr_en; + } pbus; + struct { - int subchan; - uint16_t method; - uint32_t param; - } cache0, cache1[64]; - } pfifo; - - struct - { - uint32_t addr; - uint32_t data; - uint8_t access_reg[4]; - uint8_t mode; - } rma; - - struct - { - uint32_t intr, intr_en; + uint32_t intr; + uint32_t intr_en; - uint64_t time; - uint32_t alarm; + uint32_t ramht; + uint32_t ramht_addr; + uint32_t ramht_size; - uint16_t clock_mul, clock_div; - } ptimer; - - struct - { - int width; - int bpp; - uint32_t config_0; - } pfb; - - struct - { - uint32_t boot0; - } pextdev; + uint32_t ramfc; + uint32_t ramfc_addr; - struct - { - int pgraph_speedhack; + uint32_t ramro; + uint32_t ramro_addr; + uint32_t ramro_size; - uint32_t obj_handle[8]; - uint16_t obj_class[8]; + uint16_t chan_mode; + uint16_t chan_dma; + uint16_t chan_size; //0 = 1024, 1 = 512 - uint32_t debug[5]; - - uint32_t intr; - uint32_t intr_en; + struct + { + uint32_t dmaput; + uint32_t dmaget; + } channels[16]; - uint32_t invalid; - uint32_t invalid_en; + struct + { + int chanid; + int push_enabled; + } caches[2]; - uint32_t ctx_switch[5]; - uint32_t ctx_control; - uint32_t ctx_user; - uint32_t ctx_cache[8][5]; + struct + { + int subchan; + uint16_t method; + uint32_t param; + } cache0, cache1[64]; + } pfifo; - uint32_t fifo_enable; + struct + { + uint32_t addr; + uint32_t data; + uint8_t access_reg[4]; + uint8_t mode; + } rma; - uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; - uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; + struct + { + uint32_t intr, intr_en; - uint32_t src_canvas_min, src_canvas_max; - uint32_t dst_canvas_min, dst_canvas_max; + uint64_t time; + uint32_t alarm; - uint32_t beta; + uint16_t clock_mul, clock_div; + } ptimer; - uint32_t notify; + struct + { + int width; + int bpp; + uint32_t config_0; + } pfb; - uint32_t instance; + struct + { + uint32_t boot0; + } pextdev; - struct - { - uint32_t point_color; - int32_t point_x[0x20], point_y[0x20]; - } speedhack; - } pgraph; - - struct - { - uint32_t nvpll; - uint32_t nv_m,nv_n,nv_p; - - uint32_t mpll; - uint32_t m_m,m_n,m_p; - - uint32_t vpll; - uint32_t v_m,v_n,v_p; - - uint32_t pll_ctrl; - - uint32_t gen_ctrl; - } pramdac; - - uint32_t pramin[0x80000]; - - uint32_t channels[16][8][0x2000]; - - struct - { - int scl; - int sda; - uint8_t addr; //actually 7 bits - } i2c; - - int mtime, mfreq; - int nvtime, nvfreq; + struct + { + int pgraph_speedhack; + + uint32_t obj_handle[8]; + uint16_t obj_class[8]; + + uint32_t debug[5]; + + uint32_t intr; + uint32_t intr_en; + + uint32_t invalid; + uint32_t invalid_en; + + uint32_t ctx_switch[5]; + uint32_t ctx_control; + uint32_t ctx_user; + uint32_t ctx_cache[8][5]; + + uint32_t fifo_enable; + + uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; + uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; + + uint32_t src_canvas_min, src_canvas_max; + uint32_t dst_canvas_min, dst_canvas_max; + + uint32_t beta; + + uint32_t notify; + + uint32_t instance; + + struct + { + uint32_t point_color; + int32_t point_x[0x20], point_y[0x20]; + } speedhack; + } pgraph; + + struct + { + uint32_t nvpll; + uint32_t nv_m,nv_n,nv_p; + + uint32_t mpll; + uint32_t m_m,m_n,m_p; + + uint32_t vpll; + uint32_t v_m,v_n,v_p; + + uint32_t pll_ctrl; + + uint32_t gen_ctrl; + } pramdac; + + uint32_t pramin[0x80000]; + + uint32_t channels[16][8][0x2000]; + + struct + { + int scl; + int sda; + uint8_t addr; //actually 7 bits + } i2c; + + int mtime, mfreq; + int nvtime, nvfreq; } riva128_t; //Internally, the RIVA 128 operates in a weird 38-bit color depth, with 10 bits for RGB, and 8 bits for alpha, according to envytools. typedef struct { - uint8_t a; - unsigned r : 10; - unsigned g : 10; - unsigned b : 10; + uint8_t a; + unsigned r : 10; + unsigned g : 10; + unsigned b : 10; } riva128_color_t; const char* riva128_pmc_interrupts[32] = @@ -218,12 +218,12 @@ const char* riva128_pmc_interrupts[32] = const char* riva128_pbus_interrupts[32] = { - "BUS_ERROR","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" + "BUS_ERROR","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","" }; const char* riva128_pfifo_interrupts[32] = { - "CACHE_ERROR","","","","RUNOUT","","","","RUNOUT_OVERFLOW","","","","DMA_PUSHER","","","","DMA_PTE","","","","","","","","","","","","","","","" + "CACHE_ERROR","","","","RUNOUT","","","","RUNOUT_OVERFLOW","","","","DMA_PUSHER","","","","DMA_PTE","","","","","","","","","","","","","","","" }; static uint8_t riva128_pci_read(int func, int addr, void *p); @@ -236,1123 +236,1581 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p); static riva128_color_t riva128_pgraph_expand_color(uint32_t ctx, uint32_t color) { - riva128_color_t ret; - int format = ctx & 7; - int alpha_enable = (ctx >> 3) & 1; + riva128_color_t ret; + int format = ctx & 7; + int alpha_enable = (ctx >> 3) & 1; - switch(format) - { - default: - pclog("RIVA 128 Unknown color format %i found!\n", format); - ret.a = 0x0; - break; - case 0: - ret.a = ((color >> 15) & 1) * 0xff; - ret.r = ((color >> 10) & 0x1f) << 5; - ret.g = ((color >> 5) & 0x1f) << 5; - ret.b = ((color >> 0) & 0x1f) << 5; - break; - case 1: - ret.a = ((color >> 24) & 0xff); - ret.r = ((color >> 16) & 0xff) << 2; - ret.g = ((color >> 8) & 0xff) << 2; - ret.b = ((color >> 0) & 0xff) << 2; - break; - case 2: - ret.a = ((color >> 30) & 3) * 0x55; - ret.r = ((color >> 20) & 0x3ff); - ret.g = ((color >> 10) & 0x3ff); - ret.b = ((color >> 0) & 0x3ff); - break; - case 3: - ret.a = ((color >> 8) & 0xff); - ret.r = ret.g = ret.b = ((color >> 0) & 0xff) << 2; - break; - case 4: - ret.a = ((color >> 16) & 0xffff) >> 8; - ret.r = ret.g = ret.b = ((color >> 0) & 0xffff) >> 6; - break; - } + switch(format) + { + default: + pclog("RIVA 128 Unknown color format %i found!\n", format); + ret.a = 0x0; + break; + case 0: + ret.a = ((color >> 15) & 1) * 0xff; + ret.r = ((color >> 10) & 0x1f) << 5; + ret.g = ((color >> 5) & 0x1f) << 5; + ret.b = ((color >> 0) & 0x1f) << 5; + break; + case 1: + ret.a = ((color >> 24) & 0xff); + ret.r = ((color >> 16) & 0xff) << 2; + ret.g = ((color >> 8) & 0xff) << 2; + ret.b = ((color >> 0) & 0xff) << 2; + break; + case 2: + ret.a = ((color >> 30) & 3) * 0x55; + ret.r = ((color >> 20) & 0x3ff); + ret.g = ((color >> 10) & 0x3ff); + ret.b = ((color >> 0) & 0x3ff); + break; + case 3: + ret.a = ((color >> 8) & 0xff); + ret.r = ret.g = ret.b = ((color >> 0) & 0xff) << 2; + break; + case 4: + ret.a = ((color >> 16) & 0xffff) >> 8; + ret.r = ret.g = ret.b = ((color >> 0) & 0xffff) >> 6; + break; + } - if(!alpha_enable) ret.a = 0xff; + if(!alpha_enable) ret.a = 0xff; - return ret; + return ret; } static uint32_t riva128_pgraph_blend_factor(uint32_t alpha, uint32_t beta) { - if(beta == 0xff) return alpha; - if(alpha == 0xff) return beta; - alpha >>= 4; - beta >>= 3; - return (alpha * beta) >> 1; + if(beta == 0xff) return alpha; + if(alpha == 0xff) return beta; + alpha >>= 4; + beta >>= 3; + return (alpha * beta) >> 1; } static uint32_t riva128_pgraph_do_blend(uint32_t factor, uint32_t dst, uint32_t src, int is_r5g5b5) { - factor &= 0xf8; - if(factor == 0xf8) return src; - if(!factor) return dst; - src >>= 2; dst >>= 2; - if(is_r5g5b5) - { - src &= 0xf8; dst &= 0xf8; - } - return ((dst * (0x100 - factor)) + (src * factor)) >> 6; + factor &= 0xf8; + if(factor == 0xf8) return src; + if(!factor) return dst; + src >>= 2; + dst >>= 2; + if(is_r5g5b5) + { + src &= 0xf8; + dst &= 0xf8; + } + return ((dst * (0x100 - factor)) + (src * factor)) >> 6; } static uint8_t riva128_pmc_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - //pclog("RIVA 128 PMC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 PMC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - if(riva128->card_id == 0x03) switch(addr) - { - case 0x000000: ret = 0x11; break; - case 0x000001: ret = 0x01; break; - case 0x000002: ret = 0x03; break; - case 0x000003: ret = 0x00; break; - } - else if(riva128->card_id == 0x04) switch(addr) - { - case 0x000000: ret = 0x00; break; - case 0x000001: ret = 0x40; break; - case 0x000002: ret = 0x00; break; - case 0x000003: ret = 0x00; break; - } - else if(riva128->card_id == 0x05) switch(addr) - { - case 0x000000: ret = 0x00; break; - case 0x000001: ret = 0x40; break; - case 0x000002: ret = 0x10; break; - case 0x000003: ret = 0x00; break; - } - switch(addr) - { - case 0x000100: ret = riva128->pmc.intr & 0xff; break; - case 0x000101: ret = (riva128->pmc.intr >> 8) & 0xff; break; - case 0x000102: ret = (riva128->pmc.intr >> 16) & 0xff; break; - case 0x000103: ret = (riva128->pmc.intr >> 24) & 0xff; break; - case 0x000140: ret = riva128->pmc.intr & 0xff; break; - case 0x000141: ret = (riva128->pmc.intr_en >> 8) & 0xff; break; - case 0x000142: ret = (riva128->pmc.intr_en >> 16) & 0xff; break; - case 0x000143: ret = (riva128->pmc.intr_en >> 24) & 0xff; break; - case 0x000160: ret = riva128->pmc.intr_line & 0xff; break; - case 0x000161: ret = (riva128->pmc.intr_line >> 8) & 0xff; break; - case 0x000162: ret = (riva128->pmc.intr_line >> 16) & 0xff; break; - case 0x000163: ret = (riva128->pmc.intr_line >> 24) & 0xff; break; - case 0x000200: ret = riva128->pmc.enable & 0xff; break; - case 0x000201: ret = (riva128->pmc.enable >> 8) & 0xff; break; - case 0x000202: ret = (riva128->pmc.enable >> 16) & 0xff; break; - case 0x000203: ret = (riva128->pmc.enable >> 24) & 0xff; break; - } + if(riva128->card_id == 0x03) switch(addr) + { + case 0x000000: + ret = 0x11; + break; + case 0x000001: + ret = 0x01; + break; + case 0x000002: + ret = 0x03; + break; + case 0x000003: + ret = 0x00; + break; + } + else if(riva128->card_id == 0x04) switch(addr) + { + case 0x000000: + ret = 0x00; + break; + case 0x000001: + ret = 0x40; + break; + case 0x000002: + ret = 0x00; + break; + case 0x000003: + ret = 0x00; + break; + } + else if(riva128->card_id == 0x05) switch(addr) + { + case 0x000000: + ret = 0x00; + break; + case 0x000001: + ret = 0x40; + break; + case 0x000002: + ret = 0x10; + break; + case 0x000003: + ret = 0x00; + break; + } + switch(addr) + { + case 0x000100: + ret = riva128->pmc.intr & 0xff; + break; + case 0x000101: + ret = (riva128->pmc.intr >> 8) & 0xff; + break; + case 0x000102: + ret = (riva128->pmc.intr >> 16) & 0xff; + break; + case 0x000103: + ret = (riva128->pmc.intr >> 24) & 0xff; + break; + case 0x000140: + ret = riva128->pmc.intr & 0xff; + break; + case 0x000141: + ret = (riva128->pmc.intr_en >> 8) & 0xff; + break; + case 0x000142: + ret = (riva128->pmc.intr_en >> 16) & 0xff; + break; + case 0x000143: + ret = (riva128->pmc.intr_en >> 24) & 0xff; + break; + case 0x000160: + ret = riva128->pmc.intr_line & 0xff; + break; + case 0x000161: + ret = (riva128->pmc.intr_line >> 8) & 0xff; + break; + case 0x000162: + ret = (riva128->pmc.intr_line >> 16) & 0xff; + break; + case 0x000163: + ret = (riva128->pmc.intr_line >> 24) & 0xff; + break; + case 0x000200: + ret = riva128->pmc.enable & 0xff; + break; + case 0x000201: + ret = (riva128->pmc.enable >> 8) & 0xff; + break; + case 0x000202: + ret = (riva128->pmc.enable >> 16) & 0xff; + break; + case 0x000203: + ret = (riva128->pmc.enable >> 24) & 0xff; + break; + } - return ret; + return ret; } static void riva128_pmc_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - //pclog("RIVA 128 PMC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + //pclog("RIVA 128 PMC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x000100: - riva128->pmc.intr &= ~val; - break; - case 0x000140: - riva128->pmc.intr_en = val & 3; - break; - case 0x000200: - riva128->pmc.enable = val; - break; - } + switch(addr) + { + case 0x000100: + riva128->pmc.intr &= ~val; + break; + case 0x000140: + riva128->pmc.intr_en = val & 3; + break; + case 0x000200: + riva128->pmc.enable = val; + break; + } } static void riva128_pmc_interrupt(int num, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - riva128->pmc.intr |= (1 << num); + riva128->pmc.intr |= (1 << num); - picint(1 << riva128->pci_regs[0x3c]); + picint(1 << riva128->pci_regs[0x3c]); } static uint8_t riva128_pbus_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - //pclog("RIVA 128 PBUS read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 PBUS read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x001100: ret = riva128->pbus.intr & 0xff; break; - case 0x001101: ret = (riva128->pbus.intr >> 8) & 0xff; break; - case 0x001102: ret = (riva128->pbus.intr >> 16) & 0xff; break; - case 0x001103: ret = (riva128->pbus.intr >> 24) & 0xff; break; - case 0x001140: ret = riva128->pbus.intr & 0xff; break; - case 0x001141: ret = (riva128->pbus.intr_en >> 8) & 0xff; break; - case 0x001142: ret = (riva128->pbus.intr_en >> 16) & 0xff; break; - case 0x001143: ret = (riva128->pbus.intr_en >> 24) & 0xff; break; - case 0x001800 ... 0x0018ff: ret = riva128_pci_read(0, addr - 0x1800, riva128); break; - } + switch(addr) + { + case 0x001100: + ret = riva128->pbus.intr & 0xff; + break; + case 0x001101: + ret = (riva128->pbus.intr >> 8) & 0xff; + break; + case 0x001102: + ret = (riva128->pbus.intr >> 16) & 0xff; + break; + case 0x001103: + ret = (riva128->pbus.intr >> 24) & 0xff; + break; + case 0x001140: + ret = riva128->pbus.intr & 0xff; + break; + case 0x001141: + ret = (riva128->pbus.intr_en >> 8) & 0xff; + break; + case 0x001142: + ret = (riva128->pbus.intr_en >> 16) & 0xff; + break; + case 0x001143: + ret = (riva128->pbus.intr_en >> 24) & 0xff; + break; + case 0x001800 ... 0x0018ff: + ret = riva128_pci_read(0, addr - 0x1800, riva128); + break; + } - return ret; + return ret; } static void riva128_pbus_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - //pclog("RIVA 128 PBUS write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + //pclog("RIVA 128 PBUS write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x001100: - riva128->pbus.intr &= ~val; - break; - case 0x001140: - riva128->pbus.intr_en = val; - break; - case 0x001800 ... 0x0018ff: - riva128_pci_write(0, (addr & 0xfc) + 0, (val >> 0) & 0xff, riva128); - riva128_pci_write(0, (addr & 0xfc) + 1, (val >> 8) & 0xff, riva128); - riva128_pci_write(0, (addr & 0xfc) + 2, (val >> 16) & 0xff, riva128); - riva128_pci_write(0, (addr & 0xfc) + 3, (val >> 24) & 0xff, riva128); - break; - } + switch(addr) + { + case 0x001100: + riva128->pbus.intr &= ~val; + break; + case 0x001140: + riva128->pbus.intr_en = val; + break; + case 0x001800 ... 0x0018ff: + riva128_pci_write(0, (addr & 0xfc) + 0, (val >> 0) & 0xff, riva128); + riva128_pci_write(0, (addr & 0xfc) + 1, (val >> 8) & 0xff, riva128); + riva128_pci_write(0, (addr & 0xfc) + 2, (val >> 16) & 0xff, riva128); + riva128_pci_write(0, (addr & 0xfc) + 3, (val >> 24) & 0xff, riva128); + break; + } } static uint8_t riva128_pfifo_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - pclog("RIVA 128 PFIFO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + pclog("RIVA 128 PFIFO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x002100: ret = riva128->pfifo.intr & 0xff; break; - case 0x002101: ret = (riva128->pfifo.intr >> 8) & 0xff; break; - case 0x002102: ret = (riva128->pfifo.intr >> 16) & 0xff; break; - case 0x002103: ret = (riva128->pfifo.intr >> 24) & 0xff; break; - case 0x002140: ret = riva128->pfifo.intr_en & 0xff; break; - case 0x002141: ret = (riva128->pfifo.intr_en >> 8) & 0xff; break; - case 0x002142: ret = (riva128->pfifo.intr_en >> 16) & 0xff; break; - case 0x002143: ret = (riva128->pfifo.intr_en >> 24) & 0xff; break; - case 0x002210: ret = riva128->pfifo.ramht & 0xff; break; - case 0x002211: ret = (riva128->pfifo.ramht >> 8) & 0xff; break; - case 0x002212: ret = (riva128->pfifo.ramht >> 16) & 0xff; break; - case 0x002213: ret = (riva128->pfifo.ramht >> 24) & 0xff; break; - case 0x002214: ret = riva128->pfifo.ramfc & 0xff; break; - case 0x002215: ret = (riva128->pfifo.ramfc >> 8) & 0xff; break; - case 0x002216: ret = (riva128->pfifo.ramfc >> 16) & 0xff; break; - case 0x002217: ret = (riva128->pfifo.ramfc >> 24) & 0xff; break; - case 0x002218: ret = riva128->pfifo.ramro & 0xff; break; - case 0x002219: ret = (riva128->pfifo.ramro >> 8) & 0xff; break; - case 0x00221a: ret = (riva128->pfifo.ramro >> 16) & 0xff; break; - case 0x00221b: ret = (riva128->pfifo.ramro >> 24) & 0xff; break; - case 0x002504: ret = riva128->pfifo.chan_mode & 0xff; break; - case 0x002505: ret = (riva128->pfifo.chan_mode >> 8) & 0xff; break; - case 0x002506: ret = (riva128->pfifo.chan_mode >> 16) & 0xff; break; - case 0x002507: ret = (riva128->pfifo.chan_mode >> 24) & 0xff; break; - case 0x002508: ret = riva128->pfifo.chan_dma & 0xff; break; - case 0x002509: ret = (riva128->pfifo.chan_dma >> 8) & 0xff; break; - case 0x00250a: ret = (riva128->pfifo.chan_dma >> 16) & 0xff; break; - case 0x00250b: ret = (riva128->pfifo.chan_dma >> 24) & 0xff; break; - case 0x00250c: ret = riva128->pfifo.chan_size & 0xff; break; - case 0x00250d: ret = (riva128->pfifo.chan_size >> 8) & 0xff; break; - case 0x00250e: ret = (riva128->pfifo.chan_size >> 16) & 0xff; break; - case 0x00250f: ret = (riva128->pfifo.chan_size >> 24) & 0xff; break; - //HACK - case 0x002400: ret = 0x10; break; - case 0x002401: ret = 0x00; break; - case 0x003204: ret = riva128->pfifo.caches[1].chanid; break; - case 0x003214: ret = 0x10; break; - case 0x003215: ret = 0x00; break; - case 0x003220: ret = 0x01; break; - } + switch(addr) + { + case 0x002100: + ret = riva128->pfifo.intr & 0xff; + break; + case 0x002101: + ret = (riva128->pfifo.intr >> 8) & 0xff; + break; + case 0x002102: + ret = (riva128->pfifo.intr >> 16) & 0xff; + break; + case 0x002103: + ret = (riva128->pfifo.intr >> 24) & 0xff; + break; + case 0x002140: + ret = riva128->pfifo.intr_en & 0xff; + break; + case 0x002141: + ret = (riva128->pfifo.intr_en >> 8) & 0xff; + break; + case 0x002142: + ret = (riva128->pfifo.intr_en >> 16) & 0xff; + break; + case 0x002143: + ret = (riva128->pfifo.intr_en >> 24) & 0xff; + break; + case 0x002210: + ret = riva128->pfifo.ramht & 0xff; + break; + case 0x002211: + ret = (riva128->pfifo.ramht >> 8) & 0xff; + break; + case 0x002212: + ret = (riva128->pfifo.ramht >> 16) & 0xff; + break; + case 0x002213: + ret = (riva128->pfifo.ramht >> 24) & 0xff; + break; + case 0x002214: + ret = riva128->pfifo.ramfc & 0xff; + break; + case 0x002215: + ret = (riva128->pfifo.ramfc >> 8) & 0xff; + break; + case 0x002216: + ret = (riva128->pfifo.ramfc >> 16) & 0xff; + break; + case 0x002217: + ret = (riva128->pfifo.ramfc >> 24) & 0xff; + break; + case 0x002218: + ret = riva128->pfifo.ramro & 0xff; + break; + case 0x002219: + ret = (riva128->pfifo.ramro >> 8) & 0xff; + break; + case 0x00221a: + ret = (riva128->pfifo.ramro >> 16) & 0xff; + break; + case 0x00221b: + ret = (riva128->pfifo.ramro >> 24) & 0xff; + break; + case 0x002504: + ret = riva128->pfifo.chan_mode & 0xff; + break; + case 0x002505: + ret = (riva128->pfifo.chan_mode >> 8) & 0xff; + break; + case 0x002506: + ret = (riva128->pfifo.chan_mode >> 16) & 0xff; + break; + case 0x002507: + ret = (riva128->pfifo.chan_mode >> 24) & 0xff; + break; + case 0x002508: + ret = riva128->pfifo.chan_dma & 0xff; + break; + case 0x002509: + ret = (riva128->pfifo.chan_dma >> 8) & 0xff; + break; + case 0x00250a: + ret = (riva128->pfifo.chan_dma >> 16) & 0xff; + break; + case 0x00250b: + ret = (riva128->pfifo.chan_dma >> 24) & 0xff; + break; + case 0x00250c: + ret = riva128->pfifo.chan_size & 0xff; + break; + case 0x00250d: + ret = (riva128->pfifo.chan_size >> 8) & 0xff; + break; + case 0x00250e: + ret = (riva128->pfifo.chan_size >> 16) & 0xff; + break; + case 0x00250f: + ret = (riva128->pfifo.chan_size >> 24) & 0xff; + break; + //HACK + case 0x002400: + ret = 0x10; + break; + case 0x002401: + ret = 0x00; + break; + case 0x003204: + ret = riva128->pfifo.caches[1].chanid; + break; + case 0x003214: + ret = 0x10; + break; + case 0x003215: + ret = 0x00; + break; + case 0x003220: + ret = 0x01; + break; + } - return ret; + return ret; } static void riva128_pfifo_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 PFIFO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + pclog("RIVA 128 PFIFO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x002100: - riva128->pfifo.intr &= ~val; - break; - case 0x002140: - riva128->pfifo.intr_en = val; - break; - case 0x002210: - riva128->pfifo.ramht = val; - riva128->pfifo.ramht_addr = (val & 0x1f0) << 8; - switch(val & 0x30000) - { - case 0x00000: - riva128->pfifo.ramht_size = 4 * 1024; - break; - case 0x10000: - riva128->pfifo.ramht_size = 8 * 1024; - break; - case 0x20000: - riva128->pfifo.ramht_size = 16 * 1024; - break; - case 0x30000: - riva128->pfifo.ramht_size = 32 * 1024; - break; - } - break; - case 0x002214: - riva128->pfifo.ramfc = val; - riva128->pfifo.ramfc_addr = (val & 0x1fe) << 4; - break; - case 0x002218: - riva128->pfifo.ramro = val; - riva128->pfifo.ramro_addr = (val & 0x1fe) << 4; - if(val & 0x10000) riva128->pfifo.ramro_size = 8192; - else riva128->pfifo.ramro_size = 512; - break; - case 0x002504: - riva128->pfifo.chan_mode = val; - break; - case 0x002508: - riva128->pfifo.chan_dma = val; - break; - case 0x00250c: - riva128->pfifo.chan_size = val; - break; - case 0x003200: - riva128->pfifo.caches[1].push_enabled = val; - break; - case 0x003204: - riva128->pfifo.caches[1].chanid = val; - break; - } + switch(addr) + { + case 0x002100: + riva128->pfifo.intr &= ~val; + break; + case 0x002140: + riva128->pfifo.intr_en = val; + break; + case 0x002210: + riva128->pfifo.ramht = val; + riva128->pfifo.ramht_addr = (val & 0x1f0) << 8; + switch(val & 0x30000) + { + case 0x00000: + riva128->pfifo.ramht_size = 4 * 1024; + break; + case 0x10000: + riva128->pfifo.ramht_size = 8 * 1024; + break; + case 0x20000: + riva128->pfifo.ramht_size = 16 * 1024; + break; + case 0x30000: + riva128->pfifo.ramht_size = 32 * 1024; + break; + } + break; + case 0x002214: + riva128->pfifo.ramfc = val; + riva128->pfifo.ramfc_addr = (val & 0x1fe) << 4; + break; + case 0x002218: + riva128->pfifo.ramro = val; + riva128->pfifo.ramro_addr = (val & 0x1fe) << 4; + if(val & 0x10000) riva128->pfifo.ramro_size = 8192; + else riva128->pfifo.ramro_size = 512; + break; + case 0x002504: + riva128->pfifo.chan_mode = val; + break; + case 0x002508: + riva128->pfifo.chan_dma = val; + break; + case 0x00250c: + riva128->pfifo.chan_size = val; + break; + case 0x003200: + riva128->pfifo.caches[1].push_enabled = val; + break; + case 0x003204: + riva128->pfifo.caches[1].chanid = val; + break; + } } static void riva128_pfifo_interrupt(int num, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - riva128->pfifo.intr |= (1 << num); + riva128->pfifo.intr |= (1 << num); - riva128_pmc_interrupt(8, riva128); + riva128_pmc_interrupt(8, riva128); } static uint8_t riva128_ptimer_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - //pclog("RIVA 128 PTIMER read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 PTIMER read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x009100: ret = riva128->ptimer.intr & 0xff; break; - case 0x009101: ret = (riva128->ptimer.intr >> 8) & 0xff; break; - case 0x009102: ret = (riva128->ptimer.intr >> 16) & 0xff; break; - case 0x009103: ret = (riva128->ptimer.intr >> 24) & 0xff; break; - case 0x009140: ret = riva128->ptimer.intr & 0xff; break; - case 0x009141: ret = (riva128->ptimer.intr_en >> 8) & 0xff; break; - case 0x009142: ret = (riva128->ptimer.intr_en >> 16) & 0xff; break; - case 0x009143: ret = (riva128->ptimer.intr_en >> 24) & 0xff; break; - case 0x009200: ret = riva128->ptimer.clock_div & 0xff; break; - case 0x009201: ret = (riva128->ptimer.clock_div >> 8) & 0xff; break; - case 0x009202: ret = (riva128->ptimer.clock_div >> 16) & 0xff; break; - case 0x009203: ret = (riva128->ptimer.clock_div >> 24) & 0xff; break; - case 0x009210: ret = riva128->ptimer.clock_mul & 0xff; break; - case 0x009211: ret = (riva128->ptimer.clock_mul >> 8) & 0xff; break; - case 0x009212: ret = (riva128->ptimer.clock_mul >> 16) & 0xff; break; - case 0x009213: ret = (riva128->ptimer.clock_mul >> 24) & 0xff; break; - case 0x009400: ret = riva128->ptimer.time & 0xff; break; - case 0x009401: ret = (riva128->ptimer.time >> 8) & 0xff; break; - case 0x009402: ret = (riva128->ptimer.time >> 16) & 0xff; break; - case 0x009403: ret = (riva128->ptimer.time >> 24) & 0xff; break; - case 0x009410: ret = (riva128->ptimer.time >> 32) & 0xff; break; - case 0x009411: ret = (riva128->ptimer.time >> 40) & 0xff; break; - case 0x009412: ret = (riva128->ptimer.time >> 48) & 0xff; break; - case 0x009413: ret = (riva128->ptimer.time >> 56) & 0xff; break; - case 0x009420: ret = riva128->ptimer.alarm & 0xff; break; - case 0x009421: ret = (riva128->ptimer.alarm >> 8) & 0xff; break; - case 0x009422: ret = (riva128->ptimer.alarm >> 16) & 0xff; break; - case 0x009423: ret = (riva128->ptimer.alarm >> 24) & 0xff; break; - } + switch(addr) + { + case 0x009100: + ret = riva128->ptimer.intr & 0xff; + break; + case 0x009101: + ret = (riva128->ptimer.intr >> 8) & 0xff; + break; + case 0x009102: + ret = (riva128->ptimer.intr >> 16) & 0xff; + break; + case 0x009103: + ret = (riva128->ptimer.intr >> 24) & 0xff; + break; + case 0x009140: + ret = riva128->ptimer.intr & 0xff; + break; + case 0x009141: + ret = (riva128->ptimer.intr_en >> 8) & 0xff; + break; + case 0x009142: + ret = (riva128->ptimer.intr_en >> 16) & 0xff; + break; + case 0x009143: + ret = (riva128->ptimer.intr_en >> 24) & 0xff; + break; + case 0x009200: + ret = riva128->ptimer.clock_div & 0xff; + break; + case 0x009201: + ret = (riva128->ptimer.clock_div >> 8) & 0xff; + break; + case 0x009202: + ret = (riva128->ptimer.clock_div >> 16) & 0xff; + break; + case 0x009203: + ret = (riva128->ptimer.clock_div >> 24) & 0xff; + break; + case 0x009210: + ret = riva128->ptimer.clock_mul & 0xff; + break; + case 0x009211: + ret = (riva128->ptimer.clock_mul >> 8) & 0xff; + break; + case 0x009212: + ret = (riva128->ptimer.clock_mul >> 16) & 0xff; + break; + case 0x009213: + ret = (riva128->ptimer.clock_mul >> 24) & 0xff; + break; + case 0x009400: + ret = riva128->ptimer.time & 0xff; + break; + case 0x009401: + ret = (riva128->ptimer.time >> 8) & 0xff; + break; + case 0x009402: + ret = (riva128->ptimer.time >> 16) & 0xff; + break; + case 0x009403: + ret = (riva128->ptimer.time >> 24) & 0xff; + break; + case 0x009410: + ret = (riva128->ptimer.time >> 32) & 0xff; + break; + case 0x009411: + ret = (riva128->ptimer.time >> 40) & 0xff; + break; + case 0x009412: + ret = (riva128->ptimer.time >> 48) & 0xff; + break; + case 0x009413: + ret = (riva128->ptimer.time >> 56) & 0xff; + break; + case 0x009420: + ret = riva128->ptimer.alarm & 0xff; + break; + case 0x009421: + ret = (riva128->ptimer.alarm >> 8) & 0xff; + break; + case 0x009422: + ret = (riva128->ptimer.alarm >> 16) & 0xff; + break; + case 0x009423: + ret = (riva128->ptimer.alarm >> 24) & 0xff; + break; + } - //riva128->ptimer.time += 0x10000; + //riva128->ptimer.time += 0x10000; - return ret; + return ret; } static void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 PTIMER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + pclog("RIVA 128 PTIMER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x009100: - riva128->ptimer.intr &= ~val; - break; - case 0x009140: - riva128->ptimer.intr_en = val; - break; - case 0x009200: - if(!(val & 0xffff)) val = 1; - riva128->ptimer.clock_div = val & 0xffff; - break; - case 0x009210: - if((val & 0xffff) > riva128->ptimer.clock_div) val = riva128->ptimer.clock_div; - riva128->ptimer.clock_mul = val & 0xffff; - break; - case 0x009420: - riva128->ptimer.alarm = val & 0xffffffe0; - break; - } + switch(addr) + { + case 0x009100: + riva128->ptimer.intr &= ~val; + break; + case 0x009140: + riva128->ptimer.intr_en = val; + break; + case 0x009200: + if(!(val & 0xffff)) val = 1; + riva128->ptimer.clock_div = val & 0xffff; + break; + case 0x009210: + if((val & 0xffff) > riva128->ptimer.clock_div) val = riva128->ptimer.clock_div; + riva128->ptimer.clock_mul = val & 0xffff; + break; + case 0x009420: + riva128->ptimer.alarm = val & 0xffffffe0; + break; + } } static void riva128_ptimer_interrupt(int num, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - riva128->ptimer.intr |= (1 << num); + riva128->ptimer.intr |= (1 << num); - riva128_pmc_interrupt(20, riva128); + riva128_pmc_interrupt(20, riva128); } static uint8_t riva128_pfb_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - //pclog("RIVA 128 PFB read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 PFB read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x100000: - { - switch(riva128->card_id) - { - case 0x03: - { - switch(riva128->memory_size) - { - case 1: case 8: ret = 0; - case 2: ret = 1; - case 4: ret = 2; - } - ret |= 0x04; - break; - } - case 0x04: case 0x05: - { - switch(riva128->memory_size) - { - case 4: ret = 1; break; - case 8: ret = 2; break; - case 16: ret = 3; break; - case 32: ret = 0; break; - } - ret |= 0x14; - break; - } - } - break; - } - case 0x100200: ret = riva128->pfb.config_0 & 0xff; break; - case 0x100201: ret = (riva128->pfb.config_0 >> 8) & 0xff; break; - case 0x100202: ret = (riva128->pfb.config_0 >> 16) & 0xff; break; - case 0x100203: ret = (riva128->pfb.config_0 >> 24) & 0xff; break; - } + switch(addr) + { + case 0x100000: + { + switch(riva128->card_id) + { + case 0x03: + { + switch(riva128->memory_size) + { + case 1: + case 8: + ret = 0; + case 2: + ret = 1; + case 4: + ret = 2; + } + ret |= 0x04; + break; + } + case 0x04: + case 0x05: + { + switch(riva128->memory_size) + { + case 4: + ret = 1; + break; + case 8: + ret = 2; + break; + case 16: + ret = 3; + break; + case 32: + ret = 0; + break; + } + ret |= 0x14; + break; + } + } + break; + } + case 0x100200: + ret = riva128->pfb.config_0 & 0xff; + break; + case 0x100201: + ret = (riva128->pfb.config_0 >> 8) & 0xff; + break; + case 0x100202: + ret = (riva128->pfb.config_0 >> 16) & 0xff; + break; + case 0x100203: + ret = (riva128->pfb.config_0 >> 24) & 0xff; + break; + } - return ret; + return ret; } static void riva128_pfb_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - //pclog("RIVA 128 PFB write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + //pclog("RIVA 128 PFB write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x100200: - riva128->pfb.config_0 = val; - riva128->pfb.width = (val & 0x3f) << 5; - switch((val >> 8) & 3) - { - case 1: riva128->pfb.bpp = 8; break; - case 2: riva128->pfb.bpp = 16; break; - case 3: riva128->pfb.bpp = 32; break; - } - break; - } + switch(addr) + { + case 0x100200: + riva128->pfb.config_0 = val; + riva128->pfb.width = (val & 0x3f) << 5; + switch((val >> 8) & 3) + { + case 1: + riva128->pfb.bpp = 8; + break; + case 2: + riva128->pfb.bpp = 16; + break; + case 3: + riva128->pfb.bpp = 32; + break; + } + break; + } } static uint8_t riva128_pextdev_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - //pclog("RIVA 128 PEXTDEV read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 PEXTDEV read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x101000: ret = 0x9e; break; - case 0x101001: ret = 0x01; break; - } + switch(addr) + { + case 0x101000: + ret = 0x9e; + break; + case 0x101001: + ret = 0x01; + break; + } - return ret; + return ret; } static uint8_t riva128_pgraph_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - pclog("RIVA 128 PGRAPH read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + pclog("RIVA 128 PGRAPH read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x400080: ret = riva128->pgraph.debug[0] & 0xff; break; - case 0x400081: ret = (riva128->pgraph.debug[0] >> 8) & 0xff; break; - case 0x400082: ret = (riva128->pgraph.debug[0] >> 16) & 0xff; break; - case 0x400083: ret = (riva128->pgraph.debug[0] >> 24) & 0xff; break; - case 0x400084: ret = riva128->pgraph.debug[1] & 0xff; break; - case 0x400085: ret = (riva128->pgraph.debug[1] >> 8) & 0xff; break; - case 0x400086: ret = (riva128->pgraph.debug[1] >> 16) & 0xff; break; - case 0x400087: ret = (riva128->pgraph.debug[1] >> 24) & 0xff; break; - case 0x400088: ret = riva128->pgraph.debug[2] & 0xff; break; - case 0x400089: ret = (riva128->pgraph.debug[2] >> 8) & 0xff; break; - case 0x40008a: ret = (riva128->pgraph.debug[2] >> 16) & 0xff; break; - case 0x40008b: ret = (riva128->pgraph.debug[2] >> 24) & 0xff; break; - case 0x40008c: ret = riva128->pgraph.debug[3] & 0xff; break; - case 0x40008d: ret = (riva128->pgraph.debug[3] >> 8) & 0xff; break; - case 0x40008e: ret = (riva128->pgraph.debug[3] >> 16) & 0xff; break; - case 0x40008f: ret = (riva128->pgraph.debug[3] >> 24) & 0xff; break; + switch(addr) + { + case 0x400080: + ret = riva128->pgraph.debug[0] & 0xff; + break; + case 0x400081: + ret = (riva128->pgraph.debug[0] >> 8) & 0xff; + break; + case 0x400082: + ret = (riva128->pgraph.debug[0] >> 16) & 0xff; + break; + case 0x400083: + ret = (riva128->pgraph.debug[0] >> 24) & 0xff; + break; + case 0x400084: + ret = riva128->pgraph.debug[1] & 0xff; + break; + case 0x400085: + ret = (riva128->pgraph.debug[1] >> 8) & 0xff; + break; + case 0x400086: + ret = (riva128->pgraph.debug[1] >> 16) & 0xff; + break; + case 0x400087: + ret = (riva128->pgraph.debug[1] >> 24) & 0xff; + break; + case 0x400088: + ret = riva128->pgraph.debug[2] & 0xff; + break; + case 0x400089: + ret = (riva128->pgraph.debug[2] >> 8) & 0xff; + break; + case 0x40008a: + ret = (riva128->pgraph.debug[2] >> 16) & 0xff; + break; + case 0x40008b: + ret = (riva128->pgraph.debug[2] >> 24) & 0xff; + break; + case 0x40008c: + ret = riva128->pgraph.debug[3] & 0xff; + break; + case 0x40008d: + ret = (riva128->pgraph.debug[3] >> 8) & 0xff; + break; + case 0x40008e: + ret = (riva128->pgraph.debug[3] >> 16) & 0xff; + break; + case 0x40008f: + ret = (riva128->pgraph.debug[3] >> 24) & 0xff; + break; - case 0x400100: ret = riva128->pgraph.intr & 0xff; break; - case 0x400101: ret = (riva128->pgraph.intr >> 8) & 0xff; break; - case 0x400102: ret = (riva128->pgraph.intr >> 16) & 0xff; break; - case 0x400103: ret = (riva128->pgraph.intr >> 24) & 0xff; break; - case 0x400104: ret = riva128->pgraph.invalid & 0xff; break; - case 0x400105: ret = (riva128->pgraph.invalid >> 8) & 0xff; break; - case 0x400106: ret = (riva128->pgraph.invalid >> 16) & 0xff; break; - case 0x400107: ret = (riva128->pgraph.invalid >> 24) & 0xff; break; - case 0x400140: ret = riva128->pgraph.intr_en & 0xff; break; - case 0x400141: ret = (riva128->pgraph.intr_en >> 8) & 0xff; break; - case 0x400142: ret = (riva128->pgraph.intr_en >> 16) & 0xff; break; - case 0x400143: ret = (riva128->pgraph.intr_en >> 24) & 0xff; break; - case 0x400144: ret = riva128->pgraph.invalid_en & 0xff; break; - case 0x400145: ret = (riva128->pgraph.invalid_en >> 8) & 0xff; break; - case 0x400146: ret = (riva128->pgraph.invalid_en >> 16) & 0xff; break; - case 0x400147: ret = (riva128->pgraph.invalid_en >> 24) & 0xff; break; + case 0x400100: + ret = riva128->pgraph.intr & 0xff; + break; + case 0x400101: + ret = (riva128->pgraph.intr >> 8) & 0xff; + break; + case 0x400102: + ret = (riva128->pgraph.intr >> 16) & 0xff; + break; + case 0x400103: + ret = (riva128->pgraph.intr >> 24) & 0xff; + break; + case 0x400104: + ret = riva128->pgraph.invalid & 0xff; + break; + case 0x400105: + ret = (riva128->pgraph.invalid >> 8) & 0xff; + break; + case 0x400106: + ret = (riva128->pgraph.invalid >> 16) & 0xff; + break; + case 0x400107: + ret = (riva128->pgraph.invalid >> 24) & 0xff; + break; + case 0x400140: + ret = riva128->pgraph.intr_en & 0xff; + break; + case 0x400141: + ret = (riva128->pgraph.intr_en >> 8) & 0xff; + break; + case 0x400142: + ret = (riva128->pgraph.intr_en >> 16) & 0xff; + break; + case 0x400143: + ret = (riva128->pgraph.intr_en >> 24) & 0xff; + break; + case 0x400144: + ret = riva128->pgraph.invalid_en & 0xff; + break; + case 0x400145: + ret = (riva128->pgraph.invalid_en >> 8) & 0xff; + break; + case 0x400146: + ret = (riva128->pgraph.invalid_en >> 16) & 0xff; + break; + case 0x400147: + ret = (riva128->pgraph.invalid_en >> 24) & 0xff; + break; - case 0x400180: ret = riva128->pgraph.ctx_switch[0] & 0xff; break; - case 0x400181: ret = (riva128->pgraph.ctx_switch[0] >> 8) & 0xff; break; - case 0x400182: ret = (riva128->pgraph.ctx_switch[0] >> 16) & 0xff; break; - case 0x400183: ret = (riva128->pgraph.ctx_switch[0] >> 24) & 0xff; break; + case 0x400180: + ret = riva128->pgraph.ctx_switch[0] & 0xff; + break; + case 0x400181: + ret = (riva128->pgraph.ctx_switch[0] >> 8) & 0xff; + break; + case 0x400182: + ret = (riva128->pgraph.ctx_switch[0] >> 16) & 0xff; + break; + case 0x400183: + ret = (riva128->pgraph.ctx_switch[0] >> 24) & 0xff; + break; - case 0x400190: ret = riva128->pgraph.ctx_control & 0xff; break; - case 0x400191: ret = (riva128->pgraph.ctx_control >> 8) & 0xff; break; - case 0x400192: ret = (riva128->pgraph.ctx_control >> 16) & 0xff; break; - case 0x400193: ret = (riva128->pgraph.ctx_control >> 24) & 0xff; break; - case 0x400194: ret = riva128->pgraph.ctx_user & 0xff; break; - case 0x400195: ret = (riva128->pgraph.ctx_user >> 8) & 0xff; break; - case 0x400196: ret = (riva128->pgraph.ctx_user >> 16) & 0xff; break; - case 0x400197: ret = (riva128->pgraph.ctx_user >> 24) & 0xff; break; + case 0x400190: + ret = riva128->pgraph.ctx_control & 0xff; + break; + case 0x400191: + ret = (riva128->pgraph.ctx_control >> 8) & 0xff; + break; + case 0x400192: + ret = (riva128->pgraph.ctx_control >> 16) & 0xff; + break; + case 0x400193: + ret = (riva128->pgraph.ctx_control >> 24) & 0xff; + break; + case 0x400194: + ret = riva128->pgraph.ctx_user & 0xff; + break; + case 0x400195: + ret = (riva128->pgraph.ctx_user >> 8) & 0xff; + break; + case 0x400196: + ret = (riva128->pgraph.ctx_user >> 16) & 0xff; + break; + case 0x400197: + ret = (riva128->pgraph.ctx_user >> 24) & 0xff; + break; - case 0x4001a0 ... 0x4001bf: ret = (riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] >> ((addr & 3) << 3)) & 0xff; break; + case 0x4001a0 ... 0x4001bf: + ret = (riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] >> ((addr & 3) << 3)) & 0xff; + break; - case 0x4006a4: ret = riva128->pgraph.fifo_enable & 1; break; - } + case 0x4006a4: + ret = riva128->pgraph.fifo_enable & 1; + break; + } - if(riva128->card_id == 0x03) switch(addr) - { - case 0x40053c: ret = riva128->pgraph.uclip_xmin & 0xff; break; - case 0x40053d: ret = (riva128->pgraph.uclip_xmin >> 8) & 0xff; break; - case 0x40053e: ret = (riva128->pgraph.uclip_xmin >> 16) & 0xff; break; - case 0x40053f: ret = (riva128->pgraph.uclip_xmin >> 24) & 0xff; break; - case 0x400540: ret = riva128->pgraph.uclip_ymin & 0xff; break; - case 0x400541: ret = (riva128->pgraph.uclip_ymin >> 8) & 0xff; break; - case 0x400542: ret = (riva128->pgraph.uclip_ymin >> 16) & 0xff; break; - case 0x400543: ret = (riva128->pgraph.uclip_ymin >> 24) & 0xff; break; - case 0x400544: ret = riva128->pgraph.uclip_xmax & 0xff; break; - case 0x400545: ret = (riva128->pgraph.uclip_xmax >> 8) & 0xff; break; - case 0x400546: ret = (riva128->pgraph.uclip_xmax >> 16) & 0xff; break; - case 0x400547: ret = (riva128->pgraph.uclip_xmax >> 24) & 0xff; break; - case 0x400548: ret = riva128->pgraph.uclip_ymax & 0xff; break; - case 0x400549: ret = (riva128->pgraph.uclip_ymax >> 8) & 0xff; break; - case 0x40054a: ret = (riva128->pgraph.uclip_ymax >> 16) & 0xff; break; - case 0x40054b: ret = (riva128->pgraph.uclip_ymax >> 24) & 0xff; break; - case 0x400560: ret = riva128->pgraph.oclip_xmin & 0xff; break; - case 0x400561: ret = (riva128->pgraph.oclip_xmin >> 8) & 0xff; break; - case 0x400562: ret = (riva128->pgraph.oclip_xmin >> 16) & 0xff; break; - case 0x400563: ret = (riva128->pgraph.oclip_xmin >> 24) & 0xff; break; - case 0x400564: ret = riva128->pgraph.oclip_ymin & 0xff; break; - case 0x400565: ret = (riva128->pgraph.oclip_ymin >> 8) & 0xff; break; - case 0x400566: ret = (riva128->pgraph.oclip_ymin >> 16) & 0xff; break; - case 0x400567: ret = (riva128->pgraph.oclip_ymin >> 24) & 0xff; break; - case 0x400568: ret = riva128->pgraph.oclip_xmax & 0xff; break; - case 0x400569: ret = (riva128->pgraph.oclip_xmax >> 8) & 0xff; break; - case 0x40056a: ret = (riva128->pgraph.oclip_xmax >> 16) & 0xff; break; - case 0x40056b: ret = (riva128->pgraph.oclip_xmax >> 24) & 0xff; break; - case 0x40056c: ret = riva128->pgraph.oclip_ymax & 0xff; break; - case 0x40056d: ret = (riva128->pgraph.oclip_ymax >> 8) & 0xff; break; - case 0x40056e: ret = (riva128->pgraph.oclip_ymax >> 16) & 0xff; break; - case 0x40056f: ret = (riva128->pgraph.oclip_ymax >> 24) & 0xff; break; - case 0x400640: ret = riva128->pgraph.beta & 0xff; break; - case 0x400641: ret = (riva128->pgraph.beta >> 8) & 0xff; break; - case 0x400642: ret = (riva128->pgraph.beta >> 16) & 0xff; break; - case 0x400643: ret = (riva128->pgraph.beta >> 24) & 0xff; break; - case 0x400684: ret = riva128->pgraph.notify & 0xff; break; - case 0x400685: ret = (riva128->pgraph.notify >> 8) & 0xff; break; - case 0x400686: ret = (riva128->pgraph.notify >> 16) & 0xff; break; - case 0x400687: ret = (riva128->pgraph.notify >> 24) & 0xff; break; - } + if(riva128->card_id == 0x03) switch(addr) + { + case 0x40053c: + ret = riva128->pgraph.uclip_xmin & 0xff; + break; + case 0x40053d: + ret = (riva128->pgraph.uclip_xmin >> 8) & 0xff; + break; + case 0x40053e: + ret = (riva128->pgraph.uclip_xmin >> 16) & 0xff; + break; + case 0x40053f: + ret = (riva128->pgraph.uclip_xmin >> 24) & 0xff; + break; + case 0x400540: + ret = riva128->pgraph.uclip_ymin & 0xff; + break; + case 0x400541: + ret = (riva128->pgraph.uclip_ymin >> 8) & 0xff; + break; + case 0x400542: + ret = (riva128->pgraph.uclip_ymin >> 16) & 0xff; + break; + case 0x400543: + ret = (riva128->pgraph.uclip_ymin >> 24) & 0xff; + break; + case 0x400544: + ret = riva128->pgraph.uclip_xmax & 0xff; + break; + case 0x400545: + ret = (riva128->pgraph.uclip_xmax >> 8) & 0xff; + break; + case 0x400546: + ret = (riva128->pgraph.uclip_xmax >> 16) & 0xff; + break; + case 0x400547: + ret = (riva128->pgraph.uclip_xmax >> 24) & 0xff; + break; + case 0x400548: + ret = riva128->pgraph.uclip_ymax & 0xff; + break; + case 0x400549: + ret = (riva128->pgraph.uclip_ymax >> 8) & 0xff; + break; + case 0x40054a: + ret = (riva128->pgraph.uclip_ymax >> 16) & 0xff; + break; + case 0x40054b: + ret = (riva128->pgraph.uclip_ymax >> 24) & 0xff; + break; + case 0x400560: + ret = riva128->pgraph.oclip_xmin & 0xff; + break; + case 0x400561: + ret = (riva128->pgraph.oclip_xmin >> 8) & 0xff; + break; + case 0x400562: + ret = (riva128->pgraph.oclip_xmin >> 16) & 0xff; + break; + case 0x400563: + ret = (riva128->pgraph.oclip_xmin >> 24) & 0xff; + break; + case 0x400564: + ret = riva128->pgraph.oclip_ymin & 0xff; + break; + case 0x400565: + ret = (riva128->pgraph.oclip_ymin >> 8) & 0xff; + break; + case 0x400566: + ret = (riva128->pgraph.oclip_ymin >> 16) & 0xff; + break; + case 0x400567: + ret = (riva128->pgraph.oclip_ymin >> 24) & 0xff; + break; + case 0x400568: + ret = riva128->pgraph.oclip_xmax & 0xff; + break; + case 0x400569: + ret = (riva128->pgraph.oclip_xmax >> 8) & 0xff; + break; + case 0x40056a: + ret = (riva128->pgraph.oclip_xmax >> 16) & 0xff; + break; + case 0x40056b: + ret = (riva128->pgraph.oclip_xmax >> 24) & 0xff; + break; + case 0x40056c: + ret = riva128->pgraph.oclip_ymax & 0xff; + break; + case 0x40056d: + ret = (riva128->pgraph.oclip_ymax >> 8) & 0xff; + break; + case 0x40056e: + ret = (riva128->pgraph.oclip_ymax >> 16) & 0xff; + break; + case 0x40056f: + ret = (riva128->pgraph.oclip_ymax >> 24) & 0xff; + break; + case 0x400640: + ret = riva128->pgraph.beta & 0xff; + break; + case 0x400641: + ret = (riva128->pgraph.beta >> 8) & 0xff; + break; + case 0x400642: + ret = (riva128->pgraph.beta >> 16) & 0xff; + break; + case 0x400643: + ret = (riva128->pgraph.beta >> 24) & 0xff; + break; + case 0x400684: + ret = riva128->pgraph.notify & 0xff; + break; + case 0x400685: + ret = (riva128->pgraph.notify >> 8) & 0xff; + break; + case 0x400686: + ret = (riva128->pgraph.notify >> 16) & 0xff; + break; + case 0x400687: + ret = (riva128->pgraph.notify >> 24) & 0xff; + break; + } - return ret; + return ret; } static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 PGRAPH write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + pclog("RIVA 128 PGRAPH write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x400100: - riva128->pgraph.intr &= ~val; - break; - case 0x400104: - riva128->pgraph.invalid &= ~val; - break; - case 0x400140: - riva128->pgraph.intr_en = val; - if(riva128->card_id == 0x03) riva128->pgraph.intr_en &= 0x11111111; - else if(riva128->card_id < 0x10) riva128->pgraph.intr_en &= 0x00011311; - break; - case 0x400144: - if(riva128->card_id == 0x03) - { - riva128->pgraph.invalid_en = val; - riva128->pgraph.invalid_en &= 0x00011111; - } - break; - } + switch(addr) + { + case 0x400100: + riva128->pgraph.intr &= ~val; + break; + case 0x400104: + riva128->pgraph.invalid &= ~val; + break; + case 0x400140: + riva128->pgraph.intr_en = val; + if(riva128->card_id == 0x03) riva128->pgraph.intr_en &= 0x11111111; + else if(riva128->card_id < 0x10) riva128->pgraph.intr_en &= 0x00011311; + break; + case 0x400144: + if(riva128->card_id == 0x03) + { + riva128->pgraph.invalid_en = val; + riva128->pgraph.invalid_en &= 0x00011111; + } + break; + } - if(riva128->card_id == 0x03) switch(addr) - { - case 0x400080: - riva128->pgraph.debug[0] = val & 0x13311110; - break; - case 0x400084: - riva128->pgraph.debug[1] = val & 0x10113301; - break; - case 0x400088: - riva128->pgraph.debug[2] = val & 0x1133f111; - break; - case 0x40008c: - riva128->pgraph.debug[3] = val & 0x1173ff31; - break; - case 0x400180: - riva128->pgraph.debug[1] &= ~1; //Clear recent volatile reset bit on object switch. - riva128->pgraph.ctx_switch[0] = val & 0x3ff3f71f; - break; - case 0x400190: - riva128->pgraph.ctx_control = val & 0x11010103; - break; - case 0x400194: - riva128->pgraph.ctx_user = val & 0x7f1fe000; - break; - case 0x4001a0 ... 0x4001bc: - riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] = val & 0x3ff3f71f; - break; - case 0x40053c: - riva128->pgraph.uclip_xmin = val & 0x3ffff; - break; - case 0x400540: - riva128->pgraph.uclip_ymin = val & 0x3ffff; - break; - case 0x400544: - riva128->pgraph.uclip_xmax = val & 0x3ffff; - break; - case 0x400548: - riva128->pgraph.uclip_ymax = val & 0x3ffff; - break; - case 0x400550: - riva128->pgraph.src_canvas_min = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x400554: - riva128->pgraph.src_canvas_max = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x400558: - riva128->pgraph.dst_canvas_min = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x40055c: - riva128->pgraph.dst_canvas_max = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); - break; - case 0x400560: - riva128->pgraph.oclip_xmin = val & 0x3ffff; - break; - case 0x400564: - riva128->pgraph.oclip_ymin = val & 0x3ffff; - break; - case 0x400568: - riva128->pgraph.oclip_xmax = val & 0x3ffff; - break; - case 0x40056c: - riva128->pgraph.oclip_ymax = val & 0x3ffff; - break; - case 0x400640: - { - uint32_t tmp = val & 0x7f800000; - if(val & 0x80000000) tmp = 0; - riva128->pgraph.beta = tmp; - break; - } - case 0x400684: - riva128->pgraph.notify = val & 0x0011ffff; - break; - case 0x4006a4: - riva128->pgraph.fifo_enable = val & 1; - break; - } - else if(riva128->card_id < 0x10) switch(addr) - { - case 0x400080: - riva128->pgraph.debug[0] = val & 0x1337f000; - break; - case 0x400084: - riva128->pgraph.debug[1] = val & ((riva128->card_id == 0x04) ? 0x72113101 : 0xf2ffb701); - break; - case 0x400088: - riva128->pgraph.debug[2] = val & 0x11d7fff1; - break; - case 0x40008c: - riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); - break; - } + if(riva128->card_id == 0x03) switch(addr) + { + case 0x400080: + riva128->pgraph.debug[0] = val & 0x13311110; + break; + case 0x400084: + riva128->pgraph.debug[1] = val & 0x10113301; + break; + case 0x400088: + riva128->pgraph.debug[2] = val & 0x1133f111; + break; + case 0x40008c: + riva128->pgraph.debug[3] = val & 0x1173ff31; + break; + case 0x400180: + riva128->pgraph.debug[1] &= ~1; //Clear recent volatile reset bit on object switch. + riva128->pgraph.ctx_switch[0] = val & 0x3ff3f71f; + break; + case 0x400190: + riva128->pgraph.ctx_control = val & 0x11010103; + break; + case 0x400194: + riva128->pgraph.ctx_user = val & 0x7f1fe000; + break; + case 0x4001a0 ... 0x4001bc: + riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] = val & 0x3ff3f71f; + break; + case 0x40053c: + riva128->pgraph.uclip_xmin = val & 0x3ffff; + break; + case 0x400540: + riva128->pgraph.uclip_ymin = val & 0x3ffff; + break; + case 0x400544: + riva128->pgraph.uclip_xmax = val & 0x3ffff; + break; + case 0x400548: + riva128->pgraph.uclip_ymax = val & 0x3ffff; + break; + case 0x400550: + riva128->pgraph.src_canvas_min = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); + break; + case 0x400554: + riva128->pgraph.src_canvas_max = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); + break; + case 0x400558: + riva128->pgraph.dst_canvas_min = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); + break; + case 0x40055c: + riva128->pgraph.dst_canvas_max = val & (riva128->is_nv3t ? 0x7fff07ff : 0x3fff07ff); + break; + case 0x400560: + riva128->pgraph.oclip_xmin = val & 0x3ffff; + break; + case 0x400564: + riva128->pgraph.oclip_ymin = val & 0x3ffff; + break; + case 0x400568: + riva128->pgraph.oclip_xmax = val & 0x3ffff; + break; + case 0x40056c: + riva128->pgraph.oclip_ymax = val & 0x3ffff; + break; + case 0x400640: + { + uint32_t tmp = val & 0x7f800000; + if(val & 0x80000000) tmp = 0; + riva128->pgraph.beta = tmp; + break; + } + case 0x400684: + riva128->pgraph.notify = val & 0x0011ffff; + break; + case 0x4006a4: + riva128->pgraph.fifo_enable = val & 1; + break; + } + else if(riva128->card_id < 0x10) switch(addr) + { + case 0x400080: + riva128->pgraph.debug[0] = val & 0x1337f000; + break; + case 0x400084: + riva128->pgraph.debug[1] = val & ((riva128->card_id == 0x04) ? 0x72113101 : 0xf2ffb701); + break; + case 0x400088: + riva128->pgraph.debug[2] = val & 0x11d7fff1; + break; + case 0x40008c: + riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); + break; + } } static void riva128_pgraph_interrupt(int num, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - riva128->pgraph.intr |= (1 << num); + riva128->pgraph.intr |= (1 << num); - riva128_pmc_interrupt(12, riva128); + riva128_pmc_interrupt(12, riva128); } static void riva128_pgraph_invalid_interrupt(int num, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - riva128->pgraph.invalid |= (1 << num); + riva128->pgraph.invalid |= (1 << num); - riva128_pgraph_interrupt(0, riva128); + riva128_pgraph_interrupt(0, riva128); } static void riva128_pgraph_volatile_reset(void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - //TODO + //TODO } static uint8_t riva128_pramdac_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - //pclog("RIVA 128 PRAMDAC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 PRAMDAC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x680500: ret = riva128->pramdac.nvpll & 0xff; break; - case 0x680501: ret = (riva128->pramdac.nvpll >> 8) & 0xff; break; - case 0x680502: ret = (riva128->pramdac.nvpll >> 16) & 0xff; break; - case 0x680503: ret = (riva128->pramdac.nvpll >> 24) & 0xff; break; - case 0x680504: ret = riva128->pramdac.mpll & 0xff; break; - case 0x680505: ret = (riva128->pramdac.mpll >> 8) & 0xff; break; - case 0x680506: ret = (riva128->pramdac.mpll >> 16) & 0xff; break; - case 0x680507: ret = (riva128->pramdac.mpll >> 24) & 0xff; break; - case 0x680508: ret = riva128->pramdac.vpll & 0xff; break; - case 0x680509: ret = (riva128->pramdac.vpll >> 8) & 0xff; break; - case 0x68050a: ret = (riva128->pramdac.vpll >> 16) & 0xff; break; - case 0x68050b: ret = (riva128->pramdac.vpll >> 24) & 0xff; break; - case 0x68050c: ret = riva128->pramdac.pll_ctrl & 0xff; break; - case 0x68050d: ret = (riva128->pramdac.pll_ctrl >> 8) & 0xff; break; - case 0x68050e: ret = (riva128->pramdac.pll_ctrl >> 16) & 0xff; break; - case 0x68050f: ret = (riva128->pramdac.pll_ctrl >> 24) & 0xff; break; - case 0x680600: ret = riva128->pramdac.gen_ctrl & 0xff; break; - case 0x680601: ret = (riva128->pramdac.gen_ctrl >> 8) & 0xff; break; - case 0x680602: ret = (riva128->pramdac.gen_ctrl >> 16) & 0xff; break; - case 0x680603: ret = (riva128->pramdac.gen_ctrl >> 24) & 0xff; break; - } + switch(addr) + { + case 0x680500: + ret = riva128->pramdac.nvpll & 0xff; + break; + case 0x680501: + ret = (riva128->pramdac.nvpll >> 8) & 0xff; + break; + case 0x680502: + ret = (riva128->pramdac.nvpll >> 16) & 0xff; + break; + case 0x680503: + ret = (riva128->pramdac.nvpll >> 24) & 0xff; + break; + case 0x680504: + ret = riva128->pramdac.mpll & 0xff; + break; + case 0x680505: + ret = (riva128->pramdac.mpll >> 8) & 0xff; + break; + case 0x680506: + ret = (riva128->pramdac.mpll >> 16) & 0xff; + break; + case 0x680507: + ret = (riva128->pramdac.mpll >> 24) & 0xff; + break; + case 0x680508: + ret = riva128->pramdac.vpll & 0xff; + break; + case 0x680509: + ret = (riva128->pramdac.vpll >> 8) & 0xff; + break; + case 0x68050a: + ret = (riva128->pramdac.vpll >> 16) & 0xff; + break; + case 0x68050b: + ret = (riva128->pramdac.vpll >> 24) & 0xff; + break; + case 0x68050c: + ret = riva128->pramdac.pll_ctrl & 0xff; + break; + case 0x68050d: + ret = (riva128->pramdac.pll_ctrl >> 8) & 0xff; + break; + case 0x68050e: + ret = (riva128->pramdac.pll_ctrl >> 16) & 0xff; + break; + case 0x68050f: + ret = (riva128->pramdac.pll_ctrl >> 24) & 0xff; + break; + case 0x680600: + ret = riva128->pramdac.gen_ctrl & 0xff; + break; + case 0x680601: + ret = (riva128->pramdac.gen_ctrl >> 8) & 0xff; + break; + case 0x680602: + ret = (riva128->pramdac.gen_ctrl >> 16) & 0xff; + break; + case 0x680603: + ret = (riva128->pramdac.gen_ctrl >> 24) & 0xff; + break; + } - return ret; + return ret; } static void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - //pclog("RIVA 128 PRAMDAC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + //pclog("RIVA 128 PRAMDAC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x680500: - riva128->pramdac.nvpll = val; - riva128->pramdac.nv_m = val & 0xff; - riva128->pramdac.nv_n = (val >> 8) & 0xff; - riva128->pramdac.nv_p = (val >> 16) & 7; - svga_recalctimings(svga); - break; - case 0x680504: - riva128->pramdac.mpll = val; - riva128->pramdac.m_m = val & 0xff; - riva128->pramdac.m_n = (val >> 8) & 0xff; - riva128->pramdac.m_p = (val >> 16) & 7; - svga_recalctimings(svga); - break; - case 0x680508: - riva128->pramdac.vpll = val; - riva128->pramdac.v_m = val & 0xff; - riva128->pramdac.v_n = (val >> 8) & 0xff; - riva128->pramdac.v_p = (val >> 16) & 7; - svga_recalctimings(svga); - break; - case 0x68050c: - riva128->pramdac.pll_ctrl = val; - break; - case 0x680600: - riva128->pramdac.gen_ctrl = val; - break; - } + switch(addr) + { + case 0x680500: + riva128->pramdac.nvpll = val; + riva128->pramdac.nv_m = val & 0xff; + riva128->pramdac.nv_n = (val >> 8) & 0xff; + riva128->pramdac.nv_p = (val >> 16) & 7; + svga_recalctimings(svga); + break; + case 0x680504: + riva128->pramdac.mpll = val; + riva128->pramdac.m_m = val & 0xff; + riva128->pramdac.m_n = (val >> 8) & 0xff; + riva128->pramdac.m_p = (val >> 16) & 7; + svga_recalctimings(svga); + break; + case 0x680508: + riva128->pramdac.vpll = val; + riva128->pramdac.v_m = val & 0xff; + riva128->pramdac.v_n = (val >> 8) & 0xff; + riva128->pramdac.v_p = (val >> 16) & 7; + svga_recalctimings(svga); + break; + case 0x68050c: + riva128->pramdac.pll_ctrl = val; + break; + case 0x680600: + riva128->pramdac.gen_ctrl = val; + break; + } } static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 RAMHT lookup with handle %08X %04X:%08X\n", handle, CS, cpu_state.pc); - - uint32_t ramht_base = riva128->pfifo.ramht_addr; - - uint32_t tmp = handle; - uint32_t hash = 0; - - int bits; - - switch(riva128->pfifo.ramht_size) - { - case 4096: bits = 12; - case 8192: bits = 13; - case 16384: bits = 14; - case 32768: bits = 15; - } - - while(handle) - { - hash ^= (tmp & (riva128->pfifo.ramht_size - 1)); - tmp = handle >> 1; - } - - hash ^= riva128->pfifo.caches[1].chanid << (bits - 4); - - return riva128->pramin[ramht_base + (hash * 8)]; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + pclog("RIVA 128 RAMHT lookup with handle %08X %04X:%08X\n", handle, CS, cpu_state.pc); + + uint32_t ramht_base = riva128->pfifo.ramht_addr; + + uint32_t tmp = handle; + uint32_t hash = 0; + + int bits; + + switch(riva128->pfifo.ramht_size) + { + case 4096: + bits = 12; + case 8192: + bits = 13; + case 16384: + bits = 14; + case 32768: + bits = 15; + } + + while(handle) + { + hash ^= (tmp & (riva128->pfifo.ramht_size - 1)); + tmp = handle >> 1; + } + + hash ^= riva128->pfifo.caches[1].chanid << (bits - 4); + + return riva128->pramin[ramht_base + (hash * 8)]; } static void riva128_puller_exec_method(int chanid, int subchanid, int offset, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 Puller executing method %04X on channel %01X[%01X] %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + pclog("RIVA 128 Puller executing method %04X on channel %01X[%01X] %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc); - if(riva128->card_id == 0x03) - { - uint32_t tmp = riva128_ramht_lookup(val, riva128); - riva128->pgraph.instance = (tmp & 0xffff) << 4; - unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; - unsigned new_subc = subchanid & 7; - if((old_subc != new_subc) || !offset) - { - uint32_t tmp_ctx = riva128->pramin[riva128->pgraph.instance]; - if(!offset) riva128->pgraph.ctx_cache[new_subc][0] = tmp_ctx & 0x3ff3f71f; - riva128->pgraph.ctx_user &= 0x1fe000; - riva128->pgraph.ctx_user |= tmp & 0x1f0000; - riva128->pgraph.ctx_user |= new_subc << 13; - if(riva128->pgraph.debug[1] & 0x100000) riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[new_subc][0]; - if(riva128->pgraph.debug[2] & 0x10000000) - { - riva128_pgraph_volatile_reset(riva128); - riva128->pgraph.debug[1] |= 1; - } - else riva128->pgraph.debug[1] &= ~1; - if(riva128->pgraph.notify & 0x10000) - { - riva128_pgraph_invalid_interrupt(16, riva128); - riva128->pgraph.fifo_enable = 0; - } - } + if(riva128->card_id == 0x03) + { + uint32_t tmp = riva128_ramht_lookup(val, riva128); + riva128->pgraph.instance = (tmp & 0xffff) << 4; + unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; + unsigned new_subc = subchanid & 7; + if((old_subc != new_subc) || !offset) + { + uint32_t tmp_ctx = riva128->pramin[riva128->pgraph.instance]; + if(!offset) riva128->pgraph.ctx_cache[new_subc][0] = tmp_ctx & 0x3ff3f71f; + riva128->pgraph.ctx_user &= 0x1fe000; + riva128->pgraph.ctx_user |= tmp & 0x1f0000; + riva128->pgraph.ctx_user |= new_subc << 13; + if(riva128->pgraph.debug[1] & 0x100000) riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[new_subc][0]; + if(riva128->pgraph.debug[2] & 0x10000000) + { + riva128_pgraph_volatile_reset(riva128); + riva128->pgraph.debug[1] |= 1; + } + else riva128->pgraph.debug[1] &= ~1; + if(riva128->pgraph.notify & 0x10000) + { + riva128_pgraph_invalid_interrupt(16, riva128); + riva128->pgraph.fifo_enable = 0; + } + } - if(!riva128->pgraph.invalid && (((riva128->pgraph.debug[3] >> 20) & 3) == 3) && offset) - { - riva128_pgraph_invalid_interrupt(4, riva128); - riva128->pgraph.fifo_enable = 0; - } + if(!riva128->pgraph.invalid && (((riva128->pgraph.debug[3] >> 20) & 3) == 3) && offset) + { + riva128_pgraph_invalid_interrupt(4, riva128); + riva128->pgraph.fifo_enable = 0; + } - unsigned new_class = (tmp >> 16) & 0x1f; - if((riva128->pgraph.debug[1] & 0x10000) && ((riva128->pgraph.instance >> 4) != riva128->pgraph.ctx_switch[3]) && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104)) - { - riva128->pgraph.ctx_switch[3] = riva128->pgraph.instance >> 4; - riva128->pgraph.ctx_switch[1] = riva128->pramin[riva128->pgraph.instance + 4] & 0xffff; - riva128->pgraph.notify &= 0xf10000; - riva128->pgraph.notify |= (riva128->pramin[riva128->pgraph.instance + 4] >> 16) & 0xffff; - riva128->pgraph.ctx_switch[2] = riva128->pramin[riva128->pgraph.instance + 8] & 0x1ffff; - } - } + unsigned new_class = (tmp >> 16) & 0x1f; + if((riva128->pgraph.debug[1] & 0x10000) && ((riva128->pgraph.instance >> 4) != riva128->pgraph.ctx_switch[3]) && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104)) + { + riva128->pgraph.ctx_switch[3] = riva128->pgraph.instance >> 4; + riva128->pgraph.ctx_switch[1] = riva128->pramin[riva128->pgraph.instance + 4] & 0xffff; + riva128->pgraph.notify &= 0xf10000; + riva128->pgraph.notify |= (riva128->pramin[riva128->pgraph.instance + 4] >> 16) & 0xffff; + riva128->pgraph.ctx_switch[2] = riva128->pramin[riva128->pgraph.instance + 8] & 0x1ffff; + } + } } static void riva128_pusher_run(int chanid, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - while(riva128->pfifo.channels[chanid].dmaget != riva128->pfifo.channels[chanid].dmaput) - { - uint32_t dmaget = riva128->pfifo.channels[chanid].dmaget; - uint32_t cmd = ((uint32_t*)svga->vram)[dmaget >> 2]; - uint32_t* params = ((uint32_t*)svga->vram)[(dmaget + 4) >> 2]; - if(((cmd & 0xe0000003) == 0x20000000) && (riva128->card_id >= 0x04)) - { - //old nv4 jump command - riva128->pfifo.channels[chanid].dmaget = cmd & 0x1ffffffc; - } - if((cmd & 0xe0030003) == 0) - { - //nv3 increasing method command - uint32_t method = cmd & 0x1ffc; - int subchannel = (cmd >> 13) & 7; - int method_count = (cmd >> 18) & 0x7ff; - for(int i = 0;ipfifo.channels[chanid].dmaget += 4; - } + while(riva128->pfifo.channels[chanid].dmaget != riva128->pfifo.channels[chanid].dmaput) + { + uint32_t dmaget = riva128->pfifo.channels[chanid].dmaget; + uint32_t cmd = ((uint32_t*)svga->vram)[dmaget >> 2]; + uint32_t* params = ((uint32_t*)svga->vram)[(dmaget + 4) >> 2]; + if(((cmd & 0xe0000003) == 0x20000000) && (riva128->card_id >= 0x04)) + { + //old nv4 jump command + riva128->pfifo.channels[chanid].dmaget = cmd & 0x1ffffffc; + } + if((cmd & 0xe0030003) == 0) + { + //nv3 increasing method command + uint32_t method = cmd & 0x1ffc; + int subchannel = (cmd >> 13) & 7; + int method_count = (cmd >> 18) & 0x7ff; + for(int i = 0; ipfifo.channels[chanid].dmaget += 4; + } } static void riva128_user_write(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - pclog("RIVA 128 USER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - - addr -= 0x800000; - - int chanid = (addr >> 16) & 0xf; - int subchanid = (addr >> 13) & 0x7; - int offset = addr & 0x1fff; - - if(riva128->pfifo.chan_mode & (1 << chanid)) - { - //DMA mode, at least this has docs. - switch(offset) + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + pclog("RIVA 128 USER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + + addr -= 0x800000; + + int chanid = (addr >> 16) & 0xf; + int subchanid = (addr >> 13) & 0x7; + int offset = addr & 0x1fff; + + if(riva128->pfifo.chan_mode & (1 << chanid)) { - case 0x40: - riva128->pfifo.channels[chanid].dmaput = val; - if(riva128->pfifo.caches[1].push_enabled) riva128_pusher_run(chanid, riva128); - break; - case 0x44: - riva128->pfifo.channels[chanid].dmaget = val; - break; + //DMA mode, at least this has docs. + switch(offset) + { + case 0x40: + riva128->pfifo.channels[chanid].dmaput = val; + if(riva128->pfifo.caches[1].push_enabled) riva128_pusher_run(chanid, riva128); + break; + case 0x44: + riva128->pfifo.channels[chanid].dmaget = val; + break; + } + } + else + { + //I don't know what to do here, as there are basically no docs on PIO PFIFO submission. + pclog("RIVA 128 PIO PFIFO submission attempted\n"); } - } - else - { - //I don't know what to do here, as there are basically no docs on PIO PFIFO submission. - pclog("RIVA 128 PIO PFIFO submission attempted\n"); - } } static uint8_t riva128_mmio_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - addr &= 0xffffff; + addr &= 0xffffff; - //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER. DO NOT REMOVE. - if(!((addr >= 0x009000) && (addr <= 0x009fff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER. DO NOT REMOVE. + if(!((addr >= 0x009000) && (addr <= 0x009fff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x000000 ... 0x000fff: - ret = riva128_pmc_read(addr, riva128); - break; - case 0x001000 ... 0x001fff: - ret = riva128_pbus_read(addr, riva128); - break; - case 0x002000 ... 0x002fff: - ret = riva128_pfifo_read(addr, riva128); - break; - case 0x009000 ... 0x009fff: - ret = riva128_ptimer_read(addr, riva128); - break; - case 0x100000 ... 0x100fff: - ret = riva128_pfb_read(addr, riva128); - break; - case 0x101000 ... 0x101fff: - ret = riva128_pextdev_read(addr, riva128); - break; - case 0x110000 ... 0x11ffff: - if(riva128->card_id == 0x03) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; - break; - case 0x300000 ... 0x30ffff: - if(riva128->card_id >= 0x04) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; - break; - case 0x400000 ... 0x401fff: - ret = riva128_pgraph_read(addr, riva128); - break; - case 0x6013b4 ... 0x6013b5: case 0x6013d4 ... 0x6013d5: case 0x0c03c2 ... 0x0c03c5: case 0x0c03cc ... 0x0c03cf: - ret = riva128_in(addr & 0xfff, riva128); - break; - case 0x680000 ... 0x680fff: - ret = riva128_pramdac_read(addr, riva128); - break; - } - return ret; + switch(addr) + { + case 0x000000 ... 0x000fff: + ret = riva128_pmc_read(addr, riva128); + break; + case 0x001000 ... 0x001fff: + ret = riva128_pbus_read(addr, riva128); + break; + case 0x002000 ... 0x002fff: + ret = riva128_pfifo_read(addr, riva128); + break; + case 0x009000 ... 0x009fff: + ret = riva128_ptimer_read(addr, riva128); + break; + case 0x100000 ... 0x100fff: + ret = riva128_pfb_read(addr, riva128); + break; + case 0x101000 ... 0x101fff: + ret = riva128_pextdev_read(addr, riva128); + break; + case 0x110000 ... 0x11ffff: + if(riva128->card_id == 0x03) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; + break; + case 0x300000 ... 0x30ffff: + if(riva128->card_id >= 0x04) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; + break; + case 0x400000 ... 0x401fff: + ret = riva128_pgraph_read(addr, riva128); + break; + case 0x6013b4 ... 0x6013b5: + case 0x6013d4 ... 0x6013d5: + case 0x0c03c2 ... 0x0c03c5: + case 0x0c03cc ... 0x0c03cf: + ret = riva128_in(addr & 0xfff, riva128); + break; + case 0x680000 ... 0x680fff: + ret = riva128_pramdac_read(addr, riva128); + break; + } + return ret; } static uint16_t riva128_mmio_read_w(uint32_t addr, void *p) { - addr &= 0xffffff; - //pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - return (riva128_mmio_read(addr+0,p) << 0) | (riva128_mmio_read(addr+1,p) << 8); + addr &= 0xffffff; + //pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + return (riva128_mmio_read(addr+0,p) << 0) | (riva128_mmio_read(addr+1,p) << 8); } static uint32_t riva128_mmio_read_l(uint32_t addr, void *p) { - addr &= 0xffffff; - //pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); - return (riva128_mmio_read(addr+0,p) << 0) | (riva128_mmio_read(addr+1,p) << 8) | (riva128_mmio_read(addr+2,p) << 16) | (riva128_mmio_read(addr+3,p) << 24); + addr &= 0xffffff; + //pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + return (riva128_mmio_read(addr+0,p) << 0) | (riva128_mmio_read(addr+1,p) << 8) | (riva128_mmio_read(addr+2,p) << 16) | (riva128_mmio_read(addr+3,p) << 24); } static void riva128_mmio_write(uint32_t addr, uint8_t val, void *p) { - addr &= 0xffffff; - //pclog("RIVA 128 MMIO write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - if(addr != 0x6013d4 && addr != 0x6013d5 && addr != 0x6013b4 && addr != 0x6013b5) - { - uint32_t tmp = riva128_mmio_read_l(addr,p); - tmp &= ~(0xff << ((addr & 3) << 3)); - tmp |= val << ((addr & 3) << 3); - riva128_mmio_write_l(addr, tmp, p); - } - else - { - riva128_out(addr & 0xfff, val & 0xff, p); - } + addr &= 0xffffff; + //pclog("RIVA 128 MMIO write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + if(addr != 0x6013d4 && addr != 0x6013d5 && addr != 0x6013b4 && addr != 0x6013b5) + { + uint32_t tmp = riva128_mmio_read_l(addr,p); + tmp &= ~(0xff << ((addr & 3) << 3)); + tmp |= val << ((addr & 3) << 3); + riva128_mmio_write_l(addr, tmp, p); + } + else + { + riva128_out(addr & 0xfff, val & 0xff, p); + } } static void riva128_mmio_write_w(uint32_t addr, uint16_t val, void *p) { - addr &= 0xffffff; - //pclog("RIVA 128 MMIO write %08X %04X %04X:%08X\n", addr, val, CS, cpu_state.pc); - uint32_t tmp = riva128_mmio_read_l(addr,p); - tmp &= ~(0xffff << ((addr & 2) << 4)); - tmp |= val << ((addr & 2) << 4); - riva128_mmio_write_l(addr, tmp, p); + addr &= 0xffffff; + //pclog("RIVA 128 MMIO write %08X %04X %04X:%08X\n", addr, val, CS, cpu_state.pc); + uint32_t tmp = riva128_mmio_read_l(addr,p); + tmp &= ~(0xffff << ((addr & 2) << 4)); + tmp |= val << ((addr & 2) << 4); + riva128_mmio_write_l(addr, tmp, p); } static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - addr &= 0xffffff; + addr &= 0xffffff; - pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x000000 ... 0x000fff: - riva128_pmc_write(addr, val, riva128); - break; - case 0x001000 ... 0x001fff: - riva128_pbus_write(addr, val, riva128); - break; - case 0x002000 ... 0x002fff: - riva128_pfifo_write(addr, val, riva128); - break; - case 0x009000 ... 0x009fff: - riva128_ptimer_write(addr, val, riva128); - break; - case 0x100000 ... 0x100fff: - riva128_pfb_write(addr, val, riva128); - break; - case 0x400000 ... 0x401fff: - riva128_pgraph_write(addr, val, riva128); - break; - case 0x680000 ... 0x680fff: - riva128_pramdac_write(addr, val, riva128); - break; - case 0x800000 ... 0xffffff: - riva128_user_write(addr, val, riva128); - break; - } + switch(addr) + { + case 0x000000 ... 0x000fff: + riva128_pmc_write(addr, val, riva128); + break; + case 0x001000 ... 0x001fff: + riva128_pbus_write(addr, val, riva128); + break; + case 0x002000 ... 0x002fff: + riva128_pfifo_write(addr, val, riva128); + break; + case 0x009000 ... 0x009fff: + riva128_ptimer_write(addr, val, riva128); + break; + case 0x100000 ... 0x100fff: + riva128_pfb_write(addr, val, riva128); + break; + case 0x400000 ... 0x401fff: + riva128_pgraph_write(addr, val, riva128); + break; + case 0x680000 ... 0x680fff: + riva128_pramdac_write(addr, val, riva128); + break; + case 0x800000 ... 0xffffff: + riva128_user_write(addr, val, riva128); + break; + } } static void riva128_ptimer_tick(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - uint64_t time = riva128->ptimer.clock_mul - riva128->ptimer.clock_div; + uint64_t time = riva128->ptimer.clock_mul - riva128->ptimer.clock_div; - time *= 1000; + time *= 1000; - uint64_t tmp = riva128->ptimer.time; - riva128->ptimer.time += time << 5; + uint64_t tmp = riva128->ptimer.time; + riva128->ptimer.time += time << 5; - if((tmp < riva128->ptimer.alarm) && (riva128->ptimer.time >= riva128->ptimer.alarm)) riva128_ptimer_interrupt(0, riva128); + if((tmp < riva128->ptimer.alarm) && (riva128->ptimer.time >= riva128->ptimer.alarm)) riva128_ptimer_interrupt(0, riva128); } static void riva128_mclk_poll(void *p) @@ -1360,9 +1818,9 @@ static void riva128_mclk_poll(void *p) riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - if(riva128->card_id == 0x03) riva128_ptimer_tick(riva128); + if(riva128->card_id == 0x03) riva128_ptimer_tick(riva128); - riva128->mtime += cpuclock / riva128->mfreq; + riva128->mtime += cpuclock / riva128->mfreq; } static void riva128_nvclk_poll(void *p) @@ -1370,596 +1828,689 @@ static void riva128_nvclk_poll(void *p) riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - if(riva128->card_id > 0x40 && riva128->card_id != 0x03) riva128_ptimer_tick(riva128); + if(riva128->card_id > 0x40 && riva128->card_id != 0x03) riva128_ptimer_tick(riva128); - riva128->nvtime += cpuclock / riva128->nvfreq; + riva128->nvtime += cpuclock / riva128->nvfreq; } static uint8_t riva128_rma_in(uint16_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - addr &= 0xff; + addr &= 0xff; - //pclog("RIVA 128 RMA read %04X %04X:%08X\n", addr, CS, cpu_state.pc); + //pclog("RIVA 128 RMA read %04X %04X:%08X\n", addr, CS, cpu_state.pc); - switch(addr) - { - case 0x00: ret = 0x65; break; - case 0x01: ret = 0xd0; break; - case 0x02: ret = 0x16; break; - case 0x03: ret = 0x2b; break; - case 0x08: case 0x09: case 0x0a: case 0x0b: ret = riva128_mmio_read(riva128->rma.addr + (addr & 3), riva128); break; - } + switch(addr) + { + case 0x00: + ret = 0x65; + break; + case 0x01: + ret = 0xd0; + break; + case 0x02: + ret = 0x16; + break; + case 0x03: + ret = 0x2b; + break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + ret = riva128_mmio_read(riva128->rma.addr + (addr & 3), riva128); + break; + } - return ret; + return ret; } static void riva128_rma_out(uint16_t addr, uint8_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - addr &= 0xff; + addr &= 0xff; - //pclog("RIVA 128 RMA write %04X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + //pclog("RIVA 128 RMA write %04X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - switch(addr) - { - case 0x04: - riva128->rma.addr &= ~0xff; - riva128->rma.addr |= val; - break; - case 0x05: - riva128->rma.addr &= ~0xff00; - riva128->rma.addr |= (val << 8); - break; - case 0x06: - riva128->rma.addr &= ~0xff0000; - riva128->rma.addr |= (val << 16); - break; - case 0x07: - riva128->rma.addr &= ~0xff000000; - riva128->rma.addr |= (val << 24); - break; - case 0x08: case 0x0c: case 0x10: case 0x14: - riva128->rma.data &= ~0xff; - riva128->rma.data |= val; - break; - case 0x09: case 0x0d: case 0x11: case 0x15: - riva128->rma.data &= ~0xff00; - riva128->rma.data |= (val << 8); - break; - case 0x0a: case 0x0e: case 0x12: case 0x16: - riva128->rma.data &= ~0xff0000; - riva128->rma.data |= (val << 16); - break; - case 0x0b: case 0x0f: case 0x13: case 0x17: - riva128->rma.data &= ~0xff000000; - riva128->rma.data |= (val << 24); - if(riva128->rma.addr < 0x1000000) riva128_mmio_write_l(riva128->rma.addr & 0xffffff, riva128->rma.data, riva128); - else svga_writel_linear((riva128->rma.addr - 0x1000000), riva128->rma.data, svga); - break; - } + switch(addr) + { + case 0x04: + riva128->rma.addr &= ~0xff; + riva128->rma.addr |= val; + break; + case 0x05: + riva128->rma.addr &= ~0xff00; + riva128->rma.addr |= (val << 8); + break; + case 0x06: + riva128->rma.addr &= ~0xff0000; + riva128->rma.addr |= (val << 16); + break; + case 0x07: + riva128->rma.addr &= ~0xff000000; + riva128->rma.addr |= (val << 24); + break; + case 0x08: + case 0x0c: + case 0x10: + case 0x14: + riva128->rma.data &= ~0xff; + riva128->rma.data |= val; + break; + case 0x09: + case 0x0d: + case 0x11: + case 0x15: + riva128->rma.data &= ~0xff00; + riva128->rma.data |= (val << 8); + break; + case 0x0a: + case 0x0e: + case 0x12: + case 0x16: + riva128->rma.data &= ~0xff0000; + riva128->rma.data |= (val << 16); + break; + case 0x0b: + case 0x0f: + case 0x13: + case 0x17: + riva128->rma.data &= ~0xff000000; + riva128->rma.data |= (val << 24); + if(riva128->rma.addr < 0x1000000) riva128_mmio_write_l(riva128->rma.addr & 0xffffff, riva128->rma.data, riva128); + else svga_writel_linear((riva128->rma.addr - 0x1000000), riva128->rma.data, svga); + break; + } - if(addr & 0x10) riva128->rma.addr+=4; + if(addr & 0x10) riva128->rma.addr+=4; } static uint8_t riva128_in(uint16_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; - switch (addr) - { - case 0x3D0 ... 0x3D3: - //pclog("RIVA 128 RMA BAR Register read %04X %04X:%08X\n", addr, CS, cpu_state.pc); - if(!(riva128->rma.mode & 1)) return ret; - ret = riva128_rma_in(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128); - return ret; - } - - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + switch (addr) + { + case 0x3D0 ... 0x3D3: + //pclog("RIVA 128 RMA BAR Register read %04X %04X:%08X\n", addr, CS, cpu_state.pc); + if(!(riva128->rma.mode & 1)) return ret; + ret = riva128_rma_in(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128); + return ret; + } - // if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, cpu_state.pc); - switch (addr) - { - case 0x3D4: - ret = svga->crtcreg; - break; - case 0x3D5: - switch(svga->crtcreg) - { - case 0x3e: - ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); - break; - default: - ret = svga->crtc[svga->crtcreg]; - break; - } - //if(svga->crtcreg > 0x18) - // pclog("RIVA 128 Extended CRTC read %02X %04X:%08X\n", svga->crtcreg, CS, cpu_state.pc); - break; - default: - ret = svga_in(addr, svga); - break; - } - // if (addr != 0x3da) pclog("%02X\n", ret); - return ret; + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + // if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, cpu_state.pc); + switch (addr) + { + case 0x3D4: + ret = svga->crtcreg; + break; + case 0x3D5: + switch(svga->crtcreg) + { + case 0x3e: + ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); + break; + default: + ret = svga->crtc[svga->crtcreg]; + break; + } + //if(svga->crtcreg > 0x18) + // pclog("RIVA 128 Extended CRTC read %02X %04X:%08X\n", svga->crtcreg, CS, cpu_state.pc); + break; + default: + ret = svga_in(addr, svga); + break; + } + // if (addr != 0x3da) pclog("%02X\n", ret); + return ret; } static void riva128_out(uint16_t addr, uint8_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; - uint8_t old; - - switch(addr) - { - case 0x3D0 ... 0x3D3: - //pclog("RIVA 128 RMA BAR Register write %04X %02x %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128->rma.access_reg[addr & 3] = val; - if(!(riva128->rma.mode & 1)) return; - riva128_rma_out(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128->rma.access_reg[addr & 3], riva128); - return; - } + uint8_t old; - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + switch(addr) + { + case 0x3D0 ... 0x3D3: + //pclog("RIVA 128 RMA BAR Register write %04X %02x %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128->rma.access_reg[addr & 3] = val; + if(!(riva128->rma.mode & 1)) return; + riva128_rma_out(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128->rma.access_reg[addr & 3], riva128); + return; + } - switch(addr) - { - case 0x3D4: - svga->crtcreg = val; - return; - case 0x3D5: - if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) - return; - if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) - val = (svga->crtc[7] & ~0x10) | (val & 0x10); - old = svga->crtc[svga->crtcreg]; - svga->crtc[svga->crtcreg] = val; - switch(svga->crtcreg) - { - case 0x1a: - svga_recalctimings(svga); - break; - case 0x1e: - riva128->read_bank = val; - if (svga->chain4) svga->read_bank = riva128->read_bank << 15; - else svga->read_bank = riva128->read_bank << 13; - break; - case 0x1d: - riva128->write_bank = val; - if (svga->chain4) svga->write_bank = riva128->write_bank << 15; - else svga->write_bank = riva128->write_bank << 13; - break; - case 0x26: - if (!svga->attrff) - svga->attraddr = val & 31; - break; - case 0x19: - case 0x25: - case 0x28: - case 0x2d: - svga_recalctimings(svga); - break; - case 0x38: - riva128->rma.mode = val & 0xf; - break; - case 0x3f: - riva128->i2c.scl = (val & 0x20) ? 1 : 0; - riva128->i2c.sda = (val & 0x10) ? 1 : 0; - break; - } - //if(svga->crtcreg > 0x18) - // pclog("RIVA 128 Extended CRTC write %02X %02x %04X:%08X\n", svga->crtcreg, val, CS, cpu_state.pc); - if (old != val) - { - if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) - { - svga->fullchange = changeframecount; - svga_recalctimings(svga); - } - } - return; - } + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; - svga_out(addr, val, svga); + switch(addr) + { + case 0x3D4: + svga->crtcreg = val; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + switch(svga->crtcreg) + { + case 0x1a: + svga_recalctimings(svga); + break; + case 0x1e: + riva128->read_bank = val; + if (svga->chain4) svga->read_bank = riva128->read_bank << 15; + else svga->read_bank = riva128->read_bank << 13; + break; + case 0x1d: + riva128->write_bank = val; + if (svga->chain4) svga->write_bank = riva128->write_bank << 15; + else svga->write_bank = riva128->write_bank << 13; + break; + case 0x26: + if (!svga->attrff) + svga->attraddr = val & 31; + break; + case 0x19: + case 0x25: + case 0x28: + case 0x2d: + svga_recalctimings(svga); + break; + case 0x38: + riva128->rma.mode = val & 0xf; + break; + case 0x3f: + riva128->i2c.scl = (val & 0x20) ? 1 : 0; + riva128->i2c.sda = (val & 0x10) ? 1 : 0; + break; + } + //if(svga->crtcreg > 0x18) + // pclog("RIVA 128 Extended CRTC write %02X %02x %04X:%08X\n", svga->crtcreg, val, CS, cpu_state.pc); + if (old != val) + { + if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) + { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + return; + } + + svga_out(addr, val, svga); } static uint32_t riva128_ramin_readl(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; - return ret; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; + return ret; } static uint8_t riva128_ramin_readb(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; - ret >>= 24 - ((addr & 3) << 3); - return ret; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; + ret >>= 24 - ((addr & 3) << 3); + return ret; } static uint16_t riva128_ramin_readw(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; - ret >>= 16 - ((addr & 2) << 3); - return ret; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; + ret >>= 16 - ((addr & 2) << 3); + return ret; } static void riva128_ramin_writel(uint32_t addr, uint32_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - riva128->pramin[(addr & 0x1ffffc) >> 2] = val; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + riva128->pramin[(addr & 0x1ffffc) >> 2] = val; } static void riva128_ramin_writeb(uint32_t addr, uint8_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint32_t tmp = riva128_ramin_readl(addr,p); - tmp &= ~(0xff << ((addr & 3) << 3)); - tmp |= val << ((addr & 3) << 3); - riva128_ramin_writel(addr, tmp, p); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint32_t tmp = riva128_ramin_readl(addr,p); + tmp &= ~(0xff << ((addr & 3) << 3)); + tmp |= val << ((addr & 3) << 3); + riva128_ramin_writel(addr, tmp, p); } static void riva128_ramin_writew(uint32_t addr, uint16_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint32_t tmp = riva128_ramin_readl(addr,p); - tmp &= ~(0xffff << ((addr & 2) << 4)); - tmp |= val << ((addr & 2) << 4); - riva128_ramin_writel(addr, tmp, p); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint32_t tmp = riva128_ramin_readl(addr,p); + tmp &= ~(0xffff << ((addr & 2) << 4)); + tmp |= val << ((addr & 2) << 4); + riva128_ramin_writel(addr, tmp, p); } static uint8_t riva128_pci_read(int func, int addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - uint8_t ret = 0; - //pclog("RIVA 128 PCI read %02X %04X:%08X\n", addr, CS, cpu_state.pc); - switch (addr) - { - case 0x00: ret = riva128->vendor_id & 0xff; break; - case 0x01: ret = riva128->vendor_id >> 8; break; + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + uint8_t ret = 0; + //pclog("RIVA 128 PCI read %02X %04X:%08X\n", addr, CS, cpu_state.pc); + switch (addr) + { + case 0x00: + ret = riva128->vendor_id & 0xff; + break; + case 0x01: + ret = riva128->vendor_id >> 8; + break; - case 0x02: ret = riva128->device_id & 0xff; break; - case 0x03: ret = riva128->device_id >> 8; break; + case 0x02: + ret = riva128->device_id & 0xff; + break; + case 0x03: + ret = riva128->device_id >> 8; + break; - case 0x04: ret = riva128->pci_regs[0x04] & 0x37; break; - case 0x05: ret = riva128->pci_regs[0x05] & 0x01; break; + case 0x04: + ret = riva128->pci_regs[0x04] & 0x37; + break; + case 0x05: + ret = riva128->pci_regs[0x05] & 0x01; + break; - case 0x06: ret = 0x20; break; - case 0x07: ret = riva128->pci_regs[0x07] & 0x73; break; + case 0x06: + ret = 0x20; + break; + case 0x07: + ret = riva128->pci_regs[0x07] & 0x73; + break; - case 0x08: ret = 0x01; break; /*Revision ID*/ - case 0x09: ret = 0; break; /*Programming interface*/ + case 0x08: + ret = 0x01; + break; /*Revision ID*/ + case 0x09: + ret = 0; + break; /*Programming interface*/ - case 0x0a: ret = 0x00; break; /*Supports VGA interface*/ - case 0x0b: ret = 0x03; /*output = 3; */break; + case 0x0a: + ret = 0x00; + break; /*Supports VGA interface*/ + case 0x0b: + ret = 0x03; /*output = 3; */break; - case 0x0e: ret = 0x00; break; /*Header type*/ + case 0x0e: + ret = 0x00; + break; /*Header type*/ - case 0x13: - case 0x17: - ret = riva128->pci_regs[addr]; - break; + case 0x13: + case 0x17: + ret = riva128->pci_regs[addr]; + break; - case 0x2c: case 0x2d: case 0x2e: case 0x2f: - ret = riva128->pci_regs[addr]; - //if(CS == 0x0028) output = 3; - break; + case 0x2c: + case 0x2d: + case 0x2e: + case 0x2f: + ret = riva128->pci_regs[addr]; + //if(CS == 0x0028) output = 3; + break; - case 0x30: return riva128->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ - case 0x31: return 0x00; - case 0x32: return riva128->pci_regs[0x32]; - case 0x33: return riva128->pci_regs[0x33]; + case 0x30: + return riva128->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ + case 0x31: + return 0x00; + case 0x32: + return riva128->pci_regs[0x32]; + case 0x33: + return riva128->pci_regs[0x33]; - case 0x34: ret = 0x00; break; + case 0x34: + ret = 0x00; + break; - case 0x3c: ret = riva128->pci_regs[0x3c]; break; + case 0x3c: + ret = riva128->pci_regs[0x3c]; + break; - case 0x3d: ret = 0x01; break; /*INTA*/ + case 0x3d: + ret = 0x01; + break; /*INTA*/ - case 0x3e: ret = 0x03; break; - case 0x3f: ret = 0x01; break; + case 0x3e: + ret = 0x03; + break; + case 0x3f: + ret = 0x01; + break; - } - // pclog("%02X\n", ret); - return ret; + } + // pclog("%02X\n", ret); + return ret; } static void riva128_reenable_svga_mappings(svga_t *svga) { - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ - { - case 0x0: /*128k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); - svga->banked_mask = 0xffff; - break; - case 0x4: /*64k at A0000*/ - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); - svga->banked_mask = 0xffff; - break; - case 0x8: /*32k at B0000*/ - mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); - svga->banked_mask = 0x7fff; - break; - case 0xC: /*32k at B8000*/ - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); - svga->banked_mask = 0x7fff; - break; - } + switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } } static void riva128_pci_write(int func, int addr, uint8_t val, void *p) { - //pclog("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x3d: case 0x3e: case 0x3f: - return; + //pclog("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + switch (addr) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + return; - case PCI_REG_COMMAND: - riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&riva128->mmio_mapping); - mem_mapping_disable(&riva128->linear_mapping); - mem_mapping_disable(&riva128->ramin_mapping); - if (val & PCI_COMMAND_IO) - { - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - } - if (val & PCI_COMMAND_MEM) - { - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - if (!mmio_addr && !linear_addr) - { - riva128_reenable_svga_mappings(svga); - } - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); - mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); - svga->linear_base = linear_addr; - } - } - return; + case PCI_REG_COMMAND: + riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; + io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&riva128->mmio_mapping); + mem_mapping_disable(&riva128->linear_mapping); + mem_mapping_disable(&riva128->ramin_mapping); + if (val & PCI_COMMAND_IO) + { + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + } + if (val & PCI_COMMAND_MEM) + { + uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + if (!mmio_addr && !linear_addr) + { + riva128_reenable_svga_mappings(svga); + } + if (mmio_addr) + { + mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); + } + if (linear_addr) + { + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); + mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); + svga->linear_base = linear_addr; + } + } + return; - case 0x05: - riva128->pci_regs[0x05] = val & 0x01; - return; + case 0x05: + riva128->pci_regs[0x05] = val & 0x01; + return; - case 0x07: - riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); - return; + case 0x07: + riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); + return; - case 0x13: - { - riva128->pci_regs[addr] = val; - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - mem_mapping_disable(&riva128->mmio_mapping); - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - return; - } + case 0x13: + { + riva128->pci_regs[addr] = val; + uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + mem_mapping_disable(&riva128->mmio_mapping); + if (mmio_addr) + { + mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); + } + return; + } - case 0x17: - { - riva128->pci_regs[addr] = val; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - mem_mapping_disable(&riva128->linear_mapping); - mem_mapping_disable(&riva128->ramin_mapping); - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); - mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); - svga->linear_base = linear_addr; - } - return; - } + case 0x17: + { + riva128->pci_regs[addr] = val; + uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + mem_mapping_disable(&riva128->linear_mapping); + mem_mapping_disable(&riva128->ramin_mapping); + if (linear_addr) + { + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0xc00000); + mem_mapping_set_addr(&riva128->ramin_mapping, linear_addr + 0xc00000, 0x200000); + svga->linear_base = linear_addr; + } + return; + } - case 0x30: case 0x32: case 0x33: - riva128->pci_regs[addr] = val; - mem_mapping_disable(&riva128->bios_rom.mapping); - if (riva128->pci_regs[0x30] & 0x01) - { - uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); - // pclog("RIVA 128 bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x8000); - } - return; + case 0x30: + case 0x32: + case 0x33: + riva128->pci_regs[addr] = val; + mem_mapping_disable(&riva128->bios_rom.mapping); + if (riva128->pci_regs[0x30] & 0x01) + { + uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); + // pclog("RIVA 128 bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x8000); + } + return; - case 0x3c: - riva128->pci_regs[0x3c] = val & 0x0f; - return; + case 0x3c: + riva128->pci_regs[0x3c] = val & 0x0f; + return; - case 0x40: case 0x41: case 0x42: case 0x43: - riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f - return; - } + case 0x40: + case 0x41: + case 0x42: + case 0x43: + riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f + return; + } } static void rivatnt_pci_write(int func, int addr, uint8_t val, void *p) { - //pclog("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x3d: case 0x3e: case 0x3f: - return; + //pclog("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + switch (addr) + { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x3d: + case 0x3e: + case 0x3f: + return; - case PCI_REG_COMMAND: - riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; - io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - mem_mapping_disable(&svga->mapping); - mem_mapping_disable(&riva128->mmio_mapping); - mem_mapping_disable(&riva128->linear_mapping); - if (val & PCI_COMMAND_IO) - { - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - } - if (val & PCI_COMMAND_MEM) - { - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - if (!mmio_addr && !linear_addr) - { - riva128_reenable_svga_mappings(svga); - } - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - svga->linear_base = linear_addr; - } - } - return; + case PCI_REG_COMMAND: + riva128->pci_regs[PCI_REG_COMMAND] = val & 0x27; + io_removehandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&riva128->mmio_mapping); + mem_mapping_disable(&riva128->linear_mapping); + if (val & PCI_COMMAND_IO) + { + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + } + if (val & PCI_COMMAND_MEM) + { + uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + if (!mmio_addr && !linear_addr) + { + riva128_reenable_svga_mappings(svga); + } + if (mmio_addr) + { + mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); + } + if (linear_addr) + { + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); + svga->linear_base = linear_addr; + } + } + return; - case 0x05: - riva128->pci_regs[0x05] = val & 0x01; - return; + case 0x05: + riva128->pci_regs[0x05] = val & 0x01; + return; - case 0x07: - riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); - return; + case 0x07: + riva128->pci_regs[0x07] = (riva128->pci_regs[0x07] & 0x8f) | (val & 0x70); + return; - case 0x13: - { - riva128->pci_regs[addr] = val; - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; - mem_mapping_disable(&riva128->mmio_mapping); - if (mmio_addr) - { - mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); - } - return; - } + case 0x13: + { + riva128->pci_regs[addr] = val; + uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + mem_mapping_disable(&riva128->mmio_mapping); + if (mmio_addr) + { + mem_mapping_set_addr(&riva128->mmio_mapping, mmio_addr, 0x1000000); + } + return; + } - case 0x17: - { - riva128->pci_regs[addr] = val; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; - mem_mapping_disable(&riva128->linear_mapping); - if (linear_addr) - { - mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); - svga->linear_base = linear_addr; - } - return; - } + case 0x17: + { + riva128->pci_regs[addr] = val; + uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + mem_mapping_disable(&riva128->linear_mapping); + if (linear_addr) + { + mem_mapping_set_addr(&riva128->linear_mapping, linear_addr, 0x1000000); + svga->linear_base = linear_addr; + } + return; + } - case 0x30: case 0x32: case 0x33: - riva128->pci_regs[addr] = val; - mem_mapping_disable(&riva128->bios_rom.mapping); - if (riva128->pci_regs[0x30] & 0x01) - { - uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); - // pclog("RIVA TNT bios_rom enabled at %08x\n", addr); - mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x10000); - } - return; + case 0x30: + case 0x32: + case 0x33: + riva128->pci_regs[addr] = val; + mem_mapping_disable(&riva128->bios_rom.mapping); + if (riva128->pci_regs[0x30] & 0x01) + { + uint32_t addr = (riva128->pci_regs[0x32] << 16) | (riva128->pci_regs[0x33] << 24); + // pclog("RIVA TNT bios_rom enabled at %08x\n", addr); + mem_mapping_set_addr(&riva128->bios_rom.mapping, addr, 0x10000); + } + return; - case 0x3c: - riva128->pci_regs[0x3c] = val & 0x0f; - return; + case 0x3c: + riva128->pci_regs[0x3c] = val & 0x0f; + return; - case 0x40: case 0x41: case 0x42: case 0x43: - riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f - return; - } + case 0x40: + case 0x41: + case 0x42: + case 0x43: + riva128->pci_regs[addr - 0x14] = val; //0x40-0x43 are ways to write to 0x2c-0x2f + return; + } } static void riva128_recalctimings(svga_t *svga) { - riva128_t *riva128 = (riva128_t *)svga->p; + riva128_t *riva128 = (riva128_t *)svga->p; - svga->ma_latch += (svga->crtc[0x19] & 0x1f) << 16; - svga->rowoffset += (svga->crtc[0x19] & 0xe0) << 3; - if (svga->crtc[0x25] & 0x01) svga->vtotal += 0x400; - if (svga->crtc[0x25] & 0x02) svga->dispend += 0x400; - if (svga->crtc[0x25] & 0x04) svga->vblankstart += 0x400; - if (svga->crtc[0x25] & 0x08) svga->vsyncstart += 0x400; - if (svga->crtc[0x25] & 0x10) svga->htotal += 0x100; - if (svga->crtc[0x2d] & 0x01) svga->hdisp += 0x100; - //The effects of the large screen bit seem to just be doubling the row offset. - //However, these large modes still don't work. Possibly core SVGA bug? It does report 640x2 res after all. - if (!(svga->crtc[0x1a] & 0x04)) svga->rowoffset <<= 1; - switch(svga->crtc[0x28] & 3) - { - case 1: - svga->bpp = 8; - svga->lowres = 0; - svga->render = svga_render_8bpp_highres; - break; - case 2: - svga->bpp = 16; - svga->lowres = 0; - svga->render = svga_render_16bpp_highres; - break; - case 3: - svga->bpp = 32; - svga->lowres = 0; - svga->render = svga_render_32bpp_highres; - break; - } + svga->ma_latch += (svga->crtc[0x19] & 0x1f) << 16; + svga->rowoffset += (svga->crtc[0x19] & 0xe0) << 3; + if (svga->crtc[0x25] & 0x01) svga->vtotal += 0x400; + if (svga->crtc[0x25] & 0x02) svga->dispend += 0x400; + if (svga->crtc[0x25] & 0x04) svga->vblankstart += 0x400; + if (svga->crtc[0x25] & 0x08) svga->vsyncstart += 0x400; + if (svga->crtc[0x25] & 0x10) svga->htotal += 0x100; + if (svga->crtc[0x2d] & 0x01) svga->hdisp += 0x100; + //The effects of the large screen bit seem to just be doubling the row offset. + //However, these large modes still don't work. Possibly core SVGA bug? It does report 640x2 res after all. + if (!(svga->crtc[0x1a] & 0x04)) svga->rowoffset <<= 1; + switch(svga->crtc[0x28] & 3) + { + case 1: + svga->bpp = 8; + svga->lowres = 0; + svga->render = svga_render_8bpp_highres; + break; + case 2: + svga->bpp = 16; + svga->lowres = 0; + svga->render = svga_render_16bpp_highres; + break; + case 3: + svga->bpp = 32; + svga->lowres = 0; + svga->render = svga_render_32bpp_highres; + break; + } - /*if((svga->crtc[0x28] & 3) != 0) - { - if(svga->crtc[0x1a] & 2) svga_set_ramdac_type(svga, RAMDAC_6BIT); - else svga_set_ramdac_type(svga, RAMDAC_8BIT); - } - else svga_set_ramdac_type(svga, RAMDAC_6BIT);*/ - - double freq; + /*if((svga->crtc[0x28] & 3) != 0) + { + if(svga->crtc[0x1a] & 2) svga_set_ramdac_type(svga, RAMDAC_6BIT); + else svga_set_ramdac_type(svga, RAMDAC_8BIT); + } + else svga_set_ramdac_type(svga, RAMDAC_6BIT);*/ - if (((svga->miscout >> 2) & 2) == 2) - { - freq = 13500000.0; + double freq; - if(riva128->pramdac.v_m == 0) freq = 0; - else - { - freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m; - //pclog("RIVA 128 Pixel clock is %f Hz\n", freq); - } - - svga->clock = cpuclock / freq; - } + if (((svga->miscout >> 2) & 2) == 2) + { + freq = 13500000.0; - freq = 13500.0; + if(riva128->pramdac.v_m == 0) freq = 0; + else + { + freq = (freq * riva128->pramdac.v_n) / (1 << riva128->pramdac.v_p) / riva128->pramdac.v_m; + //pclog("RIVA 128 Pixel clock is %f Hz\n", freq); + } + + svga->clock = cpuclock / freq; + } + + freq = 13500.0; if(riva128->pramdac.nv_m == 0) freq = 0; else @@ -1968,9 +2519,9 @@ static void riva128_recalctimings(svga_t *svga) //pclog("RIVA 128 Core clock is %f Hz\n", freq); } - riva128->mfreq = freq; + riva128->mfreq = freq; - freq = 13500.0; + freq = 13500.0; if(riva128->pramdac.m_m == 0) freq = 0; else @@ -1979,606 +2530,612 @@ static void riva128_recalctimings(svga_t *svga) //pclog("RIVA 128 Core clock is %f Hz\n", freq); } - riva128->nvfreq = freq; + riva128->nvfreq = freq; } static void *riva128_init() { - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); + riva128_t *riva128 = malloc(sizeof(riva128_t)); + memset(riva128, 0, sizeof(riva128_t)); - riva128->card_id = 0x03; - riva128->is_nv3t = 0; + riva128->card_id = 0x03; + riva128->is_nv3t = 0; - riva128->vendor_id = 0x12d2; - riva128->device_id = 0x0018; + riva128->vendor_id = 0x12d2; + riva128->device_id = 0x0018; - riva128->memory_size = device_get_config_int("memory"); + riva128->memory_size = device_get_config_int("memory"); - riva128->pgraph.pgraph_speedhack = device_get_config_int("pgraph_speedhack"); + riva128->pgraph.pgraph_speedhack = device_get_config_int("pgraph_speedhack"); - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); + svga_init(&riva128->svga, riva128, riva128->memory_size << 20, + riva128_recalctimings, + riva128_in, riva128_out, + NULL, NULL); - rom_init(&riva128->bios_rom, "roms/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); + rom_init(&riva128->bios_rom, "roms/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&riva128->bios_rom.mapping); - mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128); + mem_mapping_add(&riva128->mmio_mapping, 0, 0, + riva128_mmio_read, + riva128_mmio_read_w, + riva128_mmio_read_l, + riva128_mmio_write, + riva128_mmio_write_w, + riva128_mmio_write_l, + NULL, + 0, + riva128); - mem_mapping_add(&riva128->ramin_mapping, 0, 0, - riva128_ramin_readb, - riva128_ramin_readw, - riva128_ramin_readl, - riva128_ramin_writeb, - riva128_ramin_writew, - riva128_ramin_writel, - NULL, - 0, - riva128); + mem_mapping_add(&riva128->ramin_mapping, 0, 0, + riva128_ramin_readb, + riva128_ramin_readw, + riva128_ramin_readl, + riva128_ramin_writeb, + riva128_ramin_writew, + riva128_ramin_writel, + NULL, + 0, + riva128); - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); + mem_mapping_add(&riva128->linear_mapping, 0, 0, + svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + 0, + &riva128->svga); - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0x02; - riva128->pci_regs[0x2d] = 0x11; - riva128->pci_regs[0x2e] = 0x16; - riva128->pci_regs[0x2f] = 0x10; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; + // riva128->pci_regs[4] = 3; + riva128->pci_regs[4] = 7; + riva128->pci_regs[5] = 0; + riva128->pci_regs[6] = 0; + riva128->pci_regs[7] = 2; - //riva128->pci_regs[0x3c] = 3; + riva128->pci_regs[0x2c] = 0x02; + riva128->pci_regs[0x2d] = 0x11; + riva128->pci_regs[0x2e] = 0x16; + riva128->pci_regs[0x2f] = 0x10; - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - - pci_add(riva128_pci_read, riva128_pci_write, riva128); + riva128->pci_regs[0x30] = 0x00; + riva128->pci_regs[0x32] = 0x0c; + riva128->pci_regs[0x33] = 0x00; - //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; + //riva128->pci_regs[0x3c] = 3; - riva128->pramdac.nv_m = 0x03; - riva128->pramdac.nv_n = 0xc2; - riva128->pramdac.nv_p = 0x0d; + riva128->pmc.intr = 0; + riva128->pbus.intr = 0; + riva128->pfifo.intr = 0; + riva128->pgraph.intr = 0; - timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); - timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + pci_add(riva128_pci_read, riva128_pci_write, riva128); - return riva128; + //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. + riva128->pramdac.m_m = 0x03; + riva128->pramdac.m_n = 0xc2; + riva128->pramdac.m_p = 0x0d; + + riva128->pramdac.nv_m = 0x03; + riva128->pramdac.nv_n = 0xc2; + riva128->pramdac.nv_p = 0x0d; + + timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); + timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + + return riva128; } static void riva128_close(void *p) { - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); + riva128_t *riva128 = (riva128_t *)p; + FILE *f = fopen("vram.dmp", "wb"); + fwrite(riva128->svga.vram, 4 << 20, 1, f); + fclose(f); - svga_close(&riva128->svga); + svga_close(&riva128->svga); - free(riva128); + free(riva128); } static int riva128_available() { - return rom_present("roms/Diamond_V330_rev-e.vbi"); + return rom_present("roms/Diamond_V330_rev-e.vbi"); } static void riva128_speed_changed(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - svga_recalctimings(&riva128->svga); + svga_recalctimings(&riva128->svga); } static void riva128_force_redraw(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - riva128->svga.fullchange = changeframecount; + riva128->svga.fullchange = changeframecount; } static void riva128_add_status_info(char *s, int max_len, void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - svga_add_status_info(s, max_len, &riva128->svga); + svga_add_status_info(s, max_len, &riva128->svga); } static device_config_t riva128_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } }; static device_config_t riva128zx_config[] = { - { - .name = "pgraph_speedhack", - .description = "PGRAPH speedhack", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Off", - .value = 0, - }, - { - .description = "On", - .value = 1, - }, - { - .description = "" - } - }, - //DO NOT TURN THIS OFF YET. THE PGRAPH SPEEDHACK IS CURRENTLY NECESSARY FOR WORKING EMULATION. - .default_int = 1 - }, - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } + { + .name = "pgraph_speedhack", + .description = "PGRAPH speedhack", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Off", + .value = 0, + }, + { + .description = "On", + .value = 1, + }, + { + .description = "" + } + }, + //DO NOT TURN THIS OFF YET. THE PGRAPH SPEEDHACK IS CURRENTLY NECESSARY FOR WORKING EMULATION. + .default_int = 1 + }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "1 MB", + .value = 1 + }, + { + .description = "2 MB", + .value = 2 + }, + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "" + } + }, + .default_int = 4 + }, + { + .type = -1 + } }; device_t riva128_device = { - "nVidia RIVA 128", - 0, - riva128_init, - riva128_close, - riva128_available, - riva128_speed_changed, - riva128_force_redraw, - riva128_add_status_info, - riva128_config + "nVidia RIVA 128", + 0, + riva128_init, + riva128_close, + riva128_available, + riva128_speed_changed, + riva128_force_redraw, + riva128_add_status_info, + riva128_config }; static void *rivatnt_init() { - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); + riva128_t *riva128 = malloc(sizeof(riva128_t)); + memset(riva128, 0, sizeof(riva128_t)); - riva128->card_id = 0x04; - riva128->is_nv3t = 0; + riva128->card_id = 0x04; + riva128->is_nv3t = 0; - riva128->vendor_id = 0x10de; - riva128->device_id = 0x0020; + riva128->vendor_id = 0x10de; + riva128->device_id = 0x0020; - riva128->memory_size = device_get_config_int("memory"); + riva128->memory_size = device_get_config_int("memory"); - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); + svga_init(&riva128->svga, riva128, riva128->memory_size << 20, + riva128_recalctimings, + riva128_in, riva128_out, + NULL, NULL); - rom_init(&riva128->bios_rom, "roms/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); + rom_init(&riva128->bios_rom, "roms/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&riva128->bios_rom.mapping); - mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128); - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); + mem_mapping_add(&riva128->mmio_mapping, 0, 0, + riva128_mmio_read, + riva128_mmio_read_w, + riva128_mmio_read_l, + riva128_mmio_write, + riva128_mmio_write_w, + riva128_mmio_write_l, + NULL, + 0, + riva128); + mem_mapping_add(&riva128->linear_mapping, 0, 0, + svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + 0, + &riva128->svga); - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0x02; - riva128->pci_regs[0x2d] = 0x11; - riva128->pci_regs[0x2e] = 0x16; - riva128->pci_regs[0x2f] = 0x10; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; + // riva128->pci_regs[4] = 3; + riva128->pci_regs[4] = 7; + riva128->pci_regs[5] = 0; + riva128->pci_regs[6] = 0; + riva128->pci_regs[7] = 2; - //riva128->pci_regs[0x3c] = 3; + riva128->pci_regs[0x2c] = 0x02; + riva128->pci_regs[0x2d] = 0x11; + riva128->pci_regs[0x2e] = 0x16; + riva128->pci_regs[0x2f] = 0x10; - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - - pci_add(riva128_pci_read, rivatnt_pci_write, riva128); + riva128->pci_regs[0x30] = 0x00; + riva128->pci_regs[0x32] = 0x0c; + riva128->pci_regs[0x33] = 0x00; - //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; + //riva128->pci_regs[0x3c] = 3; - riva128->pramdac.nv_m = 0x03; - riva128->pramdac.nv_n = 0xc2; - riva128->pramdac.nv_p = 0x0d; + riva128->pmc.intr = 0; + riva128->pbus.intr = 0; + riva128->pfifo.intr = 0; + riva128->pgraph.intr = 0; - timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); - timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + pci_add(riva128_pci_read, rivatnt_pci_write, riva128); - return riva128; + //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. + riva128->pramdac.m_m = 0x03; + riva128->pramdac.m_n = 0xc2; + riva128->pramdac.m_p = 0x0d; + + riva128->pramdac.nv_m = 0x03; + riva128->pramdac.nv_n = 0xc2; + riva128->pramdac.nv_p = 0x0d; + + timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); + timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + + return riva128; } static void rivatnt_close(void *p) { - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); + riva128_t *riva128 = (riva128_t *)p; + FILE *f = fopen("vram.dmp", "wb"); + fwrite(riva128->svga.vram, 4 << 20, 1, f); + fclose(f); - svga_close(&riva128->svga); + svga_close(&riva128->svga); - free(riva128); + free(riva128); } static int rivatnt_available() { - return rom_present("roms/NV4_diamond_revB.rom"); + return rom_present("roms/NV4_diamond_revB.rom"); } static void rivatnt_speed_changed(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - svga_recalctimings(&riva128->svga); + svga_recalctimings(&riva128->svga); } static void rivatnt_force_redraw(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - riva128->svga.fullchange = changeframecount; + riva128->svga.fullchange = changeframecount; } static void rivatnt_add_status_info(char *s, int max_len, void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - svga_add_status_info(s, max_len, &riva128->svga); + svga_add_status_info(s, max_len, &riva128->svga); } static device_config_t rivatnt_config[] = { - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "" - } - }, - .default_int = 16 - }, - { - .type = -1 - } + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "" + } + }, + .default_int = 16 + }, + { + .type = -1 + } }; device_t rivatnt_device = { - "nVidia RIVA TNT", - 0, - rivatnt_init, - rivatnt_close, - rivatnt_available, - rivatnt_speed_changed, - rivatnt_force_redraw, - rivatnt_add_status_info, - rivatnt_config + "nVidia RIVA TNT", + 0, + rivatnt_init, + rivatnt_close, + rivatnt_available, + rivatnt_speed_changed, + rivatnt_force_redraw, + rivatnt_add_status_info, + rivatnt_config }; static void *rivatnt2_init() { - riva128_t *riva128 = malloc(sizeof(riva128_t)); - memset(riva128, 0, sizeof(riva128_t)); + riva128_t *riva128 = malloc(sizeof(riva128_t)); + memset(riva128, 0, sizeof(riva128_t)); - riva128->card_id = 0x05; - riva128->is_nv3t = 0; + riva128->card_id = 0x05; + riva128->is_nv3t = 0; - int model = device_get_config_int("model"); + int model = device_get_config_int("model"); - riva128->vendor_id = 0x10de; - riva128->device_id = ((model > 1) ? 0x0029 : 0x0028); + riva128->vendor_id = 0x10de; + riva128->device_id = ((model > 1) ? 0x0029 : 0x0028); - riva128->memory_size = device_get_config_int("memory"); + riva128->memory_size = device_get_config_int("memory"); - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, - riva128_recalctimings, - riva128_in, riva128_out, - NULL, NULL); + svga_init(&riva128->svga, riva128, riva128->memory_size << 20, + riva128_recalctimings, + riva128_in, riva128_out, + NULL, NULL); - switch(model) - { - case 0: rom_init(&riva128->bios_rom, "roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; - case 1: rom_init(&riva128->bios_rom, "roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; - case 2: rom_init(&riva128->bios_rom, "roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; - } - if (PCI) - mem_mapping_disable(&riva128->bios_rom.mapping); + switch(model) + { + case 0: + rom_init(&riva128->bios_rom, "roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + break; + case 1: + rom_init(&riva128->bios_rom, "roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + break; + case 2: + rom_init(&riva128->bios_rom, "roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + break; + } + if (PCI) + mem_mapping_disable(&riva128->bios_rom.mapping); - mem_mapping_add(&riva128->mmio_mapping, 0, 0, - riva128_mmio_read, - riva128_mmio_read_w, - riva128_mmio_read_l, - riva128_mmio_write, - riva128_mmio_write_w, - riva128_mmio_write_l, - NULL, - 0, - riva128); - mem_mapping_add(&riva128->linear_mapping, 0, 0, - svga_read_linear, - svga_readw_linear, - svga_readl_linear, - svga_write_linear, - svga_writew_linear, - svga_writel_linear, - NULL, - 0, - &riva128->svga); + mem_mapping_add(&riva128->mmio_mapping, 0, 0, + riva128_mmio_read, + riva128_mmio_read_w, + riva128_mmio_read_l, + riva128_mmio_write, + riva128_mmio_write_w, + riva128_mmio_write_l, + NULL, + 0, + riva128); + mem_mapping_add(&riva128->linear_mapping, 0, 0, + svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + 0, + &riva128->svga); - io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); + io_sethandler(0x03c0, 0x0020, riva128_in, NULL, NULL, riva128_out, NULL, NULL, riva128); - // riva128->pci_regs[4] = 3; - riva128->pci_regs[4] = 7; - riva128->pci_regs[5] = 0; - riva128->pci_regs[6] = 0; - riva128->pci_regs[7] = 2; - - riva128->pci_regs[0x2c] = 0x02; - riva128->pci_regs[0x2d] = 0x11; - riva128->pci_regs[0x2e] = 0x16; - riva128->pci_regs[0x2f] = 0x10; - - riva128->pci_regs[0x30] = 0x00; - riva128->pci_regs[0x32] = 0x0c; - riva128->pci_regs[0x33] = 0x00; + // riva128->pci_regs[4] = 3; + riva128->pci_regs[4] = 7; + riva128->pci_regs[5] = 0; + riva128->pci_regs[6] = 0; + riva128->pci_regs[7] = 2; - //riva128->pci_regs[0x3c] = 3; + riva128->pci_regs[0x2c] = 0x02; + riva128->pci_regs[0x2d] = 0x11; + riva128->pci_regs[0x2e] = 0x16; + riva128->pci_regs[0x2f] = 0x10; - riva128->pmc.intr = 0; - riva128->pbus.intr = 0; - riva128->pfifo.intr = 0; - riva128->pgraph.intr = 0; - - pci_add(riva128_pci_read, rivatnt_pci_write, riva128); + riva128->pci_regs[0x30] = 0x00; + riva128->pci_regs[0x32] = 0x0c; + riva128->pci_regs[0x33] = 0x00; - //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. - riva128->pramdac.m_m = 0x03; - riva128->pramdac.m_n = 0xc2; - riva128->pramdac.m_p = 0x0d; + //riva128->pci_regs[0x3c] = 3; - riva128->pramdac.nv_m = 0x03; - riva128->pramdac.nv_n = 0xc2; - riva128->pramdac.nv_p = 0x0d; + riva128->pmc.intr = 0; + riva128->pbus.intr = 0; + riva128->pfifo.intr = 0; + riva128->pgraph.intr = 0; - timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); - timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + pci_add(riva128_pci_read, rivatnt_pci_write, riva128); - return riva128; + //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. + riva128->pramdac.m_m = 0x03; + riva128->pramdac.m_n = 0xc2; + riva128->pramdac.m_p = 0x0d; + + riva128->pramdac.nv_m = 0x03; + riva128->pramdac.nv_n = 0xc2; + riva128->pramdac.nv_p = 0x0d; + + timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); + timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + + return riva128; } static void rivatnt2_close(void *p) { - riva128_t *riva128 = (riva128_t *)p; - FILE *f = fopen("vram.dmp", "wb"); - fwrite(riva128->svga.vram, 4 << 20, 1, f); - fclose(f); + riva128_t *riva128 = (riva128_t *)p; + FILE *f = fopen("vram.dmp", "wb"); + fwrite(riva128->svga.vram, 4 << 20, 1, f); + fclose(f); - svga_close(&riva128->svga); + svga_close(&riva128->svga); - free(riva128); + free(riva128); } static int rivatnt2_available() { - return rom_present("roms/NV5diamond.bin") || rom_present("roms/inno3d64bit.BIN") || rom_present("roms/creative.BIN"); + return rom_present("roms/NV5diamond.bin") || rom_present("roms/inno3d64bit.BIN") || rom_present("roms/creative.BIN"); } static void rivatnt2_speed_changed(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - svga_recalctimings(&riva128->svga); + svga_recalctimings(&riva128->svga); } static void rivatnt2_force_redraw(void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - riva128->svga.fullchange = changeframecount; + riva128->svga.fullchange = changeframecount; } static void rivatnt2_add_status_info(char *s, int max_len, void *p) { - riva128_t *riva128 = (riva128_t *)p; + riva128_t *riva128 = (riva128_t *)p; - svga_add_status_info(s, max_len, &riva128->svga); + svga_add_status_info(s, max_len, &riva128->svga); } static device_config_t rivatnt2_config[] = { - { - .name = "model", - .description = "Card model", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Vanilla TNT2", - .value = 0, - }, - { - .description = "TNT2 Pro", - .value = 1, - }, - { - .description = "TNT2 Ultra", - .value = 2, - }, - }, - .default_int = 0 - }, - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "4 MB", - .value = 4 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "16 MB", - .value = 16 - }, - { - .description = "32 MB", - .value = 32 - }, - { - .description = "" - } - }, - .default_int = 32 - }, - { - .type = -1 - } + { + .name = "model", + .description = "Card model", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Vanilla TNT2", + .value = 0, + }, + { + .description = "TNT2 Pro", + .value = 1, + }, + { + .description = "TNT2 Ultra", + .value = 2, + }, + }, + .default_int = 0 + }, + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "4 MB", + .value = 4 + }, + { + .description = "8 MB", + .value = 8 + }, + { + .description = "16 MB", + .value = 16 + }, + { + .description = "32 MB", + .value = 32 + }, + { + .description = "" + } + }, + .default_int = 32 + }, + { + .type = -1 + } }; device_t rivatnt2_device = { - "nVidia RIVA TNT2", - 0, - rivatnt2_init, - rivatnt2_close, - rivatnt2_available, - rivatnt2_speed_changed, - rivatnt2_force_redraw, - rivatnt2_add_status_info, - rivatnt2_config + "nVidia RIVA TNT2", + 0, + rivatnt2_init, + rivatnt2_close, + rivatnt2_available, + rivatnt2_speed_changed, + rivatnt2_force_redraw, + rivatnt2_add_status_info, + rivatnt2_config }; From 6b86549b7ec92a3dd7c61d0b83f4ea4dfb5dcadd Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 19:41:42 +0100 Subject: [PATCH 016/392] Modified empty IDE channel handling, should hopefully reduce problems; Fixed several ATAPI CD-ROM bugs; Added some missing CPL override checks to the MMU translate functions; Tertiary and quaternary IDE controllers are now automatically disabled if not a single device is attached to them; Changed sleep time on compile from 10 seconds to 2 seconds. --- src/Makefile.mingw | 4 +- src/buslogic.c | 1 + src/cdrom.c | 62 +++++++++++++----- src/ide.c | 159 ++++++++++++++++++++++++++++----------------- src/mem.c | 138 +++++++++++++++++++-------------------- src/pc.rc | 26 ++++++++ src/resources.h | 12 ++++ src/win.c | 24 +++++++ 8 files changed, 280 insertions(+), 146 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index f7032d7d0..371cb1713 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) - sleep 10 + sleep 2 strip "86Box.exe" - sleep 10 + sleep 2 all : 86Box.exe diff --git a/src/buslogic.c b/src/buslogic.c index f0948bc4c..c7d121606 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1706,6 +1706,7 @@ void *BuslogicInit() io_sethandler(scsi_base, 0x0004, BuslogicRead, NULL, NULL, BuslogicWrite, NULL, NULL, Buslogic); + BuslogicLog("Building CD-ROM map...\n"); build_scsi_cdrom_map(); if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id)) diff --git a/src/cdrom.c b/src/cdrom.c index bf5d7da7c..3e9e30d22 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -304,6 +304,7 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type) cdrom[id].sense[0] = 0xf0; cdrom[id].sense[7] = 10; cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : 3; + cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode); if (!cdrom_drives[id].bus_type) { cdrom_set_signature(id); @@ -772,7 +773,26 @@ static void cdrom_command_common(uint8_t id) cdrom[id].status = BUSY_STAT; cdrom[id].phase = 1; cdrom[id].pos = 0; - cdrom[id].callback = 60 * CDROM_TIME; + if (cdrom[id].packet_status == CDROM_PHASE_COMPLETE) + { + cdrom[id].callback = 20 * CDROM_TIME; + } + else if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) + { + if (cdrom[id].current_cdb[0] == 0x42) + { + cdrom_log("CD-ROM %i: READ SUBCHANNEL\n"); + cdrom[id].callback = 1000 * CDROM_TIME; + } + else + { + cdrom[id].callback = 60 * CDROM_TIME; + } + } + else + { + cdrom[id].callback = 60 * CDROM_TIME; + } } static void cdrom_command_complete(uint8_t id) @@ -807,6 +827,15 @@ static void cdrom_command_write_dma(uint8_t id) cdrom_command_common(id); } +static int cdrom_request_length_is_zero(uint8_t id) +{ + if ((cdrom[id].request_length == 0) && !cdrom_drives[id].bus_type) + { + return 1; + } + return 0; +} + static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) { cdrom_log("CD-ROM %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, cdrom[id].current_cdb[0], len, block_len, alloc_len, direction, cdrom[id].request_length); @@ -818,7 +847,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al len = alloc_len; } } - if ((len == 0) || (cdrom_current_mode(id) == 0)) + if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0)) { cdrom_command_complete(id); } @@ -828,14 +857,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (cdrom_drives[id].bus_type) { - if (cdrom_is_media_access(id)) - { - SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len; - } - else - { - SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len; - } + SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len; } if (direction == 0) { @@ -1150,7 +1172,7 @@ int cdrom_read_blocks(uint8_t id, int *len, int first_batch) if (!cdrom[id].sector_len) { cdrom_command_complete(id); - return 0; + return -1; } cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos); @@ -1754,7 +1776,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } ret = cdrom_read_blocks(id, &alloc_length, 1); - if (!ret) + if (ret <= 0) { return; } @@ -2465,13 +2487,20 @@ int cdrom_block_check(uint8_t id) if (cdrom_is_media_access(id)) { /* We have finished the current block. */ - cdrom_log("CD-ROM %i: %i bytes total read, %i bytes all total\n", cdrom[id].total_read, cdrom[id].all_blocks_total); + cdrom_log("CD-ROM %i: %i bytes total read, %i bytes all total\n", id, cdrom[id].total_read, cdrom[id].all_blocks_total); if (cdrom[id].total_read >= cdrom[id].all_blocks_total) { cdrom_log("CD-ROM %i: %i bytes read, current block finished\n", id, cdrom[id].total_read); /* Read the next block. */ ret = cdrom_read_blocks(id, &alloc_length, 0); - if (!ret) + if (ret == -1) + { + /* Return value is -1 - there are no further blocks to read. */ + cdrom_log("CD-ROM %i: %i bytes read, no further blocks to read\n", id, cdrom[id].total_read); + cdrom[id].status = BUSY_STAT; + return 1; + } + else if (ret == 0) { /* Return value is 0 - an error has occurred. */ cdrom_log("CD-ROM %i: %i bytes read, error while reading blocks\n", id, cdrom[id].total_read); @@ -2746,6 +2775,7 @@ int cdrom_phase_callback(uint8_t id) // cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); cdrom[id].status = READY_STAT; cdrom[id].phase = 3; + cdrom[id].packet_status = 0xFF; return 1; case CDROM_PHASE_DATA_OUT: // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); @@ -2809,7 +2839,7 @@ uint8_t cdrom_read(uint8_t channel) /* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */ if (ret) { - cdrom_log("CD-ROM %i: Return value is 1\n", id); + cdrom_log("CD-ROM %i: Return value is 1 (request length: %i)\n", id, cdrom[id].request_length); if (cdrom[id].request_pos >= cdrom[id].request_length) { /* Time for a DRQ. */ @@ -2825,7 +2855,7 @@ uint8_t cdrom_read(uint8_t channel) { cdrom_log("CD-ROM %i: Return value is 0\n", id); } - cdrom_log("CD-ROM %i: Returning: %04X (buffer position: %i, request position: %i, total: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos, cdrom[id].total_read); + cdrom_log("CD-ROM %i: Returning: %02X (buffer position: %i, request position: %i, total: %i)\n", id, temp, cdrom[id].pos, cdrom[id].request_pos, cdrom[id].total_read); return temp; } else diff --git a/src/ide.c b/src/ide.c index 4d24a1314..c0d98f3a6 100644 --- a/src/ide.c +++ b/src/ide.c @@ -59,8 +59,10 @@ #define WIN_READ_DMA 0xC8 #define WIN_WRITE_DMA 0xCA #define WIN_STANDBYNOW1 0xE0 +#define WIN_IDLENOW1 0xE1 #define WIN_SETIDLE1 0xE3 #define WIN_CHECKPOWERMODE1 0xE5 +#define WIN_SLEEP1 0xE6 #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ #define WIN_SET_FEATURES 0xEF #define WIN_READ_NATIVE_MAX 0xF8 @@ -373,8 +375,11 @@ static void ide_identify(IDE *ide) // ide->buffer[63] = 7; /*Multiword DMA*/ if (ide->board < 2) { + ide->buffer[53] = 2; ide->buffer[62] = ide->dma_identify_data[0]; ide->buffer[63] = ide->dma_identify_data[1]; + ide->buffer[65] = 150; + ide->buffer[66] = 150; ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ ide->buffer[88] = ide->dma_identify_data[2]; } @@ -398,14 +403,19 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ + ide->buffer[73] = 6; + ide->buffer[73] = 9; if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) { ide->buffer[49] |= 0x100; /* DMA supported */ ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[53] = 2; ide->buffer[62] = ide->dma_identify_data[0]; ide->buffer[63] = ide->dma_identify_data[1]; - ide->buffer[88] = ide->dma_identify_data[2]; + ide->buffer[65] = 150; + ide->buffer[66] = 150; + // ide->buffer[88] = ide->dma_identify_data[2]; } } @@ -580,20 +590,28 @@ int ide_cdrom_is_pio_only(IDE *ide) int ide_set_features(IDE *ide) { uint8_t cdrom_id = cur_ide[ide->board]; + + uint8_t features = 0; + + uint8_t sf_data = 0; uint8_t val = 0; if (ide_drive_is_cdrom(ide)) { - val = cdrom[cdrom_id].phase & 7; + features = cdrom[cdrom_id].features; + sf_data = cdrom[cdrom_id].phase; } else { - val = ide->secount & 7; + features = ide->cylprecomp; + sf_data = ide->secount; } + + val = sf_data & 7; if (ide->type == IDE_NONE) return 0; - switch(ide->cylprecomp) + switch(features) { case 0x02: case 0x82: @@ -612,17 +630,21 @@ int ide_set_features(IDE *ide) case 0xc2: return 1; case 0x03: +#if 0 if (ide->type == IDE_CDROM) { return 0; } - switch(ide->secount >> 3) +#endif + switch(sf_data >> 3) { case 0: - case 1: ide->dma_identify_data[0] = ide->dma_identify_data[1] = 7; ide->dma_identify_data[2] = 0x3f; break; + case 1: + /* We do not (yet) emulate flow control, so return with error if this is attempted. */ + return 0; case 2: if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) { @@ -722,6 +744,9 @@ void resetide(void) { cur_ide[d] = d << 1; } + + ide_ter_disable_cond(); + ide_qua_disable_cond(); } int idetimes = 0; @@ -741,9 +766,6 @@ void ide_write_data(int ide_board, uint8_t val) #endif // ide_log("Write IDEw %04X\n",val); - idebufferb[ide->pos] = val; - ide->pos++; - if (ide->command == WIN_PACKETCMD) { if (!ide_drive_is_cdrom(ide)) @@ -761,6 +783,9 @@ void ide_write_data(int ide_board, uint8_t val) } else { + idebufferb[ide->pos] = val; + ide->pos++; + if (ide->pos>=512) { ide->pos=0; @@ -962,19 +987,31 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case 0x1F7: /* Command register */ if (ide->type == IDE_NONE) { - ide->error=1; - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].error = 1; - } return; } -#if 0 - if (ide_drive_is_cdrom(ide_other)) + if (ide_drive_is_cdrom(ide)) { +#if 0 ide_log("Write CD-ROM ATA command: %02X\n", val); - } #endif + switch(val) + { + case WIN_SRST: + case WIN_CHECKPOWERMODE1: + case WIN_DRIVE_DIAGNOSTICS: + case WIN_IDLENOW1: + case WIN_PACKETCMD: + case WIN_PIDENTIFY: + case WIN_IDENTIFY: + case WIN_SET_FEATURES: + case WIN_SLEEP1: + case WIN_STANDBYNOW1: + break; + default: + val = 0xFF; + break; + } + } ide_irq_lower(ide); ide->command=val; @@ -1146,8 +1183,10 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ case WIN_NOP: case WIN_STANDBYNOW1: + case WIN_IDLENOW1: case WIN_SETIDLE1: /* Idle */ case WIN_CHECKPOWERMODE1: + case WIN_SLEEP1: if (ide_drive_is_cdrom(ide)) { cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; @@ -1260,10 +1299,6 @@ uint8_t ide_read_data(int ide_board) uint8_t *idebufferb = (uint8_t *) ide->buffer; - temp = idebufferb[ide->pos]; - - ide->pos++; - if (ide->command == WIN_PACKETCMD) { if (!ide_drive_is_cdrom(ide)) @@ -1277,6 +1312,11 @@ uint8_t ide_read_data(int ide_board) idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; } } + else + { + temp = idebufferb[ide->pos]; + ide->pos++; + } if (ide->pos>=512 && ide->command != WIN_PACKETCMD) { ide->pos=0; @@ -1324,19 +1364,6 @@ uint8_t readide(int ide_board, uint16_t addr) addr|=0x90; addr&=0xFFF7; - if (ide->type == IDE_NONE && (addr == 0x1f0 || addr == 0x1f7 || addr == 0x3f6)) - { - if ((addr == 0x1f7) || (addr == 0x3f6)) - { - /* This is apparently required for an empty ID channel. */ - ide_log("Reading port %04X on empty IDE channel, returning 0x30...\n", addr); - // return 0x20; - return 0x20 | DSC_STAT; - } - ide_log("Reading port %04X on empty IDE channel, returning zero...\n", addr); - return 0; - } - switch (addr) { case 0x1F0: /* Data */ @@ -1349,7 +1376,7 @@ uint8_t readide(int ide_board, uint16_t addr) case 0x1F1: /* Error */ if (ide->type == IDE_NONE) { - temp = 1; + temp = 0; } else { @@ -1378,32 +1405,18 @@ uint8_t readide(int ide_board, uint16_t addr) 0 1 0 Data from host 1 0 1 Status. */ case 0x1F2: /* Sector count */ - if (ide->type == IDE_NONE) + if (ide_drive_is_cdrom(ide)) { - temp = 1; + temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase; } else { - if (ide_drive_is_cdrom(ide)) - { - temp = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase; - } - else - { - temp = ide->secount; - } + temp = ide->secount; } break; case 0x1F3: /* Sector */ - if (ide->type == IDE_NONE) - { - temp = 1; - } - else - { - temp = (uint8_t)ide->sector; - } + temp = (uint8_t)ide->sector; break; case 0x1F4: /* Cylinder low */ @@ -1443,7 +1456,7 @@ uint8_t readide(int ide_board, uint16_t addr) break; case 0x1F6: /* Drive/Head */ - if (ide->type == IDE_NONE) + if (ide_drive_is_cdrom(ide)) { temp = (uint8_t)(((cur_ide[ide_board] & 1) ? 0x10 : 0) | 0xa0); } @@ -1457,6 +1470,10 @@ uint8_t readide(int ide_board, uint16_t addr) DF (drive fault). */ case 0x1F7: /* Status */ ide_irq_lower(ide); + if (ide->type == IDE_NONE) + { + return 0; + } if (ide_drive_is_cdrom(ide)) { temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); @@ -1471,8 +1488,7 @@ uint8_t readide(int ide_board, uint16_t addr) case 0x3F6: /* Alternate Status */ if (ide->type == IDE_NONE) { - temp = DSC_STAT; - break; + return 0; } if (ide_drive_is_cdrom(ide)) { @@ -1614,6 +1630,7 @@ void callbackide(int ide_board) } case WIN_NOP: case WIN_STANDBYNOW1: + case WIN_IDLENOW1: case WIN_SETIDLE1: if (ide_drive_is_cdrom(ide)) { @@ -1627,9 +1644,11 @@ void callbackide(int ide_board) return; case WIN_CHECKPOWERMODE1: + case WIN_SLEEP1: if (ide_drive_is_cdrom(ide)) { - goto abort_cmd; + cdrom[cdrom_id].phase = 0xFF; + cdrom[cdrom_id].status = READY_STAT | DSC_STAT; } ide->secount = 0xFF; ide->atastat = READY_STAT | DSC_STAT; @@ -1854,10 +1873,13 @@ void callbackide(int ide_board) if (ide_drive_is_cdrom(ide)) { cdrom[cdrom_id].status = 0; + cdrom[cdrom_id].error = 1; + ide_irq_raise(ide); } else { ide->atastat = READY_STAT | DSC_STAT; + ide->error = 1; ide_irq_raise(ide); } return; @@ -1930,6 +1952,8 @@ void callbackide(int ide_board) if (ide->type == IDE_NONE) { ide_set_signature(ide); + cdrom[cdrom_id].status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[cdrom_id].pos = 0; goto abort_cmd; } if (ide_drive_is_cdrom(ide)) @@ -1959,7 +1983,10 @@ void callbackide(int ide_board) idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; ide_log("IDE callback now: %i\n", idecallback[ide_board]); return; - } + + case 0xFF: + goto abort_cmd; + } abort_cmd: ide->command = 0; @@ -2141,6 +2168,14 @@ void ide_ter_disable() io_removehandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); } +void ide_ter_disable_cond() +{ + if ((ide_drives[4].type == IDE_NONE) && (ide_drives[5].type == IDE_NONE)) + { + ide_ter_disable(); + } +} + void ide_ter_init() { ide_ter_enable(); @@ -2154,6 +2189,14 @@ void ide_qua_enable() io_sethandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); } +void ide_qua_disable_cond() +{ + if ((ide_drives[6].type == IDE_NONE) && (ide_drives[7].type == IDE_NONE)) + { + ide_qua_disable(); + } +} + void ide_qua_disable() { io_removehandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); diff --git a/src/mem.c b/src/mem.c index acc1280cf..8c16fd33e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -948,95 +948,93 @@ int pctrans=0; extern uint32_t testr[9]; +int mem_cpl3_check() +{ + if ((CPL == 3) && !cpl_override) + { + return 1; + } + return 0; +} + +/* The relevant page table entry bits are: + 0 = P (1 = page is present, 0 = page is not present); + 1 = R/W (0 = read-only for user, 1 = writable for user); + 2 = U/S (0 = system page, 1 = user page). */ uint32_t mmutranslatereal(uint32_t addr, int rw) { - uint32_t addr2; - uint32_t temp,temp2,temp3; - - if (cpu_state.abrt) - { -// pclog("Translate recursive abort\n"); - return -1; - } -/* if ((addr&~0xFFFFF)==0x77f00000) pclog("Do translate %08X %i %08X %08X\n",addr,rw,EAX,cpu_state.pc); - if (addr==0x77f61000) output = 3; - if (addr==0x77f62000) { dumpregs(); exit(-1); } - if (addr==0x77f9a000) { dumpregs(); exit(-1); }*/ - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp=temp2=((uint32_t *)ram)[addr2>>2]; -// if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, temp); - if (!(temp&1))// || (CPL==3 && !(temp&4) && !cpl_override) || (rw && !(temp&2) && (CPL==3 || cr0&WP_FLAG))) + uint32_t pde_addr; + uint32_t section_flags; + uint32_t temp_section_flags; + uint32_t masked_flags; + + if (cpu_state.abrt) + { + // pclog("Translate recursive abort\n"); + return -1; + } + pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2]; + // if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, section_flags); + if (!(section_flags & 1))// || !(section_flags & 4) && mem_cpl3_check()) || (rw && !(section_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))) + { + // if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,cpu_state.pc,CPL,rw); + + cr2 = addr; + section_flags &= 1; + if (CPL==3) section_flags |= 4; + if (rw) section_flags |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = section_flags; + return -1; + } + section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC))>>2]; + masked_flags = section_flags & temp_section_flags; + // if (output == 3) pclog("Do translate %08X %08X\n", section_flags, temp3); + if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))) { -// if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,cpu_state.pc,CPL,rw); + // if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,section_flags,opcode,opcode2,frame,rmdat32, CS,cpu_state.pc,SS,ESP,ins,CPL,rw); - cr2=addr; - temp&=1; - if (CPL==3) temp|=4; - if (rw) temp|=2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; -/* if (addr == 0x70046D) - { - dumpregs(); - exit(-1); - }*/ - return -1; - } - temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; - temp3=temp&temp2; -// if (output == 3) pclog("Do translate %08X %08X\n", temp, temp3); - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) - { -// if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,temp,opcode,opcode2,frame,rmdat32, CS,cpu_state.pc,SS,ESP,ins,CPL,rw); + cr2 = addr; + section_flags &= 1; + if (CPL==3) section_flags |= 4; + if (rw) section_flags |= 2; + cpu_state.abrt = ABRT_PF; + abrt_error = section_flags; + // pclog("%04X\n",cpu_state.abrt); + return -1; + } + mmu_perm = section_flags & 4; + ((uint32_t *)ram)[pde_addr >> 2] |= 0x20; + ((uint32_t *)ram)[((temp_section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC)) >> 2] |= (rw ? 0x60 : 0x20); + // /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),section_flags,cs,cpu_state.pc,EDI); -// dumpregs(); -// exit(-1); -// if (addr == 0x815F6E90) output = 3; -/* if (addr == 0x10ADE020) output = 3;*/ -/* if (addr == 0x10150010 && !nopageerrors) - { - dumpregs(); - exit(-1); - }*/ - - cr2=addr; - temp&=1; - if (CPL==3) temp|=4; - if (rw) temp|=2; - cpu_state.abrt = ABRT_PF; - abrt_error = temp; -// pclog("%04X\n",cpu_state.abrt); - return -1; - } - mmu_perm=temp&4; - ((uint32_t *)ram)[addr2>>2]|=0x20; - ((uint32_t *)ram)[((temp2&~0xFFF)+((addr>>10)&0xFFC))>>2]|=(rw?0x60:0x20); -// /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),temp,cs,cpu_state.pc,EDI); - - return (temp&~0xFFF)+(addr&0xFFF); + return (section_flags & ~0xFFF) + (addr & 0xFFF); } uint32_t mmutranslate_noabrt(uint32_t addr, int rw) { - uint32_t addr2; - uint32_t temp,temp2,temp3; + uint32_t pde_addr; + uint32_t section_flags; + uint32_t temp_section_flags; + uint32_t masked_flags; if (cpu_state.abrt) return -1; - addr2 = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - temp=temp2=((uint32_t *)ram)[addr2>>2]; + pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); + section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2]; - if (!(temp&1)) + if (!(section_flags & 1)) return -1; - temp=((uint32_t *)ram)[((temp&~0xFFF)+((addr>>10)&0xFFC))>>2]; - temp3=temp&temp2; + section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF)+((addr >> 10) & 0xFFC)) >> 2]; + masked_flags = section_flags & temp_section_flags; - if (!(temp&1) || (CPL==3 && !(temp3&4) && !cpl_override) || (rw && !(temp3&2) && (CPL==3 || cr0&WP_FLAG))) + if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))) return -1; - return (temp&~0xFFF)+(addr&0xFFF); + return (section_flags & ~0xFFF) + (addr & 0xFFF); } void mmu_invalidate(uint32_t addr) diff --git a/src/pc.rc b/src/pc.rc index 925da15fc..c90783586 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -293,14 +293,28 @@ BEGIN END MENUITEM "&Status", IDM_STATUS #ifdef ENABLE_LOG_TOGGLES +#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG MENUITEM SEPARATOR +#endif +#ifdef ENABLE_BUSLOGIC_LOG MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC +#endif +#ifdef ENABLE_CDROM_LOG MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM +#endif +#ifdef ENABLE_D86F_LOG MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F +#endif +#ifdef ENABLE_FDC_LOG MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC +#endif +#ifdef ENABLE_IDE_LOG MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE +#endif +#ifdef ENABLE_NE2000_LOG MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 #endif +#endif #ifdef ENABLE_LOG_BREAKPOINT MENUITEM SEPARATOR MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT @@ -311,13 +325,25 @@ END MainAccel ACCELERATORS BEGIN #ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_CDROM_LOG VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_D86F_LOG VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_FDC_LOG VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_IDE_LOG VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_NE2000_LOG VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY #endif +#endif #ifdef ENABLE_LOG_BREAKPOINT VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY #endif diff --git a/src/resources.h b/src/resources.h index 931b5a8b0..0c70ea07b 100644 --- a/src/resources.h +++ b/src/resources.h @@ -188,13 +188,25 @@ #define IDM_SCSI_DMA6 45406 #define IDM_SCSI_DMA7 45407 #ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG #define IDM_LOG_BUSLOGIC 51200 +#endif +#ifdef ENABLE_CDROM_LOG #define IDM_LOG_CDROM 51201 +#endif +#ifdef ENABLE_D86F_LOG #define IDM_LOG_D86F 51202 +#endif +#ifdef ENABLE_FDC_LOG #define IDM_LOG_FDC 51203 +#endif +#ifdef ENABLE_IDE_LOG #define IDM_LOG_IDE 51204 +#endif +#ifdef ENABLE_NE2000_LOG #define IDM_LOG_NE2000 51205 #endif +#endif #ifdef ENABLE_LOG_BREAKPOINT #define IDM_LOG_BREAKPOINT 51206 #endif diff --git a/src/win.c b/src/win.c index ccfc70858..921102401 100644 --- a/src/win.c +++ b/src/win.c @@ -733,12 +733,24 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED); #ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_CDROM_LOG CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_D86F_LOG CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_FDC_LOG CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_IDE_LOG CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_NE2000_LOG CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif #endif CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); @@ -1510,36 +1522,48 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; #ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG case IDM_LOG_BUSLOGIC: buslogic_do_log ^= 1; CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); break; +#endif +#ifdef ENABLE_CDROM_LOG case IDM_LOG_CDROM: cdrom_do_log ^= 1; CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); break; +#endif +#ifdef ENABLE_D86F_LOG case IDM_LOG_D86F: d86f_do_log ^= 1; CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); break; +#endif +#ifdef ENABLE_FDC_LOG case IDM_LOG_FDC: fdc_do_log ^= 1; CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); break; +#endif +#ifdef ENABLE_IDE_LOG case IDM_LOG_IDE: ide_do_log ^= 1; CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); break; +#endif +#ifdef ENABLE_NE2000_LOG case IDM_LOG_NE2000: ne2000_do_log ^= 1; CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); break; #endif +#endif #ifdef ENABLE_LOG_BREAKPOINT case IDM_LOG_BREAKPOINT: From 4f77d037f361fa9092247cad6595080343bc9a9e Mon Sep 17 00:00:00 2001 From: slipstream/RoL Date: Tue, 17 Jan 2017 20:04:19 +0000 Subject: [PATCH 017/392] Add crash dump functionality --- src/Makefile.mingw | 2 +- src/win-crashdump.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ src/win-crashdump.h | 7 +++ src/win.c | 3 ++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/win-crashdump.c create mode 100644 src/win-crashdump.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 371cb1713..280ec5a13 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ - vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ + vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-crashdump.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-video.o x86seg.o x87.o xtide.o pc.res DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o diff --git a/src/win-crashdump.c b/src/win-crashdump.c new file mode 100644 index 000000000..1220afde0 --- /dev/null +++ b/src/win-crashdump.c @@ -0,0 +1,114 @@ +/* Copyright holders: Riley + see COPYING for more details + + win-crashdump.c : Windows exception handler to make a crash dump just before a crash happens. +*/ +#define _WIN32_WINNT 0x0501 +#include +#include +#include +#include +#include "86box.h" +#include "win-crashdump.h" + +PVOID hExceptionHandler; +char* ExceptionHandlerBuffer; + + +LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { + // Win32-specific functions will be used wherever possible, just in case the C stdlib-equivalents try to allocate memory. + // (The Win32-specific functions are generally just wrappers over NT system calls anyway.) + + // So, the program is about to crash. Oh no what do? + // Let's create a crash dump file as a debugging-aid. + + // First, what would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. + SYSTEMTIME SystemTime; + GetSystemTime(&SystemTime); + sprintf(ExceptionHandlerBuffer, + "86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp", + SystemTime.wYear, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond, + SystemTime.wMilliseconds); + + DWORD Error; + + // Now the filename is in the buffer, the file can be created. + HANDLE hDumpFile = CreateFile( + ExceptionHandlerBuffer, // The filename of the file to open. + GENERIC_WRITE, // The permissions to request. + 0, // Make sure other processes can't touch the crash dump at all while it's open. + NULL, // Leave the security descriptor undefined, it doesn't matter. + OPEN_ALWAYS, // Opens the file if it exists, creates a new file if it doesn't. + FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter. + NULL); // A template file is not being used. + + // Check to make sure the file was actually created. + if (hDumpFile == INVALID_HANDLE_VALUE) { + // CreateFile() failed, so just do nothing more. + return EXCEPTION_CONTINUE_SEARCH; + } + + // Now the file is open, let's write the data we were passed out in a human-readable format. + + sprintf(ExceptionHandlerBuffer, + "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" + "" + "Exception details:\r\n" + "Exception NTSTATUS code: 0x%08x\r\n" + "Occured at address: 0x%p\r\n" + "Number of parameters: %d\r\n" + "Exception parameters: ", + emulator_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, + + ExceptionInfo->ExceptionRecord->ExceptionCode, + ExceptionInfo->ExceptionRecord->ExceptionAddress, + ExceptionInfo->ExceptionRecord->NumberParameters); + + char* CurrentBufferPointer; + + for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); + } + + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1]; + + PCONTEXT Registers = ExceptionInfo->ContextRecord; + + #if defined(__i386__) && !defined(__x86_64) + sprintf(CurrentBufferPointer, + "\r\n" + "Register dump:\r\n" + "eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n" + "\r\n", + Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip); + #else + // Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition. + sprintf(CurrentBufferPointer,"\r\n"); + #endif + + WriteFile(hDumpFile, + ExceptionHandlerBuffer, + strlen(ExceptionHandlerBuffer), + NULL, + NULL); + + // Finally, close the file. + CloseHandle(hDumpFile); + + // And return, therefore causing the crash, but only after the crash dump has been created. + + return EXCEPTION_CONTINUE_SEARCH; +} + +void InitCrashDump() { + // An exception handler should not allocate memory, so allocate 10kb for it to use if it gets called, an amount which should be more than enough. + ExceptionHandlerBuffer = malloc(10240); + // Register the exception handler. Zero first argument means this exception handler gets called last, therefore, crash dump is only made, when a crash is going to happen. + hExceptionHandler = AddVectoredExceptionHandler(0,MakeCrashDump); +} \ No newline at end of file diff --git a/src/win-crashdump.h b/src/win-crashdump.h new file mode 100644 index 000000000..8048cd7af --- /dev/null +++ b/src/win-crashdump.h @@ -0,0 +1,7 @@ +/* Copyright holders: Riley + see COPYING for more details + + win-crashdump.c : Windows crash dump exception handler header file. +*/ + +void InitCrashDump(); \ No newline at end of file diff --git a/src/win.c b/src/win.c index 921102401..ddccc1cad 100644 --- a/src/win.c +++ b/src/win.c @@ -44,6 +44,7 @@ #include "win-d3d.h" #include "win-d3d-fs.h" //#include "win-opengl.h" +#include "win-crashdump.h" #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 @@ -556,6 +557,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, char emulator_title[200]; LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ + + InitCrashDump(); // First thing to do before anything else is to make sure crash dumps get created. process_command_line(); From 8baa55ccbe6681ab587bb3fd3eb844a30628ed1f Mon Sep 17 00:00:00 2001 From: slipstream/RoL Date: Tue, 17 Jan 2017 20:11:34 +0000 Subject: [PATCH 018/392] Forgot to change mingw64 makefile. --- src/Makefile.mingw64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9a3243143..4f6e02a7c 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ - vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ + vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-crashdump.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-video.o x86seg.o x87.o xtide.o pc.res DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o From 6ab8e5be80f224e27e45af40eee6c015e5c0c88c Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 22:15:15 +0100 Subject: [PATCH 019/392] Rewrote the MMU translation code completely, thank you TheCollector1995 for testing; Fixed NT page faults with AHA-154x and BusLogic, patch by TheCollector1995. --- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 4 +- src/buslogic.c | 6 +- src/mem.c | 175 +++++++++++++++++++++++++------------------ 4 files changed, 112 insertions(+), 77 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 280ec5a13..58716145d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) - sleep 2 + sleep 5 strip "86Box.exe" - sleep 2 + sleep 5 all : 86Box.exe diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 4f6e02a7c..3c3c1524b 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lws 86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) - sleep 10 + sleep 5 strip "86Box64.exe" - sleep 10 + sleep 5 all : 86Box64.exe diff --git a/src/buslogic.c b/src/buslogic.c index c7d121606..4c8d4fb4d 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -629,7 +629,11 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C CmdBlock->common.TargetStatus = TargetStatus; //Rewrite the CCB up to the CDB. - DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); + if (CmdBlock->common.TargetStatus != 0x02) + { + pclog("CCB rewritten to the CDB\n"); + DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); + } } BuslogicLog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); diff --git a/src/mem.c b/src/mem.c index 8c16fd33e..7d5e965ed 100644 --- a/src/mem.c +++ b/src/mem.c @@ -957,84 +957,115 @@ int mem_cpl3_check() return 0; } -/* The relevant page table entry bits are: - 0 = P (1 = page is present, 0 = page is not present); - 1 = R/W (0 = read-only for user, 1 = writable for user); - 2 = U/S (0 = system page, 1 = user page). */ +void mmu_page_fault(uint32_t addr, uint32_t error_code) +{ + cr2 = addr; + cpu_state.abrt = ABRT_PF; + abrt_error = error_code; +} + +int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_abrt) +{ + uint8_t error_code = 0; + + uint8_t is_page_fault = 0; + + if (mem_cpl3_check()) error_code = 4; /* If CPL = 3 and it's not a PDE check, set US bit. */ + if (rw) error_code |= 2; /* If writing and it's not a PDE check, set RW bit. */ + + if (!(flags & 1)) + { + pclog("Trying to read or write a page that is not present!\n"); + is_page_fault = 1; + } + + if (!pde) + { + if (!(flags & 4) && mem_cpl3_check()) + { + pclog("Trying to read a system page from user mode!\n"); + is_page_fault = 1; + } + if (rw && !(flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))) + { + pclog("Trying to write a read-only-for-user page from user mode!\n"); + is_page_fault = 1; + } + } + + if (is_page_fault) + { + if (is_abrt) + { + mmu_page_fault(addr, error_code | (flags & 1)); + } + return -1; + } + + return 0; +} + +#define PAGE_DIRTY_AND_ACCESSED 0x60 +#define PAGE_DIRTY 0x40 +#define PAGE_ACCESSED 0x20 + +/* rw means 0 = read, 1 = write */ +uint32_t mmutranslate(uint32_t addr, int rw, int is_abrt) +{ + /* Mask out the lower 12 bits. */ + uint32_t dir_base = 0; + + uint32_t table_addr = 0; + uint32_t page_addr = 0; + + uint32_t table_flags = 0; + uint32_t page_flags = 0; + + if (cpu_state.abrt) + { + return -1; + } + + dir_base = cr3 & ~0xfff; + table_addr = dir_base + ((addr >> 20) & 0xffc); + + /* First check the flags of the page directory entry. */ + table_flags = ((uint32_t *)ram)[table_addr >> 2]; + + if (mmu_page_fault_check(addr, rw, table_flags & 7, 1, is_abrt) == -1) + { + return -1; + } + + page_addr = table_flags & ~0xfff; + page_addr += ((addr >> 10) & 0xffc); + + /* Then check the flags of the page table entry. */ + page_flags = ((uint32_t *)ram)[page_addr >> 2]; + + if (mmu_page_fault_check(addr, rw, page_flags & 7, 0, is_abrt) == -1) + { + return -1; + } + + if (is_abrt) + { + mmu_perm = page_flags & 4; + ((uint32_t *)ram)[table_addr >> 2] |= PAGE_ACCESSED; + ((uint32_t *)ram)[page_addr >> 2] |= (rw ? PAGE_DIRTY_AND_ACCESSED : PAGE_ACCESSED); + } + + return (page_flags & ~0xFFF) + (addr & 0xFFF); +} + uint32_t mmutranslatereal(uint32_t addr, int rw) { - uint32_t pde_addr; - uint32_t section_flags; - uint32_t temp_section_flags; - uint32_t masked_flags; - - if (cpu_state.abrt) - { - // pclog("Translate recursive abort\n"); - return -1; - } - pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2]; - // if (output == 3) pclog("Do translate %08X %i %08X\n", addr, rw, section_flags); - if (!(section_flags & 1))// || !(section_flags & 4) && mem_cpl3_check()) || (rw && !(section_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))) - { - // if (!nopageerrors) pclog("Section not present! %08X %08X %02X %04X:%08X %i %i\n",addr,temp,opcode,CS,cpu_state.pc,CPL,rw); - - cr2 = addr; - section_flags &= 1; - if (CPL==3) section_flags |= 4; - if (rw) section_flags |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = section_flags; - return -1; - } - section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC))>>2]; - masked_flags = section_flags & temp_section_flags; - // if (output == 3) pclog("Do translate %08X %08X\n", section_flags, temp3); - if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))) - { - // if (!nopageerrors) pclog("Page not present! %08X %08X %02X %02X %i %08X %04X:%08X %04X:%08X %i %i %i\n",addr,section_flags,opcode,opcode2,frame,rmdat32, CS,cpu_state.pc,SS,ESP,ins,CPL,rw); - - cr2 = addr; - section_flags &= 1; - if (CPL==3) section_flags |= 4; - if (rw) section_flags |= 2; - cpu_state.abrt = ABRT_PF; - abrt_error = section_flags; - // pclog("%04X\n",cpu_state.abrt); - return -1; - } - mmu_perm = section_flags & 4; - ((uint32_t *)ram)[pde_addr >> 2] |= 0x20; - ((uint32_t *)ram)[((temp_section_flags & ~0xFFF) + ((addr >> 10) & 0xFFC)) >> 2] |= (rw ? 0x60 : 0x20); - // /*if (output) */pclog("Translate %08X %08X %08X %08X:%08X %08X\n",addr,(temp&~0xFFF)+(addr&0xFFF),section_flags,cs,cpu_state.pc,EDI); - - return (section_flags & ~0xFFF) + (addr & 0xFFF); + return mmutranslate(addr, rw, 1); } uint32_t mmutranslate_noabrt(uint32_t addr, int rw) { - uint32_t pde_addr; - uint32_t section_flags; - uint32_t temp_section_flags; - uint32_t masked_flags; - - if (cpu_state.abrt) - return -1; - - pde_addr = ((cr3 & ~0xfff) + ((addr >> 20) & 0xffc)); - section_flags = temp_section_flags = ((uint32_t *)ram)[pde_addr >> 2]; - - if (!(section_flags & 1)) - return -1; - - section_flags = ((uint32_t *)ram)[((section_flags & ~0xFFF)+((addr >> 10) & 0xFFC)) >> 2]; - masked_flags = section_flags & temp_section_flags; - - if (!(section_flags & 1) || (!(masked_flags & 4) && mem_cpl3_check()) || (rw && !(masked_flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG)))) - return -1; - - return (section_flags & ~0xFFF) + (addr & 0xFFF); + return mmutranslate(addr, rw, 0); } void mmu_invalidate(uint32_t addr) From 58d557dc6457b0aca52b0e2f67bb540ad4f15840 Mon Sep 17 00:00:00 2001 From: slipstream/RoL Date: Tue, 17 Jan 2017 21:32:16 +0000 Subject: [PATCH 020/392] Crash dumps now only made if 86box is actually about to crash --- src/win-crashdump.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/win-crashdump.c b/src/win-crashdump.c index 1220afde0..af01408e2 100644 --- a/src/win-crashdump.c +++ b/src/win-crashdump.c @@ -19,6 +19,12 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { // Win32-specific functions will be used wherever possible, just in case the C stdlib-equivalents try to allocate memory. // (The Win32-specific functions are generally just wrappers over NT system calls anyway.) + if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) { + // The exception code is not a fatal exception (highest 4 bits of ntstatus = 0xC) + // Not going to crash, let's not make a crash dump + return EXCEPTION_CONTINUE_SEARCH; + } + // So, the program is about to crash. Oh no what do? // Let's create a crash dump file as a debugging-aid. From 2820b69439072993c21aea05e53695003a187518 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 17 Jan 2017 23:58:16 +0100 Subject: [PATCH 021/392] Fix for BusLogic scatter/gather by TheCollector1995. --- src/buslogic.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 4c8d4fb4d..82fe4b950 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1562,10 +1562,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, } pclog("Request complete\n"); - pclog("SCSI Status %02X, Sense %02X, Asc %02X, Ascq %02X\n", SCSIStatus, cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); - - if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES || - BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) + + if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { temp = BuslogicGetDataLength(BuslogicRequests); temp -= SCSIDevices[Id].InitLength; @@ -1581,6 +1579,19 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); } } + else if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) + { + if (BuslogicRequests->Is24bit) + { + U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, 0); + BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); + } + else + { + BuslogicRequests->CmdBlock.new.DataLength = 0; + BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); + } + } if (SCSIStatus == SCSI_STATUS_OK) { @@ -1597,7 +1608,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, { BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); - if (Mailbox32->u.out.ActionCode == MBO_START) + if (Mailbox32->u.out.ActionCode == MBO_START && Lun == 0) BuslogicStartMailbox(Buslogic); } } From 66757dfaad692ce0aec5c6742762607cd4c9d749 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 18 Jan 2017 00:43:43 +0100 Subject: [PATCH 022/392] Added IBM PS/1 Model 2121 with ISA expansion, allows selecting any graphics card. --- src/ibm.h | 2 ++ src/model.c | 1 + src/win.c | 7 +++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 061602145..0e95a3f30 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -415,6 +415,8 @@ enum ROM_THOR, /*Intel Advanced/ATX / 430FX / AMI BIOS / National Semiconductors PC87306*/ ROM_MRTHOR, /*Intel Advanced/ATX / 430FX / MR.BIOS / National Semiconductors PC87306*/ ROM_POWERMATE_V,/*NEC PowerMate V / 430FX / Phoenix BIOS / SMC FDC37C665*/ + + ROM_IBMPS1_2121,/*IBM PS/1 Model 2121 with ISA expansion bus*/ ROM_MAX }; diff --git a/src/model.c b/src/model.c index 64562f7a2..a6e7dc8f4 100644 --- a/src/model.c +++ b/src/model.c @@ -146,6 +146,7 @@ MODEL models[] = {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, {"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, diff --git a/src/win.c b/src/win.c index ddccc1cad..0d0ac7b5a 100644 --- a/src/win.c +++ b/src/win.c @@ -1053,7 +1053,8 @@ LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) BOOL bControlKeyDown; KBDLLHOOKSTRUCT* p; - if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) + // if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) + if (nCode < 0 || nCode != HC_ACTION) return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); p = (KBDLLHOOKSTRUCT*)lParam; @@ -2155,7 +2156,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_SYSCOMMAND: - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) + // if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) + /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) return 0; /*disable ALT key for menu*/ default: From 71503f69a4be33b5c2fcf03e4b4733816b304b98 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 18 Jan 2017 00:45:30 +0100 Subject: [PATCH 023/392] Fixed a compile-breaking error. --- src/ibm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ibm.h b/src/ibm.h index 0e95a3f30..ef2896d8f 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -416,7 +416,7 @@ enum ROM_MRTHOR, /*Intel Advanced/ATX / 430FX / MR.BIOS / National Semiconductors PC87306*/ ROM_POWERMATE_V,/*NEC PowerMate V / 430FX / Phoenix BIOS / SMC FDC37C665*/ - ROM_IBMPS1_2121,/*IBM PS/1 Model 2121 with ISA expansion bus*/ + ROM_IBMPS1_2121_ISA,/*IBM PS/1 Model 2121 with ISA expansion bus*/ ROM_MAX }; From fc42c2e2e7bc4c787e9ccd1476c6b5e52fecec8c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 18 Jan 2017 02:24:05 +0100 Subject: [PATCH 024/392] BusLogic now starts mailboxes for all LUN's when nothing is attached to a given ID; BusLogic now sets callback on MBO_FREE. --- src/buslogic.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 82fe4b950..0d62b8d53 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -631,7 +631,7 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C //Rewrite the CCB up to the CDB. if (CmdBlock->common.TargetStatus != 0x02) { - pclog("CCB rewritten to the CDB\n"); + BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); } } @@ -1480,13 +1480,13 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, uint32_t i; - pclog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); + BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++) - pclog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); + BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); - pclog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); - pclog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); - pclog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); + BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); + BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); + BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); //This not ready/unit attention stuff below is only for the Buslogic! //The Adaptec one is in scsi_cdrom.c. @@ -1560,8 +1560,13 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, if (BuslogicRequests->RequestSenseBuffer) BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); } + else + { + BuslogicLog("Mailbox32->u.out.ActionCode = %02X\n", Mailbox32->u.out.ActionCode); + SCSICallback[Id] = 50 * SCSI_TIME; + } - pclog("Request complete\n"); + BuslogicLog("Request complete\n"); if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { @@ -1608,7 +1613,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, { BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); - if (Mailbox32->u.out.ActionCode == MBO_START && Lun == 0) + // if (Mailbox32->u.out.ActionCode == MBO_START && Lun == 0) + if (Mailbox32->u.out.ActionCode == MBO_START && Lun <= 7) BuslogicStartMailbox(Buslogic); } } From 401520661dbf9713fe04b0a7191618aa55f0ebca Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Tue, 17 Jan 2017 20:10:17 -0600 Subject: [PATCH 025/392] Add in NV4 context switching --- src/vid_nv_riva128.c | 59 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index d3a94bf31..d23cf90f2 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -151,6 +151,9 @@ typedef struct riva128_t uint32_t fifo_enable; + uint32_t fifo_st2_addr; + uint32_t fifo_st2_data; + uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; @@ -226,6 +229,9 @@ const char* riva128_pfifo_interrupts[32] = "CACHE_ERROR","","","","RUNOUT","","","","RUNOUT_OVERFLOW","","","","DMA_PUSHER","","","","DMA_PTE","","","","","","","","","","","","","","","" }; +static uint32_t riva128_ramht_lookup(uint32_t handle, void *p); +static void riva128_pgraph_volatile_reset(void *p); + static uint8_t riva128_pci_read(int func, int addr, void *p); static void riva128_pci_write(int func, int addr, uint8_t val, void *p); @@ -965,6 +971,50 @@ static uint8_t riva128_pextdev_read(uint32_t addr, void *p) return ret; } +static void rivatnt_pgraph_ctx_switch(uint32_t addr, uint32_t val, void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + + if(!(riva128->fifo_st2_addr & 1)) return; + + unsigned old_subc = (riva128->ctx_user >> 13) & 7; + unsigned new_subc = (riva128->fifo_st2_addr >> 12) & 7; + unsigned mthd = (riva128->fifo_st2_addr >> 1) & 0x7ff; + riva128->fifo_st2_addr &= ~1; + unsigned do_ctx_switch = mthd == 0; + + if(old_subc != new_subc || do_ctx_switch) + { + if(do_ctx_switch) riva128->ctx_cache[new_subc][3] = riva128->fifo_st2_data & 0xffff; + + uint32_t ctx_mask = 0x0303f0ff; + + unsigned reload = (riva128->debug[1] >> 15) & 1; + if(reload || do_ctx_switch) + { + uint32_t instance = riva128_ramht_lookup(val, riva128); + riva128->ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; + riva128->ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; + riva128->ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; + riva128->ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; + } + + unsigned reset = (riva128->debug[2] >> 28) & 1; + if(reset) + { + riva128->debug[1] |= 1; + riva128_pgraph_volatile_reset(riva128); + } + else riva128->debug[1] &= ~1; + + if(riva128->debug[1] & 0x100000) + { + for(int i = 0; i < 5; i++) riva128->ctx_switch[i] = riva128->ctx_cache[new_subc][i]; + } + } +} + static uint8_t riva128_pgraph_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -1366,6 +1416,13 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x40008c: riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); break; + case 0x400754: + riva128->pgraph.fifo_st2_addr = val; + break; + case 0x400758: + riva128->pgraph.fifo_st2_data = val; + rivatnt_pgraph_ctx_switch(riva128); + break; } } @@ -1555,7 +1612,7 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui if(riva128->card_id == 0x03) { uint32_t tmp = riva128_ramht_lookup(val, riva128); - riva128->pgraph.instance = (tmp & 0xffff) << 4; + riva128->pgraph.instance = (tmp & 0xffff) << 2; unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; unsigned new_subc = subchanid & 7; if((old_subc != new_subc) || !offset) From 0548d8f9c89efa0860b7d3182da6075ef7060d78 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 18 Jan 2017 21:51:03 +0100 Subject: [PATCH 026/392] Essentially reverted 8-bit IDE data reads and writes to old operation, fixes the hard disk bug; SCSI LUN is now selectable for the CD-ROM drives; Made sure every BusLogic RequestSetup ends in a StartMailbox sooner or later, fixes freezes with the DOS BusLogic drivers; Commented out execess logging from mem.c; Applied the mainline PCem commit that fixes the Bahamas64 on some boards. --- src/buslogic.c | 212 +++++++++++++++++++++++++++---------------- src/cdrom-ioctl.c | 124 +++++++++++++++++++------ src/cdrom.c | 227 ++++++++++++++++++++++++++++++++-------------- src/cdrom.h | 10 +- src/ide.c | 89 +++++++++++++----- src/mem.c | 6 +- src/pc.c | 18 +++- src/pc.rc | 48 ++++++++++ src/resources.h | 32 +++++++ src/scsi.c | 88 +++++------------- src/scsi.h | 7 +- src/vid_s3.c | 8 +- src/win.c | 32 ++++++- 13 files changed, 612 insertions(+), 289 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 0d62b8d53..e4a8d8b9a 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -685,6 +685,7 @@ static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bit) { + uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; if (Is24bit) @@ -698,8 +699,13 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi DataLength = BuslogicRequests->CmdBlock.new.DataLength; } - if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - DataLength = 0; + /* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) + DataLength = 0; */ + + if ((BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_6) && (BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_10)) + { + return; + } BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); @@ -737,8 +743,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer); - SCSIDevices[BuslogicRequests->TargetID].InitLength = DataToTransfer; - SCSIDevices[BuslogicRequests->TargetID].CmdBuffer[SCSIDevices[BuslogicRequests->TargetID].pos++] = SCSIDevices[BuslogicRequests->TargetID].InitLength; + SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = DataToTransfer; //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //checking its length, so do this procedure for both no read/write commands. @@ -763,7 +768,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, DataToTransfer); + DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; } ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); @@ -774,10 +780,12 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { uint32_t Address = DataPointer; - SCSIDevices[BuslogicRequests->TargetID].InitLength = DataLength; - SCSIDevices[BuslogicRequests->TargetID].CmdBuffer[SCSIDevices[BuslogicRequests->TargetID].pos++] = SCSIDevices[BuslogicRequests->TargetID].InitLength; + SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = DataLength; - DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID].InitLength); + if (DataLength > 0) + { + DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); + } } } } @@ -798,6 +806,8 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) { uint32_t sg_buffer_pos = 0; + uint32_t transfer_length = 0; + if (BuslogicRequests->Is24bit) { DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer); @@ -808,9 +818,19 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) DataPointer = BuslogicRequests->CmdBlock.new.DataPointer; DataLength = BuslogicRequests->CmdBlock.new.DataLength; } + + if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) + { + DataLength = SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; + } + + if ((DataLength != 0) && (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) + { + BuslogicLog("Data length not 0 with TEST UNIT READY: %i (%i)\n", DataLength, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); + } - if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - DataLength = 0; + /* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) + DataLength = 0; */ BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); @@ -852,7 +872,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer + sg_buffer_pos, DataToTransfer); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; } @@ -863,11 +883,21 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { uint32_t Address = DataPointer; - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID].InitLength); + if (DataLength > 0) + { + if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) + { + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); + } + else + { + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength); + } + } } } - SCSIDevices[BuslogicRequests->TargetID].InitLength = 0; + SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0; } uint8_t BuslogicRead(uint16_t Port, void *p) @@ -916,15 +946,20 @@ uint8_t BuslogicRead(uint16_t Port, void *p) return Temp; } -int buslogic_scsi_drive_is_cdrom(uint8_t id) +int buslogic_scsi_drive_is_cdrom(uint8_t id, uint8_t lun) { - if (scsi_cdrom_drives[id] >= CDROM_NUM) + if (lun > 7) + { + return 0; + } + + if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) { return 0; } else { - if (cdrom_drives[scsi_cdrom_drives[id]].enabled && cdrom_drives[scsi_cdrom_drives[id]].bus_type && (cdrom_drives[scsi_cdrom_drives[id]].bus_mode & 2)) + if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) { return 1; } @@ -939,6 +974,10 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) { int i = 0; + uint8_t j = 0; + + uint8_t max_id = scsi_model ? 16 : 8; + Buslogic_t *Buslogic = (Buslogic_t *)p; BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); @@ -964,9 +1003,9 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) { for (i = 0; i < CDROM_NUM; i++) { - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id)) + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun)) { - SCSICallback[cdrom_drives[i].scsi_device_id] = 1; + SCSICallback[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun] = 1; } } break; @@ -1105,13 +1144,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x0A: - for (i = 0; i < 8; i++) + for (i = 0; i < max_id; i++) { - if (buslogic_scsi_drive_is_cdrom(i)) - Buslogic->DataBuf[i] = 1; - - Buslogic->DataBuf[7] = 0; - Buslogic->DataReplyLeft = 8; + for (j = 0; j < 8; j++) + { + if (buslogic_scsi_drive_is_cdrom(i, j)) + Buslogic->DataBuf[i] = 1; + + Buslogic->DataBuf[7] = 0; + Buslogic->DataReplyLeft = 8; + } } break; @@ -1147,14 +1189,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } break; - case 0x23: - for (i = 0; i < 8; i++) + for (i = 0; i < max_id; i++) { - if (buslogic_scsi_drive_is_cdrom(i)) - Buslogic->DataBuf[i] = 1; + for (i = 0; j < 8; j++) + { + if (buslogic_scsi_drive_is_cdrom(i, j)) + Buslogic->DataBuf[i] = 1; - Buslogic->DataReplyLeft = 8; + Buslogic->DataReplyLeft = 8; + } } break; @@ -1200,13 +1244,15 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x24: { - uint8_t i; uint16_t TargetsPresentMask = 0; - for (i=0;iDataBuf[0] = TargetsPresentMask&0x0F; Buslogic->DataBuf[1] = TargetsPresentMask>>8; @@ -1414,6 +1460,7 @@ static void BuslogicSenseBufferAllocate(BuslogicRequests_t *BuslogicRequests) static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Copy) { uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); + uint8_t cdrom_id = scsi_cdrom_drives[BuslogicRequests->TargetID][BuslogicRequests->LUN]; if (SenseLength && Copy) { @@ -1434,8 +1481,7 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress); - // DMAPageWrite(SenseBufferAddress, BuslogicRequests->RequestSenseBuffer, SenseLength); - DMAPageWrite(SenseBufferAddress, cdrom[BuslogicRequests->TargetID].sense, SenseLength); + DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength); } //Free the sense buffer when needed. free(BuslogicRequests->RequestSenseBuffer); @@ -1451,6 +1497,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, uint32_t temp = 0; + uint8_t temp_cdb[12]; + //Fetch data from the Command Control Block. DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32)); @@ -1463,9 +1511,9 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, BuslogicLog("Scanning SCSI Target ID %i\n", Id); //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. - if (buslogic_scsi_drive_is_cdrom(Id) && Lun == 0) + if (buslogic_scsi_drive_is_cdrom(Id, Lun)) { - cdrom_id = scsi_cdrom_drives[Id]; + cdrom_id = scsi_cdrom_drives[Id][Lun]; BuslogicLog("SCSI Target ID %i detected and working\n", Id); @@ -1483,6 +1531,22 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++) BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); + + memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); + if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) + { + memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength); + } + else + { + memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); + } + + if (BuslogicRequests->CmdBlock.common.CdbLength != 12) + { + cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */ + temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ + } BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); @@ -1495,11 +1559,11 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, { if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND)) { - if (!cdrom_pre_execution_check(cdrom_id, BuslogicRequests->CmdBlock.common.Cdb)) + if (!cdrom_pre_execution_check(cdrom_id, temp_cdb)) { SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSICallback[Id]=50*SCSI_TIME; - SCSIDevices[BuslogicRequests->TargetID].InitLength = 0; + SCSICallback[Id][Lun]=50*SCSI_TIME; + SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0; if (BuslogicRequests->RequestSenseBuffer) BuslogicSenseBufferFree(BuslogicRequests, 1); BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); @@ -1508,28 +1572,13 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, } } - //First, get the data buffer otherwise putting it after the - //exec function results into not getting read/write commands right and - //failing to detect the device. - - /* Note by Tohka: After looking at the code, both functions do a copy of one part of the buffer to another, - with no purpose, whatsoever, and then end up with SCSIDevices.pos being equal to the InitLength. - SCSIReadData does not use pos at all, and the write code does, but in a useless way, therefore that - variable is going away. - All I am going to do at this point is zero the buffer. - Also, instead of directly calling SCSIReadData from here, this will be modified to call the CD-ROM - callback for the correct CD-ROM drive, and make that call SCSIReadData. - Since the new code will have the target ID and LUN inside the cdrom struct, as well as a copy of the Cdb - and the InitLength (in cdrom[id].request_length), it can be called from there and do everything needed. */ - - memset(SCSIDevices[Id].CmdBuffer, 0, 390144); + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); //Finally, execute the SCSI command immediately and get the transfer length. SCSIPhase = SCSI_PHASE_COMMAND; - cdrom_command(cdrom_id, BuslogicRequests->CmdBlock.common.Cdb); - // SCSIDevices[Id].InitLength = cdrom[cdrom_id].0; - // SCSIGetLength(Id, &SCSIDevices[Id].InitLength); + SCSIDevices[Id][Lun].InitLength = 0; + cdrom_command(cdrom_id, temp_cdb); SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); if (SCSIStatus == SCSI_STATUS_OK) { @@ -1553,9 +1602,12 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, /* Error (Check Condition) - call the phase callback to complete the command. */ cdrom_phase_callback(cdrom_id); } - SCSICallback[Id] = cdrom[cdrom_id].callback; + SCSICallback[Id][Lun] = cdrom[cdrom_id].callback; - BuslogicDataBufferFree(BuslogicRequests); + if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (SCSIDevices[Id][Lun].InitLength != 0)) + { + BuslogicDataBufferFree(BuslogicRequests); + } if (BuslogicRequests->RequestSenseBuffer) BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); @@ -1563,7 +1615,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, else { BuslogicLog("Mailbox32->u.out.ActionCode = %02X\n", Mailbox32->u.out.ActionCode); - SCSICallback[Id] = 50 * SCSI_TIME; + SCSICallback[Id][Lun] = 50 * SCSI_TIME; } BuslogicLog("Request complete\n"); @@ -1571,7 +1623,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { temp = BuslogicGetDataLength(BuslogicRequests); - temp -= SCSIDevices[Id].InitLength; + temp -= SCSIDevices[Id][Lun].InitLength; if (BuslogicRequests->Is24bit) { @@ -1686,11 +1738,11 @@ static void BuslogicStartMailbox(Buslogic_t *Buslogic) } } -void BuslogicCommandCallback(int Id, void *p) +void BuslogicCommandCallback(int id, int lun, void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; - SCSICallback[Id] = 0; + SCSICallback[id][lun] = 0; if (Buslogic->MailboxCount) { BuslogicStartMailbox(Buslogic); @@ -1699,22 +1751,22 @@ void BuslogicCommandCallback(int Id, void *p) void BuslogicCommandCallback0(void *p) { - BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, p); + BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun, p); } void BuslogicCommandCallback1(void *p) { - BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, p); + BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun, p); } void BuslogicCommandCallback2(void *p) { - BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, p); + BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun, p); } void BuslogicCommandCallback3(void *p) { - BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, p); + BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun, p); } void *BuslogicInit() @@ -1730,25 +1782,25 @@ void *BuslogicInit() BuslogicLog("Building CD-ROM map...\n"); build_scsi_cdrom_map(); - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id)) + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun)) { - SCSIDevices[cdrom_drives[0].scsi_device_id].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id], &SCSICallback[cdrom_drives[0].scsi_device_id], Buslogic); + SCSIDevices[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], Buslogic); } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id)) + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun)) { - SCSIDevices[cdrom_drives[1].scsi_device_id].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id], &SCSICallback[cdrom_drives[1].scsi_device_id], Buslogic); + SCSIDevices[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], Buslogic); } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id)) + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun)) { - SCSIDevices[cdrom_drives[2].scsi_device_id].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id], &SCSICallback[cdrom_drives[2].scsi_device_id], Buslogic); + SCSIDevices[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], Buslogic); } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id)) + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun)) { - SCSIDevices[cdrom_drives[3].scsi_device_id].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id], &SCSICallback[cdrom_drives[3].scsi_device_id], Buslogic); + SCSIDevices[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun].LunType == SCSI_CDROM; + timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], Buslogic); } BuslogicLog("Buslogic on port 0x%04X\n", scsi_base); diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 3f87f4798..7fc61eeb3 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -37,7 +37,7 @@ enum CD_PAUSED }; -int cdrom_ioctl_do_log = 1; +int cdrom_ioctl_do_log = 0; void cdrom_ioctl_log(const char *format, ...) { @@ -517,34 +517,23 @@ struct sptd_with_sense UCHAR data[65536]; } sptd; -static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) +static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) { - HANDLE fh; - DWORD ioctl_bytes; - DWORD out_size; - int ioctl_rv = 0; int sector_type = 0; int temp_len = 0; - SCSISense.SenseKey = 0; - SCSISense.Asc = 0; - SCSISense.Ascq = 0; + if (no_length_check) + { + return 8192; + } - *len = 0; - memset(&sptd, 0, sizeof(sptd)); - sptd.s.Length = sizeof(SCSI_PASS_THROUGH); - sptd.s.CdbLength = 12; - sptd.s.DataIn = SCSI_IOCTL_DATA_IN; - sptd.s.TimeOutValue = 80 * 60; - goto bypass_check; - if (no_length_check) goto bypass_check; switch (cdb[0]) { case 0x08: case 0x28: case 0xa8: /* READ (6), READ (10), READ (12) */ - sptd.s.DataTransferLength = 2048 * cdrom[id].requested_blocks; + return 2048 * number_of_blocks; break; case 0xb9: sector_type = (cdb[1] >> 2) & 7; @@ -554,7 +543,7 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, if (sector_type == 0) { cdrom_illegal_mode(id); - return 1; + return -1; } } goto common_handler; @@ -567,7 +556,7 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, if (sector_type == 0) { cdrom_illegal_mode(id); - return 1; + return -1; } } common_handler: @@ -595,16 +584,38 @@ common_handler: if (temp_len <= 0) { cdrom_illegal_mode(id); - return 1; + return -1; } - sptd.s.DataTransferLength = temp_len * cdrom[id].requested_blocks; + return temp_len * cdrom[id].requested_blocks; break; default: -bypass_check: /* Other commands */ - sptd.s.DataTransferLength = 65536; + return 8192; break; } + +} + +static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) +{ + HANDLE fh; + DWORD ioctl_bytes; + DWORD out_size; + int ioctl_rv = 0; + int sector_type = 0; + int temp_len = 0; + + SCSISense.SenseKey = 0; + SCSISense.Asc = 0; + SCSISense.Ascq = 0; + + *len = 0; + memset(&sptd, 0, sizeof(sptd)); + sptd.s.Length = sizeof(SCSI_PASS_THROUGH); + sptd.s.CdbLength = 12; + sptd.s.DataIn = SCSI_IOCTL_DATA_IN; + sptd.s.TimeOutValue = 80 * 60; + sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; sptd.s.SenseInfoLength = 32; sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; @@ -755,6 +766,19 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t const UCHAR cdb[12]; int ret; + + int block_length = 0; + + int temp_block_length = 0; + int temp_pos = 0; + + int blocks_at_once = 0; + int buffer_pos = 0; + + int temp_requested_blocks = 0; + int transferred_blocks = 0; + + int temp_len = 0; if (cdb[0] == 0x43) { @@ -765,9 +789,57 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t ioctl_open(id, 0); memcpy(cdb, in_cdb, 12); - ret = SCSICommand(id, cdb, buf, len, 0); - memcpy(b, buf, *len); + temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + if (temp_block_length != -1) + { + if (temp_block_length > 65534) + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer...\n", id, temp_block_length); + block_length = temp_block_length / cdrom[id].requested_blocks; + blocks_at_once = 32768 / block_length; + + buffer_pos = 0; + temp_pos = cdrom[id].sector_pos; + temp_requested_blocks = cdrom[id].requested_blocks; + transferred_blocks = 0; + temp_len = 0; + +split_block_read_iterate: + if (temp_requested_blocks < blocks_at_once) + { + cdrom_ioctl[id].actual_requested_blocks = temp_requested_blocks; + } + else + { + cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; + } + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); + cdrom_update_cdb(cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); + ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); + *len += temp_len; + transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; + if (ret && (transferred_blocks >= cdrom[id].requested_blocks)) + { + temp_pos += cdrom_ioctl[id].actual_requested_blocks; + buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); + goto split_block_read_iterate; + } + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Split transfer done\n", id); + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length); + cdrom_ioctl[id].actual_requested_blocks = cdrom[id].requested_blocks; + ret = SCSICommand(id, cdb, buf, len, 0); + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id); + } + memcpy(b, buf, *len); + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); + } cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); diff --git a/src/cdrom.c b/src/cdrom.c index 3e9e30d22..0aad0daf8 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -33,7 +33,22 @@ cdrom_t cdrom[CDROM_NUM]; cdrom_drive_t cdrom_drives[CDROM_NUM]; uint8_t atapi_cdrom_drives[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -uint8_t scsi_cdrom_drives[16] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +uint8_t scsi_cdrom_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; static struct __attribute__((__packed__)) { @@ -240,13 +255,13 @@ void build_atapi_cdrom_map() } } -int find_cdrom_for_scsi_id(uint8_t scsi_id) +int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t i = 0; for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type && (cdrom_drives[i].scsi_device_id == scsi_id)) + if (cdrom_drives[i].bus_type && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) { return i; } @@ -257,15 +272,22 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id) void build_scsi_cdrom_map() { uint8_t i = 0; - - memset(scsi_cdrom_drives, 0xff, 16); + uint8_t j = 0; for (i = 0; i < 16; i++) { - scsi_cdrom_drives[i] = find_cdrom_for_scsi_id(i); - if (scsi_cdrom_drives[i] != 0xff) + memset(scsi_cdrom_drives[i], 0xff, 8); + } + + for (i = 0; i < 16; i++) + { + for (j = 0; j < 8; j++) { - cdrom_init(scsi_cdrom_drives[i], 12, 1); + scsi_cdrom_drives[i][j] = find_cdrom_for_scsi_id(i, j); + if (scsi_cdrom_drives[i][j] != 0xff) + { + cdrom_init(scsi_cdrom_drives[i][j], 12, 1); + } } } } @@ -849,6 +871,10 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0)) { + if (cdrom_drives[id].bus_type) + { + SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0; + } cdrom_command_complete(id); } else @@ -857,7 +883,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (cdrom_drives[id].bus_type) { - SCSIDevices[cdrom_drives[id].scsi_device_id].InitLength = alloc_len; + SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; } if (direction == 0) { @@ -928,6 +954,15 @@ static void cdrom_not_ready(uint8_t id) cdrom_cmd_error(id); } +/* This is 05/00/00, based on what a Daemon Tools drive returns for such a case. */ +static void cdrom_illegal_lun(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = 0; + cdrom_ascq = 0; + cdrom_cmd_error(id); +} + static void cdrom_illegal_opcode(uint8_t id) { cdrom_sense_key = SENSE_ILLEGAL_REQUEST; @@ -1007,7 +1042,7 @@ static int cdrom_pass_through(uint8_t id, int *len) if ((cdrom_sense_key != 0) || (cdrom_asc != 0) || (cdrom_ascq != 0)) { /* Command failed with sense, error with that sense. */ - cdrom_log("CD-ROM %i: Command failed with sense, error with that sense.\n", id); + cdrom_log("CD-ROM %i: Command failed with sense, error with that sense (%02X/%02X/%02X).\n", id, cdrom_sense_key, cdrom_asc, cdrom_ascq); cdrom_cmd_error(id); return 0; } @@ -1020,58 +1055,58 @@ static int cdrom_pass_through(uint8_t id, int *len) } } -int cdrom_update_cdb(uint8_t id) +int cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) { int temp = 0; - switch(cdrom[id].current_cdb[0]) + switch(cdb[0]) { case GPCMD_READ_6: - cdrom[id].current_cdb[1] = (cdrom[id].sector_pos >> 16) & 0xff; - cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 8) & 0xff; - cdrom[id].current_cdb[3] = cdrom[id].sector_pos & 0xff; + cdb[1] = (lba_pos >> 16) & 0xff; + cdb[2] = (lba_pos >> 8) & 0xff; + cdb[3] = lba_pos & 0xff; break; case GPCMD_READ_10: - cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff; - cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff; - cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff; - cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff; - cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 8) & 0xff; - cdrom[id].current_cdb[8] = cdrom[id].requested_blocks & 0xff; + cdb[2] = (lba_pos >> 24) & 0xff; + cdb[3] = (lba_pos >> 16) & 0xff; + cdb[4] = (lba_pos >> 8) & 0xff; + cdb[5] = lba_pos & 0xff; + cdb[7] = (number_of_blocks >> 8) & 0xff; + cdb[8] = number_of_blocks & 0xff; break; case GPCMD_READ_12: - cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff; - cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff; - cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff; - cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff; - cdrom[id].current_cdb[6] = (cdrom[id].requested_blocks >> 24) & 0xff; - cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 16) & 0xff; - cdrom[id].current_cdb[8] = (cdrom[id].requested_blocks >> 8) & 0xff; - cdrom[id].current_cdb[9] = cdrom[id].requested_blocks & 0xff; + cdb[2] = (lba_pos >> 24) & 0xff; + cdb[3] = (lba_pos >> 16) & 0xff; + cdb[4] = (lba_pos >> 8) & 0xff; + cdb[5] = lba_pos & 0xff; + cdb[6] = (number_of_blocks >> 24) & 0xff; + cdb[7] = (number_of_blocks >> 16) & 0xff; + cdb[8] = (number_of_blocks >> 8) & 0xff; + cdb[9] = number_of_blocks & 0xff; break; case GPCMD_READ_CD_MSF: - temp = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos); - cdrom[id].current_cdb[3] = (temp >> 16) & 0xff; - cdrom[id].current_cdb[4] = (temp >> 8) & 0xff; - cdrom[id].current_cdb[5] = temp & 0xff; + temp = cdrom_lba_to_msf_accurate(lba_pos); + cdb[3] = (temp >> 16) & 0xff; + cdb[4] = (temp >> 8) & 0xff; + cdb[5] = temp & 0xff; - temp = cdrom_lba_to_msf_accurate(cdrom[id].sector_pos + cdrom[id].requested_blocks - 1); - cdrom[id].current_cdb[6] = (temp >> 16) & 0xff; - cdrom[id].current_cdb[7] = (temp >> 8) & 0xff; - cdrom[id].current_cdb[8] = temp & 0xff; + temp = cdrom_lba_to_msf_accurate(lba_pos + number_of_blocks - 1); + cdb[6] = (temp >> 16) & 0xff; + cdb[7] = (temp >> 8) & 0xff; + cdb[8] = temp & 0xff; break; case GPCMD_READ_CD: - cdrom[id].current_cdb[2] = (cdrom[id].sector_pos >> 24) & 0xff; - cdrom[id].current_cdb[3] = (cdrom[id].sector_pos >> 16) & 0xff; - cdrom[id].current_cdb[4] = (cdrom[id].sector_pos >> 8) & 0xff; - cdrom[id].current_cdb[5] = cdrom[id].sector_pos & 0xff; - cdrom[id].current_cdb[6] = (cdrom[id].requested_blocks >> 16) & 0xff; - cdrom[id].current_cdb[7] = (cdrom[id].requested_blocks >> 8) & 0xff; - cdrom[id].current_cdb[8] = cdrom[id].requested_blocks & 0xff; + cdb[2] = (lba_pos >> 24) & 0xff; + cdb[3] = (lba_pos >> 16) & 0xff; + cdb[4] = (lba_pos >> 8) & 0xff; + cdb[5] = lba_pos & 0xff; + cdb[6] = (number_of_blocks >> 16) & 0xff; + cdb[7] = (number_of_blocks >> 8) & 0xff; + cdb[8] = number_of_blocks & 0xff; break; } } @@ -1177,7 +1212,7 @@ int cdrom_read_blocks(uint8_t id, int *len, int first_batch) cdrom_log("Reading %i blocks starting from %i...\n", cdrom[id].requested_blocks, cdrom[id].sector_pos); - cdrom_update_cdb(id); + cdrom_update_cdb(cdrom[id].current_cdb, cdrom[id].sector_pos, cdrom[id].requested_blocks); ret = cdrom_read_data(id, msf, type, flags, len); @@ -1385,9 +1420,19 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { int ready = 0; + if (cdrom_drives[id].bus_type) + { + if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) + { + cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((cdrom[id].request_length >> 5) & 7)); + cdrom_illegal_lun(id); + return 0; + } + } + if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - cdrom_log("CD-ROM %i: Attempting to unknown command %02X over %s\n", id, cdb[0], cdrom_drives[id].bus_type ? "SCSI" : "ATAPI"); + cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], cdrom_drives[id].bus_type ? "SCSI" : "ATAPI"); cdrom_illegal_opcode(id); return 0; } @@ -2630,11 +2675,11 @@ int cdrom_read_from_ide_dma(uint8_t channel) } } -int cdrom_read_from_scsi_dma(uint8_t scsi_id) +int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t *cdbufferb; - uint8_t id = scsi_cdrom_drives[scsi_id]; + uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; cdbufferb = (uint8_t *) cdrom[id].buffer; @@ -2643,8 +2688,8 @@ int cdrom_read_from_scsi_dma(uint8_t scsi_id) return 0; } - cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength); - memcpy(cdbufferb, SCSIDevices[scsi_id].CmdBuffer, SCSIDevices[scsi_id].InitLength); + cdrom_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); + memcpy(cdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSIDevices[scsi_id][scsi_lun].InitLength); return 1; } @@ -2657,7 +2702,7 @@ int cdrom_read_from_dma(uint8_t id) if (cdrom_drives[id].bus_type) { - ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id); + ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } else { @@ -2713,11 +2758,11 @@ int cdrom_write_to_ide_dma(uint8_t channel) } } -int cdrom_write_to_scsi_dma(uint8_t scsi_id) +int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) { uint8_t *cdbufferb; - uint8_t id = scsi_cdrom_drives[scsi_id]; + uint8_t id = scsi_cdrom_drives[scsi_id][scsi_lun]; if (id > CDROM_NUM) { @@ -2726,10 +2771,10 @@ int cdrom_write_to_scsi_dma(uint8_t scsi_id) cdbufferb = (uint8_t *) cdrom[id].buffer; - cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id].InitLength); - memcpy(SCSIDevices[scsi_id].CmdBuffer, cdbufferb, SCSIDevices[scsi_id].InitLength); + cdrom_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); + memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, cdbufferb, SCSIDevices[scsi_id][scsi_lun].InitLength); cdrom_log("CD-ROM %i: Data from CD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[0], cdbufferb[1], cdbufferb[2], cdbufferb[3], cdbufferb[4], cdbufferb[5], cdbufferb[6], cdbufferb[7]); - cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id].CmdBuffer[0], SCSIDevices[scsi_id].CmdBuffer[1], SCSIDevices[scsi_id].CmdBuffer[2], SCSIDevices[scsi_id].CmdBuffer[3], SCSIDevices[scsi_id].CmdBuffer[4], SCSIDevices[scsi_id].CmdBuffer[5], SCSIDevices[scsi_id].CmdBuffer[6], SCSIDevices[scsi_id].CmdBuffer[7]); + cdrom_log("CD-ROM %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); return 1; } @@ -2739,7 +2784,7 @@ int cdrom_write_to_dma(uint8_t id) if (cdrom_drives[id].bus_type) { - ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id); + ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } else { @@ -2810,14 +2855,15 @@ int cdrom_phase_callback(uint8_t id) } /* Reimplement as 8-bit due to reimplementation of IDE data read and write. */ -uint8_t cdrom_read(uint8_t channel) +uint32_t cdrom_read(uint8_t channel, int length) { uint8_t *cdbufferb; + uint16_t *cdbufferw; + uint32_t *cdbufferl; uint8_t id = atapi_cdrom_drives[channel]; - // uint16_t temp = 0; - uint8_t temp = 0; + uint32_t temp = 0; int ret = 0; if (id > CDROM_NUM) @@ -2826,15 +2872,33 @@ uint8_t cdrom_read(uint8_t channel) } cdbufferb = (uint8_t *) cdrom[id].buffer; + cdbufferw = cdrom[id].buffer; + cdbufferl = (uint32_t *) cdrom[id].buffer; - temp = cdbufferb[cdrom[id].pos]; - - cdrom[id].pos++; - cdrom[id].request_pos++; + switch(length) + { + case 1: + temp = cdbufferb[cdrom[id].pos]; + cdrom[id].pos++; + cdrom[id].request_pos++; + break; + case 2: + temp = cdbufferw[cdrom[id].pos >> 1]; + cdrom[id].pos += 2; + cdrom[id].request_pos += 2; + break; + case 4: + temp = cdbufferl[cdrom[id].pos >> 2]; + cdrom[id].pos += 4; + cdrom[id].request_pos += 4; + break; + default: + return 0; + } if (cdrom[id].packet_status == CDROM_PHASE_DATA_IN) { - cdrom[id].total_read++; + cdrom[id].total_read += length; ret = cdrom_block_check(id); /* If the block check has returned 0, this means all the requested blocks have been read, therefore the command has finished. */ if (ret) @@ -2866,9 +2930,12 @@ uint8_t cdrom_read(uint8_t channel) } /* Reimplement as 8-bit due to reimplementation of IDE data read and write. */ -void cdrom_write(uint8_t channel, uint8_t val) +void cdrom_write(uint8_t channel, uint32_t val, int length) { + uint8_t i = 0; uint8_t *cdbufferb; + uint16_t *cdbufferw; + uint32_t *cdbufferl; uint8_t id = atapi_cdrom_drives[channel]; @@ -2880,14 +2947,34 @@ void cdrom_write(uint8_t channel, uint8_t val) } cdbufferb = (uint8_t *) cdrom[id].buffer; + cdbufferw = cdrom[id].buffer; + cdbufferl = (uint32_t *) cdrom[id].buffer; - cdbufferb[cdrom[id].pos] = val; - cdrom[id].pos++; + switch(length) + { + case 1: + cdbufferb[cdrom[id].pos] = val & 0xff; + cdrom[id].pos++; + break; + case 2: + cdbufferw[cdrom[id].pos >> 1] = val & 0xff; + cdrom[id].pos += 2; + break; + case 4: + cdbufferl[cdrom[id].pos >> 2] = val; + cdrom[id].pos += 4; + break; + default: + return; + } if (cdrom[id].packet_status == CDROM_PHASE_DATA_OUT) { - ret = cdrom_mode_select_write(id, val); - cdrom_mode_select_return(id, ret); + for (i = 0; i < length; i++) + { + ret = cdrom_mode_select_write(id, val); + cdrom_mode_select_return(id, ret); + } return; } else if (cdrom[id].packet_status == CDROM_PHASE_IDLE) diff --git a/src/cdrom.h b/src/cdrom.h index 032e2978d..759c5e134 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -94,7 +94,7 @@ typedef struct __attribute__((__packed__)) int prev_status; int unit_attention; - uint8_t sense[18]; + uint8_t sense[256]; int request_pos; @@ -135,6 +135,7 @@ typedef struct __attribute__((__packed__)) uint8_t ide_channel; uint8_t scsi_device_id; + uint8_t scsi_device_lun; uint8_t sound_on; } cdrom_drive_t; @@ -143,7 +144,7 @@ extern cdrom_drive_t cdrom_drives[CDROM_NUM]; extern uint8_t atapi_cdrom_drives[8]; -extern uint8_t scsi_cdrom_drives[16]; +extern uint8_t scsi_cdrom_drives[16][8]; extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); @@ -175,6 +176,7 @@ typedef struct uint32_t cd_end; int16_t cd_buffer[BUF_SIZE]; int cd_buflen; + int actual_requested_blocks; } cdrom_ioctl_t; void ioctl_close(uint8_t id); @@ -189,8 +191,8 @@ int cdrom_CDROM_PHASE_to_scsi(uint8_t id); int cdrom_atapi_phase_to_scsi(uint8_t id); void cdrom_command(uint8_t id, uint8_t *cdb); int cdrom_phase_callback(uint8_t id); -uint8_t cdrom_read(uint8_t channel); -void cdrom_write(uint8_t channel, uint8_t val); +uint32_t cdrom_read(uint8_t channel, int length); +void cdrom_write(uint8_t channel, uint32_t val, int length); int cdrom_lba_to_msf_accurate(int lba); void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); diff --git a/src/ide.c b/src/ide.c index c0d98f3a6..5c4063f01 100644 --- a/src/ide.c +++ b/src/ide.c @@ -344,6 +344,7 @@ static void ide_identify(IDE *ide) h = hdc[cur_ide[ide->board]].hpc; /* Heads */ s = hdc[cur_ide[ide->board]].spt; /* Sectors */ + ide->buffer[0] = 0x40; /* Fixed disk */ ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ @@ -372,6 +373,7 @@ static void ide_identify(IDE *ide) ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[61] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16; + ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/ // ide->buffer[63] = 7; /*Multiword DMA*/ if (ide->board < 2) { @@ -380,8 +382,8 @@ static void ide_identify(IDE *ide) ide->buffer[63] = ide->dma_identify_data[1]; ide->buffer[65] = 150; ide->buffer[66] = 150; - ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ - ide->buffer[88] = ide->dma_identify_data[2]; + // ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ + // ide->buffer[88] = ide->dma_identify_data[2]; } } @@ -405,6 +407,7 @@ static void ide_atapi_identify(IDE *ide) ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[73] = 6; ide->buffer[73] = 9; + ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) { @@ -751,12 +754,14 @@ void resetide(void) int idetimes = 0; -void ide_write_data(int ide_board, uint8_t val) +void ide_write_data(int ide_board, uint32_t val, int length) { int ret = 0; IDE *ide = &ide_drives[cur_ide[ide_board]]; uint8_t *idebufferb = (uint8_t *) ide->buffer; + uint16_t *idebufferw = ide->buffer; + uint32_t *idebufferl = (uint32_t *) ide->buffer; #if 0 if (ide_drive_is_cdrom(ide)) @@ -768,12 +773,14 @@ void ide_write_data(int ide_board, uint8_t val) // ide_log("Write IDEw %04X\n",val); if (ide->command == WIN_PACKETCMD) { + ide->pos = 0; + if (!ide_drive_is_cdrom(ide)) { return; } - cdrom_write(cur_ide[ide_board], val); + cdrom_write(cur_ide[ide_board], val, length); if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) { @@ -783,8 +790,23 @@ void ide_write_data(int ide_board, uint8_t val) } else { - idebufferb[ide->pos] = val; - ide->pos++; + switch(length) + { + case 1: + idebufferb[ide->pos] = val & 0xff; + ide->pos++; + break; + case 2: + idebufferw[ide->pos >> 1] = val & 0xffff; + ide->pos += 2; + break; + case 4: + idebufferl[ide->pos >> 2] = val; + ide->pos += 4; + break; + default: + return; + } if (ide->pos>=512) { @@ -807,15 +829,13 @@ void ide_write_data(int ide_board, uint8_t val) void writeidew(int ide_board, uint16_t val) { // ide_log("WriteIDEw %04X\n", val); - ide_write_data(ide_board, val); - ide_write_data(ide_board, val >> 8); + ide_write_data(ide_board, val, 2); } void writeidel(int ide_board, uint32_t val) { // ide_log("WriteIDEl %08X\n", val); - writeidew(ide_board, val); - writeidew(ide_board, val >> 16); + ide_write_data(ide_board, val, 4); } void writeide(int ide_board, uint16_t addr, uint8_t val) @@ -832,7 +852,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) switch (addr) { case 0x1F0: /* Data */ - ide_write_data(ide_board, val); + // writeidew(ide_board, val | (val << 8)); + writeidew(ide_board, val | (val << 8)); return; /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ @@ -1292,21 +1313,24 @@ ide_bad_command: // fatal("Bad IDE write %04X %02X\n", addr, val); } -uint8_t ide_read_data(int ide_board) +uint32_t ide_read_data(int ide_board, int length) { IDE *ide = &ide_drives[cur_ide[ide_board]]; - uint8_t temp; + uint32_t temp; uint8_t *idebufferb = (uint8_t *) ide->buffer; + uint16_t *idebufferw = ide->buffer; + uint32_t *idebufferl = (uint32_t *) ide->buffer; if (ide->command == WIN_PACKETCMD) { + ide->pos = 0; if (!ide_drive_is_cdrom(ide)) { ide_log("Drive not CD-ROM (position: %i)\n", ide->pos); return 0; } - temp = cdrom_read(cur_ide[ide_board]); + temp = cdrom_read(cur_ide[ide_board], length); if (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback) { idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; @@ -1314,8 +1338,23 @@ uint8_t ide_read_data(int ide_board) } else { - temp = idebufferb[ide->pos]; - ide->pos++; + switch (length) + { + case 1: + temp = idebufferb[ide->pos]; + ide->pos++; + break; + case 2: + temp = idebufferw[ide->pos >> 1]; + ide->pos += 2; + break; + case 4: + temp = idebufferb[ide->pos >> 2]; + ide->pos += 4; + break; + default: + return 0; + } } if (ide->pos>=512 && ide->command != WIN_PACKETCMD) { @@ -1367,7 +1406,10 @@ uint8_t readide(int ide_board, uint16_t addr) switch (addr) { case 0x1F0: /* Data */ - return ide_read_data(ide_board); + // temp = ide_read_data(ide_board, 1); + tempw = readidew(ide_board); + // pclog("Read IDEW %04X\n", tempw); + temp = tempw & 0xff; break; /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), @@ -1517,20 +1559,17 @@ int all_blocks_total = 0; uint16_t readidew(int ide_board) { - uint16_t temp = 0; - uint16_t temp2 = 0; - temp = ide_read_data(ide_board); - temp2 = ide_read_data(ide_board); - temp2 <<= 8; - return (temp | temp2); + uint16_t temp; + temp = ide_read_data(ide_board, 2); + return temp; } uint32_t readidel(int ide_board) { uint16_t temp; // ide_log("Read IDEl %i\n", ide_board); - temp = readidew(ide_board); - return temp | (readidew(ide_board) << 16); + temp = ide_read_data(ide_board, 4); + return temp; } int times30=0; diff --git a/src/mem.c b/src/mem.c index 7d5e965ed..e79b54d6c 100644 --- a/src/mem.c +++ b/src/mem.c @@ -975,7 +975,7 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_ if (!(flags & 1)) { - pclog("Trying to read or write a page that is not present!\n"); + // pclog("Trying to read or write a page that is not present!\n"); is_page_fault = 1; } @@ -983,12 +983,12 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_ { if (!(flags & 4) && mem_cpl3_check()) { - pclog("Trying to read a system page from user mode!\n"); + // pclog("Trying to read a system page from user mode!\n"); is_page_fault = 1; } if (rw && !(flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))) { - pclog("Trying to write a read-only-for-user page from user mode!\n"); + // pclog("Trying to write a read-only-for-user page from user mode!\n"); is_page_fault = 1; } } diff --git a/src/pc.c b/src/pc.c index 13408d206..764af631c 100644 --- a/src/pc.c +++ b/src/pc.c @@ -275,7 +275,7 @@ void initpc(int argc, char *argv[]) { if (cdrom_drives[i].bus_type) { - SCSIReset(cdrom_drives[i].scsi_device_id); + SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); } if (cdrom_drives[i].host_drive == 0) @@ -453,7 +453,7 @@ void resetpchard() { if (cdrom_drives[i].bus_type) { - SCSIReset(cdrom_drives[i].scsi_device_id); + SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); } } @@ -736,6 +736,7 @@ void loadconfig(char *fn) cdrom_drives[0].bus_type = config_get_int(NULL, "cdrom_1_bus_type", 0); cdrom_drives[0].ide_channel = config_get_int(NULL, "cdrom_1_ide_channel", 2); cdrom_drives[0].scsi_device_id = config_get_int(NULL, "cdrom_1_scsi_device_id", 2); + cdrom_drives[0].scsi_device_lun = config_get_int(NULL, "cdrom_1_scsi_device_lun", 0); p = (char *)config_get_string(NULL, "cdrom_1_iso_path", ""); if (p) strcpy(cdrom_iso[0].iso_path, p); @@ -748,6 +749,7 @@ void loadconfig(char *fn) cdrom_drives[1].bus_type = config_get_int(NULL, "cdrom_2_bus_type", 0); cdrom_drives[1].ide_channel = config_get_int(NULL, "cdrom_2_ide_channel", 3); cdrom_drives[1].scsi_device_id = config_get_int(NULL, "cdrom_2_scsi_device_id", 3); + cdrom_drives[1].scsi_device_lun = config_get_int(NULL, "cdrom_2_scsi_device_lun", 0); p = (char *)config_get_string(NULL, "cdrom_2_iso_path", ""); if (p) strcpy(cdrom_iso[1].iso_path, p); @@ -760,6 +762,7 @@ void loadconfig(char *fn) cdrom_drives[2].bus_type = config_get_int(NULL, "cdrom_3_bus_type", 0); cdrom_drives[2].ide_channel = config_get_int(NULL, "cdrom_3_ide_channel", 4); cdrom_drives[2].scsi_device_id = config_get_int(NULL, "cdrom_3_scsi_device_id", 4); + cdrom_drives[2].scsi_device_lun = config_get_int(NULL, "cdrom_3_scsi_device_lun", 0); p = (char *)config_get_string(NULL, "cdrom_3_iso_path", ""); if (p) strcpy(cdrom_iso[2].iso_path, p); @@ -772,6 +775,7 @@ void loadconfig(char *fn) cdrom_drives[3].bus_type = config_get_int(NULL, "cdrom_4_bus_type", 0); cdrom_drives[3].ide_channel = config_get_int(NULL, "cdrom_4_ide_channel", 5); cdrom_drives[3].scsi_device_id = config_get_int(NULL, "cdrom_4_scsi_device_id", 5); + cdrom_drives[3].scsi_device_lun = config_get_int(NULL, "cdrom_4_scsi_device_lun", 0); p = (char *)config_get_string(NULL, "cdrom_4_iso_path", ""); if (p) strcpy(cdrom_iso[3].iso_path, p); @@ -951,6 +955,7 @@ void saveconfig() config_set_int(NULL, "cdrom_1_bus_type", cdrom_drives[0].bus_type); config_set_int(NULL, "cdrom_1_ide_channel", cdrom_drives[0].ide_channel); config_set_int(NULL, "cdrom_1_scsi_device_id", cdrom_drives[0].scsi_device_id); + config_set_int(NULL, "cdrom_1_scsi_device_lun", cdrom_drives[0].scsi_device_lun); config_set_string(NULL, "cdrom_1_iso_path", cdrom_iso[0].iso_path); @@ -959,7 +964,8 @@ void saveconfig() config_set_int(NULL, "cdrom_2_sound_on", cdrom_drives[1].sound_on); config_set_int(NULL, "cdrom_2_bus_type", cdrom_drives[1].bus_type); config_set_int(NULL, "cdrom_2_ide_channel", cdrom_drives[1].ide_channel); - config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id); + config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id); + config_set_int(NULL, "cdrom_2_scsi_device_lun", cdrom_drives[1].scsi_device_lun); config_set_string(NULL, "cdrom_2_iso_path", cdrom_iso[1].iso_path); @@ -968,7 +974,8 @@ void saveconfig() config_set_int(NULL, "cdrom_3_sound_on", cdrom_drives[2].sound_on); config_set_int(NULL, "cdrom_3_bus_type", cdrom_drives[2].bus_type); config_set_int(NULL, "cdrom_3_ide_channel", cdrom_drives[2].ide_channel); - config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id); + config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id); + config_set_int(NULL, "cdrom_3_scsi_device_lun", cdrom_drives[2].scsi_device_lun); config_set_string(NULL, "cdrom_3_iso_path", cdrom_iso[2].iso_path); @@ -977,7 +984,8 @@ void saveconfig() config_set_int(NULL, "cdrom_4_sound_on", cdrom_drives[3].sound_on); config_set_int(NULL, "cdrom_4_bus_type", cdrom_drives[3].bus_type); config_set_int(NULL, "cdrom_4_ide_channel", cdrom_drives[3].ide_channel); - config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id); + config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id); + config_set_int(NULL, "cdrom_4_scsi_device_lun", cdrom_drives[3].scsi_device_lun); config_set_string(NULL, "cdrom_4_iso_path", cdrom_iso[3].iso_path); diff --git a/src/pc.rc b/src/pc.rc index c90783586..10067fd2d 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -56,6 +56,7 @@ BEGIN MENUITEM "&I:",IDM_CDROM_1_I MENUITEM "&J:",IDM_CDROM_1_J END + MENUITEM SEPARATOR POPUP "S&CSI ID..." BEGIN MENUITEM "&0",IDM_CDROM_1_0 @@ -74,6 +75,17 @@ BEGIN MENUITEM "14",IDM_CDROM_1_14 MENUITEM "15",IDM_CDROM_1_15 END + POPUP "SCSI &LUN..." + BEGIN + MENUITEM "&0",IDM_CDROM_1_LUN_0 + MENUITEM "&1",IDM_CDROM_1_LUN_1 + MENUITEM "&2",IDM_CDROM_1_LUN_2 + MENUITEM "&3",IDM_CDROM_1_LUN_3 + MENUITEM "&4",IDM_CDROM_1_LUN_4 + MENUITEM "&5",IDM_CDROM_1_LUN_5 + MENUITEM "&6",IDM_CDROM_1_LUN_6 + MENUITEM "&7",IDM_CDROM_1_LUN_7 + END MENUITEM SEPARATOR MENUITEM "&ISO...",IDM_CDROM_1_ISO END @@ -98,6 +110,7 @@ BEGIN MENUITEM "&I:",IDM_CDROM_2_I MENUITEM "&J:",IDM_CDROM_2_J END + MENUITEM SEPARATOR POPUP "S&CSI ID..." BEGIN MENUITEM "&0",IDM_CDROM_2_0 @@ -116,6 +129,17 @@ BEGIN MENUITEM "14",IDM_CDROM_2_14 MENUITEM "15",IDM_CDROM_2_15 END + POPUP "SCSI &LUN..." + BEGIN + MENUITEM "&0",IDM_CDROM_2_LUN_0 + MENUITEM "&1",IDM_CDROM_2_LUN_1 + MENUITEM "&2",IDM_CDROM_2_LUN_2 + MENUITEM "&3",IDM_CDROM_2_LUN_3 + MENUITEM "&4",IDM_CDROM_2_LUN_4 + MENUITEM "&5",IDM_CDROM_2_LUN_5 + MENUITEM "&6",IDM_CDROM_2_LUN_6 + MENUITEM "&7",IDM_CDROM_2_LUN_7 + END MENUITEM SEPARATOR MENUITEM "&ISO...",IDM_CDROM_2_ISO END @@ -140,6 +164,7 @@ BEGIN MENUITEM "&I:",IDM_CDROM_3_I MENUITEM "&J:",IDM_CDROM_3_J END + MENUITEM SEPARATOR POPUP "S&CSI ID..." BEGIN MENUITEM "&0",IDM_CDROM_3_0 @@ -158,6 +183,17 @@ BEGIN MENUITEM "14",IDM_CDROM_3_14 MENUITEM "15",IDM_CDROM_3_15 END + POPUP "SCSI &LUN..." + BEGIN + MENUITEM "&0",IDM_CDROM_3_LUN_0 + MENUITEM "&1",IDM_CDROM_3_LUN_1 + MENUITEM "&2",IDM_CDROM_3_LUN_2 + MENUITEM "&3",IDM_CDROM_3_LUN_3 + MENUITEM "&4",IDM_CDROM_3_LUN_4 + MENUITEM "&5",IDM_CDROM_3_LUN_5 + MENUITEM "&6",IDM_CDROM_3_LUN_6 + MENUITEM "&7",IDM_CDROM_3_LUN_7 + END MENUITEM SEPARATOR MENUITEM "&ISO...",IDM_CDROM_3_ISO END @@ -181,6 +217,7 @@ BEGIN MENUITEM "&I:",IDM_CDROM_4_I MENUITEM "&J:",IDM_CDROM_4_J END + MENUITEM SEPARATOR POPUP "S&CSI ID..." BEGIN MENUITEM "&0",IDM_CDROM_4_0 @@ -199,6 +236,17 @@ BEGIN MENUITEM "14",IDM_CDROM_4_14 MENUITEM "15",IDM_CDROM_4_15 END + POPUP "SCSI &LUN..." + BEGIN + MENUITEM "&0",IDM_CDROM_4_LUN_0 + MENUITEM "&1",IDM_CDROM_4_LUN_1 + MENUITEM "&2",IDM_CDROM_4_LUN_2 + MENUITEM "&3",IDM_CDROM_4_LUN_3 + MENUITEM "&4",IDM_CDROM_4_LUN_4 + MENUITEM "&5",IDM_CDROM_4_LUN_5 + MENUITEM "&6",IDM_CDROM_4_LUN_6 + MENUITEM "&7",IDM_CDROM_4_LUN_7 + END MENUITEM SEPARATOR MENUITEM "&ISO...",IDM_CDROM_4_ISO END diff --git a/src/resources.h b/src/resources.h index 0c70ea07b..406bfba81 100644 --- a/src/resources.h +++ b/src/resources.h @@ -65,6 +65,14 @@ #define IDM_CDROM_1_13 40713 #define IDM_CDROM_1_14 40714 #define IDM_CDROM_1_15 40715 +#define IDM_CDROM_1_LUN_0 40800 +#define IDM_CDROM_1_LUN_1 40801 +#define IDM_CDROM_1_LUN_2 40802 +#define IDM_CDROM_1_LUN_3 40803 +#define IDM_CDROM_1_LUN_4 40804 +#define IDM_CDROM_1_LUN_5 40805 +#define IDM_CDROM_1_LUN_6 40806 +#define IDM_CDROM_1_LUN_7 40807 #define IDM_CDROM_2_ISO 41100 #define IDM_CDROM_2_RELOAD 41101 #define IDM_CDROM_2_EMPTY 41200 @@ -95,6 +103,14 @@ #define IDM_CDROM_2_13 41713 #define IDM_CDROM_2_14 41714 #define IDM_CDROM_2_15 41715 +#define IDM_CDROM_2_LUN_0 41800 +#define IDM_CDROM_2_LUN_1 41801 +#define IDM_CDROM_2_LUN_2 41802 +#define IDM_CDROM_2_LUN_3 41803 +#define IDM_CDROM_2_LUN_4 41804 +#define IDM_CDROM_2_LUN_5 41805 +#define IDM_CDROM_2_LUN_6 41806 +#define IDM_CDROM_2_LUN_7 41807 #define IDM_CDROM_3_ISO 42100 #define IDM_CDROM_3_RELOAD 42101 #define IDM_CDROM_3_EMPTY 42200 @@ -125,6 +141,14 @@ #define IDM_CDROM_3_13 42713 #define IDM_CDROM_3_14 42714 #define IDM_CDROM_3_15 42715 +#define IDM_CDROM_3_LUN_0 42800 +#define IDM_CDROM_3_LUN_1 42801 +#define IDM_CDROM_3_LUN_2 42802 +#define IDM_CDROM_3_LUN_3 42803 +#define IDM_CDROM_3_LUN_4 42804 +#define IDM_CDROM_3_LUN_5 42805 +#define IDM_CDROM_3_LUN_6 42806 +#define IDM_CDROM_3_LUN_7 42807 #define IDM_CDROM_4_ISO 43100 #define IDM_CDROM_4_RELOAD 43101 #define IDM_CDROM_4_EMPTY 43200 @@ -155,6 +179,14 @@ #define IDM_CDROM_4_13 43713 #define IDM_CDROM_4_14 43714 #define IDM_CDROM_4_15 43715 +#define IDM_CDROM_4_LUN_0 43800 +#define IDM_CDROM_4_LUN_1 43801 +#define IDM_CDROM_4_LUN_2 43802 +#define IDM_CDROM_4_LUN_3 43803 +#define IDM_CDROM_4_LUN_4 43804 +#define IDM_CDROM_4_LUN_5 43805 +#define IDM_CDROM_4_LUN_6 43806 +#define IDM_CDROM_4_LUN_7 43807 #define IDM_IDE_TER_ENABLED 44000 #define IDM_IDE_TER_IRQ9 44009 #define IDM_IDE_TER_IRQ10 44010 diff --git a/src/scsi.c b/src/scsi.c index 5f709815d..17f573b14 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -16,82 +16,38 @@ uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; uint8_t SCSIStatus = SCSI_STATUS_OK; -int SCSICallback[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +int SCSICallback[16][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 } }; uint8_t scsi_cdrom_id = 3; /*common setting*/ -//Get the transfer length of the command -void SCSIGetLength(uint8_t id, int *datalen) -{ - *datalen = SCSIDevices[id].CmdBufferLength; -} - -#if 0 -//Execute SCSI command -void SCSIExecCommand(uint8_t id, uint8_t *buffer, uint8_t *cdb) -{ - SCSICDROM_Command(id, buffer, cdb); -} - -//Read pending data from the resulting SCSI command -void SCSIReadData(uint8_t id, uint8_t *cdb, uint8_t *data, int datalen) -{ - SCSICDROM_ReadData(id, cdb, data, datalen); -} - -///// -void SCSIDMAResetPosition(uint8_t Id) -{ - //Reset position in memory after reaching its limit - SCSIDevices[Id].pos = 0; -} - -//Read data from buffer with given position in buffer memory -void SCSIRead(uint8_t Id, uint8_t *dstbuf, uint8_t *srcbuf, uint32_t len_size) -{ - if (!len_size) //If there's no data, don't try to do anything. - return; - - int c; - - for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested - { - memcpy(dstbuf, srcbuf + SCSIDevices[Id].pos, len_size); - SCSIDevices[Id].pos = c; - - //pclog("SCSI Read: position at %i\n", SCSIDevices[Id].pos); - } -} - -//Write data to buffer with given position in buffer memory -void SCSIWrite(uint8_t Id, uint8_t *srcbuf, uint8_t *dstbuf, uint32_t len_size) -{ - int c; - - for (c = 0; c <= len_size; c++) //Count as many bytes as the length of the buffer is requested - { - memcpy(srcbuf + SCSIDevices[Id].pos, dstbuf, len_size); - SCSIDevices[Id].pos = c; - - //pclog("SCSI Write: position at %i\n", SCSIDevices[Id].pos); - } -} -///// -#endif - //Initialization function for the SCSI layer -void SCSIReset(uint8_t Id) +void SCSIReset(uint8_t id, uint8_t lun) { - uint8_t cdrom_id = scsi_cdrom_drives[Id]; + uint8_t cdrom_id = scsi_cdrom_drives[id][lun]; - if (buslogic_scsi_drive_is_cdrom(Id)) + if (buslogic_scsi_drive_is_cdrom(id, lun)) { - SCSICallback[cdrom_id]=0; + SCSICallback[id][lun] = 0; cdrom_reset(cdrom_id); - SCSIDevices[Id].LunType = SCSI_CDROM; + SCSIDevices[id][lun].LunType = SCSI_CDROM; } else { - SCSIDevices[Id].LunType = SCSI_NONE; + SCSIDevices[id][lun].LunType = SCSI_NONE; } } diff --git a/src/scsi.h b/src/scsi.h index e59d5b60a..125131732 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -188,7 +188,7 @@ int MediaPresent; extern uint8_t SCSIStatus; extern uint8_t SCSIPhase; -extern int SCSICallback[16]; +extern int SCSICallback[16][8]; extern uint8_t scsi_cdrom_id; struct @@ -221,14 +221,13 @@ extern int prev_status; struct { - uint32_t pos; uint8_t CmdBuffer[390144]; uint32_t CmdBufferLength; int LunType; uint32_t InitLength; -} SCSIDevices[16]; +} SCSIDevices[16][8]; -extern void SCSIReset(uint8_t Id); +extern void SCSIReset(uint8_t id, uint8_t lun); uint32_t SCSICDROMModeSense(uint8_t *buf, uint32_t pos, uint8_t type); uint8_t SCSICDROMSetProfile(uint8_t *buf, uint8_t *index, uint16_t profile); diff --git a/src/vid_s3.c b/src/vid_s3.c index caaf63cb8..896447174 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2314,7 +2314,7 @@ void *s3_bahamas64_init() { s3_t *s3 = s3_init("roms/bahamas64.BIN", S3_VISION864); - s3->id = 0xc1; /*Vision864P*/ + s3->id = 0xc0; /*Vision864P*/ s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; @@ -2393,7 +2393,7 @@ void *s3_phoenix_vision864_init() { s3_t *s3 = s3_init("roms/86c864p.bin", S3_VISION864); - s3->id = 0xc1; /*Vision864P*/ + s3->id = 0xc0; /*Vision864P*/ s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; @@ -2413,7 +2413,7 @@ void *s3_diamond_stealth64_init() s3_t *s3 = s3_init("roms/STEALT64.BIN", S3_VISION864); svga_t *svga = &s3->svga; - s3->id = 0xc1; /*Vision864P*/ + s3->id = 0xc0; /*Vision864P*/ s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; @@ -2432,7 +2432,7 @@ void *s3_miro_vision964_init() { s3_t *s3 = s3_init("roms/mirocrystal.VBI", S3_VISION964); - s3->id = 0xd1; /*Vision964P*/ + s3->id = 0xd0; /*Vision964P*/ s3->id_ext = s3->id_ext_pci = 0xd1; s3->packed_mmio = 1; diff --git a/src/win.c b/src/win.c index 0d0ac7b5a..d9c98fe24 100644 --- a/src/win.c +++ b/src/win.c @@ -526,6 +526,7 @@ int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; int valid_dma_channels[3] = { 5, 6, 7 }; int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; +int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; int find_in_array(int *array, int val, int len, int menu_base) { @@ -663,18 +664,25 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (!find_in_array(valid_ide_channels, cdrom_drives[e].ide_channel, 8, IDM_CDROM_1_C + (e * 1000))) { - fatal("Tertiary IDE controller: Invalid IRQ\n"); + fatal("CD-ROM %i: Invalid IDE channel\n", e); } CheckMenuItem(menu, IDM_CDROM_1_C + (e * 1000) + cdrom_drives[e].ide_channel, MF_CHECKED); if (!find_in_array(valid_scsi_ids, cdrom_drives[e].scsi_device_id, 15, IDM_CDROM_1_0 + (e * 1000))) { - fatal("Tertiary IDE controller: Invalid IRQ\n"); + fatal("CD-ROM %i: Invalid SCSI ID\n", e); } CheckMenuItem(menu, IDM_CDROM_1_0 + (e * 1000) + cdrom_drives[e].scsi_device_id, MF_CHECKED); + if (!find_in_array(valid_scsi_luns, cdrom_drives[e].scsi_device_lun, 8, IDM_CDROM_1_LUN_0 + (e * 1000))) + { + fatal("CD-ROM %i: Invalid SCSI LUN\n", e); + } + + CheckMenuItem(menu, IDM_CDROM_1_LUN_0 + (e * 1000) + cdrom_drives[e].scsi_device_lun, MF_CHECKED); + if (cdrom_drives[e].host_drive == 200) { CheckMenuItem(menu, IDM_CDROM_1_ISO + (e * 1000), MF_CHECKED); @@ -1685,6 +1693,26 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM pause = 0; break; + case IDM_CDROM_1_LUN_0 ... IDM_CDROM_1_LUN_7: + case IDM_CDROM_2_LUN_0 ... IDM_CDROM_2_LUN_7: + case IDM_CDROM_3_LUN_0 ... IDM_CDROM_3_LUN_7: + case IDM_CDROM_4_LUN_0 ... IDM_CDROM_4_LUN_7: + menu_sub_param = LOWORD(wParam) % 100; + cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_LUN_0); + if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) + { + break; + } + pause = 1; + Sleep(100); + CheckMenuItem(hmenu, IDM_CDROM_1_LUN_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_lun, MF_UNCHECKED); + cdrom_drives[cdrom_id].scsi_device_lun = menu_sub_param; + CheckMenuItem(hmenu, IDM_CDROM_1_LUN_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_lun, MF_CHECKED); + saveconfig(); + resetpchard(); + pause = 0; + break; + case IDM_IDE_TER_ENABLED: if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) { From 4dba9668728aa66f7903421e30839d790cfc2f05 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 18 Jan 2017 22:33:52 +0100 Subject: [PATCH 027/392] Reverted the makefiles back to 10 seconds sleeping time. --- src/Makefile.mingw | 4 ++-- src/Makefile.mingw64 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 58716145d..89afc76e1 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) - sleep 5 + sleep 10 strip "86Box.exe" - sleep 5 + sleep 10 all : 86Box.exe diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 3c3c1524b..4f6e02a7c 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -32,9 +32,9 @@ LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lws 86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) - sleep 5 + sleep 10 strip "86Box64.exe" - sleep 5 + sleep 10 all : 86Box64.exe From 3aa22e19ddd68d362be4eaf0ae6fabe21fe56b87 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 19 Jan 2017 00:11:21 +0100 Subject: [PATCH 028/392] Revert "Add in NV4 context switching" --- src/vid_nv_riva128.c | 59 +------------------------------------------- 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index d23cf90f2..d3a94bf31 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -151,9 +151,6 @@ typedef struct riva128_t uint32_t fifo_enable; - uint32_t fifo_st2_addr; - uint32_t fifo_st2_data; - uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; @@ -229,9 +226,6 @@ const char* riva128_pfifo_interrupts[32] = "CACHE_ERROR","","","","RUNOUT","","","","RUNOUT_OVERFLOW","","","","DMA_PUSHER","","","","DMA_PTE","","","","","","","","","","","","","","","" }; -static uint32_t riva128_ramht_lookup(uint32_t handle, void *p); -static void riva128_pgraph_volatile_reset(void *p); - static uint8_t riva128_pci_read(int func, int addr, void *p); static void riva128_pci_write(int func, int addr, uint8_t val, void *p); @@ -971,50 +965,6 @@ static uint8_t riva128_pextdev_read(uint32_t addr, void *p) return ret; } -static void rivatnt_pgraph_ctx_switch(uint32_t addr, uint32_t val, void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - if(!(riva128->fifo_st2_addr & 1)) return; - - unsigned old_subc = (riva128->ctx_user >> 13) & 7; - unsigned new_subc = (riva128->fifo_st2_addr >> 12) & 7; - unsigned mthd = (riva128->fifo_st2_addr >> 1) & 0x7ff; - riva128->fifo_st2_addr &= ~1; - unsigned do_ctx_switch = mthd == 0; - - if(old_subc != new_subc || do_ctx_switch) - { - if(do_ctx_switch) riva128->ctx_cache[new_subc][3] = riva128->fifo_st2_data & 0xffff; - - uint32_t ctx_mask = 0x0303f0ff; - - unsigned reload = (riva128->debug[1] >> 15) & 1; - if(reload || do_ctx_switch) - { - uint32_t instance = riva128_ramht_lookup(val, riva128); - riva128->ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; - riva128->ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; - riva128->ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; - riva128->ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; - } - - unsigned reset = (riva128->debug[2] >> 28) & 1; - if(reset) - { - riva128->debug[1] |= 1; - riva128_pgraph_volatile_reset(riva128); - } - else riva128->debug[1] &= ~1; - - if(riva128->debug[1] & 0x100000) - { - for(int i = 0; i < 5; i++) riva128->ctx_switch[i] = riva128->ctx_cache[new_subc][i]; - } - } -} - static uint8_t riva128_pgraph_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -1416,13 +1366,6 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x40008c: riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); break; - case 0x400754: - riva128->pgraph.fifo_st2_addr = val; - break; - case 0x400758: - riva128->pgraph.fifo_st2_data = val; - rivatnt_pgraph_ctx_switch(riva128); - break; } } @@ -1612,7 +1555,7 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui if(riva128->card_id == 0x03) { uint32_t tmp = riva128_ramht_lookup(val, riva128); - riva128->pgraph.instance = (tmp & 0xffff) << 2; + riva128->pgraph.instance = (tmp & 0xffff) << 4; unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; unsigned new_subc = subchanid & 7; if((old_subc != new_subc) || !offset) From 69dc594610b99076e04c6260e5af647127e56c8b Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 19 Jan 2017 06:56:50 -0600 Subject: [PATCH 029/392] Fix compilation --- src/vid_nv_riva128.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index d23cf90f2..a28f9b8b7 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -971,46 +971,46 @@ static uint8_t riva128_pextdev_read(uint32_t addr, void *p) return ret; } -static void rivatnt_pgraph_ctx_switch(uint32_t addr, uint32_t val, void *p) +static void rivatnt_pgraph_ctx_switch(void *p) { riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - if(!(riva128->fifo_st2_addr & 1)) return; + if(!(riva128->pgraph.fifo_st2_addr & 1)) return; - unsigned old_subc = (riva128->ctx_user >> 13) & 7; - unsigned new_subc = (riva128->fifo_st2_addr >> 12) & 7; - unsigned mthd = (riva128->fifo_st2_addr >> 1) & 0x7ff; - riva128->fifo_st2_addr &= ~1; + unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; + unsigned new_subc = (riva128->pgraph.fifo_st2_addr >> 12) & 7; + unsigned mthd = (riva128->pgraph.fifo_st2_addr >> 1) & 0x7ff; + riva128->pgraph.fifo_st2_addr &= ~1; unsigned do_ctx_switch = mthd == 0; if(old_subc != new_subc || do_ctx_switch) { - if(do_ctx_switch) riva128->ctx_cache[new_subc][3] = riva128->fifo_st2_data & 0xffff; + if(do_ctx_switch) riva128->pgraph.ctx_cache[new_subc][3] = riva128->pgraph.fifo_st2_data & 0xffff; uint32_t ctx_mask = 0x0303f0ff; - unsigned reload = (riva128->debug[1] >> 15) & 1; + unsigned reload = (riva128->pgraph.debug[1] >> 15) & 1; if(reload || do_ctx_switch) { - uint32_t instance = riva128_ramht_lookup(val, riva128); - riva128->ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; - riva128->ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; - riva128->ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; - riva128->ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; + uint32_t instance = riva128_ramht_lookup(riva128->pgraph.fifo_st2_data, riva128); + riva128->pgraph.ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; + riva128->pgraph.ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; + riva128->pgraph.ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; + riva128->pgraph.ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; } - unsigned reset = (riva128->debug[2] >> 28) & 1; + unsigned reset = (riva128->pgraph.debug[2] >> 28) & 1; if(reset) { - riva128->debug[1] |= 1; + riva128->pgraph.debug[1] |= 1; riva128_pgraph_volatile_reset(riva128); } - else riva128->debug[1] &= ~1; + else riva128->pgraph.debug[1] &= ~1; - if(riva128->debug[1] & 0x100000) + if(riva128->pgraph.debug[1] & 0x100000) { - for(int i = 0; i < 5; i++) riva128->ctx_switch[i] = riva128->ctx_cache[new_subc][i]; + for(int i = 0; i < 5; i++) riva128->pgraph.ctx_switch[i] = riva128->pgraph.ctx_cache[new_subc][i]; } } } From d9256b227b9f52b5ef932f9d811dab54e0996b70 Mon Sep 17 00:00:00 2001 From: slipstream/RoL Date: Fri, 20 Jan 2017 12:16:58 +0000 Subject: [PATCH 030/392] Crash dump changes - Crash dumps now attempt to be created in the directory with 86Box.exe - Crash dumps now attempt to find the full path + filename of the module where the crash occured, and includes it if found --- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/win-crashdump.c | 83 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 89afc76e1..e3e69794a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static +LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 4f6e02a7c..a18c8d8f3 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcap +LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcap 86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) diff --git a/src/win-crashdump.c b/src/win-crashdump.c index af01408e2..b640c61ae 100644 --- a/src/win-crashdump.c +++ b/src/win-crashdump.c @@ -5,6 +5,7 @@ */ #define _WIN32_WINNT 0x0501 #include +#include #include #include #include @@ -13,6 +14,7 @@ PVOID hExceptionHandler; char* ExceptionHandlerBuffer; +#define ExceptionHandlerBufferSize (10240) LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { @@ -28,10 +30,30 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { // So, the program is about to crash. Oh no what do? // Let's create a crash dump file as a debugging-aid. - // First, what would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. + // First, get the path to 86Box.exe. + char* CurrentBufferPointer; + GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); + if (GetLastError() != ERROR_SUCCESS) { + // Could not get the full path of 86Box.exe. Just create the file in the current directory. + CurrentBufferPointer = ExceptionHandlerBuffer; + } else { + // Walk through the string backwards looking for the last backslash, so as to remove the "86Box.exe" filename from the string. + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + for (; CurrentBufferPointer > ExceptionHandlerBuffer; CurrentBufferPointer--) { + if (CurrentBufferPointer[0] == '\\') { + // Found the backslash, null terminate the string after it. + CurrentBufferPointer[1] = 0; + break; + } + } + + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + } + + // What would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. SYSTEMTIME SystemTime; GetSystemTime(&SystemTime); - sprintf(ExceptionHandlerBuffer, + sprintf(CurrentBufferPointer, "86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp", SystemTime.wYear, SystemTime.wMonth, @@ -61,22 +83,63 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { // Now the file is open, let's write the data we were passed out in a human-readable format. + // Let's get the name of the module where the exception occured. + HMODULE hMods[1024]; + MODULEINFO modInfo; + HMODULE ipModule = 0; + DWORD cbNeeded; + // Try to get a list of all loaded modules. + if (EnumProcessModules(GetCurrentProcess(), hMods, sizeof(hMods), &cbNeeded)) { + // The list was obtained, walk through each of the modules. + for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { + // For each module, get the module information (base address, size, entry point) + GetModuleInformation(GetCurrentProcess(), hMods[i], &modInfo, sizeof(MODULEINFO)); + // If the exception address is located in the range of where this module is loaded... + if ( + (ExceptionInfo->ExceptionRecord->ExceptionAddress >= modInfo.lpBaseOfDll) && + (ExceptionInfo->ExceptionRecord->ExceptionAddress < (modInfo.lpBaseOfDll + modInfo.SizeOfImage)) + ) { + // ...this is the module we're looking for! + ipModule = hMods[i]; + break; + } + } + } + + // Start to put the crash-dump string into the buffer. + sprintf(ExceptionHandlerBuffer, "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" "" "Exception details:\r\n" "Exception NTSTATUS code: 0x%08x\r\n" - "Occured at address: 0x%p\r\n" - "Number of parameters: %d\r\n" - "Exception parameters: ", + "Occured at address: 0x%p", emulator_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, ExceptionInfo->ExceptionRecord->ExceptionCode, - ExceptionInfo->ExceptionRecord->ExceptionAddress, + ExceptionInfo->ExceptionRecord->ExceptionAddress); + + + // If we found the module that the exception occured in, get the full path to the module the exception occured at and include it. + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + if (ipModule != 0) { + sprintf(CurrentBufferPointer," ["); + GetModuleFileName(ipModule,&CurrentBufferPointer[2],ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); + if (GetLastError() == ERROR_SUCCESS) { + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(CurrentBufferPointer,"]"); + CurrentBufferPointer += 1; + } + } + + // Continue to create the crash-dump string. + sprintf(CurrentBufferPointer, + "\r\n" + "Number of parameters: %d\r\n" + "Exception parameters: ", ExceptionInfo->ExceptionRecord->NumberParameters); - char* CurrentBufferPointer; - + // Add the exception parameters to the crash-dump string. for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); @@ -87,6 +150,7 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { PCONTEXT Registers = ExceptionInfo->ContextRecord; #if defined(__i386__) && !defined(__x86_64) + // This binary is being compiled for x86, include a register dump. sprintf(CurrentBufferPointer, "\r\n" "Register dump:\r\n" @@ -98,6 +162,7 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { sprintf(CurrentBufferPointer,"\r\n"); #endif + // The crash-dump string has been created, write it to disk. WriteFile(hDumpFile, ExceptionHandlerBuffer, strlen(ExceptionHandlerBuffer), @@ -114,7 +179,7 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { void InitCrashDump() { // An exception handler should not allocate memory, so allocate 10kb for it to use if it gets called, an amount which should be more than enough. - ExceptionHandlerBuffer = malloc(10240); + ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize); // Register the exception handler. Zero first argument means this exception handler gets called last, therefore, crash dump is only made, when a crash is going to happen. hExceptionHandler = AddVectoredExceptionHandler(0,MakeCrashDump); } \ No newline at end of file From 5bac9b4ce0f72be4627c9af57a1eae99358f0727 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Jan 2017 23:41:58 +0100 Subject: [PATCH 031/392] Revert "Fix compilation" --- src/vid_nv_riva128.c | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 582de8d00..d3a94bf31 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -965,50 +965,6 @@ static uint8_t riva128_pextdev_read(uint32_t addr, void *p) return ret; } -static void rivatnt_pgraph_ctx_switch(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - if(!(riva128->pgraph.fifo_st2_addr & 1)) return; - - unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; - unsigned new_subc = (riva128->pgraph.fifo_st2_addr >> 12) & 7; - unsigned mthd = (riva128->pgraph.fifo_st2_addr >> 1) & 0x7ff; - riva128->pgraph.fifo_st2_addr &= ~1; - unsigned do_ctx_switch = mthd == 0; - - if(old_subc != new_subc || do_ctx_switch) - { - if(do_ctx_switch) riva128->pgraph.ctx_cache[new_subc][3] = riva128->pgraph.fifo_st2_data & 0xffff; - - uint32_t ctx_mask = 0x0303f0ff; - - unsigned reload = (riva128->pgraph.debug[1] >> 15) & 1; - if(reload || do_ctx_switch) - { - uint32_t instance = riva128_ramht_lookup(riva128->pgraph.fifo_st2_data, riva128); - riva128->pgraph.ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; - riva128->pgraph.ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; - riva128->pgraph.ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; - riva128->pgraph.ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; - } - - unsigned reset = (riva128->pgraph.debug[2] >> 28) & 1; - if(reset) - { - riva128->pgraph.debug[1] |= 1; - riva128_pgraph_volatile_reset(riva128); - } - else riva128->pgraph.debug[1] &= ~1; - - if(riva128->pgraph.debug[1] & 0x100000) - { - for(int i = 0; i < 5; i++) riva128->pgraph.ctx_switch[i] = riva128->pgraph.ctx_cache[new_subc][i]; - } - } -} - static uint8_t riva128_pgraph_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; From 3f612ab71a1631136febd185f20bebcda0943e7e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 20 Jan 2017 23:53:19 +0100 Subject: [PATCH 032/392] IDE dword reads and writes reverted to original operation, fixes the last hard disk problems; ATAPI CD-ROM word reads no longer incorrectly discard the upper 16 bits, fixes the CD-ROM problems; Significantly rewrote parts of the AHA-154x and BusLogic emulation, NT 3.1 RTM and MS-DOS drivers now works correctly; The function in cdrom.c to read data blocks from the disc now correctly advances the position of the sector to read in non-passthrough mode, fixes multiblock reads from directly mounted ISO's; Both ATAPI and SCSI now always check for Unit Attention and Not Ready on command execution. --- src/buslogic.c | 757 ++++++++++++++++++++++++++++------------------ src/cdrom-ioctl.c | 14 +- src/cdrom-iso.c | 18 +- src/cdrom.c | 77 +++-- src/cdrom.h | 5 +- src/ide.c | 36 ++- src/ide.h | 1 + src/scsi.c | 18 -- src/scsi.h | 1 - 9 files changed, 551 insertions(+), 376 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index e4a8d8b9a..a1404b934 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -306,7 +306,6 @@ typedef struct __attribute__((packed)) Mailbox32_t } u; } Mailbox32_t; - /////////////////////////////////////////////////////////////////////////////// // // CCB - Buslogic SCSI Command Control Block @@ -511,6 +510,10 @@ typedef struct __attribute__((packed)) Buslogic_t int DmaChannel; int IrqEnabled; int Mbx24bit; + int MailboxOutInterrupts; + int MbiActive[256]; + int DoScan; + int PendingInterrupt; } Buslogic_t; int scsi_model = 1; @@ -518,7 +521,9 @@ int scsi_base = 0x330; int scsi_dma = 6; int scsi_irq = 11; -int buslogic_do_log = 0; +int buslogic_do_log = 1; + +int BuslogicCallback = 0; static void BuslogicStartMailbox(Buslogic_t *Buslogic); @@ -538,9 +543,20 @@ void BuslogicLog(const char *format, ...) static void BuslogicClearInterrupt(Buslogic_t *Buslogic) { - BuslogicLog("Buslogic: Clearing Interrupt 0x%02X\n", Buslogic->Interrupt); + BuslogicLog("Buslogic: Lowering Interrupt 0x%02X\n", Buslogic->Interrupt); Buslogic->Interrupt = 0; + BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); picintc(1 << Buslogic->Irq); + if (Buslogic->PendingInterrupt) + { + Buslogic->Interrupt = Buslogic->PendingInterrupt; + BuslogicLog("Buslogic: Raising Interrupt 0x%02X (Pending)\n", Buslogic->Interrupt); + if (Buslogic->MailboxOutInterrupts || !(Buslogic->Interrupt & INTR_MBOA)) + { + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); + } + Buslogic->PendingInterrupt = 0; + } } static void BuslogicLocalRam(Buslogic_t *Buslogic) @@ -568,6 +584,7 @@ static void BuslogicLocalRam(Buslogic_t *Buslogic) static void BuslogicReset(Buslogic_t *Buslogic) { + BuslogicCallback = 0; Buslogic->Status = STAT_IDLE | STAT_INIT; Buslogic->Geometry = 0x80; Buslogic->Command = 0xFF; @@ -578,6 +595,9 @@ static void BuslogicReset(Buslogic_t *Buslogic) Buslogic->ExtendedLUNCCBFormat = 0; Buslogic->MailboxOutPosCur = 0; Buslogic->MailboxInPosCur = 0; + Buslogic->MailboxOutInterrupts = 0; + Buslogic->DoScan = 0; + Buslogic->PendingInterrupt = 0; BuslogicClearInterrupt(Buslogic); @@ -596,32 +616,94 @@ static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset) static void BuslogicCommandComplete(Buslogic_t *Buslogic) { - Buslogic->Status |= STAT_IDLE; Buslogic->DataReply = 0; + Buslogic->Status |= STAT_IDLE; + if (Buslogic->Command != 0x02) { Buslogic->Status &= ~STAT_DFULL; - Buslogic->Interrupt = INTR_ANY | INTR_HACC; - picint(1 << Buslogic->Irq); + Buslogic->Interrupt = (INTR_ANY | INTR_HACC); + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); } Buslogic->Command = 0xFF; Buslogic->CmdParam = 0; } +static uint32_t BuslogicMailboxInRead(Buslogic_t *Buslogic, uint8_t *CompletionCode) +{ + Mailbox32_t TempMailbox32; + Mailbox_t TempMailboxIn; + + uint32_t Incoming = 0; + + Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + if (Buslogic->Mbx24bit) + { + DMAPageRead(Incoming, &TempMailboxIn, sizeof(Mailbox_t)); + *CompletionCode = TempMailboxIn.CmdStatus; + } + else + { + DMAPageRead(Incoming, &TempMailbox32, sizeof(Mailbox32_t)); + *CompletionCode = TempMailbox32.u.in.CompletionCode; + } + + return Incoming; +} + +static void BuslogicMailboxInAdvance(Buslogic_t *Buslogic) +{ + Buslogic->MailboxInPosCur = (Buslogic->MailboxInPosCur + 1) % Buslogic->MailboxCount; +} + static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock, uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode) { Mailbox32_t Mailbox32; Mailbox_t MailboxIn; + + Mailbox32_t TempMailbox32; + Mailbox_t TempMailboxIn; + + uint32_t Incoming = 0; + uint32_t i = 0; + + uint8_t CompletionCode = 0; Mailbox32.CCBPointer = CCBPointer; Mailbox32.u.in.HostStatus = HostStatus; Mailbox32.u.in.TargetStatus = TargetStatus; Mailbox32.u.in.CompletionCode = MailboxCompletionCode; - - uint32_t Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + Incoming = 0; + + if (!Buslogic->StrictRoundRobinMode) + { + uint8_t MailboxCur = Buslogic->MailboxInPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do + { + /* Fetch mailbox from guest memory. */ + Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode); + + /* Check the next mailbox. */ + BuslogicMailboxInAdvance(Buslogic); + } while ((CompletionCode != MBI_FREE) && (MailboxCur != Buslogic->MailboxInPosCur)); + } + else + { + Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode); + } + + if (CompletionCode != MBI_FREE) + { + return; + } if (MailboxCompletionCode != MBI_NOT_FOUND) { @@ -629,12 +711,16 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C CmdBlock->common.TargetStatus = TargetStatus; //Rewrite the CCB up to the CDB. - if (CmdBlock->common.TargetStatus != 0x02) + if ((CmdBlock->common.TargetStatus != 0x02) && (CCBPointer != 0)) { BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); } } + else + { + BuslogicLog("Mailbox not found!\n"); + } BuslogicLog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); @@ -645,20 +731,36 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C BuslogicLog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); DMAPageWrite(Incoming, &MailboxIn, sizeof(Mailbox_t)); + BuslogicLog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); } else { BuslogicLog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); - DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); + if (Incoming != 0) + { + DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); + BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + } + } + + /* Advance to the next mailbox. */ + if (Buslogic->StrictRoundRobinMode) + { + BuslogicMailboxInAdvance(Buslogic); + } + + if (Buslogic->Interrupt & INTR_HACC) + { + BuslogicLog("Pending IRQ\n"); + Buslogic->PendingInterrupt = INTR_MBIF | INTR_ANY; + } + else + { + Buslogic->Interrupt = INTR_MBIF | INTR_ANY; + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); } - - Buslogic->MailboxInPosCur++; - if (Buslogic->MailboxInPosCur > Buslogic->MailboxCount) - Buslogic->MailboxInPosCur = 0; - - Buslogic->Interrupt = INTR_MBIF | INTR_ANY; - picint(1 << Buslogic->Irq); } static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) @@ -688,6 +790,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; + uint32_t ScatterGatherEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + if (Is24bit) { DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer); @@ -699,17 +803,9 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi DataLength = BuslogicRequests->CmdBlock.new.DataLength; } - /* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - DataLength = 0; */ - - if ((BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_6) && (BuslogicRequests->CmdBlock.common.Cdb[0] != GPCMD_MODE_SELECT_10)) - { - return; - } - BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); - if (DataLength && BuslogicRequests->CmdBlock.common.ControlByte != 0x03) + if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) @@ -717,7 +813,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi uint32_t ScatterGatherRead; uint32_t ScatterEntry; SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherLeft = DataLength / (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t ScatterGatherLeft = DataLength / ScatterGatherEntryLength; uint32_t ScatterGatherAddrCurrent = DataPointer; uint32_t DataToTransfer = 0; @@ -733,12 +829,16 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) { uint32_t Address; - + + BuslogicLog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer += ScatterGatherBuffer[ScatterEntry].Segment; + + BuslogicLog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); } - ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + ScatterGatherAddrCurrent += ScatterGatherRead * ScatterGatherEntryLength; } while (ScatterGatherLeft > 0); BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer); @@ -749,7 +849,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi //checking its length, so do this procedure for both no read/write commands. if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT || BuslogicRequests->CmdBlock.common.ControlByte == 0x00) { - ScatterGatherLeft = DataLength / (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + ScatterGatherLeft = DataLength / ScatterGatherEntryLength; ScatterGatherAddrCurrent = DataPointer; do @@ -764,10 +864,14 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) { uint32_t Address; - + + BuslogicLog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; + BuslogicLog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; } @@ -819,42 +923,40 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) DataLength = BuslogicRequests->CmdBlock.new.DataLength; } - if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) + /* if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) { DataLength = SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; - } + } */ if ((DataLength != 0) && (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) { BuslogicLog("Data length not 0 with TEST UNIT READY: %i (%i)\n", DataLength, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); } - /* if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - DataLength = 0; */ + if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) + { + DataLength = 0; + } BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //checking its length, so do this procedure for both read/write commands. - if (DataLength > 0 && (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN || - BuslogicRequests->CmdBlock.common.ControlByte == 0x00) && BuslogicRequests->CmdBlock.common.ControlByte != 0x03) + if ((DataLength > 0) && + ((BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || + (BuslogicRequests->CmdBlock.common.ControlByte == 0x00))) { - if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || - BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) + if ((BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || + (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { uint32_t ScatterGatherRead; uint32_t ScatterEntry; SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherReqSize = (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); - uint32_t ScatterGatherLeft = DataLength / ScatterGatherReqSize; - uint32_t ScatterGatherLength = (ScatterGatherLeft * ScatterGatherReqSize); + uint32_t ScatterGatherEntrySize = (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t ScatterGatherLeft = DataLength / ScatterGatherEntrySize; + // uint32_t ScatterGatherLength = (ScatterGatherLeft * ScatterGatherEntrySize); uint32_t ScatterGatherAddrCurrent = DataPointer; - if (DataLength > ScatterGatherLength) - { - ScatterGatherLeft++; - } - do { ScatterGatherRead = (ScatterGatherLeft < ELEMENTS(ScatterGatherBuffer)) @@ -868,36 +970,57 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) { uint32_t Address; uint32_t DataToTransfer; + + BuslogicLog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; + BuslogicLog("BusLogic S/G: Writing %i bytes at %08X\n", DataToTransfer, Address); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; } - ScatterGatherAddrCurrent += ScatterGatherRead * (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + ScatterGatherAddrCurrent += (ScatterGatherRead * ScatterGatherEntrySize); } while (ScatterGatherLeft > 0); } else if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { uint32_t Address = DataPointer; - if (DataLength > 0) - { - if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) - { - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); - } - else - { - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength); - } - } + + BuslogicLog("BusLogic DMA: Writing %i bytes at %08X\n", DataLength, Address); + DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength); } } - SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0; + if ((BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) + { + uint32_t Residual; + + /* Should be 0 when scatter/gather? */ + if (DataLength >= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) + { + Residual = BuslogicGetDataLength(BuslogicRequests); + Residual -= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; + } + else + { + Residual = 0; + } + + if (BuslogicRequests->Is24bit) + { + U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, Residual); + BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); + } + else + { + BuslogicRequests->CmdBlock.new.DataLength = Residual; + BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); + } + } } uint8_t BuslogicRead(uint16_t Port, void *p) @@ -942,7 +1065,7 @@ uint8_t BuslogicRead(uint16_t Port, void *p) break; } - BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); + // BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); return Temp; } @@ -980,7 +1103,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic_t *Buslogic = (Buslogic_t *)p; BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); + // BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); switch (Port & 3) { @@ -999,16 +1122,9 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 1: - if ((Val == 0x02) && (Buslogic->Command == 0xFF)) + if (!(Buslogic->Status & STAT_IDLE) && (Buslogic->Command == 0xFF) && (Val != 0x02) && (Val != 0x05)) { - for (i = 0; i < CDROM_NUM; i++) - { - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun)) - { - SCSICallback[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun] = 1; - } - } - break; + break; /* Any command other than 02 and 05 can only be executed when the IDLE bit is set. */ } if (Buslogic->Command == 0xFF) @@ -1021,6 +1137,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) switch (Buslogic->Command) { case 0x00: + case 0x02: case 0x04: case 0x0A: case 0x0B: @@ -1030,6 +1147,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->CmdParamLeft = 0; break; + case 0x05: case 0x07: case 0x08: case 0x09: @@ -1066,6 +1184,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x81: + BuslogicLog("Command 0x81 on %s\n", scsi_model ? "BusLogic" : "Adaptec"); Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0; break; @@ -1112,15 +1231,49 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataReplyLeft = 0; } break; + + case 0x02: + if (Buslogic->Status & STAT_INIT) + { + Buslogic->Status |= STAT_INVCMD; + } + else + { + if (!BuslogicCallback) + { + BuslogicLog("SCSI started\n"); + BuslogicCallback = 1; + } + else + { + BuslogicLog("SCSI reactivated\n"); + } + Buslogic->DoScan = 1; + } + Buslogic->DataReplyLeft = 0; + break; case 0x04: Buslogic->DataBuf[0] = 0x41; Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; - Buslogic->DataBuf[2] = '5'; - Buslogic->DataBuf[3] = '0'; + Buslogic->DataBuf[2] = scsi_model ? '5' : '3'; + Buslogic->DataBuf[3] = scsi_model ? '0' : '1'; Buslogic->DataReplyLeft = 4; break; + case 0x05: + if (Buslogic->CmdBuf[0] <= 1) + { + Buslogic->MailboxOutInterrupts = Buslogic->CmdBuf[0]; + BuslogicLog("Mailbox out interrupts: %s\n", Buslogic->MailboxOutInterrupts ? "ON" : "OFF"); + } + else + { + Buslogic->Status |= STAT_INVCMD; + } + Buslogic->DataReplyLeft = 0; + break; + case 0x06: Buslogic->DataReplyLeft = 0; break; @@ -1226,6 +1379,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Address.mid = Buslogic->CmdBuf[1]; Address.lo = Buslogic->CmdBuf[2]; FIFOBuf = ADDR_TO_U32(Address); + BuslogicLog("Buslogic FIFO: Writing 64 bytes at %08X\n", FIFOBuf); DMAPageWrite(FIFOBuf, &Buslogic->LocalRam.u8View[64], 64); } break; @@ -1265,6 +1419,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->IrqEnabled = 0; else Buslogic->IrqEnabled = 1; + BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); picintc(1 << Buslogic->Irq); break; @@ -1408,6 +1563,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } break; + default: case 0x22: //undocumented case 0x28: //only for the Adaptec 154xC series case 0x29: //only for the Adaptec 154xC series @@ -1449,14 +1605,6 @@ static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) return RequestSenseLength; } -static void BuslogicSenseBufferAllocate(BuslogicRequests_t *BuslogicRequests) -{ - uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); - - if (SenseLength) - BuslogicRequests->RequestSenseBuffer = (uint8_t *)malloc(SenseLength); -} - static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Copy) { uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); @@ -1480,14 +1628,85 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co } BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress); - - DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength); + + if (SenseBufferAddress) + { + BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength); + } } - //Free the sense buffer when needed. - free(BuslogicRequests->RequestSenseBuffer); } -static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun, uint8_t cdrom_id) +{ + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + uint8_t cdrom_phase; + + uint32_t temp = 0; + + uint8_t temp_cdb[12]; + uint32_t i; + + BuslogicLog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); + + BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); + for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++) + { + BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); + if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) + { + memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength); + } + else + { + memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); + } + + cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */ + + if (BuslogicRequests->CmdBlock.common.CdbLength != 12) + { + temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ + } + + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); + + //Finally, execute the SCSI command immediately and get the transfer length. + + SCSIPhase = SCSI_PHASE_COMMAND; + SCSIDevices[Id][Lun].InitLength = 0; + cdrom_command(cdrom_id, temp_cdb); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + if (SCSIStatus == SCSI_STATUS_OK) + { + cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); + if (cdrom_phase == 2) + { + /* Command completed - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + else + { + /* Command first phase complete - call the callback to execute the second phase. */ + cdrom_phase_callback(cdrom_id); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + /* Command second phase complete - call the callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + } + else + { + /* Error (Check Condition) - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + + BuslogicLog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); +} + +static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) { BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; uint8_t Id, Lun; @@ -1495,9 +1714,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, uint8_t cdrom_id; uint8_t cdrom_phase; - uint32_t temp = 0; - - uint8_t temp_cdb[12]; + uint8_t last_id = scsi_model ? 15 : 7; //Fetch data from the Command Control Block. DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32)); @@ -1507,171 +1724,69 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Id = BuslogicRequests->TargetID; Lun = BuslogicRequests->LUN; + + if ((Id > last_id) || (Lun > 7)) + { + BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + return 1; + } BuslogicLog("Scanning SCSI Target ID %i\n", Id); - - //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. - if (buslogic_scsi_drive_is_cdrom(Id, Lun)) + + cdrom_id = scsi_cdrom_drives[Id][Lun]; + + BuslogicRequests->CCBPointer = CCBPointer; + BuslogicRequests->Is24bit = Buslogic->Mbx24bit; + + SCSIStatus = SCSI_STATUS_OK; + + BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); + + if (!buslogic_scsi_drive_is_cdrom(Id, Lun)) { - cdrom_id = scsi_cdrom_drives[Id][Lun]; + BuslogicLog("SCSI Target ID %i and LUN %i have no device attached\n", Id, Lun); - BuslogicLog("SCSI Target ID %i detected and working\n", Id); + BuslogicDataBufferFree(BuslogicRequests); - BuslogicRequests->CCBPointer = CCBPointer; - BuslogicRequests->Is24bit = Buslogic->Mbx24bit; + BuslogicSenseBufferFree(BuslogicRequests, 0); - if (Mailbox32->u.out.ActionCode == MBO_START) - { - BuslogicSenseBufferAllocate(BuslogicRequests); - - BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); - - uint32_t i; - - BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); - for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++) - BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); - - memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); - if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) - { - memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength); - } - else - { - memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); - } - - if (BuslogicRequests->CmdBlock.common.CdbLength != 12) - { - cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */ - temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ - } - - BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); - BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); - BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); - - //This not ready/unit attention stuff below is only for the Buslogic! - //The Adaptec one is in scsi_cdrom.c. - - if (!cdrom_drives[cdrom_id].check_on_execution) - { - if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND)) - { - if (!cdrom_pre_execution_check(cdrom_id, temp_cdb)) - { - SCSIStatus = SCSI_STATUS_CHECK_CONDITION; - SCSICallback[Id][Lun]=50*SCSI_TIME; - SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = 0; - if (BuslogicRequests->RequestSenseBuffer) - BuslogicSenseBufferFree(BuslogicRequests, 1); - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - return; - } - } - } - - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - - //Finally, execute the SCSI command immediately and get the transfer length. - - SCSIPhase = SCSI_PHASE_COMMAND; - SCSIDevices[Id][Lun].InitLength = 0; - cdrom_command(cdrom_id, temp_cdb); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); - if (SCSIStatus == SCSI_STATUS_OK) - { - cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); - if (cdrom_phase == 2) - { - /* Command completed - call the phase callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - else - { - /* Command first phase complete - call the callback to execute the second phase. */ - cdrom_phase_callback(cdrom_id); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); - /* Command second phase complete - call the callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - } - else - { - /* Error (Check Condition) - call the phase callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - SCSICallback[Id][Lun] = cdrom[cdrom_id].callback; - - if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && (SCSIDevices[Id][Lun].InitLength != 0)) - { - BuslogicDataBufferFree(BuslogicRequests); - } - - if (BuslogicRequests->RequestSenseBuffer) - BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); - } - else - { - BuslogicLog("Mailbox32->u.out.ActionCode = %02X\n", Mailbox32->u.out.ActionCode); - SCSICallback[Id][Lun] = 50 * SCSI_TIME; - } - - BuslogicLog("Request complete\n"); - - if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) - { - temp = BuslogicGetDataLength(BuslogicRequests); - temp -= SCSIDevices[Id][Lun].InitLength; - - if (BuslogicRequests->Is24bit) - { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, temp); - BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); - } - else - { - BuslogicRequests->CmdBlock.new.DataLength = temp; - BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); - } - } - else if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) - { - if (BuslogicRequests->Is24bit) - { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, 0); - BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); - } - else - { - BuslogicRequests->CmdBlock.new.DataLength = 0; - BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); - } - } - - if (SCSIStatus == SCSI_STATUS_OK) - { - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, - MBI_SUCCESS); - } - else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) - { - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, - MBI_ERROR); - } + BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); } else { - BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); + BuslogicLog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); + + BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); + BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); + BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); + + if (BuslogicRequests->CmdBlock.common.ControlByte > 0x03) + { + BuslogicLog("Invalid control byte: %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); + } + + BuslogicCDROMCommand(Buslogic, Id, Lun, cdrom_id); + + BuslogicDataBufferFree(BuslogicRequests); - // if (Mailbox32->u.out.ActionCode == MBO_START && Lun == 0) - if (Mailbox32->u.out.ActionCode == MBO_START && Lun <= 7) - BuslogicStartMailbox(Buslogic); + BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); + + BuslogicLog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) + { + BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } + else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) + { + BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } } + + return 1; } -static void BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) +static int BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) { BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; CCBU CmdBlock; @@ -1681,6 +1796,8 @@ static void BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); + + return 1; } static uint32_t BuslogicMailboxOut(Buslogic_t *Buslogic, Mailbox32_t *Mailbox32) @@ -1707,70 +1824,127 @@ static uint32_t BuslogicMailboxOut(Buslogic_t *Buslogic, Mailbox32_t *Mailbox32) return Outgoing; } -static void BuslogicStartMailbox(Buslogic_t *Buslogic) -{ +static void BuslogicMailboxOutAdvance(Buslogic_t *Buslogic) +{ + Buslogic->MailboxOutPosCur = (Buslogic->MailboxOutPosCur + 1) % Buslogic->MailboxCount; +} + +static int BuslogicProcessMailbox(Buslogic_t *Buslogic) +{ Mailbox32_t Mailbox32; Mailbox_t MailboxOut; uint32_t Outgoing; - uint8_t MailboxOutCur = Buslogic->MailboxOutPosCur; - - do + uint8_t CmdStatus = MBO_FREE; + uint32_t CodeOffset = 0; + + int old_irq_enabled = Buslogic->IrqEnabled; + + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + + int ret = 0; + + CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + + if (!Buslogic->StrictRoundRobinMode) + { + uint8_t MailboxCur = Buslogic->MailboxOutPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do + { + /* Fetch mailbox from guest memory. */ + Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); + + /* Check the next mailbox. */ + BuslogicMailboxOutAdvance(Buslogic); + } while ((Mailbox32.u.out.ActionCode == MBO_FREE) && (MailboxCur != Buslogic->MailboxOutPosCur)); + } + else { Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); - Buslogic->MailboxOutPosCur = (Buslogic->MailboxOutPosCur + 1) % Buslogic->MailboxCount; - } while (Mailbox32.u.out.ActionCode == MBO_FREE && MailboxOutCur != Buslogic->MailboxOutPosCur); + } - uint8_t CmdStatus = MBO_FREE; - uint32_t CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + /* Check if the mailbox is actually loaded. */ + if (Mailbox32.u.out.ActionCode == MBO_FREE) + { + BuslogicLog("No loaded mailbox left\n"); - DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); - - if (Mailbox32.u.out.ActionCode == MBO_START || Mailbox32.u.out.ActionCode == MBO_FREE) + if (Buslogic->MailboxOutInterrupts) + { + if (Buslogic->Interrupt & INTR_HACC) + { + BuslogicLog("Pending IRQ\n"); + Buslogic->PendingInterrupt = INTR_MBOA | INTR_ANY; + } + else + { + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + Buslogic->Interrupt = INTR_MBOA | INTR_ANY; + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); + } + } + + return 0; + } + + /* We got the mailbox, mark it as free in the guest. */ + if (Mailbox32.u.out.ActionCode != MBO_FREE) + { + BuslogicLog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); + } + + if ((Mailbox32.u.out.ActionCode == MBO_START) || (Mailbox32.u.out.ActionCode == MBO_FREE)) { BuslogicLog("Start Mailbox Command\n"); - BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32); + ret = BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32); } else if (Mailbox32.u.out.ActionCode == MBO_ABORT) { BuslogicLog("Abort Mailbox Command\n"); - BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer); + ret = BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer); } + else + { + BuslogicLog("Invalid action code: %02X\n", Mailbox32.u.out.ActionCode); + ret = 0; + } + + /* Advance to the next mailbox. */ + if (Buslogic->StrictRoundRobinMode) + { + BuslogicMailboxOutAdvance(Buslogic); + } + + return ret; } -void BuslogicCommandCallback(int id, int lun, void *p) +void BuslogicCommandCallback(void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; + + int ret = 0; + int i = 0; + + // BuslogicLog("BusLogic Callback!\n"); - SCSICallback[id][lun] = 0; if (Buslogic->MailboxCount) { - BuslogicStartMailbox(Buslogic); + ret = BuslogicProcessMailbox(Buslogic); + + BuslogicCallback += 50 * SCSI_TIME; + } + else + { + fatal("Callback active with mailbox count 0!\n"); } -} - -void BuslogicCommandCallback0(void *p) -{ - BuslogicCommandCallback(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun, p); -} - -void BuslogicCommandCallback1(void *p) -{ - BuslogicCommandCallback(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun, p); -} - -void BuslogicCommandCallback2(void *p) -{ - BuslogicCommandCallback(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun, p); -} - -void BuslogicCommandCallback3(void *p) -{ - BuslogicCommandCallback(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun, p); } void *BuslogicInit() { + int i = 0; + Buslogic_t *Buslogic = malloc(sizeof(Buslogic_t)); memset(Buslogic, 0, sizeof(Buslogic_t)); @@ -1782,26 +1956,15 @@ void *BuslogicInit() BuslogicLog("Building CD-ROM map...\n"); build_scsi_cdrom_map(); - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[0].scsi_device_id, cdrom_drives[0].scsi_device_lun)) + for (i = 0; i < CDROM_NUM; i++) { - SCSIDevices[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback0, &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], &SCSICallback[cdrom_drives[0].scsi_device_id][cdrom_drives[0].scsi_device_lun], Buslogic); - } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[1].scsi_device_id, cdrom_drives[1].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback1, &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], &SCSICallback[cdrom_drives[1].scsi_device_id][cdrom_drives[1].scsi_device_lun], Buslogic); - } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[2].scsi_device_id, cdrom_drives[2].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback2, &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], &SCSICallback[cdrom_drives[2].scsi_device_id][cdrom_drives[2].scsi_device_lun], Buslogic); - } - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[3].scsi_device_id, cdrom_drives[3].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun].LunType == SCSI_CDROM; - timer_add(BuslogicCommandCallback3, &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], &SCSICallback[cdrom_drives[3].scsi_device_id][cdrom_drives[3].scsi_device_lun], Buslogic); + if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun)) + { + SCSIDevices[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun].LunType == SCSI_CDROM; + } } + + timer_add(BuslogicCommandCallback, &BuslogicCallback, &BuslogicCallback, Buslogic); BuslogicLog("Buslogic on port 0x%04X\n", scsi_base); @@ -1826,4 +1989,4 @@ device_t BuslogicDevice = NULL, NULL, NULL -}; \ No newline at end of file +}; diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 7fc61eeb3..490d4ab45 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -779,6 +779,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t int transferred_blocks = 0; int temp_len = 0; + int chunk = 0; if (cdb[0] == 0x43) { @@ -791,13 +792,14 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t memcpy(cdb, in_cdb, 12); temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + *len = 0; if (temp_block_length != -1) { if (temp_block_length > 65534) { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer...\n", id, temp_block_length); block_length = temp_block_length / cdrom[id].requested_blocks; blocks_at_once = 32768 / block_length; + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer into chunks of %i blocks...\n", id, temp_block_length, blocks_at_once); buffer_pos = 0; temp_pos = cdrom[id].sector_pos; @@ -806,12 +808,15 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t temp_len = 0; split_block_read_iterate: - if (temp_requested_blocks < blocks_at_once) + chunk = (cdrom[id].requested_blocks - transferred_blocks); + if (chunk < blocks_at_once) { - cdrom_ioctl[id].actual_requested_blocks = temp_requested_blocks; + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is less than a complete split block\n", id, chunk); + cdrom_ioctl[id].actual_requested_blocks = chunk; } else { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is more or equal than a complete split block\n", id, chunk); cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; } cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); @@ -819,8 +824,9 @@ split_block_read_iterate: ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); *len += temp_len; transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; - if (ret && (transferred_blocks >= cdrom[id].requested_blocks)) + if (ret && (transferred_blocks < cdrom[id].requested_blocks)) { + /* Return value was successful and there are still more blocks left to transfer. */ temp_pos += cdrom_ioctl[id].actual_requested_blocks; buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); goto split_block_read_iterate; diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index bb3d7c361..241e1e3dd 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -3,6 +3,8 @@ */ /*ISO CD-ROM support*/ +#include + #include "ibm.h" #include "cdrom.h" #include "cdrom-iso.h" @@ -10,12 +12,12 @@ static CDROM iso_cdrom; -int cdrom_iso_do_log = 1; +int cdrom_iso_do_log = 0; void cdrom_iso_log(const char *format, ...) { #ifdef ENABLE_CDROM_ISO_LOG - if (cdrom_do_log) + if (cdrom_iso_do_log) { va_list ap; va_start(ap, format); @@ -273,12 +275,14 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf if (cdrom_sector_flags & 0x80) /* Sync */ { + cdrom_iso_log("CD-ROM %i: Sync\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); cdrom_sector_size += 12; temp_b += 12; } if (cdrom_sector_flags & 0x20) /* Header */ { + cdrom_iso_log("CD-ROM %i: Header\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); cdrom_sector_size += 4; temp_b += 4; @@ -289,6 +293,7 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf { if (!(cdrom_sector_flags & 0x10)) /* No user data */ { + cdrom_iso_log("CD-ROM %i: Sub-header\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); cdrom_sector_size += 8; temp_b += 8; @@ -296,12 +301,14 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf } if (cdrom_sector_flags & 0x10) /* User data */ { + cdrom_iso_log("CD-ROM %i: User data\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); cdrom_sector_size += 2048; temp_b += 2048; } if (cdrom_sector_flags & 0x08) /* EDC/ECC */ { + cdrom_iso_log("CD-ROM %i: EDC/ECC\n", id); memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); cdrom_sector_size += 288; temp_b += 288; @@ -312,33 +319,36 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf if ((cdrom_sector_flags & 0x06) == 0x02) { /* Add error flags. */ + cdrom_iso_log("CD-ROM %i: Error flags\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); cdrom_sector_size += 294; } else if ((cdrom_sector_flags & 0x06) == 0x04) { /* Add error flags. */ + cdrom_iso_log("CD-ROM %i: Full error flags\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); cdrom_sector_size += 296; } if ((cdrom_sector_flags & 0x700) == 0x100) { + cdrom_iso_log("CD-ROM %i: Raw subchannel data\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); cdrom_sector_size += 96; } else if ((cdrom_sector_flags & 0x700) == 0x200) { + cdrom_iso_log("CD-ROM %i: Q subchannel data\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); cdrom_sector_size += 16; } else if ((cdrom_sector_flags & 0x700) == 0x400) { + cdrom_iso_log("CD-ROM %i: R/W subchannel data\n", id); memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); cdrom_sector_size += 96; } - - memcpy(buffer, b, cdrom_sector_size); *len = cdrom_sector_size; diff --git a/src/cdrom.c b/src/cdrom.c index 0aad0daf8..e7cb9c63f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -330,12 +330,10 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type) if (!cdrom_drives[id].bus_type) { cdrom_set_signature(id); - cdrom_drives[id].check_on_execution = 1; cdrom_drives[id].max_blocks_at_once = 1; } else { - cdrom_drives[id].check_on_execution = scsi_model ? 0 : 1; cdrom_drives[id].max_blocks_at_once = 85; } cdrom[id].status = READY_STAT | DSC_STAT; @@ -881,12 +879,12 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (cdrom_current_mode(id) == 2) { - if (cdrom_drives[id].bus_type) - { - SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; - } if (direction == 0) { + if (cdrom_drives[id].bus_type) + { + SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; + } cdrom_command_read_dma(id); } else @@ -1121,6 +1119,8 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) int i = 0; int temp_len = 0; + int last_valid_data_pos = 0; + if (cdrom_drives[id].handler->pass_through) { cdsize = cdrom_drives[id].handler->size(id); @@ -1156,7 +1156,9 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) for (i = 0; i < cdrom[id].requested_blocks; i++) { - ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos, msf, type, flags, &temp_len); + ret = cdrom_drives[id].handler->readsector_raw(id, cdbufferb + cdrom[id].data_pos, cdrom[id].sector_pos + i, msf, type, flags, &temp_len); + + last_valid_data_pos = cdrom[id].data_pos; cdrom[id].data_pos += temp_len; cdrom[id].old_len += temp_len; @@ -1170,7 +1172,7 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) } } - cdrom_log("CD-ROM %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + cdrom_log("CD-ROM %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[last_valid_data_pos + 0], cdbufferb[last_valid_data_pos + 1], cdbufferb[last_valid_data_pos + 2], cdbufferb[last_valid_data_pos + 3], cdbufferb[last_valid_data_pos + 4], cdbufferb[last_valid_data_pos + 5], cdbufferb[last_valid_data_pos + 6], cdbufferb[last_valid_data_pos + 7]); } return 1; @@ -1616,12 +1618,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].sector_len = 0; /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ - if (cdrom_drives[id].check_on_execution) + if (cdrom_pre_execution_check(id, cdb) == 0) { - if (cdrom_pre_execution_check(id, cdb) == 0) - { - return; - } + return; } cdrom[id].prev_status = cdrom[id].cd_status; @@ -2645,7 +2644,7 @@ int cdrom_mode_select_return(uint8_t id, int ret) } } -int cdrom_phase_callback(uint8_t id); +void cdrom_phase_callback(uint8_t id); int cdrom_read_from_ide_dma(uint8_t channel) { @@ -2799,58 +2798,72 @@ int cdrom_write_to_dma(uint8_t id) return 1; } +void cdrom_irq_raise(uint8_t id) +{ + if (!cdrom_drives[id].bus_type) + { + ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); + } +} + /* If the result is 1, issue an IRQ, otherwise not. */ -int cdrom_phase_callback(uint8_t id) +void cdrom_phase_callback(uint8_t id) { switch(cdrom[id].packet_status) { case CDROM_PHASE_IDLE: - // cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_IDLE\n", id); cdrom[id].pos=0; cdrom[id].phase = 1; cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); - return 0; + return; case CDROM_PHASE_COMMAND: - // cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_COMMAND\n", id); cdrom[id].status = BUSY_STAT | (cdrom[id].status &ERR_STAT); memcpy(cdrom[id].atapi_cdb, (uint8_t *) cdrom[id].buffer, cdrom[id].cdb_len); cdrom_command(id, cdrom[id].atapi_cdb); - return 0; + return; case CDROM_PHASE_COMPLETE: - // cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_COMPLETE\n", id); cdrom[id].status = READY_STAT; cdrom[id].phase = 3; cdrom[id].packet_status = 0xFF; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_OUT: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT\n", id); cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); cdrom[id].phase = 0; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_OUT_DMA: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_OUT_DMA\n", id); cdrom_read_from_dma(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_IN: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN\n", id); cdrom[id].status = READY_STAT | DRQ_STAT | (cdrom[id].status & ERR_STAT); cdrom[id].phase = 2; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_DATA_IN_DMA: - // cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_DATA_IN_DMA\n", id); cdrom_write_to_dma(id); cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - return 1; + cdrom_irq_raise(id); + return; case CDROM_PHASE_ERROR: - // cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); + cdrom_log("CD-ROM %i: CDROM_PHASE_ERROR\n", id); cdrom[id].status = READY_STAT | ERR_STAT; cdrom[id].phase = 3; - return 1; + cdrom_irq_raise(id); + return; } } @@ -2957,7 +2970,7 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) cdrom[id].pos++; break; case 2: - cdbufferw[cdrom[id].pos >> 1] = val & 0xff; + cdbufferw[cdrom[id].pos >> 1] = val & 0xffff; cdrom[id].pos += 2; break; case 4: diff --git a/src/cdrom.h b/src/cdrom.h index 759c5e134..25c9bc201 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -129,9 +129,6 @@ typedef struct __attribute__((__packed__)) uint8_t bus_mode; /* Bit 0 = PIO suported; Bit 1 = DMA supportd. */ - uint8_t check_on_execution; /* 0 = Not Ready/Unit Attention checkeck is performed on the controller's side before command execution; - 1 = Not Ready/Unit Attention checkeck is performed on command execution. */ - uint8_t ide_channel; uint8_t scsi_device_id; @@ -190,7 +187,7 @@ void build_scsi_cdrom_map(); int cdrom_CDROM_PHASE_to_scsi(uint8_t id); int cdrom_atapi_phase_to_scsi(uint8_t id); void cdrom_command(uint8_t id, uint8_t *cdb); -int cdrom_phase_callback(uint8_t id); +void cdrom_phase_callback(uint8_t id); uint32_t cdrom_read(uint8_t channel, int length); void cdrom_write(uint8_t channel, uint32_t val, int length); int cdrom_lba_to_msf_accurate(int lba); diff --git a/src/ide.c b/src/ide.c index 5c4063f01..c1dca50e6 100644 --- a/src/ide.c +++ b/src/ide.c @@ -202,7 +202,7 @@ int image_is_hdi(const char *s) int ide_enable[4] = { 1, 1, 0, 0 }; int ide_irq[4] = { 14, 15, 10, 11 }; -static inline void ide_irq_raise(IDE *ide) +void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { @@ -344,7 +344,7 @@ static void ide_identify(IDE *ide) h = hdc[cur_ide[ide->board]].hpc; /* Heads */ s = hdc[cur_ide[ide->board]].spt; /* Sectors */ - ide->buffer[0] = 0x40; /* Fixed disk */ + // ide->buffer[0] = 0x40; /* Fixed disk */ ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ @@ -403,10 +403,11 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ + ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[73] = 6; - ide->buffer[73] = 9; + ide->buffer[74] = 9; ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) @@ -736,7 +737,7 @@ void resetide(void) if (ide_drives[d].type != IDE_NONE) { ide_drives[d].dma_identify_data[0] = 7; - ide_drives[d].dma_identify_data[1] = 7 | (1 << 15); + ide_drives[d].dma_identify_data[1] = 7 | (1 << 10); ide_drives[d].dma_identify_data[2] = 0x3f; } @@ -835,7 +836,9 @@ void writeidew(int ide_board, uint16_t val) void writeidel(int ide_board, uint32_t val) { // ide_log("WriteIDEl %08X\n", val); - ide_write_data(ide_board, val, 4); + // ide_write_data(ide_board, val, 4); + writeidew(ide_board, val); + writeidew(ide_board, val >> 16); } void writeide(int ide_board, uint16_t addr, uint8_t val) @@ -1349,7 +1352,7 @@ uint32_t ide_read_data(int ide_board, int length) ide->pos += 2; break; case 4: - temp = idebufferb[ide->pos >> 2]; + temp = idebufferl[ide->pos >> 2]; ide->pos += 4; break; default: @@ -1559,17 +1562,21 @@ int all_blocks_total = 0; uint16_t readidew(int ide_board) { - uint16_t temp; - temp = ide_read_data(ide_board, 2); - return temp; + return ide_read_data(ide_board, 2); } +/* uint32_t readidel(int ide_board) +{ + // ide_log("Read IDEl %i\n", ide_board); + return ide_read_data(ide_board, 4); +} */ + uint32_t readidel(int ide_board) { uint16_t temp; - // ide_log("Read IDEl %i\n", ide_board); - temp = ide_read_data(ide_board, 4); - return temp; + // pclog("Read IDEl %i\n", ide_board); + temp = readidew(ide_board); + return temp | (readidew(ide_board) << 16); } int times30=0; @@ -2015,10 +2022,7 @@ void callbackide(int ide_board) goto abort_cmd; } - if (cdrom_phase_callback(atapi_cdrom_drives[cur_ide[ide_board]])) - { - ide_irq_raise(ide); - } + cdrom_phase_callback(atapi_cdrom_drives[cur_ide[ide_board]]); idecallback[ide_board] = cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].callback; ide_log("IDE callback now: %i\n", idecallback[ide_board]); return; diff --git a/src/ide.h b/src/ide.h index 0bd0fcac0..87dc9081c 100644 --- a/src/ide.h +++ b/src/ide.h @@ -62,6 +62,7 @@ extern int idecallback[4]; extern char ide_fn[IDE_NUM][512]; +void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); IDE ide_drives[IDE_NUM]; diff --git a/src/scsi.c b/src/scsi.c index 17f573b14..6a3c5746e 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -16,22 +16,6 @@ uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; uint8_t SCSIStatus = SCSI_STATUS_OK; -int SCSICallback[16][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 0 } }; uint8_t scsi_cdrom_id = 3; /*common setting*/ //Initialization function for the SCSI layer @@ -41,8 +25,6 @@ void SCSIReset(uint8_t id, uint8_t lun) if (buslogic_scsi_drive_is_cdrom(id, lun)) { - SCSICallback[id][lun] = 0; - cdrom_reset(cdrom_id); SCSIDevices[id][lun].LunType = SCSI_CDROM; } diff --git a/src/scsi.h b/src/scsi.h index 125131732..b3f4becaf 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -188,7 +188,6 @@ int MediaPresent; extern uint8_t SCSIStatus; extern uint8_t SCSIPhase; -extern int SCSICallback[16][8]; extern uint8_t scsi_cdrom_id; struct From b6c02971415882e7bc71c2d8dee2035b0d7e63c9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 00:14:51 +0100 Subject: [PATCH 033/392] Applied the properly working Nvidia commit from Mooch. --- src/vid_nv_riva128.c | 59 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index d3a94bf31..a28f9b8b7 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -151,6 +151,9 @@ typedef struct riva128_t uint32_t fifo_enable; + uint32_t fifo_st2_addr; + uint32_t fifo_st2_data; + uint32_t uclip_xmin, uclip_ymin, uclip_xmax, uclip_ymax; uint32_t oclip_xmin, oclip_ymin, oclip_xmax, oclip_ymax; @@ -226,6 +229,9 @@ const char* riva128_pfifo_interrupts[32] = "CACHE_ERROR","","","","RUNOUT","","","","RUNOUT_OVERFLOW","","","","DMA_PUSHER","","","","DMA_PTE","","","","","","","","","","","","","","","" }; +static uint32_t riva128_ramht_lookup(uint32_t handle, void *p); +static void riva128_pgraph_volatile_reset(void *p); + static uint8_t riva128_pci_read(int func, int addr, void *p); static void riva128_pci_write(int func, int addr, uint8_t val, void *p); @@ -965,6 +971,50 @@ static uint8_t riva128_pextdev_read(uint32_t addr, void *p) return ret; } +static void rivatnt_pgraph_ctx_switch(void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + + if(!(riva128->pgraph.fifo_st2_addr & 1)) return; + + unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; + unsigned new_subc = (riva128->pgraph.fifo_st2_addr >> 12) & 7; + unsigned mthd = (riva128->pgraph.fifo_st2_addr >> 1) & 0x7ff; + riva128->pgraph.fifo_st2_addr &= ~1; + unsigned do_ctx_switch = mthd == 0; + + if(old_subc != new_subc || do_ctx_switch) + { + if(do_ctx_switch) riva128->pgraph.ctx_cache[new_subc][3] = riva128->pgraph.fifo_st2_data & 0xffff; + + uint32_t ctx_mask = 0x0303f0ff; + + unsigned reload = (riva128->pgraph.debug[1] >> 15) & 1; + if(reload || do_ctx_switch) + { + uint32_t instance = riva128_ramht_lookup(riva128->pgraph.fifo_st2_data, riva128); + riva128->pgraph.ctx_cache[new_subc][0] = riva128->pramin[(instance >> 2)] & ctx_mask; + riva128->pgraph.ctx_cache[new_subc][1] = riva128->pramin[(instance >> 2) + 1] & 0xffff3f03; + riva128->pgraph.ctx_cache[new_subc][2] = riva128->pramin[(instance >> 2) + 2]; + riva128->pgraph.ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; + } + + unsigned reset = (riva128->pgraph.debug[2] >> 28) & 1; + if(reset) + { + riva128->pgraph.debug[1] |= 1; + riva128_pgraph_volatile_reset(riva128); + } + else riva128->pgraph.debug[1] &= ~1; + + if(riva128->pgraph.debug[1] & 0x100000) + { + for(int i = 0; i < 5; i++) riva128->pgraph.ctx_switch[i] = riva128->pgraph.ctx_cache[new_subc][i]; + } + } +} + static uint8_t riva128_pgraph_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -1366,6 +1416,13 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x40008c: riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); break; + case 0x400754: + riva128->pgraph.fifo_st2_addr = val; + break; + case 0x400758: + riva128->pgraph.fifo_st2_data = val; + rivatnt_pgraph_ctx_switch(riva128); + break; } } @@ -1555,7 +1612,7 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui if(riva128->card_id == 0x03) { uint32_t tmp = riva128_ramht_lookup(val, riva128); - riva128->pgraph.instance = (tmp & 0xffff) << 4; + riva128->pgraph.instance = (tmp & 0xffff) << 2; unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; unsigned new_subc = subchanid & 7; if((old_subc != new_subc) || !offset) From b2c7b4665d685f7c77d427a723f7e044de944072 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 01:06:29 +0100 Subject: [PATCH 034/392] Fixed cdrom_ascq #define so it no longer points to the same as cdrom_asc. --- src/cdrom.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom.h b/src/cdrom.h index 25c9bc201..c7c9101e6 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -197,7 +197,7 @@ void cdrom_set_signature(int id); #define cdrom_sense_error cdrom[id].sense[0] #define cdrom_sense_key cdrom[id].sense[2] #define cdrom_asc cdrom[id].sense[12] -#define cdrom_ascq cdrom[id].sense[12] +#define cdrom_ascq cdrom[id].sense[13] #define cdrom_drive cdrom_drives[id].host_drive #endif \ No newline at end of file From 2e15aca382e56a2793b12ab3e55446f01ef8c2aa Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 01:17:49 +0100 Subject: [PATCH 035/392] The error code in cdrom.c now logs errors; Illegal LUN is now invalid LUN and 05/25/00. --- src/cdrom.c | 9 +++++---- src/scsi.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index e7cb9c63f..f1e006b4c 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -929,6 +929,7 @@ static void cdrom_cmd_error(uint8_t id) cdrom[id].phase = 3; cdrom[id].packet_status = 0x80; cdrom[id].callback = 50 * CDROM_TIME; + cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", id cdrom_sense_key, cdrom_asc, cdrom_ascq); } static void cdrom_unit_attention(uint8_t id) @@ -942,6 +943,7 @@ static void cdrom_unit_attention(uint8_t id) cdrom[id].phase = 3; cdrom[id].packet_status = 0x80; cdrom[id].callback = 50 * CDROM_TIME; + cdrom_log("CD-ROM %i: UNIT ATTENTION\n", id); } static void cdrom_not_ready(uint8_t id) @@ -952,11 +954,10 @@ static void cdrom_not_ready(uint8_t id) cdrom_cmd_error(id); } -/* This is 05/00/00, based on what a Daemon Tools drive returns for such a case. */ -static void cdrom_illegal_lun(uint8_t id) +static void cdrom_invalid_lun(uint8_t id) { cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = 0; + cdrom_asc = ASC_INV_LUN; cdrom_ascq = 0; cdrom_cmd_error(id); } @@ -1427,7 +1428,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { cdrom_log("CD-ROM %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((cdrom[id].request_length >> 5) & 7)); - cdrom_illegal_lun(id); + cdrom_invalid_lun(id); return 0; } } diff --git a/src/scsi.h b/src/scsi.h index b3f4becaf..1400823cc 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -78,6 +78,7 @@ #define ASC_ILLEGAL_OPCODE 0x20 #define ASC_LBA_OUT_OF_RANGE 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 +#define ASC_INV_LUN 0x25 #define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 #define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 #define ASC_INCOMPATIBLE_FORMAT 0x30 From 13e85cc7a61cf6758adcf64af9929f47c25853a5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 01:19:49 +0100 Subject: [PATCH 036/392] Fixed a compile-breaking error. --- src/cdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom.c b/src/cdrom.c index f1e006b4c..dfafae81f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -929,7 +929,7 @@ static void cdrom_cmd_error(uint8_t id) cdrom[id].phase = 3; cdrom[id].packet_status = 0x80; cdrom[id].callback = 50 * CDROM_TIME; - cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", id cdrom_sense_key, cdrom_asc, cdrom_ascq); + cdrom_log("CD-ROM %i: ERROR: %02X/%02X/%02X\n", id, cdrom_sense_key, cdrom_asc, cdrom_ascq); } static void cdrom_unit_attention(uint8_t id) From 45183ea02677c70348acf09c42e4b9ab189dd9ac Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 01:48:55 +0100 Subject: [PATCH 037/392] SCSI auto-sense is now done as an actual pseudo-execution of the REQUEST SENSE command. --- src/buslogic.c | 7 ++- src/cdrom.c | 129 +++++++++++++++++++++++++++++++------------------ src/cdrom.h | 1 + 3 files changed, 88 insertions(+), 49 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index a1404b934..f9b6f819d 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1609,6 +1609,10 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co { uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); uint8_t cdrom_id = scsi_cdrom_drives[BuslogicRequests->TargetID][BuslogicRequests->LUN]; + + uint8_t temp_sense[256]; + + cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); if (SenseLength && Copy) { @@ -1632,7 +1636,8 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co if (SenseBufferAddress) { BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); - DMAPageWrite(SenseBufferAddress, cdrom[cdrom_id].sense, SenseLength); + DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); + BuslogicLog("First 8 bytes of written sense data: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); } } } diff --git a/src/cdrom.c b/src/cdrom.c index dfafae81f..37993377b 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1551,6 +1551,84 @@ void cdrom_reset(uint8_t id) cdrom[id].unit_attention = 0; } +void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +{ + /*Will return 18 bytes of 0*/ + if (alloc_length != 0) + { + memset(buffer, 0, alloc_length); + memcpy(buffer, cdrom[id].sense, alloc_length); + } + + buffer[0] = 0x70; + + if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom[id].completed) + { + buffer[2]=SENSE_ILLEGAL_REQUEST; + buffer[12]=ASC_AUDIO_PLAY_OPERATION; + buffer[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; + } + else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED)) + { + buffer[2]=SENSE_ILLEGAL_REQUEST; + buffer[12]=ASC_AUDIO_PLAY_OPERATION; + buffer[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; + } + else + { + if (cdrom[id].unit_attention) + { + buffer[2]=SENSE_UNIT_ATTENTION; + buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[13]=0; + } + } + + // cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]); + + if (buffer[2] == SENSE_UNIT_ATTENTION) + { + /* If the last remaining sense is unit attention, clear + that condition. */ + cdrom[id].unit_attention = 0; + } + + /* Clear the sense stuff as per the spec. */ + cdrom_sense_clear(id, GPCMD_REQUEST_SENSE, 0); + break; +} + +void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +{ + int ready = 0; + + if (cdrom_drives[id].handler->medium_changed(id)) + { + // cdrom_log("CD-ROM %i: Medium has changed...\n", id); + cdrom_insert(id); + } + + ready = cdrom_drives[id].handler->ready(id); + + if (!ready && cdrom[id].unit_attention) + { + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + cdrom[id].unit_attention = 0; + } + + /* If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. */ + if (cdrom[id].unit_attention == 1) + { + // cdrom_log("CD-ROM %i: Unit attention now 2\n", id); + cdrom[id].unit_attention = 2; + } + + cdrom_request_sense(id, buffer, alloc_length); +} + void cdrom_command(uint8_t id, uint8_t *cdb) { uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; @@ -1650,54 +1728,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom_seek(id, 0); break; - case GPCMD_REQUEST_SENSE: /* Used by ROS 4+ */ - alloc_length = cdb[4]; - temp_command = cdb[0]; - - /*Will return 18 bytes of 0*/ - if (alloc_length != 0) - { - memset(cdbufferb, 0, alloc_length); - memcpy(cdbufferb, cdrom[id].sense, alloc_length); - } - - cdbufferb[0] = 0x70; - - if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && completed) - { - cdbufferb[2]=SENSE_ILLEGAL_REQUEST; - cdbufferb[12]=ASC_AUDIO_PLAY_OPERATION; - cdbufferb[13]=ASCQ_AUDIO_PLAY_OPERATION_COMPLETED; - } - else if ((cdrom_sense_key == 0) && (cdrom[id].cd_status >= CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_STOPPED)) - { - cdbufferb[2]=SENSE_ILLEGAL_REQUEST; - cdbufferb[12]=ASC_AUDIO_PLAY_OPERATION; - cdbufferb[13]=(cdrom[id].cd_status == CD_STATUS_PLAYING) ? ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS : ASCQ_AUDIO_PLAY_OPERATION_PAUSED; - } - else - { - if (cdrom[id].unit_attention) - { - cdbufferb[2]=SENSE_UNIT_ATTENTION; - cdbufferb[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - cdbufferb[13]=0; - } - } - - // cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]); - - if (cdbufferb[2] == SENSE_UNIT_ATTENTION) - { - /* If the last remaining sense is unit attention, clear - that condition. */ - cdrom[id].unit_attention = 0; - } - - /* Clear the sense stuff as per the spec. */ - cdrom_sense_clear(id, temp_command, 0); - - cdrom_data_command_finish(id, 18, 18, alloc_length, 0); + case GPCMD_REQUEST_SENSE: + cdrom_request_sense(id, cdbufferb, cdb[4]); + cdrom_data_command_finish(id, 18, 18, cdb[4], 0); break; case GPCMD_SET_SPEED: diff --git a/src/cdrom.h b/src/cdrom.h index c7c9101e6..3cbbcaec2 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -193,6 +193,7 @@ void cdrom_write(uint8_t channel, uint32_t val, int length); int cdrom_lba_to_msf_accurate(int lba); void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); +void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); #define cdrom_sense_error cdrom[id].sense[0] #define cdrom_sense_key cdrom[id].sense[2] From 4486926b6db6f5dfee7b15d3c83c86fafd2fd318 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 01:58:48 +0100 Subject: [PATCH 038/392] Fixed a compile-breaking error. --- src/buslogic.c | 4 ++-- src/cdrom.c | 26 +++++++++++++++++--------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index f9b6f819d..14d662437 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1612,11 +1612,11 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co uint8_t temp_sense[256]; - cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); - if (SenseLength && Copy) { uint32_t SenseBufferAddress; + + cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); /*The sense address, in 32-bit mode, is located in the Sense Pointer of the CCB, but in 24-bit mode, it is located at the end of the Command Descriptor Block. */ diff --git a/src/cdrom.c b/src/cdrom.c index 37993377b..e8e1120db 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1551,6 +1551,20 @@ void cdrom_reset(uint8_t id) cdrom[id].unit_attention = 0; } +void cdrom_playing_completed(uint8_t id) +{ + cdrom[id].prev_status = cdrom[id].cd_status; + cdrom[id].cd_status = cdrom_drives[id].handler->status(id); + if (((cdrom[id].prev_status == CD_STATUS_PLAYING) || (cdrom[id].prev_status == CD_STATUS_PAUSED)) && ((cdrom[id].cd_status != CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_PAUSED))) + { + return 1; + } + else + { + return 0; + } +} + void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { /*Will return 18 bytes of 0*/ @@ -1562,7 +1576,7 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) buffer[0] = 0x70; - if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom[id].completed) + if ((cdrom_sense_key > 0) && ((cdrom[id].cd_status < CD_STATUS_PLAYING) || (cdrom[id].cd_status == CD_STATUS_STOPPED)) && cdrom_playing_completed(id)) { buffer[2]=SENSE_ILLEGAL_REQUEST; buffer[12]=ASC_AUDIO_PLAY_OPERATION; @@ -1702,15 +1716,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) return; } - cdrom[id].prev_status = cdrom[id].cd_status; - cdrom[id].cd_status = cdrom_drives[id].handler->status(id); - if (((cdrom[id].prev_status == CD_STATUS_PLAYING) || (cdrom[id].prev_status == CD_STATUS_PAUSED)) && ((cdrom[id].cd_status != CD_STATUS_PLAYING) && (cdrom[id].cd_status != CD_STATUS_PAUSED))) + if (cdb[0] != GPCMD_REQUEST_SENSE) { - completed = 1; - } - else - { - completed = 0; + completed = cdrom_playing_completed(id); } switch (cdb[0]) From a24020efcd724254c701437b2716123173ea172e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 02:00:34 +0100 Subject: [PATCH 039/392] Fixed the last compile-breaking error. --- src/cdrom.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cdrom.c b/src/cdrom.c index e8e1120db..2bb8fac08 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1609,7 +1609,6 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) /* Clear the sense stuff as per the spec. */ cdrom_sense_clear(id, GPCMD_REQUEST_SENSE, 0); - break; } void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) From 6a396b4bcbc1d043f123f34fc2b48f60ac74ee99 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 02:02:35 +0100 Subject: [PATCH 040/392] Fixed the last compile-breaking error, for really this time. --- src/cdrom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cdrom.c b/src/cdrom.c index 2bb8fac08..37e484735 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1551,7 +1551,7 @@ void cdrom_reset(uint8_t id) cdrom[id].unit_attention = 0; } -void cdrom_playing_completed(uint8_t id) +int cdrom_playing_completed(uint8_t id) { cdrom[id].prev_status = cdrom[id].cd_status; cdrom[id].cd_status = cdrom_drives[id].handler->status(id); From 1aa37bfc27eefc048fe79fd6114a54ad3b5a7354 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 03:03:46 +0100 Subject: [PATCH 041/392] REQUEST SENSE now correctly delays the reporting of UNIT ATTENTION if another error is pending, unless the error is not ready and the REQUEST SENSE is a standalone command; The SCSI-specific auto-REQUEST SENSE now no longer advances UNIT ATTENTION phase, making sure the next command will report UNIT ATTENTION. --- src/buslogic.c | 2 +- src/cdrom.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 14d662437..b21b17e08 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1637,7 +1637,7 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co { BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); - BuslogicLog("First 8 bytes of written sense data: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); + BuslogicLog("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); } } } diff --git a/src/cdrom.c b/src/cdrom.c index 37e484735..9612bad08 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1590,7 +1590,7 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) } else { - if (cdrom[id].unit_attention) + if (cdrom[id].unit_attention && (cdrom_sense_key == 0)) { buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; @@ -1631,13 +1631,7 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len cdrom[id].unit_attention = 0; } - /* If the UNIT ATTENTION condition is set and the command does not allow - execution under it, error out and report the condition. */ - if (cdrom[id].unit_attention == 1) - { - // cdrom_log("CD-ROM %i: Unit attention now 2\n", id); - cdrom[id].unit_attention = 2; - } + /* Do *NOT* advance the unit attention phase. */ cdrom_request_sense(id, buffer, alloc_length); } @@ -1736,6 +1730,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_REQUEST_SENSE: + /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE + should forget about the not ready, and report unit attention straight away. */ + if (cdrom[id].unit_attention && (cdrom_sense_key == 2)) + { + cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; + } cdrom_request_sense(id, cdbufferb, cdb[4]); cdrom_data_command_finish(id, 18, 18, cdb[4], 0); break; From 754e8ff88fa1aae235a6e36032410283007027b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 06:21:46 +0100 Subject: [PATCH 042/392] SCSI incoming mailbox now correctly also rewrites the CCB up to the CDB even if the status is CHECK CONDITION, fixes CD-ROM disc changes when using SCSI; Previous CD-ROM sense is now correctly cleared when a REQUEST SENSE command is performed, fixes detection of disc change after setting the drive to empty first regardless of what bus is used for the CD-ROM. --- src/buslogic.c | 23 +++++++++++++---------- src/cdrom.c | 26 ++++++++++---------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index b21b17e08..182765cd5 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -521,7 +521,7 @@ int scsi_base = 0x330; int scsi_dma = 6; int scsi_irq = 11; -int buslogic_do_log = 1; +int buslogic_do_log = 0; int BuslogicCallback = 0; @@ -711,11 +711,8 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C CmdBlock->common.TargetStatus = TargetStatus; //Rewrite the CCB up to the CDB. - if ((CmdBlock->common.TargetStatus != 0x02) && (CCBPointer != 0)) - { - BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); - DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); - } + BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); + DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); } else { @@ -806,7 +803,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && DataLength) - { + { if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { @@ -1595,10 +1592,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) { + BuslogicLog("Unconverted Request Sense length %i\n", RequestSenseLength); + if (RequestSenseLength == 0) RequestSenseLength = 14; - else if ((RequestSenseLength >= 1) && (RequestSenseLength < 8)) + else if (RequestSenseLength == 1) RequestSenseLength = 0; + /* else if ((RequestSenseLength > 1) && (RequestSenseLength < 8)) + { + if (!scsi_model) RequestSenseLength = 0; + } */ BuslogicLog("Request Sense length %i\n", RequestSenseLength); @@ -1607,7 +1610,7 @@ static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Copy) { - uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); + uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); uint8_t cdrom_id = scsi_cdrom_drives[BuslogicRequests->TargetID][BuslogicRequests->LUN]; uint8_t temp_sense[256]; @@ -1873,7 +1876,7 @@ static int BuslogicProcessMailbox(Buslogic_t *Buslogic) /* Check if the mailbox is actually loaded. */ if (Mailbox32.u.out.ActionCode == MBO_FREE) { - BuslogicLog("No loaded mailbox left\n"); + // BuslogicLog("No loaded mailbox left\n"); if (Buslogic->MailboxOutInterrupts) { diff --git a/src/cdrom.c b/src/cdrom.c index 9612bad08..03671d5a0 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -909,13 +909,10 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al cdrom_log("CD-ROM %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", id, cdrom[id].packet_status, cdrom[id].request_length, cdrom[id].packet_len, cdrom[id].pos, cdrom[id].phase); } -static void cdrom_sense_clear(int id, int command, int ignore_ua) +static void cdrom_sense_clear(int id, int command) { - if ((cdrom_sense_key == SENSE_UNIT_ATTENTION) || ignore_ua) - { - cdrom[id].previous_command = command; - cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; - } + cdrom[id].previous_command = command; + cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; } static void cdrom_cmd_error(uint8_t id) @@ -1469,15 +1466,16 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) disc changes. */ cdrom[id].unit_attention = 0; } - + /* If the UNIT ATTENTION condition is set and the command does not allow execution under it, error out and report the condition. */ if (cdrom[id].unit_attention == 1) { - // cdrom_log("CD-ROM %i: Unit attention now 2\n", id); - cdrom[id].unit_attention = 2; + /* Only increment the unit attention phase if the command can not pass through it. */ if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) { + // cdrom_log("CD-ROM %i: Unit attention now 2\n", id); + cdrom[id].unit_attention = 2; cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); cdrom_unit_attention(id); return 0; @@ -1496,7 +1494,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) { - cdrom_sense_clear(id, cdb[0], 1); + cdrom_sense_clear(id, cdb[0]); } /* Next it's time for NOT READY. */ @@ -1608,7 +1606,7 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) } /* Clear the sense stuff as per the spec. */ - cdrom_sense_clear(id, GPCMD_REQUEST_SENSE, 0); + cdrom_sense_clear(id, GPCMD_REQUEST_SENSE); } void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) @@ -1630,7 +1628,7 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len disc changes. */ cdrom[id].unit_attention = 0; } - + /* Do *NOT* advance the unit attention phase. */ cdrom_request_sense(id, buffer, alloc_length); @@ -1732,10 +1730,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_REQUEST_SENSE: /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE should forget about the not ready, and report unit attention straight away. */ - if (cdrom[id].unit_attention && (cdrom_sense_key == 2)) - { - cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; - } cdrom_request_sense(id, cdbufferb, cdb[4]); cdrom_data_command_finish(id, 18, 18, cdb[4], 0); break; From 0dd769d72711ba0f8b12edf1c9797b1cbafdcdae Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 17:48:45 +0100 Subject: [PATCH 043/392] ATA PACKET COMMAND now correctly callbacks+aborts when issued on a hard disk, fixes hard disk problems with a DOS CD-ROM driver loaded. --- src/ide.c | 92 ++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 52 deletions(-) diff --git a/src/ide.c b/src/ide.c index c1dca50e6..abcb9e224 100644 --- a/src/ide.c +++ b/src/ide.c @@ -138,11 +138,11 @@ int idecallback[4] = {0, 0, 0, 0}; int cur_ide[4]; -int ide_do_log = 0; +int ide_do_log = 1; void ide_log(const char *format, ...) { -#ifdef ENABLE_IDE_LOG +// #ifdef ENABLE_IDE_LOG if (ide_do_log) { va_list ap; @@ -151,7 +151,7 @@ void ide_log(const char *format, ...) va_end(ap); fflush(stdout); } -#endif +// #endif } uint8_t getstat(IDE *ide) { return ide->atastat; } @@ -565,6 +565,8 @@ void ide_set_signature(IDE *ide) if (ide_drive_is_cdrom(ide)) { cdrom_set_signature(cdrom_id); + ide->secount = cdrom[cdrom_id].phase; + ide->cylinder = cdrom[cdrom_id].request_length; } else { @@ -865,19 +867,13 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) { cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].features = val; } - else - { - ide->cylprecomp = val; - } + ide->cylprecomp = val; if (ide_drive_is_cdrom(ide_other)) { cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].features = val; } - else - { - ide_other->cylprecomp = val; - } + ide_other->cylprecomp = val; return; case 0x1F2: /* Sector count */ @@ -886,20 +882,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide_log("Sector count write: %i\n", val); cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].phase = val; } - else - { - ide->secount = val; - } + ide->secount = val; if (ide_drive_is_cdrom(ide_other)) { ide_log("Other sector count write: %i\n", val); cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].phase = val; } - else - { - ide_other->secount = val; - } + ide_other->secount = val; return; case 0x1F3: /* Sector */ @@ -915,22 +905,16 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF00; cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= val; } - else - { - ide->cylinder = (ide->cylinder & 0xFF00) | val; - ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); - } + ide->cylinder = (ide->cylinder & 0xFF00) | val; + ide->lba_addr = (ide->lba_addr & 0xFFF00FF) | (val << 8); if (ide_drive_is_cdrom(ide_other)) { cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF00; cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= val; } - else - { - ide_other->cylinder = (ide_other->cylinder&0xFF00) | val; - ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); - } + ide_other->cylinder = (ide_other->cylinder&0xFF00) | val; + ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); return; case 0x1F5: /* Cylinder high */ @@ -939,22 +923,16 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF; cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length |= (val << 8); } - else - { - ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); - } + ide->cylinder = (ide->cylinder & 0xFF) | (val << 8); + ide->lba_addr = (ide->lba_addr & 0xF00FFFF) | (val << 16); if (ide_drive_is_cdrom(ide_other)) { cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length &= 0xFF; cdrom[atapi_cdrom_drives[cur_ide[ide_board] ^ 1]].request_length |= (val << 8); } - else - { - ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); - } + ide_other->cylinder = (ide_other->cylinder & 0xFF) | (val << 8); + ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); return; case 0x1F6: /* Drive/Head */ @@ -979,6 +957,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; cdrom[atapi_cdrom_drives[ide->channel]].request_length = 0xEB14; cdrom[atapi_cdrom_drives[ide->channel]].callback = 0; + ide->cylinder = 0xEB14; } if (ide_drive_is_cdrom(ide_other)) { @@ -987,6 +966,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) cdrom[atapi_cdrom_drives[ide_other->channel]].phase = 1; cdrom[atapi_cdrom_drives[ide_other->channel]].request_length = 0xEB14; cdrom[atapi_cdrom_drives[ide_other->channel]].callback = 0; + ide->cylinder = 0xEB14; } idecallback[ide_board] = 0; @@ -1013,6 +993,8 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) { return; } + +#if 0 if (ide_drive_is_cdrom(ide)) { #if 0 @@ -1032,13 +1014,18 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_STANDBYNOW1: break; default: + ide_irq_lower(ide); + ide->command=val; val = 0xFF; + goto skip_to_command_processing; break; } } +#endif ide_irq_lower(ide); ide->command=val; - + +skip_to_command_processing: // ide_log("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); ide->error=0; if (ide_drive_is_cdrom(ide)) @@ -1259,9 +1246,12 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } else { - ide->pos=0; - ide->secount = 1; - ide->atastat = READY_STAT | DRQ_STAT |(ide->atastat&ERR_STAT); + ide->packetstatus = ATAPI_STATUS_IDLE; + ide->atastat = BUSY_STAT; + timer_process(); + idecallback[ide_board]=1;//30*IDE_TIME; + timer_update_outstanding(); + ide->pos=0; } return; @@ -1289,7 +1279,7 @@ ide_bad_command: timer_process(); if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 500*IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]].callback = 0; } idecallback[ide_board]=500*IDE_TIME; timer_update_outstanding(); @@ -1501,14 +1491,7 @@ uint8_t readide(int ide_board, uint16_t addr) break; case 0x1F6: /* Drive/Head */ - if (ide_drive_is_cdrom(ide)) - { - temp = (uint8_t)(((cur_ide[ide_board] & 1) ? 0x10 : 0) | 0xa0); - } - else - { - temp = (uint8_t)(ide->head | ((cur_ide[ide_board] & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); - } + temp = (uint8_t)(ide->head | ((cur_ide[ide_board] & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); break; /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is @@ -1616,6 +1599,7 @@ void callbackide(int ide_board) cdrom[cdrom_id].error = 1; cdrom[cdrom_id].phase = 1; cdrom[cdrom_id].request_length=0xEB14; + ide->cylinder = 0xEB14; if (cdrom_drives[cdrom_id].handler->stop) { cdrom_drives[cdrom_id].handler->stop(cdrom_id); @@ -1632,6 +1616,7 @@ void callbackide(int ide_board) cdrom[cdrom_id].error = 1; cdrom[cdrom_id].phase = 1; cdrom[cdrom_id].request_length=0xEB14; + ide_other->cylinder = 0xEB14; if (cdrom_drives[cdrom_id].handler->stop) { cdrom_drives[cdrom_id].handler->stop(cdrom_id); @@ -1659,6 +1644,9 @@ void callbackide(int ide_board) if (ide_drive_is_cdrom(ide)) { + cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + cdrom[cdrom_id].error = 1; + cdrom[cdrom_id].phase = 1; cdrom_reset(cdrom_id); } ide_irq_raise(ide); From bd28cc5e57001730346c96a1c4213ce1b7565abe Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 21 Jan 2017 17:52:27 +0100 Subject: [PATCH 044/392] Disabled the IDE logging again. --- src/ide.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ide.c b/src/ide.c index abcb9e224..a3b99b623 100644 --- a/src/ide.c +++ b/src/ide.c @@ -138,11 +138,11 @@ int idecallback[4] = {0, 0, 0, 0}; int cur_ide[4]; -int ide_do_log = 1; +int ide_do_log = 0; void ide_log(const char *format, ...) { -// #ifdef ENABLE_IDE_LOG +#ifdef ENABLE_IDE_LOG if (ide_do_log) { va_list ap; @@ -151,7 +151,7 @@ void ide_log(const char *format, ...) va_end(ap); fflush(stdout); } -// #endif +#endif } uint8_t getstat(IDE *ide) { return ide->atastat; } From 46479aa1bde1ab236fff6e2a52308504bc1cb08e Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sun, 22 Jan 2017 00:22:14 -0600 Subject: [PATCH 045/392] Add basic USB support sorta --- src/Makefile.am | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/usb.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ src/usb.h | 32 +++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 src/usb.c create mode 100644 src/usb.h diff --git a/src/Makefile.am b/src/Makefile.am index 10ca53e8d..233d3c6a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,7 @@ olivetti_m24.c opti.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c scat.c ser sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \ sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \ sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c thread-pthread.c \ -timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \ +timer.c um8669f.c um8881f.c usb.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \ vid_ati68860_ramdac.c vid_cga.c vid_cl_gd.c vid_cl_gd_blit.c vid_cl_ramdac.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_hercules.c vid_herculesplus.c\ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_nv_riva128.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \ vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c \ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e3e69794a..ec298348f 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -13,7 +13,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ - soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o usb.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_hercules.o vid_herculesplus.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \ vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index a18c8d8f3..389e2296e 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -13,7 +13,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ - soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ + soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o usb.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \ vid_et4000w32.o vid_hercules.o vid_herculesplus.ovid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \ vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ diff --git a/src/usb.c b/src/usb.c new file mode 100644 index 000000000..9a1d424c0 --- /dev/null +++ b/src/usb.c @@ -0,0 +1,48 @@ +/* Copyright holders: Melissa Goad + see COPYING for more details +*/ + +#include + +#include "ibm.h" +#include "io.h" +#include "mem.h" + +#include "usb.h" + +uint8_t (*usb_packet_handle[32])(usb_packet_t* packet, void *priv); +void *usb_priv[32]; +static int usb_min_card, usb_max_card; + +void usb_init(int min_card, int max_card) +{ + int c; + + for (c = 0; c < 32; c++) + usb_packet_handle[c] = usb_priv[c] = NULL; + + usb_min_card = min_card; + usb_max_card = max_card; +} + +void usb_add_specific(int card, void (*packet_handle)(usb_packet_t *packet, void *priv), void *priv) +{ + usb_packet_handle[card] = packet_handle; + usb_priv[card] = priv; +} + +void usb_add(void (*packet_handle)(usb_packet_t *packet, void *priv), void *priv) +{ + int c; + + for (c = usb_min_card; c <= usb_max_card; c++) + { + if (!usb_packet_handle[c]) + { + usb_packet_handle[c] = packet_handle; + usb_priv[c] = priv; + // pclog("USB device added to card: %i\n", c); + return; + } + } +} \ No newline at end of file diff --git a/src/usb.h b/src/usb.h new file mode 100644 index 000000000..b61e702f2 --- /dev/null +++ b/src/usb.h @@ -0,0 +1,32 @@ +/* Copyright holders: Melissa Goad + see COPYING for more details +*/ + +typedef struct +{ + uint8_t pid; //low 4 bits are the real pid, top 4 bits are just ~pid + uint8_t dev_addr; + uint8_t dev_endpoint; + uint8_t* data; + int len; + void* device; +} usb_packet_t; + +typedef enum +{ + USB_DEV_TYPE_NONE = 0, + USB_DEV_TYPE_MOUSE, + USB_DEV_TYPE_TABLET, + USB_DEV_TYPE_KEYPAD, + USB_DEV_TYPE_DISK, + USB_DEV_TYPE_CDROM, + USB_DEV_TYPE_HUB, + USB_DEV_TYPE_PRINTER +} usb_device_type_t; + +typedef enum +{ + USB_PID_TOKEN_SETUP = 0x2d, + USB_PID_TOKEN_IN = 0x69, + USB_PID_TOKEN_OUT = 0xe1 +} usb_pid_type_t; \ No newline at end of file From f52213d4e322c19452a2860cf2517bc7b14d79b6 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sun, 22 Jan 2017 00:35:15 -0600 Subject: [PATCH 046/392] Add more PID token types --- src/usb.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/usb.h b/src/usb.h index b61e702f2..69adcf96b 100644 --- a/src/usb.h +++ b/src/usb.h @@ -7,7 +7,9 @@ typedef struct uint8_t pid; //low 4 bits are the real pid, top 4 bits are just ~pid uint8_t dev_addr; uint8_t dev_endpoint; - uint8_t* data; + int crc5; + uint16_t crc16; + uint8_t data[1024]; int len; void* device; } usb_packet_t; @@ -26,7 +28,14 @@ typedef enum typedef enum { + USB_PID_TOKEN_STALL = 0x1e, USB_PID_TOKEN_SETUP = 0x2d, + USB_PID_TOKEN_PRE = 0x3c, + USB_PID_TOKEN_DATA1 = 0x4b, + USB_PID_TOKEN_NAK = 0x5a, USB_PID_TOKEN_IN = 0x69, + USB_PID_TOKEN_SOF = 0xa5, + USB_PID_TOKEN_DATA0 = 0xc3, + USB_PID_TOKEN_ACK = 0xd2, USB_PID_TOKEN_OUT = 0xe1 } usb_pid_type_t; \ No newline at end of file From bc5ac4a699babdebfd6d07d1bf0a7fc895b1fd08 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 24 Jan 2017 01:03:23 +0100 Subject: [PATCH 047/392] Reverted Direct3D to 2048x2048 buffer and suppressed the EGA/(S)VGA overscan, if enabled, in 2048x modes, fixes Direct3D freezes; Improved the BusLogic incoming mailbox code; The BusLogic callback is now three-phases and outgoing mailbox interrupts are emulated correctly; Fixed the CD-ROM command READ DISC INFORMATION (0x51), fixes NetBSD crashing 86Box with segmentation fault when using the AHA-154x; Added the CD-ROM command PAUSE/RESUME ALT (0xC2). --- src/buslogic.c | 331 +++++++++++++++++++++---------------------- src/cdrom.c | 15 +- src/disc.c | 12 +- src/dma.c | 2 +- src/ibm.h | 2 + src/ide.c | 24 +--- src/pc.c | 4 + src/scsi.h | 1 + src/vid_ati_mach64.c | 4 +- src/vid_cl_gd.c | 4 +- src/vid_et4000w32.c | 18 +-- src/vid_s3.c | 4 +- src/vid_s3_virge.c | 4 +- src/vid_svga.c | 13 +- src/vid_voodoo.c | 23 ++- src/video.c | 4 +- src/win-d3d-fs.cc | 26 ++-- src/win-d3d.cc | 67 +++++---- src/win-ddraw-fs.cc | 4 +- src/win-ddraw.cc | 8 +- src/win.c | 16 ++- 21 files changed, 308 insertions(+), 278 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 182765cd5..5c94fee82 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -480,6 +480,9 @@ typedef struct __attribute__((packed)) BuslogicRequests_t int Is24bit; uint8_t TargetID; uint8_t LUN; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t MailboxCompletionCode; } BuslogicRequests_t; typedef struct __attribute__((packed)) Buslogic_t @@ -512,7 +515,6 @@ typedef struct __attribute__((packed)) Buslogic_t int Mbx24bit; int MailboxOutInterrupts; int MbiActive[256]; - int DoScan; int PendingInterrupt; } Buslogic_t; @@ -521,9 +523,10 @@ int scsi_base = 0x330; int scsi_dma = 6; int scsi_irq = 11; -int buslogic_do_log = 0; - int BuslogicCallback = 0; +int BuslogicInOperation = 0; + +int buslogic_do_log = 0; static void BuslogicStartMailbox(Buslogic_t *Buslogic); @@ -596,8 +599,8 @@ static void BuslogicReset(Buslogic_t *Buslogic) Buslogic->MailboxOutPosCur = 0; Buslogic->MailboxInPosCur = 0; Buslogic->MailboxOutInterrupts = 0; - Buslogic->DoScan = 0; Buslogic->PendingInterrupt = 0; + BuslogicInOperation = 0; BuslogicClearInterrupt(Buslogic); @@ -617,9 +620,8 @@ static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset) static void BuslogicCommandComplete(Buslogic_t *Buslogic) { Buslogic->DataReply = 0; - Buslogic->Status |= STAT_IDLE; - + if (Buslogic->Command != 0x02) { Buslogic->Status &= ~STAT_DFULL; @@ -632,6 +634,38 @@ static void BuslogicCommandComplete(Buslogic_t *Buslogic) Buslogic->CmdParam = 0; } +static void BuslogicRaiseInterrupt(Buslogic_t *Buslogic, uint8_t Interrupt) +{ + if (Buslogic->Interrupt & INTR_HACC) + { + BuslogicLog("Pending IRQ\n"); + Buslogic->PendingInterrupt = Interrupt; + } + else + { + Buslogic->Interrupt = Interrupt; + BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); + if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); + } +} + +static void BuslogicMailboxInSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock, + uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode) +{ + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + + BuslogicRequests->CCBPointer = CCBPointer; + memcpy(&(BuslogicRequests->CmdBlock), CmdBlock, sizeof(CCB32)); + BuslogicRequests->Is24bit = Buslogic->Mbx24bit; + BuslogicRequests->HostStatus = HostStatus; + BuslogicRequests->TargetStatus = TargetStatus; + BuslogicRequests->MailboxCompletionCode = MailboxCompletionCode; + + BuslogicLog("Mailbox in setup\n"); + + BuslogicInOperation = 2; +} + static uint32_t BuslogicMailboxInRead(Buslogic_t *Buslogic, uint8_t *CompletionCode) { Mailbox32_t TempMailbox32; @@ -660,50 +694,28 @@ static void BuslogicMailboxInAdvance(Buslogic_t *Buslogic) Buslogic->MailboxInPosCur = (Buslogic->MailboxInPosCur + 1) % Buslogic->MailboxCount; } -static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock, - uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode) +static void BuslogicMailboxIn(Buslogic_t *Buslogic) { + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + + uint32_t CCBPointer = BuslogicRequests->CCBPointer; + CCBU *CmdBlock = &(BuslogicRequests->CmdBlock); + uint8_t HostStatus = BuslogicRequests->HostStatus; + uint8_t TargetStatus = BuslogicRequests->TargetStatus; + uint8_t MailboxCompletionCode = BuslogicRequests->MailboxCompletionCode; + Mailbox32_t Mailbox32; Mailbox_t MailboxIn; Mailbox32_t TempMailbox32; Mailbox_t TempMailboxIn; - uint32_t Incoming = 0; - uint32_t i = 0; - - uint8_t CompletionCode = 0; - Mailbox32.CCBPointer = CCBPointer; Mailbox32.u.in.HostStatus = HostStatus; Mailbox32.u.in.TargetStatus = TargetStatus; Mailbox32.u.in.CompletionCode = MailboxCompletionCode; - Incoming = 0; - - if (!Buslogic->StrictRoundRobinMode) - { - uint8_t MailboxCur = Buslogic->MailboxInPosCur; - - /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ - do - { - /* Fetch mailbox from guest memory. */ - Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode); - - /* Check the next mailbox. */ - BuslogicMailboxInAdvance(Buslogic); - } while ((CompletionCode != MBI_FREE) && (MailboxCur != Buslogic->MailboxInPosCur)); - } - else - { - Incoming = BuslogicMailboxInRead(Buslogic, &CompletionCode); - } - - if (CompletionCode != MBI_FREE) - { - return; - } + uint32_t Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); if (MailboxCompletionCode != MBI_NOT_FOUND) { @@ -734,30 +746,17 @@ static void BuslogicMailboxIn(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *C { BuslogicLog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); - if (Incoming != 0) - { - DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); - BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); - } + DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); + BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); } + + Buslogic->MailboxInPosCur++; + if (Buslogic->MailboxInPosCur >= Buslogic->MailboxCount) + Buslogic->MailboxInPosCur = 0; - /* Advance to the next mailbox. */ - if (Buslogic->StrictRoundRobinMode) - { - BuslogicMailboxInAdvance(Buslogic); - } + BuslogicRaiseInterrupt(Buslogic, INTR_MBIF | INTR_ANY); - if (Buslogic->Interrupt & INTR_HACC) - { - BuslogicLog("Pending IRQ\n"); - Buslogic->PendingInterrupt = INTR_MBIF | INTR_ANY; - } - else - { - Buslogic->Interrupt = INTR_MBIF | INTR_ANY; - BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); - if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); - } + BuslogicInOperation = 0; } static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) @@ -844,7 +843,7 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //checking its length, so do this procedure for both no read/write commands. - if (BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT || BuslogicRequests->CmdBlock.common.ControlByte == 0x00) + if ((BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (BuslogicRequests->CmdBlock.common.ControlByte == 0x00)) { ScatterGatherLeft = DataLength / ScatterGatherEntryLength; ScatterGatherAddrCurrent = DataPointer; @@ -891,20 +890,11 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *BuslogicRequests, int Is24bi } } -uint32_t BuslogicGetDataLength(BuslogicRequests_t *BuslogicRequests) -{ - if (BuslogicRequests->Is24bit) - { - return ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength); - } - else - { - return BuslogicRequests->CmdBlock.new.DataLength; - } -} - void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) { + uint32_t DataPointer = 0; + uint32_t DataLength = 0; + uint32_t sg_buffer_pos = 0; uint32_t transfer_length = 0; @@ -936,7 +926,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) } BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); - + //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without //checking its length, so do this procedure for both read/write commands. if ((DataLength > 0) && @@ -999,7 +989,7 @@ void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) /* Should be 0 when scatter/gather? */ if (DataLength >= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) { - Residual = BuslogicGetDataLength(BuslogicRequests); + Residual = DataLength; Residual -= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; } else @@ -1100,7 +1090,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic_t *Buslogic = (Buslogic_t *)p; BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - // BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); + BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); switch (Port & 3) { @@ -1119,11 +1109,20 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 1: - if (!(Buslogic->Status & STAT_IDLE) && (Buslogic->Command == 0xFF) && (Val != 0x02) && (Val != 0x05)) + /* Fast path for the mailbox execution command. */ + if ((Val == 0x02) && (Buslogic->Command == 0xFF)) { - break; /* Any command other than 02 and 05 can only be executed when the IDLE bit is set. */ + /* If there are no mailboxes configured, don't even try to do anything. */ + if (Buslogic->MailboxCount) + { + if (!BuslogicCallback) + { + BuslogicCallback = 50 * SCSI_TIME; + } + } + return; } - + if (Buslogic->Command == 0xFF) { Buslogic->Command = Val; @@ -1134,7 +1133,6 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) switch (Buslogic->Command) { case 0x00: - case 0x02: case 0x04: case 0x0A: case 0x0B: @@ -1229,27 +1227,6 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } break; - case 0x02: - if (Buslogic->Status & STAT_INIT) - { - Buslogic->Status |= STAT_INVCMD; - } - else - { - if (!BuslogicCallback) - { - BuslogicLog("SCSI started\n"); - BuslogicCallback = 1; - } - else - { - BuslogicLog("SCSI reactivated\n"); - } - Buslogic->DoScan = 1; - } - Buslogic->DataReplyLeft = 0; - break; - case 0x04: Buslogic->DataBuf[0] = 0x41; Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; @@ -1507,6 +1484,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf; Reply->uBusType = 'A'; /* ISA style */ + Reply->uBiosAddress = 0; Reply->u16ScatterGatherLimit = 8192; Reply->cMailbox = Buslogic->MailboxCount; Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr; @@ -1520,15 +1498,21 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } } break; - + + /* VirtualBox has these two modes implemented in reverse. + According to the BusLogic datasheet: + 0 is the strict round robin mode, which is also the one used by the AHA-154x according to the + Adaptec specification; + 1 is the aggressive round robin mode, which "hunts" for an active outgoing mailbox and then + processes it. */ case 0x8F: if (scsi_model) { if (Buslogic->CmdBuf[0] == 0) - Buslogic->StrictRoundRobinMode = 0; - else if (Buslogic->CmdBuf[0] == 1) Buslogic->StrictRoundRobinMode = 1; - + else if (Buslogic->CmdBuf[0] == 1) + Buslogic->StrictRoundRobinMode = 0; + Buslogic->DataReplyLeft = 0; } else @@ -1636,24 +1620,29 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Co BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress); - if (SenseBufferAddress) - { - BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); - DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); - BuslogicLog("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); - } + BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); + BuslogicLog("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); } } -static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun, uint8_t cdrom_id) +static void BuslogicCDROMCommand(Buslogic_t *Buslogic) { BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + uint8_t Id, Lun; + + uint8_t cdrom_id; uint8_t cdrom_phase; uint32_t temp = 0; uint8_t temp_cdb[12]; uint32_t i; + + Id = BuslogicRequests->TargetID; + Lun = BuslogicRequests->LUN; + + cdrom_id = scsi_cdrom_drives[Id][Lun]; BuslogicLog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); @@ -1685,7 +1674,6 @@ static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun, //Finally, execute the SCSI command immediately and get the transfer length. SCSIPhase = SCSI_PHASE_COMMAND; - SCSIDevices[Id][Lun].InitLength = 0; cdrom_command(cdrom_id, temp_cdb); SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); if (SCSIStatus == SCSI_STATUS_OK) @@ -1712,6 +1700,21 @@ static void BuslogicCDROMCommand(Buslogic_t *Buslogic, uint8_t Id, uint8_t Lun, } BuslogicLog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); + + BuslogicDataBufferFree(BuslogicRequests); + + BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); + + BuslogicLog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) + { + BuslogicMailboxInSetup(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } + else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) + { + BuslogicMailboxInSetup(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } } static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) @@ -1726,6 +1729,9 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M //Fetch data from the Command Control Block. DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32)); + + BuslogicRequests->Is24bit = Buslogic->Mbx24bit; + BuslogicRequests->CCBPointer = CCBPointer; BuslogicRequests->TargetID = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Id : BuslogicRequests->CmdBlock.new.Id; BuslogicRequests->LUN = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Lun : BuslogicRequests->CmdBlock.new.Lun; @@ -1735,7 +1741,7 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M if ((Id > last_id) || (Lun > 7)) { - BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + BuslogicMailboxInSetup(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); return 1; } @@ -1743,11 +1749,10 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M cdrom_id = scsi_cdrom_drives[Id][Lun]; - BuslogicRequests->CCBPointer = CCBPointer; - BuslogicRequests->Is24bit = Buslogic->Mbx24bit; - SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[Id][Lun].InitLength = 0; + BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); if (!buslogic_scsi_drive_is_cdrom(Id, Lun)) @@ -1758,7 +1763,7 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M BuslogicSenseBufferFree(BuslogicRequests, 0); - BuslogicMailboxIn(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); + BuslogicMailboxInSetup(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); } else { @@ -1773,22 +1778,7 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M BuslogicLog("Invalid control byte: %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); } - BuslogicCDROMCommand(Buslogic, Id, Lun, cdrom_id); - - BuslogicDataBufferFree(BuslogicRequests); - - BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); - - BuslogicLog("Request complete\n"); - - if (SCSIStatus == SCSI_STATUS_OK) - { - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - } - else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) - { - BuslogicMailboxIn(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - } + BuslogicInOperation = 1; } return 1; @@ -1803,7 +1793,7 @@ static int BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) DMAPageRead(CCBPointer, &CmdBlock, sizeof(CCB32)); //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. - BuslogicMailboxIn(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); + BuslogicMailboxInSetup(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); return 1; } @@ -1873,37 +1863,26 @@ static int BuslogicProcessMailbox(Buslogic_t *Buslogic) Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); } - /* Check if the mailbox is actually loaded. */ - if (Mailbox32.u.out.ActionCode == MBO_FREE) - { - // BuslogicLog("No loaded mailbox left\n"); - - if (Buslogic->MailboxOutInterrupts) - { - if (Buslogic->Interrupt & INTR_HACC) - { - BuslogicLog("Pending IRQ\n"); - Buslogic->PendingInterrupt = INTR_MBOA | INTR_ANY; - } - else - { - BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); - Buslogic->Interrupt = INTR_MBOA | INTR_ANY; - if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); - } - } - - return 0; - } - - /* We got the mailbox, mark it as free in the guest. */ if (Mailbox32.u.out.ActionCode != MBO_FREE) { + /* We got the mailbox, mark it as free in the guest. */ BuslogicLog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); } - if ((Mailbox32.u.out.ActionCode == MBO_START) || (Mailbox32.u.out.ActionCode == MBO_FREE)) + if (Buslogic->MailboxOutInterrupts) + { + BuslogicRaiseInterrupt(Buslogic, INTR_MBOA | INTR_ANY); + } + + /* Check if the mailbox is actually loaded. */ + if (Mailbox32.u.out.ActionCode == MBO_FREE) + { + // BuslogicLog("No loaded mailbox left\n"); + return 0; + } + + if (Mailbox32.u.out.ActionCode == MBO_START) { BuslogicLog("Start Mailbox Command\n"); ret = BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32); @@ -1932,21 +1911,41 @@ void BuslogicCommandCallback(void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; + BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; + int ret = 0; int i = 0; - // BuslogicLog("BusLogic Callback!\n"); - - if (Buslogic->MailboxCount) - { - ret = BuslogicProcessMailbox(Buslogic); + // BuslogicLog("BusLogic Callback (%08X)!\n", BuslogicCallback); - BuslogicCallback += 50 * SCSI_TIME; + if (BuslogicInOperation == 0) + { + BuslogicLog("BusLogic Callback: Start outgoing mailbox\n"); + if (Buslogic->MailboxCount) + { + ret = BuslogicProcessMailbox(Buslogic); + } + else + { + fatal("Callback active with mailbox count 0!\n"); + } + } + else if (BuslogicInOperation == 1) + { + BuslogicLog("BusLogic Callback: Process request\n"); + BuslogicCDROMCommand(Buslogic); + } + else if (BuslogicInOperation == 2) + { + BuslogicLog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(Buslogic); } else { - fatal("Callback active with mailbox count 0!\n"); + fatal("Invalid BusLogic callback phase: %i\n", BuslogicInOperation); } + + BuslogicCallback += 50 * SCSI_TIME; } void *BuslogicInit() diff --git a/src/cdrom.c b/src/cdrom.c index 03671d5a0..df218e204 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -117,6 +117,7 @@ uint8_t cdrom_command_flags[0x100] = [GPCMD_MECHANISM_STATUS] = IMPLEMENTED, [GPCMD_READ_CD] = IMPLEMENTED | CHECK_READY, [GPCMD_SEND_DVD_STRUCTURE] = IMPLEMENTED | CHECK_READY, + [GPCMD_PAUSE_RESUME_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, [GPCMD_SCAN_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, [GPCMD_SET_SPEED_ALT] = IMPLEMENTED | SCSI_ONLY }; @@ -2084,6 +2085,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_READ_DISC_INFORMATION: + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len); @@ -2105,7 +2110,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) len=34; } - cdrom_data_command_finish(id, len, len, alloc_length, 0); + cdrom_data_command_finish(id, len, len, max_len, 0); break; case GPCMD_READ_TRACK_INFORMATION: @@ -2156,7 +2161,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } } - cdrom_data_command_finish(id, len, len, alloc_length, 0); + cdrom_data_command_finish(id, len, len, max_len, 0); break; case GPCMD_PLAY_AUDIO_10: @@ -2326,11 +2331,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { ret = cdrom_read_dvd_structure(id, format, cdb, cdbufferb); - /* if (!ret) - { - cdrom_cmd_error(id, SENSE_ILLEGAL_REQUEST, -ret, 0); - } - else */ if (ret) { cdrom_data_command_finish(id, len, len, alloc_length, 0); @@ -2467,6 +2467,7 @@ atapi_out: cdrom_command_complete(id); break; + case GPCMD_PAUSE_RESUME_ALT: case GPCMD_PAUSE_RESUME: if (cdb[8] & 1) { diff --git a/src/disc.c b/src/disc.c index ee4a4ccc3..8a273f463 100644 --- a/src/disc.c +++ b/src/disc.c @@ -194,14 +194,22 @@ double disc_real_period(int drive) dusec = (double) TIMER_USEC; - return (ddbp * dusec); + /* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */ + if (romset == ROM_MRTHOR) + { + return (ddbp * dusec) / 2.0; + } + else + { + return (ddbp * dusec); + } } void disc_poll(int drive) { if (drive >= FDD_NUM) { - disc_poll_time[drive] += (int) (32.0 * TIMER_USEC); + disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC); return; } diff --git a/src/dma.c b/src/dma.c index d61e22cc3..723c2c7a4 100644 --- a/src/dma.c +++ b/src/dma.c @@ -594,8 +594,8 @@ void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize) void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize) { // uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); - memcpy(&ram[PhysAddress], DataWrite, TotalSize); mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); + memcpy(&ram[PhysAddress], DataWrite, TotalSize); // DataWrite -= PageLen; DataWrite -= TotalSize; } diff --git a/src/ibm.h b/src/ibm.h index ef2896d8f..abcf11f4d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -607,3 +607,5 @@ extern int fdc_do_log; extern int ide_do_log; extern int ne2000_do_log; #endif + +extern int suppress_overscan; diff --git a/src/ide.c b/src/ide.c index a3b99b623..83ff385e4 100644 --- a/src/ide.c +++ b/src/ide.c @@ -378,8 +378,7 @@ static void ide_identify(IDE *ide) if (ide->board < 2) { ide->buffer[53] = 2; - ide->buffer[62] = ide->dma_identify_data[0]; - ide->buffer[63] = ide->dma_identify_data[1]; + ide->buffer[63] = ide->dma_identify_data[0]; ide->buffer[65] = 150; ide->buffer[66] = 150; // ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ @@ -415,8 +414,7 @@ static void ide_atapi_identify(IDE *ide) ide->buffer[49] |= 0x100; /* DMA supported */ ide->buffer[52] = 2 << 8; /*DMA timing mode*/ ide->buffer[53] = 2; - ide->buffer[62] = ide->dma_identify_data[0]; - ide->buffer[63] = ide->dma_identify_data[1]; + ide->buffer[63] = ide->dma_identify_data[0]; ide->buffer[65] = 150; ide->buffer[66] = 150; // ide->buffer[88] = ide->dma_identify_data[2]; @@ -645,29 +643,17 @@ int ide_set_features(IDE *ide) switch(sf_data >> 3) { case 0: - ide->dma_identify_data[0] = ide->dma_identify_data[1] = 7; - ide->dma_identify_data[2] = 0x3f; + ide->dma_identify_data[0] = 7; break; case 1: /* We do not (yet) emulate flow control, so return with error if this is attempted. */ return 0; - case 2: - if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) - { - return 0; - } - ide->dma_identify_data[0] = 7 | (1 << (val + 8)); - ide->dma_identify_data[1] = 7; - ide->dma_identify_data[2] = 0x3f; - break; case 4: if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) { return 0; } - ide->dma_identify_data[0] = 7; - ide->dma_identify_data[1] = 7 | (1 << (val + 8)); - ide->dma_identify_data[2] = 0x3f; + ide->dma_identify_data[0] = 7 | (1 << (val + 8)); break; default: return 0; @@ -739,8 +725,6 @@ void resetide(void) if (ide_drives[d].type != IDE_NONE) { ide_drives[d].dma_identify_data[0] = 7; - ide_drives[d].dma_identify_data[1] = 7 | (1 << 10); - ide_drives[d].dma_identify_data[2] = 0x3f; } ide_drives[d].error = 1; diff --git a/src/pc.c b/src/pc.c index 764af631c..3067757bc 100644 --- a/src/pc.c +++ b/src/pc.c @@ -393,10 +393,14 @@ void resetpc_cad() pc_keyboard_send(211); /* Delete key released */ } +int suppress_overscan = 0; + void resetpchard() { int i = 0; + suppress_overscan = 0; + savenvr(); saveconfig(); diff --git a/src/scsi.h b/src/scsi.h index 1400823cc..3a441af95 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -53,6 +53,7 @@ #define GPCMD_MECHANISM_STATUS 0xbd #define GPCMD_READ_CD 0xbe #define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ +#define GPCMD_PAUSE_RESUME_ALT 0xc2 #define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ #define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 1ed70ee5e..b74ad8d73 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -2496,8 +2496,8 @@ void mach64_hwcursor_draw(svga_t *svga, int displine) uint8_t dat; uint32_t col0 = mach64->ramdac.pallook[0]; uint32_t col1 = mach64->ramdac.pallook[1]; - int y_add = enable_overscan ? 16 : 0; - int x_add = enable_overscan ? 8 : 0; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; offset = svga->hwcursor_latch.xoff; for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) diff --git a/src/vid_cl_gd.c b/src/vid_cl_gd.c index b244f408a..b9b49c141 100644 --- a/src/vid_cl_gd.c +++ b/src/vid_cl_gd.c @@ -410,8 +410,8 @@ void clgd_hwcursor_draw(svga_t *svga, int displine) int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; int largecur = (svga->seqregs[0x12] & 4); int cursize = (largecur) ? 64 : 32; - int y_add = enable_overscan ? 16 : 0; - int x_add = enable_overscan ? 8 : 0; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; for (x = 0; x < cursize; x += 8) { diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index d5e879443..430bf7347 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -1043,20 +1043,22 @@ void et4000w32p_hwcursor_draw(svga_t *svga, int displine) int x, offset; uint8_t dat; offset = svga->hwcursor_latch.xoff; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 32] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 32] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 33 + x_add] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 33 + x_add] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 34] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 34] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? 0xFFFFFF : 0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 35] = (dat & 1) ? 0xFFFFFF : 0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x_add + x + 35] ^= 0xFFFFFF; dat >>= 2; offset += 4; } diff --git a/src/vid_s3.c b/src/vid_s3.c index 896447174..4cb3134e6 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2067,8 +2067,8 @@ void s3_hwcursor_draw(svga_t *svga, int displine) uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = enable_overscan ? 16 : 0; - int x_add = enable_overscan ? 8 : 0; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 5b0264633..24a315b15 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3328,8 +3328,8 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = enable_overscan ? 16 : 0; - int x_add = enable_overscan ? 8 : 0; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; // pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); for (x = 0; x < 64; x += 16) diff --git a/src/vid_svga.c b/src/vid_svga.c index d0090aa75..0f3cc464c 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -1497,6 +1497,17 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) if (xsize<64) xsize=640; if (ysize<32) ysize=200; + if (xsize > 2032) + { + x_add = 0; + y_add = 0; + suppress_overscan = 0; + } + else + { + suppress_overscan = 1; + } + updatewindowsize(xsize + x_add,ysize + y_add); } if (vid_resize) @@ -1505,7 +1516,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) ysize = wy + 1; } - if (enable_overscan) + if (enable_overscan && !suppress_overscan) { if ((wx >= 160) && ((wy + 1) >= 120)) { diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 3306a3fc3..8d8afeb39 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -3412,7 +3412,20 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { int y; - if (params->fbzMode & FBZ_RGB_WMASK) + int low_y, high_y; + + if (params->fbzMode & (1 << 17)) + { + high_y = voodoo->v_disp - params->clipLowY; + low_y = voodoo->v_disp - params->clipHighY; + } + else + { + low_y = params->clipLowY; + high_y = params->clipHighY; + } + + if (params->fbzMode & FBZ_RGB_WMASK) { int r, g, b; uint16_t col; @@ -3422,7 +3435,7 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) b = (params->color1 >> 3) & 0x1f; col = b | (g << 5) | (r << 11); - for (y = params->clipLowY; y < params->clipHighY; y++) + for (y = low_y; y < high_y; y++) { uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y*voodoo->row_width) & voodoo->fb_mask]; int x; @@ -3433,7 +3446,7 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) } if (params->fbzMode & FBZ_DEPTH_WMASK) { - for (y = params->clipLowY; y < params->clipHighY; y++) + for (y = low_y; y < high_y; y++) { uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y*voodoo->row_width) & voodoo->fb_mask]; int x; @@ -6556,8 +6569,8 @@ static void voodoo_filterline(voodoo_t *voodoo, uint16_t *fil, int column, uint1 void voodoo_callback(void *p) { voodoo_t *voodoo = (voodoo_t *)p; - int y_add = enable_overscan ? 16 : 0; - int x_add = enable_overscan ? 8 : 0; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS) { diff --git a/src/video.c b/src/video.c index 9cd292101..9211ac742 100644 --- a/src/video.c +++ b/src/video.c @@ -475,9 +475,9 @@ void initvideo() int c, d, e; /* Account for overscan. */ - buffer32 = create_bitmap(2064, 2056); + buffer32 = create_bitmap(2048, 2048); - buffer = create_bitmap(2064, 2056); + buffer = create_bitmap(2048, 2048); for (c = 0; c < 64; c++) { diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 86d8b895f..4d129228d 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -70,12 +70,12 @@ static uint32_t pal_lookup[256]; static CUSTOMVERTEX d3d_verts[] = { { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2080.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2080.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; void d3d_fs_init(HWND h) @@ -162,19 +162,19 @@ static void d3d_fs_init_objects() &v_buffer, NULL); - d3ddev->CreateTexture(2080, 2080, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); r.top = r.left = 0; - r.bottom = 2079; - r.right = 2079; + r.bottom = 2047; + r.right = 2047; if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - for (y = 0; y < 2080; y++) + for (y = 0; y < 2048; y++) { uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); - memset(p, 0, 2080 * 4); + memset(p, 0, 2048 * 4); } d3dTexture->UnlockRect(0); @@ -346,8 +346,8 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2080.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2080.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; GetClientRect(d3d_device_window, &window_rect); d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); @@ -453,8 +453,8 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2080.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2080.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; GetClientRect(d3d_device_window, &window_rect); d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index d73deb98e..a1e2fa8c5 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -63,12 +63,12 @@ static uint32_t pal_lookup[256]; static CUSTOMVERTEX d3d_verts[] = { { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2080.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2080.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2080.0f, 2080.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; void d3d_init(HWND h) @@ -135,19 +135,18 @@ void d3d_init_objects() &v_buffer, NULL); - d3ddev->CreateTexture(2080, 2080, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); r.top = r.left = 0; - r.bottom = 2079; - r.right = 2079; + r.bottom = r.right = 2047; if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - for (y = 0; y < 2056; y++) + for (y = 0; y < 2048; y++) { uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); - memset(p, 0, 2064 * 4); + memset(p, 0, 2048 * 4); } d3dTexture->UnlockRect(0); @@ -242,7 +241,7 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { video_blit_complete(); return; /*Nothing to do*/ - } + } r.top = y1; r.left = 0; @@ -263,10 +262,10 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) else video_blit_complete(); - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2080.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2080.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; GetClientRect(d3d_hwnd, &r); d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; @@ -321,7 +320,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) int yy, xx; HRESULT hr = D3D_OK; - if (h == 0) + if (h == 0) { video_blit_complete(); return; /*Nothing to do*/ @@ -330,7 +329,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) r.top = 0; r.left = 0; r.bottom = h; - r.right = 2079; + r.right = 2047; if (hr == D3D_OK) { @@ -353,6 +352,24 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) else video_blit_complete(); + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + + GetClientRect(d3d_hwnd, &r); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer + if (hr == D3D_OK) + hr = v_buffer->Unlock(); // unlock the vertex buffer + if (hr == D3D_OK) hr = d3ddev->BeginScene(); @@ -376,28 +393,8 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) if (hr == D3D_OK) hr = d3ddev->EndScene(); } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - - GetClientRect(d3d_hwnd, &r); - d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; - d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; - d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; - d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index b1800d931..bfb9a5a1c 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -103,8 +103,8 @@ void ddraw_fs_init(HWND h) ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2080; - ddsd.dwHeight = 2080; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) fatal("CreateSurface back failed\n"); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 251029db7..f786310ca 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -91,8 +91,8 @@ void ddraw_init(HWND h) ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2080; - ddsd.dwHeight = 2080; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) fatal("CreateSurface back failed\n"); @@ -101,8 +101,8 @@ void ddraw_init(HWND h) ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2080; - ddsd.dwHeight = 2080; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) fatal("CreateSurface back failed\n"); diff --git a/src/win.c b/src/win.c index d9c98fe24..33840cd63 100644 --- a/src/win.c +++ b/src/win.c @@ -121,17 +121,25 @@ void updatewindowsize(int x, int y) if (x < 160) x = 160; if (y < 100) y = 100; + int temp_overscan_x = overscan_x; + int temp_overscan_y = overscan_y; + + if (suppress_overscan) + { + temp_overscan_x = temp_overscan_y = 0; + } + winsizex=x; efwinsizey=y; if (force_43) { /* Account for possible overscan. */ - if (overscan_y == 16) + if (temp_overscan_y == 16) { /* CGA */ - winsizey = ((int) (((double) (x - overscan_x) / 4.0) * 3.0)) + overscan_y; + winsizey = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; } - else if (overscan_y < 16) + else if (temp_overscan_y < 16) { /* MDA/Hercules */ winsizey = efwinsizey; @@ -141,7 +149,7 @@ void updatewindowsize(int x, int y) if (enable_overscan) { /* EGA/(S)VGA with overscan */ - winsizey = ((int) (((double) (x - overscan_x) / 4.0) * 3.0)) + overscan_y; + winsizey = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; } else { From f2c8591220f42e4c544bc92f13de57f19534c980 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 24 Jan 2017 20:25:58 +0100 Subject: [PATCH 048/392] The CD-ROM READ CAPACITY, READ SUBCHANNEL, READ TOC, READ DISC INFORMATION, and READ TRACK INFORMATION commands now return a sane length if the length from pass through is 8192 bytes. --- src/cdrom.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/cdrom.c b/src/cdrom.c index df218e204..b025ed07e 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1759,6 +1759,20 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } + + if (len == 8192) + { + max_len = cdb[8] + (cdb[7] << 8); + len = cdbufferb[0] + (cdbufferb[1] << 8); + len += 2; + if (max_len < len) + { + max_len -= 2; + cdbufferb[0] = max_len >> 8; + cdbufferb[1] = max_len & 0xff; + len = max_len + 2; + } + } } else { @@ -2096,6 +2110,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } + if (len == 8192) + { + cdbufferb[0] = 0; + cdbufferb[1] = 32; + len = 34; + } } else { @@ -2130,6 +2150,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } + + if (len == 8192) + { + cdbufferb[0] = 0; + cdbufferb[1] = 34; + len = 36; + } } else { @@ -2142,6 +2169,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) len = 36; memset(cdbufferb, 0, 36); + cdbufferb[0] = 0; cdbufferb[1] = 34; cdbufferb[2] = 1; /* track number (LSB) */ cdbufferb[3] = 1; /* session number (LSB) */ @@ -2243,6 +2271,21 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } break; } + if (len == 8192) + { + switch(cdb[3]) + { + case 0: + len = 4; + break; + case 1: + len = 16; + break; + default: + len = 24; + break; + } + } } else { @@ -2519,6 +2562,10 @@ atapi_out: { return; } + if (len == 8192) + { + len = 8; + } } else { From 6f705abd61c7218ebad6a22ad661e98449768170 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 24 Jan 2017 20:32:55 +0100 Subject: [PATCH 049/392] Changed the default pass through transfer length for non-media access commands to 65534 bytes instead of 8192, just in case someone tries to use a disc with an abnormal number of tracks. --- src/cdrom-ioctl.c | 4 ++-- src/cdrom.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 490d4ab45..fdd4433ef 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -524,7 +524,7 @@ static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_bl if (no_length_check) { - return 8192; + return 65534; } switch (cdb[0]) @@ -590,7 +590,7 @@ common_handler: break; default: /* Other commands */ - return 8192; + return 65534; break; } diff --git a/src/cdrom.c b/src/cdrom.c index b025ed07e..902d4343d 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1760,7 +1760,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) return; } - if (len == 8192) + if (len == 65534) { max_len = cdb[8] + (cdb[7] << 8); len = cdbufferb[0] + (cdbufferb[1] << 8); @@ -2110,7 +2110,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - if (len == 8192) + if (len == 65534) { cdbufferb[0] = 0; cdbufferb[1] = 32; @@ -2151,7 +2151,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) return; } - if (len == 8192) + if (len == 65534) { cdbufferb[0] = 0; cdbufferb[1] = 34; @@ -2271,7 +2271,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } break; } - if (len == 8192) + if (len == 65534) { switch(cdb[3]) { @@ -2562,7 +2562,7 @@ atapi_out: { return; } - if (len == 8192) + if (len == 65534) { len = 8; } From 89840c7fc93ec05c2199a181c274da234f9afb47 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 25 Jan 2017 06:58:40 +0100 Subject: [PATCH 050/392] CD-ROM READ SUBCHANNEL command now does not pass through if requested data type is 1 (current position), instead the current position held by the emulator is returned; CD-ROM READ SUBCHANNEL command now respects the allocated length set in the CDB. --- src/cdrom.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index 902d4343d..66de19852 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2243,8 +2243,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_READ_SUBCHANNEL: + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + cdrom_log("CD-ROM %i: Getting page %i\n", id, cdb[3]); - if (cdrom_drives[id].handler->pass_through) + if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { ret = cdrom_pass_through(id, &len); if (!ret) @@ -2315,7 +2319,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[pos++] = 0; /*Audio status*/ cdbufferb[pos++] = 0; cdbufferb[pos++] = 0; /*Subchannel length*/ cdbufferb[pos++] = cdb[3] & 3; /*Format code*/ - if ((temp & 3) == 1) + if (cdb[3] == 1) { cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); if (((cdbufferb[1] == 0x13) && !completed) || (cd_status == CD_STATUS_DATA_ONLY)) @@ -2323,7 +2327,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[1] = 0x15; } } - if (!(cdb[2] & 0x40) || ((cdb[3] & 3) == 0)) + if (!(cdb[2] & 0x40) || (cdb[3] == 0)) { len = 4; } @@ -2333,7 +2337,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } } - cdrom_data_command_finish(id, len, len, len, 0); + cdrom_data_command_finish(id, len, len, max_len, 0); break; case GPCMD_READ_DVD_STRUCTURE: From d4afd7c2c3fea9860bd5d2652497c75a298e7c0a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 26 Jan 2017 17:20:55 +0100 Subject: [PATCH 051/392] Added some things that were missing from the DMA controller; Fixed a link-breaking bug in cdrom.c; The AHA-154x now supports commands 0x28 (GET EXTENDED BIOS INFO) and 0x29 (UNLOCK MAILBOX) and no longer reports a firmware revision with scatter/gather bug; The BusLogic now supports command 0x20 (RESET); Fixed the GPIO register mapping on the National Semiconductors PC87306 Super I/O chip. --- src/Makefile.mingw | 6 +- src/buslogic.c | 69 +++++++++++++++++--- src/cdrom.c | 2 +- src/dma.c | 153 ++++++++++++++++++++++++++++----------------- src/ibm.h | 1 + src/pc87306.c | 26 ++++++-- src/piix.c | 8 ++- 7 files changed, 188 insertions(+), 77 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e3e69794a..4854b83e5 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,7 +2,7 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -g DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ @@ -33,8 +33,8 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) sleep 10 - strip "86Box.exe" - sleep 10 +a.exe: strip "86Box.exe" +a.exe: sleep 10 all : 86Box.exe diff --git a/src/buslogic.c b/src/buslogic.c index 5c94fee82..d131846a3 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -516,6 +516,7 @@ typedef struct __attribute__((packed)) Buslogic_t int MailboxOutInterrupts; int MbiActive[256]; int PendingInterrupt; + int Lock; } Buslogic_t; int scsi_model = 1; @@ -600,6 +601,7 @@ static void BuslogicReset(Buslogic_t *Buslogic) Buslogic->MailboxInPosCur = 0; Buslogic->MailboxOutInterrupts = 0; Buslogic->PendingInterrupt = 0; + Buslogic->Lock = 0; BuslogicInOperation = 0; BuslogicClearInterrupt(Buslogic); @@ -1136,6 +1138,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x04: case 0x0A: case 0x0B: + case 0x20: case 0x23: case 0x84: case 0x85: @@ -1183,8 +1186,11 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0; break; - case 0x28: case 0x29: + Buslogic->CmdParamLeft = scsi_model ? 0 : 2; + break; + + case 0x28: case 0x86: //Valid only for PCI case 0x95: //Valid only for PCI Buslogic->CmdParamLeft = 0; @@ -1230,8 +1236,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x04: Buslogic->DataBuf[0] = 0x41; Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; - Buslogic->DataBuf[2] = scsi_model ? '5' : '3'; - Buslogic->DataBuf[3] = scsi_model ? '0' : '1'; + Buslogic->DataBuf[2] = '5'; + Buslogic->DataBuf[3] = '0'; Buslogic->DataReplyLeft = 4; break; @@ -1362,7 +1368,19 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataBuf[0] = Buslogic->CmdBuf[0]; Buslogic->DataReplyLeft = 1; break; - + + case 0x20: + Buslogic->DataReplyLeft = 0; + if (scsi_model) + { + BuslogicResetControl(Buslogic, 1); + } + else + { + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x21: if (Buslogic->CmdParam == 1) Buslogic->CmdParamLeft = Buslogic->CmdBuf[0]; @@ -1396,7 +1414,44 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); picintc(1 << Buslogic->Irq); break; - + + case 0x28: + if (!scsi_model) + { + Buslogic->DataBuf[0] = 0x08; + Buslogic->DataBuf[1] = Buslogic->Lock; + Buslogic->DataReplyLeft = 2; + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + + case 0x29: + if (!scsi_model) + { + if (Buslogic->CmdBuf[1] = Buslogic->Lock) + { + if (Buslogic->CmdBuf[0] & 1) + { + Buslogic->Lock = 1; + } + else + { + Buslogic->Lock = 0; + } + } + Buslogic->DataReplyLeft = 0; + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x81: { if (scsi_model) @@ -1546,8 +1601,8 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) default: case 0x22: //undocumented - case 0x28: //only for the Adaptec 154xC series - case 0x29: //only for the Adaptec 154xC series + // case 0x28: //only for the Adaptec 154xC series + // case 0x29: //only for the Adaptec 154xC series case 0x86: //PCI only, not ISA case 0x95: //PCI only, not ISA Buslogic->DataReplyLeft = 0; diff --git a/src/cdrom.c b/src/cdrom.c index 66de19852..b86ffd284 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2322,7 +2322,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdb[3] == 1) { cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); - if (((cdbufferb[1] == 0x13) && !completed) || (cd_status == CD_STATUS_DATA_ONLY)) + if (((cdbufferb[1] == 0x13) && !completed) || (cdrom[id].cd_status == CD_STATUS_DATA_ONLY)) { cdbufferb[1] = 0x15; } diff --git a/src/dma.c b/src/dma.c index 723c2c7a4..59ae03401 100644 --- a/src/dma.c +++ b/src/dma.c @@ -66,18 +66,23 @@ uint8_t dma_read(uint16_t addr, void *priv) case 8: /*Status register*/ temp = dma.stat; - dma.stat = 0; + dma.stat &= 0xf0; return temp; - - case 0xd: - return 0; + + case 0xd: /*Temporary register*/ + return dmaregs[addr & 0xd]; + + case 0xf: /*Mask register*/ + return dma16.m; + + default: + return 0; } -// printf("Bad DMA read %04X %04X:%04X\n",addr,CS,pc); - return dmaregs[addr & 0xf]; } void dma_write(uint16_t addr, uint8_t val, void *priv) { + int channel = val & 3; // printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); dmaregs[addr & 0xf] = val; switch (addr & 0xf) @@ -102,14 +107,30 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) case 8: /*Control register*/ dma.command = val; return; + + case 9: /*Request register*/ + if (val & 4) + { + dma.request |= (1 << (channel + 4)); + if (dma.command & 1) + { + dma.request |= (1 << channel); + } + } + else + { + dma.request &= ~(1 << (channel + 4)); + } + return; case 0xa: /*Mask*/ if (val & 4) dma.m |= (1 << (val & 3)); else dma.m &= ~(1 << (val & 3)); return; - + case 0xb: /*Mode*/ - dma.mode[val & 3] = val; + dma.mode[val & 3] = val & 0xfc; + dma.stat &= ~(1 << (val & 3)); return; case 0xc: /*Clear FF*/ @@ -135,7 +156,7 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) uint8_t dma16_read(uint16_t addr, void *priv) { uint8_t temp; -// printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,pc); + // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); addr >>= 1; switch (addr & 0xf) { @@ -153,15 +174,24 @@ uint8_t dma16_read(uint16_t addr, void *priv) case 8: /*Status register*/ temp = dma16.stat; - dma16.stat = 0; + dma16.stat &= 0xf0; return temp; + + case 0xd: /*Temporary register*/ + return dma16regs[addr & 0xd]; + + case 0xf: /*Mask register*/ + return dma16.m; + + default: + return 0; } - return dma16regs[addr & 0xf]; } void dma16_write(uint16_t addr, uint8_t val, void *priv) { -// printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,pc); + int channel = val & 3; + // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); addr >>= 1; dma16regs[addr & 0xf] = val; switch (addr & 0xf) @@ -183,7 +213,23 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 8: /*Control register*/ + dma16.command = val; return; + + case 9: /*Request register*/ + if (val & 4) + { + dma16.request |= (1 << (channel + 4)); + if (dma16.command & 1) + { + dma16.request |= (1 << channel); + } + } + else + { + dma16.request &= ~(1 << (channel + 4)); + } + return; case 0xa: /*Mask*/ if (val & 4) dma16.m |= (1 << (val & 3)); @@ -191,7 +237,8 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xb: /*Mode*/ - dma16.mode[val & 3] = val; + dma16.mode[val & 3] = val & 0xfc; + dma16.stat &= ~(1 << (val & 3)); return; case 0xc: /*Clear FF*/ @@ -209,7 +256,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xf: /*Mask write*/ - dma16.m = val&0xf; + dma16.m = val & 0xf; return; } } @@ -217,6 +264,7 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) void dma_page_write(uint16_t addr, uint8_t val, void *priv) { + // printf("Write dma16 Page %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); dmapages[addr & 0xf] = val; switch (addr & 0xf) { @@ -249,6 +297,7 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) uint8_t dma_page_read(uint16_t addr, void *priv) { + // printf("Read DMA Page %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); return dmapages[addr & 0xf]; } @@ -357,6 +406,35 @@ DMA * get_dma_controller(int channel) } } +int dma_tc(DMA *dma_controller, int channel) +{ + if (dma_controller->command & 1) + { + /* Memory to memory command */ + dma_controller->stat |= (1 << 0); + dma_controller->stat |= (1 << 1); + dma_controller->request &= ~(1 << 0); + dma_controller->request &= ~(1 << 1); + } + else + { + dma_controller->stat |= (1 << channel); + dma_controller->request &= ~(1 << channel); + } + + if (dma_controller->mode[channel] & 0x10) /*Auto-init*/ + { + // pclog("DMA read auto-init\n"); + dma_controller->cc[channel] = dma_controller->cb[channel] & 0xffff; + dma_controller->ac[channel] = dma_controller->ab[channel] & 0xffff; + } + else + { + dma_controller->cc[channel] &= 0xffff; + dma_controller->m |= (1 << channel); + } +} + int dma_channel_read(int channel) { uint16_t temp; @@ -438,18 +516,7 @@ int dma_channel_read(int channel) if ((dma_controller->cc[real_channel] < 0) || mem_over) { tc = 1; - if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/ - { - // pclog("DMA read auto-init\n"); - dma_controller->cc[real_channel] = dma_controller->cb[real_channel] & 0xffff; - dma_controller->ac[real_channel] = dma_controller->ab[real_channel] & 0xffff; - } - else - { - dma_controller->cc[real_channel] &= 0xffff; - dma_controller->m |= (1 << real_channel); - } - dma_controller->stat |= (1 << real_channel); + dma_tc(dma_controller, real_channel); } if (tc) @@ -540,18 +607,7 @@ int dma_channel_write(int channel, uint16_t val) if ((dma_controller->cc[real_channel] < 0) || mem_over) { tc = 1; - if (dma_controller->mode[real_channel] & 0x10) /*Auto-init*/ - { - // pclog("DMA write auto-init\n"); - dma_controller->cc[real_channel] = dma_controller->cb[real_channel] & 0xffff; - dma_controller->ac[real_channel] = dma_controller->ab[real_channel] & 0xffff; - } - else - { - dma_controller->cc[real_channel] &= 0xffff; - dma_controller->m |= (1 << real_channel); - } - dma_controller->stat |= (1 << real_channel); + dma_tc(dma_controller, real_channel); } // if (dma_is_masked(channel)) @@ -565,38 +621,17 @@ int dma_channel_write(int channel, uint16_t val) return 0; } -#if 0 -static uint32_t PageLengthReadWrite(uint32_t PhysAddress, uint32_t TotalSize) -{ - uint32_t LengthSize; - uint32_t Page; - - Page = PhysAddress & 4095; - - if ((Page + TotalSize - 1) >= 4096) - { - TotalSize = 4096 - Page; - } - - return TotalSize; -} -#endif - //DMA Bus Master Page Read/Write void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize) { - // uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); memcpy(DataRead, &ram[PhysAddress], TotalSize); - // DataRead -= PageLen; DataRead -= TotalSize; } void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize) { - // uint32_t PageLen = PageLengthReadWrite(PhysAddress, TotalSize); mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); memcpy(&ram[PhysAddress], DataWrite, TotalSize); - // DataWrite -= PageLen; DataWrite -= TotalSize; } diff --git a/src/ibm.h b/src/ibm.h index abcf11f4d..3f0ed78ee 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -308,6 +308,7 @@ typedef struct DMA uint8_t page[4]; uint8_t stat; uint8_t command; + uint8_t request; } DMA; DMA dma,dma16; diff --git a/src/pc87306.c b/src/pc87306.c index 9290c6209..d10fb4844 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -170,14 +170,21 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) if (tries) { if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg]; - if (pc87306_curreg == 0xF) pc87306_gpio_remove(); - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)) + tries = 0; + if ((pc87306_curreg <= 28) && (pc87306_curreg != 8) && (pc87306_curreg != 0x18)) { + if (pc87306_curreg == 0) + { + val &= 0x5f; + } + if ((pc87306_curreg == 0x0F) || (pc87306_curreg == 0x12)) + { + pc87306_gpio_remove(); + } pc87306_regs[pc87306_curreg] = val; // pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]); + goto process_value; } - tries = 0; - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)) goto process_value; } else { @@ -270,6 +277,7 @@ process_value: fdc_update_densel_polarity((val & 0x40) ? 1 : 0); break; case 0xF: + case 0x12: pc87306_gpio_init(); break; case 0x1C: @@ -342,7 +350,15 @@ void pc87306_gpio_remove() void pc87306_gpio_init() { - io_sethandler(pc87306_regs[0xF] << 2, 0x0002, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); + if ((pc87306_regs[0x12]) & 0x10) + { + io_sethandler(pc87306_regs[0xF] << 2, 0x0001, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); + } + + if ((pc87306_regs[0x12]) & 0x20) + { + io_sethandler((pc87306_regs[0xF] << 2) + 1, 0x0001, pc87306_gpio_read, NULL, NULL, pc87306_gpio_write, NULL, NULL, NULL); + } } void pc87306_init() diff --git a/src/piix.c b/src/piix.c index ce3e33b0d..e4297d276 100644 --- a/src/piix.c +++ b/src/piix.c @@ -26,6 +26,7 @@ static uint8_t card_piix[256], card_piix_ide[256]; void piix_write(int func, int addr, uint8_t val, void *priv) { + uint16_t old_base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); // pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); if (func > 1) return; @@ -83,9 +84,12 @@ void piix_write(int func, int addr, uint8_t val, void *priv) if (addr == 4 || (addr & ~3) == 0x20) /*Bus master base address*/ { uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); - io_removehandler(0, 0x10000, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + io_removehandler(old_base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + pclog("Setting PIIX IDE bus master to new base address: %04X\n", base); if (card_piix_ide[0x04] & 1) - io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + { + io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); + } } // pclog("PIIX write %02X %02X\n", addr, val); } From dcb89d3d2a7617a76dacc99028081fbbf46335bd Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Jan 2017 11:01:36 -0600 Subject: [PATCH 052/392] Change ATI 18800 BIOS --- src/vid_ati18800.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index 74cc6be64..110980f41 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -123,7 +123,6 @@ uint8_t ati18800_in(uint16_t addr, void *p) if (ati_eeprom_read(&ati18800->eeprom)) temp |= 8; break; - default: temp = ati18800->regs[ati18800->index]; break; @@ -167,7 +166,7 @@ void *ati18800_init() ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); memset(ati18800, 0, sizeof(ati18800_t)); - rom_init(&ati18800->bios_rom, "roms/vgaedge16.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati18800->bios_rom, "roms/vga88.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ NULL, @@ -187,7 +186,7 @@ void *ati18800_init() static int ati18800_available() { - return rom_present("roms/vgaedge16.vbi"); + return rom_present("roms/vga88.BIN"); } void ati18800_close(void *p) From dddd309bb8dae8dec06a49014aa3cec44b03fdd9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 26 Jan 2017 18:32:45 +0100 Subject: [PATCH 053/392] Fixed the makefile. --- src/Makefile.mingw | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 4854b83e5..e3e69794a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,7 +2,7 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -g +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ @@ -33,8 +33,8 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) sleep 10 -a.exe: strip "86Box.exe" -a.exe: sleep 10 + strip "86Box.exe" + sleep 10 all : 86Box.exe From e6c5a104b3445c75e5e1b1a65bebbe7562973873 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Jan 2017 13:59:21 -0600 Subject: [PATCH 054/392] Fixed some bugs --- src/vid_ati28800.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 0db9a6b09..69004067c 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -46,6 +46,7 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) break; case 0x1cf: ati28800->regs[ati28800->index & 0x3f] = val; + pclog("ATI 28800 ATI register write %02x %02x\n", ati28800->index, val); switch (ati28800->index & 0x3f) { case 0x2d: @@ -315,13 +316,40 @@ void ati28800_recalctimings(svga_t *svga) #ifndef RELEASE_BUILD pclog("ati28800_recalctimings\n"); #endif - svga->interlace = (!svga->scrblank && (ati28800->regs[0x30] & 0x20)); + svga->interlace = (!svga->scrblank && (ati28800->regs[0x3e] & 2)); + + uint8_t clock_sel = (svga->miscout >> 2) & 3; + clock_sel |= (ati28800->regs[0x39] & 2) << 2; + clock_sel |= (ati28800->regs[0x3e] & 0x10) >> 1; + double freq; + switch(clock_sel) + { + case 0x00: freq = 42954000; break; + case 0x01: freq = 48771000; break; + case 0x02: freq = 16657000; break; + case 0x03: freq = 36000000; break; + case 0x04: freq = 50350000; break; + case 0x05: freq = 56640000; break; + case 0x06: freq = 28322000; break; + case 0x07: freq = 44900000; break; + case 0x08: freq = 30240000; break; + case 0x09: freq = 32000000; break; + case 0x0a: freq = 37500000; break; + case 0x0b: freq = 39000000; break; + case 0x0c: freq = 40000000; break; + case 0x0d: freq = 56644000; break; + case 0x0e: freq = 75000000; break; + case 0x0f: freq = 65000000; break; + } + + svga->clock = cpuclock / freq; if (!svga->scrblank && (ati28800->regs[0x30] & 0x20)) /*Extended 256 colour modes*/ { #ifndef RELEASE_BUILD pclog("8bpp_highres\n"); #endif + svga->bpp = 8; svga->render = svga_render_8bpp_highres; svga->rowoffset <<= 1; svga->ma <<= 1; From 865e35d61276f401af1cac57c50219bd8ebf2dfe Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 26 Jan 2017 21:34:09 -0600 Subject: [PATCH 055/392] Fix an nVidia bug --- src/vid_nv_riva128.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index a28f9b8b7..a192f5c32 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1416,6 +1416,9 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x40008c: riva128->pgraph.debug[3] = val & ((riva128->card_id == 0x04) ? 0x11ffff33 : 0xfbffff73); break; + } + if(riva128->card_id >= 0x04) switch(addr) + { case 0x400754: riva128->pgraph.fifo_st2_addr = val; break; From 10503674eb0a6ae5ef555adf4bc6fcfa506d24cd Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 27 Jan 2017 23:03:20 +0100 Subject: [PATCH 056/392] All MODE SENSE and MODE SELECT commands now support the block descriptor when a CD-ROM drive is set to SCSI; Fixed MODE SELECT behavior with ATAPI; Removed excess PIIX logging; Fixed and improved the CD Audio buffer code in sound.c. --- src/cdrom-ioctl.c | 167 +++++++++++++++++++----------- src/cdrom-iso.c | 13 +++ src/cdrom-null.c | 6 ++ src/cdrom.c | 255 +++++++++++++++++++++++++++++++++------------- src/cdrom.h | 2 + src/piix.c | 1 - src/sound.c | 106 ++++++++++--------- 7 files changed, 371 insertions(+), 179 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index fdd4433ef..807f188fd 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -304,6 +304,7 @@ static int ioctl_medium_changed(uint8_t id) if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) { cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_windows[id].toc = ltoc; cdrom_ioctl[id].tocvalid = 1; if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) @@ -318,6 +319,7 @@ static int ioctl_medium_changed(uint8_t id) (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) { cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_windows[id].toc = ltoc; cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; /* TOC mismatches. */ @@ -345,69 +347,77 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) int track = get_track_nr(id, cdpos); uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); - b[pos++] = sub.CurrentPosition.Control; - b[pos++] = track + 1; - b[pos++] = sub.CurrentPosition.IndexNumber; + cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); + + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = track + 1; + b[pos++] = sub.CurrentPosition.IndexNumber; - if (msf) - { - uint32_t dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } + if (msf) + { + uint32_t dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; - return 0x12; - } + if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; + return 0x12; + } - b[pos++]=sub.CurrentPosition.Control; - b[pos++]=sub.CurrentPosition.TrackNumber; - b[pos++]=sub.CurrentPosition.IndexNumber; + b[pos++]=sub.CurrentPosition.Control; + b[pos++]=sub.CurrentPosition.TrackNumber; + b[pos++]=sub.CurrentPosition.IndexNumber; + + cdrom_ioctl_log("cdpos = %i, track_address = %i\n", MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]), MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3])); - if (msf) - { - int c; - for (c = 0; c < 4; c++) - b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; - for (c = 0; c < 4; c++) - b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; - } - else - { - uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } + if (msf) + { + int c; + for (c = 0; c < 4; c++) + { + b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; + } + for (c = 0; c < 4; c++) + { + b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; + } + } + else + { + uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + } - return 0x13; + return 0x13; } static void ioctl_eject(uint8_t id) @@ -664,6 +674,43 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) ioctl_close(id); } +static int ioctl_media_type_id(uint8_t id) +{ + uint8_t old_sense[3] = { 0, 0, 0 }; + + UCHAR msbuf[28]; + int len = 0; + int sense = 0; + + const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; + + old_sense[0] = cdrom_sense_key; + old_sense[1] = cdrom_asc; + old_sense[2] = cdrom_asc; + + ioctl_open(id, 0); + + SCSICommand(id, cdb, msbuf, &len, 1); + + pclog("Returned length: %i, media type: %i\n", len, msbuf[2]); + + ioctl_close(id); + + sense = cdrom_sense_key; + cdrom_sense_key = old_sense[0]; + cdrom_asc = old_sense[1]; + cdrom_asc = old_sense[2]; + + if (sense == 0) + { + return msbuf[2]; + } + else + { + return 3; + } +} + static uint32_t msf_to_lba32(int lba) { int m = (lba >> 16) & 0xff; @@ -754,6 +801,7 @@ static void ioctl_validate_toc(uint8_t id) } cdrom_ioctl[id].cd_state = CD_STOPPED; ioctl_open(id, 0); + cdrom_ioctl_log("Validating TOC...\n"); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); cdrom_ioctl[id].tocvalid=1; @@ -781,7 +829,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t int temp_len = 0; int chunk = 0; - if (cdb[0] == 0x43) + if (in_cdb[0] == 0x43) { /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ ioctl_validate_toc(id); @@ -950,6 +998,7 @@ static CDROM ioctl_cdrom= { ioctl_ready, ioctl_medium_changed, + ioctl_media_type_id, ioctl_audio_callback, ioctl_audio_stop, NULL, diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index 241e1e3dd..dc10fbf64 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -589,10 +589,23 @@ static int iso_is_track_audio(uint8_t id, uint32_t pos, int ismsf) return 0; } +static int iso_media_type_id(uint8_t id) +{ + if (iso_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + static CDROM iso_cdrom = { iso_ready, iso_medium_changed, + iso_media_type_id, NULL, NULL, iso_readtoc, diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 6e886ed27..2409df412 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -100,10 +100,16 @@ static int null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t * return 0; } +static int null_media_type_id(uint8_t id) +{ + return 0x70; +} + static CDROM null_cdrom = { null_ready, null_medium_changed, + null_media_type_id, NULL, NULL, null_readtoc, diff --git a/src/cdrom.c b/src/cdrom.c index b86ffd284..02d693b43 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -27,8 +27,9 @@ #define MODE_SELECT_PHASE_IDLE 0 #define MODE_SELECT_PHASE_HEADER 1 -#define MODE_SELECT_PHASE_PAGE_HEADER 2 -#define MODE_SELECT_PHASE_PAGE 3 +#define MODE_SELECT_PHASE_BLOCK_DESC 2 +#define MODE_SELECT_PHASE_PAGE_HEADER 3 +#define MODE_SELECT_PHASE_PAGE 4 cdrom_t cdrom[CDROM_NUM]; cdrom_drive_t cdrom_drives[CDROM_NUM]; @@ -170,19 +171,19 @@ uint8_t cdrom_mode_sense_pages_changeable[CDROM_NUM][0x40][0x40] = { { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, + [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } }; @@ -535,7 +536,7 @@ int cdrom_mode_select_terminate(uint8_t id, int force) { cdrom_mode_sense_save(id); } - cdrom[id].current_page_pos = cdrom[id].current_page_len = 0; + cdrom[id].current_page_pos = cdrom[id].current_page_len = cdrom[id].block_descriptor_len = 0; cdrom[id].total_length = cdrom[id].written_length = 0; cdrom[id].mode_select_phase = MODE_SELECT_PHASE_IDLE; if (force) @@ -550,10 +551,51 @@ int cdrom_mode_select_terminate(uint8_t id, int force) } } -int cdrom_mode_select_header(uint8_t id) +int cdrom_mode_select_header(uint8_t id, uint8_t val) +{ + if (cdrom[id].current_page_pos == 0) + { + cdrom[id].block_descriptor_len = 0; + } + else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 2)) + { + if (cdrom_drives[id].bus_type && (cdrom[id].current_page_len == 8)) + { + cdrom[id].block_descriptor_len |= ((uint16_t) val) << 8; + cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); + } + } + else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 1)) + { + if (cdrom_drives[id].bus_type) + { + cdrom[id].block_descriptor_len |= (uint16_t) val; + cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); + } + } + + cdrom[id].current_page_pos++; + + if (cdrom[id].current_page_pos >= cdrom[id].current_page_len) + { + cdrom[id].current_page_pos = 0; + if (cdrom[id].block_descriptor_len) + { + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_BLOCK_DESC; + } + else + { + cdrom[id].mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER; + } + } + + return 1; +} + +int cdrom_mode_select_block_desc(uint8_t id) { cdrom[id].current_page_pos++; - if (cdrom[id].current_page_pos >= cdrom[id].current_page_len) + if (cdrom[id].current_page_pos >= 8) { cdrom[id].current_page_pos = 0; cdrom[id].mode_select_phase = MODE_SELECT_PHASE_PAGE_HEADER; @@ -652,7 +694,11 @@ int cdrom_mode_select_write(uint8_t id, uint8_t val) break; case MODE_SELECT_PHASE_HEADER: cdrom_log("CD-ROM %i: MODE SELECT header (%02X)\n", id, val); - ret = cdrom_mode_select_header(id); + ret = cdrom_mode_select_header(id, val); + break; + case MODE_SELECT_PHASE_BLOCK_DESC: + cdrom_log("CD-ROM %i: MODE SELECT block descriptor (%02X)\n", id, val); + ret = cdrom_mode_select_block_desc(id); break; case MODE_SELECT_PHASE_PAGE_HEADER: cdrom_log("CD-ROM %i: MODE SELECT page header (%02X)\n", id, val); @@ -682,6 +728,41 @@ int cdrom_mode_select_write(uint8_t id, uint8_t val) return ret; } +uint8_t cdrom_read_capacity_cdb[12] = {0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static int cdrom_pass_through(uint8_t id, int *len, uint8_t *cdb, uint8_t *buffer); + +int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, int *len) +{ + int ret = 0; + int size = 0; + + if (cdrom_drives[id].handler->pass_through) + { + ret = cdrom_pass_through(id, len, cdb, buffer); + if (!ret) + { + return 0; + } + if (*len == 65534) + { + *len = 8; + } + } + else + { + size = cdrom_drives[id].handler->size(id) - 1; /* IMPORTANT: What's returned is the last LBA block. */ + memset(buffer, 0, 8); + buffer[0] = (size >> 24) & 0xff; + buffer[1] = (size >> 16) & 0xff; + buffer[2] = (size >> 8) & 0xff; + buffer[3] = size & 0xff; + buffer[6] = 8; /* 2048 = 0x0800 */ + *len = 8; + } + return 1; +} + /*SCSI Mode Sense 6/10*/ uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, uint8_t pos) { @@ -700,7 +781,7 @@ uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, ui } } -uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type) +uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) { uint8_t page_control = (type >> 6) & 3; @@ -711,6 +792,20 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type) type &= 0x3f; + int len = 0; + + if (block_descriptor_len) + { + buf[pos++] = 1; /* Density code. */ + buf[pos++] = 0; /* Number of blocks (0 = all). */ + buf[pos++] = 0; + buf[pos++] = 0; + buf[pos++] = 0; /* Reserved. */ + buf[pos++] = 0; /* Block length (0x800 = 2048 bytes). */ + buf[pos++] = 8; + buf[pos++] = 0; + } + for (i = 0; i < 0x40; i++) { if ((type == GPMODE_ALL_PAGES) || (type == i)) @@ -1018,13 +1113,15 @@ static void cdrom_data_phase_error(uint8_t id) cdrom_cmd_error(id); } -static int cdrom_pass_through(uint8_t id, int *len) +static int cdrom_pass_through(uint8_t id, int *len, uint8_t *cdb, uint8_t *buffer) { int ret = 0; - uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; + // uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; - ret = cdrom_drives[id].handler->pass_through(id, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos, len); - cdrom_log("CD-ROM %i: Data from pass through: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + // ret = cdrom_drives[id].handler->pass_through(id, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos, len); + ret = cdrom_drives[id].handler->pass_through(id, cdb, buffer, len); + // cdrom_log("CD-ROM %i: Data from pass through: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + cdrom_log("CD-ROM %i: Data from pass through: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); cdrom_log("CD-ROM %i: Returned value: %i\n", id, ret); if (!ret) @@ -1124,7 +1221,7 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) { cdsize = cdrom_drives[id].handler->size(id); - ret = cdrom_pass_through(id, len); + ret = cdrom_pass_through(id, len, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos); cdrom[id].data_pos += *len; if (!ret) @@ -1656,6 +1753,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) int alloc_length; int completed; uint8_t index = 0; + int block_desc = 0; int media; int format; int ret; @@ -1688,16 +1786,19 @@ void cdrom_command(uint8_t id, uint8_t *cdb) memcpy(cdrom[id].current_cdb, cdb, cdrom[id].cdb_len); - cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention); - cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); -#if 0 - - int CdbLength; - for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++) + if (cdb[0] != 0) { - cdrom_log("CD-ROM %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); - } + cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention); + cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); + +#if 0 + int CdbLength; + for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++) + { + cdrom_log("CD-ROM %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); + } #endif + } msf = cdb[1] & 2; cdrom[id].sector_len = 0; @@ -1754,7 +1855,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len); + ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { return; @@ -1894,7 +1995,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_READ_HEADER: if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len); + ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { return; @@ -1927,6 +2028,15 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: + if (cdrom_drives[id].bus_type) + { + block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; + } + else + { + block_desc = 0; + } + if (cdb[0] == GPCMD_MODE_SENSE_6) { len = cdb[4]; @@ -1947,30 +2057,44 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdb[0] == GPCMD_MODE_SENSE_6) { - len = cdrom_mode_sense(id, cdbufferb, 4, cdb[2]); - cdbufferb[0] = len - 1; - cdbufferb[1] = 3; /*120mm data CD-ROM*/ + len = cdrom_mode_sense(id, cdbufferb, 4, cdb[2], block_desc); if (len > alloc_length) { len = alloc_length; } + cdbufferb[0] = len - 1; + cdbufferb[1] = cdrom_drives[id].handler->media_type_id(id); + if (block_desc) + { + cdbufferb[3] = 8; + } } else { - len = cdrom_mode_sense(id, cdbufferb, 8, cdb[2]); + len = cdrom_mode_sense(id, cdbufferb, 8, cdb[2], block_desc); if (len > alloc_length) { len = alloc_length; } cdbufferb[0]=(len - 2) >> 8; cdbufferb[1]=(len - 2) & 255; - cdbufferb[2] = 3; /*120mm data CD-ROM*/ - if (len > alloc_length) + cdbufferb[2] = cdrom_drives[id].handler->media_type_id(id); + if (block_desc) { - len = alloc_length; + cdbufferb[6] = 0; + cdbufferb[7] = 8; } } + if (len > alloc_length) + { + len = alloc_length; + } + else if (len < alloc_length) + { + alloc_length = len; + } + cdrom_log("CD-ROM %i: Reading mode page: %02X...\n", id, cdb[2]); cdrom_data_command_finish(id, len, len, alloc_length, 0); @@ -2105,7 +2229,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len); + ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { return; @@ -2145,7 +2269,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len); + ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { return; @@ -2246,11 +2370,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) max_len = cdb[7]; max_len <<= 8; max_len |= cdb[8]; + msf = (cdb[1] >> 1) & 1; cdrom_log("CD-ROM %i: Getting page %i\n", id, cdb[3]); if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { - ret = cdrom_pass_through(id, &len); + ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { return; @@ -2264,15 +2389,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case CD_STATUS_PAUSED: cdbufferb[1] = 0x12; break; + case CD_STATUS_DATA_ONLY: + cdbufferb[1] = 0x15; + break; default: - if (completed) - { - cdbufferb[1] = 0x13; - } - else - { - cdbufferb[1] = 0x15; - } + cdbufferb[1] = 0x13; break; } if (len == 65534) @@ -2322,9 +2443,20 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (cdb[3] == 1) { cdbufferb[1] = cdrom_drives[id].handler->getcurrentsubchannel(id, &cdbufferb[5], msf); - if (((cdbufferb[1] == 0x13) && !completed) || (cdrom[id].cd_status == CD_STATUS_DATA_ONLY)) + switch(cdrom[id].cd_status) { - cdbufferb[1] = 0x15; + case CD_STATUS_PLAYING: + cdbufferb[1] = 0x11; + break; + case CD_STATUS_PAUSED: + cdbufferb[1] = 0x12; + break; + case CD_STATUS_DATA_ONLY: + cdbufferb[1] = 0x15; + break; + default: + cdbufferb[1] = 0x13; + break; } } if (!(cdb[2] & 0x40) || (cdb[3] == 0)) @@ -2343,7 +2475,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_READ_DVD_STRUCTURE: if (cdrom_drives[id].handler->pass_through) { - ret = cdrom_pass_through(id, &len); + ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { return; @@ -2559,28 +2691,9 @@ atapi_out: break; case GPCMD_READ_CDROM_CAPACITY: - if (cdrom_drives[id].handler->pass_through) + if (cdrom_read_capacity(id, cdrom[id].current_cdb, cdbufferb, &len) == 0) { - ret = cdrom_pass_through(id, &len); - if (!ret) - { - return; - } - if (len == 65534) - { - len = 8; - } - } - else - { - size = cdrom_drives[id].handler->size(id) - 1; /* IMPORTANT: What's returned is the last LBA block. */ - memset(cdbufferb, 0, 8); - cdbufferb[0] = (size >> 24) & 0xff; - cdbufferb[1] = (size >> 16) & 0xff; - cdbufferb[2] = (size >> 8) & 0xff; - cdbufferb[3] = size & 0xff; - cdbufferb[6] = 8; /* 2048 = 0x0800 */ - len = 8; + return; } cdrom_data_command_finish(id, len, len, len, 0); @@ -3037,6 +3150,8 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) uint16_t *cdbufferw; uint32_t *cdbufferl; + uint8_t old_pos = 0; + uint8_t id = atapi_cdrom_drives[channel]; int ret = 0; @@ -3050,6 +3165,8 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) cdbufferw = cdrom[id].buffer; cdbufferl = (uint32_t *) cdrom[id].buffer; + old_pos = cdrom[id].pos; + switch(length) { case 1: @@ -3072,7 +3189,7 @@ void cdrom_write(uint8_t channel, uint32_t val, int length) { for (i = 0; i < length; i++) { - ret = cdrom_mode_select_write(id, val); + ret = cdrom_mode_select_write(id, cdbufferb[old_pos + i]); cdrom_mode_select_return(id, ret); } return; diff --git a/src/cdrom.h b/src/cdrom.h index 3cbbcaec2..08dc4ffc2 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -24,6 +24,7 @@ typedef struct CDROM { int (*ready)(uint8_t id); int (*medium_changed)(uint8_t id); + int (*media_type_id)(uint8_t id); void (*audio_callback)(uint8_t id, int16_t *output, int len); void (*audio_stop)(uint8_t id); int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); @@ -110,6 +111,7 @@ typedef struct __attribute__((__packed__)) int all_blocks_total; int old_len; + int block_descriptor_len; } cdrom_t; extern cdrom_t cdrom[CDROM_NUM]; diff --git a/src/piix.c b/src/piix.c index e4297d276..2a28547c9 100644 --- a/src/piix.c +++ b/src/piix.c @@ -85,7 +85,6 @@ void piix_write(int func, int addr, uint8_t val, void *priv) { uint16_t base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); io_removehandler(old_base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); - pclog("Setting PIIX IDE bus master to new base address: %04X\n", base); if (card_piix_ide[0x04] & 1) { io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); diff --git a/src/sound.c b/src/sound.c index 97ee72733..e290a0fdc 100644 --- a/src/sound.c +++ b/src/sound.c @@ -109,15 +109,15 @@ static void sound_cd_thread(void *param) { int i = 0; - while (1) - { - int c, has_audio; - - thread_wait_event(sound_cd_event, -1); + while (1) + { + int c, has_audio; + + thread_wait_event(sound_cd_event, -1); for (c = 0; c < CD_BUFLEN*2; c += 2) { - cd_out_buffer[c] = 0; - cd_out_buffer[c+1] = 0; + cd_out_buffer[c] = 0.0; + cd_out_buffer[c+1] = 0.0; } for (i = 0; i < CDROM_NUM; i++) { @@ -127,57 +127,63 @@ static void sound_cd_thread(void *param) cdrom_drives[i].handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2); has_audio = cdrom_drives[i].sound_on; } - if (soundon && has_audio) - { - int32_t audio_vol_l = cdrom_mode_sense_get_volume(i, 0); - int32_t audio_vol_r = cdrom_mode_sense_get_volume(i, 1); - int channel_select[2]; - - channel_select[0] = cdrom_mode_sense_get_channel(i, 0); - channel_select[1] = cdrom_mode_sense_get_channel(i, 1); - - for (c = 0; c < CD_BUFLEN*2; c += 2) - { - int32_t cd_buffer_temp[2] = {0, 0}; + if (soundon && has_audio) + { + int32_t audio_vol_l = cdrom_mode_sense_get_volume(i, 0); + int32_t audio_vol_r = cdrom_mode_sense_get_volume(i, 1); + int channel_select[2]; - /*First, adjust input from drive according to ATAPI/SCSI volume.*/ - cd_buffer[i][c] = ((int32_t)cd_buffer[i][c] * audio_vol_l) / 255; - cd_buffer[i][c+1] = ((int32_t)cd_buffer[i][c+1] * audio_vol_r) / 255; + channel_select[0] = cdrom_mode_sense_get_channel(i, 0); + channel_select[1] = cdrom_mode_sense_get_channel(i, 1); - /*Apply ATAPI channel select*/ - if (channel_select[0] & 1) - cd_buffer_temp[0] += cd_buffer[i][c]; - if (channel_select[0] & 2) - cd_buffer_temp[1] += cd_buffer[i][c]; - if (channel_select[1] & 1) - cd_buffer_temp[0] += cd_buffer[i][c+1]; - if (channel_select[1] & 2) - cd_buffer_temp[1] += cd_buffer[i][c+1]; - - /*Apply sound card CD volume*/ - cd_buffer_temp[0] = (cd_buffer_temp[0] * (int)cd_vol_l) / 65535; - cd_buffer_temp[1] = (cd_buffer_temp[1] * (int)cd_vol_r) / 65535; + for (c = 0; c < CD_BUFLEN*2; c += 2) + { + float cd_buffer_temp[2] = {0.0, 0.0}; + float cd_buffer_temp2[2] = {0.0, 0.0}; - if (cd_buffer_temp[0] > 32767) - cd_buffer_temp[0] = 32767; - if (cd_buffer_temp[0] < -32768) - cd_buffer_temp[0] = -32768; - if (cd_buffer_temp[1] > 32767) - cd_buffer_temp[1] = 32767; - if (cd_buffer_temp[1] < -32768) - cd_buffer_temp[1] = -32768; + /* First, transfer the CD audio data to the temporary buffer. */ + cd_buffer_temp[0] = (float) cd_buffer[i][c]; + cd_buffer_temp[1] = (float) cd_buffer[i][c+1]; + + /* Then, adjust input from drive according to ATAPI/SCSI volume. */ + cd_buffer_temp[0] *= (float) audio_vol_l; + cd_buffer_temp[0] /= 255.0; + cd_buffer_temp[1] *= (float) audio_vol_r; + cd_buffer_temp[1] /= 255.0; - cd_buffer[i][c] = cd_buffer_temp[0]; - cd_buffer[i][c+1] = cd_buffer_temp[1]; + /*Apply ATAPI channel select*/ + cd_buffer_temp2[0] = cd_buffer_temp2[1] = 0.0; + if (channel_select[0] & 1) + { + cd_buffer_temp2[0] += cd_buffer_temp[0]; + } + if (channel_select[0] & 2) + { + cd_buffer_temp2[1] += cd_buffer_temp[0]; + } + if (channel_select[1] & 1) + { + cd_buffer_temp2[0] += cd_buffer_temp[1]; + } + if (channel_select[1] & 2) + { + cd_buffer_temp2[1] += cd_buffer_temp[1]; + } - cd_out_buffer[c] += ((float) cd_buffer[i][c]) / 32768.0; - cd_out_buffer[c+1] += ((float) cd_buffer[i][c+1]) / 32768.0; - } + /*Apply sound card CD volume*/ + cd_buffer_temp2[0] *= (float) cd_vol_l; + cd_buffer_temp2[0] /= 65535.0; - } + cd_buffer_temp2[1] *= (float) cd_vol_r; + cd_buffer_temp2[1] /= 65535.0; + + cd_out_buffer[c] += (cd_buffer_temp2[0] / 32768.0); + cd_out_buffer[c+1] += (cd_buffer_temp2[1] / 32768.0); + } + } } givealbuffer_cd(cd_out_buffer); - } + } } static int32_t *outbuffer; From 55b6f1b802217782b7985111a948f81ae611300a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Jan 2017 20:39:36 +0100 Subject: [PATCH 057/392] Intel SIO/PIIX/PIIX3 Turbo Reset Control is now properly implemented; Floppy disk controller is now COMPLETELY reset on hard reset; NukedOPL is now optional (but enabled by default) so people on older hardware can gain a few % of performance by going back to DOSBox OPL; *.CPP files now get all the correct optimization flags applied; Added NEC PowerMate V emulation - you can get into CMOS SETUP but it hangs before booting, and PCI graphics card don't work (yet). --- src/Makefile.mingw | 3 ++ src/Makefile.mingw64 | 3 ++ src/cpu.c | 10 ++--- src/disc.c | 3 ++ src/fdc.c | 15 ++++++- src/fdc37c665.c | 25 ++++++------ src/fdc37c932fr.c | 17 ++++++-- src/i430fx.c | 44 +++++++-------------- src/i430hx.c | 21 +++++++--- src/i430lx.c | 47 +++++++--------------- src/i430nx.c | 47 +++++++--------------- src/i430vx.c | 19 +++++++-- src/i440fx.c | 22 +++++++---- src/ibm.h | 14 +++++++ src/io.c | 4 +- src/mem.c | 6 +-- src/memregs.c | 26 ++++++++++-- src/model.c | 13 +++--- src/nvr.c | 4 -- src/pc.c | 3 ++ src/pc.rc | 3 ++ src/pc87306.c | 17 +++++--- src/piix.c | 82 +++++++++++++++++++------------------- src/resources.h | 1 + src/sio.c | 94 +++++++++++++++++++++++++++++--------------- src/sound_dbopl.cc | 19 ++++++++- src/sound_dbopl.h | 2 + src/vid_voodoo.c | 21 +++++----- src/w83877f.c | 18 +++++++-- src/win.c | 16 ++++++++ 30 files changed, 372 insertions(+), 247 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ec298348f..ffe7582f5 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -49,5 +49,8 @@ clean : %.o : %.cc $(CPP) $(CFLAGS) -c $< +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< + pc.res: pc.rc $(WINDRES) $(RFLAGS) -i pc.rc --input-format=rc -o pc.res -O coff diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 389e2296e..56f114255 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -49,5 +49,8 @@ clean : %.o : %.cc $(CPP) $(CFLAGS) -c $< +%.o : %.cpp + $(CPP) $(CFLAGS) -c $< + pc.res: pc.rc $(WINDRES) $(RFLAGS) -i pc.rc --input-format=rc -o pc.res -O coff diff --git a/src/cpu.c b/src/cpu.c index 6db4457ab..fc811f532 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -1939,9 +1939,9 @@ void cpu_RDMSR() switch (ECX) { case 0x10: - EAX = tsc & 0xffffffff; - EDX = tsc >> 32; - break; + EAX = tsc & 0xffffffff; + EDX = tsc >> 32; + break; } break; case CPU_Cx6x86: @@ -2150,8 +2150,8 @@ void cpu_WRMSR() switch (ECX) { case 0x10: - tsc = EAX | ((uint64_t)EDX << 32); - break; + tsc = EAX | ((uint64_t)EDX << 32); + break; } break; case CPU_Cx6x86: diff --git a/src/disc.c b/src/disc.c index 8a273f463..b1401df7a 100644 --- a/src/disc.c +++ b/src/disc.c @@ -207,6 +207,9 @@ double disc_real_period(int drive) void disc_poll(int drive) { + disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC); + return; + if (drive >= FDD_NUM) { disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC); diff --git a/src/fdc.c b/src/fdc.c index e310d5e17..b3b61f7da 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +#include #include #include #include "ibm.h" @@ -2165,9 +2166,9 @@ void fdc_indexpulse() // rfdc_log("c82c711_fdc_indexpulse\n"); } -void fdc_init() +void fdc_hard_reset() { - timer_add(fdc_callback, &disctime, &disctime, NULL); + memset(&fdc, 0, sizeof(FDC)); fdc.dskchg_activelow = 0; fdc.enable_3f1 = 1; @@ -2201,6 +2202,16 @@ void fdc_init() swwp = 0; disable_write = 0; + + disc_reset(); + fdc_reset(); +} + +void fdc_init() +{ + fdc_hard_reset(); + + timer_add(fdc_callback, &disctime, &disctime, NULL); } void fdc_add() diff --git a/src/fdc37c665.c b/src/fdc37c665.c index d076ae2cb..59e0bcb78 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -139,31 +139,30 @@ uint8_t fdc37c665_read(uint16_t port, void *priv) return 0xff; } -void fdc37c665_init() +void fdc37c665_reset(void) { - io_sethandler(0x03f0, 0x0002, fdc37c665_read, NULL, NULL, fdc37c665_write, NULL, NULL, NULL); - fdc_update_is_nsc(0); - fdc37c665_lock[0] = fdc37c665_lock[1] = 0; + memset(fdc37c665_lock, 0, 2); + memset(fdc37c665_regs, 0, 16); fdc37c665_regs[0x0] = 0x3b; fdc37c665_regs[0x1] = 0x9f; fdc37c665_regs[0x2] = 0xdc; fdc37c665_regs[0x3] = 0x78; - fdc37c665_regs[0x4] = 0x00; - fdc37c665_regs[0x5] = 0x00; fdc37c665_regs[0x6] = 0xff; - fdc37c665_regs[0x7] = 0x00; - fdc37c665_regs[0x8] = 0x00; - fdc37c665_regs[0x9] = 0x00; - fdc37c665_regs[0xa] = 0x00; - fdc37c665_regs[0xb] = 0x00; - fdc37c665_regs[0xc] = 0x00; fdc37c665_regs[0xd] = 0x65; fdc37c665_regs[0xe] = 0x01; - fdc37c665_regs[0xf] = 0x00; fdc_update_densel_polarity(1); fdc_update_densel_force(0); fdd_swap = 0; } + +void fdc37c665_init() +{ + io_sethandler(0x03f0, 0x0002, fdc37c665_read, NULL, NULL, fdc37c665_write, NULL, NULL, NULL); + + fdc37c665_reset(); + + pci_reset_handler.super_io_reset = fdc37c665_reset; +} diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 68abfea5e..27385712a 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -393,12 +393,10 @@ uint8_t fdc37c932fr_read(uint16_t port, void *priv) } } -void fdc37c932fr_init() +void fdc37c932fr_reset(void) { int i = 0; - lpt2_remove(); - fdc37c932fr_regs[3] = 3; fdc37c932fr_regs[0x20] = 3; fdc37c932fr_regs[0x21] = 1; @@ -485,8 +483,19 @@ void fdc37c932fr_init() fdc_update_drvrate(2, 0); fdc_update_drvrate(3, 0); fdc_update_max_track(79); + + fdc37c932fr_locked = 0; +} + +void fdc37c932fr_init() +{ + lpt2_remove(); + + fdc37c932fr_reset(); + io_sethandler(0xe0, 0x0006, fdc37c932fr_gpio_read, NULL, NULL, fdc37c932fr_gpio_write, NULL, NULL, NULL); io_sethandler(0xea, 0x0002, fdc37c932fr_gpio_read, NULL, NULL, fdc37c932fr_gpio_write, NULL, NULL, NULL); io_sethandler(0x3f0, 0x0002, fdc37c932fr_read, NULL, NULL, fdc37c932fr_write, NULL, NULL, NULL); - fdc37c932fr_locked = 0; + + pci_reset_handler.super_io_reset = fdc37c932fr_reset; } diff --git a/src/i430fx.c b/src/i430fx.c index 9e4addfc6..34420f75f 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -102,27 +102,8 @@ uint8_t i430fx_read(int func, int addr, void *priv) return card_i430fx[addr]; } -/*The Turbo-Reset Control Register isn't listed in the i430FX datasheet, however - the Advanced/EV BIOS seems to assume it exists. It aliases with one of the PCI - registers.*/ -static uint8_t trc = 0; - -void i430fx_trc_write(uint16_t port, uint8_t val, void *p) +void i430fx_reset(void) { - if ((val & 4) && !(trc & 4)) - { - if (val & 2) /*Hard reset*/ - i430fx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ - resetx86(); - } - - trc = val; -} - -void i430fx_init() -{ - pci_add_specific(0, i430fx_read, i430fx_write, NULL); - memset(card_i430fx, 0, 256); card_i430fx[0x00] = 0x86; card_i430fx[0x01] = 0x80; /*Intel*/ card_i430fx[0x02] = 0x22; card_i430fx[0x03] = 0x01; /*SB82437FX-66*/ @@ -138,8 +119,6 @@ void i430fx_init() card_i430fx[0x53] = 0x14; card_i430fx[0x56] = 0x52; /*DRAM control*/ } -// card_i430fx[0x53] = 0x14; -// card_i430fx[0x56] = 0x52; /*DRAM control*/ card_i430fx[0x57] = 0x01; card_i430fx[0x60] = card_i430fx[0x61] = card_i430fx[0x62] = card_i430fx[0x63] = card_i430fx[0x64] = 0x02; if (romset == ROM_MB500N) @@ -148,17 +127,24 @@ void i430fx_init() card_i430fx[0x69] = 0x03; card_i430fx[0x70] = 0x20; } -// card_i430fx[0x67] = 0x11; -// card_i430fx[0x69] = 0x03; -// card_i430fx[0x70] = 0x20; card_i430fx[0x72] = 0x02; -// card_i430fx[0x74] = 0x0e; -// card_i430fx[0x78] = 0x23; if (romset == ROM_MB500N) { card_i430fx[0x74] = 0x0e; card_i430fx[0x78] = 0x23; } - - if (romset != ROM_MB500N) io_sethandler(0x0cf9, 0x0001, NULL, NULL, NULL, i430fx_trc_write, NULL, NULL, NULL); +} + +void i430fx_pci_reset(void) +{ + i430fx_write(0, 0x59, 0xf, NULL); +} + +void i430fx_init() +{ + pci_add_specific(0, i430fx_read, i430fx_write, NULL); + + i430fx_reset(); + + pci_reset_handler.pci_master_reset = i430fx_pci_reset; } diff --git a/src/i430hx.c b/src/i430hx.c index 33f8e137d..8d20e98e4 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -103,11 +103,8 @@ uint8_t i430hx_read(int func, int addr, void *priv) return card_i430hx[addr]; } - -void i430hx_init() +void i430hx_reset(void) { - pci_add_specific(0, i430hx_read, i430hx_write, NULL); - memset(card_i430hx, 0, 256); card_i430hx[0x00] = 0x86; card_i430hx[0x01] = 0x80; /*Intel*/ card_i430hx[0x02] = 0x50; card_i430hx[0x03] = 0x12; /*82439HX*/ @@ -115,9 +112,7 @@ void i430hx_init() card_i430hx[0x06] = 0x00; card_i430hx[0x07] = 0x02; card_i430hx[0x08] = 0x00; /*A0 stepping*/ card_i430hx[0x09] = 0x00; card_i430hx[0x0a] = 0x00; card_i430hx[0x0b] = 0x06; - // card_i430hx[0x52] = 0x42; /*256kb PLB cache*/ card_i430hx[0x51] = 0x20; - // card_i430hx[0x52] = 0xB2; /*512kb cache*/ card_i430hx[0x52] = 0xB5; /*512kb cache*/ card_i430hx[0x59] = 0x40; @@ -129,3 +124,17 @@ void i430hx_init() card_i430hx[0x68] = 0x11; card_i430hx[0x72] = 0x02; } + +void i430hx_pci_reset(void) +{ + i430hx_write(0, 0x59, 0xf, NULL); +} + +void i430hx_init() +{ + pci_add_specific(0, i430hx_read, i430hx_write, NULL); + + i430hx_reset(); + + pci_reset_handler.pci_master_reset = i430hx_pci_reset; +} diff --git a/src/i430lx.c b/src/i430lx.c index 6a2d4a0ea..624d3f8d0 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -105,29 +105,8 @@ uint8_t i430lx_read(int func, int addr, void *priv) return card_i430lx[addr]; } -static uint8_t trc = 0; - -uint8_t i430lx_trc_read(uint16_t port, void *p) +void i430lx_reset(void) { - return trc; -} - -void i430lx_trc_write(uint16_t port, uint8_t val, void *p) -{ - if ((val & 4) && !(trc & 4)) - { - if (val & 2) /*Hard reset*/ - i430lx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ - resetx86(); - } - - trc = val; -} - -void i430lx_init() -{ - pci_add_specific(0, i430lx_read, i430lx_write, NULL); - memset(card_i430lx, 0, 256); card_i430lx[0x00] = 0x86; card_i430lx[0x01] = 0x80; /*Intel*/ card_i430lx[0x02] = 0xa3; card_i430lx[0x03] = 0x04; /*82434LX*/ @@ -137,16 +116,20 @@ void i430lx_init() card_i430lx[0x09] = 0x00; card_i430lx[0x0a] = 0x00; card_i430lx[0x0b] = 0x06; card_i430lx[0x50] = 0x80; card_i430lx[0x52] = 0x40; /*256kb PLB cache*/ -// card_i430lx[0x53] = 0x14; -// card_i430lx[0x56] = 0x52; /*DRAM control*/ card_i430lx[0x57] = 0x31; card_i430lx[0x60] = card_i430lx[0x61] = card_i430lx[0x62] = card_i430lx[0x63] = card_i430lx[0x64] = 0x02; -// card_i430lx[0x67] = 0x11; -// card_i430lx[0x69] = 0x03; -// card_i430lx[0x70] = 0x20; -// card_i430lx[0x72] = 0x02; -// card_i430lx[0x74] = 0x0e; -// card_i430lx[0x78] = 0x23; - - io_sethandler(0x0cf9, 0x0001, i430lx_trc_read, NULL, NULL, i430lx_trc_write, NULL, NULL, NULL); +} + +void i430lx_pci_reset(void) +{ + i430lx_write(0, 0x59, 0xf, NULL); +} + +void i430lx_init() +{ + pci_add_specific(0, i430lx_read, i430lx_write, NULL); + + i430lx_reset(); + + pci_reset_handler.pci_master_reset = i430lx_pci_reset; } diff --git a/src/i430nx.c b/src/i430nx.c index 9b7ef653b..9b58d4000 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -102,29 +102,8 @@ uint8_t i430nx_read(int func, int addr, void *priv) return card_i430nx[addr]; } -static uint8_t trc = 0; - -uint8_t i430nx_trc_read(uint16_t port, void *p) +void i430nx_reset(void) { - return trc; -} - -void i430nx_trc_write(uint16_t port, uint8_t val, void *p) -{ - if ((val & 4) && !(trc & 4)) - { - if (val & 2) /*Hard reset*/ - i430nx_write(0, 0x59, 0xf, NULL); /*Should reset all PCI devices, but just set PAM0 to point to ROM for now*/ - resetx86(); - } - - trc = val; -} - -void i430nx_init() -{ - pci_add_specific(0, i430nx_read, i430nx_write, NULL); - memset(card_i430nx, 0, 256); card_i430nx[0x00] = 0x86; card_i430nx[0x01] = 0x80; /*Intel*/ card_i430nx[0x02] = 0xa3; card_i430nx[0x03] = 0x04; /*82434NX*/ @@ -134,17 +113,21 @@ void i430nx_init() card_i430nx[0x09] = 0x00; card_i430nx[0x0a] = 0x00; card_i430nx[0x0b] = 0x06; card_i430nx[0x50] = 0xA0; card_i430nx[0x52] = 0x44; /*256kb PLB cache*/ -// card_i430nx[0x53] = 0x14; -// card_i430nx[0x56] = 0x52; /*DRAM control*/ card_i430nx[0x57] = 0x31; card_i430nx[0x60] = card_i430nx[0x61] = card_i430nx[0x62] = card_i430nx[0x63] = card_i430nx[0x64] = 0x02; card_i430nx[0x66] = card_i430nx[0x67] = 0x02; -// card_i430nx[0x67] = 0x11; -// card_i430nx[0x69] = 0x03; -// card_i430nx[0x70] = 0x20; -// card_i430nx[0x72] = 0x02; -// card_i430nx[0x74] = 0x0e; -// card_i430nx[0x78] = 0x23; - - io_sethandler(0x0cf9, 0x0001, i430nx_trc_read, NULL, NULL, i430nx_trc_write, NULL, NULL, NULL); +} + +void i430nx_pci_reset(void) +{ + i430nx_write(0, 0x59, 0xf, NULL); +} + +void i430nx_init() +{ + pci_add_specific(0, i430nx_read, i430nx_write, NULL); + + i430nx_reset(); + + pci_reset_handler.pci_master_reset = i430nx_pci_reset; } diff --git a/src/i430vx.c b/src/i430vx.c index 487c1f977..ae9aec90e 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -103,11 +103,8 @@ uint8_t i430vx_read(int func, int addr, void *priv) return card_i430vx[addr]; } - -void i430vx_init() +void i430vx_reset(void) { - pci_add_specific(0, i430vx_read, i430vx_write, NULL); - memset(card_i430vx, 0, 256); card_i430vx[0x00] = 0x86; card_i430vx[0x01] = 0x80; /*Intel*/ card_i430vx[0x02] = 0x30; card_i430vx[0x03] = 0x70; /*82437VX*/ @@ -127,3 +124,17 @@ void i430vx_init() card_i430vx[0x74] = 0x0e; card_i430vx[0x78] = 0x23; } + +void i430vx_pci_reset(void) +{ + i430vx_write(0, 0x59, 0xf, NULL); +} + +void i430vx_init() +{ + pci_add_specific(0, i430vx_read, i430vx_write, NULL); + + i430vx_reset(); + + pci_reset_handler.pci_master_reset = i430vx_pci_reset; +} diff --git a/src/i440fx.c b/src/i440fx.c index 43889c0ec..3481adfab 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -103,11 +103,8 @@ uint8_t i440fx_read(int func, int addr, void *priv) return card_i440fx[addr]; } - -void i440fx_init() +void i440fx_reset(void) { - pci_add_specific(0, i440fx_read, i440fx_write, NULL); - memset(card_i440fx, 0, 256); card_i440fx[0x00] = 0x86; card_i440fx[0x01] = 0x80; /*Intel*/ card_i440fx[0x02] = 0x37; card_i440fx[0x03] = 0x12; /*82441FX*/ @@ -129,8 +126,19 @@ void i440fx_init() card_i440fx[0x58] = 0x10; card_i440fx[0x5a] = card_i440fx[0x5b] = card_i440fx[0x5c] = card_i440fx[0x5d] = card_i440fx[0x5e] = 0x11; card_i440fx[0x5f] = 0x31; - // card_i440fx[0x60] = card_i440fx[0x61] = card_i440fx[0x62] = card_i440fx[0x63] = card_i440fx[0x64] = card_i440fx[0x65] = card_i440fx[0x66] = card_i440fx[0x67] = 0x02; - // card_i440fx[0x70] = 0x20; - // card_i440fx[0x71] = 0x10; card_i440fx[0x72] = 0x02; } + +void i440fx_pci_reset(void) +{ + i440fx_write(0, 0x59, 0xf, NULL); +} + +void i440fx_init() +{ + pci_add_specific(0, i440fx_read, i440fx_write, NULL); + + i440fx_reset(); + + pci_reset_handler.pci_master_reset = i440fx_pci_reset; +} diff --git a/src/ibm.h b/src/ibm.h index 3f0ed78ee..726192285 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -610,3 +610,17 @@ extern int ne2000_do_log; #endif extern int suppress_overscan; + +typedef struct PCI_RESET +{ + void (*pci_master_reset)(void); + void (*pci_set_reset)(void); + void (*super_io_reset)(void); +} PCI_RESET; + +extern PCI_RESET pci_reset_handler; + +uint8_t trc_read(uint16_t port, void *priv); +void trc_write(uint16_t port, uint8_t val, void *priv); +void trc_init(); + diff --git a/src/io.c b/src/io.c index 4ec126c1d..6361e6afa 100644 --- a/src/io.c +++ b/src/io.c @@ -128,7 +128,7 @@ uint8_t inb(uint16_t port) temp &= port_inb[port][1](port, port_priv[port][1]); /* if (!port_inb[port][0] && !port_inb[port][1]) - pclog("Bad INB %04X %04X:%04X\n", port, CS, pc); */ + pclog("Bad INB %04X %04X:%04X\n", port, CS, cpu_state.pc); */ return temp; } @@ -143,7 +143,7 @@ void outb(uint16_t port, uint8_t val) port_outb[port][1](port, val, port_priv[port][1]); /* if (!port_outb[port][0] && !port_outb[port][1]) - pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, pc); */ + pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, cpu_state.pc); */ return; } diff --git a/src/mem.c b/src/mem.c index e79b54d6c..b9f3d6eec 100644 --- a/src/mem.c +++ b/src/mem.c @@ -677,7 +677,6 @@ int loadbios() biosmask = 0x1ffff; return 1; -#if 0 case ROM_POWERMATE_V: f = romfopen("roms/powermate_v/BIOS.ROM", "rb"); /* Works */ if (!f) break; @@ -685,7 +684,6 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; -#endif case ROM_P54TP4XE: f = romfopen("roms/p54tp4xe/T15I0302.AWD", "rb"); @@ -2115,7 +2113,7 @@ void mem_reset_page_blocks() } } -void mem_reset() +/* void mem_reset() { int c; @@ -2135,7 +2133,7 @@ void mem_reset() mem_a20_key = 2; mem_a20_recalc(); -} +} */ static int port_92_reg = 0; diff --git a/src/memregs.c b/src/memregs.c index 578f9e3d4..de269223d 100644 --- a/src/memregs.c +++ b/src/memregs.c @@ -13,14 +13,26 @@ static uint8_t mem_regs[2] = {0xFF, 0xFF}; +static uint8_t mem_reg_ffff = 0; + void memregs_write(uint16_t port, uint8_t val, void *priv) { - mem_regs[port - 0xE1] = val; + if (port == 0xffff) + { + mem_reg_ffff = 0; + } + + mem_regs[(port & 1) ^ 1] = val; } uint8_t memregs_read(uint16_t port, void *priv) { - return mem_regs[port - 0xE1]; + if (port == 0xffff) + { + return mem_reg_ffff; + } + + return mem_regs[(port & 1) ^ 1]; } void memregs_init() @@ -28,4 +40,12 @@ void memregs_init() pclog("Memory Registers Init\n"); io_sethandler(0x00e1, 0x0002, memregs_read, NULL, NULL, memregs_write, NULL, NULL, NULL); -} \ No newline at end of file +} + +void powermate_memregs_init() +{ + pclog("Memory Registers Init\n"); + + io_sethandler(0x00ed, 0x0002, memregs_read, NULL, NULL, memregs_write, NULL, NULL, NULL); + io_sethandler(0xffff, 0x0001, memregs_read, NULL, NULL, memregs_write, NULL, NULL, NULL); +} diff --git a/src/model.c b/src/model.c index a6e7dc8f4..2a33af2a5 100644 --- a/src/model.c +++ b/src/model.c @@ -101,9 +101,7 @@ void at_r418_init(); void at_586mc1_init(); void at_plato_init(); void at_mb500n_init(); -#if 0 void at_powermate_v_init(); -#endif void at_p54tp4xe_init(); void at_acerm3a_init(); void at_acerv35n_init(); @@ -117,6 +115,8 @@ int model; int AMSTRAD, AT, PCI, TANDY; +PCI_RESET pci_reset_handler; + MODEL models[] = { {"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, @@ -166,9 +166,7 @@ MODEL models[] = {"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, -#if 0 {"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL}, -#endif {"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"MR Intel Advanced/ATX", ROM_MRTHOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL}, @@ -529,11 +527,10 @@ void at_mb500n_init() device_add(&intel_flash_bxt_device); } -#if 0 void at_powermate_v_init() { at_init(); - memregs_init(); + powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430fx_init(); piix_init(7); @@ -541,7 +538,6 @@ void at_powermate_v_init() acerm3a_io_init(); device_add(&intel_flash_bxt_device); } -#endif void at_p54tp4xe_init() { @@ -639,6 +635,9 @@ void model_init() AMSTRAD = AT = PCI = TANDY = 0; io_init(); + pci_reset_handler.pci_master_reset = NULL; + pci_reset_handler.pci_set_reset = NULL; + pci_reset_handler.super_io_reset = NULL; fdc_update_is_nsc(0); models[model].init(); if (models[model].device) diff --git a/src/nvr.c b/src/nvr.c index f5e632724..186e61f08 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -233,9 +233,7 @@ void loadnvr() case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "rb"); nvrmask = 127; break; case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "rb"); nvrmask = 127; break; case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "rb"); nvrmask = 127; break; -#if 0 case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "rb"); nvrmask = 127; break; -#endif case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "rb"); nvrmask = 127; break; case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "rb"); nvrmask = 127; break; case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "rb"); nvrmask = 127; break; @@ -310,9 +308,7 @@ void savenvr() case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "wb"); break; case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "wb"); break; case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "wb"); break; -#if 0 case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "wb"); break; -#endif case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "wb"); break; case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "wb"); break; case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "wb"); break; diff --git a/src/pc.c b/src/pc.c index 3067757bc..68f3a2ac0 100644 --- a/src/pc.c +++ b/src/pc.c @@ -40,6 +40,7 @@ #include "serial.h" #include "sound.h" #include "sound_cms.h" +#include "sound_dbopl.h" #include "sound_opl.h" #include "sound_sb.h" #include "sound_ssi2001.h" @@ -854,6 +855,7 @@ void loadconfig(char *fn) enable_flash = config_get_int(NULL, "enable_flash", 1); enable_sync = config_get_int(NULL, "enable_sync", 1); + opl3_type = config_get_int(NULL, "opl3_type", 1); window_w = config_get_int(NULL, "window_w", 0); window_h = config_get_int(NULL, "window_h", 0); @@ -1046,6 +1048,7 @@ void saveconfig() config_set_int(NULL, "enable_flash", enable_flash); config_set_int(NULL, "enable_sync", enable_sync); + config_set_int(NULL, "opl3_type", opl3_type); config_set_int(NULL, "joystick_type", joystick_type); config_set_int(NULL, "mouse_type", mouse_type); diff --git a/src/pc.rc b/src/pc.rc index 10067fd2d..da2ad821b 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -312,9 +312,12 @@ BEGIN POPUP "&Settings" BEGIN MENUITEM "&Configure...", IDM_CONFIG + MENUITEM SEPARATOR MENUITEM "&Load configuration...", IDM_CONFIG_LOAD MENUITEM "&Save configuration...", IDM_CONFIG_SAVE MENUITEM SEPARATOR + MENUITEM "Use &Nuked OPL for OPL 3...", IDM_USE_NUKEDOPL + MENUITEM SEPARATOR POPUP "&Video" BEGIN MENUITEM "&Resizeable window",IDM_VID_RESIZE diff --git a/src/pc87306.c b/src/pc87306.c index d10fb4844..ac1c2abdb 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -361,14 +361,11 @@ void pc87306_gpio_init() } } -void pc87306_init() +void pc87306_reset(void) { memset(pc87306_regs, 0, 29); - lpt2_remove(); - // pc87306_regs[0] = 0xF; pc87306_regs[0] = 0x4B; - // pc87306_regs[1] = 0x11; pc87306_regs[1] = 0x01; pc87306_regs[3] = 2; pc87306_regs[5] = 0xD; @@ -388,5 +385,15 @@ void pc87306_init() fdc_update_densel_polarity(1); fdc_update_max_track(85); fdd_swap = 0; - io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, NULL); +} + +void pc87306_init() +{ + lpt2_remove(); + + pc87306_reset(); + + io_sethandler(0x02e, 0x0002, pc87306_read, NULL, NULL, pc87306_write, NULL, NULL, NULL); + + pci_reset_handler.super_io_reset = pc87306_reset; } diff --git a/src/piix.c b/src/piix.c index 2a28547c9..d0672e63d 100644 --- a/src/piix.c +++ b/src/piix.c @@ -500,9 +500,41 @@ void piix_bus_master_set_irq(int channel) piix_busmaster[channel].status |= 4; } -static int reset_reg = 0; +/* static int reset_reg = 0; -void piix_reset() +static uint8_t rc_read(uint16_t port, void *priv) +{ + return reset_reg & 0xfb; +} + +static void rc_write(uint16_t port, uint8_t val, void *priv) +{ + if (!(reset_reg & 4) && (val & 4)) + { + if (reset_reg & 2) + { + // pclog("PIIX: Hard reset\n"); + resetpchard(); + } + else + { + // pclog("PIIX: Soft reset\n"); + if (piix_type == 3) + { + piix3_reset(); + } + else + { + piix_reset(); + } + resetide(); + softresetx86(); + } + } + reset_reg = val; +} */ + +void piix_reset(void) { memset(card_piix, 0, 256); card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ @@ -541,7 +573,7 @@ void piix_reset() card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; } -void piix3_reset() +void piix3_reset(void) { memset(card_piix, 0, 256); card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ @@ -582,57 +614,25 @@ void piix3_reset() card_piix_ide[0x44] = 0x00; } -static uint8_t rc_read(uint16_t port, void *priv) -{ - return reset_reg & 0xfb; -} - -static void rc_write(uint16_t port, uint8_t val, void *priv) -{ - if (!(reset_reg & 4) && (val & 4)) - { - if (reset_reg & 2) - { - // pclog("PIIX: Hard reset\n"); - resetpchard(); - } - else - { - // pclog("PIIX: Soft reset\n"); - if (piix_type == 3) - { - piix3_reset(); - } - else - { - piix_reset(); - } - resetide(); - softresetx86(); - } - } - reset_reg = val; -} - void piix_init(int card) { pci_add_specific(card, piix_read, piix_write, NULL); piix_reset(); - reset_reg = 0; - piix_type = 1; ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, piix_bus_master_set_irq); - io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL); + trc_init(); port_92_reset(); port_92_add(); dma_alias_set(); + + pci_reset_handler.pci_set_reset = piix_reset; } void piix3_init(int card) @@ -641,17 +641,17 @@ void piix3_init(int card) piix3_reset(); - reset_reg = 0; - piix_type = 3; ide_set_bus_master(piix_bus_master_dma_read, piix_bus_master_dma_write, piix_bus_master_set_irq); - io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL); + trc_init(); port_92_reset(); port_92_add(); dma_alias_set(); + + pci_reset_handler.pci_set_reset = piix_reset; } diff --git a/src/resources.h b/src/resources.h index 406bfba81..dbd056533 100644 --- a/src/resources.h +++ b/src/resources.h @@ -15,6 +15,7 @@ #define IDM_CONFIG 40020 #define IDM_CONFIG_LOAD 40021 #define IDM_CONFIG_SAVE 40022 +#define IDM_USE_NUKEDOPL 40023 #define IDM_STATUS 40030 #define IDM_VID_RESIZE 40050 #define IDM_VID_REMEMBER 40051 diff --git a/src/sio.c b/src/sio.c index a808aeb7b..ffc676995 100644 --- a/src/sio.c +++ b/src/sio.c @@ -9,6 +9,8 @@ #include #include "ibm.h" +#include "cdrom.h" +#include "cpu.h" #include "ide.h" #include "io.h" #include "mem.h" @@ -82,9 +84,64 @@ uint8_t sio_read(int func, int addr, void *priv) return card_sio[addr]; } -static int reset_reg = 0; +static int trc_reg = 0; -void sio_reset() +uint8_t trc_read(uint16_t port, void *priv) +{ + return trc_reg & 0xfb; +} + +void trc_write(uint16_t port, uint8_t val, void *priv) +{ + int i = 0; + + pclog("TRC Write: %02X\n", val); + if (!(trc_reg & 4) && (val & 4)) + { + if (val & 2) + { + if (pci_reset_handler.pci_master_reset) + { + pci_reset_handler.pci_master_reset(); + } + + if (pci_reset_handler.pci_set_reset) + { + pci_reset_handler.pci_set_reset(); + } + + fdc_hard_reset(); + + if (pci_reset_handler.super_io_reset) + { + pci_reset_handler.super_io_reset(); + } + + resetide(); + for (i = 0; i < CDROM_NUM; i++) + { + if (!cdrom_drives[i].bus_type) + { + cdrom_reset(i); + } + } + + port_92_reset(); + keyboard_at_reset(); + } + resetx86(); + } + trc_reg = val & 0xfd; +} + +void trc_init() +{ + trc_reg = 0; + + io_sethandler(0x0cf9, 0x0001, trc_read, NULL, NULL, trc_write, NULL, NULL, NULL); +} + +void sio_reset(void) { memset(card_sio, 0, 256); card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/ @@ -109,44 +166,19 @@ void sio_reset() card_sio[0xA8] = 0x0F; } -static uint8_t rc_read(uint16_t port, void *priv) -{ - return reset_reg & 0xfb; -} - -static void rc_write(uint16_t port, uint8_t val, void *priv) -{ - if (!(reset_reg & 4) && (val & 4)) - { - if (reset_reg & 2) - { - // pclog("SIO: Hard reset\n"); - resetpchard(); - } - else - { - // pclog("SIO: Soft reset\n"); - sio_reset(); - resetide(); - softresetx86(); - } - } - reset_reg = val; -} - void sio_init(int card) { pci_add_specific(card, sio_read, sio_write, NULL); - sio_reset(); + sio_reset(); - reset_reg = 0; - - io_sethandler(0x0cf9, 0x0001, rc_read, NULL, NULL, rc_write, NULL, NULL, NULL); + trc_init(); port_92_reset(); port_92_add(); dma_alias_set(); + + pci_reset_handler.pci_set_reset = sio_reset; } diff --git a/src/sound_dbopl.cc b/src/sound_dbopl.cc index cd13180f3..13f87df44 100644 --- a/src/sound_dbopl.cc +++ b/src/sound_dbopl.cc @@ -5,6 +5,8 @@ #include "dosbox/nukedopl.h" #include "sound_dbopl.h" +int opl3_type = 0; + static struct { DBOPL::Chip chip; @@ -38,13 +40,13 @@ enum void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), void *timer_param, int nr, int is_opl3) { - if (!is_opl3) + if (!is_opl3 || !opl3_type) { DBOPL::InitTables(); opl[nr].chip.Setup(48000, 0); opl[nr].timer_callback = timer_callback; opl[nr].timer_param = timer_param; - opl[nr].is_opl3 = 0; + opl[nr].is_opl3 = is_opl3; } else { @@ -154,5 +156,18 @@ void opl2_update(int nr, int16_t *buffer, int samples) void opl3_update(int nr, int16_t *buffer, int samples) { + int c; + Bit32s buffer_32[samples*2]; + + if (opl3_type) + { OPL3_GenerateStream(&opl[nr].opl3chip, buffer, samples); + } + else + { + opl[nr].chip.GenerateBlock3(samples, buffer_32); + + for (c = 0; c < samples*2; c++) + buffer[c] = (int16_t)buffer_32[c]; + } } diff --git a/src/sound_dbopl.h b/src/sound_dbopl.h index d16ce9549..49b2aa095 100644 --- a/src/sound_dbopl.h +++ b/src/sound_dbopl.h @@ -10,6 +10,8 @@ extern "C" { void opl_timer_over(int nr, int timer); void opl2_update(int nr, int16_t *buffer, int samples); void opl3_update(int nr, int16_t *buffer, int samples); + + extern int opl3_type; #ifdef __cplusplus } #endif diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 8d8afeb39..172a6e17e 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -3411,7 +3411,6 @@ static inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) { int y; - int low_y, high_y; if (params->fbzMode & (1 << 17)) @@ -3425,7 +3424,7 @@ static void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params) high_y = params->clipHighY; } - if (params->fbzMode & FBZ_RGB_WMASK) + if (params->fbzMode & FBZ_RGB_WMASK) { int r, g, b; uint16_t col; @@ -4610,21 +4609,21 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_bltSrcChromaRange: voodoo->bltSrcChromaRange = val; - voodoo->bltSrcChromaMinR = val & 0x1f; + voodoo->bltSrcChromaMinB = val & 0x1f; voodoo->bltSrcChromaMinG = (val >> 5) & 0x3f; - voodoo->bltSrcChromaMinB = (val >> 11) & 0x1f; - voodoo->bltSrcChromaMaxR = (val >> 16) & 0x1f; + voodoo->bltSrcChromaMinR = (val >> 11) & 0x1f; + voodoo->bltSrcChromaMaxB = (val >> 16) & 0x1f; voodoo->bltSrcChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltSrcChromaMaxB = (val >> 27) & 0x1f; + voodoo->bltSrcChromaMaxR = (val >> 27) & 0x1f; break; case SST_bltDstChromaRange: voodoo->bltDstChromaRange = val; - voodoo->bltDstChromaMinR = val & 0x1f; + voodoo->bltDstChromaMinB = val & 0x1f; voodoo->bltDstChromaMinG = (val >> 5) & 0x3f; - voodoo->bltDstChromaMinB = (val >> 11) & 0x1f; - voodoo->bltDstChromaMaxR = (val >> 16) & 0x1f; + voodoo->bltDstChromaMinR = (val >> 11) & 0x1f; + voodoo->bltDstChromaMaxB = (val >> 16) & 0x1f; voodoo->bltDstChromaMaxG = (val >> 21) & 0x3f; - voodoo->bltDstChromaMaxB = (val >> 27) & 0x1f; + voodoo->bltDstChromaMaxR = (val >> 27) & 0x1f; break; case SST_bltClipX: voodoo->bltClipRight = val & 0xfff; @@ -5627,6 +5626,8 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) temp |= (voodoo->swap_count << 28); if (voodoo->cmd_written - voodoo->cmd_read) temp |= 0x380; /*Busy*/ + if (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr) + temp |= 0x380; /*Busy*/ if (!voodoo->v_retrace) temp |= 0x40; if (!voodoo->voodoo_busy) diff --git a/src/w83877f.c b/src/w83877f.c index ef595040f..0096b998d 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -481,13 +481,14 @@ uint8_t w83877f_read(uint16_t port, void *priv) } } -void w83877f_init() +void w83877f_reset(void) { - fdc_remove(); - fdc_add_for_superio(); lpt1_remove(); lpt1_init(0x378); - lpt2_remove(); + + fdc_remove(); + fdc_add_for_superio(); + w83877f_regs[3] = 0x30; w83877f_regs[7] = 0xF5; w83877f_regs[9] = 0x0A; @@ -525,3 +526,12 @@ void w83877f_init() w83877f_locked = 0; w83877f_rw_locked = 0; } + +void w83877f_init() +{ + lpt2_remove(); + + w83877f_reset(); + + pci_reset_handler.super_io_reset = w83877f_reset; +} diff --git a/src/win.c b/src/win.c index 33840cd63..79b46de76 100644 --- a/src/win.c +++ b/src/win.c @@ -32,6 +32,7 @@ #include "nethandler.h" #include "nvr.h" #include "sound.h" +#include "sound_dbopl.h" #include "thread.h" #include "disc.h" @@ -772,6 +773,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, #endif #endif + CheckMenuItem(menu, IDM_USE_NUKEDOPL, opl3_type ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_FLASH, enable_flash ? MF_CHECKED : MF_UNCHECKED); @@ -1525,6 +1527,20 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM saveconfig(); break; + case IDM_USE_NUKEDOPL: + if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) + { + break; + } + pause = 1; + Sleep(100); + opl3_type ^= 1; + CheckMenuItem(hmenu, IDM_USE_NUKEDOPL, opl3_type ? MF_CHECKED : MF_UNCHECKED); + saveconfig(); + resetpchard(); + pause = 0; + break; + case IDM_VID_FORCE43: video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); break; From 0c7c4197da61f42ead541df4f10ae74e6d0cc87f Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 1 Feb 2017 17:55:11 +0100 Subject: [PATCH 058/392] Commented out the PowerMate V; Added port 0xED to the Acer Pentium machines. --- src/intel_flash.c | 4 ++++ src/mem.c | 4 ++++ src/memregs.c | 6 +++--- src/model.c | 12 +++++++----- src/nvr.c | 8 ++++++++ 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/intel_flash.c b/src/intel_flash.c index d27835870..19d7a7864 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -176,9 +176,11 @@ void *intel_flash_init(uint8_t type) case ROM_MB500N: strcpy(flash_path, "roms/mb500n/"); break; +#if 0 case ROM_POWERMATE_V: strcpy(flash_path, "roms/powermate_v/"); break; +#endif case ROM_P54TP4XE: strcpy(flash_path, "roms/p54tp4xe/"); break; @@ -203,9 +205,11 @@ void *intel_flash_init(uint8_t type) case ROM_440FX: strcpy(flash_path, "roms/440fx/"); break; +#if 0 case ROM_MARL: strcpy(flash_path, "roms/marl/"); break; +#endif case ROM_THOR: strcpy(flash_path, "roms/thor/"); break; diff --git a/src/mem.c b/src/mem.c index b9f3d6eec..460a4b204 100644 --- a/src/mem.c +++ b/src/mem.c @@ -677,6 +677,7 @@ int loadbios() biosmask = 0x1ffff; return 1; +#if 0 case ROM_POWERMATE_V: f = romfopen("roms/powermate_v/BIOS.ROM", "rb"); /* Works */ if (!f) break; @@ -684,6 +685,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; +#endif case ROM_P54TP4XE: f = romfopen("roms/p54tp4xe/T15I0302.AWD", "rb"); @@ -741,6 +743,7 @@ int loadbios() biosmask = 0x1ffff; return 1; +#if 0 case ROM_MARL: f = romfopen("roms/marl/1008DB0_.BIO", "rb"); if (!f) break; @@ -755,6 +758,7 @@ int loadbios() biosmask = 0x1ffff; //is486=1; return 1; +#endif case ROM_THOR: f = romfopen("roms/thor/1006CN0_.BIO", "rb"); diff --git a/src/memregs.c b/src/memregs.c index de269223d..ec832225a 100644 --- a/src/memregs.c +++ b/src/memregs.c @@ -11,7 +11,7 @@ #include "io.h" #include "memregs.h" -static uint8_t mem_regs[2] = {0xFF, 0xFF}; +static uint8_t mem_regs[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; static uint8_t mem_reg_ffff = 0; @@ -22,7 +22,7 @@ void memregs_write(uint16_t port, uint8_t val, void *priv) mem_reg_ffff = 0; } - mem_regs[(port & 1) ^ 1] = val; + mem_regs[port & 0xf] = val; } uint8_t memregs_read(uint16_t port, void *priv) @@ -32,7 +32,7 @@ uint8_t memregs_read(uint16_t port, void *priv) return mem_reg_ffff; } - return mem_regs[(port & 1) ^ 1]; + return mem_regs[port & 0xf]; } void memregs_init() diff --git a/src/model.c b/src/model.c index 2a33af2a5..c50523b3d 100644 --- a/src/model.c +++ b/src/model.c @@ -101,13 +101,13 @@ void at_r418_init(); void at_586mc1_init(); void at_plato_init(); void at_mb500n_init(); -void at_powermate_v_init(); +// void at_powermate_v_init(); void at_p54tp4xe_init(); void at_acerm3a_init(); void at_acerv35n_init(); void at_p55t2p4_init(); void at_p55tvp4_init(); -void at_marl_init(); +// void at_marl_init(); void at_p55va_init(); void at_i440fx_init(); @@ -166,7 +166,7 @@ MODEL models[] = {"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, - {"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL}, +/* {"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL}, */ {"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"MR Intel Advanced/ATX", ROM_MRTHOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL}, @@ -527,7 +527,7 @@ void at_mb500n_init() device_add(&intel_flash_bxt_device); } -void at_powermate_v_init() +/* void at_powermate_v_init() { at_init(); powermate_memregs_init(); @@ -537,7 +537,7 @@ void at_powermate_v_init() fdc37c665_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); -} +} */ void at_p54tp4xe_init() { @@ -554,6 +554,7 @@ void at_acerm3a_init() { at_init(); memregs_init(); + powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); i430hx_init(); piix3_init(7); @@ -566,6 +567,7 @@ void at_acerv35n_init() { at_init(); memregs_init(); + powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); i430hx_init(); piix3_init(7); diff --git a/src/nvr.c b/src/nvr.c index 186e61f08..450d6faa2 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -233,7 +233,9 @@ void loadnvr() case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "rb"); nvrmask = 127; break; case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "rb"); nvrmask = 127; break; case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "rb"); nvrmask = 127; break; +#if 0 case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "rb"); nvrmask = 127; break; +#endif case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "rb"); nvrmask = 127; break; case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "rb"); nvrmask = 127; break; case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "rb"); nvrmask = 127; break; @@ -241,7 +243,9 @@ void loadnvr() case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "rb"); nvrmask = 127; break; case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "rb"); nvrmask = 127; break; case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "rb"); nvrmask = 127; break; +#if 0 case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "rb"); nvrmask = 127; break; +#endif case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "rb"); nvrmask = 127; break; case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "rb"); nvrmask = 127; break; default: return; @@ -308,7 +312,9 @@ void savenvr() case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "wb"); break; case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "wb"); break; case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "wb"); break; +#if 0 case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "wb"); break; +#endif case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "wb"); break; case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "wb"); break; case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "wb"); break; @@ -316,7 +322,9 @@ void savenvr() case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "wb"); break; case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "wb"); break; case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "wb"); break; +#if 0 case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "wb"); break; +#endif case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "wb"); break; case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "wb"); break; default: return; From e24d0ab18ab30f87dbcee524c2c47d39023a1b2d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 1 Feb 2017 21:41:35 +0100 Subject: [PATCH 059/392] Reenabled the floppy drive poller, floppies should now work again. --- src/disc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/disc.c b/src/disc.c index b1401df7a..8a273f463 100644 --- a/src/disc.c +++ b/src/disc.c @@ -207,9 +207,6 @@ double disc_real_period(int drive) void disc_poll(int drive) { - disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC); - return; - if (drive >= FDD_NUM) { disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC); From 6ab214a2b07444b27ae039b0b29a6919579b7f58 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Feb 2017 02:55:08 +0100 Subject: [PATCH 060/392] Commented out the NEC PowerMate V, because it doesn't work; Applied all mainline PCem commits; CD-ROM sound thread is now disabled if all CD-ROM drives are either disabled or have audio disabled; Fixed the displayed incorrect zero cylinders, head, and sectors per cylinder when loading an already existing HDI image; Fixed the CD-ROM audio menu item not checking/unchecking correctly. --- src/ibm.h | 2 +- src/ide.c | 8 +++++ src/io.c | 7 ++++ src/model.c | 14 +++++--- src/pc.c | 2 ++ src/sound.c | 83 +++++++++++++++++++++++++++++++++++++++++++---- src/soundopenal.c | 6 +++- src/win-hdconf.c | 2 +- src/win.c | 3 +- 9 files changed, 113 insertions(+), 14 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 726192285..558f7a92e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -496,7 +496,7 @@ float VGACONST1,VGACONST2; float RTCCONST; int gated,speakval,speakon; -#define SOUNDBUFLEN (48000/10) +#define SOUNDBUFLEN (48000/40) /*Sound Blaster*/ diff --git a/src/ide.c b/src/ide.c index 83ff385e4..eb98e78d2 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1283,6 +1283,14 @@ ide_bad_command: ide->atastat = ide_other->atastat = BUSY_STAT; // ide_log("IDE Reset %i\n", ide_board); } + if (val & 4) + { + /*Drive held in reset*/ + timer_process(); + idecallback[ide_board] = 0; + timer_update_outstanding(); + ide->atastat = ide_other->atastat = BUSY_STAT; + } ide->fdisk = ide_other->fdisk = val; ide_irq_update(ide); return; diff --git a/src/io.c b/src/io.c index 6361e6afa..9431268fd 100644 --- a/src/io.c +++ b/src/io.c @@ -130,6 +130,9 @@ uint8_t inb(uint16_t port) /* if (!port_inb[port][0] && !port_inb[port][1]) pclog("Bad INB %04X %04X:%04X\n", port, CS, cpu_state.pc); */ + /* if (port_inb[port][0] || port_inb[port][1]) + pclog("Good INB %04X %04X:%04X\n", port, CS, cpu_state.pc); */ + return temp; } @@ -144,6 +147,10 @@ void outb(uint16_t port, uint8_t val) /* if (!port_outb[port][0] && !port_outb[port][1]) pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, cpu_state.pc); */ + + /* if (port_outb[port][0] || port_outb[port][1]) + pclog("Good OUTB %04X %02X %04X:%08X\n", port, val, CS, cpu_state.pc); */ + return; } diff --git a/src/model.c b/src/model.c index c50523b3d..174fe63e0 100644 --- a/src/model.c +++ b/src/model.c @@ -101,7 +101,9 @@ void at_r418_init(); void at_586mc1_init(); void at_plato_init(); void at_mb500n_init(); -// void at_powermate_v_init(); +#if 0 +void at_powermate_v_init(); +#endif void at_p54tp4xe_init(); void at_acerm3a_init(); void at_acerv35n_init(); @@ -166,7 +168,9 @@ MODEL models[] = {"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, -/* {"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL}, */ +#if 0 + {"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL}, +#endif {"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"MR Intel Advanced/ATX", ROM_MRTHOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL}, @@ -527,7 +531,8 @@ void at_mb500n_init() device_add(&intel_flash_bxt_device); } -/* void at_powermate_v_init() +#if 0 +void at_powermate_v_init() { at_init(); powermate_memregs_init(); @@ -537,7 +542,8 @@ void at_mb500n_init() fdc37c665_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); -} */ +} +#endif void at_p54tp4xe_init() { diff --git a/src/pc.c b/src/pc.c index 68f3a2ac0..408133744 100644 --- a/src/pc.c +++ b/src/pc.c @@ -501,6 +501,8 @@ void resetpchard() } } } + + sound_cd_thread_reset(); } char romsets[17][40]={"IBM PC","IBM XT","Generic Turbo XT","Euro PC","Tandy 1000","Amstrad PC1512","Sinclair PC200","Amstrad PC1640","IBM AT","AMI 286 clone","Dell System 200","Misc 286","IBM AT 386","Misc 386","386 clone","486 clone","486 clone 2"}; diff --git a/src/sound.c b/src/sound.c index e290a0fdc..87adb2580 100644 --- a/src/sound.c +++ b/src/sound.c @@ -98,6 +98,7 @@ static float cd_out_buffer[CD_BUFLEN * 2]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; static unsigned int cd_vol_l, cd_vol_r; +static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) { @@ -114,18 +115,34 @@ static void sound_cd_thread(void *param) int c, has_audio; thread_wait_event(sound_cd_event, -1); + if (!soundon) + { + return; + } for (c = 0; c < CD_BUFLEN*2; c += 2) { cd_out_buffer[c] = 0.0; cd_out_buffer[c+1] = 0.0; } + has_audio = 0; + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].enabled && cdrom_drives[i].sound_on) + { + has_audio++; + } + } + if (!has_audio) + { + return; + } for (i = 0; i < CDROM_NUM; i++) { has_audio = 0; if (cdrom_drives[i].handler->audio_callback) { cdrom_drives[i].handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2); - has_audio = cdrom_drives[i].sound_on; + has_audio = (cdrom_drives[i].enabled && cdrom_drives[i].sound_on); } if (soundon && has_audio) { @@ -189,16 +206,34 @@ static void sound_cd_thread(void *param) static int32_t *outbuffer; static float *outbuffer_ex; +static int cd_thread_enable = 0; + void sound_init() { + int i = 0; + int available_cdrom_drives = 0; + initalmain(0,NULL); inital(); outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int32_t)); outbuffer_ex = malloc(SOUNDBUFLEN * 2 * sizeof(float)); - - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].enabled && cdrom_drives[i].sound_on) + { + available_cdrom_drives++; + } + } + + if (available_cdrom_drives) + { + sound_cd_event = thread_create_event(); + sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + } + + cd_thread_enable = available_cdrom_drives ? 1 : 0; } void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) @@ -244,7 +279,15 @@ void sound_poll(void *priv) if (soundon) givealbuffer(outbuffer_ex); - thread_set_event(sound_cd_event); + if (cd_thread_enable) + { + cd_buf_update--; + if (!cd_buf_update) + { + cd_buf_update = (48000 / SOUNDBUFLEN) / (CD_FREQ / CD_BUFLEN); + thread_set_event(sound_cd_event); + } + } sound_pos_global = 0; } @@ -258,6 +301,7 @@ void sound_speed_changed() void sound_reset() { int i = 0; + int available_cdrom_drives = 0; timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL); @@ -267,10 +311,37 @@ void sound_reset() for (i = 0; i < CDROM_NUM; i++) { - pclog("Resetting audio for CD-ROM %i...\n", i); if (cdrom_drives[i].handler->audio_stop) { cdrom_drives[i].handler->audio_stop(i); } } } + +void sound_cd_thread_reset() +{ + int i = 0; + int available_cdrom_drives = 0; + + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].enabled && cdrom_drives[i].sound_on) + { + available_cdrom_drives++; + } + } + + if (available_cdrom_drives && !cd_thread_enable) + { + thread_destroy_event(sound_cd_event); + thread_kill(sound_cd_thread_h); + sound_cd_thread_h = NULL; + } + else if (!available_cdrom_drives && cd_thread_enable) + { + sound_cd_event = thread_create_event(); + sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + } + + cd_thread_enable = available_cdrom_drives ? 1 : 0; +} diff --git a/src/soundopenal.c b/src/soundopenal.c index 29173b75b..aeb9d728d 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -87,6 +87,8 @@ void inital() int c; float buf[BUFLEN*2]; + float cd_buf[CD_BUFLEN*2]; + // printf("1\n"); check(); @@ -114,13 +116,15 @@ void inital() alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); check(); - memset(buf,0,BUFLEN*4); + memset(buf,0,BUFLEN*2*sizeof(float)); + memset(cd_buf,0,BUFLEN*2*sizeof(float)); // printf("5\n"); for (c = 0; c < 4; c++) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); } alSourceQueueBuffers(source[0], 4, buffers); diff --git a/src/win-hdconf.c b/src/win-hdconf.c index 8ab21591e..d42bd8e80 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -440,7 +440,7 @@ static void hdconf_file(HWND hdlg, int drive_num) if (image_is_hdi(openfilestring)) { - fseeko64(f, 0x10, SEEK_END); + fseeko64(f, 0x10, SEEK_SET); fread(§or_size, 1, 4, f); if (sector_size != 512) { diff --git a/src/win.c b/src/win.c index 79b46de76..84c8781bc 100644 --- a/src/win.c +++ b/src/win.c @@ -1655,8 +1655,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_SOUND_ON); Sleep(100); cdrom_drives[cdrom_id].sound_on ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_SOUND_ON + (cdrom_id * 1000), cdrom_drives[cdrom_id].enabled ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_SOUND_ON + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_CHECKED : MF_UNCHECKED); saveconfig(); + sound_cd_thread_reset(); break; case IDM_CDROM_1_SCSI: From 3c61b80a345c2ba07f7c421478c6fbe53dc076cf Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Feb 2017 23:24:56 +0100 Subject: [PATCH 061/392] Fixed several bugs in the emulation of the National Semiconductors PC87306 Super I/O chip; Attempt to fix sound fluttering in waiting for a better fix from mainline PCem; Attempt to make the Sound Blaster louder; Removed excess logging from cdrom_ioctl.c. --- src/cdrom-ioctl.c | 2 +- src/fdc.c | 33 +++++++-- src/ibm.h | 3 +- src/pc87306.c | 166 ++++++++++++++++++++++++++++++++-------------- src/serial.c | 4 +- src/sound.c | 10 +-- src/sound_sb.c | 62 ++++++++--------- src/soundopenal.c | 1 - 8 files changed, 187 insertions(+), 94 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 807f188fd..8cf8e94a3 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -692,7 +692,7 @@ static int ioctl_media_type_id(uint8_t id) SCSICommand(id, cdb, msbuf, &len, 1); - pclog("Returned length: %i, media type: %i\n", len, msbuf[2]); + // pclog("Returned length: %i, media type: %i\n", len, msbuf[2]); ioctl_close(id); diff --git a/src/fdc.c b/src/fdc.c index b3b61f7da..57532b4a2 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -102,6 +102,8 @@ typedef struct FDC int fintr; int rw_drive; + + uint16_t base_address; } FDC; static FDC fdc; @@ -591,7 +593,8 @@ void fdc_implied_seek() void fdc_write(uint16_t addr, uint8_t val, void *priv) { -// fdc_log("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready); + fdc_log("Write FDC %04X %02X\n",addr,val); + // fdc_log("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready); int drive, i, drive_num; int seek_time, seek_time_base; @@ -1256,7 +1259,6 @@ bad_command: disc_3f7=val; return; } -// printf("Write FDC %04X %02X\n",addr,val); // dumpregs(); // exit(-1); } @@ -1266,7 +1268,8 @@ uint8_t fdc_read(uint16_t addr, void *priv) { uint8_t temp; int drive; -// /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %02x %i ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,fdc.stat,ins); + fdc_log("Read FDC %04X\n",addr); + // /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %02x %i ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,fdc.stat,ins); switch (addr&7) { case 0: /* STA */ @@ -2168,6 +2171,8 @@ void fdc_indexpulse() void fdc_hard_reset() { + int base_address = fdc.base_address; + memset(&fdc, 0, sizeof(FDC)); fdc.dskchg_activelow = 0; fdc.enable_3f1 = 1; @@ -2205,6 +2210,9 @@ void fdc_hard_reset() disc_reset(); fdc_reset(); + + fdc.max_track = 79; + fdc.base_address = base_address; } void fdc_init() @@ -2222,6 +2230,16 @@ void fdc_add() fdc.ps1 = 0; fdc.max_track = 79; fdc.perp = 0; + fdc.base_address = 0x03f0; + fdc_log("FDC Added (%04X)\n", fdc.base_address); +} + +void fdc_set_base(int base, int super_io) +{ + io_sethandler(base + (super_io ? 2 : 0), super_io ? 0x0004 : 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + io_sethandler(base + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + fdc.base_address = base; + fdc_log("FDC Base address set%s (%04X)\n", super_io ? " for Super I/O" : "", fdc.base_address); } void fdc_add_for_superio() @@ -2230,6 +2248,8 @@ void fdc_add_for_superio() io_sethandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); fdc.pcjr = 0; fdc.ps1 = 0; + fdc.base_address = 0x03f0; + fdc_log("FDC Added for Super I/O (%04X)\n", fdc.base_address); } void fdc_add_pcjr() @@ -2240,12 +2260,15 @@ void fdc_add_pcjr() fdc.ps1 = 0; fdc.max_track = 79; fdc.perp = 0; + fdc.base_address = 0x03f0; + fdc_log("FDC Added for PCjr (%04X)\n", fdc.base_address); } void fdc_remove() { - io_removehandler(0x03f0, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); - io_removehandler(0x03f7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + fdc_log("FDC Removed (%04X)\n", fdc.base_address); + io_removehandler(fdc.base_address, 0x0006, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); + io_removehandler(fdc.base_address + 7, 0x0001, fdc_read, NULL, NULL, fdc_write, NULL, NULL, NULL); } void fdc_discchange_clear(int drive) diff --git a/src/ibm.h b/src/ibm.h index 558f7a92e..aa3ac2277 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -496,7 +496,8 @@ float VGACONST1,VGACONST2; float RTCCONST; int gated,speakval,speakon; -#define SOUNDBUFLEN (48000/40) +// #define SOUNDBUFLEN (48000/40) +#define SOUNDBUFLEN (32000/20) /*Sound Blaster*/ diff --git a/src/pc87306.c b/src/pc87306.c index ac1c2abdb..cb67e05e7 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -39,18 +39,19 @@ void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) uint8_t uart_int1() { /* 0: IRQ3, 1: IRQ4 */ - return ((pc87306_regs[0x1C] >> 2) & 1) ? 3 : 4; + return ((pc87306_regs[0x1C] >> 2) & 1) ? 4 : 3; } uint8_t uart_int2() { - return ((pc87306_regs[0x1C] >> 6) & 1) ? 3 : 4; + /* 0: IRQ3, 1: IRQ4 */ + return ((pc87306_regs[0x1C] >> 6) & 1) ? 4 : 3; } uint8_t uart1_int() { uint8_t temp; - temp = ((pc87306_regs[1] >> 2) & 1) ? 3 : 4; /* 0 = IRQ 4, 1 = IRQ 3 */ + temp = ((pc87306_regs[1] >> 2) & 1) ? 3 : 4; /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ // pclog("UART 1 set to IRQ %i\n", (pc87306_regs[0x1C] & 1) ? uart_int1() : temp); return (pc87306_regs[0x1C] & 1) ? uart_int1() : temp; } @@ -58,7 +59,7 @@ uint8_t uart1_int() uint8_t uart2_int() { uint8_t temp; - temp = ((pc87306_regs[1] >> 4) & 1) ? 3 : 4; /* 0 = IRQ 4, 1 = IRQ 3 */ + temp = ((pc87306_regs[1] >> 4) & 1) ? 3 : 4; /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ // pclog("UART 2 set to IRQ %i\n", (pc87306_regs[0x1C] & 1) ? uart_int2() : temp); return (pc87306_regs[0x1C] & 1) ? uart_int2() : temp; } @@ -66,30 +67,27 @@ uint8_t uart2_int() void lpt1_handler() { int temp; - if (pc87306_regs[0x1B] & 0x10) + temp = pc87306_regs[0x01] & 3; + switch (temp) { - temp = (pc87306_regs[0x1B] & 0x20) >> 5; - if (temp) - { + case 0: lpt_port = 0x378; - } - else - { + break; + case 1: + if (pc87306_regs[0x1B] & 0x40) + { + lpt_port = ((uint16_t) pc87306_regs[0x19]) << 2; + } + else + { + lpt_port = 0x3bc; + } + break; + case 2: lpt_port = 0x278; - } - } - else - { - temp = pc87306_regs[0x01] & 3; - switch (temp) - { - case 0: lpt_port = 0x378; - case 1: lpt_port = 0x3bc; - case 2: lpt_port = 0x278; - } + break; } lpt1_init(lpt_port); - pc87306_regs[0x19] = lpt_port >> 2; } void serial1_handler() @@ -171,13 +169,17 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg]; tries = 0; + if ((pc87306_curreg == 0x19) && !(pc87306_regs[0x1B] & 0x40)) + { + return; + } if ((pc87306_curreg <= 28) && (pc87306_curreg != 8) && (pc87306_curreg != 0x18)) { if (pc87306_curreg == 0) { val &= 0x5f; } - if ((pc87306_curreg == 0x0F) || (pc87306_curreg == 0x12)) + if (((pc87306_curreg == 0x0F) || (pc87306_curreg == 0x12)) && valxor) { pc87306_gpio_remove(); } @@ -198,13 +200,14 @@ process_value: switch(pc87306_curreg) { case 0: + // pclog("Register 0\n"); if (valxor & 1) { lpt1_remove(); - } - if ((valxor & 1) && (val & 1)) - { - lpt1_handler(); + if (val & 1) + { + lpt1_handler(); + } } if (valxor & 2) @@ -223,6 +226,14 @@ process_value: serial2_handler(); } } + if ((valxor & 8) || (valxor & 0x20)) + { + fdc_remove(); + if (val & 8) + { + fdc_set_base((val & 0x20) ? 0x370 : 0x3f0, 0); + } + } break; case 1: @@ -256,29 +267,81 @@ process_value: } break; case 2: - lpt1_remove(); - serial1_remove(); - serial2_remove(); - if (val & 1) + if (valxor & 1) { - pc87306_regs[0] &= 0xb0; - } - else - { - lpt1_handler(); - serial1_handler(); - // serial2_handler(); - pc87306_regs[0] |= 0x4b; + if (val & 1) + { + // pclog("Powering down functions...\n"); + lpt1_remove(); + serial1_remove(); + serial2_remove(); + fdc_remove(); + } + else + { + // pclog("Powering up functions...\n"); + if (pc87306_regs[0] & 1) + { + lpt1_handler(); + } + if (pc87306_regs[0] & 2) + { + serial1_handler(); + } + if (pc87306_regs[0] & 4) + { + serial2_handler(); + } + if (pc87306_regs[0] & 8) + { + fdc_set_base((pc87306_regs[0] & 0x20) ? 0x370 : 0x3f0, 0); + } + } } break; case 9: - // pclog("Setting DENSEL polarity to: %i (before: %i)\n", (val & 0x40 ? 1 : 0), fdc_get_densel_polarity()); - fdc_update_enh_mode((val & 4) ? 1 : 0); - fdc_update_densel_polarity((val & 0x40) ? 1 : 0); + if (valxor & 0x44) + { + // pclog("Setting DENSEL polarity to: %i (before: %i)\n", (val & 0x40 ? 1 : 0), fdc_get_densel_polarity()); + fdc_update_enh_mode((val & 4) ? 1 : 0); + fdc_update_densel_polarity((val & 0x40) ? 1 : 0); + } break; case 0xF: + if (valxor) + { + pc87306_gpio_init(); + } + break; case 0x12: - pc87306_gpio_init(); + if (valxor & 0x30) + { + pc87306_gpio_init(); + } + break; + case 0x19: + if (valxor) + { + lpt1_remove(); + if (pc87306_regs[0] & 1) + { + lpt1_handler(); + } + } + break; + case 0x1B: + if (valxor & 0x40) + { + lpt1_remove(); + if (!(val & 0x40)) + { + pc87306_regs[0x19] = 0xEF; + } + if (pc87306_regs[0] & 1) + { + lpt1_handler(); + } + } break; case 0x1C: // if (valxor & 0x25) @@ -290,7 +353,10 @@ process_value: { serial1_handler(); } - if (pc87306_regs[0] & 4) serial2_handler(); + if (pc87306_regs[0] & 4) + { + serial2_handler(); + } } break; } @@ -373,9 +439,7 @@ void pc87306_reset(void) pc87306_regs[9] = 0xFF; pc87306_regs[0xF] = 0x1E; pc87306_regs[0x12] = 0x30; - pc87306_regs[0x19] = 0xDE; - pc87306_regs[0x1B] = 0x10; - pc87306_regs[0x1C] = 0; + pc87306_regs[0x19] = 0xEF; /* 0 = 360 rpm @ 500 kbps for 3.5" 1 = Default, 300 rpm @ 500,300,250,1000 kbps for 3.5" @@ -384,7 +448,13 @@ void pc87306_reset(void) fdc_update_enh_mode(0); fdc_update_densel_polarity(1); fdc_update_max_track(85); + fdc_remove(); + fdc_add(0x3f0, 0); fdd_swap = 0; + serial1_remove(); + serial2_remove(); + serial1_handler(); + serial2_handler(); } void pc87306_init() diff --git a/src/serial.c b/src/serial.c index 3c386e035..e753aa1cf 100644 --- a/src/serial.c +++ b/src/serial.c @@ -20,8 +20,8 @@ SERIAL serial1, serial2; void serial_reset() { - serial1.iir = serial1.ier = serial1.lcr = 0; - serial2.iir = serial2.ier = serial2.lcr = 0; + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; + serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; serial1.fifo_read = serial1.fifo_write = 0; serial2.fifo_read = serial2.fifo_write = 0; } diff --git a/src/sound.c b/src/sound.c index 87adb2580..f7c40af6b 100644 --- a/src/sound.c +++ b/src/sound.c @@ -332,16 +332,16 @@ void sound_cd_thread_reset() } if (available_cdrom_drives && !cd_thread_enable) + { + sound_cd_event = thread_create_event(); + sound_cd_thread_h = thread_create(sound_cd_thread, NULL); + } + else if (!available_cdrom_drives && cd_thread_enable) { thread_destroy_event(sound_cd_event); thread_kill(sound_cd_thread_h); sound_cd_thread_h = NULL; } - else if (!available_cdrom_drives && cd_thread_enable) - { - sound_cd_event = thread_create_event(); - sound_cd_thread_h = thread_create(sound_cd_thread, NULL); - } cd_thread_enable = available_cdrom_drives ? 1 : 0; } diff --git a/src/sound_sb.c b/src/sound_sb.c index ca7b0b6c4..bb49d96d2 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -54,22 +54,22 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 13); + out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 13); if (sb->mixer.filter) { - out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; - out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; + out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 13; + out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 13; } else { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 16; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 13; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 13; } - out_l = (out_l * mixer->master_l) >> 16; - out_r = (out_r * mixer->master_r) >> 16; + out_l = (out_l * mixer->master_l) >> 13; + out_r = (out_r * mixer->master_r) >> 13; if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { @@ -103,25 +103,25 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) sb_dsp_update(&sb->dsp); for (c = 0; c < len * 2; c += 2) { - int c_emu8k = (((c/2) * 44100) / 48000)*2; + // int c_emu8k = (((c/2) * 44100) / 48000)*2; int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 13); + out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 13); if (sb->mixer.filter) { - out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; - out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; + out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 13; + out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 13; } else { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 16; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 13; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 13; } - out_l = (out_l * mixer->master_l) >> 16; - out_r = (out_r * mixer->master_r) >> 16; + out_l = (out_l * mixer->master_l) >> 13; + out_r = (out_r * mixer->master_r) >> 13; if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { @@ -160,25 +160,25 @@ static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) int c_emu8k = (((c/2) * 44100) / 48000)*2; int32_t out_l, out_r; - out_l = (((int32_t)sb->opl.buffer[c] * (int32_t)mixer->fm_l) >> 16); - out_r = (((int32_t)sb->opl.buffer[c + 1] * (int32_t)mixer->fm_r) >> 16); + out_l = (((int32_t)sb->opl.buffer[c] * (int32_t)mixer->fm_l) >> 13); + out_r = (((int32_t)sb->opl.buffer[c + 1] * (int32_t)mixer->fm_r) >> 13); - out_l += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 16); - out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_l) >> 16); + out_l += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 13); + out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_l) >> 13); if (sb->mixer.filter) { - out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; - out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; + out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 13; + out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 13; } else { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 16; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 13; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 13; } - out_l = (out_l * mixer->master_l) >> 16; - out_r = (out_r * mixer->master_r) >> 16; + out_l = (out_l * mixer->master_l) >> 13; + out_r = (out_r * mixer->master_r) >> 13; if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { @@ -224,8 +224,8 @@ void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->filter = !(mixer->regs[0xe] & 0x20); mixer->bass_l = mixer->bass_r = 8; mixer->treble_l = mixer->treble_r = 8; - sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, - ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); + sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 8191, + ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 8191); // pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]); // pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); if (mixer->index == 0xe) @@ -299,8 +299,8 @@ void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->treble_l = mixer->regs[0x44] >> 4; mixer->treble_r = mixer->regs[0x45] >> 4; mixer->filter = 0; - sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, - ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); + sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 8191, + ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 8191); // pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]); // pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); } diff --git a/src/soundopenal.c b/src/soundopenal.c index aeb9d728d..45322c1a8 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -123,7 +123,6 @@ void inital() for (c = 0; c < 4; c++) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); } From 22c3a74e3b59a0eca717258ab4aeca7b3c808d0f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 Feb 2017 06:53:46 +0100 Subject: [PATCH 062/392] The SCSI data buffer is now zeroed before being allocated, MODE SELECT data is therefore no longer lost in transit; SCSI DMA writes (for MODE SELECT) now correctly use InitLength instead of request_length when bus type is SCSI; Fixed MODE SELECT page saving; CD Audio volume is now correctly initialized on card initialization for all Sound Blaster variants, fixes CD Audio being muted when booting without the Sound Blaster initialization program; Brought the Sound Blaster variants back to a sane sound volume but still louder than the old quietness; Moved SCSI adapter initialization to before sound card initialization, fixes DOS SCSI CD-ROM driver hangs under some conditions. --- src/buslogic.c | 5 +-- src/cdrom.c | 31 ++++++++++++++---- src/gameport.c | 4 +-- src/pc.c | 22 ++++++------- src/sound.c | 10 ++++-- src/sound_sb.c | 87 +++++++++++++++++++++++++++++++++----------------- 6 files changed, 105 insertions(+), 54 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index d131846a3..293601837 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -1724,8 +1724,6 @@ static void BuslogicCDROMCommand(Buslogic_t *Buslogic) temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ } - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - //Finally, execute the SCSI command immediately and get the transfer length. SCSIPhase = SCSI_PHASE_COMMAND; @@ -1808,6 +1806,9 @@ static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, M SCSIDevices[Id][Lun].InitLength = 0; + /* Do this here, so MODE SELECT data will does not get lost in transit. */ + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); + BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); if (!buslogic_scsi_drive_is_cdrom(Id, Lun)) diff --git a/src/cdrom.c b/src/cdrom.c index 02d693b43..20068125f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -532,10 +532,6 @@ int cdrom_mode_select_terminate(uint8_t id, int force) if (((cdrom[id].written_length >= cdrom[id].total_length) || force) && (cdrom[id].mode_select_phase != MODE_SELECT_PHASE_IDLE)) { cdrom_log("CD-ROM %i: MODE SELECT terminate: %i\n", id, force); - if (!force && cdrom[id].do_page_save && (cdrom_mode_sense_pages_default[id][cdrom[id].current_page_pos][0] & 0x80)) - { - cdrom_mode_sense_save(id); - } cdrom[id].current_page_pos = cdrom[id].current_page_len = cdrom[id].block_descriptor_len = 0; cdrom[id].total_length = cdrom[id].written_length = 0; cdrom[id].mode_select_phase = MODE_SELECT_PHASE_IDLE; @@ -707,6 +703,14 @@ int cdrom_mode_select_write(uint8_t id, uint8_t val) case MODE_SELECT_PHASE_PAGE: cdrom_log("CD-ROM %i: MODE SELECT page (%02X)\n", id, val); ret = cdrom_mode_select_page(id, val); + if (cdrom[id].mode_select_phase == MODE_SELECT_PHASE_PAGE_HEADER) + { + if (cdrom[id].do_page_save && (cdrom_mode_sense_pages_default[id][cdrom[id].current_page_code][0] & 0x80)) + { + cdrom_log("CD-ROM %i: Page %i finished, saving it...\n", id, cdrom[id].current_page_code); + cdrom_mode_sense_save(id); + } + } break; default: cdrom_log("CD-ROM %i: MODE SELECT unknown phase (%02X)\n", id, val); @@ -1791,13 +1795,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention); cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); -#if 0 +// #if 0 int CdbLength; for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++) { cdrom_log("CD-ROM %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); } -#endif +// #endif } msf = cdb[1] & 2; @@ -2899,6 +2903,8 @@ int cdrom_read_from_dma(uint8_t id) int i = 0; int ret = 0; + int in_data_length = 0; + if (cdrom_drives[id].bus_type) { ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); @@ -2913,7 +2919,18 @@ int cdrom_read_from_dma(uint8_t id) return 0; } - for (i = 0; i < cdrom[id].request_length; i++) + if (cdrom_drives[id].bus_type) + { + in_data_length = SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength; + cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length); + } + else + { + in_data_length = cdrom[id].request_length; + cdrom_log("CD-ROM %i: ATAPI Input data length: %i\n", id, in_data_length); + } + + for (i = 0; i < in_data_length; i++) { ret = cdrom_mode_select_write(id, cdbufferb[i]); ret = cdrom_mode_select_return(id, ret); diff --git a/src/gameport.c b/src/gameport.c index 6fa788491..7b135dc39 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -122,7 +122,7 @@ void gameport_write(uint16_t addr, uint8_t val, void *p) timer_clock(); gameport->state |= 0x0f; -// pclog("gameport_write : joysticks_present=%i\n", joysticks_present); + pclog("gameport_write : joysticks_present=%i\n", joysticks_present); gameport->axis[0].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 0)); gameport->axis[1].count = gameport_time(gameport->joystick->read_axis(gameport->joystick_dat, 1)); @@ -145,7 +145,7 @@ uint8_t gameport_read(uint16_t addr, void *p) // else // ret = 0xff; -// pclog("gameport_read: ret=%02x %08x:%08x isa_cycles=%i %i\n", ret, cs, cpu_state.pc, isa_cycles, gameport->axis[0].count); + // pclog("gameport_read: ret=%02x %08x:%08x isa_cycles=%i %i\n", ret, cs, cpu_state.pc, isa_cycles, gameport->axis[0].count); cycles -= ISA_CYCLES(8); diff --git a/src/pc.c b/src/pc.c index 408133744..ab4e2f7b6 100644 --- a/src/pc.c +++ b/src/pc.c @@ -442,17 +442,6 @@ void resetpchard() vlan_reset(); //NETWORK } network_card_init(network_card_current); - - sound_card_init(sound_card_current); - if (GUS) - device_add(&gus_device); - if (GAMEBLASTER) - device_add(&cms_device); - if (SSI2001) - device_add(&ssi2001_device); - if (voodoo_enabled) - device_add(&voodoo_device); - pc_reset(); for (i = 0; i < CDROM_NUM; i++) { @@ -467,6 +456,17 @@ void resetpchard() { device_add(&BuslogicDevice); } + + sound_card_init(sound_card_current); + if (GUS) + device_add(&gus_device); + if (GAMEBLASTER) + device_add(&cms_device); + if (SSI2001) + device_add(&ssi2001_device); + if (voodoo_enabled) + device_add(&voodoo_device); + pc_reset(); loadnvr(); diff --git a/src/sound.c b/src/sound.c index f7c40af6b..e6b51d6d0 100644 --- a/src/sound.c +++ b/src/sound.c @@ -164,9 +164,11 @@ static void sound_cd_thread(void *param) /* Then, adjust input from drive according to ATAPI/SCSI volume. */ cd_buffer_temp[0] *= (float) audio_vol_l; - cd_buffer_temp[0] /= 255.0; + // cd_buffer_temp[0] /= 255.0; + cd_buffer_temp[0] /= 511.0; cd_buffer_temp[1] *= (float) audio_vol_r; - cd_buffer_temp[1] /= 255.0; + // cd_buffer_temp[1] /= 255.0; + cd_buffer_temp[1] /= 511.0; /*Apply ATAPI channel select*/ cd_buffer_temp2[0] = cd_buffer_temp2[1] = 0.0; @@ -229,11 +231,13 @@ void sound_init() if (available_cdrom_drives) { + // pclog("One or more CD-ROM drives are available, starting CD Audio thread...\n"); sound_cd_event = thread_create_event(); sound_cd_thread_h = thread_create(sound_cd_thread, NULL); } cd_thread_enable = available_cdrom_drives ? 1 : 0; + // pclog("cd_thread_enable = %i\n", cd_thread_enable); } void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) @@ -333,11 +337,13 @@ void sound_cd_thread_reset() if (available_cdrom_drives && !cd_thread_enable) { + // pclog("One or more CD-ROM drives are now available, but none was before, starting the CD Audio thread...\n"); sound_cd_event = thread_create_event(); sound_cd_thread_h = thread_create(sound_cd_thread, NULL); } else if (!available_cdrom_drives && cd_thread_enable) { + // pclog("No CD-ROM drives are now available, but one or more was before, killing the CD Audio thread...\n"); thread_destroy_event(sound_cd_event); thread_kill(sound_cd_thread_h); sound_cd_thread_h = NULL; diff --git a/src/sound_sb.c b/src/sound_sb.c index bb49d96d2..20baaa547 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -54,22 +54,22 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 13); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 13); + out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); + out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); if (sb->mixer.filter) { - out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 13; - out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 13; + out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; + out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; } else { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 13; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 13; + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 16; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; } - out_l = (out_l * mixer->master_l) >> 13; - out_r = (out_r * mixer->master_r) >> 13; + out_l = (out_l * mixer->master_l) >> 15; + out_r = (out_r * mixer->master_r) >> 15; if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { @@ -106,22 +106,22 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) // int c_emu8k = (((c/2) * 44100) / 48000)*2; int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 13); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 13); + out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); + out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); if (sb->mixer.filter) { - out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 13; - out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 13; + out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; + out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; } else { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 13; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 13; + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 16; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; } - out_l = (out_l * mixer->master_l) >> 13; - out_r = (out_r * mixer->master_r) >> 13; + out_l = (out_l * mixer->master_l) >> 15; + out_r = (out_r * mixer->master_r) >> 15; if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { @@ -160,25 +160,25 @@ static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) int c_emu8k = (((c/2) * 44100) / 48000)*2; int32_t out_l, out_r; - out_l = (((int32_t)sb->opl.buffer[c] * (int32_t)mixer->fm_l) >> 13); - out_r = (((int32_t)sb->opl.buffer[c + 1] * (int32_t)mixer->fm_r) >> 13); + out_l = (((int32_t)sb->opl.buffer[c] * (int32_t)mixer->fm_l) >> 16); + out_r = (((int32_t)sb->opl.buffer[c + 1] * (int32_t)mixer->fm_r) >> 16); - out_l += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 13); - out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_l) >> 13); + out_l += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 16); + out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_l) >> 16); if (sb->mixer.filter) { - out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 13; - out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 13; + out_l += (int)(((sb_iir(0, (float)sb->dsp.buffer[c]) / 1.3) * mixer->voice_l) / 3) >> 16; + out_r += (int)(((sb_iir(1, (float)sb->dsp.buffer[c + 1]) / 1.3) * mixer->voice_r) / 3) >> 16; } else { - out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 13; - out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 13; + out_l += ((int32_t)(sb->dsp.buffer[c] * mixer->voice_l) / 3) >> 16; + out_r += ((int32_t)(sb->dsp.buffer[c + 1] * mixer->voice_r) / 3) >> 16; } - out_l = (out_l * mixer->master_l) >> 13; - out_r = (out_r * mixer->master_r) >> 13; + out_l = (out_l * mixer->master_l) >> 15; + out_r = (out_r * mixer->master_r) >> 15; if (mixer->bass_l != 8 || mixer->bass_r != 8 || mixer->treble_l != 8 || mixer->treble_r != 8) { @@ -224,8 +224,8 @@ void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->filter = !(mixer->regs[0xe] & 0x20); mixer->bass_l = mixer->bass_r = 8; mixer->treble_l = mixer->treble_r = 8; - sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 8191, - ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 8191); + sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, + ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); // pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]); // pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); if (mixer->index == 0xe) @@ -299,8 +299,8 @@ void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->treble_l = mixer->regs[0x44] >> 4; mixer->treble_r = mixer->regs[0x45] >> 4; mixer->filter = 0; - sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 8191, - ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 8191); + sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, + ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); // pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]); // pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); } @@ -370,9 +370,12 @@ void sb_mixer_init(sb_mixer_t *mixer) mixer->master_l = mixer->master_r = 65535; mixer->voice_l = mixer->voice_r = 65535; mixer->fm_l = mixer->fm_r = 65535; + mixer->cd_l = mixer->cd_r = 65535; mixer->bass_l = mixer->bass_r = 8; mixer->treble_l = mixer->treble_r = 8; mixer->filter = 1; + sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, + ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); } void *sb_1_init() @@ -449,6 +452,7 @@ void *sb_pro_v1_init() sb->mixer.regs[0x22] = 0xff; sb->mixer.regs[0x04] = 0xff; sb->mixer.regs[0x26] = 0xff; + sb->mixer.regs[0x28] = 0xff; sb->mixer.regs[0xe] = 0; return sb; @@ -475,6 +479,7 @@ void *sb_pro_v2_init() sb->mixer.regs[0x22] = 0xff; sb->mixer.regs[0x04] = 0xff; sb->mixer.regs[0x26] = 0xff; + sb->mixer.regs[0x28] = 0xff; sb->mixer.regs[0xe] = 0; return sb; @@ -506,6 +511,8 @@ void *sb_16_init() sb->mixer.regs[0x33] = 31 << 3; sb->mixer.regs[0x34] = 31 << 3; sb->mixer.regs[0x35] = 31 << 3; + sb->mixer.regs[0x36] = 31 << 3; + sb->mixer.regs[0x37] = 31 << 3; sb->mixer.regs[0x44] = 8 << 4; sb->mixer.regs[0x45] = 8 << 4; sb->mixer.regs[0x46] = 8 << 4; @@ -513,6 +520,7 @@ void *sb_16_init() sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4); sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4); sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4); + sb->mixer.regs[0x28] = (sb->mixer.regs[0x36] & 0xf0) | (sb->mixer.regs[0x37] >> 4); return sb; } @@ -550,6 +558,8 @@ void *sb_awe32_init() sb->mixer.regs[0x33] = 31 << 3; sb->mixer.regs[0x34] = 31 << 3; sb->mixer.regs[0x35] = 31 << 3; + sb->mixer.regs[0x36] = 31 << 3; + sb->mixer.regs[0x37] = 31 << 3; sb->mixer.regs[0x44] = 8 << 4; sb->mixer.regs[0x45] = 8 << 4; sb->mixer.regs[0x46] = 8 << 4; @@ -557,6 +567,7 @@ void *sb_awe32_init() sb->mixer.regs[0x22] = (sb->mixer.regs[0x30] & 0xf0) | (sb->mixer.regs[0x31] >> 4); sb->mixer.regs[0x04] = (sb->mixer.regs[0x32] & 0xf0) | (sb->mixer.regs[0x33] >> 4); sb->mixer.regs[0x26] = (sb->mixer.regs[0x34] & 0xf0) | (sb->mixer.regs[0x35] >> 4); + sb->mixer.regs[0x28] = (sb->mixer.regs[0x36] & 0xf0) | (sb->mixer.regs[0x37] >> 4); return sb; } @@ -760,6 +771,14 @@ static device_config_t sb_16_config[] = .description = "0x240", .value = 0x240 }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "0x280", + .value = 0x280 + }, { .description = "" } @@ -891,6 +910,14 @@ static device_config_t sb_awe32_config[] = .description = "0x240", .value = 0x240 }, + { + .description = "0x260", + .value = 0x260 + }, + { + .description = "0x280", + .value = 0x280 + }, { .description = "" } From c8c49ac216becf1d026cadd09c4c6053b478a2d6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 7 Feb 2017 02:19:48 +0100 Subject: [PATCH 063/392] Reworked serial and LPT set up - they can now bet set to any I/O base address (though that capability is not used by anything yet); The CD-ROM IOCTL direct pass through code now does sanity check on the requested data size before passing the command - fixes crashes with some DMA-only host DVD drives; The network poller is now in its own thread; The hack is back in the emulation of the National Semiconductors PC87306 Super I/O Chip - it's the only way right now to have serial working on that board; Fixed a part of the code that was still using NukedOPL even when OPL 3 was set to DOSBox OPL; Applied all mainline PCem commits. --- src/Makefile.mingw | 2 +- src/cdrom-ioctl.c | 30 +- src/cdrom.c | 76 +- src/lpt.c | 14 +- src/ne2000.c | 3454 +++++++++++++++---------------- src/nethandler.c | 85 +- src/pc.c | 4 + src/pc87306.c | 54 +- src/serial.c | 35 +- src/sound_dbopl.cc | 20 +- src/vid_voodoo.c | 68 +- src/vid_voodoo_codegen_x86-64.h | 8 +- src/vid_voodoo_codegen_x86.h | 11 +- src/x86seg.c | 12 +- 14 files changed, 1990 insertions(+), 1883 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ffe7582f5..3b3c23cf8 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static +LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lwpcap 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 8cf8e94a3..f922dea9a 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -42,14 +42,14 @@ int cdrom_ioctl_do_log = 0; void cdrom_ioctl_log(const char *format, ...) { #ifdef ENABLE_CDROM_LOG - if (cdrom_ioctl_do_log) - { + if (cdrom_ioctl_do_log) + { va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); fflush(stdout); - } + } #endif } @@ -534,11 +534,33 @@ static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_bl if (no_length_check) { - return 65534; + switch (cdb[0]) + { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); + default: + return 65534; + } } switch (cdb[0]) { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); case 0x08: case 0x28: case 0xa8: diff --git a/src/cdrom.c b/src/cdrom.c index 20068125f..a71ba8b60 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -212,14 +212,14 @@ int cdrom_do_log = 0; void cdrom_log(const char *format, ...) { #ifdef ENABLE_CDROM_LOG - if (cdrom_do_log) - { + if (cdrom_do_log) + { va_list ap; va_start(ap, format); vprintf(format, ap); va_end(ap); fflush(stdout); - } + } #endif } @@ -1857,6 +1857,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_READ_TOC_PMA_ATIP: cdrom[id].toctimes++; + max_len = cdb[7]; + max_len <<= 8; + max_len |= cdb[8]; + if (cdrom_drives[id].handler->pass_through) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); @@ -1864,19 +1868,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - - if (len == 65534) + alloc_length = cdbufferb[0]; + alloc_length <<= 8; + alloc_length |= cdbufferb[1]; + alloc_length += 2; + if (alloc_length < len) { - max_len = cdb[8] + (cdb[7] << 8); - len = cdbufferb[0] + (cdbufferb[1] << 8); - len += 2; - if (max_len < len) - { - max_len -= 2; - cdbufferb[0] = max_len >> 8; - cdbufferb[1] = max_len & 0xff; - len = max_len + 2; - } + len = alloc_length; } } else @@ -2238,11 +2236,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - if (len == 65534) + alloc_length = cdbufferb[0]; + alloc_length <<= 8; + alloc_length |= cdbufferb[1]; + alloc_length += 2; + if (alloc_length < len) { - cdbufferb[0] = 0; - cdbufferb[1] = 32; - len = 34; + len = alloc_length; } } else @@ -2278,12 +2278,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - - if (len == 65534) + alloc_length = cdbufferb[0]; + alloc_length <<= 8; + alloc_length |= cdbufferb[1]; + alloc_length += 2; + if (alloc_length < len) { - cdbufferb[0] = 0; - cdbufferb[1] = 34; - len = 36; + len = alloc_length; } } else @@ -2400,20 +2401,21 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[1] = 0x13; break; } - if (len == 65534) + switch(cdb[3]) { - switch(cdb[3]) - { - case 0: - len = 4; - break; - case 1: - len = 16; - break; - default: - len = 24; - break; - } + case 0: + alloc_length = 4; + break; + case 1: + alloc_length = 16; + break; + default: + alloc_length = 24; + break; + } + if (alloc_length < len) + { + len = alloc_length; } } else diff --git a/src/lpt.c b/src/lpt.c index 251c56a4a..1d29b7d9a 100644 --- a/src/lpt.c +++ b/src/lpt.c @@ -65,31 +65,33 @@ uint8_t lpt2_read(uint16_t port, void *priv) return 0xff; } +uint16_t lpt_addr[2] = { 0x378, 0x278 }; + void lpt_init() { io_sethandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); io_sethandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + lpt_addr[0] = 0x378; + lpt_addr[1] = 0x378; } void lpt1_init(uint16_t port) { io_sethandler(port, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + lpt_addr[0] = port; } void lpt1_remove() { - io_removehandler(0x0278, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_removehandler(0x0378, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); - io_removehandler(0x03bc, 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); + io_removehandler(lpt_addr[0], 0x0003, lpt1_read, NULL, NULL, lpt1_write, NULL, NULL, NULL); } void lpt2_init(uint16_t port) { io_sethandler(port, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + lpt_addr[1] = port; } void lpt2_remove() { - io_removehandler(0x0278, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - io_removehandler(0x0378, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); - io_removehandler(0x03bc, 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); + io_removehandler(lpt_addr[1], 0x0003, lpt2_read, NULL, NULL, lpt2_write, NULL, NULL, NULL); } void lpt2_remove_ams() diff --git a/src/ne2000.c b/src/ne2000.c index 3694a06e7..ec5140559 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -48,32 +48,10 @@ uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; #define NETBLOCKING 0 //we won't block our pcap -static HINSTANCE net_hLib = 0; /* handle to DLL */ -static char* net_lib_name = "wpcap.dll"; pcap_t *net_pcap; -typedef pcap_t* (__cdecl * PCAP_OPEN_LIVE)(const char *, int, int, int, char *); -typedef int (__cdecl * PCAP_SENDPACKET)(pcap_t* handle, const u_char* msg, int len); -typedef int (__cdecl * PCAP_SETNONBLOCK)(pcap_t *, int, char *); -typedef const u_char*(__cdecl *PCAP_NEXT)(pcap_t *, struct pcap_pkthdr *); -typedef const char*(__cdecl *PCAP_LIB_VERSION)(void); -typedef void (__cdecl *PCAP_CLOSE)(pcap_t *); -typedef int (__cdecl *PCAP_GETNONBLOCK)(pcap_t *p, char *errbuf); -typedef int (__cdecl *PCAP_COMPILE)(pcap_t *p, struct bpf_program *fp, const char *str, int optimize, bpf_u_int32 netmask); -typedef int (__cdecl *PCAP_SETFILTER)(pcap_t *p, struct bpf_program *fp); - -PCAP_LIB_VERSION _pcap_lib_version; -PCAP_OPEN_LIVE _pcap_open_live; -PCAP_SENDPACKET _pcap_sendpacket; -PCAP_SETNONBLOCK _pcap_setnonblock; -PCAP_NEXT _pcap_next; -PCAP_CLOSE _pcap_close; -PCAP_GETNONBLOCK _pcap_getnonblock; -PCAP_COMPILE _pcap_compile; -PCAP_SETFILTER _pcap_setfilter; queueADT slirpq; int net_slirp_inited=0; -int net_is_slirp=1; //by default we go with slirp int net_is_pcap=0; //and pretend pcap is dead. int fizz=0; void slirp_tic(); @@ -93,150 +71,158 @@ uint8_t rtl8029as_eeprom[128]; typedef struct ne2000_t { - // - // ne2k register state + // + // ne2k register state - // - // Page 0 - // - // Command Register - 00h read/write - struct CR_t { - int stop; // STP - Software Reset command - int start; // START - start the NIC - int tx_packet; // TXP - initiate packet transmission - uint8_t rdma_cmd; // RD0,RD1,RD2 - Remote DMA command - uint8_t pgsel; // PS0,PS1 - Page select - } CR; - // Interrupt Status Register - 07h read/write - struct ISR_t { - int pkt_rx; // PRX - packet received with no errors - int pkt_tx; // PTX - packet transmitted with no errors - int rx_err; // RXE - packet received with 1 or more errors - int tx_err; // TXE - packet tx'd " " " " " - int overwrite; // OVW - rx buffer resources exhausted - int cnt_oflow; // CNT - network tally counter MSB's set - int rdma_done; // RDC - remote DMA complete - int reset; // RST - reset status - } ISR; - // Interrupt Mask Register - 0fh write - struct IMR_t { - int rx_inte; // PRXE - packet rx interrupt enable - int tx_inte; // PTXE - packet tx interrput enable - int rxerr_inte; // RXEE - rx error interrupt enable - int txerr_inte; // TXEE - tx error interrupt enable - int overw_inte; // OVWE - overwrite warn int enable - int cofl_inte; // CNTE - counter o'flow int enable - int rdma_inte; // RDCE - remote DMA complete int enable - int reserved; // D7 - reserved - } IMR; - // Data Configuration Register - 0eh write - struct DCR_t { - int wdsize; // WTS - 8/16-bit select - int endian; // BOS - byte-order select - int longaddr; // LAS - long-address select - int loop; // LS - loopback select - int auto_rx; // AR - auto-remove rx packets with remote DMA - uint8_t fifo_size; // FT0,FT1 - fifo threshold - } DCR; - // Transmit Configuration Register - 0dh write - struct TCR_t { - int crc_disable; // CRC - inhibit tx CRC - uint8_t loop_cntl; // LB0,LB1 - loopback control - int ext_stoptx; // ATD - allow tx disable by external mcast - int coll_prio; // OFST - backoff algorithm select - uint8_t reserved; // D5,D6,D7 - reserved - } TCR; - // Transmit Status Register - 04h read - struct TSR_t { - int tx_ok; // PTX - tx complete without error - int reserved; // D1 - reserved - int collided; // COL - tx collided >= 1 times - int aborted; // ABT - aborted due to excessive collisions - int no_carrier; // CRS - carrier-sense lost - int fifo_ur; // FU - FIFO underrun - int cd_hbeat; // CDH - no tx cd-heartbeat from transceiver - int ow_coll; // OWC - out-of-window collision - } TSR; - // Receive Configuration Register - 0ch write - struct RCR_t { - int errors_ok; // SEP - accept pkts with rx errors - int runts_ok; // AR - accept < 64-byte runts - int broadcast; // AB - accept eth broadcast address - int multicast; // AM - check mcast hash array - int promisc; // PRO - accept all packets - int monitor; // MON - check pkts, but don't rx - uint8_t reserved; // D6,D7 - reserved - } RCR; - // Receive Status Register - 0ch read - struct RSR_t { - int rx_ok; // PRX - rx complete without error - int bad_crc; // CRC - Bad CRC detected - int bad_falign; // FAE - frame alignment error - int fifo_or; // FO - FIFO overrun - int rx_missed; // MPA - missed packet error - int rx_mbit; // PHY - unicast or mcast/bcast address match - int rx_disabled; // DIS - set when in monitor mode - int deferred; // DFR - collision active - } RSR; + // + // Page 0 + // + // Command Register - 00h read/write + struct CR_t + { + int stop; // STP - Software Reset command + int start; // START - start the NIC + int tx_packet; // TXP - initiate packet transmission + uint8_t rdma_cmd; // RD0,RD1,RD2 - Remote DMA command + uint8_t pgsel; // PS0,PS1 - Page select + } CR; + // Interrupt Status Register - 07h read/write + struct ISR_t + { + int pkt_rx; // PRX - packet received with no errors + int pkt_tx; // PTX - packet transmitted with no errors + int rx_err; // RXE - packet received with 1 or more errors + int tx_err; // TXE - packet tx'd " " " " " + int overwrite; // OVW - rx buffer resources exhausted + int cnt_oflow; // CNT - network tally counter MSB's set + int rdma_done; // RDC - remote DMA complete + int reset; // RST - reset status + } ISR; + // Interrupt Mask Register - 0fh write + struct IMR_t + { + int rx_inte; // PRXE - packet rx interrupt enable + int tx_inte; // PTXE - packet tx interrput enable + int rxerr_inte; // RXEE - rx error interrupt enable + int txerr_inte; // TXEE - tx error interrupt enable + int overw_inte; // OVWE - overwrite warn int enable + int cofl_inte; // CNTE - counter o'flow int enable + int rdma_inte; // RDCE - remote DMA complete int enable + int reserved; // D7 - reserved + } IMR; + // Data Configuration Register - 0eh write + struct DCR_t + { + int wdsize; // WTS - 8/16-bit select + int endian; // BOS - byte-order select + int longaddr; // LAS - long-address select + int loop; // LS - loopback select + int auto_rx; // AR - auto-remove rx packets with remote DMA + uint8_t fifo_size; // FT0,FT1 - fifo threshold + } DCR; + // Transmit Configuration Register - 0dh write + struct TCR_t + { + int crc_disable; // CRC - inhibit tx CRC + uint8_t loop_cntl; // LB0,LB1 - loopback control + int ext_stoptx; // ATD - allow tx disable by external mcast + int coll_prio; // OFST - backoff algorithm select + uint8_t reserved; // D5,D6,D7 - reserved + } TCR; + // Transmit Status Register - 04h read + struct TSR_t + { + int tx_ok; // PTX - tx complete without error + int reserved; // D1 - reserved + int collided; // COL - tx collided >= 1 times + int aborted; // ABT - aborted due to excessive collisions + int no_carrier; // CRS - carrier-sense lost + int fifo_ur; // FU - FIFO underrun + int cd_hbeat; // CDH - no tx cd-heartbeat from transceiver + int ow_coll; // OWC - out-of-window collision + } TSR; + // Receive Configuration Register - 0ch write + struct RCR_t + { + int errors_ok; // SEP - accept pkts with rx errors + int runts_ok; // AR - accept < 64-byte runts + int broadcast; // AB - accept eth broadcast address + int multicast; // AM - check mcast hash array + int promisc; // PRO - accept all packets + int monitor; // MON - check pkts, but don't rx + uint8_t reserved; // D6,D7 - reserved + } RCR; + // Receive Status Register - 0ch read + struct RSR_t + { + int rx_ok; // PRX - rx complete without error + int bad_crc; // CRC - Bad CRC detected + int bad_falign; // FAE - frame alignment error + int fifo_or; // FO - FIFO overrun + int rx_missed; // MPA - missed packet error + int rx_mbit; // PHY - unicast or mcast/bcast address match + int rx_disabled; // DIS - set when in monitor mode + int deferred; // DFR - collision active + } RSR; - uint16_t local_dma; // 01,02h read ; current local DMA addr - uint8_t page_start; // 01h write ; page start register - uint8_t page_stop; // 02h write ; page stop register - uint8_t bound_ptr; // 03h read/write ; boundary pointer - uint8_t tx_page_start; // 04h write ; transmit page start register - uint8_t num_coll; // 05h read ; number-of-collisions register - uint16_t tx_bytes; // 05,06h write ; transmit byte-count register - uint8_t fifo; // 06h read ; FIFO - uint16_t remote_dma; // 08,09h read ; current remote DMA addr - uint16_t remote_start; // 08,09h write ; remote start address register - uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register - uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) - uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) - uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) + uint16_t local_dma; // 01,02h read ; current local DMA addr + uint8_t page_start; // 01h write ; page start register + uint8_t page_stop; // 02h write ; page stop register + uint8_t bound_ptr; // 03h read/write ; boundary pointer + uint8_t tx_page_start; // 04h write ; transmit page start register + uint8_t num_coll; // 05h read ; number-of-collisions register + uint16_t tx_bytes; // 05,06h write ; transmit byte-count register + uint8_t fifo; // 06h read ; FIFO + uint16_t remote_dma; // 08,09h read ; current remote DMA addr + uint16_t remote_start; // 08,09h write ; remote start address register + uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register + uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) + uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) + uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) - // - // Page 1 - // - // Command Register 00h (repeated) - // - uint8_t physaddr[6]; // 01-06h read/write ; MAC address - uint8_t curr_page; // 07h read/write ; current page register - uint8_t mchash[8]; // 08-0fh read/write ; multicast hash array + // + // Page 1 + // + // Command Register 00h (repeated) + // + uint8_t physaddr[6]; // 01-06h read/write ; MAC address + uint8_t curr_page; // 07h read/write ; current page register + uint8_t mchash[8]; // 08-0fh read/write ; multicast hash array - // - // Page 2 - diagnostic use only - // - // Command Register 00h (repeated) - // - // Page Start Register 01h read (repeated) - // Page Stop Register 02h read (repeated) - // Current Local DMA Address 01,02h write (repeated) - // Transmit Page start address 04h read (repeated) - // Receive Configuration Register 0ch read (repeated) - // Transmit Configuration Register 0dh read (repeated) - // Data Configuration Register 0eh read (repeated) - // Interrupt Mask Register 0fh read (repeated) - // - uint8_t rempkt_ptr; // 03h read/write ; remote next-packet pointer - uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer - uint16_t address_cnt; // 06,07h read/write ; address counter + // + // Page 2 - diagnostic use only + // + // Command Register 00h (repeated) + // + // Page Start Register 01h read (repeated) + // Page Stop Register 02h read (repeated) + // Current Local DMA Address 01,02h write (repeated) + // Transmit Page start address 04h read (repeated) + // Receive Configuration Register 0ch read (repeated) + // Transmit Configuration Register 0dh read (repeated) + // Data Configuration Register 0eh read (repeated) + // Interrupt Mask Register 0fh read (repeated) + // + uint8_t rempkt_ptr; // 03h read/write ; remote next-packet pointer + uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer + uint16_t address_cnt; // 06,07h read/write ; address counter - // - // Page 3 - should never be modified. - // + // + // Page 3 - should never be modified. + // - // Novell ASIC state - uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes - uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory + // Novell ASIC state + uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes + uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory - // ne2k internal state - uint32_t base_address; - int base_irq; - int tx_timer_index; - int tx_timer_active; + // ne2k internal state + uint32_t base_address; + int base_irq; + int tx_timer_index; + int tx_timer_active; + + rom_t bios_rom; - rom_t bios_rom; - } ne2000_t; int disable_netbios = 0; @@ -251,92 +237,92 @@ int ne2000_do_log = 0; void ne2000_log(const char *format, ...) { #ifdef ENABLE_NE2000_LOG - if (ne2000_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } + if (ne2000_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } #endif } static void ne2000_setirq(ne2000_t *ne2000, int irq) { - ne2000->base_irq = irq; + ne2000->base_irq = irq; } + // // reset - restore state to power-up, cancelling all i/o // static void ne2000_reset(void *p, int reset) { - ne2000_t *ne2000 = (ne2000_t *)p; - int i; + ne2000_t *ne2000 = (ne2000_t *)p; + int i; - ne2000_log("ne2000 reset\n"); + ne2000_log("ne2000 reset\n"); - // Initialise the mac address area by doubling the physical address - ne2000->macaddr[0] = ne2000->physaddr[0]; - ne2000->macaddr[1] = ne2000->physaddr[0]; - ne2000->macaddr[2] = ne2000->physaddr[1]; - ne2000->macaddr[3] = ne2000->physaddr[1]; - ne2000->macaddr[4] = ne2000->physaddr[2]; - ne2000->macaddr[5] = ne2000->physaddr[2]; - ne2000->macaddr[6] = ne2000->physaddr[3]; - ne2000->macaddr[7] = ne2000->physaddr[3]; - ne2000->macaddr[8] = ne2000->physaddr[4]; - ne2000->macaddr[9] = ne2000->physaddr[4]; - ne2000->macaddr[10] = ne2000->physaddr[5]; - ne2000->macaddr[11] = ne2000->physaddr[5]; + // Initialise the mac address area by doubling the physical address + ne2000->macaddr[0] = ne2000->physaddr[0]; + ne2000->macaddr[1] = ne2000->physaddr[0]; + ne2000->macaddr[2] = ne2000->physaddr[1]; + ne2000->macaddr[3] = ne2000->physaddr[1]; + ne2000->macaddr[4] = ne2000->physaddr[2]; + ne2000->macaddr[5] = ne2000->physaddr[2]; + ne2000->macaddr[6] = ne2000->physaddr[3]; + ne2000->macaddr[7] = ne2000->physaddr[3]; + ne2000->macaddr[8] = ne2000->physaddr[4]; + ne2000->macaddr[9] = ne2000->physaddr[4]; + ne2000->macaddr[10] = ne2000->physaddr[5]; + ne2000->macaddr[11] = ne2000->physaddr[5]; - // ne2k signature - for (i = 12; i < 32; i++) - ne2000->macaddr[i] = 0x57; + // ne2k signature + for (i = 12; i < 32; i++) + { + ne2000->macaddr[i] = 0x57; + } - // Zero out registers and memory - memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); - memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); - memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); - memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); - memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); - memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); - //memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); - memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); - ne2000->tx_timer_active = 0; - ne2000->local_dma = 0; - ne2000->page_start = 0; - ne2000->page_stop = 0; - ne2000->bound_ptr = 0; - ne2000->tx_page_start = 0; - ne2000->num_coll = 0; - ne2000->tx_bytes = 0; - ne2000->fifo = 0; - ne2000->remote_dma = 0; - ne2000->remote_start = 0; - ne2000->remote_bytes = 0; - ne2000->tallycnt_0 = 0; - ne2000->tallycnt_1 = 0; - ne2000->tallycnt_2 = 0; + // Zero out registers and memory + memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); + memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); + memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); + memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); + memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); + memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); + // memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); + memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); + ne2000->tx_timer_active = 0; + ne2000->local_dma = 0; + ne2000->page_start = 0; + ne2000->page_stop = 0; + ne2000->bound_ptr = 0; + ne2000->tx_page_start = 0; + ne2000->num_coll = 0; + ne2000->tx_bytes = 0; + ne2000->fifo = 0; + ne2000->remote_dma = 0; + ne2000->remote_start = 0; + ne2000->remote_bytes = 0; + ne2000->tallycnt_0 = 0; + ne2000->tallycnt_1 = 0; + ne2000->tallycnt_2 = 0; - //memset( & ne2000->physaddr, 0, sizeof(ne2000->physaddr)); - //memset( & ne2000->mchash, 0, sizeof(ne2000->mchash)); - ne2000->curr_page = 0; + ne2000->curr_page = 0; - ne2000->rempkt_ptr = 0; - ne2000->localpkt_ptr = 0; - ne2000->address_cnt = 0; + ne2000->rempkt_ptr = 0; + ne2000->localpkt_ptr = 0; + ne2000->address_cnt = 0; - memset( & ne2000->mem, 0, sizeof(ne2000->mem)); + memset( & ne2000->mem, 0, sizeof(ne2000->mem)); - // Set power-up conditions - ne2000->CR.stop = 1; - ne2000->CR.rdma_cmd = 4; - ne2000->ISR.reset = 1; - ne2000->DCR.longaddr = 1; - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); - //DEV_pic_lower_irq(ne2000->base_irq); + // Set power-up conditions + ne2000->CR.stop = 1; + ne2000->CR.rdma_cmd = 4; + ne2000->ISR.reset = 1; + ne2000->DCR.longaddr = 1; + picint(1 << ne2000->base_irq); + picintc(1 << ne2000->base_irq); } #include "bswap.h" @@ -349,11 +335,11 @@ uint32_t ne2000_read_cr(ne2000_t *ne2000) { uint32_t val; - val = (((ne2000->CR.pgsel & 0x03) << 6) | - ((ne2000->CR.rdma_cmd & 0x07) << 3) | - (ne2000->CR.tx_packet << 2) | - (ne2000->CR.start << 1) | - (ne2000->CR.stop)); + val = (((ne2000->CR.pgsel & 0x03) << 6) | + ((ne2000->CR.rdma_cmd & 0x07) << 3) | + (ne2000->CR.tx_packet << 2) | + (ne2000->CR.start << 1) | + (ne2000->CR.stop)); ne2000_log("%s: read CR returns 0x%02x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); return val; } @@ -363,13 +349,15 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000_log("%s: wrote 0x%02x to CR\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", value); // Validate remote-DMA - if ((value & 0x38) == 0x00) { + if ((value & 0x38) == 0x00) + { ne2000_log("CR write - invalid rDMA value 0\n"); value |= 0x20; /* dma_cmd == 4 is a safe default */ } // Check for s/w reset - if (value & 0x01) { + if (value & 0x01) + { ne2000->ISR.reset = 1; ne2000->CR.stop = 1; } else { @@ -380,7 +368,8 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) // If start command issued, the RST bit in the ISR // must be cleared - if ((value & 0x02) && !ne2000->CR.start) { + if ((value & 0x02) && !ne2000->CR.start) + { ne2000->ISR.reset = 0; } @@ -388,7 +377,8 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000->CR.pgsel = (value & 0xc0) >> 6; // Check for send-packet command - if (ne2000->CR.rdma_cmd == 3) { + if (ne2000->CR.rdma_cmd == 3) + { // Set up DMA read from receive ring ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; ne2000->remote_bytes = (uint16_t) ne2000_chipmem_read(ne2000, ne2000->bound_ptr * 256 + 2, 2); @@ -396,52 +386,66 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) } // Check for start-tx - if ((value & 0x04) && ne2000->TCR.loop_cntl) { - if (ne2000->TCR.loop_cntl != 1) { - ne2000_log("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } else { - ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], - ne2000->tx_bytes); + if ((value & 0x04) && ne2000->TCR.loop_cntl) + { + if (ne2000->TCR.loop_cntl != 1) + { + ne2000_log("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); } - } else if (value & 0x04) { - if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) { - if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ - return; /* Solaris9 probe */ - ne2000_log("CR write - tx start, dev in reset\n"); + else + { + ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + } + } + else if (value & 0x04) + { + if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) + { + if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ + { + return; /* Solaris9 probe */ + } + ne2000_log("CR write - tx start, dev in reset\n"); } if (ne2000->tx_bytes == 0) + { ne2000_log("CR write - tx start, tx bytes == 0\n"); + } // Send the packet to the system driver ne2000->CR.tx_packet = 1; - if(net_is_slirp) + if(!net_is_pcap) { slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); ne2000_log("ne2000 slirp sending packet\n"); } - if(net_is_pcap && net_pcap!=NULL) + else if (net_is_pcap && (net_pcap != NULL)) { - _pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); + pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); ne2000_log("ne2000 pcap sending packet\n"); } // some more debug if (ne2000->tx_timer_active) - ne2000_log("CR write, tx timer still active\n"); + { + ne2000_log("CR write, tx timer still active\n"); + } ne2000_tx_event(ne2000, value); - } + } // Linux probes for an interrupt by setting up a remote-DMA read // of 0 bytes with remote-DMA completion interrupts enabled. // Detect this here if (ne2000->CR.rdma_cmd == 0x01 && ne2000->CR.start && - ne2000->remote_bytes == 0) { + ne2000->remote_bytes == 0) + { ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); + if (ne2000->IMR.rdma_inte) + { + picint(1 << ne2000->base_irq); } } } @@ -457,57 +461,73 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len) { - uint32_t retval = 0; + uint32_t retval = 0; - if ((io_len == 2) && (address & 0x1)) - ne2000_log("unaligned chipmem word read\n"); + if ((io_len == 2) && (address & 0x1)) + { + ne2000_log("unaligned chipmem word read\n"); + } - // ROM'd MAC address - if ((address >=0) && (address <= 31)) { - retval = ne2000->macaddr[address % 32]; - if ((io_len == 2) || (io_len == 4)) { - retval |= (ne2000->macaddr[(address + 1) % 32] << 8); - } - if (io_len == 4) { - retval |= (ne2000->macaddr[(address + 2) % 32] << 16); - retval |= (ne2000->macaddr[(address + 3) % 32] << 24); - } - return (retval); - } + // ROM'd MAC address + if ((address >=0) && (address <= 31)) + { + retval = ne2000->macaddr[address % 32]; + if ((io_len == 2) || (io_len == 4)) + { + retval |= (ne2000->macaddr[(address + 1) % 32] << 8); + } + if (io_len == 4) + { + retval |= (ne2000->macaddr[(address + 2) % 32] << 16); + retval |= (ne2000->macaddr[(address + 3) % 32] << 24); + } + return (retval); + } - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - retval = ne2000->mem[address - BX_NE2K_MEMSTART]; - if ((io_len == 2) || (io_len == 4)) { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); - } - if (io_len == 4) { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); - } - return (retval); - } + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + { + retval = ne2000->mem[address - BX_NE2K_MEMSTART]; + if ((io_len == 2) || (io_len == 4)) + { + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); + } + if (io_len == 4) + { + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); + retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); + } + return (retval); + } - ne2000_log("out-of-bounds chipmem read, %04X\n", address); + ne2000_log("out-of-bounds chipmem read, %04X\n", address); - return (0xff); + return (0xff); } void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) { - if ((io_len == 2) && (address & 0x1)) - ne2000_log("unaligned chipmem word write\n"); + if ((io_len == 2) && (address & 0x1)) + { + ne2000_log("unaligned chipmem word write\n"); + } - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) { - ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; - if ((io_len == 2) || (io_len == 4)) { - ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; - } - if (io_len == 4) { - ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; - ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; - } - } else - ne2000_log("out-of-bounds chipmem write, %04X\n", address); + if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) + { + ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; + if ((io_len == 2) || (io_len == 4)) + { + ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; + } + if (io_len == 4) + { + ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; + ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; + } + } + else + { + ne2000_log("out-of-bounds chipmem write, %04X\n", address); + } } // @@ -522,115 +542,146 @@ void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, un // uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - uint32_t retval = 0; + uint32_t retval = 0; - switch (offset) { - case 0x0: // Data register - // - // A read remote-DMA command must have been issued, - // and the source-address and length registers must - // have been initialised. - // - if (io_len > ne2000->remote_bytes) { - ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); - //return 0; - } + switch (offset) + { + case 0x0: // Data register + // + // A read remote-DMA command must have been issued, + // and the source-address and length registers must + // have been initialised. + // + if (io_len > ne2000->remote_bytes) + { + ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); + } - ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); - retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); - // - // The 8390 bumps the address and decreases the byte count - // by the selected word size after every access, not by - // the amount of data requested by the host (io_len). - // - if (io_len == 4) { - ne2000->remote_dma += io_len; - } else { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - if (ne2000->remote_dma == ne2000->page_stop << 8) { - ne2000->remote_dma = ne2000->page_start << 8; - } - // keep s.remote_bytes from underflowing - if (ne2000->remote_bytes > ne2000->DCR.wdsize) - if (io_len == 4) { - ne2000->remote_bytes -= io_len; - } else { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - else - ne2000->remote_bytes = 0; + ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); + retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); + // + // The 8390 bumps the address and decreases the byte count + // by the selected word size after every access, not by + // the amount of data requested by the host (io_len). + // + if (io_len == 4) + { + ne2000->remote_dma += io_len; + } + else + { + ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + } - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - } - } - break; + if (ne2000->remote_dma == ne2000->page_stop << 8) + { + ne2000->remote_dma = ne2000->page_start << 8; + } - case 0xf: // Reset register - ne2000_reset(ne2000, BX_RESET_SOFTWARE); - break; + // keep s.remote_bytes from underflowing + if (ne2000->remote_bytes > ne2000->DCR.wdsize) + { + if (io_len == 4) + { + ne2000->remote_bytes -= io_len; + } + else + { + ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); + } + } + else + { + ne2000->remote_bytes = 0; + } - default: - ne2000_log("asic read invalid address %04x\n", (unsigned) offset); - break; - } + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) + { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) + { + picint(1 << ne2000->base_irq); + } + } + break; - return (retval); + case 0xf: // Reset register + ne2000_reset(ne2000, BX_RESET_SOFTWARE); + break; + + default: + ne2000_log("asic read invalid address %04x\n", (unsigned) offset); + break; + } + + return (retval); } void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); - switch (offset) { - case 0x0: // Data register - see asic_read for a description + ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); + switch (offset) + { + case 0x0: // Data register - see asic_read for a description + if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) + { + ne2000_log("dma write length %d on byte mode operation\n", io_len); + break; + } + if (ne2000->remote_bytes == 0) + { + ne2000_log("dma write, byte count 0\n"); + } - if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) { - ne2000_log("dma write length %d on byte mode operation\n", io_len); - break; - } - if (ne2000->remote_bytes == 0) { - ne2000_log("dma write, byte count 0\n"); - } + ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); + if (io_len == 4) + { + ne2000->remote_dma += io_len; + } + else + { + ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + } - ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); - if (io_len == 4) { - ne2000->remote_dma += io_len; - } else { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - if (ne2000->remote_dma == ne2000->page_stop << 8) { - ne2000->remote_dma = ne2000->page_start << 8; - } + if (ne2000->remote_dma == ne2000->page_stop << 8) + { + ne2000->remote_dma = ne2000->page_start << 8; + } - if (io_len == 4) { - ne2000->remote_bytes -= io_len; - } else { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) - ne2000->remote_bytes = 0; + if (io_len == 4) + { + ne2000->remote_bytes -= io_len; + } + else + { + ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); + } - // If all bytes have been written, signal remote-DMA complete - if (ne2000->remote_bytes == 0) { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) { - picint(1 << ne2000->base_irq); - } - } - break; + if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) + { + ne2000->remote_bytes = 0; + } - case 0xf: // Reset register - // end of reset pulse - break; + // If all bytes have been written, signal remote-DMA complete + if (ne2000->remote_bytes == 0) + { + ne2000->ISR.rdma_done = 1; + if (ne2000->IMR.rdma_inte) + { + picint(1 << ne2000->base_irq); + } + } + break; - default: // this is invalid, but happens under win95 device detection - ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); - break; - } + case 0xf: // Reset register + // end of reset pulse + break; + + default: // this is invalid, but happens under win95 device detection + ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); + break; + } } // @@ -639,311 +690,346 @@ void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsign // uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - uint8_t value = 0; + uint8_t value = 0; - if (io_len > 1) { - ne2000_log("bad length! page 0 read from register 0x%02x, len=%u\n", offset, - io_len); /* encountered with win98 hardware probe */ - return value; - } + if (io_len > 1) + { + ne2000_log("bad length! page 0 read from register 0x%02x, len=%u\n", offset, io_len); /* encountered with win98 hardware probe */ + return value; + } - switch (offset) { - case 0x1: // CLDA0 - value = (ne2000->local_dma & 0xff); - break; + switch (offset) + { + case 0x1: // CLDA0 + value = (ne2000->local_dma & 0xff); + break; - case 0x2: // CLDA1 - value = (ne2000->local_dma >> 8); - break; + case 0x2: // CLDA1 + value = (ne2000->local_dma >> 8); + break; - case 0x3: // BNRY - value = ne2000->bound_ptr; - break; + case 0x3: // BNRY + value = ne2000->bound_ptr; + break; - case 0x4: // TSR - value = ((ne2000->TSR.ow_coll << 7) | - (ne2000->TSR.cd_hbeat << 6) | - (ne2000->TSR.fifo_ur << 5) | - (ne2000->TSR.no_carrier << 4) | - (ne2000->TSR.aborted << 3) | - (ne2000->TSR.collided << 2) | - (ne2000->TSR.tx_ok)); - break; + case 0x4: // TSR + value = ((ne2000->TSR.ow_coll << 7) | + (ne2000->TSR.cd_hbeat << 6) | + (ne2000->TSR.fifo_ur << 5) | + (ne2000->TSR.no_carrier << 4) | + (ne2000->TSR.aborted << 3) | + (ne2000->TSR.collided << 2) | + (ne2000->TSR.tx_ok)); + break; - case 0x5: // NCR - value = ne2000->num_coll; - break; + case 0x5: // NCR + value = ne2000->num_coll; + break; - case 0x6: // FIFO - // reading FIFO is only valid in loopback mode - ne2000_log("reading FIFO not supported yet\n"); - value = ne2000->fifo; - break; + case 0x6: // FIFO + // reading FIFO is only valid in loopback mode + ne2000_log("reading FIFO not supported yet\n"); + value = ne2000->fifo; + break; - case 0x7: // ISR - value = ((ne2000->ISR.reset << 7) | - (ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - break; + case 0x7: // ISR + value = ((ne2000->ISR.reset << 7) | + (ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + break; - case 0x8: // CRDA0 - value = (ne2000->remote_dma & 0xff); - break; + case 0x8: // CRDA0 + value = (ne2000->remote_dma & 0xff); + break; - case 0x9: // CRDA1 - value = (ne2000->remote_dma >> 8); - break; + case 0x9: // CRDA1 + value = (ne2000->remote_dma >> 8); + break; - case 0xa: // reserved / RTL8029ID0 - if (network_card_current == 2) { - value = 0x50; - } else { - ne2000_log("reserved read - page 0, 0xa\n"); - value = 0xff; - } - break; + case 0xa: // reserved / RTL8029ID0 + if (network_card_current == 2) + { + value = 0x50; + } + else + { + ne2000_log("reserved read - page 0, 0xa\n"); + value = 0xff; + } + break; - case 0xb: // reserved / RTL8029ID1 - if (network_card_current == 2) { - value = 0x43; - } else { - ne2000_log("reserved read - page 0, 0xb\n"); - value = 0xff; - } - break; + case 0xb: // reserved / RTL8029ID1 + if (network_card_current == 2) + { + value = 0x43; + } + else + { + ne2000_log("reserved read - page 0, 0xb\n"); + value = 0xff; + } + break; - case 0xc: // RSR - value = ((ne2000->RSR.deferred << 7) | - (ne2000->RSR.rx_disabled << 6) | - (ne2000->RSR.rx_mbit << 5) | - (ne2000->RSR.rx_missed << 4) | - (ne2000->RSR.fifo_or << 3) | - (ne2000->RSR.bad_falign << 2) | - (ne2000->RSR.bad_crc << 1) | - (ne2000->RSR.rx_ok)); - break; + case 0xc: // RSR + value = ((ne2000->RSR.deferred << 7) | + (ne2000->RSR.rx_disabled << 6) | + (ne2000->RSR.rx_mbit << 5) | + (ne2000->RSR.rx_missed << 4) | + (ne2000->RSR.fifo_or << 3) | + (ne2000->RSR.bad_falign << 2) | + (ne2000->RSR.bad_crc << 1) | + (ne2000->RSR.rx_ok)); + break; - case 0xd: // CNTR0 - value = ne2000->tallycnt_0; - break; + case 0xd: // CNTR0 + value = ne2000->tallycnt_0; + break; - case 0xe: // CNTR1 - value = ne2000->tallycnt_1; - break; + case 0xe: // CNTR1 + value = ne2000->tallycnt_1; + break; - case 0xf: // CNTR2 - value = ne2000->tallycnt_2; - break; + case 0xf: // CNTR2 + value = ne2000->tallycnt_2; + break; - default: - ne2000_log("page 0 register 0x%02x out of range\n", offset); - break; - } + default: + ne2000_log("page 0 register 0x%02x out of range\n", offset); + break; + } - ne2000_log("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); - return value; + ne2000_log("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); + return value; } void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - uint8_t value2; + uint8_t value2; - // It appears to be a common practice to use outw on page0 regs... + // It appears to be a common practice to use outw on page0 regs... - // break up outw into two outb's - if (io_len == 2) { - ne2000_page0_write(ne2000, offset, (value & 0xff), 1); - if (offset < 0x0f) { - ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); - } - return; - } + // break up outw into two outb's + if (io_len == 2) + { + ne2000_page0_write(ne2000, offset, (value & 0xff), 1); + if (offset < 0x0f) + { + ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); + } + return; + } - ne2000_log("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); + ne2000_log("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); - switch (offset) { - case 0x1: // PSTART - ne2000->page_start = value; - break; + switch (offset) + { + case 0x1: // PSTART + ne2000->page_start = value; + break; - case 0x2: // PSTOP - ne2000->page_stop = value; - break; + case 0x2: // PSTOP + ne2000->page_stop = value; + break; - case 0x3: // BNRY - ne2000->bound_ptr = value; - break; + case 0x3: // BNRY + ne2000->bound_ptr = value; + break; - case 0x4: // TPSR - ne2000->tx_page_start = value; - break; + case 0x4: // TPSR + ne2000->tx_page_start = value; + break; - case 0x5: // TBCR0 - // Clear out low byte and re-insert - ne2000->tx_bytes &= 0xff00; - ne2000->tx_bytes |= (value & 0xff); - break; + case 0x5: // TBCR0 + // Clear out low byte and re-insert + ne2000->tx_bytes &= 0xff00; + ne2000->tx_bytes |= (value & 0xff); + break; - case 0x6: // TBCR1 - // Clear out high byte and re-insert - ne2000->tx_bytes &= 0x00ff; - ne2000->tx_bytes |= ((value & 0xff) << 8); - break; + case 0x6: // TBCR1 + // Clear out high byte and re-insert + ne2000->tx_bytes &= 0x00ff; + ne2000->tx_bytes |= ((value & 0xff) << 8); + break; - case 0x7: // ISR - value &= 0x7f; // clear RST bit - status-only bit - // All other values are cleared iff the ISR bit is 1 - ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); - ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); - ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); - ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); - ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); - ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); - ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); - value = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - value &= ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - if (value == 0) - picintc(1 << ne2000->base_irq); - break; + case 0x7: // ISR + value &= 0x7f; // clear RST bit - status-only bit + // All other values are cleared iff the ISR bit is 1 + ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); + ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); + ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); + ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); + ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); + ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); + ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); + value = ((ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + value &= ((ne2000->IMR.rdma_inte << 6) | + (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | + (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | + (ne2000->IMR.tx_inte << 1) | + (ne2000->IMR.rx_inte)); + if (value == 0) + { + picintc(1 << ne2000->base_irq); + } + break; - case 0x8: // RSAR0 - // Clear out low byte and re-insert - ne2000->remote_start &= 0xff00; - ne2000->remote_start |= (value & 0xff); - ne2000->remote_dma = ne2000->remote_start; - break; + case 0x8: // RSAR0 + // Clear out low byte and re-insert + ne2000->remote_start &= 0xff00; + ne2000->remote_start |= (value & 0xff); + ne2000->remote_dma = ne2000->remote_start; + break; - case 0x9: // RSAR1 - // Clear out high byte and re-insert - ne2000->remote_start &= 0x00ff; - ne2000->remote_start |= ((value & 0xff) << 8); - ne2000->remote_dma = ne2000->remote_start; - break; + case 0x9: // RSAR1 + // Clear out high byte and re-insert + ne2000->remote_start &= 0x00ff; + ne2000->remote_start |= ((value & 0xff) << 8); + ne2000->remote_dma = ne2000->remote_start; + break; - case 0xa: // RBCR0 - // Clear out low byte and re-insert - ne2000->remote_bytes &= 0xff00; - ne2000->remote_bytes |= (value & 0xff); - break; + case 0xa: // RBCR0 + // Clear out low byte and re-insert + ne2000->remote_bytes &= 0xff00; + ne2000->remote_bytes |= (value & 0xff); + break; - case 0xb: // RBCR1 - // Clear out high byte and re-insert - ne2000->remote_bytes &= 0x00ff; - ne2000->remote_bytes |= ((value & 0xff) << 8); - break; + case 0xb: // RBCR1 + // Clear out high byte and re-insert + ne2000->remote_bytes &= 0x00ff; + ne2000->remote_bytes |= ((value & 0xff) << 8); + break; - case 0xc: // RCR - // Check if the reserved bits are set - if (value & 0xc0) - ne2000_log("RCR write, reserved bits set\n"); + case 0xc: // RCR + // Check if the reserved bits are set + if (value & 0xc0) + { + ne2000_log("RCR write, reserved bits set\n"); + } - // Set all other bit-fields - ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); - ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); - ne2000->RCR.broadcast = ((value & 0x04) == 0x04); - ne2000->RCR.multicast = ((value & 0x08) == 0x08); - ne2000->RCR.promisc = ((value & 0x10) == 0x10); - ne2000->RCR.monitor = ((value & 0x20) == 0x20); + // Set all other bit-fields + ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); + ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); + ne2000->RCR.broadcast = ((value & 0x04) == 0x04); + ne2000->RCR.multicast = ((value & 0x08) == 0x08); + ne2000->RCR.promisc = ((value & 0x10) == 0x10); + ne2000->RCR.monitor = ((value & 0x20) == 0x20); - // Monitor bit is a little suspicious... - if (value & 0x20) - ne2000_log("RCR write, monitor bit set!\n"); - break; + // Monitor bit is a little suspicious... + if (value & 0x20) + { + ne2000_log("RCR write, monitor bit set!\n"); + } + break; - case 0xd: // TCR - // Check reserved bits - if (value & 0xe0) - ne2000_log("TCR write, reserved bits set\n"); + case 0xd: // TCR + // Check reserved bits + if (value & 0xe0) + { + ne2000_log("TCR write, reserved bits set\n"); + } - // Test loop mode (not supported) - if (value & 0x06) { - ne2000->TCR.loop_cntl = (value & 0x6) >> 1; - ne2000_log("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } else { - ne2000->TCR.loop_cntl = 0; - } + // Test loop mode (not supported) + if (value & 0x06) + { + ne2000->TCR.loop_cntl = (value & 0x6) >> 1; + ne2000_log("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); + } + else + { + ne2000->TCR.loop_cntl = 0; + } - // Inhibit-CRC not supported. - if (value & 0x01) - ne2000_log("TCR write, inhibit-CRC not supported\n"); + // Inhibit-CRC not supported. + if (value & 0x01) + { + ne2000_log("TCR write, inhibit-CRC not supported\n"); + } - // Auto-transmit disable very suspicious - if (value & 0x08) - ne2000_log("TCR write, auto transmit disable not supported\n"); + // Auto-transmit disable very suspicious + if (value & 0x08) + { + ne2000_log("TCR write, auto transmit disable not supported\n"); + } - // Allow collision-offset to be set, although not used - ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); - break; + // Allow collision-offset to be set, although not used + ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); + break; - case 0xe: // DCR - // the loopback mode is not suppported yet - if (!(value & 0x08)) { - ne2000_log("DCR write, loopback mode selected\n"); - } - // It is questionable to set longaddr and auto_rx, since they - // aren't supported on the ne2000. Print a warning and continue - if (value & 0x04) - ne2000_log("DCR write - LAS set ???\n"); - if (value & 0x10) - ne2000_log("DCR write - AR set ???\n"); + case 0xe: // DCR + // the loopback mode is not suppported yet + if (!(value & 0x08)) + { + ne2000_log("DCR write, loopback mode selected\n"); + } + // It is questionable to set longaddr and auto_rx, since they + // aren't supported on the ne2000. Print a warning and continue + if (value & 0x04) + { + ne2000_log("DCR write - LAS set ???\n"); + } + if (value & 0x10) + { + ne2000_log("DCR write - AR set ???\n"); + } - // Set other values. - ne2000->DCR.wdsize = ((value & 0x01) == 0x01); - ne2000->DCR.endian = ((value & 0x02) == 0x02); - ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? - ne2000->DCR.loop = ((value & 0x08) == 0x08); - ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? - ne2000->DCR.fifo_size = (value & 0x50) >> 5; - break; + // Set other values. + ne2000->DCR.wdsize = ((value & 0x01) == 0x01); + ne2000->DCR.endian = ((value & 0x02) == 0x02); + ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? + ne2000->DCR.loop = ((value & 0x08) == 0x08); + ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? + ne2000->DCR.fifo_size = (value & 0x50) >> 5; + break; - case 0xf: // IMR - // Check for reserved bit - if (value & 0x80) - ne2000_log("IMR write, reserved bit set\n"); + case 0xf: // IMR + // Check for reserved bit + if (value & 0x80) + { + ne2000_log("IMR write, reserved bit set\n"); + } - // Set other values - ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); - ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); - ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); - ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); - ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); - ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); - ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - value2 = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - if (((value & value2) & 0x7f) == 0) { - picintc(1 << ne2000->base_irq); - } else { - picint(1 << ne2000->base_irq); - } - break; + // Set other values + ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); + ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); + ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); + ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); + ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); + ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); + ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); + value2 = ((ne2000->ISR.rdma_done << 6) | + (ne2000->ISR.cnt_oflow << 5) | + (ne2000->ISR.overwrite << 4) | + (ne2000->ISR.tx_err << 3) | + (ne2000->ISR.rx_err << 2) | + (ne2000->ISR.pkt_tx << 1) | + (ne2000->ISR.pkt_rx)); + if (((value & value2) & 0x7f) == 0) + { + picintc(1 << ne2000->base_irq); + } + else + { + picint(1 << ne2000->base_irq); + } + break; - default: - ne2000_log("page 0 write, bad register 0x%02x\n", offset); - break; - } + default: + ne2000_log("page 0 write, bad register 0x%02x\n", offset); + break; + } } // @@ -952,84 +1038,76 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig // uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); + ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); - switch (offset) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - return (ne2000->physaddr[offset - 1]); - break; + switch (offset) + { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + return (ne2000->physaddr[offset - 1]); - case 0x7: // CURR - ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); - return (ne2000->curr_page); + case 0x7: // CURR + ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); + return (ne2000->curr_page); - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - return (ne2000->mchash[offset - 8]); - break; + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + return (ne2000->mchash[offset - 8]); - default: - ne2000_log("page 1 read register 0x%02x out of range\n", offset); - break; - } - - return (0); + default: + ne2000_log("page 1 read register 0x%02x out of range\n", offset); + return 0; + } } void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_log("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, - io_len, value); + ne2000_log("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); - switch (offset) { - case 0x1: // PAR0-5 - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - ne2000->physaddr[offset - 1] = value; - if (offset == 6) { - ne2000_log("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", - ne2000->physaddr[0], - ne2000->physaddr[1], - ne2000->physaddr[2], - ne2000->physaddr[3], - ne2000->physaddr[4], - ne2000->physaddr[5]); - } - break; + switch (offset) + { + case 0x1: // PAR0-5 + case 0x2: + case 0x3: + case 0x4: + case 0x5: + case 0x6: + ne2000->physaddr[offset - 1] = value; + if (offset == 6) + { + ne2000_log("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", ne2000->physaddr[0], ne2000->physaddr[1], ne2000->physaddr[2], ne2000->physaddr[3], ne2000->physaddr[4], ne2000->physaddr[5]); + } + break; - case 0x7: // CURR - ne2000->curr_page = value; - break; + case 0x7: // CURR + ne2000->curr_page = value; + break; - case 0x8: // MAR0-7 - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000->mchash[offset - 8] = value; - break; + case 0x8: // MAR0-7 + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ne2000->mchash[offset - 8] = value; + break; - default: - ne2000_log("page 1 write register 0x%02x out of range\n", offset); - break; - } + default: + ne2000_log("page 1 write register 0x%02x out of range\n", offset); + break; + } } // @@ -1038,136 +1116,137 @@ void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig // uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); + ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); - switch (offset) { - case 0x1: // PSTART - return (ne2000->page_start); + switch (offset) + { + case 0x1: // PSTART + return (ne2000->page_start); - case 0x2: // PSTOP - return (ne2000->page_stop); + case 0x2: // PSTOP + return (ne2000->page_stop); - case 0x3: // Remote Next-packet pointer - return (ne2000->rempkt_ptr); + case 0x3: // Remote Next-packet pointer + return (ne2000->rempkt_ptr); - case 0x4: // TPSR - return (ne2000->tx_page_start); + case 0x4: // TPSR + return (ne2000->tx_page_start); - case 0x5: // Local Next-packet pointer - return (ne2000->localpkt_ptr); + case 0x5: // Local Next-packet pointer + return (ne2000->localpkt_ptr); - case 0x6: // Address counter (upper) - return (ne2000->address_cnt >> 8); + case 0x6: // Address counter (upper) + return (ne2000->address_cnt >> 8); - case 0x7: // Address counter (lower) - return (ne2000->address_cnt & 0xff); + case 0x7: // Address counter (lower) + return (ne2000->address_cnt & 0xff); - case 0x8: // Reserved - case 0x9: - case 0xa: - case 0xb: - ne2000_log("reserved read - page 2, register 0x%02x\n", offset); - return (0xff); + case 0x8: // Reserved + case 0x9: + case 0xa: + case 0xb: + ne2000_log("reserved read - page 2, register 0x%02x\n", offset); + return (0xff); - case 0xc: // RCR - return ((ne2000->RCR.monitor << 5) | - (ne2000->RCR.promisc << 4) | - (ne2000->RCR.multicast << 3) | - (ne2000->RCR.broadcast << 2) | - (ne2000->RCR.runts_ok << 1) | - (ne2000->RCR.errors_ok)); + case 0xc: // RCR + return ((ne2000->RCR.monitor << 5) | + (ne2000->RCR.promisc << 4) | + (ne2000->RCR.multicast << 3) | + (ne2000->RCR.broadcast << 2) | + (ne2000->RCR.runts_ok << 1) | + (ne2000->RCR.errors_ok)); - case 0xd: // TCR - return ((ne2000->TCR.coll_prio << 4) | - (ne2000->TCR.ext_stoptx << 3) | - ((ne2000->TCR.loop_cntl & 0x3) << 1) | - (ne2000->TCR.crc_disable)); + case 0xd: // TCR + return ((ne2000->TCR.coll_prio << 4) | + (ne2000->TCR.ext_stoptx << 3) | + ((ne2000->TCR.loop_cntl & 0x3) << 1) | + (ne2000->TCR.crc_disable)); - case 0xe: // DCR - return (((ne2000->DCR.fifo_size & 0x3) << 5) | - (ne2000->DCR.auto_rx << 4) | - (ne2000->DCR.loop << 3) | - (ne2000->DCR.longaddr << 2) | - (ne2000->DCR.endian << 1) | - (ne2000->DCR.wdsize)); + case 0xe: // DCR + return (((ne2000->DCR.fifo_size & 0x3) << 5) | + (ne2000->DCR.auto_rx << 4) | + (ne2000->DCR.loop << 3) | + (ne2000->DCR.longaddr << 2) | + (ne2000->DCR.endian << 1) | + (ne2000->DCR.wdsize)); - case 0xf: // IMR - return ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); + case 0xf: // IMR + return ((ne2000->IMR.rdma_inte << 6) | + (ne2000->IMR.cofl_inte << 5) | + (ne2000->IMR.overw_inte << 4) | + (ne2000->IMR.txerr_inte << 3) | + (ne2000->IMR.rxerr_inte << 2) | + (ne2000->IMR.tx_inte << 1) | + (ne2000->IMR.rx_inte)); - default: - ne2000_log("page 2 register 0x%02x out of range\n", offset); - break; - } + default: + ne2000_log("page 2 register 0x%02x out of range\n", offset); + break; + } - return (0); + return (0); } void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - // Maybe all writes here should be BX_PANIC()'d, since they - // affect internal operation, but let them through for now - // and print a warning. - ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, - io_len, value); + // Maybe all writes here should be BX_PANIC()'d, since they + // affect internal operation, but let them through for now + // and print a warning. + ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); - switch (offset) { - case 0x1: // CLDA0 - // Clear out low byte and re-insert - ne2000->local_dma &= 0xff00; - ne2000->local_dma |= (value & 0xff); - break; + switch (offset) + { + case 0x1: // CLDA0 + // Clear out low byte and re-insert + ne2000->local_dma &= 0xff00; + ne2000->local_dma |= (value & 0xff); + break; - case 0x2: // CLDA1 - // Clear out high byte and re-insert - ne2000->local_dma &= 0x00ff; - ne2000->local_dma |= ((value & 0xff) << 8); - break; + case 0x2: // CLDA1 + // Clear out high byte and re-insert + ne2000->local_dma &= 0x00ff; + ne2000->local_dma |= ((value & 0xff) << 8); + break; - case 0x3: // Remote Next-pkt pointer - ne2000->rempkt_ptr = value; - break; + case 0x3: // Remote Next-pkt pointer + ne2000->rempkt_ptr = value; + break; - case 0x4: - ne2000_log("page 2 write to reserved register 0x04\n"); - break; + case 0x4: + ne2000_log("page 2 write to reserved register 0x04\n"); + break; - case 0x5: // Local Next-packet pointer - ne2000->localpkt_ptr = value; - break; + case 0x5: // Local Next-packet pointer + ne2000->localpkt_ptr = value; + break; - case 0x6: // Address counter (upper) - // Clear out high byte and re-insert - ne2000->address_cnt &= 0x00ff; - ne2000->address_cnt |= ((value & 0xff) << 8); - break; + case 0x6: // Address counter (upper) + // Clear out high byte and re-insert + ne2000->address_cnt &= 0x00ff; + ne2000->address_cnt |= ((value & 0xff) << 8); + break; - case 0x7: // Address counter (lower) - // Clear out low byte and re-insert - ne2000->address_cnt &= 0xff00; - ne2000->address_cnt |= (value & 0xff); - break; + case 0x7: // Address counter (lower) + // Clear out low byte and re-insert + ne2000->address_cnt &= 0xff00; + ne2000->address_cnt |= (value & 0xff); + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000_log("page 2 write to reserved register 0x%02x\n", offset); - break; + case 0x8: + case 0x9: + case 0xa: + case 0xb: + case 0xc: + case 0xd: + case 0xe: + case 0xf: + ne2000_log("page 2 write to reserved register 0x%02x\n", offset); + break; - default: - ne2000_log("page 2 write, illegal register 0x%02x\n", offset); - break; - } + default: + ne2000_log("page 2 write, illegal register 0x%02x\n", offset); + break; + } } // @@ -1175,48 +1254,48 @@ void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig // uint32_t ne2000_page3_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { - if (network_card_current == 2) { - switch (offset) { - case 0x3: // CONFIG0 - return (0); - case 0x5: // CONFIG2 - return (0x40); - case 0x6: // CONFIG3 - return (0x40); - default: - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } - } else { - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } + if (network_card_current == 2) + { + switch (offset) + { + case 0x3: // CONFIG0 + return (0); + case 0x5: // CONFIG2 + return (0x40); + case 0x6: // CONFIG3 + return (0x40); + default: + ne2000_log("page 3 read register 0x%02x attempted\n", offset); + return (0); + } + } + else + { + ne2000_log("page 3 read register 0x%02x attempted\n", offset); + return (0); + } } void ne2000_page3_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - ne2000_log("page 3 write register 0x%02x attempted\n", offset); - return; -} - -void ne2000_tx_timer(void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_log("tx_timer\n"); - ne2000->CR.tx_packet = 0; - ne2000->TSR.tx_ok = 1; - ne2000->ISR.pkt_tx = 1; - // Generate an interrupt if not masked - if (ne2000->IMR.tx_inte) { - picint(1 << ne2000->base_irq); - } - ne2000->tx_timer_active = 0; + ne2000_log("page 3 write register 0x%02x attempted\n", offset); + return; } void ne2000_tx_event(void *p, uint32_t val) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_tx_timer(ne2000); + ne2000_t *ne2000 = (ne2000_t *)p; + + ne2000_log("tx_timer\n"); + ne2000->CR.tx_packet = 0; + ne2000->TSR.tx_ok = 1; + ne2000->ISR.pkt_tx = 1; + // Generate an interrupt if not masked + if (ne2000->IMR.tx_inte) + { + picint(1 << ne2000->base_irq); + } + ne2000->tx_timer_active = 0; } // @@ -1226,79 +1305,91 @@ void ne2000_tx_event(void *p, uint32_t val) // uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) { - ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); - uint32_t retval = 0; - int offset = address - ne2000->base_address; + ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); + uint32_t retval = 0; + int offset = address - ne2000->base_address; - if (offset >= 0x10) { - retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); - } else if (offset == 0x00) { - retval = ne2000_read_cr(ne2000); - } else { - switch (ne2000->CR.pgsel) { - case 0x00: - retval = ne2000_page0_read(ne2000, offset, io_len); - break; + if (offset >= 0x10) + { + retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); + } + else if (offset == 0x00) + { + retval = ne2000_read_cr(ne2000); + } + else + { + switch (ne2000->CR.pgsel) + { + case 0x00: + retval = ne2000_page0_read(ne2000, offset, io_len); + break; - case 0x01: - retval = ne2000_page1_read(ne2000, offset, io_len); - break; + case 0x01: + retval = ne2000_page1_read(ne2000, offset, io_len); + break; - case 0x02: - retval = ne2000_page2_read(ne2000, offset, io_len); - break; + case 0x02: + retval = ne2000_page2_read(ne2000, offset, io_len); + break; - case 0x03: - retval = ne2000_page3_read(ne2000, offset, io_len); - break; + case 0x03: + retval = ne2000_page3_read(ne2000, offset, io_len); + break; - default: - ne2000_log("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); - break; - } - } + default: + ne2000_log("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); + break; + } + } - return (retval); + return (retval); } void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) { - ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); - int offset = address - ne2000->base_address; + ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); + int offset = address - ne2000->base_address; - // - // The high 16 bytes of i/o space are for the ne2000 asic - - // the low 16 bytes are for the DS8390, with the current - // page being selected by the PS0,PS1 registers in the - // command register - // - if (offset >= 0x10) { - ne2000_asic_write(ne2000, offset - 0x10, value, io_len); - } else if (offset == 0x00) { - ne2000_write_cr(ne2000, value); - } else { - switch (ne2000->CR.pgsel) { - case 0x00: - ne2000_page0_write(ne2000, offset, value, io_len); - break; + // + // The high 16 bytes of i/o space are for the ne2000 asic - + // the low 16 bytes are for the DS8390, with the current + // page being selected by the PS0,PS1 registers in the + // command register + // + if (offset >= 0x10) + { + ne2000_asic_write(ne2000, offset - 0x10, value, io_len); + } + else if (offset == 0x00) + { + ne2000_write_cr(ne2000, value); + } + else + { + switch (ne2000->CR.pgsel) + { + case 0x00: + ne2000_page0_write(ne2000, offset, value, io_len); + break; - case 0x01: - ne2000_page1_write(ne2000, offset, value, io_len); - break; + case 0x01: + ne2000_page1_write(ne2000, offset, value, io_len); + break; - case 0x02: - ne2000_page2_write(ne2000, offset, value, io_len); - break; + case 0x02: + ne2000_page2_write(ne2000, offset, value, io_len); + break; - case 0x03: - ne2000_page3_write(ne2000, offset, value, io_len); - break; + case 0x03: + ne2000_page3_write(ne2000, offset, value, io_len); + break; - default: - ne2000_log("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - break; - } - } + default: + ne2000_log("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); + break; + } + } } /* @@ -1308,22 +1399,26 @@ void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned i static int mcast_index(const void *dst) { #define POLYNOMIAL 0x04c11db6 - unsigned long crc = 0xffffffffL; - int carry, i, j; - unsigned char b; - unsigned char *ep = (unsigned char *) dst; + unsigned long crc = 0xffffffffL; + int carry, i, j; + unsigned char b; + unsigned char *ep = (unsigned char *) dst; - for (i = 6; --i >= 0;) { - b = *ep++; - for (j = 8; --j >= 0;) { - carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); - crc <<= 1; - b >>= 1; - if (carry) - crc = ((crc ^ POLYNOMIAL) | carry); - } - } - return (crc >> 26); + for (i = 6; --i >= 0;) + { + b = *ep++; + for (j = 8; --j >= 0;) + { + carry = ((crc & 0x80000000L) ? 1 : 0) ^ (b & 0x01); + crc <<= 1; + b >>= 1; + if (carry) + { + crc = ((crc ^ POLYNOMIAL) | carry); + } + } + } + return (crc >> 26); #undef POLYNOMIAL } @@ -1336,149 +1431,157 @@ static int mcast_index(const void *dst) */ void ne2000_rx_frame(void *p, const void *buf, int io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *ne2000 = (ne2000_t *)p; - int pages; - int avail; - int idx; - int wrapped; - int nextpage; - uint8_t pkthdr[4]; - uint8_t *pktbuf = (uint8_t *) buf; - uint8_t *startptr; - static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; + int pages; + int avail; + int idx; + int wrapped; + int nextpage; + uint8_t pkthdr[4]; + uint8_t *pktbuf = (uint8_t *) buf; + uint8_t *startptr; + static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + uint32_t mac_cmp32[2]; + uint16_t mac_cmp16[2]; - if(io_len != 60) { - ne2000_log("rx_frame with length %d\n", io_len); - } + if(io_len != 60) + { + ne2000_log("rx_frame with length %d\n", io_len); + } - //LOG_MSG("stop=%d, pagestart=%x, dcr_loop=%x, tcr_loopcntl=%x", - // ne2000->CR.stop, ne2000->page_start, - // ne2000->DCR.loop, ne2000->TCR.loop_cntl); - if ((ne2000->CR.stop != 0) || - (ne2000->page_start == 0) /*|| - ((ne2000->DCR.loop == 0) && - (ne2000->TCR.loop_cntl != 0))*/) { - return; - } + if ((ne2000->CR.stop != 0) || + (ne2000->page_start == 0)) + { + return; + } - // Add the pkt header + CRC to the length, and work - // out how many 256-byte pages the frame would occupy - pages = (io_len + 4 + 4 + 255)/256; + // Add the pkt header + CRC to the length, and work + // out how many 256-byte pages the frame would occupy + pages = (io_len + 4 + 4 + 255)/256; - if (ne2000->curr_page < ne2000->bound_ptr) { - avail = ne2000->bound_ptr - ne2000->curr_page; - } else { - avail = (ne2000->page_stop - ne2000->page_start) - - (ne2000->curr_page - ne2000->bound_ptr); - wrapped = 1; - } + if (ne2000->curr_page < ne2000->bound_ptr) + { + avail = ne2000->bound_ptr - ne2000->curr_page; + } + else + { + avail = (ne2000->page_stop - ne2000->page_start) - (ne2000->curr_page - ne2000->bound_ptr); + wrapped = 1; + } - // Avoid getting into a buffer overflow condition by not attempting - // to do partial receives. The emulation to handle this condition - // seems particularly painful. - if ((avail < pages) + // Avoid getting into a buffer overflow condition by not attempting + // to do partial receives. The emulation to handle this condition + // seems particularly painful. + if ((avail < pages) #if BX_NE2K_NEVER_FULL_RING - || (avail == pages) + || (avail == pages) #endif - ) { - ne2000_log("no space\n"); - return; - } + ) + { + ne2000_log("no space\n"); + return; + } - if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) { - ne2000_log("rejected small packet, length %d\n", io_len); - return; - } - // some computers don't care... - if (io_len < 60) io_len=60; + if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) + { + ne2000_log("rejected small packet, length %d\n", io_len); + return; + } + // some computers don't care... + if (io_len < 60) + { + io_len=60; + } - // Do address filtering if not in promiscuous mode - if (! ne2000->RCR.promisc) { - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (buf); - mac_cmp16[0] = *(uint16_t *) (buf+4); - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (bcast_addr); - mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); - // if (!memcmp(buf, bcast_addr, 6)) { - if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) { - if (!ne2000->RCR.broadcast) { - return; - } - } else if (pktbuf[0] & 0x01) { - if (! ne2000->RCR.multicast) { - return; - } - idx = mcast_index(buf); - if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) { - return; - } - } else if (0 != memcmp(buf, ne2000->physaddr, 6)) { - return; - } - } else { - ne2000_log("rx_frame promiscuous receive\n"); - } + // Do address filtering if not in promiscuous mode + if (! ne2000->RCR.promisc) + { + /* Received. */ + mac_cmp32[0] = *(uint32_t *) (buf); + mac_cmp16[0] = *(uint16_t *) (buf+4); + /* Local. */ + mac_cmp32[1] = *(uint32_t *) (bcast_addr); + mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); + if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) + { + if (!ne2000->RCR.broadcast) + { + return; + } + } + else if (pktbuf[0] & 0x01) + { + if (! ne2000->RCR.multicast) + { + return; + } + idx = mcast_index(buf); + if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) + { + return; + } + } + else if (0 != memcmp(buf, ne2000->physaddr, 6)) + { + return; + } + } + else + { + ne2000_log("rx_frame promiscuous receive\n"); + } - ne2000_log("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", - io_len, - pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], - pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + ne2000_log("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); - nextpage = ne2000->curr_page + pages; - if (nextpage >= ne2000->page_stop) { - nextpage -= ne2000->page_stop - ne2000->page_start; - } + nextpage = ne2000->curr_page + pages; + if (nextpage >= ne2000->page_stop) + { + nextpage -= ne2000->page_stop - ne2000->page_start; + } - // Setup packet header - pkthdr[0] = 0; // rx status - old behavior - pkthdr[0] = 1; // Probably better to set it all the time - // rather than set it to 0, which is clearly wrong. - if (pktbuf[0] & 0x01) { - pkthdr[0] |= 0x20; // rx status += multicast packet - } - pkthdr[1] = nextpage; // ptr to next packet - pkthdr[2] = (io_len + 4) & 0xff; // length-low - pkthdr[3] = (io_len + 4) >> 8; // length-hi + // Setup packet header + pkthdr[0] = 0; // rx status - old behavior + pkthdr[0] = 1; // Probably better to set it all the time + // rather than set it to 0, which is clearly wrong. + if (pktbuf[0] & 0x01) + { + pkthdr[0] |= 0x20; // rx status += multicast packet + } + pkthdr[1] = nextpage; // ptr to next packet + pkthdr[2] = (io_len + 4) & 0xff; // length-low + pkthdr[3] = (io_len + 4) >> 8; // length-hi - // copy into buffer, update curpage, and signal interrupt if config'd - startptr = & ne2000->mem[ne2000->curr_page * 256 - - BX_NE2K_MEMSTART]; - if ((nextpage > ne2000->curr_page) || - ((ne2000->curr_page + pages) == ne2000->page_stop)) { - // memcpy(startptr, pkthdr, 4); - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, io_len); - ne2000->curr_page = nextpage; - } else { - int endbytes = (ne2000->page_stop - ne2000->curr_page) - * 256; - // memcpy(startptr, pkthdr, 4); - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, endbytes - 4); - startptr = & ne2000->mem[ne2000->page_start * 256 - - BX_NE2K_MEMSTART]; - memcpy(startptr, (void *)(pktbuf + endbytes - 4), - io_len - endbytes + 8); - ne2000->curr_page = nextpage; - } + // copy into buffer, update curpage, and signal interrupt if config'd + startptr = & ne2000->mem[ne2000->curr_page * 256 - BX_NE2K_MEMSTART]; + if ((nextpage > ne2000->curr_page) || ((ne2000->curr_page + pages) == ne2000->page_stop)) + { + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, io_len); + ne2000->curr_page = nextpage; + } + else + { + int endbytes = (ne2000->page_stop - ne2000->curr_page) * 256; + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, endbytes - 4); + startptr = & ne2000->mem[ne2000->page_start * 256 - BX_NE2K_MEMSTART]; + memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); + ne2000->curr_page = nextpage; + } - ne2000->RSR.rx_ok = 1; - if (pktbuf[0] & 0x80) { - ne2000->RSR.rx_mbit = 1; - } + ne2000->RSR.rx_ok = 1; + if (pktbuf[0] & 0x80) + { + ne2000->RSR.rx_mbit = 1; + } - ne2000->ISR.pkt_rx = 1; - - if (ne2000->IMR.rx_inte) { - //LOG_MSG("packet rx interrupt"); - picint(1 << ne2000->base_irq); - //DEV_pic_raise_irq(ne2000->base_irq); - } //else LOG_MSG("no packet rx interrupt"); + ne2000->ISR.pkt_rx = 1; + if (ne2000->IMR.rx_inte) + { + picint(1 << ne2000->base_irq); + } } uint8_t ne2000_readb(uint16_t addr, void *p) @@ -1491,9 +1594,13 @@ uint16_t ne2000_readw(uint16_t addr, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; if (ne2000->DCR.wdsize & 1) + { return ne2000_read(ne2000, addr, 2); + } else - return ne2000_read(ne2000, addr, 1); + { + return ne2000_read(ne2000, addr, 1); + } } uint32_t ne2000_readl(uint16_t addr, void *p) @@ -1512,9 +1619,13 @@ void ne2000_writew(uint16_t addr, uint16_t val, void *p) { ne2000_t *ne2000 = (ne2000_t *)p; if (ne2000->DCR.wdsize & 1) + { ne2000_write(ne2000, addr, val, 2); + } else + { ne2000_write(ne2000, addr, val, 1); + } } void ne2000_writel(uint16_t addr, uint32_t val, void *p) @@ -1532,32 +1643,35 @@ void ne2000_poller(void *p) uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; - - int res; -if(net_is_slirp) { - while(QueuePeek(slirpq)>0) - { - qp=QueueDelete(slirpq); - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - { - free(qp); - return; - } - ne2000_rx_frame(ne2000,&qp->data,qp->len); - ne2000_log("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); - free(qp); - } + int res; + if (!net_is_pcap) + { + while(QueuePeek(slirpq) > 0) + { + qp=QueueDelete(slirpq); + if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) + { + free(qp); + return; + } + ne2000_rx_frame(ne2000,&qp->data,qp->len); + ne2000_log("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); + free(qp); + } fizz++; - if(fizz>1200){fizz=0;slirp_tic();} - }//end slirp -if(net_is_pcap && net_pcap!=NULL) - { + if (fizz>1200) + { + fizz=0;slirp_tic(); + } + }//end slirp + else if (net_is_pcap && (net_pcap != NULL)) + { if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) { return; } - data=_pcap_next(net_pcap,&h); - if(data==0x0) + data=pcap_next(net_pcap,&h); + if(data==0x0) { return; } @@ -1567,18 +1681,12 @@ if(net_is_pcap && net_pcap!=NULL) /* Local. */ mac_cmp32[1] = *(uint32_t *) (maclocal); mac_cmp16[1] = *(uint16_t *) (maclocal+4); - // if((memcmp(data+6,maclocal,6))==0) - /* if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) - { - ne2000_log("ne2000 we just saw ourselves\n"); - } - else { */ if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { // ne2000_log("ne2000 pcap received a frame %d bytes\n",h.caplen); ne2000_rx_frame(ne2000,data,h.caplen); } - } + } } typedef union @@ -1599,64 +1707,85 @@ uint32_t bios_mask = 0; void ne2000_io_set(uint16_t addr, ne2000_t *ne2000) { - old_base_addr = addr; - io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + old_base_addr = addr; + io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); } void ne2000_io_remove(int16_t addr, ne2000_t *ne2000) { - io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); } uint8_t ne2000_pci_read(int func, int addr, void *p) { - ne2000_t *ne2000 = (ne2000_t *) p; + ne2000_t *ne2000 = (ne2000_t *) p; - // ne2000_log("NE2000 PCI read %08X\n", addr); - switch (addr) - { - case 0x00:/* case 0x2C:*/ return 0xec; - case 0x01:/* case 0x2D:*/ return 0x10; + // ne2000_log("NE2000 PCI read %08X\n", addr); + switch (addr) + { + case 0x00: + return 0xec; + case 0x01: + return 0x10; - case 0x02:/* case 0x2E:*/ return 0x29; - case 0x03:/* case 0x2F:*/ return 0x80; + case 0x02: + return 0x29; + case 0x03: + return 0x80; - case 0x2C: return 0xF4; - case 0x2D: return 0x1A; - case 0x2E: return 0x00; - case 0x2F: return 0x11; + case 0x2C: + return 0xF4; + case 0x2D: + return 0x1A; + case 0x2E: + return 0x00; + case 0x2F: + return 0x11; - case 0x04: - return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return ne2000_pci_regs[0x05]; + case 0x04: + return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ + case 0x05: + return ne2000_pci_regs[0x05]; - case 0x07: return 2; + case 0x07: + return 2; - case 0x08: return 0; /*Revision ID*/ - case 0x09: return 0; /*Programming interface*/ + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ - case 0x0B: return ne2000_pci_regs[0x0B]; + case 0x0B: + return ne2000_pci_regs[0x0B]; - case 0x10: return 1; /*I/O space*/ - case 0x11: return ne2000_pci_bar[0].addr_regs[1]; - case 0x12: return ne2000_pci_bar[0].addr_regs[2]; - case 0x13: return ne2000_pci_bar[0].addr_regs[3]; + case 0x10: + return 1; /*I/O space*/ + case 0x11: + return ne2000_pci_bar[0].addr_regs[1]; + case 0x12: + return ne2000_pci_bar[0].addr_regs[2]; + case 0x13: + return ne2000_pci_bar[0].addr_regs[3]; - case 0x30: return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ - // case 0x31: return (ne2000_pci_bar[1].addr_regs[1] & 0xE0) | 0x18; - case 0x31: return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; - case 0x32: return ne2000_pci_bar[1].addr_regs[2]; - case 0x33: return ne2000_pci_bar[1].addr_regs[3]; + case 0x30: + return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ + case 0x31: + return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; + case 0x32: + return ne2000_pci_bar[1].addr_regs[2]; + case 0x33: + return ne2000_pci_bar[1].addr_regs[3]; - case 0x3C: return ne2000_pci_regs[0x3C]; - case 0x3D: return ne2000_pci_regs[0x3D]; - } - return 0; + case 0x3C: + return ne2000_pci_regs[0x3C]; + case 0x3D: + return ne2000_pci_regs[0x3D]; + } + return 0; } void ne2000_update_bios(ne2000_t *ne2000) @@ -1682,63 +1811,57 @@ void ne2000_update_bios(ne2000_t *ne2000) void ne2000_pci_write(int func, int addr, uint8_t val, void *p) { - ne2000_t *ne2000 = (ne2000_t *) p; + ne2000_t *ne2000 = (ne2000_t *) p; - // ne2000_log("ne2000_pci_write: addr=%02x val=%02x\n", addr, val); - switch (addr) - { - case 0x04: - if (val & PCI_COMMAND_IO) - { - ne2000_io_remove(ne2000->base_address, ne2000); - ne2000_io_set(ne2000->base_address, ne2000); - } - else - { - ne2000_io_remove(ne2000->base_address, ne2000); - } - ne2000_pci_regs[addr] = val; - break; + switch (addr) + { + case 0x04: + ne2000_io_remove(ne2000->base_address, ne2000); + if (val & PCI_COMMAND_IO) + { + ne2000_io_set(ne2000->base_address, ne2000); + } + ne2000_pci_regs[addr] = val; + break; - case 0x10: - val &= 0xfc; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O, if old base was >= 0x280. */ - ne2000_io_remove(ne2000->base_address, ne2000); - /* Then let's set the PCI regs. */ - ne2000_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; - /* If the base is below 0x280, return. */ - /* Log the new base. */ - ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); - /* We're done, so get out of the here. */ - return; - - case 0x30: case 0x31: case 0x32: case 0x33: - ne2000_pci_bar[1].addr_regs[addr & 3] = val; - ne2000_pci_bar[1].addr_regs[1] &= bios_mask; - bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; - ne2000_pci_bar[1].addr &= 0xffffe000; - ne2000_pci_bar[1].addr |= 0x1801; - ne2000_update_bios(ne2000); - return; + case 0x10: + val &= 0xfc; + val |= 1; + case 0x11: case 0x12: case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O, if old base was >= 0x280. */ + ne2000_io_remove(ne2000->base_address, ne2000); + /* Then let's set the PCI regs. */ + ne2000_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; + /* Log the new base. */ + ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); + /* We're done, so get out of the here. */ + return; -/* Commented out until an APIC controller is emulated for the PIIX3, - otherwise the RTL-8029/AS will not get an IRQ on boards using the PIIX3. */ + case 0x30: case 0x31: case 0x32: case 0x33: + ne2000_pci_bar[1].addr_regs[addr & 3] = val; + ne2000_pci_bar[1].addr_regs[1] &= bios_mask; + bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; + ne2000_pci_bar[1].addr &= 0xffffe000; + ne2000_pci_bar[1].addr |= 0x1801; + ne2000_update_bios(ne2000); + return; + + /* Commented out until an APIC controller is emulated for the PIIX3, + otherwise the RTL-8029/AS will not get an IRQ on boards using the PIIX3. */ #if 0 - case 0x3C: - ne2000_pci_regs[addr] = val; - if (val != 0xFF) - { - ne2000_log("NE2000 IRQ now: %i\n", val); - ne2000_setirq(ne2000, val); - } - return; + case 0x3C: + ne2000_pci_regs[addr] = val; + if (val != 0xFF) + { + ne2000_log("NE2000 IRQ now: %i\n", val); + ne2000_setirq(ne2000, val); + } + return; #endif - } + } } void ne2000_rom_init(ne2000_t *ne2000, char *s) @@ -1773,220 +1896,78 @@ void ne2000_rom_init(ne2000_t *ne2000, char *s) rom_init(&ne2000->bios_rom, s, 0xd0000, bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); } +static char errbuf[32768]; + void *ne2000_init() -{ - int rc; - int config_net_type; - int net_type; - ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); - memset(ne2000, 0, sizeof(ne2000_t)); - - ne2000->base_address = device_get_config_int("addr"); - disable_netbios = device_get_config_int("disable_netbios"); - ne2000_setirq(ne2000, device_get_config_int("irq")); - - //net_type - //0 pcap - //1 slirp - // - config_net_type = device_get_config_int("net_type"); - // net_is_slirp = config_get_int(NULL, "net_type", 1); - /* Network type is now specified in device config. */ - net_is_slirp = config_net_type ? 1 : 0; - net_is_pcap = config_net_type ? 0 : 1; - if(!strcmp("nothing", config_get_string(NULL, "pcap_device", "nothing"))) - { - net_is_pcap = 0; - net_is_slirp = 1; - } - pclog("net_is_pcap = %i, net_is_slirp = %i\n", net_is_pcap, net_is_slirp); - - // ne2000_log("ne2000 pcap device %s\n",config_get_string(NULL,"pcap_device","nothing")); - - ne2000_io_set(ne2000->base_address, ne2000); - memcpy(ne2000->physaddr, maclocal, 6); - - if (!disable_netbios) - ne2000_rom_init(ne2000, "roms/ne2000.rom"); - - ne2000_reset(ne2000, BX_RESET_HARDWARE); - vlan_handler(ne2000_poller, ne2000); - - ne2000_log("ne2000 isa init 0x%X %d\tslirp is %d net_is_pcap is %d\n",ne2000->base_address,device_get_config_int("irq"),net_is_slirp,net_is_pcap); - - //need a switch statment for more network types. - - if ( net_is_slirp ) { - ne2000_log("ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - ne2000_log("ne2000 slirp_init returned: %d\n",rc); - if ( rc == 0 ) - { - ne2000_log("ne2000 slirp initalized!\n"); - - net_slirp_inited=1; - slirpq = QueueCreate(); - net_is_slirp=1; - fizz=0; - ne2000_log("ne2000 slirpq is %x\n",&slirpq); - } - else { - net_slirp_inited=0; - net_is_slirp=0; - } - } - if ( net_is_pcap ) { //pcap - char errbuf[32768]; - - ne2000_log("ne2000 initalizing libpcap\n"); - net_is_slirp=0; - net_hLib = LoadLibraryA(net_lib_name); - if(net_hLib==0) - { - ne2000_log("ne2000 Failed to load %s\n",net_lib_name); - net_is_pcap=0; - //return; - } - _pcap_lib_version =(PCAP_LIB_VERSION)GetProcAddress(net_hLib,"pcap_lib_version"); - _pcap_open_live=(PCAP_OPEN_LIVE)GetProcAddress(net_hLib,"pcap_open_live"); - _pcap_sendpacket=(PCAP_SENDPACKET)GetProcAddress(net_hLib,"pcap_sendpacket"); - _pcap_setnonblock=(PCAP_SETNONBLOCK)GetProcAddress(net_hLib,"pcap_setnonblock"); - _pcap_next=(PCAP_NEXT)GetProcAddress(net_hLib,"pcap_next"); - _pcap_close=(PCAP_CLOSE)GetProcAddress(net_hLib,"pcap_close"); - _pcap_getnonblock=(PCAP_GETNONBLOCK)GetProcAddress(net_hLib,"pcap_getnonblock"); - _pcap_compile=(PCAP_COMPILE)GetProcAddress(net_hLib,"pcap_compile"); - _pcap_setfilter=(PCAP_SETFILTER)GetProcAddress(net_hLib,"pcap_setfilter"); - - if(_pcap_lib_version && _pcap_open_live && _pcap_sendpacket && _pcap_setnonblock && _pcap_next && _pcap_close && _pcap_getnonblock) - { - ne2000_log("ne2000 Pcap version [%s]\n",_pcap_lib_version()); - - //if((net_pcap=_pcap_open_live("\\Device\\NPF_{0CFA803F-F443-4BB9-A83A-657029A98195}",1518,1,15,errbuf))==0) - if((net_pcap=_pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; return(ne2000); //YUCK!!! - } - } - else { - ne2000_log("%d %d %d %d %d %d %d\n",_pcap_lib_version, _pcap_open_live,_pcap_sendpacket,_pcap_setnonblock,_pcap_next,_pcap_close,_pcap_getnonblock); - net_is_pcap=1; - } - - //Time to check that we are in non-blocking mode. - rc=_pcap_getnonblock(net_pcap,errbuf); - ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - ne2000_log("ne2000 Setting interface to non-blocking mode.."); - rc=_pcap_setnonblock(net_pcap,1,errbuf); - if(rc==0) { //no errors! - ne2000_log(".."); - rc=_pcap_getnonblock(net_pcap,errbuf); - if(rc==1) { - ne2000_log("..!",rc); - net_is_pcap=1; - } - else{ - ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - }//end set nonblock - else{ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} - ne2000_log("\n"); - break; - case 1: - ne2000_log("non blocking\n"); - break; - default: - ne2000_log("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if( net_is_pcap ) { - if(_pcap_compile && _pcap_setfilter) { //we can do this! - struct bpf_program fp; - char filter_exp[255]; - ne2000_log("ne2000 Building packet filter..."); - sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); - - //I'm doing a MAC level filter so TCP/IP doesn't matter. - if (_pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { - ne2000_log("\nne2000 Couldn't compile filter\n"); - } - else { - ne2000_log("..."); - if (_pcap_setfilter(net_pcap, &fp) == -1) { - ne2000_log("\nError installing pcap filter.\n"); - }//end of set_filter failure - else { - ne2000_log("...!\n"); - } - } - ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); - //scanf(filter_exp); //pause - } - else - { - ne2000_log("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); - net_is_pcap=0; - } - ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } - } //end pcap setup - - //timer_add(slirp_tic,&delay,TIMER_ALWAYS_ENABLED,NULL); - //timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); -ne2000_log("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); -//exit(0); -return ne2000; -} - -void *rtl8029as_init() { int rc; int config_net_type; int net_type; int irq; + int pcap_device_available = 0; + int is_rtl8029as = 0; ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); + if (PCI && (network_card_current == 2)) + { + is_rtl8029as = 1; + } + else + { + network_card_current = 1; + is_rtl8029as = 0; + } + + if (is_rtl8029as) + { + ne2000->base_address = 0x340; + } + else + { + ne2000->base_address = device_get_config_int("addr"); + } + disable_netbios = device_get_config_int("disable_netbios"); - + irq = device_get_config_int("irq"); ne2000_setirq(ne2000, irq); - //net_type - //0 pcap - //1 slirp - // config_net_type = device_get_config_int("net_type"); - // net_is_slirp = config_get_int(NULL, "net_type", 1); /* Network type is now specified in device config. */ - net_is_slirp = config_net_type ? 1 : 0; net_is_pcap = config_net_type ? 0 : 1; if(!strcmp("nothing", config_get_string(NULL, "pcap_device", "nothing"))) { net_is_pcap = 0; - net_is_slirp = 1; + pcap_device_available = 0; } - pclog("net_is_pcap = %i, net_is_slirp = %i\n", net_is_pcap, net_is_slirp); - - // ne2000_log("ne2000 pcap device %s\n",config_get_string(NULL,"pcap_device","nothing")); - - pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); + else + { + pcap_device_available = 1; + } + ne2000_log("net_is_pcap = %i\n", net_is_pcap); + if (is_rtl8029as) + { + pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); + } + + ne2000_io_set(ne2000->base_address, ne2000); + + memcpy(ne2000->physaddr, maclocal, 6); + if (!disable_netbios) { - ne2000_rom_init(ne2000, "roms/rtl8029as.rom"); + ne2000_rom_init(ne2000, "roms/ne2000.rom"); - if (PCI) mem_mapping_disable(&ne2000->bios_rom.mapping); + if (is_rtl8029as) + { + mem_mapping_disable(&ne2000->bios_rom.mapping); + } } - + + if (is_rtl8029as) + { ne2000_pci_regs[0x04] = 1; ne2000_pci_regs[0x05] = 0; @@ -2020,411 +2001,398 @@ void *rtl8029as_init() rtl8029as_eeprom[0x77] = rtl8029as_eeprom[0x7B] = rtl8029as_eeprom[0x7F] = 0x80; rtl8029as_eeprom[0x78] = rtl8029as_eeprom[0x7C] = 0x10; rtl8029as_eeprom[0x79] = rtl8029as_eeprom[0x7D] = 0xEC; - - ne2000->base_address = 0x340; - ne2000_io_set(ne2000->base_address, ne2000); - - memcpy(ne2000->physaddr, maclocal, 6); + } - ne2000_reset(ne2000, BX_RESET_HARDWARE); - vlan_handler(ne2000_poller, ne2000); + ne2000_reset(ne2000, BX_RESET_HARDWARE); + vlan_handler(ne2000_poller, ne2000); - ne2000_log("ne2000 pci init 0x%X\tslirp is %d net_is_pcap is %d\n",ne2000->base_address,net_is_slirp,net_is_pcap); + ne2000_log("ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n",is_rtl8029as ? "pci" : "isa",ne2000->base_address,device_get_config_int("irq"),net_is_pcap); //need a switch statment for more network types. - - if ( net_is_slirp ) { - ne2000_log("ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - ne2000_log("ne2000 slirp_init returned: %d\n",rc); - if ( rc == 0 ) + if (!net_is_pcap) + { +initialize_slirp: + ne2000_log("ne2000 initalizing SLiRP\n"); + net_is_pcap=0; + rc=slirp_init(); + ne2000_log("ne2000 slirp_init returned: %d\n",rc); + if (!rc) { - ne2000_log("ne2000 slirp initalized!\n"); + ne2000_log("ne2000 slirp initalized!\n"); - net_slirp_inited=1; - slirpq = QueueCreate(); - net_is_slirp=1; - fizz=0; - ne2000_log("ne2000 slirpq is %x\n",&slirpq); - } - else { - net_slirp_inited=0; - net_is_slirp=0; - } - } - if ( net_is_pcap ) { //pcap - char errbuf[32768]; + net_slirp_inited = 1; + slirpq = QueueCreate(); + fizz=0; + ne2000_log("ne2000 slirpq is %x\n",&slirpq); + } + else + { + net_slirp_inited = 0; + if (pcap_device_available) + { + net_is_pcap = 1; + goto initialize_pcap; + } + else + { + ne2000_log("Neither SLiRP nor PCap is available on your host, disabling network adapter...\n"); + free(ne2000); + network_card_current = 0; + resetpchard(); + return NULL; + } + } + } + else + { +initialize_pcap: + ne2000_log("ne2000 initalizing libpcap\n"); - ne2000_log("ne2000 initalizing libpcap\n"); - net_is_slirp=0; - net_hLib = LoadLibraryA(net_lib_name); - if(net_hLib==0) - { - ne2000_log("ne2000 Failed to load %s\n",net_lib_name); - net_is_pcap=0; - //return; - } - _pcap_lib_version =(PCAP_LIB_VERSION)GetProcAddress(net_hLib,"pcap_lib_version"); - _pcap_open_live=(PCAP_OPEN_LIVE)GetProcAddress(net_hLib,"pcap_open_live"); - _pcap_sendpacket=(PCAP_SENDPACKET)GetProcAddress(net_hLib,"pcap_sendpacket"); - _pcap_setnonblock=(PCAP_SETNONBLOCK)GetProcAddress(net_hLib,"pcap_setnonblock"); - _pcap_next=(PCAP_NEXT)GetProcAddress(net_hLib,"pcap_next"); - _pcap_close=(PCAP_CLOSE)GetProcAddress(net_hLib,"pcap_close"); - _pcap_getnonblock=(PCAP_GETNONBLOCK)GetProcAddress(net_hLib,"pcap_getnonblock"); - _pcap_compile=(PCAP_COMPILE)GetProcAddress(net_hLib,"pcap_compile"); - _pcap_setfilter=(PCAP_SETFILTER)GetProcAddress(net_hLib,"pcap_setfilter"); - - if(_pcap_lib_version && _pcap_open_live && _pcap_sendpacket && _pcap_setnonblock && _pcap_next && _pcap_close && _pcap_getnonblock) - { - ne2000_log("ne2000 Pcap version [%s]\n",_pcap_lib_version()); + ne2000_log("ne2000 Pcap version [%s]\n",pcap_lib_version()); - //if((net_pcap=_pcap_open_live("\\Device\\NPF_{0CFA803F-F443-4BB9-A83A-657029A98195}",1518,1,15,errbuf))==0) - if((net_pcap=_pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; return(ne2000); //YUCK!!! - } - } - else { - ne2000_log("%d %d %d %d %d %d %d\n",_pcap_lib_version, _pcap_open_live,_pcap_sendpacket,_pcap_setnonblock,_pcap_next,_pcap_close,_pcap_getnonblock); - net_is_pcap=1; - } + if((net_pcap=pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) + { + ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); + net_is_pcap=0; + return(ne2000); // YUCK!!! + } - //Time to check that we are in non-blocking mode. - rc=_pcap_getnonblock(net_pcap,errbuf); - ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - ne2000_log("ne2000 Setting interface to non-blocking mode.."); - rc=_pcap_setnonblock(net_pcap,1,errbuf); - if(rc==0) { //no errors! - ne2000_log(".."); - rc=_pcap_getnonblock(net_pcap,errbuf); - if(rc==1) { - ne2000_log("..!",rc); - net_is_pcap=1; - } - else{ - ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - }//end set nonblock - else{ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} - ne2000_log("\n"); - break; - case 1: - ne2000_log("non blocking\n"); - break; - default: - ne2000_log("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if( net_is_pcap ) { - if(_pcap_compile && _pcap_setfilter) { //we can do this! - struct bpf_program fp; - char filter_exp[255]; - ne2000_log("ne2000 Building packet filter..."); - sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); + //Time to check that we are in non-blocking mode. + rc=pcap_getnonblock(net_pcap,errbuf); + ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); + switch(rc) + { + case 0: + ne2000_log("ne2000 Setting interface to non-blocking mode.."); + rc = pcap_setnonblock(net_pcap,1,errbuf); + if (rc==0) + { // no errors! + ne2000_log(".."); + rc=pcap_getnonblock(net_pcap,errbuf); + if(rc == 1) + { + ne2000_log("..!",rc); + net_is_pcap=1; + } + else + { + ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + net_is_pcap=0; + } + } // end set nonblock + else + { + ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} + ne2000_log("\n"); + break; + case 1: + ne2000_log("non blocking\n"); + break; + default: + ne2000_log("this isn't right!!!\n"); + net_is_pcap=0; + break; + } + if (net_is_pcap) + { + struct bpf_program fp; + char filter_exp[255]; + ne2000_log("ne2000 Building packet filter..."); + sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ + maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); - //I'm doing a MAC level filter so TCP/IP doesn't matter. - if (_pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { - ne2000_log("\nne2000 Couldn't compile filter\n"); - } - else { - ne2000_log("..."); - if (_pcap_setfilter(net_pcap, &fp) == -1) { - ne2000_log("\nError installing pcap filter.\n"); - }//end of set_filter failure - else { - ne2000_log("...!\n"); - } - } - ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); - //scanf(filter_exp); //pause - } - else - { - ne2000_log("ne2000 Your platform lacks pcap_compile & pcap_setfilter\n"); - net_is_pcap=0; - } - ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } - } //end pcap setup + //I'm doing a MAC level filter so TCP/IP doesn't matter. + if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) + { + ne2000_log("\nne2000 Couldn't compile filter\n"); + } + else + { + ne2000_log("..."); + if (pcap_setfilter(net_pcap, &fp) == -1) + { + ne2000_log("\nError installing pcap filter.\n"); + }//end of set_filter failure + else + { + ne2000_log("...!\n"); + } + } + ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); + } + else + { + pcap_device_available = 0; + goto initialize_slirp; + } + ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); + } // end pcap setup - //timer_add(slirp_tic,&delay,TIMER_ALWAYS_ENABLED,NULL); - //timer_add(keyboard_amstrad_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); -ne2000_log("ne2000 is_slirp %d is_pcap %d\n",net_is_slirp,net_is_pcap); -//exit(0); -return ne2000; + ne2000_log("ne2000 is_pcap %d\n", net_is_pcap); + return ne2000; } - void ne2000_close(void *p) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_io_remove(ne2000->base_address, ne2000); - free(ne2000); - - if(net_is_slirp) { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited=0; - ne2000_log("ne2000 exiting slirp\n"); - } - if(net_is_pcap && net_pcap!=NULL) - { - _pcap_close(net_pcap); - FreeLibrary(net_hLib); - ne2000_log("ne2000 closing pcap\n"); - } - ne2000_log("ne2000 close\n"); + ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_io_remove(ne2000->base_address, ne2000); + free(ne2000); + + if(!net_is_pcap) + { + QueueDestroy(slirpq); + slirp_exit(0); + net_slirp_inited=0; + ne2000_log("ne2000 exiting slirp\n"); + } + else if (net_is_pcap && (net_pcap != NULL)) + { + pcap_close(net_pcap); + ne2000_log("ne2000 closing pcap\n"); + } + ne2000_log("ne2000 close\n"); } static device_config_t ne2000_config[] = { - { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "0x280", - .value = 0x280 - }, - { - .description = "0x300", - .value = 0x300 - }, - { - .description = "0x320", - .value = 0x320 - }, - { - .description = "0x340", - .value = 0x340 - }, - { - .description = "0x360", - .value = 0x360 - }, - { - .description = "0x380", - .value = 0x380 - }, - { - .description = "" - } - }, - .default_int = 0x300 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "net_type", - .description = "Network type", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "PCap", - .value = 0 - }, - { - .description = "SLiRP", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "disable_netbios", - .description = "Network bios", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Enabled", - .value = 0 - }, - { - .description = "Disabled", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .type = -1 - } + { + .name = "addr", + .description = "Address", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "0x280", + .value = 0x280 + }, + { + .description = "0x300", + .value = 0x300 + }, + { + .description = "0x320", + .value = 0x320 + }, + { + .description = "0x340", + .value = 0x340 + }, + { + .description = "0x360", + .value = 0x360 + }, + { + .description = "0x380", + .value = 0x380 + }, + { + .description = "" + } + }, + .default_int = 0x300 + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "" + } + }, + .default_int = 10 + }, + { + .name = "net_type", + .description = "Network type", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "PCap", + .value = 0 + }, + { + .description = "SLiRP", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .name = "disable_netbios", + .description = "Network bios", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Enabled", + .value = 0 + }, + { + .description = "Disabled", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .type = -1 + } }; static device_config_t rtl8029as_config[] = { - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "" - } - }, - .default_int = 10 - }, - { - .name = "net_type", - .description = "Network type", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "PCap", - .value = 0 - }, - { - .description = "SLiRP", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "disable_netbios", - .description = "Network bios", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Enabled", - .value = 0 - }, - { - .description = "Disabled", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .type = -1 - } + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "" + } + }, + .default_int = 10 + }, + { + .name = "net_type", + .description = "Network type", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "PCap", + .value = 0 + }, + { + .description = "SLiRP", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .name = "disable_netbios", + .description = "Network bios", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Enabled", + .value = 0 + }, + { + .description = "Disabled", + .value = 1 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .type = -1 + } }; device_t ne2000_device = { - "Novell NE2000", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - ne2000_config + "Novell NE2000", + 0, + ne2000_init, + ne2000_close, + NULL, + NULL, + NULL, + NULL, + ne2000_config }; device_t rtl8029as_device = { - "Realtek RTL8029AS", - 0, - rtl8029as_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - rtl8029as_config + "Realtek RTL8029AS", + 0, + ne2000_init, + ne2000_close, + NULL, + NULL, + NULL, + NULL, + rtl8029as_config }; - //SLIRP stuff int slirp_can_output(void) { -return net_slirp_inited; + return net_slirp_inited; } void slirp_output (const unsigned char *pkt, int pkt_len) { -struct queuepacket *p; -p=(struct queuepacket *)malloc(sizeof(struct queuepacket)); -p->len=pkt_len; -memcpy(p->data,pkt,pkt_len); -QueueEnter(slirpq,p); -ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); + struct queuepacket *p; + p=(struct queuepacket *)malloc(sizeof(struct queuepacket)); + p->len=pkt_len; + memcpy(p->data,pkt,pkt_len); + QueueEnter(slirpq,p); + ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); } // Instead of calling this and crashing some times @@ -2432,28 +2400,32 @@ ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); // 60Hz clock which seems to do the job. void slirp_tic() { - int ret2,nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int timeout; - nfds=-1; + int ret2,nfds; + struct timeval tv; + fd_set rfds, wfds, xfds; + int timeout; + nfds=-1; - if(net_slirp_inited) - { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); //this can crash + if(net_slirp_inited) + { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); // this can crash + + if(timeout<0) + { + timeout=500; + } - if(timeout<0) - timeout=500; - tv.tv_sec=0; - tv.tv_usec = timeout; //basilisk default 10000 + tv.tv_sec=0; + tv.tv_usec = timeout; // basilisk default 10000 - ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - if(ret2>=0){ - slirp_select_poll(&rfds, &wfds, &xfds); - } - //ne2000_log("ne2000 slirp_tic()\n"); - }//end if slirp inited + ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); + if(ret2>=0) + { + slirp_select_poll(&rfds, &wfds, &xfds); + } + //ne2000_log("ne2000 slirp_tic()\n"); + } // end if slirp inited } diff --git a/src/nethandler.c b/src/nethandler.c index b926d1cbe..76e239de5 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -14,6 +14,7 @@ #include "ne2000.h" #include "timer.h" +#include "thread.h" int network_card_current = 0; static int network_card_last = 0; @@ -83,19 +84,95 @@ void vlan_handler(void (*poller)(void *p), void *p) vlan_handlers_num++; } +static thread_t *network_thread_h; +static event_t *network_event; + +static int network_thread_initialized = 0; +static int network_thread_enable = 0; + +static void network_thread(void *param) +{ + int c; + + // pclog("Network thread\n"); + + while(1) + { + // pclog("Waiting...\n"); + thread_wait_event(network_event, -1); + + // pclog("Processing\n"); + + for (c = 0; c < vlan_handlers_num; c++) + vlan_handlers[c].poller(vlan_handlers[c].priv); + } +} + +void network_thread_init() +{ + pclog("network_thread_init()\n"); + + if (network_card_current) + { + pclog("Thread enabled...\n"); + + network_event = thread_create_event(); + network_thread_h = thread_create(network_thread, NULL); + } + + network_thread_enable = network_card_current ? 1 : 0; + network_thread_initialized = 1; +} + +void network_thread_reset() +{ + if(!network_thread_initialized) + { + network_thread_init(); + return; + } + + pclog("network_thread_reset()\n"); + if (network_card_current && !network_thread_enable) + { + pclog("Thread enabled (disabled before...\n"); + network_event = thread_create_event(); + network_thread_h = thread_create(network_thread, NULL); + } + else if (!network_card_current && network_thread_enable) + { + pclog("Thread disabled (enabled before...\n"); + thread_destroy_event(network_event); + thread_kill(network_thread_h); + network_thread_h = NULL; + } + + network_thread_enable = network_card_current ? 1 : 0; +} + void vlan_poller(void *priv) { int c; - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0)); + vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 15000.0)); - for (c = 0; c < vlan_handlers_num; c++) - vlan_handlers[c].poller(vlan_handlers[c].priv); + if (network_thread_enable && vlan_handlers_num) + { + // pclog("Setting thread event...\n"); + thread_set_event(network_event); + } } void vlan_reset() { - timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); + pclog("vlan_reset()\n"); + + if (network_card_current) + { + pclog("Adding timer...\n"); + + timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); + } vlan_handlers_num = 0; } diff --git a/src/pc.c b/src/pc.c index ab4e2f7b6..915232cef 100644 --- a/src/pc.c +++ b/src/pc.c @@ -315,11 +315,14 @@ void initpc(int argc, char *argv[]) td0_init(); imd_init(); +#if 0 if (network_card_current != 0) { vlan_reset(); //NETWORK } network_card_init(network_card_current); + network_thread_init(); +#endif disc_load(0, discfns[0]); disc_load(1, discfns[1]); @@ -442,6 +445,7 @@ void resetpchard() vlan_reset(); //NETWORK } network_card_init(network_card_current); + network_thread_reset(); for (i = 0; i < CDROM_NUM; i++) { diff --git a/src/pc87306.c b/src/pc87306.c index cb67e05e7..e3e930117 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -19,7 +19,7 @@ static int pc87306_locked; static int pc87306_curreg; static uint8_t pc87306_regs[29]; -static uint8_t pc87306_gpio[2] = {0xFF, 0xFF}; +static uint8_t pc87306_gpio[2] = {0xFF, 0xFB}; static uint8_t tries; static uint16_t lpt_port; static int power_down = 0; @@ -29,10 +29,7 @@ void pc87306_gpio_init(); void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) { - if (port & 1) - { - return; - } + // pclog("GPIO: Writing %02X on port: %04X\n", val, port); pc87306_gpio[port & 1] = val; } @@ -167,13 +164,17 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { if (tries) { + if ((pc87306_curreg == 0) && (val == 8)) + { + val = 0x4b; + } if (pc87306_curreg <= 28) valxor = val ^ pc87306_regs[pc87306_curreg]; tries = 0; if ((pc87306_curreg == 0x19) && !(pc87306_regs[0x1B] & 0x40)) { return; } - if ((pc87306_curreg <= 28) && (pc87306_curreg != 8) && (pc87306_curreg != 0x18)) + if ((pc87306_curreg <= 28) && (pc87306_curreg != 8)/* && (pc87306_curreg != 0x18)*/) { if (pc87306_curreg == 0) { @@ -183,8 +184,8 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { pc87306_gpio_remove(); } - pc87306_regs[pc87306_curreg] = val; // pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]); + pc87306_regs[pc87306_curreg] = val; goto process_value; } } @@ -237,7 +238,7 @@ process_value: break; case 1: - if (valxor & 1) + if (valxor & 3) { lpt1_remove(); if (pc87306_regs[0] & 1) @@ -248,22 +249,26 @@ process_value: if (valxor & 0xcc) { - serial1_remove(); - if (pc87306_regs[0] & 2) { serial1_handler(); } + else + { + serial1_remove(); + } } if (valxor & 0xf0) { - serial2_remove(); - if (pc87306_regs[0] & 4) { serial2_handler(); } + else + { + serial2_remove(); + } } break; case 2: @@ -344,11 +349,8 @@ process_value: } break; case 0x1C: - // if (valxor & 0x25) if (valxor) { - serial1_remove(); - serial2_remove(); if (pc87306_regs[0] & 2) { serial1_handler(); @@ -364,10 +366,7 @@ process_value: uint8_t pc87306_gpio_read(uint16_t port, void *priv) { - if (port & 1) - { - return 0xfb; /* Bit 2 clear, since we don't emulate the on-board audio. */ - } + // pclog("Read GPIO on port: %04X (%04X:%04X)\n", port, CS, cpu_state.pc); return pc87306_gpio[port & 1]; } @@ -393,14 +392,9 @@ uint8_t pc87306_read(uint16_t port, void *priv) } else if (pc87306_curreg == 8) { - // pclog("PC87306: Read ID at data register, index 08\n"); + // pclog("PC87306: Read ID at data register, index 08 (%04X:%04X)\n", CS, cpu_state.pc); return 0x70; } - else if (pc87306_curreg == 5) - { - // pclog("PC87306: Read value %02X at data register, index 05\n", pc87306_regs[pc87306_curreg] | 4); - return pc87306_regs[pc87306_curreg] | 4; - } else { // pclog("PC87306: Read value %02X at data register, index %02X\n", pc87306_regs[pc87306_curreg], pc87306_curreg); @@ -433,10 +427,11 @@ void pc87306_reset(void) pc87306_regs[0] = 0x4B; pc87306_regs[1] = 0x01; - pc87306_regs[3] = 2; - pc87306_regs[5] = 0xD; + pc87306_regs[3] = 0x01; + pc87306_regs[5] = 0x0D; pc87306_regs[8] = 0x70; - pc87306_regs[9] = 0xFF; + pc87306_regs[9] = 0xC0; + pc87306_regs[0xB] = 0x80; pc87306_regs[0xF] = 0x1E; pc87306_regs[0x12] = 0x30; pc87306_regs[0x19] = 0xEF; @@ -449,12 +444,13 @@ void pc87306_reset(void) fdc_update_densel_polarity(1); fdc_update_max_track(85); fdc_remove(); - fdc_add(0x3f0, 0); + fdc_set_base(0x3f0, 0); fdd_swap = 0; serial1_remove(); serial2_remove(); serial1_handler(); serial2_handler(); + pc87306_gpio_init(); } void pc87306_init() diff --git a/src/serial.c b/src/serial.c index e753aa1cf..da41b00f9 100644 --- a/src/serial.c +++ b/src/serial.c @@ -85,6 +85,7 @@ uint8_t serial_read_fifo(SERIAL *serial) void serial_write(uint16_t addr, uint8_t val, void *p) { SERIAL *serial = (SERIAL *)p; + // pclog("Serial: Write value %02X on port: %04X\n", val, addr); // pclog("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr&7) { @@ -169,7 +170,7 @@ uint8_t serial_read(uint16_t addr, void *p) { SERIAL *serial = (SERIAL *)p; uint8_t temp = 0; -// pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, pc, mousedelay, ins); + // pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, cpu_state.pc, mousedelay, ins); switch (addr&7) { case 0: @@ -228,6 +229,7 @@ uint8_t serial_read(uint16_t addr, void *p) break; } // pclog("%02X\n",temp); + // pclog("Serial: Read value %02X on port: %04X\n", temp, addr); return temp; } @@ -245,6 +247,9 @@ void serial_recieve_callback(void *p) } } +uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; +int serial_irq[2] = { 4, 3 }; + /*Tandy might need COM1 at 2f8*/ void serial1_init(uint16_t addr, int irq) { @@ -253,6 +258,8 @@ void serial1_init(uint16_t addr, int irq) serial1.irq = irq; serial1.rcr_callback = NULL; timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); + serial_addr[0] = addr; + serial_irq[0] = irq; } void serial1_set(uint16_t addr, int irq) { @@ -260,18 +267,12 @@ void serial1_set(uint16_t addr, int irq) io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); serial1.irq = irq; // pclog("serial1_set(%04X, %02X)\n", addr, irq); + serial_addr[0] = addr; + serial_irq[0] = irq; } void serial1_remove() { - io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } void serial2_init(uint16_t addr, int irq) @@ -281,6 +282,8 @@ void serial2_init(uint16_t addr, int irq) serial2.irq = irq; serial2.rcr_callback = NULL; timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + serial_addr[1] = addr; + serial_irq[1] = irq; } void serial2_set(uint16_t addr, int irq) { @@ -288,16 +291,10 @@ void serial2_set(uint16_t addr, int irq) io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); serial2.irq = irq; // pclog("serial2_set(%04X, %02X)\n", addr, irq); + serial_addr[1] = addr; + serial_irq[1] = irq; } void serial2_remove() { - io_removehandler(0x208, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x228, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x238, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x2e0, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x2e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x2f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x338, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x3e8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - io_removehandler(0x3f8, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); } diff --git a/src/sound_dbopl.cc b/src/sound_dbopl.cc index 13f87df44..8f7463357 100644 --- a/src/sound_dbopl.cc +++ b/src/sound_dbopl.cc @@ -84,18 +84,18 @@ void opl_timer_over(int nr, int timer) void opl_write(int nr, uint16_t addr, uint8_t val) { if (!(addr & 1)) - { - if (!opl[nr].is_opl3) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff; - else - opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; - } + { + if (!opl[nr].is_opl3 || !opl3_type) + opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff; + else + opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; + } else { - if (!opl[nr].is_opl3) - opl[nr].chip.WriteReg(opl[nr].addr, val); - else - OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); + if (!opl[nr].is_opl3 || !opl3_type) + opl[nr].chip.WriteReg(opl[nr].addr, val); + else + OPL3_WriteReg(&opl[nr].opl3chip, opl[nr].addr, val); switch (opl[nr].addr) { diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 172a6e17e..17a1f3dec 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -964,8 +964,8 @@ enum enum { - BLTCMD_SRC_TILED = (1 << 10), - BLTCMD_DST_TILED = (1 << 12) + BLTCMD_SRC_TILED = (1 << 14), + BLTCMD_DST_TILED = (1 << 15) }; #define TEXTUREMODE_MASK 0x3ffff000 @@ -1086,7 +1086,9 @@ static void voodoo_recalc(voodoo_t *voodoo) voodoo->block_width = ((voodoo->fbiInit1 >> 4) & 15) * 2; if (voodoo->fbiInit6 & (1 << 30)) - voodoo->fbiInit1 += 1; + voodoo->block_width += 1; + if (voodoo->fbiInit1 & (1 << 24)) + voodoo->block_width += 32; voodoo->row_width = voodoo->block_width * 32 * 2; /* pclog("voodoo_recalc : front_offset %08X back_offset %08X aux_offset %08X draw_offset %08x\n", voodoo->params.front_offset, voodoo->back_offset, voodoo->params.aux_offset, voodoo->params.draw_offset); @@ -2714,7 +2716,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood goto next_line; state->fb_mem = fb_mem = &voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = &voodoo->fb_mem[params->aux_offset + (real_y * voodoo->row_width)]; + state->aux_mem = aux_mem = &voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; if (voodoo_output) pclog("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, state->xstart, state->xend, dx, start_x2); @@ -3100,7 +3102,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (params->fbzMode & FBZ_RGB_WMASK) fb_mem[x] = src_b | (src_g << 5) | (src_r << 11); - if (params->fbzMode & FBZ_DEPTH_WMASK) + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) aux_mem[x] = new_depth; } } @@ -3769,6 +3771,7 @@ static void blit_start(voodoo_t *voodoo) { uint16_t src_dat = src[src_x]; uint16_t dst_dat = dst[dst_x]; + int rop = 0; if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) { @@ -3776,8 +3779,31 @@ static void blit_start(voodoo_t *voodoo) dst_y < voodoo->bltClipLowY || dst_y > voodoo->bltClipHighY) goto skip_pixel_blit; } - - MIX(src_dat, dst_dat, voodoo->bltRop[3]); + + if (voodoo->bltCommand & BLIT_SRC_CHROMA) + { + int r = (src_dat >> 11); + int g = (src_dat >> 5) & 0x3f; + int b = src_dat & 0x1f; + + if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && + g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && + b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB) + rop |= BLIT_ROP_SRC_PASS; + } + if (voodoo->bltCommand & BLIT_DST_CHROMA) + { + int r = (dst_dat >> 11); + int g = (dst_dat >> 5) & 0x3f; + int b = dst_dat & 0x1f; + + if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && + g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && + b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB) + rop |= BLIT_ROP_DST_PASS; + } + + MIX(src_dat, dst_dat, voodoo->bltRop[rop]); dst[dst_x] = dst_dat; skip_pixel_blit: @@ -3855,7 +3881,7 @@ skip_pixel_fill: size_x = voodoo->bltSizeX & 0x1ff; } - dst = (uint64_t *)&voodoo->fb_mem[dst_y*512*8 + dst_x*8]; + dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask]; for (x = 0; x <= size_x; x++) dst[x] = dat64; @@ -4429,12 +4455,28 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_clipLeftRight: - voodoo->params.clipRight = val & 0x3ff; - voodoo->params.clipLeft = (val >> 16) & 0x3ff; + if (voodoo->type >= VOODOO_2) + { + voodoo->params.clipRight = val & 0xfff; + voodoo->params.clipLeft = (val >> 16) & 0xfff; + } + else + { + voodoo->params.clipRight = val & 0x3ff; + voodoo->params.clipLeft = (val >> 16) & 0x3ff; + } break; case SST_clipLowYHighY: - voodoo->params.clipHighY = val & 0x3ff; - voodoo->params.clipLowY = (val >> 16) & 0x3ff; + if (voodoo->type >= VOODOO_2) + { + voodoo->params.clipHighY = val & 0xfff; + voodoo->params.clipLowY = (val >> 16) & 0xfff; + } + else + { + voodoo->params.clipHighY = val & 0x3ff; + voodoo->params.clipLowY = (val >> 16) & 0x3ff; + } break; case SST_nopCMD: @@ -6285,7 +6327,7 @@ static void fifo_thread(void *param) break; default: - fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); + pclog("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp); } end_time = timer_read(); diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/vid_voodoo_codegen_x86-64.h index 8d3cc7271..855830a78 100644 --- a/src/vid_voodoo_codegen_x86-64.h +++ b/src/vid_voodoo_codegen_x86-64.h @@ -434,7 +434,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0c); addbyte(0x82); - if (state->clamp_s) + if (state->clamp_s[tmu]) { addbyte(0xeb); /*JMP +*/ addbyte(5+5+4+4); @@ -607,7 +607,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0xe8); addbyte(0xd3); /*SHR EBX, CL*/ addbyte(0xeb); - if (state->clamp_s) + if (state->clamp_s[tmu]) { addbyte(0x85); /*TEST EAX, EAX*/ addbyte(0xc0); @@ -634,7 +634,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8e); addlong(offsetof(voodoo_params_t, tex_w_mask[tmu]) - 0x10); } - if (state->clamp_t) + if (state->clamp_t[tmu]) { addbyte(0x85); /*TEST EBX, EBX*/ addbyte(0xdb); @@ -2980,7 +2980,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); } - if (params->fbzMode & FBZ_DEPTH_WMASK) + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index d10f3bbcc..f0aba4a59 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -227,8 +227,8 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV ECX, [ECX+EAX*4]*/ addbyte(0x0c); addbyte(0x81); - addbyte(0xbd); /*MOV EBP, 1*/ - addlong(1); + addbyte(0xbd); /*MOV EBP, 8*/ + addlong(8); addbyte(0x28); /*SUB DL, CL*/ addbyte(0xca); addbyte(0xd3); /*SHL EBP, CL*/ @@ -236,9 +236,6 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x8b); /*MOV EAX, state->tex_s[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, tex_s)); - addbyte(0xc1); /*SHL EBP, 3*/ - addbyte(0xe5); - addbyte(3); addbyte(0x8b); /*MOV EBX, state->tex_t[EDI]*/ addbyte(0x9f); addlong(offsetof(voodoo_state_t, tex_t)); @@ -416,7 +413,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0c); addbyte(0x82); - if (state->clamp_s) + if (state->clamp_s[tmu]) { addbyte(0xeb); /*JMP +*/ addbyte(5+5+4+4); @@ -2972,7 +2969,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x56); } - if (params->fbzMode & FBZ_DEPTH_WMASK) + if ((params->fbzMode & (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) == (FBZ_DEPTH_WMASK | FBZ_DEPTH_ENABLE)) { addbyte(0x66); /*MOV AX, new_depth*/ addbyte(0x8b); diff --git a/src/x86seg.c b/src/x86seg.c index a6db3f8ac..e19775b24 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -2036,20 +2036,16 @@ void pmodeiret(int is32) addr=seg&~7; if (seg&4) { - if (addr>=ldt.limit) - { - // pclog("TS Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); - x86gpf(NULL,seg&~3); - return; - } - addr+=ldt.base; + pclog("TS LDT %04X %04X IRET\n",seg,gdt.limit); + x86ts(NULL,seg&~3); + return; } else { if (addr>=gdt.limit) { // pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); - x86gpf(NULL,seg&~3); + x86ts(NULL,seg&~3); return; } addr+=gdt.base; From 49c2f3efe57a530590c6ab5a86f06e5aaa6e8e73 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 7 Feb 2017 03:58:20 +0100 Subject: [PATCH 064/392] fdc_hard_reset() no longer calls disc_reset() - fixes too fast floppy timings due to double timers. --- src/fdc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fdc.c b/src/fdc.c index 57532b4a2..0784bd998 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -2208,7 +2208,6 @@ void fdc_hard_reset() swwp = 0; disable_write = 0; - disc_reset(); fdc_reset(); fdc.max_track = 79; From 49278204d4ef15a73bfd95cc341ad054c757e15f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 7 Feb 2017 04:44:04 +0100 Subject: [PATCH 065/392] The code to add a timer now makes sure to only add the timer if an identical timer is not already present. --- src/timer.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/timer.c b/src/timer.c index 45268869e..7020fdf6c 100644 --- a/src/timer.c +++ b/src/timer.c @@ -98,8 +98,22 @@ void timer_reset() int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv) { + int i = 0; + if (timers_present < TIMERS_MAX) { + if (timers_present != 0) + { + /* This is the sanity check - it goes through all present timers and makes sure we're not adding a timer that already exists. */ + for (i = 0; i < timers_present; i++) + { + if (timers[i].present && (timers[i].callback == callback) && (timers[i].priv == priv) && (timers[i].count == count) && (timers[i].enable == enable)) + { + return; + } + } + } + // pclog("timer_add : adding timer %i\n", timers_present); timers[timers_present].present = 1; timers[timers_present].callback = callback; From adf9c28e618f8f081a62a41f4cf364eeab42dc5a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 Feb 2017 18:42:20 +0100 Subject: [PATCH 066/392] ATAPI DMA now tells the bus master the correct length to transfer; ATAPI DMA now transfers all blocks at once. --- src/cdrom.c | 23 +++++++++++++++++++++-- src/cdrom.h | 2 ++ src/ide.c | 10 ++++++---- src/piix.c | 8 ++++++-- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index a71ba8b60..7e16287a3 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -973,6 +973,10 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0; } + else + { + cdrom[id].init_length = 0; + } cdrom_command_complete(id); } else @@ -985,6 +989,10 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; } + else + { + cdrom[id].init_length = alloc_len; + } cdrom_command_read_dma(id); } else @@ -1963,7 +1971,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } max_len = cdrom[id].sector_len; - if (cdrom_drives[id].bus_type) + // if (cdrom_drives[id].bus_type) + if (cdrom_current_mode(id) == 2) { cdrom[id].requested_blocks = max_len; } @@ -2732,6 +2741,14 @@ int cdrom_block_check(uint8_t id) int alloc_length = 0; int ret = 0; + if (!cdrom_drives[id].bus_type) + { + cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); + ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); + } + + cdrom[id].status = BUSY_STAT; + /* If this is a media access command, and we hit the end of the block but not the entire length, read the next block. */ if (cdrom_is_media_access(id)) @@ -2787,6 +2804,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ int ret = 0; int old_pos = 0; +#if 0 if (!cdrom_drives[id].bus_type) { cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); @@ -2794,6 +2812,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ } cdrom[id].status = BUSY_STAT; +#endif if (cdrom[id].total_read >= cdrom[id].packet_len) { @@ -2963,7 +2982,7 @@ int cdrom_write_to_ide_dma(uint8_t channel) if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].request_length)) + if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].init_length)) { cdrom_data_phase_error(id); cdrom_phase_callback(id); diff --git a/src/cdrom.h b/src/cdrom.h index 08dc4ffc2..78731c317 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -112,6 +112,8 @@ typedef struct __attribute__((__packed__)) int old_len; int block_descriptor_len; + + int init_length; } cdrom_t; extern cdrom_t cdrom[CDROM_NUM]; diff --git a/src/ide.c b/src/ide.c index eb98e78d2..be9c920e0 100644 --- a/src/ide.c +++ b/src/ide.c @@ -206,10 +206,11 @@ void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { + // ide_log("Not raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); return; } - // ide_log("Raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); + ide_log("Raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); if (!(ide->fdisk&2)) { @@ -234,10 +235,11 @@ void ide_irq_lower(IDE *ide) { if ((ide->board > 3) || !(ide->irqstat)) { + // ide_log("Not lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); return; } - // ide_log("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); + ide_log("Lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); picintc(1 << ide_irq[ide->board]); ide->irqstat=0; @@ -1393,7 +1395,7 @@ uint8_t readide(int ide_board, uint16_t addr) case 0x1F0: /* Data */ // temp = ide_read_data(ide_board, 1); tempw = readidew(ide_board); - // pclog("Read IDEW %04X\n", tempw); + // ide_log("Read IDEW %04X\n", tempw); temp = tempw & 0xff; break; @@ -1549,7 +1551,7 @@ uint16_t readidew(int ide_board) uint32_t readidel(int ide_board) { uint16_t temp; - // pclog("Read IDEl %i\n", ide_board); + // ide_log("Read IDEl %i\n", ide_board); temp = readidew(ide_board); return temp | (readidew(ide_board) << 16); } diff --git a/src/piix.c b/src/piix.c index d0672e63d..b6351e4a6 100644 --- a/src/piix.c +++ b/src/piix.c @@ -409,7 +409,7 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) while (transferred < transfer_length) { if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Read count less than transfer_length! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + fatal("DMA on channel %i - Read count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + transfer_length - 1); @@ -451,14 +451,18 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) { int transferred = 0; + + // pclog("piix_bus_master_dma_write(%08X, %08X, %08X) on %08X data\n", channel, data, transfer_length, piix_busmaster[channel].count); if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ + pclog("DMA not disabled\n"); + while (transferred < transfer_length) { if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Write count less than transfer_length! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + fatal("DMA on channel %i - Write count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); if (piix_busmaster[channel].count < (transfer_length - transferred)) { From 3d8f05472173b5bac23c5ea214cfd617117ac084 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 8 Feb 2017 20:14:57 +0100 Subject: [PATCH 067/392] The network is now single-thread again, and the speed is correspondingly lower. --- src/nethandler.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/nethandler.c b/src/nethandler.c index 76e239de5..2d42fc4b6 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -96,20 +96,21 @@ static void network_thread(void *param) // pclog("Network thread\n"); - while(1) - { + // while(1) + // { // pclog("Waiting...\n"); - thread_wait_event(network_event, -1); + // thread_wait_event(network_event, -1); // pclog("Processing\n"); for (c = 0; c < vlan_handlers_num; c++) vlan_handlers[c].poller(vlan_handlers[c].priv); - } + // } } void network_thread_init() { +#if 0 pclog("network_thread_init()\n"); if (network_card_current) @@ -122,10 +123,12 @@ void network_thread_init() network_thread_enable = network_card_current ? 1 : 0; network_thread_initialized = 1; +#endif } void network_thread_reset() { +#if 0 if(!network_thread_initialized) { network_thread_init(); @@ -148,18 +151,20 @@ void network_thread_reset() } network_thread_enable = network_card_current ? 1 : 0; +#endif } void vlan_poller(void *priv) { int c; - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 15000.0)); + vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0)); if (network_thread_enable && vlan_handlers_num) { // pclog("Setting thread event...\n"); - thread_set_event(network_event); + // thread_set_event(network_event); + network_thread(priv); } } From f5ebf5b7a8eba747784843baac9e1db291e2c269 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 9 Feb 2017 01:41:32 +0100 Subject: [PATCH 068/392] ATAPI DMA is now scatter gather-aware. --- src/cdrom-ioctl.c | 2 +- src/cdrom.c | 25 +++++++++++++++++++- src/piix.c | 58 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 76 insertions(+), 9 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index f922dea9a..ba8d1f9c3 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -829,7 +829,7 @@ static void ioctl_validate_toc(uint8_t id) cdrom_ioctl[id].tocvalid=1; } -UCHAR buf[65536]; +UCHAR buf[262144]; static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) { diff --git a/src/cdrom.c b/src/cdrom.c index 7e16287a3..b0acbe5c0 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2973,6 +2973,12 @@ int cdrom_write_to_ide_dma(uint8_t channel) uint8_t id = atapi_cdrom_drives[channel]; + int transfer_length = 0; + int cdbufferb_pos = 0; + + int bus_master_len = 0; + int ret = 0; + if (id > CDROM_NUM) { return 0; @@ -2980,16 +2986,33 @@ int cdrom_write_to_ide_dma(uint8_t channel) cdbufferb = (uint8_t *) cdrom[id].buffer; + transfer_length = cdrom[id].init_length; + if (ide_bus_master_read) { - if (ide_bus_master_read(channel >> 1, cdbufferb, cdrom[id].init_length)) + while(transfer_length > 0) { + // pclog("CD-ROM %i: ATAPI DMA on position: %08X...\n", id, cdbufferb + cdbufferb_pos); + bus_master_len = piix_bus_master_get_count(channel >> 1); + ret = piix_bus_master_dma_read_ex(channel >> 1, cdbufferb + cdbufferb_pos); + if (ret != 0) + { + break; + } + transfer_length -= bus_master_len; + cdbufferb_pos += bus_master_len; + } + + if (ret > 0) + { + // pclog("CD-ROM %i: ATAPI DMA error\n", id); cdrom_data_phase_error(id); cdrom_phase_callback(id); return 0; } else { + // pclog("CD-ROM %i: ATAPI DMA successful\n", id); return 1; } } diff --git a/src/piix.c b/src/piix.c index b6351e4a6..4f81ffd2b 100644 --- a/src/piix.c +++ b/src/piix.c @@ -399,6 +399,46 @@ uint8_t piix_bus_master_read(uint16_t port, void *priv) return 0xff; } +int piix_bus_master_get_count(int channel) +{ + return piix_busmaster[channel].count; +} + +int piix_bus_master_get_eot(int channel) +{ + return piix_busmaster[channel].eot; +} + +int piix_bus_master_dma_read_ex(int channel, uint8_t *data) +{ + int transferred = 0; + + if (!(piix_busmaster[channel].status & 1)) + return 1; /*DMA disabled*/ + + mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + piix_busmaster[channel].count - 1); + + // pclog("Transferring special - %i bytes\n", piix_busmaster[channel].count); + memcpy(&ram[piix_busmaster[channel].addr], data, piix_busmaster[channel].count); + transferred += piix_busmaster[channel].count; + piix_busmaster[channel].addr += piix_busmaster[channel].count; + piix_busmaster[channel].addr %= (mem_size * 1024); + piix_busmaster[channel].count = 0; + + if (piix_busmaster[channel].eot) /*End of transfer?*/ + { + // pclog("DMA on channel %i - transfer over\n", channel); + piix_busmaster[channel].status &= ~1; + return -1; + } + else + { + // pclog("DMA on channel %i - transfer continuing\n", channel); + piix_bus_master_next_addr(channel); + } + return 0; +} + int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) { int transferred = 0; @@ -408,8 +448,10 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) while (transferred < transfer_length) { - if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Read count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + if ((piix_busmaster[channel].count < (transfer_length - transferred)) && piix_busmaster[channel].eot && (transfer_length == 512)) + { + fatal("DMA on channel %i - Read count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + } mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + transfer_length - 1); @@ -431,14 +473,14 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) transferred += (transfer_length - transferred); } -// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); if (!piix_busmaster[channel].count) { -// pclog("DMA on channel %i - block over\n", channel); + // pclog("DMA on channel %i - block over\n", channel); if (piix_busmaster[channel].eot) /*End of transfer?*/ { -// pclog("DMA on channel %i - transfer over\n", channel); + // pclog("DMA on channel %i - transfer over\n", channel); piix_busmaster[channel].status &= ~1; } else @@ -461,8 +503,10 @@ int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) while (transferred < transfer_length) { - if (piix_busmaster[channel].count < (transfer_length - transferred) && piix_busmaster[channel].eot) - fatal("DMA on channel %i - Write count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + if ((piix_busmaster[channel].count < (transfer_length - transferred)) && piix_busmaster[channel].eot && (transfer_length == 512)) + { + fatal("DMA on channel %i - Write count less than %04X! Addr %08X Count %04X EOT %i\n", channel, transfer_length, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); + } if (piix_busmaster[channel].count < (transfer_length - transferred)) { From 9a5dbc80abbfec4c888ee6725c4279ed066fc431 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 Feb 2017 04:16:16 +0100 Subject: [PATCH 069/392] Added emulation of BusLogic BT-958 PCI SCSI controller; SCSI controller configuration moved to the Settings dialog, suggestion by RichardG. --- src/buslogic.c | 607 ++++++++++++++++++++++++++++++++++++++++++++--- src/ibm.h | 2 - src/pc.c | 10 - src/pc.rc | 37 +-- src/resources.h | 20 +- src/win-config.c | 16 +- src/win.c | 209 ---------------- 7 files changed, 596 insertions(+), 305 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 293601837..263368708 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -3,6 +3,11 @@ */ /*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/ +/* Emulated SCSI controllers: + 0 - Adaptec AHA-154xB ISA; + 1 - BusLogic BT-542B ISA; + 2 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ + #include #include #include @@ -16,6 +21,7 @@ #include "rom.h" #include "dma.h" #include "pic.h" +#include "pci.h" #include "timer.h" #include "scsi.h" @@ -509,6 +515,9 @@ typedef struct __attribute__((packed)) Buslogic_t uint32_t MailboxOutPosCur; uint32_t MailboxInAddr; uint32_t MailboxInPosCur; + int Base; + int PCIBase; + int MMIOBase; int Irq; int DmaChannel; int IrqEnabled; @@ -517,20 +526,34 @@ typedef struct __attribute__((packed)) Buslogic_t int MbiActive[256]; int PendingInterrupt; int Lock; + mem_mapping_t mmio_mapping; } Buslogic_t; int scsi_model = 1; -int scsi_base = 0x330; -int scsi_dma = 6; -int scsi_irq = 11; int BuslogicCallback = 0; int BuslogicInOperation = 0; -int buslogic_do_log = 0; +/** Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ +typedef struct __attribute__((packed)) BuslogicPCIInformation_t +{ + uint8_t IsaIOPort; + uint8_t IRQ; + unsigned char LowByteTerminated:1; + unsigned char HighByteTerminated:1; + unsigned char uReserved:2; /* Reserved. */ + unsigned char JP1:1; /* Whatever that means. */ + unsigned char JP2:1; /* Whatever that means. */ + unsigned char JP3:1; /* Whatever that means. */ + /** Whether the provided info is valid. */ + unsigned char InformationIsValid:1; + uint8_t uReserved2; /* Reserved. */ +} BuslogicPCIInformation_t; static void BuslogicStartMailbox(Buslogic_t *Buslogic); +int buslogic_do_log = 0; + void BuslogicLog(const char *format, ...) { #ifdef ENABLE_BUSLOGIC_LOG @@ -545,6 +568,18 @@ void BuslogicLog(const char *format, ...) #endif } +static int BuslogicIsPCI() +{ + if (PCI && (scsi_model == 2)) + { + return 1; + } + else + { + return 0; + } +} + static void BuslogicClearInterrupt(Buslogic_t *Buslogic) { BuslogicLog("Buslogic: Lowering Interrupt 0x%02X\n", Buslogic->Interrupt); @@ -1053,11 +1088,24 @@ uint8_t BuslogicRead(uint16_t Port, void *p) Temp = Buslogic->Geometry; break; } - - // BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); + + if (Port < 0x1000) + { + BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); + } return Temp; } +uint16_t BuslogicReadW(uint16_t Port, void *p) +{ + return BuslogicRead(Port, p); +} + +uint32_t BuslogicReadL(uint16_t Port, void *p) +{ + return BuslogicRead(Port, p); +} + int buslogic_scsi_drive_is_cdrom(uint8_t id, uint8_t lun) { if (lun > 7) @@ -1082,6 +1130,9 @@ int buslogic_scsi_drive_is_cdrom(uint8_t id, uint8_t lun) } } +void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); +void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); + void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) { int i = 0; @@ -1190,9 +1241,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->CmdParamLeft = scsi_model ? 0 : 2; break; - case 0x28: case 0x86: //Valid only for PCI + Buslogic->CmdParamLeft = 0; + break; + + case 0x8C: case 0x95: //Valid only for PCI + Buslogic->CmdParamLeft = BuslogicIsPCI() ? 1 : 0; + break; + + case 0x28: Buslogic->CmdParamLeft = 0; break; } @@ -1277,17 +1335,17 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x0A: - for (i = 0; i < max_id; i++) + memset(Buslogic->DataBuf, 0, 8); + for (i = 0; i < 6; i++) { for (j = 0; j < 8; j++) { if (buslogic_scsi_drive_is_cdrom(i, j)) Buslogic->DataBuf[i] = 1; - - Buslogic->DataBuf[7] = 0; - Buslogic->DataReplyLeft = 8; } } + Buslogic->DataBuf[7] = 0; + Buslogic->DataReplyLeft = 8; break; case 0x0B: @@ -1302,6 +1360,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; ReplyInquireSetupInformation *Reply = (ReplyInquireSetupInformation *)Buslogic->DataBuf; + memset(Reply, 0, sizeof(ReplyInquireSetupInformation)); Reply->fSynchronousInitiationEnabled = 1; Reply->fParityCheckingEnabled = 1; @@ -1315,7 +1374,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) * friendly with Adaptec hardware and upsetting the HBA state. */ Reply->uCharacterD = 'D'; /* BusLogic model. */ - Reply->uHostBusType = 'A'; /* ISA bus. */ + Reply->uHostBusType = BuslogicIsPCI() ? 'F' : 'A'; /* ISA bus. */ } BuslogicLog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]); @@ -1323,15 +1382,23 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x23: - for (i = 0; i < max_id; i++) + if (scsi_model) { - for (i = 0; j < 8; j++) + memset(Buslogic->DataBuf, 0, 8); + for (i = 8; i < max_id; i++) { - if (buslogic_scsi_drive_is_cdrom(i, j)) - Buslogic->DataBuf[i] = 1; - - Buslogic->DataReplyLeft = 8; + for (i = 0; j < 8; j++) + { + if (buslogic_scsi_drive_is_cdrom(i, j)) + Buslogic->DataBuf[i] = 1; + } } + Buslogic->DataReplyLeft = 8; + } + else + { + Buslogic->Status |= STAT_INVCMD; + Buslogic->DataReplyLeft = 0; } break; @@ -1506,6 +1573,46 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } break; + case 0x86: + if (BuslogicIsPCI()) + { + BuslogicPCIInformation_t *Reply = (BuslogicPCIInformation_t *) Buslogic->DataBuf; + memset(Reply, 0, sizeof(BuslogicPCIInformation_t)); + Reply->InformationIsValid = 0; + switch(Buslogic->Base) + { + case 0x330: + Reply->IsaIOPort = 0; + break; + case 0x334: + Reply->IsaIOPort = 1; + break; + case 0x230: + Reply->IsaIOPort = 2; + break; + case 0x234: + Reply->IsaIOPort = 3; + break; + case 0x130: + Reply->IsaIOPort = 4; + break; + case 0x134: + Reply->IsaIOPort = 5; + break; + default: + Reply->IsaIOPort = 0xFF; + break; + } + Reply->IRQ = Buslogic->Irq; + Buslogic->DataReplyLeft = sizeof(BuslogicPCIInformation_t); + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x8B: { if (scsi_model) @@ -1515,7 +1622,14 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) /* The reply length is set by the guest and is found in the first byte of the command buffer. */ Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft); - const char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */ + char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */ + if (BuslogicIsPCI()) + { + aModelName[0] = '9'; + aModelName[1] = '5'; + aModelName[2] = '8'; + aModelName[3] = 'D'; + } int cCharsToTransfer = Buslogic->DataReplyLeft <= sizeof(aModelName) ? Buslogic->DataReplyLeft : sizeof(aModelName); @@ -1531,18 +1645,42 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } break; + case 0x8C: + if (BuslogicIsPCI()) + { + int i = 0; + Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; + for (i = 0; i < Buslogic->DataReplyLeft; i++) + { + Buslogic->DataBuf[0] = 0; + } + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x8D: { if (scsi_model) { Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf; + memset(Reply, 0, sizeof(ReplyInquireExtendedSetupInformation)); - Reply->uBusType = 'A'; /* ISA style */ + Reply->uBusType = (BuslogicIsPCI()) ? 'E' : 'A'; /* ISA style */ Reply->uBiosAddress = 0; Reply->u16ScatterGatherLimit = 8192; Reply->cMailbox = Buslogic->MailboxCount; Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr; + if (BuslogicIsPCI()) + { + Reply->fLevelSensitiveInterrupt = 1; + Reply->fHostWideSCSI = 1; + Reply->fHostUltraSCSI = 1; + } memcpy(Reply->aFirmwareRevision, "07B", sizeof(Reply->aFirmwareRevision)); BuslogicLog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]); } @@ -1586,7 +1724,51 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataReply = Offset; } break; - + + case 0x95: + if (BuslogicIsPCI()) + { + if (Buslogic->Base != 0) + { + io_removehandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + } + switch(Buslogic->CmdBuf[0]) + { + case 0: + Buslogic->Base = 0x330; + break; + case 1: + Buslogic->Base = 0x334; + break; + case 2: + Buslogic->Base = 0x230; + break; + case 3: + Buslogic->Base = 0x234; + break; + case 4: + Buslogic->Base = 0x130; + break; + case 5: + Buslogic->Base = 0x134; + break; + default: + Buslogic->Base = 0; + break; + } + if (Buslogic->Base != 0) + { + io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + } + Buslogic->DataReplyLeft = 0; + } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } + break; + case 0x96: if (scsi_model) { @@ -1597,14 +1779,15 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) Buslogic->DataReplyLeft = 0; } + else + { + Buslogic->DataReplyLeft = 0; + Buslogic->Status |= STAT_INVCMD; + } break; default: case 0x22: //undocumented - // case 0x28: //only for the Adaptec 154xC series - // case 0x29: //only for the Adaptec 154xC series - case 0x86: //PCI only, not ISA - case 0x95: //PCI only, not ISA Buslogic->DataReplyLeft = 0; Buslogic->Status |= STAT_INVCMD; break; @@ -1629,6 +1812,16 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) } } +void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) +{ + BuslogicWrite(Port, Val & 0xFF, p); +} + +void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) +{ + BuslogicWrite(Port, Val & 0xFF, p); +} + static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) { BuslogicLog("Unconverted Request Sense length %i\n", RequestSenseLength); @@ -2004,6 +2197,195 @@ void BuslogicCommandCallback(void *p) BuslogicCallback += 50 * SCSI_TIME; } +uint8_t mem_read_null(uint32_t addr, void *priv) +{ + return 0; +} + +uint16_t mem_read_nullw(uint32_t addr, void *priv) +{ + return 0; +} + +uint32_t mem_read_nulll(uint32_t addr, void *priv) +{ + return 0; +} + +typedef union +{ + uint32_t addr; + uint8_t addr_regs[4]; +} bar_t; + +uint8_t buslogic_pci_regs[256]; + +bar_t buslogic_pci_bar[3]; + +uint8_t BuslogicPCIRead(int func, int addr, void *p) +{ + Buslogic_t *Buslogic = (Buslogic_t *)p; + + // BuslogicLog("BusLogic PCI read %08X\n", addr); + switch (addr) + { + case 0x00: + return 0x4b; + case 0x01: + return 0x10; + + case 0x02: + return 0x40; + case 0x03: + return 0x10; + + case 0x2C: + return 0x4b; + case 0x2D: + return 0x10; + case 0x2E: + return 0x40; + case 0x2F: + return 0x10; + + case 0x04: + return buslogic_pci_regs[0x04]; /*Respond to IO and memory accesses*/ + case 0x05: + return buslogic_pci_regs[0x05]; + + case 0x07: + return 2; + + case 0x08: + return 1; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0A: + return 0; /*Subclass*/ + case 0x0B: + return 1; /* Class code*/ + + case 0x10: + return (buslogic_pci_bar[0].addr_regs[0] & 0xe0) | 1; /*I/O space*/ + case 0x11: + return buslogic_pci_bar[0].addr_regs[1]; + case 0x12: + return buslogic_pci_bar[0].addr_regs[2]; + case 0x13: + return buslogic_pci_bar[0].addr_regs[3]; + + case 0x14: + return (buslogic_pci_bar[1].addr_regs[0] & 0xe0); /*Memory space*/ + case 0x15: + return buslogic_pci_bar[1].addr_regs[1]; + case 0x16: + return buslogic_pci_bar[1].addr_regs[2]; + case 0x17: + return buslogic_pci_bar[1].addr_regs[3]; + + case 0x30: + return buslogic_pci_bar[2].addr_regs[0] & 0x01; /*BIOS ROM address*/ + case 0x31: + return buslogic_pci_bar[2].addr_regs[1] | 0x18; + case 0x32: + return buslogic_pci_bar[2].addr_regs[2]; + case 0x33: + return buslogic_pci_bar[2].addr_regs[3]; + + case 0x3C: + return Buslogic->Irq; + case 0x3D: + return 1; + } + return 0; +} + +void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) +{ + Buslogic_t *Buslogic = (Buslogic_t *)p; + + switch (addr) + { + case 0x04: + io_removehandler(Buslogic->PCIBase, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + mem_mapping_disable(&Buslogic->mmio_mapping); + if (val & PCI_COMMAND_IO) + { + if (Buslogic->PCIBase != 0) + { + io_sethandler(Buslogic->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + } + } + if (val & PCI_COMMAND_MEM) + { + if (Buslogic->PCIBase != 0) + { + mem_mapping_set_addr(&Buslogic->mmio_mapping, Buslogic->MMIOBase, 0x20); + } + } + buslogic_pci_regs[addr] = val; + break; + + case 0x10: + val &= 0xe0; + val |= 1; + case 0x11: case 0x12: case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O. */ + io_removehandler(Buslogic->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + /* Then let's set the PCI regs. */ + buslogic_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + Buslogic->PCIBase = buslogic_pci_bar[0].addr & 0xffe0; + /* Log the new base. */ + BuslogicLog("BusLogic PCI: New I/O base is %04X\n" , Buslogic->PCIBase); + /* We're done, so get out of the here. */ + if (buslogic_pci_regs[4] & PCI_COMMAND_IO) + { + if (Buslogic->PCIBase != 0) + { + io_sethandler(Buslogic->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + } + } + return; + + case 0x14: + val &= 0xe0; + case 0x15: case 0x16: case 0x17: + /* I/O Base set. */ + /* First, remove the old I/O. */ + mem_mapping_disable(&Buslogic->mmio_mapping); + /* Then let's set the PCI regs. */ + buslogic_pci_bar[1].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + Buslogic->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; + /* Log the new base. */ + BuslogicLog("BusLogic PCI: New MMIO base is %04X\n" , Buslogic->MMIOBase); + /* We're done, so get out of the here. */ + if (buslogic_pci_regs[4] & PCI_COMMAND_MEM) + { + if (Buslogic->PCIBase != 0) + { + mem_mapping_set_addr(&Buslogic->mmio_mapping, Buslogic->MMIOBase, 0x20); + } + } + return; + + /* Commented out until an APIC controller is emulated for the PIIX3, + otherwise the BT-958 will not get an IRQ on boards using the PIIX3. */ +#if 0 + case 0x3C: + buslogic_pci_regs[addr] = val; + if (val != 0xFF) + { + buslogic_log("BusLogic IRQ now: %i\n", val); + Buslogic->Irq = val; + } + return; +#endif + } +} + void *BuslogicInit() { int i = 0; @@ -2011,10 +2393,23 @@ void *BuslogicInit() Buslogic_t *Buslogic = malloc(sizeof(Buslogic_t)); memset(Buslogic, 0, sizeof(Buslogic_t)); - Buslogic->Irq = scsi_irq; - Buslogic->DmaChannel = scsi_dma; + scsi_model = device_get_config_int("model"); + Buslogic->Base = device_get_config_int("addr"); + Buslogic->PCIBase = 0; + Buslogic->MMIOBase = 0; + Buslogic->Irq = device_get_config_int("irq"); + Buslogic->DmaChannel = device_get_config_int("dma"); - io_sethandler(scsi_base, 0x0004, BuslogicRead, NULL, NULL, BuslogicWrite, NULL, NULL, Buslogic); + if (Buslogic->Base != 0) + { + if (BuslogicIsPCI()) + { + } + else + { + io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + } + } BuslogicLog("Building CD-ROM map...\n"); build_scsi_cdrom_map(); @@ -2028,8 +2423,26 @@ void *BuslogicInit() } timer_add(BuslogicCommandCallback, &BuslogicCallback, &BuslogicCallback, Buslogic); + + if (BuslogicIsPCI()) + { + pci_add(BuslogicPCIRead, BuslogicPCIWrite, Buslogic); + + buslogic_pci_bar[0].addr_regs[0] = 1; + buslogic_pci_bar[1].addr_regs[0] = 0; + + buslogic_pci_regs[0x04] = 1; + buslogic_pci_regs[0x05] = 0; + + buslogic_pci_regs[0x07] = 2; + + buslogic_pci_bar[2].addr = 0; + + mem_mapping_add(&Buslogic->mmio_mapping, 0xfffd0000, 0x20, mem_read_null, mem_read_nullw, mem_read_nulll, mem_write_null, mem_write_nullw, mem_write_nulll, NULL, MEM_MAPPING_EXTERNAL, Buslogic); + mem_mapping_disable(&Buslogic->mmio_mapping); + } - BuslogicLog("Buslogic on port 0x%04X\n", scsi_base); + BuslogicLog("Buslogic on port 0x%04X\n", Buslogic->Base); BuslogicResetControl(Buslogic, CTRL_HRST); @@ -2042,6 +2455,139 @@ void BuslogicClose(void *p) free(Buslogic); } +static device_config_t BuslogicConfig[] = +{ + { + .name = "model", + .description = "Model", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Adaptec AHA-154XB ISA", + .value = 0 + }, + { + .description = "BusLogic BT-542B ISA", + .value = 1 + }, + { + .description = "BusLogic BT-958 PCI", + .value = 2 + }, + { + .description = "" + } + }, + .default_int = 0 + }, + { + .name = "addr", + .description = "Address", + .type = CONFIG_BINARY, + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "None", + .value = 0 + }, + { + .description = "0x330", + .value = 0x330 + }, + { + .description = "0x334", + .value = 0x334 + }, + { + .description = "0x230", + .value = 0x230 + }, + { + .description = "0x234", + .value = 0x234 + }, + { + .description = "0x130", + .value = 0x130 + }, + { + .description = "0x134", + .value = 0x134 + }, + { + .description = "" + } + }, + .default_int = 0x334 + }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 9", + .value = 9 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 12", + .value = 12 + }, + { + .description = "IRQ 14", + .value = 14 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 9 + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "DMA 5", + .value = 5 + }, + { + .description = "DMA 6", + .value = 6 + }, + { + .description = "DMA 7", + .value = 7 + }, + { + .description = "" + } + }, + .default_int = 6 + }, + { + .type = -1 + } +}; + device_t BuslogicDevice = { "Adaptec/Buslogic", @@ -2051,5 +2597,6 @@ device_t BuslogicDevice = NULL, NULL, NULL, - NULL + NULL, + BuslogicConfig }; diff --git a/src/ibm.h b/src/ibm.h index aa3ac2277..78570ecc5 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -599,8 +599,6 @@ int mem_a20_state; void fatal(const char *format, ...); -extern int scsi_model, scsi_base, scsi_irq, scsi_dma; - #ifdef ENABLE_LOG_TOGGLES extern int buslogic_do_log; extern int cdrom_do_log; diff --git a/src/pc.c b/src/pc.c index 915232cef..85659113c 100644 --- a/src/pc.c +++ b/src/pc.c @@ -686,11 +686,6 @@ void loadconfig(char *fn) voodoo_enabled = config_get_int(NULL, "voodoo", 0); buslogic_enabled = config_get_int(NULL, "buslogic", 0); - scsi_model = config_get_int(NULL, "scsi_model", 1); - scsi_base = config_get_int(NULL, "scsi_base", 0x330); - scsi_irq = config_get_int(NULL, "scsi_irq", 11); - scsi_dma = config_get_int(NULL, "scsi_dma", 6); - //network ethif = config_get_int(NULL, "netinterface", 1); if (ethif >= inum) @@ -932,11 +927,6 @@ void saveconfig() config_set_int(NULL, "voodoo", voodoo_enabled); config_set_int(NULL, "buslogic", buslogic_enabled); - config_set_int(NULL, "scsi_model", scsi_model); - config_set_int(NULL, "scsi_base", scsi_base); - config_set_int(NULL, "scsi_irq", scsi_irq); - config_set_int(NULL, "scsi_dma", scsi_dma); - config_set_int(NULL, "netinterface", ethif); config_set_int(NULL, "netcard", network_card_current); diff --git a/src/pc.rc b/src/pc.rc index da2ad821b..7dd239b70 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -275,39 +275,6 @@ BEGIN MENUITEM "1&5",IDM_IDE_QUA_IRQ15 END END - POPUP "&SCSI controller" - BEGIN - MENUITEM "&Enabled",IDM_SCSI_ENABLED - POPUP "&Model" - BEGIN - MENUITEM "&Adaptec AHA-154x",IDM_SCSI_MODEL0 - MENUITEM "&BusLogic BT-542B",IDM_SCSI_MODEL1 - END - POPUP "&Base address" - BEGIN - MENUITEM "0x&130",IDM_SCSI_BASE130 - MENUITEM "0x13&4",IDM_SCSI_BASE134 - MENUITEM "0x&230",IDM_SCSI_BASE230 - MENUITEM "0&x234",IDM_SCSI_BASE234 - MENUITEM "0x33&0",IDM_SCSI_BASE330 - MENUITEM "&0x334",IDM_SCSI_BASE334 - END - POPUP "&IRQ" - BEGIN - MENUITEM "&9",IDM_SCSI_IRQ9 - MENUITEM "1&0",IDM_SCSI_IRQ10 - MENUITEM "1&1",IDM_SCSI_IRQ11 - MENUITEM "1&2",IDM_SCSI_IRQ12 - MENUITEM "1&4",IDM_SCSI_IRQ14 - MENUITEM "1&5",IDM_SCSI_IRQ15 - END - POPUP "&DMA channel" - BEGIN - MENUITEM "&5",IDM_SCSI_DMA5 - MENUITEM "&6",IDM_SCSI_DMA6 - MENUITEM "&7",IDM_SCSI_DMA7 - END - END END POPUP "&Settings" BEGIN @@ -427,8 +394,10 @@ BEGIN CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,208,102,10 CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,192,102,10 - CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,208,102,10 + CONTROL "SCSI Controller",IDC_CHECKBUSLOGIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,208,102,10 + PUSHBUTTON "Configure", IDC_CONFIGUREBUSLOGIC, 224, 208, 40, 14, WS_TABSTOP + CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,224,102,10 CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,224,102,10 PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 224, 40, 14, WS_TABSTOP diff --git a/src/resources.h b/src/resources.h index dbd056533..bc1aa903b 100644 --- a/src/resources.h +++ b/src/resources.h @@ -202,24 +202,6 @@ #define IDM_IDE_QUA_IRQ12 44032 #define IDM_IDE_QUA_IRQ14 44033 #define IDM_IDE_QUA_IRQ15 44035 -#define IDM_SCSI_ENABLED 45000 -#define IDM_SCSI_MODEL0 45100 -#define IDM_SCSI_MODEL1 45101 -#define IDM_SCSI_BASE130 45200 + 0x130 -#define IDM_SCSI_BASE134 45200 + 0x134 -#define IDM_SCSI_BASE230 45200 + 0x230 -#define IDM_SCSI_BASE234 45200 + 0x234 -#define IDM_SCSI_BASE330 45200 + 0x330 -#define IDM_SCSI_BASE334 45200 + 0x334 -#define IDM_SCSI_IRQ9 45309 -#define IDM_SCSI_IRQ10 45310 -#define IDM_SCSI_IRQ11 45311 -#define IDM_SCSI_IRQ12 45312 -#define IDM_SCSI_IRQ14 45314 -#define IDM_SCSI_IRQ15 45315 -#define IDM_SCSI_DMA5 45405 -#define IDM_SCSI_DMA6 45406 -#define IDM_SCSI_DMA7 45407 #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG #define IDM_LOG_BUSLOGIC 51200 @@ -269,6 +251,7 @@ #define IDC_CHECKSSI 1014 #define IDC_CHECKVOODOO 1015 #define IDC_CHECKDYNAREC 1016 +#define IDC_CHECKBUSLOGIC 1017 #define IDC_STATIC 1020 #define IDC_CHECKSYNC 1024 #define IDC_EDIT1 1030 @@ -379,6 +362,7 @@ #define IDC_CONFIGUREVOODOO 1202 #define IDC_CONFIGUREMOD 1203 #define IDC_CONFIGURENET 1204 +#define IDC_CONFIGUREBUSLOGIC 1205 #define IDC_JOY1 1210 #define IDC_JOY2 1211 #define IDC_JOY3 1212 diff --git a/src/win-config.c b/src/win-config.c index 3badfebd5..a72391e1b 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -13,6 +13,7 @@ #include "ide.h" #include "cpu.h" #include "device.h" +#include "buslogic.h" #include "fdd.h" #include "gameport.h" #include "model.h" @@ -48,7 +49,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR int c, d; int rom, gfx, mem, fpu; int temp_cpu, temp_cpu_m, temp_model; - int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_sound_card_current; + int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_buslogic, temp_sound_card_current; int temp_dynarec; int cpu_flags; int temp_fd1_type, temp_fd2_type, temp_fd3_type, temp_fd4_type; @@ -189,6 +190,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h=GetDlgItem(hdlg, IDC_CHECKVOODOO); SendMessage(h, BM_SETCHECK, voodoo_enabled, 0); + h=GetDlgItem(hdlg, IDC_CHECKBUSLOGIC); + SendMessage(h, BM_SETCHECK, buslogic_enabled, 0); + cpu_flags = models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; h=GetDlgItem(hdlg, IDC_CHECKDYNAREC); if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) @@ -401,6 +405,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h = GetDlgItem(hdlg, IDC_CHECKVOODOO); temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECKBUSLOGIC); + temp_buslogic = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBOSND); temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -427,7 +434,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_cpu != cpu || temp_cpu_m != cpu_manufacturer || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || - temp_voodoo != voodoo_enabled || temp_dynarec != cpu_use_dynarec || temp_mouse_type != mouse_type || + temp_voodoo != voodoo_enabled || temp_buslogic != buslogic_enabled || temp_dynarec != cpu_use_dynarec || temp_mouse_type != mouse_type || temp_fd1_type != fdd_get_type(0) || temp_fd2_type != fdd_get_type(1) || temp_fd3_type != fdd_get_type(2) || temp_fd4_type != fdd_get_type(3) || temp_network_card_current != network_card_current) { if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL)==IDOK) @@ -444,6 +451,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR SSI2001 = temp_SSI2001; sound_card_current = temp_sound_card_current; voodoo_enabled = temp_voodoo; + buslogic_enabled = temp_buslogic; cpu_use_dynarec = temp_dynarec; mouse_type = temp_mouse_type; @@ -757,6 +765,10 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR deviceconfig_open(hdlg, (void *)&voodoo_device); break; + case IDC_CONFIGUREBUSLOGIC: + deviceconfig_open(hdlg, (void *)&BuslogicDevice); + break; + case IDC_COMBOJOY: if (HIWORD(wParam) == CBN_SELCHANGE) { diff --git a/src/win.c b/src/win.c index 84c8781bc..4479b36aa 100644 --- a/src/win.c +++ b/src/win.c @@ -722,36 +722,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_IDE_QUA_IRQ9 - 9 + ide_irq[3], MF_CHECKED); - if (buslogic_enabled) - CheckMenuItem(menu, IDM_SCSI_ENABLED, MF_CHECKED); - - if (!find_in_array(valid_models, scsi_model, 2, IDM_SCSI_MODEL0)) - { - fatal("SCSI controller: Invalid model\n"); - } - - CheckMenuItem(menu, IDM_SCSI_MODEL0 + scsi_model, MF_CHECKED); - - if (!find_in_array(valid_bases, scsi_base, 6, IDM_SCSI_BASE130 - 0x130)) - { - fatal("SCSI controller: Invalid base address\n"); - } - - CheckMenuItem(menu, IDM_SCSI_BASE130 - 0x130 + scsi_base, MF_CHECKED); - - if (!find_in_array(valid_irqs, scsi_irq, 6, IDM_SCSI_IRQ9 - 9)) - { - fatal("SCSI controller: Invalid IRQ\n"); - } - CheckMenuItem(menu, IDM_SCSI_IRQ9 - 9 + scsi_irq, MF_CHECKED); - - if (!find_in_array(valid_dma_channels, scsi_dma, 3, IDM_SCSI_DMA5 - 5)) - { - fatal("SCSI controller: Invalid DMA channel\n"); - } - - CheckMenuItem(menu, IDM_SCSI_DMA5 - 5 + scsi_dma, MF_CHECKED); - #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); @@ -1157,103 +1127,6 @@ int ide_qua_set_irq(HMENU hmenu, int irq, int id) return 1; } -int scsi_set_model(HMENU hmenu, int model, int id) -{ - if (scsi_model == model) - { - return 0; - } - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - return 0; - } - pause = 1; - Sleep(100); - scsi_model = model; - CheckMenuItem(hmenu, IDM_SCSI_MODEL0, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_MODEL1, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int scsi_set_base(HMENU hmenu, int base, int id) -{ - if (scsi_base == base) - { - return 0; - } - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - return 0; - } - pause = 1; - Sleep(100); - scsi_base = base; - CheckMenuItem(hmenu, IDM_SCSI_BASE130, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_BASE134, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_BASE230, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_BASE234, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_BASE330, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_BASE334, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int scsi_set_irq(HMENU hmenu, int irq, int id) -{ - if (scsi_irq == irq) - { - return 0; - } - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - return 0; - } - pause = 1; - Sleep(100); - scsi_irq = irq; - CheckMenuItem(hmenu, IDM_SCSI_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int scsi_set_dma(HMENU hmenu, int dma, int id) -{ - if (scsi_dma == dma) - { - return 0; - } - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - return 0; - } - pause = 1; - Sleep(100); - scsi_dma = dma; - CheckMenuItem(hmenu, IDM_SCSI_DMA5, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_DMA6, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_SCSI_DMA7, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - void video_toggle_option(HMENU hmenu, int *val, int id) { *val ^= 1; @@ -1814,88 +1687,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM ide_qua_set_irq(hmenu, 15, IDM_IDE_QUA_IRQ15); break; - case IDM_SCSI_ENABLED: - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - buslogic_enabled ^= 1; - CheckMenuItem(hmenu, IDM_SCSI_ENABLED, buslogic_enabled ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_SCSI_MODEL0: - scsi_set_model(hmenu, 0, IDM_SCSI_MODEL0); - break; - - case IDM_SCSI_MODEL1: - scsi_set_model(hmenu, 1, IDM_SCSI_MODEL1); - break; - - case IDM_SCSI_BASE130: - scsi_set_base(hmenu, 0x130, IDM_SCSI_BASE130); - break; - - case IDM_SCSI_BASE134: - scsi_set_base(hmenu, 0x134, IDM_SCSI_BASE134); - break; - - case IDM_SCSI_BASE230: - scsi_set_base(hmenu, 0x230, IDM_SCSI_BASE230); - break; - - case IDM_SCSI_BASE234: - scsi_set_base(hmenu, 0x234, IDM_SCSI_BASE234); - break; - - case IDM_SCSI_BASE330: - scsi_set_base(hmenu, 0x330, IDM_SCSI_BASE330); - break; - - case IDM_SCSI_BASE334: - scsi_set_base(hmenu, 0x334, IDM_SCSI_BASE334); - break; - - case IDM_SCSI_IRQ9: - scsi_set_irq(hmenu, 9, IDM_SCSI_IRQ9); - break; - - case IDM_SCSI_IRQ10: - scsi_set_irq(hmenu, 10, IDM_SCSI_IRQ10); - break; - - case IDM_SCSI_IRQ11: - scsi_set_irq(hmenu, 11, IDM_SCSI_IRQ11); - break; - - case IDM_SCSI_IRQ12: - scsi_set_irq(hmenu, 12, IDM_SCSI_IRQ12); - break; - - case IDM_SCSI_IRQ14: - scsi_set_irq(hmenu, 14, IDM_SCSI_IRQ14); - break; - - case IDM_SCSI_IRQ15: - scsi_set_irq(hmenu, 15, IDM_SCSI_IRQ15); - break; - - case IDM_SCSI_DMA5: - scsi_set_dma(hmenu, 5, IDM_SCSI_DMA5); - break; - - case IDM_SCSI_DMA6: - scsi_set_dma(hmenu, 6, IDM_SCSI_DMA6); - break; - - case IDM_SCSI_DMA7: - scsi_set_dma(hmenu, 7, IDM_SCSI_DMA7); - break; - case IDM_CDROM_1_EMPTY: case IDM_CDROM_2_EMPTY: case IDM_CDROM_3_EMPTY: From 9cb0abc4ae8b577b807c465af88bd7b4ea2b96ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 Feb 2017 05:23:14 +0100 Subject: [PATCH 070/392] Swapped the positions (and sizes) of the Wait states and Sound card combo boxes, full sound card names should be visible again. --- src/pc.rc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pc.rc b/src/pc.rc index 7dd239b70..634a696d2 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -383,9 +383,9 @@ BEGIN COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO3,62,76,102,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Dynamic Recompiler",IDC_CHECKDYNAREC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,76,99,10 - COMBOBOX IDC_COMBOWS, 62,96,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSPD,62,116,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSND,162,116,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOWS, 62,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOSPD,162,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOSND,62,116,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 116, 40, 14, WS_TABSTOP EDITTEXT IDC_MEMTEXT, 62, 136, 36, 14, ES_AUTOHSCROLL | ES_NUMBER CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 136, 12, 14 @@ -416,8 +416,8 @@ BEGIN LTEXT "CPU type :",IDC_STATIC,15,56,34,10 LTEXT "CPU :",IDC_STATIC,15,76,34,10 LTEXT "Waitstates :",IDC_STATIC,15,96,40,10 - LTEXT "Vid. speed :",IDC_STATIC,15,116,40,10 - LTEXT "Soundcard:",IDC_STATIC,125,116,34,10 + LTEXT "Vid.speed:",IDC_STATIC,125,96,34,10 + LTEXT "Sound card :",IDC_STATIC,15,116,40,10 LTEXT "Network :",IDC_STATIC,125,136,34,10 COMBOBOX IDC_COMBONET,162,136,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGURENET, 224, 136, 40, 14, WS_TABSTOP From 8747bede970f6cf1ae9a786bc52b178f7b318856 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 12 Feb 2017 19:38:06 +0100 Subject: [PATCH 071/392] The network card poller is now actually fired, the network now actually works. --- src/nethandler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nethandler.c b/src/nethandler.c index 2d42fc4b6..90d3e0f82 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -158,9 +158,9 @@ void vlan_poller(void *priv) { int c; - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 1500.0)); + vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0)); - if (network_thread_enable && vlan_handlers_num) + if (/*network_thread_enable && */ vlan_handlers_num) { // pclog("Setting thread event...\n"); // thread_set_event(network_event); From 20a25caba7d8e45802f288948b5ae88ace4ffdea Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 Feb 2017 20:21:57 +0100 Subject: [PATCH 072/392] cdrom_set_signature() now does a sanity check on the CD-ROM drive ID, fixes random crashes on hard reset. --- src/cdrom.c | 4 ++++ src/ide.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/cdrom.c b/src/cdrom.c index b0acbe5c0..e97c946d1 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -306,6 +306,10 @@ void cdrom_reset_cdb_len(int id) void cdrom_set_signature(int id) { + if (id >= CDROM_NUM) + { + return; + } cdrom[id].phase = 1; cdrom[id].request_length = 0xEB14; } diff --git a/src/ide.c b/src/ide.c index be9c920e0..001a915a4 100644 --- a/src/ide.c +++ b/src/ide.c @@ -559,7 +559,7 @@ static void loadhd(IDE *ide, int d, const char *fn) void ide_set_signature(IDE *ide) { - uint8_t cdrom_id = atapi_cdrom_drives[cur_ide[ide->board]]; + uint8_t cdrom_id = atapi_cdrom_drives[ide->channel]; ide->sector=1; ide->head=0; if (ide_drive_is_cdrom(ide)) From 969684052573d1f043aa3408d2a56175ec391559 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 13 Feb 2017 22:36:43 +0100 Subject: [PATCH 073/392] Commented out an excess log message in piix.c. --- src/piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/piix.c b/src/piix.c index 4f81ffd2b..671d949eb 100644 --- a/src/piix.c +++ b/src/piix.c @@ -499,7 +499,7 @@ int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ - pclog("DMA not disabled\n"); + // pclog("DMA not disabled\n"); while (transferred < transfer_length) { From 07f1e37d26ad3b10f42c76f7af1b265cd6651d9a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Feb 2017 07:06:24 +0100 Subject: [PATCH 074/392] NE2000 ISA now correctly lacks 32-bit reads and writes. --- src/ne2000.c | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/ne2000.c b/src/ne2000.c index ec5140559..635a35170 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -446,6 +446,10 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) if (ne2000->IMR.rdma_inte) { picint(1 << ne2000->base_irq); + if (network_card_current == 1) + { + picintc(1 << ne2000->base_irq); + } } } } @@ -501,7 +505,20 @@ uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io ne2000_log("out-of-bounds chipmem read, %04X\n", address); - return (0xff); + if (network_card_current == 1) + { + switch(io_len) + { + case 1: + return 0xff; + case 2: + return 0xffff; + } + } + else + { + return (0xff); + } } void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) @@ -1708,16 +1725,34 @@ uint32_t bios_mask = 0; void ne2000_io_set(uint16_t addr, ne2000_t *ne2000) { old_base_addr = addr; - io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + if (network_card_current == 1) + { + io_sethandler(addr, 0x0010, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, NULL, ne2000_writeb, ne2000_writew, NULL, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); + } + else + { + io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + } } void ne2000_io_remove(int16_t addr, ne2000_t *ne2000) { - io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + if (network_card_current == 1) + { + io_removehandler(addr, 0x0010, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); + io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, NULL, ne2000_writeb, ne2000_writew, NULL, ne2000); + io_removehandler(addr+0x1f, 0x0001, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); + } + else + { + io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); + } } uint8_t ne2000_pci_read(int func, int addr, void *p) From 711f09e17b764d91d0f3aac0ebc616c792e474f5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Feb 2017 23:46:50 +0100 Subject: [PATCH 075/392] Reverted EGA emulation to be in line with mainline PCem except for the overscan, as there were some problems; Added write port 3C1 to EGA and (S)VGA, fixed Microsoft Word 2.0 for DOS; The RTL8029AS now correctly enables I/O port range when base address is changed via PCI registers with I/O access enabled; Tentative fix for DirectDraw <-> Direct3D switching issues based on proposal from TheCollector1995; Fixed 64-bit makefile; Fixed LZF_C.C so it can compile for 64-bit Windows; Applied all mainline PCem commits. --- src/Makefile.mingw64 | 2 +- src/codegen_ops_xchg.h | 8 +- src/lzf/lzf_c.c | 4 +- src/ne2000.c | 4 + src/vid_ega.c | 530 +++++++++++++++++++---------------------- src/vid_svga.c | 83 ++++++- src/vid_voodoo.c | 20 +- src/win-d3d-fs.cc | 6 +- src/win-d3d.cc | 6 +- src/win-ddraw-fs.cc | 4 +- src/win-ddraw.cc | 4 +- 11 files changed, 350 insertions(+), 321 deletions(-) diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 56f114255..7cd949b1a 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -15,7 +15,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o usb.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_hercules.o vid_herculesplus.ovid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \ + vid_et4000w32.o vid_hercules.o vid_herculesplus.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \ vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ diff --git a/src/codegen_ops_xchg.h b/src/codegen_ops_xchg.h index 0e937d187..9a72c9a5a 100644 --- a/src/codegen_ops_xchg.h +++ b/src/codegen_ops_xchg.h @@ -44,9 +44,9 @@ OP_XCHG_EAX_(EBP) static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { -#ifdef __amd64__ - return 0; -#else +// #ifdef __amd64__ + // return 0; +// #else int src_reg, dst_reg, temp_reg; if ((fetchdat & 0xc0) != 0xc0) @@ -59,7 +59,7 @@ static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); return op_pc + 1; -#endif +// #endif } static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { diff --git a/src/lzf/lzf_c.c b/src/lzf/lzf_c.c index bc07084b8..120b4a5aa 100644 --- a/src/lzf/lzf_c.c +++ b/src/lzf/lzf_c.c @@ -34,6 +34,8 @@ * either the BSD or the GPL. */ +#include + #include "lzfP.h" #define HSIZE (1 << (HLOG)) @@ -120,7 +122,7 @@ lzf_compress (const void *const in_data, unsigned int in_len, * special workaround for it. */ #if defined (WIN32) && defined (_M_X64) - unsigned _int64 off; /* workaround for missing POSIX compliance */ + uint64_t off; /* workaround for missing POSIX compliance */ #else unsigned long off; #endif diff --git a/src/ne2000.c b/src/ne2000.c index 635a35170..3f5006123 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -1873,6 +1873,10 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p) /* Log the new base. */ ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); /* We're done, so get out of the here. */ + if (val & PCI_COMMAND_IO) + { + ne2000_io_set(ne2000->base_address, ne2000); + } return; case 0x30: case 0x31: case 0x32: case 0x33: diff --git a/src/vid_ega.c b/src/vid_ega.c index 6adee44a0..a6af3377e 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -1,6 +1,3 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ /*EGA emulation*/ #include #include "ibm.h" @@ -21,10 +18,6 @@ static uint32_t pallook16[256], pallook64[256]; /*3C2 controls default mode on EGA. On VGA, it determines monitor type (mono or colour)*/ int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines), 8=EGA mode (200 lines)*/ -static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x3B, 0x0F, 0x0F, 0xFF}; -static uint8_t ega_mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x1F, 0x1F, 0x1F, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0x1F, 0xFF, 0x1F, 0x7F, 0xFF}; -static uint8_t mask_seq[5] = {0x03, 0x1F, 0x0F, 0x0F, 0x06}; - static int old_overscan_color = 0; void ega_out(uint16_t addr, uint8_t val, void *p) @@ -39,72 +32,36 @@ void ega_out(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x3c0: + case 0x3c1: if (!ega->attrff) - { - ega->attraddr = val & 31; - if ((val & 0x20) != ega->attr_palette_enable) - { - fullchange = 3; - ega->attr_palette_enable = val & 0x20; - ega_recalctimings(ega); - } - } + ega->attraddr = val & 31; else { - o = ega->attrregs[ega->attraddr & 31]; ega->attrregs[ega->attraddr & 31] = val; - ega->attrregs[0x11] &= 0x3F; if (ega->attraddr < 16) fullchange = changeframecount; if (ega->attraddr == 0x10 || ega->attraddr == 0x14 || ega->attraddr < 0x10) { for (c = 0; c < 16; c++) { - /* if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); - else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); */ - - if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0x3) << 4); - else ega->egapal[c] = (ega->attrregs[c] & 0x3f); - - // if ((ega->attrregs[0x10] & 0x40) && gfxcard != GFX_EGA) ega->egapal[c] |= ((ega->attrregs[0x14] & 0xc) << 4); - if (gfxcard != GFX_EGA) ega->egapal[c] |= ((ega->attrregs[0x14] & 0xc) << 4); + if (ega->attrregs[0x10] & 0x80) ega->egapal[c] = (ega->attrregs[c] & 0xf) | ((ega->attrregs[0x14] & 0xf) << 4); + else ega->egapal[c] = (ega->attrregs[c] & 0x3f) | ((ega->attrregs[0x14] & 0xc) << 4); } } - if ((ega->attraddr == 0x10) || (ega->attraddr == 0x11)) - { - if (o != val) ega_recalctimings(ega); - } } ega->attrff ^= 1; break; case 0x3c2: egaswitchread = val & 0xc; ega->vres = !(val & 0x80); - if (gfxcard == GFX_EGA) - ega->pallook = ega->vres ? pallook16 : pallook64; - else - ega->pallook = pallook64; + ega->pallook = ega->vres ? pallook16 : pallook64; ega->vidclock = val & 4; /*printf("3C2 write %02X\n",val);*/ - ega->enablevram = (val & 2) ? 1 : 0; - ega->oddeven_page = (val & 0x20) ? 0 : 1; ega->miscout=val; - if (val & 1) - { -// pclog("Remove mono handler\n"); - io_removehandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - } - else - { -// pclog("Set mono handler\n"); - io_sethandler(0x03a0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); - } - ega_recalctimings(ega); break; case 0x3c4: ega->seqaddr = val; break; case 0x3c5: - if (ega->seqaddr <= 4) val &= mask_seq[ega->seqaddr]; o = ega->seqregs[ega->seqaddr & 0xf]; ega->seqregs[ega->seqaddr & 0xf] = val; if (o != val && (ega->seqaddr & 0xf) == 1) @@ -132,7 +89,6 @@ void ega_out(uint16_t addr, uint8_t val, void *p) ega->gdcaddr = val; break; case 0x3cf: - if (ega->seqaddr <= 8) val &= mask_gdc[ega->gdcaddr]; ega->gdcreg[ega->gdcaddr & 15] = val; switch (ega->gdcaddr & 15) { @@ -170,15 +126,16 @@ void ega_out(uint16_t addr, uint8_t val, void *p) break; } break; + case 0x3d0: case 0x3d4: - // pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); + pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); ega->crtcreg = val & 31; return; + case 0x3d1: case 0x3d5: - // pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); + pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); // if (ega->crtcreg == 1 && val == 0x14) // fatal("Here\n"); - if (ega->crtcreg <= 0x18) val &= ega_mask_crtc[ega->crtcreg]; if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; old = ega->crtc[ega->crtcreg]; ega->crtc[ega->crtcreg] = val; @@ -194,12 +151,34 @@ void ega_out(uint16_t addr, uint8_t val, void *p) } } +/* + * Get the input status register 0 + * + * Note by Tohka: Code from PCE. + */ +static uint8_t ega_get_input_status_0(ega_t *ega) +{ + unsigned bit; + uint8_t status0 = 0; + + bit = (egaswitchread >> 2) & 3; + + if (egaswitches & (0x08 >> bit)) { + status0 |= EGA_STATUS0_SS; + } + else { + status0 &= ~EGA_STATUS0_SS; + } + + return status0; +} + uint8_t ega_in(uint16_t addr, void *p) { ega_t *ega = (ega_t *)p; -/* if (addr != 0x3da && addr != 0x3ba) - pclog("ega_in %04X\n", addr); */ +if (addr != 0x3da && addr != 0x3ba) + pclog("ega_in %04X\n", addr); if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -208,44 +187,35 @@ uint8_t ega_in(uint16_t addr, void *p) case 0x3c0: return ega->attraddr; case 0x3c1: - if (ega->attraddr == 0x10) return ((ega->attrregs[ega->attraddr] & 0x7F) | (ega->attrff << 7)); return ega->attrregs[ega->attraddr]; case 0x3c2: // printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA); - switch (egaswitchread) - { - case 0xc: return (egaswitches & 1) ? 0x10 : 0; - case 0x8: return (egaswitches & 2) ? 0x10 : 0; - case 0x4: return (egaswitches & 4) ? 0x10 : 0; - case 0x0: return (egaswitches & 8) ? 0x10 : 0; - } + return ega_get_input_status_0(ega); break; case 0x3c4: return ega->seqaddr; case 0x3c5: return ega->seqregs[ega->seqaddr & 0xf]; + case 0x3c8: + return 2; + case 0x3cc: + return ega->miscout; case 0x3ce: return ega->gdcaddr; case 0x3cf: - if (ega->gdcaddr == 0xF8) return ega->la; - if (ega->gdcaddr == 0xF9) return ega->lb; - if (ega->gdcaddr == 0xFA) return ega->lc; - if (ega->gdcaddr == 0xFB) return ega->ld; return ega->gdcreg[ega->gdcaddr & 0xf]; + case 0x3d0: case 0x3d4: return ega->crtcreg; + case 0x3d1: case 0x3d5: return ega->crtc[ega->crtcreg]; case 0x3da: ega->attrff = 0; - // ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ - if (ega->stat & 0x01) - ega->stat &= ~0x30; - else - ega->stat ^= 0x30; + ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ return ega->stat; } -// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); +// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); return 0xff; } @@ -258,50 +228,50 @@ void ega_recalctimings(ega_t *ega) ega->dispend = ega->crtc[0x12]; ega->vsyncstart = ega->crtc[0x10]; ega->split = ega->crtc[0x18]; - ega->vblankstart = ega->crtc[0x15]; if (ega->crtc[7] & 1) ega->vtotal |= 0x100; + if (ega->crtc[7] & 32) ega->vtotal |= 0x200; ega->vtotal++; if (ega->crtc[7] & 2) ega->dispend |= 0x100; + if (ega->crtc[7] & 64) ega->dispend |= 0x200; ega->dispend++; if (ega->crtc[7] & 4) ega->vsyncstart |= 0x100; + if (ega->crtc[7] & 128) ega->vsyncstart |= 0x200; ega->vsyncstart++; if (ega->crtc[7] & 0x10) ega->split |= 0x100; + if (ega->crtc[9] & 0x40) ega->split |= 0x200; ega->split+=2; - if (ega->crtc[7] & 0x08) ega->vblankstart |= 0x100; - ega->vblankstart++; - ega->hdisp = ega->crtc[1]; ega->hdisp++; ega->rowoffset = ega->crtc[0x13]; - // printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); - - if (ega->vblankstart < ega->dispend) - ega->dispend = ega->vblankstart; + printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); - disptime = ega->crtc[0] + 2; - _dispontime = ega->hdisp; - -// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); - if (ega->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } + disptime = ega->crtc[0] + 2; + _dispontime = ega->crtc[1] + 1; + + printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); + if (ega->seqregs[1] & 8) + { + disptime*=2; + _dispontime*=2; + } _dispofftime = disptime - _dispontime; - _dispontime *= crtcconst; + _dispontime *= crtcconst; _dispofftime *= crtcconst; - ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); - - /* pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), - ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); */ + pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), + ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); // printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); // printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); // printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); @@ -359,190 +329,187 @@ void ega_poll(void *p) } } } - else if (!ega->scrblank && ega->attr_palette_enable) - { - if (!(ega->gdcreg[6] & 1)) - { - if (fullchange) - { - for (x = 0; x < ega->hdisp; x++) - { - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[ega->ma << 1]; - attr = ega->vram[(ega->ma << 1) + 1]; + else if (!(ega->gdcreg[6] & 1)) + { + if (fullchange) + { + for (x = 0; x < ega->hdisp; x++) + { + drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - if (attr & 8) charaddr = ega->charsetb + (chr * 128); - else charaddr = ega->charseta + (chr * 128); + if (attr & 8) charaddr = ega->charsetb + (chr * 128); + else charaddr = ega->charseta + (chr * 128); - if (drawcursor) - { - bg = ega->pallook[ega->egapal[attr & 15]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } - else - { - fg = ega->pallook[ega->egapal[attr & 15]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } + if (drawcursor) + { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } + else + { + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; + } + } - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 8) - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - else - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } - } - } - else - { - switch (ega->gdcreg[5] & 0x20) - { - case 0x00: - if (ega->seqregs[1] & 8) - { - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; + else + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; + } + } + else + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; + else + ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; + } + } + ega->ma += 4; + ega->ma &= ega->vrammask; + } + } + } + else + { + switch (ega->gdcreg[5] & 0x20) + { + case 0x00: + if (ega->seqregs[1] & 8) + { + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; + } + else + { + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } - else - { - offset = (8 - ega->scrollcache) + 24; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } + } + else + { + offset = (8 - ega->scrollcache) + 24; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; + } + else + { + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } - break; - case 0x20: - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; - edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; - } - else - { - edat[0] = ega->vram[(ega->ma << 1)]; - edat[1] = ega->vram[(ega->ma << 1) + 1]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } + } + break; + case 0x20: + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; + edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; + } + else + { + edat[0] = ega->vram[(ega->ma << 1)]; + edat[1] = ega->vram[(ega->ma << 1) + 1]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; - } - break; - } - } - } + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } + break; + } + } if (ega->lastline < ega->displine) ega->lastline = ega->displine; } @@ -605,8 +572,7 @@ void ega_poll(void *p) } if (ega->vc == ega->vsyncstart) { - int wx = 0; - int wy = 0; + int wx, wy; ega->dispon = 0; // printf("Vsync on at line %i %i\n",displine,vc); ega->stat |= 8; @@ -619,14 +585,14 @@ void ega_poll(void *p) { xsize = x; ysize = ega->lastline - ega->firstline; - if (xsize < 64) xsize = 640; + if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; if (ega->vres) updatewindowsize(xsize + x_add_ex, (ysize << 1) + y_add_ex); else updatewindowsize(xsize + x_add_ex, ysize + y_add_ex); } - + if (enable_overscan) { if ((x >= 160) && ((ega->lastline - ega->firstline) >= 120)) @@ -655,7 +621,7 @@ void ega_poll(void *p) } } } - + video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline + y_add_ex, xsize + x_add_ex, ega->lastline - ega->firstline + y_add_ex); frames++; @@ -707,35 +673,23 @@ void ega_poll(void *p) } } + void ega_write(uint32_t addr, uint8_t val, void *p) { ega_t *ega = (ega_t *)p; uint8_t vala, valb, valc, vald; int writemask2 = ega->writemask; - uint32_t raddr = addr; - int plane, mask; egawrites++; cycles -= video_timing_b; cycles_lost += video_timing_b; - - /* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */ - if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) return; - if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) return; if (addr >= 0xB0000) addr &= 0x7fff; else addr &= 0xffff; if (ega->chain2_write) { - if ((ega->gdcreg[6] & 0xC) == 0x4) - { - writemask2 &= (ega->oddeven_page ? ~0xe : ~0xb); - } - else - { - writemask2 &= ~0xa; - } + writemask2 &= ~0xa; if (addr & 1) writemask2 <<= 1; addr &= ~1; @@ -858,7 +812,6 @@ uint8_t ega_read(uint32_t addr, void *p) ega_t *ega = (ega_t *)p; uint8_t temp, temp2, temp3, temp4; int readplane = ega->readplane; - int plane; egareads++; cycles -= video_timing_b; @@ -937,6 +890,7 @@ void ega_init(ega_t *ega) pallook16[c] = makecol32(0xaa, 0x55, 0); } ega->pallook = pallook16; + old_overscan_color = 0; } void ega_common_defaults(ega_t *ega) diff --git a/src/vid_svga.c b/src/vid_svga.c index 0f3cc464c..77300bbe9 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -21,8 +21,8 @@ extern uint8_t edatlookup[4][4]; uint8_t svga_rotate[8][256]; -static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x7B, 0x0F, 0x0F, 0xFF}; -uint8_t mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0xEF, 0xFF}; +static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x7B, 0xFF, 0x0F, 0xFF}; +uint8_t mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0xEF, 0xFF}; static uint8_t mask_seq[5] = {0x03, 0x3D, 0x0F, 0x3F, 0x0E}; /*Primary SVGA device. As multiple video cards are not yet supported this is the @@ -102,6 +102,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) return; case 0x3C0: + case 0x3C1: if (!svga->attrff) { svga->attraddr = val & 31; @@ -295,6 +296,46 @@ void svga_out(uint16_t addr, uint8_t val, void *p) } } +/* + * Get the switch sense input + * + * This is reverse engineered from the IBM VGA BIOS. I have no + * idea how and why this works. + * + * Note by Tohka: This code is from PCE, modified to be 86Box-compatible. + */ +static int svga_get_input_status_0_ss(svga_t *svga) +{ + const unsigned char *p; + unsigned char dac[3]; + + static unsigned char vals[] = { + 0x12, 0x12, 0x12, 0x10, + 0x14, 0x14, 0x14, 0x10, + 0x2d, 0x14, 0x14, 0x00, + 0x14, 0x2d, 0x14, 0x00, + 0x14, 0x14, 0x2d, 0x00, + 0x2d, 0x2d, 0x2d, 0x00, + 0x00, 0x00, 0x00, 0xff + }; + + dac[0] = svga->vgapal[0].r >> 2; + dac[1] = svga->vgapal[0].g >> 2; + dac[2] = svga->vgapal[0].b >> 2; + + p = vals; + + while (p[3] != 0xff) { + if ((p[0] == dac[0]) && (p[1] == dac[1]) && (p[2] == dac[2])) { + return (p[3] != 0); + } + + p += 4; + } + + return (1); +} + uint8_t svga_in(uint16_t addr, void *p) { svga_t *svga = (svga_t *)p; @@ -347,8 +388,15 @@ uint8_t svga_in(uint16_t addr, void *p) else temp = 0x10; #endif - temp = sense_switches & (1 << ((svga->miscout >> 2) & 3)); - return temp ? 0 : 0x10; + if (svga_get_input_status_0_ss(svga)) + { + temp |= 0x10; + } + else + { + temp &= ~0x10; + } + return temp; case 0x3C4: return svga->seqaddr; case 0x3C5: @@ -1483,6 +1531,16 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) // pclog("doblit %i %i\n", y1, y2); // pclog("svga_doblit %i %i\n", wx, svga->hdisp); + if ((xsize > 2032) || (ysize > 2032)) + { + x_add = 0; + y_add = 0; + suppress_overscan = 1; + } + else + { + suppress_overscan = 0; + } if (y1 > y2) { @@ -1497,15 +1555,15 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) if (xsize<64) xsize=640; if (ysize<32) ysize=200; - if (xsize > 2032) + if ((xsize > 2032) || (ysize > 2032)) { x_add = 0; y_add = 0; - suppress_overscan = 0; + suppress_overscan = 1; } else { - suppress_overscan = 1; + suppress_overscan = 0; } updatewindowsize(xsize + x_add,ysize + y_add); @@ -1514,6 +1572,17 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { xsize = wx; ysize = wy + 1; + + if ((xsize > 2032) || (ysize > 2032)) + { + x_add = 0; + y_add = 0; + suppress_overscan = 1; + } + else + { + suppress_overscan = 0; + } } if (enable_overscan && !suppress_overscan) diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 17a1f3dec..ca7c64359 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -160,13 +160,13 @@ typedef struct voodoo_params_t uint32_t texBaseAddr[2], texBaseAddr1[2], texBaseAddr2[2], texBaseAddr38[2]; - uint32_t tex_base[2][LOD_MAX+1]; + uint32_t tex_base[2][LOD_MAX+2]; int tex_width[2]; - int tex_w_mask[2][LOD_MAX+1]; - int tex_w_nmask[2][LOD_MAX+1]; - int tex_h_mask[2][LOD_MAX+1]; - int tex_shift[2][LOD_MAX+1]; - int tex_lod[2][LOD_MAX+1]; + int tex_w_mask[2][LOD_MAX+2]; + int tex_w_nmask[2][LOD_MAX+2]; + int tex_h_mask[2][LOD_MAX+2]; + int tex_shift[2][LOD_MAX+2]; + int tex_lod[2][LOD_MAX+2]; int tex_entry[2]; int detail_max[2], detail_bias[2], detail_scale[2]; @@ -1122,7 +1122,7 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) tex_lod++; } - for (lod = 0; lod <= LOD_MAX; lod++) + for (lod = 0; lod <= LOD_MAX+1; lod++) { if (!width) width = 1; @@ -3649,9 +3649,9 @@ static void triangle_setup(voodoo_t *voodoo) } if (voodoo->sSetupMode & SETUPMODE_W1) { - voodoo->params.tmu[1].startW = (int64_t)(voodoo->verts[va].sW0 * 4294967296.0f); - voodoo->params.tmu[1].dWdX = (int64_t)(((voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dyBC - (voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dyAB) * 4294967296.0f); - voodoo->params.tmu[1].dWdY = (int64_t)(((voodoo->verts[vb].sW0 - voodoo->verts[vc].sW0) * dxAB - (voodoo->verts[va].sW0 - voodoo->verts[vb].sW0) * dxBC) * 4294967296.0f); + voodoo->params.tmu[1].startW = (int64_t)(voodoo->verts[va].sW1 * 4294967296.0f); + voodoo->params.tmu[1].dWdX = (int64_t)(((voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dyBC - (voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dyAB) * 4294967296.0f); + voodoo->params.tmu[1].dWdY = (int64_t)(((voodoo->verts[vb].sW1 - voodoo->verts[vc].sW1) * dxAB - (voodoo->verts[va].sW1 - voodoo->verts[vb].sW1) * dxBC) * 4294967296.0f); } if (voodoo->sSetupMode & SETUPMODE_S1_T1) { diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 4d129228d..ad3b2d4a5 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -164,18 +164,18 @@ static void d3d_fs_init_objects() d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - r.top = r.left = 0; + // r.top = r.left = 0; r.bottom = 2047; r.right = 2047; if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - for (y = 0; y < 2048; y++) + /* for (y = 0; y < 2048; y++) { uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); memset(p, 0, 2048 * 4); - } + } */ d3dTexture->UnlockRect(0); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index a1e2fa8c5..30eedfdef 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -137,17 +137,17 @@ void d3d_init_objects() d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - r.top = r.left = 0; + // r.top = r.left = 0; r.bottom = r.right = 2047; if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - for (y = 0; y < 2048; y++) + /* for (y = 0; y < 2048; y++) { uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); memset(p, 0, 2048 * 4); - } + } */ d3dTexture->UnlockRect(0); diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index bfb9a5a1c..a32f5d105 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -86,8 +86,8 @@ void ddraw_fs_init(HWND h) if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) fatal("SetDisplayMode failed\n"); - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + // memset(&ddsd, 0, sizeof(ddsd)); + // ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index f786310ca..be2291900 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -87,8 +87,8 @@ void ddraw_init(HWND h) if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) fatal("CreateSurface failed\n"); - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); + // memset(&ddsd, 0, sizeof(ddsd)); + // ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.dwWidth = 2048; From de6f785029ac4b59354cd7ef8990b2d7a25a56c3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Feb 2017 23:49:48 +0100 Subject: [PATCH 076/392] Fixed a compile-breaking error. --- src/vid_ega.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_ega.c b/src/vid_ega.c index a6af3377e..6a377efe3 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -164,10 +164,10 @@ static uint8_t ega_get_input_status_0(ega_t *ega) bit = (egaswitchread >> 2) & 3; if (egaswitches & (0x08 >> bit)) { - status0 |= EGA_STATUS0_SS; + status0 |= 0x10; } else { - status0 &= ~EGA_STATUS0_SS; + status0 &= ~0x10; } return status0; From 419b0b0c58305083c22e85a0f76538333e3b3dfd Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 15 Feb 2017 18:19:00 +0100 Subject: [PATCH 077/392] Added support for custom HDX hard disk image format that is less size-limited than HDI and supports storing translation parameters; Commented out excess EGA logging. --- src/disc.c | 4 +- src/ibm.h | 11 +-- src/ide.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++- src/ide.h | 3 +- src/vid_ega.c | 14 ++-- src/vid_svga.c | 3 + src/win-hdconf.c | 36 +++++++-- 7 files changed, 232 insertions(+), 26 deletions(-) diff --git a/src/disc.c b/src/disc.c index 8a273f463..ed3d7d1d2 100644 --- a/src/disc.c +++ b/src/disc.c @@ -197,7 +197,7 @@ double disc_real_period(int drive) /* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */ if (romset == ROM_MRTHOR) { - return (ddbp * dusec) / 2.0; + return (ddbp * dusec) / 4.0; } else { @@ -209,7 +209,7 @@ void disc_poll(int drive) { if (drive >= FDD_NUM) { - disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 16.0 : 32.0) * TIMER_USEC); + disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 8.0 : 32.0) * TIMER_USEC); return; } diff --git a/src/ibm.h b/src/ibm.h index 78570ecc5..5626ea263 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -517,13 +517,14 @@ char pcempath[512]; /*Hard disc*/ -typedef struct +typedef struct __attribute__((__packed__)) { - FILE *f; - uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ - uint64_t tracks; + FILE *f; + uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ + uint64_t tracks; int is_hdi; - uint32_t base; + uint32_t base; + uint64_t at_spt,at_hpc; /*[Translation] Sectors per track, heads per cylinder*/ } hard_disk_t; #define IDE_NUM 8 diff --git a/src/ide.c b/src/ide.c index 001a915a4..db88e534d 100644 --- a/src/ide.c +++ b/src/ide.c @@ -199,6 +199,61 @@ int image_is_hdi(const char *s) } } +int image_is_hdx(const char *s, int check_signature) +{ + int i, len; + FILE *f; + uint64_t filelen; + uint64_t signature; + char ext[5] = { 0, 0, 0, 0, 0 }; + len = strlen(s); + if ((len < 4) || (s[0] == '.')) + { + return 0; + } + memcpy(ext, s + len - 4, 4); + for (i = 0; i < 4; i++) + { + ext[i] = toupper(ext[i]); + } + if (strcmp(ext, ".HDX") == 0) + { + if (check_signature) + { + f = fopen(s, "rb"); + if (!f) + { + return 0; + } + fseeko64(f, 0, SEEK_END); + filelen = ftello64(f); + fseeko64(f, 0, SEEK_SET); + if (filelen < 44) + { + return 0; + } + fread(&signature, 1, 8, f); + fclose(f); + if (signature == 0xD778A82044445459) + { + return 1; + } + else + { + return 0; + } + } + else + { + return 1; + } + } + else + { + return 0; + } +} + int ide_enable[4] = { 1, 1, 0, 0 }; int ide_irq[4] = { 14, 15, 10, 11 }; @@ -334,6 +389,7 @@ static void ide_identify(IDE *ide) { int c, h, s; uint8_t device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; + uint64_t full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); device_identify[6] = ide->channel + 0x30; ide_log("IDE Identify: %s\n", device_identify); @@ -347,7 +403,14 @@ static void ide_identify(IDE *ide) s = hdc[cur_ide[ide->board]].spt; /* Sectors */ // ide->buffer[0] = 0x40; /* Fixed disk */ - ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ + if (hdc[cur_ide[ide->board]].tracks <= 16383) + { + ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ + } + else + { + ide->buffer[1] = 16383; /* Cylinders */ + } ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ @@ -372,9 +435,26 @@ static void ide_identify(IDE *ide) ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[53] = ide->specify_success ? 1 : 0; + ide->buffer[55] = ide->hpc; + ide->buffer[56] = ide->spt; + if (((full_size / ide->hpc) / ide->spt) <= 16383) + { + ide->buffer[54] = (full_size / ide->hpc) / ide->spt; + } + else + { + ide->buffer[54] = 16383; + } + full_size = ((uint64_t) ide->hpc) * ((uint64_t) ide->spt) * ((uint64_t) ide->buffer[54]); + ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[61] = full_size >> 16; ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; - ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16; + if (ide->buffer[49] & (1 << 9)) + { + ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[61] = ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16) & 0x0FFF; + } ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/ // ide->buffer[63] = 7; /*Multiword DMA*/ if (ide->board < 2) @@ -471,7 +551,8 @@ static void loadhd(IDE *ide, int d, const char *fn) { uint32_t sector_size = 512; uint32_t zero = 0; - uint32_t full_size = 0; + uint64_t signature = 0xD778A82044445459; + uint64_t full_size = 0; int c; ide->base = 0; ide->hdi = 0; @@ -517,6 +598,20 @@ static void loadhd(IDE *ide, int d, const char *fn) fwrite(&zero, 1, 4, ide->hdfile); } } + else if (image_is_hdx(fn, 0)) + { + full_size = hdc[d].spt * hdc[d].hpc * hdc[d].tracks * 512; + ide->base = 0x28; + ide->hdi = 2; + fwrite(&signature, 1, 8, ide->hdfile); + fwrite(&full_size, 1, 8, ide->hdfile); + fwrite(§or_size, 1, 4, ide->hdfile); + fwrite(&(hdc[d].spt), 1, 4, ide->hdfile); + fwrite(&(hdc[d].hpc), 1, 4, ide->hdfile); + fwrite(&(hdc[d].tracks), 1, 4, ide->hdfile); + fwrite(&zero, 1, 4, ide->hdfile); + fwrite(&zero, 1, 4, ide->hdfile); + } ide->hdc_num = d; } } @@ -547,6 +642,25 @@ static void loadhd(IDE *ide, int d, const char *fn) fread(&(hdc[d].tracks), 1, 4, ide->hdfile); ide->hdi = 1; } + else if (image_is_hdx(fn, 1)) + { + ide->base = 0x28; + fseeko64(ide->hdfile, 0x10, SEEK_SET); + fread(§or_size, 1, 4, ide->hdfile); + if (sector_size != 512) + { + /* Sector size is not 512 */ + fclose(ide->hdfile); + ide->type = IDE_NONE; + return; + } + fread(&(hdc[d].spt), 1, 4, ide->hdfile); + fread(&(hdc[d].hpc), 1, 4, ide->hdfile); + fread(&(hdc[d].tracks), 1, 4, ide->hdfile); + fread(&(hdc[d].at_spt), 1, 4, ide->hdfile); + fread(&(hdc[d].at_hpc), 1, 4, ide->hdfile); + ide->hdi = 2; + } } } @@ -1567,6 +1681,7 @@ void callbackide(int ide_board) ext_ide = ide; int64_t snum; int cdrom_id; + uint64_t full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); if (ide_drive_is_cdrom(ide)) { @@ -1690,6 +1805,10 @@ void callbackide(int ide_board) ide_set_signature(ide); goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); @@ -1707,6 +1826,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, addr, SEEK_SET); fread(ide->buffer, 512, 1, ide->hdfile); @@ -1751,6 +1874,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); @@ -1777,6 +1904,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); @@ -1801,6 +1932,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } if (ide_bus_master_write) { @@ -1839,6 +1974,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } addr = ide_get_sector(ide) * 512; fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); fwrite(ide->buffer, 512, 1, ide->hdfile); @@ -1869,6 +2008,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -1880,6 +2023,10 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (!ide->specify_success) + { + goto id_not_found; + } addr = ide_get_sector(ide) * 512; // ide_log("Format cyl %i head %i offset %08X %08X %08X secount %i\n",ide.cylinder,ide.head,addr,addr>>32,addr,ide.secount); fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); @@ -1917,6 +2064,32 @@ void callbackide(int ide_board) { goto abort_cmd; } + if (((hdc[cur_ide[ide->board]].at_hpc == 0) && (hdc[cur_ide[ide->board]].at_spt == 0)) || (ide->hdi != 2)) + { + full_size /= (ide->head+1); + full_size /= ide->secount; + ide->specify_success = 1; + if (ide->hdi == 2) + { + hdc[cur_ide[ide->board]].at_hpc = ide->head+1; + hdc[cur_ide[ide->board]].at_spt = ide->secount; + fseeko64(ide->hdfile, 0x20, SEEK_SET); + fwrite(&(hdc[cur_ide[ide->board]].at_spt), 1, 4, ide->hdfile); + fwrite(&(hdc[cur_ide[ide->board]].at_hpc), 1, 4, ide->hdfile); + } + } + else + { + if ((hdc[cur_ide[ide->board]].at_hpc == (ide->head + 1)) && (hdc[cur_ide[ide->board]].at_spt == ide->secount)) + { + ide->specify_success = 1; + } + else + { + ide_log("WIN_SPECIFY error (%04X, %04X)\n", ide->head + 1, ide->secount); + ide->specify_success = 0; + } + } ide->spt=ide->secount; ide->hpc=ide->head+1; ide->atastat = READY_STAT | DSC_STAT; @@ -2028,6 +2201,12 @@ abort_cmd: ide->pos = 0; } ide_irq_raise(ide); + return; +id_not_found: + ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR | 0x10; + ide->pos = 0; + ide_irq_raise(ide); } void ide_callback_pri() diff --git a/src/ide.h b/src/ide.h index 87dc9081c..970bc557b 100644 --- a/src/ide.h +++ b/src/ide.h @@ -4,7 +4,7 @@ #ifndef __IDE__ #define __IDE__ -typedef struct IDE +typedef struct __attribute__((__packed__)) IDE { int type; int board; @@ -32,6 +32,7 @@ typedef struct IDE uint16_t dma_identify_data[3]; int hdi,base; int hdc_num; + uint8_t specify_success; } IDE; extern void writeide(int ide_board, uint16_t addr, uint8_t val); diff --git a/src/vid_ega.c b/src/vid_ega.c index 6a377efe3..dc8ec33a8 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -128,12 +128,12 @@ void ega_out(uint16_t addr, uint8_t val, void *p) break; case 0x3d0: case 0x3d4: - pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); + // pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); ega->crtcreg = val & 31; return; case 0x3d1: case 0x3d5: - pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); + // pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); // if (ega->crtcreg == 1 && val == 0x14) // fatal("Here\n"); if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; @@ -178,7 +178,7 @@ uint8_t ega_in(uint16_t addr, void *p) ega_t *ega = (ega_t *)p; if (addr != 0x3da && addr != 0x3ba) - pclog("ega_in %04X\n", addr); + // pclog("ega_in %04X\n", addr); if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -250,7 +250,7 @@ void ega_recalctimings(ega_t *ega) ega->rowoffset = ega->crtc[0x13]; - printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); + // printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); @@ -258,7 +258,7 @@ void ega_recalctimings(ega_t *ega) disptime = ega->crtc[0] + 2; _dispontime = ega->crtc[1] + 1; - printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); + // printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); if (ega->seqregs[1] & 8) { disptime*=2; @@ -270,8 +270,8 @@ void ega_recalctimings(ega_t *ega) ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); - pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), - ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); + /* pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), + ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); */ // printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); // printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); // printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); diff --git a/src/vid_svga.c b/src/vid_svga.c index 77300bbe9..ad6a5411c 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -1710,7 +1710,10 @@ uint32_t svga_readl(uint32_t addr, void *p) if (!svga->enablevram) return 0xffffffff; if (!svga->fast) + { + if (addr == 0xBF0000) pclog ("%08X\n", svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24)); return svga_read(addr, p) | (svga_read(addr + 1, p) << 8) | (svga_read(addr + 2, p) << 16) | (svga_read(addr + 3, p) << 24); + } egareads += 4; diff --git a/src/win-hdconf.c b/src/win-hdconf.c index d42bd8e80..a5f241a3d 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -143,9 +143,9 @@ int hdconf_idok_common(HWND hdlg) MessageBox(ghwnd, "Drive has too many heads (maximum is 16)", "86Box error", MB_OK); return 1; } - if (hd_new_cyl > 16383) + if (hd_new_cyl > 266305) { - MessageBox(ghwnd, "Drive has too many cylinders (maximum is 16383)", "86Box error", MB_OK); + MessageBox(ghwnd, "Drive has too many cylinders (maximum is 266305)", "86Box error", MB_OK); return 1; } @@ -245,7 +245,9 @@ BOOL CALLBACK hdconf_common_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR FILE *f; uint8_t buf[512]; int is_hdi; + int is_hdx; uint64_t size; + uint64_t signature = 0xD778A82044445459; uint32_t zero = 0; uint32_t sector_size = 512; uint32_t base = 0x1000; @@ -307,7 +309,7 @@ BOOL CALLBACK hdconf_common_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&full_size_bytes, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ + fwrite(&full_size_bytes, 1, 8, f); /* 0000000C: Full size of the data (32-bit) */ fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ fwrite(&hd_new_spt, 1, 4, f); /* 00000014: Sectors per cylinder */ fwrite(&hd_new_hpc, 1, 4, f); /* 00000018: Heads per cylinder */ @@ -318,6 +320,26 @@ BOOL CALLBACK hdconf_common_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fwrite(&zero, 1, 4, f); } } + else if (image_is_hdx(hd_new_name, 0)) + { + if (full_size_bytes > 0xffffffffffffffff) + { + MessageBox(ghwnd, "Drive is HDX and way too big (size filed in HDX header is 64-bit)", "86Box error", MB_OK); + fclose(f); + return TRUE; + } + + hd_new_hdi = 1; + + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&full_size_bytes, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&hd_new_spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hd_new_hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&hd_new_cyl, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + } memset(buf, 0, 512); for (c = 0; c < full_size; c++) fwrite(buf, 512, 1, f); @@ -336,7 +358,7 @@ BOOL CALLBACK hdconf_common_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR case IDC_CFILE: if (!type) { - if (!getsfile(hdlg, "Hard disc image (*.HDI;*.IMA;*.IMG)\0*.HDI;*.IMA;*.IMG\0All files (*.*)\0*.*\0", "")) + if (!getsfile(hdlg, "Hard disc image (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0", "")) { h = GetDlgItem(hdlg, IDC_EDITC); SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); @@ -429,7 +451,7 @@ static void hdconf_file(HWND hdlg, int drive_num) uint32_t base = 0x1000; int ret; - if (!getfile(hdlg, "Hard disc image (*.HDI;*.IMA;*.IMG;*.VHD)\0*.HDI;*.IMA;*.IMG;*.VHD\0All files (*.*)\0*.*\0", "")) + if (!getfile(hdlg, "Hard disc image (*.HDI;*.HDX;*.IMA;*.IMG;*.VHD)\0*.HDI;*.HDX;*.IMA;*.IMG;*.VHD\0All files (*.*)\0*.*\0", "")) { f = fopen64(openfilestring, "rb"); if (!f) @@ -438,13 +460,13 @@ static void hdconf_file(HWND hdlg, int drive_num) return; } - if (image_is_hdi(openfilestring)) + if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) { fseeko64(f, 0x10, SEEK_SET); fread(§or_size, 1, 4, f); if (sector_size != 512) { - MessageBox(ghwnd,"HDI image with a sector size that is not 512","86Box error",MB_OK); + MessageBox(ghwnd,"HDI or HDX image with a sector size that is not 512","86Box error",MB_OK); fclose(f); return; } From 77013e34c983f9d6956281cb120eb10177206224 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 15 Feb 2017 22:41:39 +0100 Subject: [PATCH 078/392] Manually applied mooch's RIVA 128 commit; Fixed the RIVA 128 in a way that does not affect other cards' operation. --- src/piix.c | 3 ++- src/vid_nv_riva128.c | 8 ++++---- src/vid_svga.c | 24 +++++++++++++++--------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/piix.c b/src/piix.c index 671d949eb..d4af9b4f1 100644 --- a/src/piix.c +++ b/src/piix.c @@ -27,12 +27,13 @@ static uint8_t card_piix[256], card_piix_ide[256]; void piix_write(int func, int addr, uint8_t val, void *priv) { uint16_t old_base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); -// pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); +// pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); if (func > 1) return; if (func == 1) /*IDE*/ { + // pclog("piix_write (IDE): func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); switch (addr) { case 0x04: diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index a192f5c32..830aef39e 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -518,7 +518,7 @@ static uint8_t riva128_pfifo_read(uint32_t addr, void *p) svga_t *svga = &riva128->svga; uint8_t ret = 0; - pclog("RIVA 128 PFIFO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + // pclog("RIVA 128 PFIFO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { @@ -646,7 +646,7 @@ static void riva128_pfifo_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - pclog("RIVA 128 PFIFO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + // pclog("RIVA 128 PFIFO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) { @@ -1734,8 +1734,8 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) addr &= 0xffffff; - //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER. DO NOT REMOVE. - if(!((addr >= 0x009000) && (addr <= 0x009fff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. + if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <- 0x003fff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { diff --git a/src/vid_svga.c b/src/vid_svga.c index ad6a5411c..7aabec6f6 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -382,19 +382,23 @@ uint8_t svga_in(uint16_t addr, void *p) case 0x3C1: return svga->attrregs[svga->attraddr]; case 0x3c2: -#if 0 - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) - temp = 0; - else - temp = 0x10; -#endif - if (svga_get_input_status_0_ss(svga)) + if (gfxcard == GFX_RIVA128) { - temp |= 0x10; + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) + temp = 0; + else + temp = 0x10; } else { - temp &= ~0x10; + if (svga_get_input_status_0_ss(svga)) + { + temp |= 0x10; + } + else + { + temp &= ~0x10; + } } return temp; case 0x3C4: @@ -966,6 +970,8 @@ int svga_init(svga_t *svga, void *p, int memsize, mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga); + memset(svga->vgapal, 0, sizeof(PALETTE)); + timer_add(svga_poll, &svga->vidtime, TIMER_ALWAYS_ENABLED, svga); svga_pri = svga; From a04b47688e369a4591060c0f3054157e98ab27b8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Feb 2017 02:18:28 +0100 Subject: [PATCH 079/392] The Virge's and Riva's are now hardcoded to IRQ 3. --- src/vid_nv_riva128.c | 3 ++- src/vid_s3_virge.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 830aef39e..f84c879a4 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -2249,7 +2249,8 @@ static uint8_t riva128_pci_read(int func, int addr, void *p) break; case 0x3c: - ret = riva128->pci_regs[0x3c]; + // ret = riva128->pci_regs[0x3c]; + ret = 0x03; break; case 0x3d: diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 24a315b15..a01fc04e8 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3686,7 +3686,8 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x32: ret = virge->pci_regs[0x32]; break; case 0x33: ret = virge->pci_regs[0x33]; break; - case 0x3c: ret = virge->pci_regs[0x3c]; break; + // case 0x3c: ret = virge->pci_regs[0x3c]; break; + case 0x3c: ret = 0x03; break; case 0x3d: ret = 0x01; break; /*INTA*/ From b15ab0505a58af7439e05c25a83f59cc0015a335 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Feb 2017 02:21:02 +0100 Subject: [PATCH 080/392] The lone picint in the Riva code is now also hard coded to IRQ 3. --- src/vid_nv_riva128.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index f84c879a4..656797b17 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -444,7 +444,8 @@ static void riva128_pmc_interrupt(int num, void *p) riva128->pmc.intr |= (1 << num); - picint(1 << riva128->pci_regs[0x3c]); + // picint(1 << riva128->pci_regs[0x3c]); + picint(1 << 3); } static uint8_t riva128_pbus_read(uint32_t addr, void *p) From 7c2335d6aa57c834e14043df641877121ed4e1e8 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 16 Feb 2017 20:17:16 -0600 Subject: [PATCH 081/392] Fix Windows 9x nVidia driver installation --- src/vid_nv_riva128.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 656797b17..c44ca6246 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -320,7 +320,7 @@ static uint8_t riva128_pmc_read(uint32_t addr, void *p) if(riva128->card_id == 0x03) switch(addr) { case 0x000000: - ret = 0x11; + ret = 0x01; break; case 0x000001: ret = 0x01; @@ -2660,10 +2660,10 @@ static void *riva128_init() riva128->pci_regs[6] = 0; riva128->pci_regs[7] = 2; - riva128->pci_regs[0x2c] = 0x02; - riva128->pci_regs[0x2d] = 0x11; - riva128->pci_regs[0x2e] = 0x16; - riva128->pci_regs[0x2f] = 0x10; + riva128->pci_regs[0x2c] = 0xd2; + riva128->pci_regs[0x2d] = 0x12; + riva128->pci_regs[0x2e] = 0x00; + riva128->pci_regs[0x2f] = 0x03; riva128->pci_regs[0x30] = 0x00; riva128->pci_regs[0x32] = 0x0c; From c4eb534269742899d909e6ffc6470ea65ede9060 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 16 Feb 2017 20:22:57 -0600 Subject: [PATCH 082/392] Fix a monstrous log blowup in nVidia drivers --- src/vid_nv_riva128.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index c44ca6246..3eeff57f6 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1828,7 +1828,8 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) addr &= 0xffffff; - pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + //DO NOT REMOVE. This fixes a monstrous log blowup in win9x's drivers when accessing PFIFO. + if(!((addr >= 0x002000) && (addr <= 0x003fff))) pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) { From 5b7ca99060cf48155a11499a44d14177d0301ed0 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 16 Feb 2017 20:41:41 -0600 Subject: [PATCH 083/392] Fix Windows 9x installation AGAIN --- src/vid_nv_riva128.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 3eeff57f6..1fce70ad9 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -2208,7 +2208,7 @@ static uint8_t riva128_pci_read(int func, int addr, void *p) break; case 0x08: - ret = 0x01; + ret = 0x00; break; /*Revision ID*/ case 0x09: ret = 0; From f67f14d6488dd3b58d5428ccc1d7c82bfd5f3ee0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Feb 2017 23:45:18 +0100 Subject: [PATCH 084/392] BusLogic callback no longer fatals the emulator when called with mailbox count 0 but just disables the callback; Reverted the ATI Mach64GX code to that from mainline PCem. --- src/buslogic.c | 4 +- src/vid_ati_mach64.c | 136 +++++++++++-------------------------------- src/vid_ati_mach64.h | 3 - 3 files changed, 37 insertions(+), 106 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 263368708..215fab872 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -2176,7 +2176,9 @@ void BuslogicCommandCallback(void *p) } else { - fatal("Callback active with mailbox count 0!\n"); + // fatal("Callback active with mailbox count 0!\n"); + BuslogicCallback = 0; + return; } } else if (BuslogicInOperation == 1) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index b74ad8d73..4c39fa344 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -1,6 +1,3 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ /*ATI Mach64 emulation*/ #include #include "ibm.h" @@ -110,9 +107,9 @@ typedef struct mach64_t uint32_t gen_test_cntl; uint32_t gui_traj_cntl; - - uint32_t host_cntl; + uint32_t host_cntl; + uint32_t mem_cntl; uint32_t ovr_clr; @@ -284,15 +281,6 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) break; case 0x1cf: mach64->regs[mach64->index & 0x3f] = val; - if ((mach64->index & 0x3f) == 0x2d) - { - if (val & 8) - { - svga->charseta = (svga->charseta & 0x3ffff) | ((((uint32_t) val) >> 4) << 18); - svga->charsetb = (svga->charsetb & 0x3ffff) | ((((uint32_t) val) >> 4) << 18); - } - break; - } if ((mach64->index & 0x3f) == 0x36) mach64_recalctimings(svga); break; @@ -316,8 +304,6 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) svga->crtcreg = val & 0x3f; return; case 0x3D5: - if (svga->crtcreg <= 0x18) - val &= mask_crtc[svga->crtcreg]; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -379,18 +365,11 @@ void mach64_recalctimings(svga_t *svga) svga->vtotal = (mach64->crtc_v_total_disp & 2047) + 1; svga->dispend = ((mach64->crtc_v_total_disp >> 16) & 2047) + 1; svga->htotal = (mach64->crtc_h_total_disp & 255) + 1; - if (mach64->regs[0x2d] & 8) svga->htotal |= (mach64->regs[0x2d] & 1) ? 0x100 : 0; svga->hdisp_time = svga->hdisp = ((mach64->crtc_h_total_disp >> 16) & 255) + 1; svga->vsyncstart = (mach64->crtc_v_sync_strt_wid & 2047) + 1; svga->rowoffset = (mach64->crtc_off_pitch >> 22); svga->clock = cpuclock / mach64->ics2595.output_clock; svga->ma_latch = (mach64->crtc_off_pitch & 0x1fffff) * 2; - if (mach64->regs[0x2d] & 8) - { - svga->ma_latch |= (((uint32_t) (mach64->regs[0x30] & 0x40)) >> 6) << 16; - svga->ma_latch |= (((uint32_t) (mach64->regs[0x23] & 0x10)) >> 4) << 17; - svga->ma_latch |= (((uint32_t) (mach64->regs[0x2d] & 0xc)) >> 2) << 18; - } svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; svga->vblankstart = svga->dispend; @@ -484,22 +463,20 @@ void mach64_updatemapping(mach64_t *mach64) svga->banked_mask = 0x7fff; break; } - // if (mach64->linear_base) - if ((mach64->config_cntl & 3) && mach64->linear_base) + if (mach64->linear_base) { if ((mach64->config_cntl & 3) == 2) { /*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, (mach64->linear_base & 0xff800000), (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, (mach64->linear_base & 0xff800000) + ((8 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); } else { /*4 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, (mach64->linear_base & 0xffc00000), (4 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, (mach64->linear_base & 0xffc00000) + ((4 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); } - svga->linear_base = mach64->linear_base; } else { @@ -667,7 +644,7 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val case 0x23c: case 0x23d: case 0x23e: case 0x23f: mach64_blit(val, 8, mach64); break; - + case 0x240: case 0x241: case 0x242: case 0x243: WRITE8(addr, mach64->host_cntl, val); break; @@ -890,7 +867,6 @@ void mach64_start_fill(mach64_t *mach64) mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; mach64->accel.x_count = mach64->accel.dst_width; - mach64->accel.y_count = mach64->accel.dst_height; mach64->accel.src_x = 0; mach64->accel.src_y = 0; @@ -1084,16 +1060,10 @@ void mach64_start_line(mach64_t *mach64) mach64->accel.op = OP_LINE; } -#if 0 #define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) & mach64->vram_mask]; \ else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask]; \ else if (width == 2) dat = *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask]; \ else dat = (svga->vram[((addr) >> 3) & mach64->vram_mask] >> ((addr) & 7)) & 1; -#endif -#define READ(addr, dat, width) if (width == 0) dat = svga->vram[((addr)) % (mach64->vram_mask + 1)]; \ - else if (width == 1) dat = *(uint16_t *)&svga->vram[((addr) << 1) % (mach64->vram_mask + 1)]; \ - else if (width == 2) dat = *(uint32_t *)&svga->vram[((addr) << 2) % (mach64->vram_mask + 1)]; \ - else dat = (svga->vram[((addr) >> 3) % (mach64->vram_mask + 1)] >> ((addr) & 7)) & 1; #define MIX switch (mix ? mach64->accel.mix_fg : mach64->accel.mix_bg) \ { \ @@ -1115,36 +1085,28 @@ void mach64_start_line(mach64_t *mach64) case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ } -#if 0 - if (dest_dat & 1) \ - svga->vram[((addr) >> 3) % (mach64->vram_mask + 1)] |= 1 << ((addr) & 7); \ - else \ - svga->vram[((addr) >> 3) % (mach64->vram_mask + 1)] &= ~(1 << ((addr) & 7)); \ - svga->changedvram[(((addr) >> 3) % (mach64->vram_mask + 1)) >> 12] = changeframecount; -#endif - #define WRITE(addr, width) if (width == 0) \ { \ - svga->vram[(addr) % (mach64->vram_mask + 1)] = dest_dat; \ - svga->changedvram[((addr) % (mach64->vram_mask + 1)) >> 12] = changeframecount; \ + svga->vram[(addr) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[((addr) & mach64->vram_mask) >> 12] = changeframecount; \ } \ else if (width == 1) \ { \ - *(uint16_t *)&svga->vram[((addr) << 1) % (mach64->vram_mask + 1)] = dest_dat; \ - svga->changedvram[(((addr) << 1) % (mach64->vram_mask + 1)) >> 12] = changeframecount; \ + *(uint16_t *)&svga->vram[((addr) << 1) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 1) & mach64->vram_mask) >> 12] = changeframecount; \ } \ else if (width == 2) \ { \ - *(uint32_t *)&svga->vram[((addr) << 2) % (mach64->vram_mask + 1)] = dest_dat; \ - svga->changedvram[(((addr) << 2) % (mach64->vram_mask + 1)) >> 12] = changeframecount; \ + *(uint32_t *)&svga->vram[((addr) << 2) & mach64->vram_mask] = dest_dat; \ + svga->changedvram[(((addr) << 2) & mach64->vram_mask) >> 12] = changeframecount; \ } \ else \ { \ if (dest_dat & 1) \ - svga->vram[((addr) >> 3) % (mach64->vram_mask + 1)] |= 1 << ((addr) & 7); \ + svga->vram[((addr) >> 3) & mach64->vram_mask] |= 1 << ((addr) & 7); \ else \ - svga->vram[((addr) >> 3) % (mach64->vram_mask + 1)] &= ~(1 << ((addr) & 7)); \ - svga->changedvram[(((addr) >> 3) % (mach64->vram_mask + 1)) >> 12] = changeframecount; \ + svga->vram[((addr) >> 3) & mach64->vram_mask] &= ~(1 << ((addr) & 7)); \ + svga->changedvram[(((addr) >> 3) & mach64->vram_mask) >> 12] = changeframecount; \ } void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) @@ -1541,8 +1503,7 @@ void mach64_load_context(mach64_t *mach64) while (mach64->context_load_cntl & 0x30000) { - // addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; - addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) % (mach64->vram_mask + 1); + addr = ((0x3fff - (mach64->context_load_cntl & 0x3fff)) * 256) & mach64->vram_mask; mach64->context_mask = *(uint32_t *)&svga->vram[addr]; #ifdef MACH64_DEBUG pclog("mach64_load_context %08X from %08X : mask %08X\n", mach64->context_load_cntl, addr, mach64->context_mask); @@ -2251,20 +2212,10 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) break; case 0x72ec: - if (mach64->vram_size == 8) - { - if (PCI) - ret = 7 | (6 << 3); /*PCI, 256Kx16 DRAM*/ - else - ret = 6 | (6 << 3); /*VLB, 256Kx16 DRAM*/ - } - else - { - if (PCI) - ret = 7 | (3 << 3); /*PCI, 256Kx16 DRAM*/ - else - ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/ - } + if (PCI) + ret = 7 | (3 << 3); /*PCI, 256Kx16 DRAM*/ + else + ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/ break; case 0x72ed: ret = 5 << 1; /*ATI-68860*/ @@ -2423,7 +2374,6 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: WRITE8(port, mach64->config_cntl, val); - mach64->linear_base = ((mach64->config_cntl & 0x3ff0) >> 4) << 22; mach64_updatemapping(mach64); break; } @@ -2496,24 +2446,22 @@ void mach64_hwcursor_draw(svga_t *svga, int displine) uint8_t dat; uint32_t col0 = mach64->ramdac.pallook[0]; uint32_t col1 = mach64->ramdac.pallook[1]; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; offset = svga->hwcursor_latch.xoff; for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 32 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 32 + x_add] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 33 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 33 + x_add] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 34 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 34 + x_add] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 35 + x_add] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 35 + x_add] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; dat >>= 2; offset += 4; } @@ -2613,11 +2561,11 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x12: - mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0xc0) << 16); + mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); mach64_updatemapping(mach64); break; case 0x13: - mach64->linear_base = (mach64->linear_base & 0xc00000) | (val << 24); + mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); mach64_updatemapping(mach64); break; @@ -2642,14 +2590,12 @@ void *mach64gx_init() { int c; mach64_t *mach64 = malloc(sizeof(mach64_t)); - uint32_t vram_amount = 0; memset(mach64, 0, sizeof(mach64_t)); mach64->vram_size = device_get_config_int("memory"); - vram_amount = (mach64-> vram_size == 0) ? (1 << 19) : (mach64->vram_size << 20); - mach64->vram_mask = vram_amount - 1; + mach64->vram_mask = (mach64->vram_size << 20) - 1; - svga_init(&mach64->svga, mach64, vram_amount, + svga_init(&mach64->svga, mach64, mach64->vram_size << 20, mach64_recalctimings, mach64_in, mach64_out, mach64_hwcursor_draw, @@ -2681,16 +2627,6 @@ void *mach64gx_init() mach64->dst_cntl = 3; - switch(mach64->vram_size) - { - case 0: default: mach64->mem_cntl = 0; break; - case 1: mach64->mem_cntl = 1; break; - case 2: mach64->mem_cntl = 2; break; - case 4: mach64->mem_cntl = 3; break; - case 6: mach64->mem_cntl = 4; break; - case 8: mach64->mem_cntl = 5; break; - } - mach64->wake_fifo_thread = thread_create_event(); mach64->fifo_not_full_event = thread_create_event(); mach64->fifo_thread = thread_create(fifo_thread, mach64); @@ -2782,10 +2718,6 @@ static device_config_t mach64gx_config[] = .type = CONFIG_SELECTION, .selection = { - { - .description = "512 kB", - .value = 0 - }, { .description = "1 MB", .value = 1 diff --git a/src/vid_ati_mach64.h b/src/vid_ati_mach64.h index 6eedc3db2..95a7e9744 100644 --- a/src/vid_ati_mach64.h +++ b/src/vid_ati_mach64.h @@ -1,4 +1 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ extern device_t mach64gx_device; From 07e2e7f8f88dfdcdf8edef1a00959cb5c87c553b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 18 Feb 2017 00:46:08 +0100 Subject: [PATCH 085/392] mach64_updatemapping() now correctly sets svga->linear_base to mach64->linear_base. --- src/vid_ati_mach64.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 4c39fa344..9b95266a7 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -423,6 +423,8 @@ void mach64_updatemapping(mach64_t *mach64) { svga_t *svga = &mach64->svga; + svga->linear_base = mach64->linear_base; + if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { pclog("Update mapping - PCI disabled\n"); From c7409972b500ca3dd56f759c4cff72d141eb9596 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 18 Feb 2017 03:17:23 +0100 Subject: [PATCH 086/392] Fixed the ATi Mach64GX. --- src/buslogic.c | 2 +- src/vid_ati_mach64.c | 54 ++++++++++++++++++++++---------------- src/vid_svga.c | 62 ++++++++++++++++++++++++++++---------------- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/src/buslogic.c b/src/buslogic.c index 215fab872..9248c636d 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -2177,7 +2177,7 @@ void BuslogicCommandCallback(void *p) else { // fatal("Callback active with mailbox count 0!\n"); - BuslogicCallback = 0; + BuslogicCallback += 50 * SCSI_TIME; return; } } diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 9b95266a7..f2faa8138 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -423,8 +423,6 @@ void mach64_updatemapping(mach64_t *mach64) { svga_t *svga = &mach64->svga; - svga->linear_base = mach64->linear_base; - if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { pclog("Update mapping - PCI disabled\n"); @@ -442,7 +440,7 @@ void mach64_updatemapping(mach64_t *mach64) case 0x0: /*128k at A0000*/ mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL); mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x1fc00); mem_mapping_enable(&mach64->mmio_mapping); svga->banked_mask = 0xffff; break; @@ -461,7 +459,7 @@ void mach64_updatemapping(mach64_t *mach64) case 0xC: /*32k at B8000*/ mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x07c00); svga->banked_mask = 0x7fff; break; } @@ -470,15 +468,18 @@ void mach64_updatemapping(mach64_t *mach64) if ((mach64->config_cntl & 3) == 2) { /*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + pclog("8 MB aperture\n"); + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x007FFC00); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x007FFC00, 0x400); } else { /*4 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); + pclog("4 MB aperture\n"); + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x003FFC00); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x003FFC00, 0x400); } + svga->linear_base = mach64->linear_base; } else { @@ -2448,22 +2449,24 @@ void mach64_hwcursor_draw(svga_t *svga, int displine) uint8_t dat; uint32_t col0 = mach64->ramdac.pallook[0]; uint32_t col1 = mach64->ramdac.pallook[1]; + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; offset = svga->hwcursor_latch.xoff; for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 32] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 32 + x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 32 + x_add] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 33] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 33 + x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 33 + x_add] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 34] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 34 + x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 34 + x_add] ^= 0xFFFFFF; dat >>= 2; - if (!(dat & 2)) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] = (dat & 1) ? col1 : col0; - else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine])[svga->hwcursor_latch.x + x + 35] ^= 0xFFFFFF; + if (!(dat & 2)) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 35 + x_add] = (dat & 1) ? col1 : col0; + else if ((dat & 3) == 3) ((uint32_t *)buffer32->line[displine + y_add])[svga->hwcursor_latch.x + x + 35 + x_add] ^= 0xFFFFFF; dat >>= 2; offset += 4; } @@ -2529,12 +2532,14 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x08: return 0; /*Revision ID*/ case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ + // case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ + case 0x0a: return 0x00; case 0x0b: return 0x03; case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return mach64->linear_base >> 16; + // case 0x12: return mach64->linear_base >> 16; + case 0x12: return 0x00; case 0x13: return mach64->linear_base >> 24; case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ @@ -2545,6 +2550,8 @@ uint8_t mach64_pci_read(int func, int addr, void *p) return 0; } +uint32_t bios_base = 0x000c0000; + void mach64_pci_write(int func, int addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; @@ -2555,19 +2562,21 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) { case PCI_REG_COMMAND: mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; + if (val & PCI_COMMAND_IO) mach64_io_set(mach64); else mach64_io_remove(mach64); + mach64_updatemapping(mach64); break; - case 0x12: + /* case 0x12: mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); mach64_updatemapping(mach64); - break; + break; */ case 0x13: - mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); + mach64->linear_base = (val << 24); mach64_updatemapping(mach64); break; @@ -2576,6 +2585,7 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) if (mach64->pci_regs[0x30] & 0x01) { uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); + bios_base = addr; pclog("Mach64 bios_rom enabled at %08x\n", addr); mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); } @@ -2609,7 +2619,7 @@ void *mach64gx_init() mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->mmio_mapping, 0xbfc00, 0x00400, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); mem_mapping_disable(&mach64->mmio_mapping); mach64_io_set(mach64); diff --git a/src/vid_svga.c b/src/vid_svga.c index 7aabec6f6..0a8970b43 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -102,7 +102,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) return; case 0x3C0: - case 0x3C1: + // case 0x3C1: if (!svga->attrff) { svga->attraddr = val & 31; @@ -1313,7 +1313,10 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) { addr<<=2; } - // addr %= svga->vram_limit; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } if (addr >= svga->vram_limit) return; if (svga_output) pclog("%08X\n", addr); @@ -1481,10 +1484,14 @@ uint8_t svga_read_linear(uint32_t addr, void *p) if (svga->chain4 || svga->fb_only) { - // addr %= svga->vram_limit; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } if (addr >= svga->vram_limit) return 0xff; - return svga->vram[svga_mask_addr(addr, svga)]; + // return svga->vram[svga_mask_addr(addr, svga)]; + return svga->vram[addr]; } else if (svga->chain2_read) { @@ -1495,17 +1502,20 @@ uint8_t svga_read_linear(uint32_t addr, void *p) else addr<<=2; - // addr %= svga->vram_limit; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } if (addr >= svga->vram_limit) return 0xff; - addr = svga_mask_addr(addr, svga); + // addr = svga_mask_addr(addr, svga); - svga->la = svga->vram[latch_addr]; - svga->lb = svga->vram[latch_addr | 0x1]; - svga->lc = svga->vram[latch_addr | 0x2]; - svga->ld = svga->vram[latch_addr | 0x3]; + svga->la = svga->vram[addr]; + svga->lb = svga->vram[addr | 0x1]; + svga->lc = svga->vram[addr | 0x2]; + svga->ld = svga->vram[addr | 0x3]; if (svga->readmode) { temp = (svga->colournocare & 1) ? 0xff : 0; @@ -1644,7 +1654,6 @@ void svga_writew(uint32_t addr, uint16_t val, void *p) if (svga_output) pclog("svga_writew: %05X ", addr); addr = (addr & svga->banked_mask) + svga->write_bank; - // addr %= svga->vram_limit; if ((!svga->extvram) && (addr >= 0x10000)) return; if (addr >= svga->vram_limit) return; @@ -1675,7 +1684,6 @@ void svga_writel(uint32_t addr, uint32_t val, void *p) if (svga_output) pclog("svga_writel: %05X ", addr); addr = (addr & svga->banked_mask) + svga->write_bank; - // addr %= svga->vram_limit; if ((!svga->extvram) && (addr >= 0x10000)) return; if (addr >= svga->vram_limit) return; @@ -1701,7 +1709,6 @@ uint16_t svga_readw(uint32_t addr, void *p) // pclog("Readw %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; - // addr %= svga->vram_limit; if ((!svga->extvram) && (addr >= 0x10000)) return 0xffff; // pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); if (addr >= svga->vram_limit) return 0xffff; @@ -1728,7 +1735,6 @@ uint32_t svga_readl(uint32_t addr, void *p) // pclog("Readl %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; - // addr %= svga->vram_limit; if ((!svga->extvram) && (addr >= 0x10000)) return 0xffffffff; // pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); if (addr >= svga->vram_limit) return 0xffffffff; @@ -1755,9 +1761,12 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *p) cycles_lost += video_timing_w; if (svga_output) pclog("Write LFBw %08X %04X\n", addr, val); - // addr %= svga->vram_limit; addr -= svga->linear_base; - if ((!svga->extvram) && (addr >= 0x10000)) return; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } + // if ((!svga->extvram) && (addr >= 0x10000)) return; if (addr >= svga->vram_limit) return; svga->changedvram[addr >> 12] = changeframecount; @@ -1785,9 +1794,12 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p) cycles_lost += video_timing_l; if (svga_output) pclog("Write LFBl %08X %08X\n", addr, val); - // addr %= svga->vram_limit; addr -= svga->linear_base; - if ((!svga->extvram) && (addr >= 0x10000)) return; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } + // if ((!svga->extvram) && (addr >= 0x10000)) return; if (addr >= svga->vram_limit) return; svga->changedvram[addr >> 12] = changeframecount; @@ -1808,9 +1820,12 @@ uint16_t svga_readw_linear(uint32_t addr, void *p) cycles -= video_timing_w; cycles_lost += video_timing_w; - // addr %= svga->vram_limit; addr -= svga->linear_base; - if ((!svga->extvram) && (addr >= 0x10000)) return 0xffff; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } + // if ((!svga->extvram) && (addr >= 0x10000)) return 0xffff; if (addr >= svga->vram_limit) return 0xffff; return *(uint16_t *)&svga->vram[addr]; @@ -1830,9 +1845,12 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) cycles -= video_timing_l; cycles_lost += video_timing_l; - // addr %= svga->vram_limit; addr -= svga->linear_base; - if ((!svga->extvram) && (addr >= 0x10000)) return 0xffffffff; + if ((gfxcard != GFX_RIVA128) && (gfxcard != GFX_RIVATNT) && (gfxcard != GFX_RIVATNT2)) + { + addr &= 0x7fffff; + } + // if ((!svga->extvram) && (addr >= 0x10000)) return 0xffffffff; if (addr >= svga->vram_limit) return 0xffffffff; return *(uint32_t *)&svga->vram[addr]; From 257d37de829f08d58d1833137baef25003df98e6 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 18 Feb 2017 13:40:26 -0600 Subject: [PATCH 087/392] Fix log blowup --- src/vid_nv_riva128.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 1fce70ad9..04555910a 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -320,7 +320,7 @@ static uint8_t riva128_pmc_read(uint32_t addr, void *p) if(riva128->card_id == 0x03) switch(addr) { case 0x000000: - ret = 0x01; + ret = 0x10; break; case 0x000001: ret = 0x01; @@ -1736,7 +1736,7 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) addr &= 0xffffff; //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. - if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <- 0x003fff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { From 946e9d8b7e1d099c9b488efc1fbe648ef0ca1111 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 18 Feb 2017 23:45:30 +0100 Subject: [PATCH 088/392] joystick_init() is now called after loading the configuration file - makes the emulator not load the joystick at all if joystick_type is set to 7 (No Joystick). --- src/pc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pc.c b/src/pc.c index 85659113c..e0ab1e0db 100644 --- a/src/pc.c +++ b/src/pc.c @@ -240,7 +240,6 @@ void initpc(int argc, char *argv[]) keyboard_init(); mouse_init(); - joystick_init(); midi_init(); if (config_file == NULL) @@ -257,6 +256,8 @@ void initpc(int argc, char *argv[]) if (config_file) saveconfig(); + joystick_init(); + cpuspeed2=(AT)?2:1; // cpuspeed2=cpuspeed; atfullspeed=0; From b8418b94dec4e86ae714afdd27e4fcf1bac454db Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 01:58:21 +0100 Subject: [PATCH 089/392] Added emulation of the Intel 82335 chip for the Phoenix 386 clone; Added the Samsung SPC-4200P; Added the Chips & Technologies VGA 451; Applied all mainline PCem commits; Added Amstrad MegaPC 386DX model (exits per documentation that I have in German). --- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/cpu.c | 32 ++++++------------------- src/cpu.h | 6 ++--- src/i82335.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ src/i82335.h | 1 + src/ibm.h | 9 ++++--- src/mem.c | 11 ++++++--- src/model.c | 25 ++++++++++++++------ src/nvr.c | 4 ++++ src/vid_vga.c | 37 +++++++++++++++++++++++++++++ src/vid_vga.h | 1 + src/vid_voodoo.c | 2 ++ src/video.c | 1 + 14 files changed, 146 insertions(+), 43 deletions(-) create mode 100644 src/i82335.c create mode 100644 src/i82335.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 3b3c23cf8..a91fe441d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -6,7 +6,7 @@ CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loo DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ + device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 7cd949b1a..277ffadcb 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -6,7 +6,7 @@ CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loo DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ + device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ diff --git a/src/cpu.c b/src/cpu.c index fc811f532..af49feb4d 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -228,28 +228,20 @@ CPU cpus_ps1_m2011[] = {"", -1, 0, 0, 0, 0} }; -CPU cpus_i386[] = +CPU cpus_i386SX[] = { - /*i386*/ + /*i386SX*/ {"i386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3}, {"i386SX/20", CPU_386SX, 1, 20000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3}, {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3}, {"i386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3}, {"i386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3}, - {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3}, - {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3}, - {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3}, - {"i386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3}, - {"i386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3}, - {"RapidCAD/25", CPU_RAPIDCAD, 2, 25000000, 1, 0, 0x430, 0, 0, 0, 4,4,3,3}, - {"RapidCAD/33", CPU_RAPIDCAD, 3, 33333333, 1, 0, 0x430, 0, 0, 0, 6,6,3,3}, - {"RapidCAD/40", CPU_RAPIDCAD, 4, 40000000, 1, 0, 0x430, 0, 0, 0, 7,7,3,3}, {"", -1, 0, 0, 0} }; CPU cpus_i386DX[] = { - /*i386*/ + /*i386DX*/ {"i386DX/16", CPU_386DX, 0, 16000000, 1, 0, 0x0308, 0, 0, 0, 3,3,3,3}, {"i386DX/20", CPU_386DX, 1, 20000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3}, {"i386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3}, @@ -263,12 +255,12 @@ CPU cpus_i386DX[] = CPU cpus_acer[] = { - /*i386*/ + /*i386SX*/ {"i386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,4,4}, {"", -1, 0, 0, 0} }; -CPU cpus_Am386[] = +CPU cpus_Am386SX[] = { /*Am386*/ {"Am386SX/16", CPU_386SX, 0, 16000000, 1, 0, 0x2308, 0, 0, 0, 3,3,3,3}, @@ -276,9 +268,6 @@ CPU cpus_Am386[] = {"Am386SX/25", CPU_386SX, 2, 25000000, 1, 0, 0x2308, 0, 0, 0, 4,4,3,3}, {"Am386SX/33", CPU_386SX, 3, 33333333, 1, 0, 0x2308, 0, 0, 0, 6,6,3,3}, {"Am386SX/40", CPU_386SX, 4, 40000000, 1, 0, 0x2308, 0, 0, 0, 7,7,3,3}, - {"Am386DX/25", CPU_386DX, 2, 25000000, 1, 0, 0x0308, 0, 0, 0, 4,4,3,3}, - {"Am386DX/33", CPU_386DX, 3, 33333333, 1, 0, 0x0308, 0, 0, 0, 6,6,3,3}, - {"Am386DX/40", CPU_386DX, 4, 40000000, 1, 0, 0x0308, 0, 0, 0, 7,7,3,3}, {"", -1, 0, 0, 0} }; @@ -292,22 +281,15 @@ CPU cpus_Am386DX[] = {"", -1, 0, 0, 0} }; -CPU cpus_486SDLC[] = +CPU cpus_486SLC[] = { - /*Cx486SLC/DLC*/ + /*Cx486SLC*/ {"Cx486SLC/20", CPU_486SLC, 1, 20000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3}, {"Cx486SLC/25", CPU_486SLC, 2, 25000000, 1, 0, 0x400, 0, 0x0000, 0, 4,4,3,3}, {"Cx486SLC/33", CPU_486SLC, 3, 33333333, 1, 0, 0x400, 0, 0x0000, 0, 6,6,3,3}, {"Cx486SRx2/32", CPU_486SLC, 3, 32000000, 2, 0, 0x406, 0, 0x0006, 0, 6,6,6,6}, {"Cx486SRx2/40", CPU_486SLC, 4, 40000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6}, {"Cx486SRx2/50", CPU_486SLC, 5, 50000000, 2, 0, 0x406, 0, 0x0006, 0, 8,8,6,6}, - {"Cx486DLC/25", CPU_486DLC, 2, 25000000, 1, 0, 0x401, 0, 0x0001, 0, 4,4,3,3}, - {"Cx486DLC/33", CPU_486DLC, 3, 33333333, 1, 0, 0x401, 0, 0x0001, 0, 6,6,3,3}, - {"Cx486DLC/40", CPU_486DLC, 4, 40000000, 1, 0, 0x401, 0, 0x0001, 0, 7,7,3,3}, - {"Cx486DRx2/32", CPU_486DLC, 3, 32000000, 2, 0, 0x407, 0, 0x0007, 0, 6,6,6,6}, - {"Cx486DRx2/40", CPU_486DLC, 4, 40000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6}, - {"Cx486DRx2/50", CPU_486DLC, 5, 50000000, 2, 0, 0x407, 0, 0x0007, 0, 8,8,6,6}, - {"Cx486DRx2/66", CPU_486DLC, 6, 66666666, 2, 0, 0x407, 0, 0x0007, 0, 12,12,6,6}, {"", -1, 0, 0, 0} }; diff --git a/src/cpu.h b/src/cpu.h index b75ee35b5..a1775ecac 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -85,11 +85,11 @@ typedef struct extern CPU cpus_8088[]; extern CPU cpus_8086[]; extern CPU cpus_286[]; -extern CPU cpus_i386[]; +extern CPU cpus_i386SX[]; extern CPU cpus_i386DX[]; -extern CPU cpus_Am386[]; +extern CPU cpus_Am386SX[]; extern CPU cpus_Am386DX[]; -extern CPU cpus_486SDLC[]; +extern CPU cpus_486SLC[]; extern CPU cpus_486DLC[]; extern CPU cpus_i486[]; extern CPU cpus_Am486[]; diff --git a/src/i82335.c b/src/i82335.c new file mode 100644 index 000000000..361b1bd0d --- /dev/null +++ b/src/i82335.c @@ -0,0 +1,56 @@ +/* Intel 82335 SX emulation, used by the Phoenix 386 clone. */ + +#include +#include "ibm.h" + +typedef struct +{ + uint8_t reg_22; +} i82335_t; + +i82335_t i82335; + +void i82335_write(uint16_t addr, uint8_t val, void *priv) +{ + int i = 0; + + switch (addr) + { + case 0x22: + i82335_t.reg_22 = val | 0xd8; + if (val & 1) + { + for (i = 0; i < 8; i++) + { + mem_mapping_enable(&bios_mapping[i]); + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_mapping_disable(&bios_mapping[i]); + } + } + break; + case 0x23: + if (val & 0x80) + { + io_removehandler(0x0022, 0x0001, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); + } + break; + } +} + +uint8_t i82335_read(uint16_t addr, void *priv) +{ +} + +void i82335_init() +{ + memset(i82335_t, 0, sizeof(i82335_t)); + + i82335_t.reg_22 = 0xd9; + + io_sethandler(0x0022, 0x0014, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); +} diff --git a/src/i82335.h b/src/i82335.h new file mode 100644 index 000000000..048730b80 --- /dev/null +++ b/src/i82335.h @@ -0,0 +1 @@ +void i82335_init(); diff --git a/src/ibm.h b/src/ibm.h index 5626ea263..e88b108d3 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -418,7 +418,10 @@ enum ROM_POWERMATE_V,/*NEC PowerMate V / 430FX / Phoenix BIOS / SMC FDC37C665*/ ROM_IBMPS1_2121_ISA,/*IBM PS/1 Model 2121 with ISA expansion bus*/ - + + ROM_SPC4200P, /*Samsung SPC-4200P / SCAT / Phoenix BIOS*/ + ROM_MEGAPCDX, /*386DX mdoel of the Mega PC - Note by Tohka: The documentation (that I have in German) clearly says such a model exists.*/ + ROM_MAX }; @@ -469,6 +472,7 @@ enum GFX_RIVATNT2, GFX_TRIGEM_UNK, + GFX_CHIPS_VGA, GFX_MAX }; @@ -496,8 +500,7 @@ float VGACONST1,VGACONST2; float RTCCONST; int gated,speakval,speakon; -// #define SOUNDBUFLEN (48000/40) -#define SOUNDBUFLEN (32000/20) +#define SOUNDBUFLEN (48000/20) /*Sound Blaster*/ diff --git a/src/mem.c b/src/mem.c index 460a4b204..def1e8c71 100644 --- a/src/mem.c +++ b/src/mem.c @@ -324,7 +324,6 @@ int loadbios() fclose(ff); fclose(f); biosmask = 0x7fff; - mem_load_atide_bios(); return 1; case ROM_DELL200: f=romfopen("roms/dells200/dell0.bin","rb"); @@ -428,6 +427,7 @@ int loadbios() return 1; case ROM_MEGAPC: + case ROM_MEGAPCDX: f = romfopen("roms/megapc/41651-bios lo.u18", "rb"); ff = romfopen("roms/megapc/211253-bios hi.u19", "rb"); if (!f || !ff) break; @@ -592,6 +592,13 @@ int loadbios() mem_load_xtide_bios(); return 1; + case ROM_SPC4200P: /*Samsung SPC-4200P*/ + f = romfopen("roms/spc4200p/U8.01", "rb"); + if (!f) break; + fread(rom, 65536, 1, f); + fclose(f); + return 1; + case ROM_PX386: /*Phoenix 80386 BIOS*/ f=romfopen("roms/px386/3iip001l.bin","rb"); ff=romfopen("roms/px386/3iip001h.bin","rb"); @@ -603,7 +610,6 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_atide_bios(); return 1; case ROM_DTK386: /*Uses NEAT chipset*/ @@ -611,7 +617,6 @@ int loadbios() if (!f) break; fread(rom, 65536, 1, f); fclose(f); - mem_load_atide_bios(); return 1; case ROM_PXXT: diff --git a/src/model.c b/src/model.c index 174fe63e0..a2518f2b2 100644 --- a/src/model.c +++ b/src/model.c @@ -32,6 +32,7 @@ #include "i430nx.h" #include "i430vx.h" #include "i440fx.h" +#include "i82335.h" #include "ide.h" #include "intel.h" #include "intel_flash.h" @@ -86,6 +87,7 @@ void ps1_m2121_init(); void at_neat_init(); void at_scat_init(); void at_acer386sx_init(); +void at_82335_init(); void at_wd76c10_init(); void at_ali1429_init(); void at_headland_init(); @@ -146,15 +148,18 @@ MODEL models[] = {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, - {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386, "AMD", cpus_Am386, "Cyrix", cpus_486SDLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, + {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_82335_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, +/* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ + {"Amstrad MegaPC 386DX",ROM_MEGAPCDX, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386SX "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, {"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, @@ -392,6 +397,12 @@ void at_acer386sx_init() acer386sx_init(); } +void at_82335_init() +{ + at_init(); + i82335_init(); +} + void at_wd76c10_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 450d6faa2..7e4e4223e 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -212,10 +212,12 @@ void loadnvr() case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "rb"); nvrmask = 127; break; + case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break; case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "rb"); nvrmask = 127; break; + case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "rb"); nvrmask = 127; break; case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "rb"); nvrmask = 127; break; @@ -291,10 +293,12 @@ void savenvr() case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "wb"); break; + case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break; case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "wb"); break; + case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "wb"); break; case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "wb"); break; case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "wb"); break; case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "wb"); break; diff --git a/src/vid_vga.c b/src/vid_vga.c index 3ad87e4bc..501643cf2 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -105,6 +105,27 @@ void *vga_init() return vga; } +void *vga_chips_init() +{ + vga_t *vga = malloc(sizeof(vga_t)); + memset(vga, 0, sizeof(vga_t)); + + rom_init(&vga->bios_rom, "roms/SD620.04M", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + + svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ + NULL, + vga_in, vga_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); + + vga->svga.bpp = 8; + vga->svga.miscout = 1; + + return vga; +} + void *trigem_unk_init() { vga_t *vga = malloc(sizeof(vga_t)); @@ -155,6 +176,11 @@ static int vga_available() return rom_present("roms/ibm_vga.bin"); } +static int vga_chips_available() +{ + return rom_present("roms/SD620.04M"); +} + void vga_close(void *p) { vga_t *vga = (vga_t *)p; @@ -196,6 +222,17 @@ device_t vga_device = vga_force_redraw, vga_add_status_info }; +device_t vga_chips_device = +{ + "Chips VGA", + 0, + vga_chips_init, + vga_close, + vga_chips_available, + vga_speed_changed, + vga_force_redraw, + vga_add_status_info +}; device_t trigem_unk_device = { "VGA", diff --git a/src/vid_vga.h b/src/vid_vga.h index 5ee66fc0b..77aff5056 100644 --- a/src/vid_vga.h +++ b/src/vid_vga.h @@ -2,5 +2,6 @@ see COPYING for more details */ extern device_t vga_device; +extern device_t vga_chips_device; extern device_t trigem_unk_device; extern device_t ps1vga_device; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index ca7c64359..deb9e69e7 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -5922,6 +5922,8 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) happen here on a real Voodoo*/ voodoo->disp_buffer = 0; voodoo->draw_buffer = 1; + voodoo_recalc(voodoo); + voodoo->front_offset = voodoo->params.front_offset; } } break; diff --git a/src/video.c b/src/video.c index 9211ac742..6e86633ca 100644 --- a/src/video.c +++ b/src/video.c @@ -69,6 +69,7 @@ static VIDEO_CARD video_cards[] = {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, {"EGA", &ega_device, GFX_EGA}, {"Chips & Technologies SuperEGA", &sega_device, GFX_SUPER_EGA}, + {"Chips & Technologies VGA 451", &vga_chips_device, GFX_CHIPS_VGA}, {"Compaq ATI VGA Wonder XL (ATI-28800-5)", &compaq_ati28800_device, GFX_VGAWONDERXL}, {"Compaq EGA", &cpqega_device, GFX_COMPAQ_EGA}, {"Compaq/Paradise VGA", &cpqvga_device, GFX_COMPAQ_VGA}, From a409ef71be8db3991fc2ae649f33bcf8313872f2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 02:39:12 +0100 Subject: [PATCH 090/392] Fixed compile-breaking errors in i82335.c. --- src/i82335.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/i82335.c b/src/i82335.c index 361b1bd0d..5ac2c8790 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -2,6 +2,8 @@ #include #include "ibm.h" +#include "io.h" +#include "mem.h" typedef struct { @@ -17,7 +19,7 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x22: - i82335_t.reg_22 = val | 0xd8; + i82335.reg_22 = val | 0xd8; if (val & 1) { for (i = 0; i < 8; i++) @@ -48,9 +50,9 @@ uint8_t i82335_read(uint16_t addr, void *priv) void i82335_init() { - memset(i82335_t, 0, sizeof(i82335_t)); + memset(i82335, 0, sizeof(i82335_t)); - i82335_t.reg_22 = 0xd9; + i82335.reg_22 = 0xd9; io_sethandler(0x0022, 0x0014, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); } From b9ebebdbaa2815b6d43f0c28a21d5a2efea5c4f5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 02:44:40 +0100 Subject: [PATCH 091/392] Fixed more compile-breaking errors in i82335.c. --- src/i82335.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/i82335.c b/src/i82335.c index 5ac2c8790..13e31a4e9 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -8,6 +8,7 @@ typedef struct { uint8_t reg_22; + uint8_t reg_23; } i82335_t; i82335_t i82335; @@ -36,6 +37,7 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) } break; case 0x23: + i82335.reg_23 = val | 0xd8; if (val & 0x80) { io_removehandler(0x0022, 0x0001, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); @@ -46,11 +48,19 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) uint8_t i82335_read(uint16_t addr, void *priv) { + if (addr == 0x22) + { + return i82335.reg_22; + } + else if (addr == 0x23) + { + return i82335.reg_23; + } } void i82335_init() { - memset(i82335, 0, sizeof(i82335_t)); + memset(&i82335, 0, sizeof(i82335_t)); i82335.reg_22 = 0xd9; From b64f7ea50222a57fe6818aeb663518960ea0032f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 02:47:01 +0100 Subject: [PATCH 092/392] Fixed last compile-breaking error in i82335.c. --- src/i82335.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/i82335.c b/src/i82335.c index 13e31a4e9..75a593484 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -13,6 +13,8 @@ typedef struct i82335_t i82335; +uint8_t i82335_read(uint16_t addr, void *priv); + void i82335_write(uint16_t addr, uint8_t val, void *priv) { int i = 0; From b440d749defb1b986073fb8ad7c5dd68f7189272 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 02:51:26 +0100 Subject: [PATCH 093/392] Fixed compile-breaking error in model.c. --- src/model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index a2518f2b2..0253cd97a 100644 --- a/src/model.c +++ b/src/model.c @@ -159,7 +159,7 @@ MODEL models[] = {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ {"Amstrad MegaPC 386DX",ROM_MEGAPCDX, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386SX "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, {"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, From 92be9c98dfe127aa24d55dcd13513ffe9b2ed3c4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 16:36:43 +0100 Subject: [PATCH 094/392] Added ability to choose monochrome displays (green, amber, and gray) for CGA MDA, and Hercules graphics cards, based on VileRancour's DOSBox patch. --- src/vid_cga.c | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/vid_hercules.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/vid_mda.c | 47 ++++++++++++++++++++++++++++++++++++++++++ src/video.c | 10 +++++++++ src/video.h | 2 ++ src/win-cgapal.h | 4 ++++ src/win-d3d-fs.cc | 45 +++++++++++++++++++++++++++++++++++++--- src/win-d3d.cc | 27 ++---------------------- src/win-ddraw-fs.cc | 27 ++---------------------- src/win-ddraw.cc | 27 ++---------------------- 10 files changed, 208 insertions(+), 78 deletions(-) create mode 100644 src/win-cgapal.h diff --git a/src/vid_cga.c b/src/vid_cga.c index 6b69e7aca..608599e29 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -12,6 +12,9 @@ #include "video.h" #include "vid_cga.h" #include "dosbox/vid_cga_comp.h" +#ifndef __unix +#include "win-cgapal.h" +#endif #define CGA_RGB 0 #define CGA_COMPOSITE 1 @@ -461,6 +464,11 @@ void *cga_standalone_init() io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); overscan_x = overscan_y = 16; + +#ifndef __unix + cga_palette = device_get_config_int("rgb_type"); + rebuild_cgapal(); +#endif return cga; } @@ -522,6 +530,48 @@ static device_config_t cga_config[] = }, .default_int = COMPOSITE_OLD }, +#ifndef __unix + { + .name = "rgb_type", + .description = "RGB type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Full 16-color", + .value = 0 + }, + { + .description = "Green, 4-color", + .value = 1 + }, + { + .description = "Green, 16-color", + .value = 2 + }, + { + .description = "Amber, 4-color", + .value = 3 + }, + { + .description = "Amber, 16-color", + .value = 4 + }, + { + .description = "Gray, 4-color", + .value = 5 + }, + { + .description = "Gray, 16-color", + .value = 6 + }, + { + .description = "" + } + }, + .default_int = 0 + }, +#endif { .name = "snow_enabled", .description = "Snow emulation", diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 9c24d8de5..8ea99e868 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -9,6 +9,9 @@ #include "timer.h" #include "video.h" #include "vid_hercules.h" +#ifndef __unix +#include "win-cgapal.h" +#endif typedef struct hercules_t { @@ -342,6 +345,11 @@ void *hercules_init() overscan_x = overscan_y = 0; +#ifndef __unix + cga_palette = device_get_config_int("rgb_type"); + rebuild_cgapal(); +#endif + return hercules; } @@ -360,6 +368,40 @@ void hercules_speed_changed(void *p) hercules_recalctimings(hercules); } +#ifndef __unix +static device_config_t hercules_config[] = +{ + { + .name = "rgb_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Default 4-color", + .value = 0 + }, + { + .description = "Green, 4-color", + .value = 1 + }, + { + .description = "Amber, 4-color", + .value = 3 + }, + { + .description = "Gray, 4-color", + .value = 5 + }, + { + .description = "" + } + }, + .default_int = 0 + } +}; +#endif + device_t hercules_device = { "Hercules", @@ -369,5 +411,10 @@ device_t hercules_device = NULL, hercules_speed_changed, NULL, +#ifdef __unix NULL +#else + NULL, + hercules_config +#endif }; diff --git a/src/vid_mda.c b/src/vid_mda.c index 41461331a..3c3015d07 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -10,6 +10,9 @@ #include "timer.h" #include "video.h" #include "vid_mda.h" +#ifndef __unix +#include "win-cgapal.h" +#endif typedef struct mda_t { @@ -298,6 +301,11 @@ void *mda_init() overscan_x = overscan_y = 0; +#ifndef __unix + cga_palette = device_get_config_int("rgb_type"); + rebuild_cgapal(); +#endif + return mda; } @@ -316,6 +324,40 @@ void mda_speed_changed(void *p) mda_recalctimings(mda); } +#ifndef __unix +static mda_config_t hercules_config[] = +{ + { + .name = "rgb_type", + .description = "Display type", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "Default 4-color", + .value = 0 + }, + { + .description = "Green, 4-color", + .value = 1 + }, + { + .description = "Amber, 4-color", + .value = 3 + }, + { + .description = "Gray, 4-color", + .value = 5 + }, + { + .description = "" + } + }, + .default_int = 0 + } +}; +#endif + device_t mda_device = { "MDA", @@ -325,5 +367,10 @@ device_t mda_device = NULL, mda_speed_changed, NULL, +#ifdef __unix NULL +#else + NULL, + mda_config +#endif }; diff --git a/src/video.c b/src/video.c index 6e86633ca..ee3bdf0d9 100644 --- a/src/video.c +++ b/src/video.c @@ -16,6 +16,9 @@ #include "rom.h" #include "thread.h" #include "timer.h" +#ifndef __unix +#include "win-cgapal.h" +#endif #include "vid_ati18800.h" #include "vid_ati28800.h" @@ -49,6 +52,8 @@ #include "vid_vga.h" #include "vid_wy700.h" +int cga_palette = 0; + typedef struct { char name[64]; @@ -255,6 +260,11 @@ void video_init() { pclog("Video_init %i %i\n",romset,gfxcard); +#ifndef __unix + cga_palette = 0; + cgapal_rebuild(); +#endif + switch (romset) { case ROM_IBMPCJR: diff --git a/src/video.h b/src/video.h index dc9f24eba..effcfb7e3 100644 --- a/src/video.h +++ b/src/video.h @@ -108,3 +108,5 @@ void ddraw_fs_take_screenshot(char *fn); #ifdef __cplusplus } #endif + +extern int cga_palette; diff --git a/src/win-cgapal.h b/src/win-cgapal.h new file mode 100644 index 000000000..d824c8929 --- /dev/null +++ b/src/win-cgapal.h @@ -0,0 +1,4 @@ +extern PALETTE cgapal; +extern PALETTE cgapal_mono[6]; + +void cgapal_rebuild(); diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index ad3b2d4a5..6e86d4949 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -12,6 +12,7 @@ #include "video.h" #include "win-d3d-fs.h" #include "win.h" +#include "win-cgapal.h" extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); @@ -42,7 +43,7 @@ struct CUSTOMVERTEX FLOAT tu, tv; }; -static PALETTE cgapal= +PALETTE cgapal = { {0,0,0},{0,42,0},{42,0,0},{42,21,0}, {0,0,0},{0,42,42},{42,0,42},{42,42,42}, @@ -65,6 +66,34 @@ static PALETTE cgapal= {0,0,0},{0,63,63},{63,0,0},{63,63,63}, }; +PALETTE cgapal_mono[6] = +{ + { // 0 - green, 4-color-optimized contrast + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},{0x03,0x39,0x0d},{0x03,0x3c,0x0e}, + {0x00,0x07,0x01},{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, + }, + { // 1 - green, 16-color-optimized contrast + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},{0x02,0x2e,0x0b},{0x02,0x31,0x0b}, + {0x01,0x22,0x08},{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, + }, + { // 2 - amber, 4-color-optimized contrast + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},{0x3f,0x26,0x01},{0x3f,0x2b,0x06}, + {0x0b,0x02,0x00},{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, + }, + { // 3 - amber, 16-color-optimized contrast + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},{0x38,0x1c,0x00},{0x3b,0x1e,0x00}, + {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, + }, + { // 4 - grey, 4-color-optimized contrast + {0x00,0x00,0x00},{0x0d,0x0d,0x0d},{0x15,0x15,0x15},{0x18,0x18,0x18},{0x24,0x24,0x24},{0x27,0x27,0x27},{0x33,0x33,0x33},{0x37,0x37,0x37}, + {0x08,0x08,0x08},{0x10,0x10,0x10},{0x1c,0x1c,0x1c},{0x20,0x20,0x20},{0x2c,0x2c,0x2c},{0x2f,0x2f,0x2f},{0x3b,0x3b,0x3b},{0x3f,0x3f,0x3f}, + }, + { // 5 - grey, 16-color-optimized contrast + {0x00,0x00,0x00},{0x0d,0x0d,0x0d},{0x12,0x12,0x12},{0x15,0x15,0x15},{0x1e,0x1e,0x1e},{0x20,0x20,0x20},{0x29,0x29,0x29},{0x2c,0x2c,0x2c}, + {0x1f,0x1f,0x1f},{0x23,0x23,0x23},{0x2b,0x2b,0x2b},{0x2d,0x2d,0x2d},{0x34,0x34,0x34},{0x36,0x36,0x36},{0x3d,0x3d,0x3d},{0x3f,0x3f,0x3f}, + }, +}; + static uint32_t pal_lookup[256]; static CUSTOMVERTEX d3d_verts[] = @@ -77,6 +106,17 @@ static CUSTOMVERTEX d3d_verts[] = {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; + +void cgapal_rebuild() +{ + for (c = 0; c < 256; c++) + pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + if (cga_palette > 1) + { + for (c = 0; c < 16; c++) + pal_lookup[c + 16] = makecol(cgapal_mono[cga_palette - 1][c].r, cgapal_mono[cga_palette - 1][c].g, cgapal_mono[cga_palette - 1][c].b); + } +} void d3d_fs_init(HWND h) { @@ -87,8 +127,7 @@ void d3d_fs_init(HWND h) d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + cgapal_rebuild(); d3d_hwnd = h; diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 30eedfdef..46a86ca56 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -9,6 +9,7 @@ #include "resources.h" #include "win-d3d.h" #include "video.h" +#include "win-cgapal.h" extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); @@ -35,29 +36,6 @@ struct CUSTOMVERTEX FLOAT tu, tv; }; -static PALETTE cgapal= -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, - - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,63}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41}, - - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; - static uint32_t pal_lookup[256]; static CUSTOMVERTEX d3d_verts[] = @@ -76,8 +54,7 @@ void d3d_init(HWND h) int c; HRESULT hr; - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + cgapal_rebuild(); d3d_hwnd = h; diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index a32f5d105..fdb31313a 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -8,6 +8,7 @@ #include "win-ddraw-fs.h" #include "win-ddraw-screenshot.h" #include "video.h" +#include "win-cgapal.h" extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); @@ -33,29 +34,6 @@ static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; static int ddraw_w, ddraw_h; -static PALETTE cgapal = -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, - - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,63}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41}, - - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; - static uint32_t pal_lookup[256]; void ddraw_fs_init(HWND h) @@ -65,8 +43,7 @@ void ddraw_fs_init(HWND h) ddraw_w = GetSystemMetrics(SM_CXSCREEN); ddraw_h = GetSystemMetrics(SM_CYSCREEN); - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + cgapal_rebuild(); if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) fatal("DirectDrawCreate failed\n"); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index be2291900..44cd43209 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -9,6 +9,7 @@ #include "win-ddraw.h" #include "win-ddraw-screenshot.h" #include "video.h" +#include "win-cgapal.h" extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); @@ -33,37 +34,13 @@ static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; -static PALETTE cgapal= -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, - - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,63}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41}, - - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; - static uint32_t pal_lookup[256]; void ddraw_init(HWND h) { int c; - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + cgapal_rebuild(); if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) fatal("DirectDrawCreate failed\n"); From 359ac7ebe9cbb8e97cbcc0307bd3cbada816d6e0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 16:39:49 +0100 Subject: [PATCH 095/392] Fixed a compile-breaking error in vid_mda.c. --- src/vid_mda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_mda.c b/src/vid_mda.c index 3c3015d07..b886c088e 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -325,7 +325,7 @@ void mda_speed_changed(void *p) } #ifndef __unix -static mda_config_t hercules_config[] = +static device_config_t mda_config[] = { { .name = "rgb_type", From abd167e73c564e2496a3d90c96eb7aedeeeb5868 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 16:43:43 +0100 Subject: [PATCH 096/392] Fixed compile-breaking error in win-d3d-fs.cc. --- src/win-d3d-fs.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 6e86d4949..ca270ba5c 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -109,6 +109,7 @@ static CUSTOMVERTEX d3d_verts[] = void cgapal_rebuild() { + int c; for (c = 0; c < 256; c++) pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); if (cga_palette > 1) @@ -120,7 +121,6 @@ void cgapal_rebuild() void d3d_fs_init(HWND h) { - int c; HRESULT hr; char emulator_title[200]; From f3c4d044d61fce499f9a96128547ab82cb80ba04 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 17:01:17 +0100 Subject: [PATCH 097/392] Fixed link-breaking errors. --- src/vid_cga.c | 2 +- src/vid_hercules.c | 2 +- src/vid_mda.c | 2 +- src/win-cgapal.h | 6 ++++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/vid_cga.c b/src/vid_cga.c index 608599e29..ab909b3f3 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -467,7 +467,7 @@ void *cga_standalone_init() #ifndef __unix cga_palette = device_get_config_int("rgb_type"); - rebuild_cgapal(); + cgapal_rebuild(); #endif return cga; diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 8ea99e868..41dacde01 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -347,7 +347,7 @@ void *hercules_init() #ifndef __unix cga_palette = device_get_config_int("rgb_type"); - rebuild_cgapal(); + cgapal_rebuild(); #endif return hercules; diff --git a/src/vid_mda.c b/src/vid_mda.c index b886c088e..9933cebab 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -303,7 +303,7 @@ void *mda_init() #ifndef __unix cga_palette = device_get_config_int("rgb_type"); - rebuild_cgapal(); + cgapal_rebuild(); #endif return mda; diff --git a/src/win-cgapal.h b/src/win-cgapal.h index d824c8929..bb6dd7f93 100644 --- a/src/win-cgapal.h +++ b/src/win-cgapal.h @@ -1,4 +1,10 @@ extern PALETTE cgapal; extern PALETTE cgapal_mono[6]; +#ifdef __cplusplus +extern "C" { +#endif void cgapal_rebuild(); +#ifdef __cplusplus +} +#endif From 7aa2b9c50edc22ecc083010fe9b740b440293a8c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 17:21:05 +0100 Subject: [PATCH 098/392] Fixed the device configuration structures for the Hercules and the MDA. --- src/vid_hercules.c | 3 +++ src/vid_mda.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 41dacde01..d3cd051e3 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -398,6 +398,9 @@ static device_config_t hercules_config[] = } }, .default_int = 0 + }, + { + .type = -1 } }; #endif diff --git a/src/vid_mda.c b/src/vid_mda.c index 9933cebab..be38890bd 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -354,6 +354,9 @@ static device_config_t mda_config[] = } }, .default_int = 0 + }, + { + .type = -1 } }; #endif From 7dccffbb0d2b1df1957c270e5a565d8fe4ee36b1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 19 Feb 2017 17:32:35 +0100 Subject: [PATCH 099/392] Fixed CGA, Hercules, and MDA. --- src/win-cgapal.h | 2 ++ src/win-d3d-fs.cc | 6 +++--- src/win-d3d.cc | 2 -- src/win-ddraw-fs.cc | 2 -- src/win-ddraw.cc | 2 -- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/win-cgapal.h b/src/win-cgapal.h index bb6dd7f93..40056a2b1 100644 --- a/src/win-cgapal.h +++ b/src/win-cgapal.h @@ -1,6 +1,8 @@ extern PALETTE cgapal; extern PALETTE cgapal_mono[6]; +extern uint32_t pal_lookup[256]; + #ifdef __cplusplus extern "C" { #endif diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index ca270ba5c..d6fad07c5 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -94,7 +94,7 @@ PALETTE cgapal_mono[6] = }, }; -static uint32_t pal_lookup[256]; +uint32_t pal_lookup[256]; static CUSTOMVERTEX d3d_verts[] = { @@ -111,11 +111,11 @@ void cgapal_rebuild() { int c; for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); if (cga_palette > 1) { for (c = 0; c < 16; c++) - pal_lookup[c + 16] = makecol(cgapal_mono[cga_palette - 1][c].r, cgapal_mono[cga_palette - 1][c].g, cgapal_mono[cga_palette - 1][c].b); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); } } diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 46a86ca56..12c40351f 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -36,8 +36,6 @@ struct CUSTOMVERTEX FLOAT tu, tv; }; -static uint32_t pal_lookup[256]; - static CUSTOMVERTEX d3d_verts[] = { { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index fdb31313a..ed18c9b64 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -34,8 +34,6 @@ static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; static int ddraw_w, ddraw_h; -static uint32_t pal_lookup[256]; - void ddraw_fs_init(HWND h) { int c; diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 44cd43209..8aadfac56 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -34,8 +34,6 @@ static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; -static uint32_t pal_lookup[256]; - void ddraw_init(HWND h) { int c; From df4b4410e6d2b952c9a45cb4e6973f0e9434c276 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 Feb 2017 00:16:42 +0100 Subject: [PATCH 100/392] Fixed CGA, Hercules, and MDA for the second time, per suggestion and code from basic2004; Added IBM PS/2 Model 30 emulation per mainline PCem patch from dns2kv2; Commented out the Chips & Technologies VGA 451 as it needs further work; Added the ability to disable XTIDE; Prepared the icon that will be used for stable builds. --- src/86Box-RB.ico | Bin 0 -> 394182 bytes src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/cpu.c | 11 ++++ src/cpu.h | 1 + src/ibm.h | 3 + src/mem.c | 110 +++++++++++++++++++++++++++------- src/model.c | 19 ++++++ src/nvr.c | 4 ++ src/pc.c | 4 ++ src/pc.rc | 12 +++- src/ps2.c | 136 +++++++++++++++++++++++++++++++++++++++++++ src/ps2.h | 1 + src/resources.h | 1 + src/vid_cga.c | 29 ++++----- src/vid_cga.h | 3 + src/vid_hercules.c | 18 +++--- src/vid_mda.c | 18 +++--- src/vid_vga.c | 8 +-- src/vid_vga.h | 2 +- src/video.c | 2 +- src/win-config.c | 12 +++- src/win-d3d-fs.cc | 14 +++-- 23 files changed, 346 insertions(+), 66 deletions(-) create mode 100644 src/86Box-RB.ico create mode 100644 src/ps2.c create mode 100644 src/ps2.h diff --git a/src/86Box-RB.ico b/src/86Box-RB.ico new file mode 100644 index 0000000000000000000000000000000000000000..2106da7e4c16176d9f20dd9e9ae682b60a9f9536 GIT binary patch literal 394182 zcmeF42e@5TnXvac_omR25CSMIz(`XR3p#dC0d)i`juk93&Tkz@v5XaLSg<3gfC^Yq zq*y2x1PeL>Di%?2T zjcRr^Z(hZ5=jw&SRdsY#Rd>0|%FplGq^fS=+Ri(#{QL#(d(E7xy7#?%pLeUOofcNr z{`;@|yyqjU>f!^c>M@V${r*sX&jXJ-s`vfuM)jJjc>#aEZ_k~Ft55#1QSHfR9?g}N z*Ev-C^WOfyCp_T^)qniQe^dt_d~kL6;fFW=`@jFY@%hhxzWLR!ezo!SuYbL9&N=5q z^So@QopxH|xZ{qijyU3o>bcK-ZuQDnzOupZXTI!ZFMGo0KKHq!`ToB?^O?^)jke#( zC!c(ePk!=~+kO1wAD{cNk9}+w&ma2ASH99X<&;yZ!wx&Fdhv^29KU_`v!8u9?_b2b zM|jr=_bj6=Is5FhuRrUov#vbz%rn1##u;aPnZILs?!SEWqaSV9_ZPh21v5E5_doyh zKd*nsJKiyJ?z!i-zWL2>wl28ffpuU}pZLTlhF|fDS2SM!@|Qp5&2N75^>2Oa zTSwme-uJfoZTpf-E@}Vb7r%)1%U}MoU9=IdkNoIIKl%*)8GhQ+o;JiYKK{lxzH#I& zZ+T1W#1l_!fB*a6Z(noGHSHU2xFOo2MT^>h{_~&PfBfSg+kg1OAKKSlciqUPmtJ}t zeHiNf{v_T%a_q6kw%+~jcem+Z`?tUSZTqI1ZfgJSZ+~mwdh4xq`|Dr-+W!6Te}6ge zxCi$L|Ilk*^O_HQ*Z%gmzul(K?aMB^tbO&> zSD*er|MNeyuDJ3FVXt2Gs#op!`q#hyuvfqO)#9)Ht#5s+edLixwt;I@gT`%OY+rH3 z6{qvOnLMw-Z!4ZL1n%Dk4pw~N10QIA=R4nN^SS-ZXFhXOd&V=K(SFg3Uevz)^2<-B zk2ATiA>Tm1p_jh&r5}6kYhPQ#|GL+`uKmInzOeoO{@?!_)##%%`O-JO@r@bZ``-5& zJg<8C)1Th_w}1P$%3j{ciB?=Wzdz zPB`I&#XNt-U;gr!*3CEH+=2&M(5v<9U;nxV?nf@Z_~H@h_Bq}?gJT6e6?CuO@P;=G z!Oshz*MUF(`OlvRpB!=HjW-_6b3VrLi_rZWx7>2ek390c$MU=e*DLTA@&_LTF5mQ~ zH#NiyJl5d(P2M;3-S2*PChy*iHlNRPe)`j&Hh=iTA66G#bWwF(quafZc2u>pRUFG! zUXOF{?fvG$p>9__gKDc#U!i~0FV98CP4uVEc>LoZFYOx2@%iVU-}u_szScmd8tRr$ zfBMr6$S-72=}z)OZwX8cO%I3GIZi%^x>k@Pe1)i+7G_) zg)f`|{~Y((&wlpxyyJQ3+Xozd^wC47o_cBp4~vTmd1~;E8Bc!llb^(UehV%~(9NMQ zk;#x9^=GfOJz@ju>z>n;k!9fNGT_>d^9ub@J@0wXv(13EPeE3G2XBu+vo<*Cs8ej{ zw$6nYUfAxn`W#;Lyj8RjWc*t2xQl$Mo^L-w?t$yqL>}Nk~ z_gV*C6XzV`y!hNg27e0-yKryx|EW)X>Xyj!_t1SKJYOByf&Oi9+d*DB=$#IFz5Bc0 z{jP&-*}B(Wdu^xJ;#|GoYb~C8?U`qtxeNL>p8u4mJY_rV>l5^hXC9&_T{SUcdhO>pN*j)G7StN1yxLXSd;f<@2xf`RZwSucJQx;0He# zIN>+ilup_dj-A4`#C5;3p+9~NP7j2(P2Qt^QcrFNO|RhDBgkd@Q=j@&hj+DkhtHP= z9du(Ccsqak)1T~j7oF8vym)bE$&w{qTD%Y4)ka5t7#lWx_0?B3z-RT&cfPZN-?xTO zFNWW5=h@5A3mx9u#?R!NzpN+q>TNu8wfQ;~jXtgB)~_kq)}gXSc!CG2i?C z_nN%FL7ysUSwY_>di>tV>*L^~kIA3X0Xgl!H`1exF7I%?-D{)Hu?=k-ve!Z{AA{U9 zfvKVJ`h5H!`Lu~%*aN+Mv2@U$%Ae@mj?YH^y2xFp*G8TH`@jFY*W2ixHn@8aHmG^q zZMW6Wr_b73ZQcvO(+X`II;D-=$Mcc74zk?=j{_U+--jQE&UvYJ z4&0ah57_yxgB-SdEzXg7Kj-xpIwo9;8Slm(9bW$UXCCOZSda#|6S!4zUqMA zF7NL2T9%`e;H`siF{*hjuX7B4 z33)q4Taok?Khjqid_Hts0Uh)U+V6k=`#bu4&{uz{<2C5tmLA*_J`cwZpFM9u-xhK# zeH+MM(AVdK!=M50c_DaOjxN$4X@N)m&z4P}6nSi;6WiFV4!XXrEaEpR8*OY|;2&S} zJ^ZeLF7eUvN1wxva@-4Ce*`*R42-uSTj8f5D=pw{!*i`(i*v5E)Dt|bgMofxBqZh*+S3Kh{7mHkK}3+W7n5 z|30w!olTy(^2#eKbYP`!_OFGn)T(B6Z>@&9*Hw+~g}rtZ$FZ9C_?^dW*KvMbJYy)H zbt}(oRdd4++nM+5Pcshm?&|;uD{!4H}~DfZo0z_Gd5Nu^oDH3;d|r9EXtIroJJ*SM59M$Jww! z;Wy&5gzqZ;uv1|>^aZ`ga_(c_VuH-)WDf zj}M?vJ3^ZwV;t_O-*4O{?D*3S{G#E1`Imor6#VxK^rkVa?`>nx^*`Id5x(z4NA#in zG;gq+e%^+ixDnfU3HaHUK33wvKVvpy18l9fLbwm2AHM?cBYfA^W&?ZV0qjHBygo(? ze2KH7iN`yzx6cy)`r*b8*q`*3hoAMVXB`ACuFwzH_TWcoPvV{W%f{{I1Jw7#aZ_#P zKbC=mXVZ`BOJDj@#EQmG;Ccu>dJugHe@=fG#&TCS!!3{`4n{fahWKqx#~PzL@WC_1kAj)>d| zavgrOaQRH%m9fE~V-ZJ0uBsP9{1N_p0Xk_D@LvH}@V)TkBR>H>AMZEDLZ63UDjvW~ z8+i#ji(BFH`T8bfHT;IQt>>rsn-Tcuoyg2AS_2-g&U;Kp~`H~gmd&o2L&IjR-JAumBE4RPM! zHx+syVsLOR|L+Ig7ojunpe>i~zRUN^i|D%W^W+Wng4b<+Rz{3f=zANR6#kz+y)@%} zA+zws2=spm^3sHU4d@WMPo2**jO8{V-*6Cq<1>+g7omf$h9BCT2QLV#{O5aouYJ(J z&E~!REx&`FE$Fs__rDmqZ-S%R$JNK+dGf!x<0k&_4D7(8vDv@#9qIsM8g-9&7T)xy z(a-H{`qJ6*nm)G;`nBNO75H~AMsGItBLjH;VQVUQEc8Emu!+sxmET{+yUiU2PO+

LFpr zjz{iR-RJwEOWVAuaT|TF8~K}df6MQQBUC1vc=-_%BW5V3qfS_jo@% z>-!f2|A@TqbJhRaK=fwlLC^7N+xWeq@1%)1u`m2KcvAUPPHbFj;V-N}241WWY@FBs zC;#aOasPvO&JEyp1brI$eth;8{g#JY+Ir&A+V*J&wY6U7`{<+ok-nNXOFc|K1OMRQ z#l)Zu^kDz%Bi4XVwMUyl^Jnp!58+pTAOHDw-_7$|ysL#>iCFyh+i!36w<1o@cs-8T zp%H$22lnUr;vO5Y%KL%40^gwrp>Y$vGXuSQ7i`nvz;P`7{yg#hx$x2V(ceGkdB4M^ zUr)P*W~{!9_pG1~BmMp2`W@i>B4YBr(7l!U!$E)AA@v~eH}E^OQ4MoO=-*-JJqurc zGjfXa@FBOuf7uP2yAQtLL&+5#f^K*YaJ?KJKN1*^C7<#+-uX3T{;OPj9lWy(?`@iU z<@2D|$2Igz@B#Rb+z7O9K+70EQEvlh#Pk{418c*aBEDb)xoSe&CO)Ehhgrb8DgN@N z;B8o&qt9V}VJ!IjJB9p&Ou*k2{!oQIuNaH0phd+qE8bJ_o(6Wg0Y1!|+K1>5IB(cD zo9_nxivCpnwD0ixTon1!fRFnc`t|rPk)t% z#U@7Vzx(dHN1kgsfIR4+gQ|x={NdHZ9`>;6kV6g`0*2kNYj44S`U3IHC+XX}(IYP> zhxruxw;%nx7qIQbaUObh6Y?T6(RahZ*%TgZe!ykUNH`sb#h#fzGS}8HmnDqm0Qnq8 zba&*$rwY#j2OJQ67w`5R8r&0K;9P9K`2xo~+vE#c=5pxUQgq>8!T0Zh>vGz+=-21r zvk%et*8)lGk`Pbhg}O8%_j<@G&P4Tos0>DZ!&-K z%!3~Epx_(ibr>4l6MyD>{K@6!t{gKpelm9@4El1s(*dP6$j{TMX}{|~7fxY>e#^l1 zZP4&WV7vx8{umg~MK_!ZZ@m?sx-Y&!b0Yk!8_he*JLC(+`#$vjJn~q}(H$-HW`}3l zZ*zAs9_TqR2uHwDoX0ie?7Y@@9yv(9i~OU<^4xpDN#q)lvvc5|t;w^EiGTe~eO_w_ z$o1Oy`x3u>8((!feA6;^L6%}%6W({cyi>psw2&VC4O-RL#yK}<8TUzB&pp!Q)e-3O z8*sndSo}kr7x{EyFkgD$fd}3fU3md&3By zzuUEOt^VBv=Yb#YkqRYA6mpZF>Yo| zA@86!I?68nv0pZGfibpiOpJf$SYO$UlR7qYrIS7HJtJ~8^!sXZ<-7B)RpKP#oX8nL zgCX(@_k~X`z-L{Kyhq+rc}0J9&MzP4!XUW@({vpW9Um4D<<{QfRD>f*z8@c+BS z;$3{-4t{W#xTb6!eBrK*>z(4eNuBdNb3Iq1k9G$atMs2fYoBJrGatZr3A~GQcqQ^= zoOhu`#O&yRF8bR3o2T!BbH}yKqeOqrCF75GiDT+Ud}2MGH50Z`=ftmFo7a2CQTOmH zp7-na_kZwx`hV)~mtX#~Rr;^rfsNgoSns>^zlDsNQ|Vx*qIs^|+VIgj=;_cq^0B-j zPI-Ta7^*{j6?GjRiL*MyK5^aeh()H<$PIMNkzaG|HLdS{@4Hu@^669P|K+R5FY>8> zvmG(&CH9|YjpCq7dX2;IJ>}U3z&u1{?kUjbK!S>`SBAzzKbze{~!2o6#b7J4*8_e zIq-}5&8|5=_|Ke27eAn@ZYFk=--F)vfxg*)^Z#|I-_Xh>g!{9UVdL*&vU;QZt!v&wEi5v(q8(i90&FvTf05|zqIIo zS00jQ@Ugn!-a4tMF~KHu@%OD2>nf|#8+>)eAMdo5scR$N&X%=JQQwr;xu?FjJQoI< z<3}sd5hsH4?Y{Q)uMM4i%E^^uME!r@x`F&|hn>BIJ_rAB?3yD5&uw7t(jrGmtk}hW z?&6PFFA}-~99e@LeBgVte;&!**k{Kq>ht3J^4>TXZg3xCEb#ix@aqBaY19`YdojMz z-+%h5uelw1^b&YI>fVU`#Cwdl$T##q>TmRa z+Ewx1;gRRM@S!rJ?)6x<@>=LK?I6$5KFX(E;uFXBy3keq9AlQy z?a#otFZ{HM%_?Cr?_qrce&;=iPyP#^;SIDm(x>;}_g`lo*nF|L6|cS%e5iM{y>Dljr=->l2=9`_cWvuxK*J{ zXQuBRVxTUuTbG!v!|%I&t-Lny9DLQ+@q_gTqyOmPDfOQ|+y8ms;6nRO3tzO?|EN>O ze>P4HABFyld&gC?uGKNmPG5^_JlE^x_w_krZS^^FsE-}|GgbVNb= z>Ccd1?2WbH&XEfJ16*Mnpq)A}?w2M-3;opl9N+s)J`X(C9-=>keu=W=a$&w@4^eA zx8)09h%a5jLiW@N$V0?0$g6&q{&UwH1iB~m5BGGn!OC(r;PSk@R-a4Lystc0AE^I{ z=N6%#!~abFp6Dq5^y8mv!XOR8Pex9SUn0)~{-b~Rd0lK?mt(-9EiPKe?|N<2xxefE zw!SV7%$pE9ETX>a{`e8&`adO1;Jd<)n1{};`KQKWok>jFCR5IWBMPsGFI zRIC$-xhlpq=IY41h7FN^^wnC14)pDiuWW0t$r)>Vt^bL0Y>0Jv*5Usd|8`&e&`I|n zUN`qVmv?*01=$H<9f{ENTXwc)o%1Aop(*vsOOHU-{zM$G6kBBuz6H;;tX;J4=mqOD zV$Kx(*47wv8z&maMjTikjca=?Vs_y(rp)W+8+?X24Ek*j#`zn6Cil57*T(DesPEvF z7|TT_x4>pSkX+}p>HE>dz~86uOTm}*s?MF!zC@f&4BH~6ZQGc4(4u+FW~}RZ$JV`D0JpM59(2pe!ekStppTP4L;<69pTbzs!b0&WL zcc=lnjB8iH4u3)pZbBZH0PEl3q2<79Jx4@-(j-@4jmiw(Jrmn78<;kOR`ZF+ci^}? zV+HqtZV%zUN26b!!F?}7PLJgHK|X&1_)np|75RQ3Z4=*Pz7RcB_iJ@e&__{=gl&m& zWouus!4+fBl{G>1HR@f!bJV*a(=itZd`7(sd=c}gz`Jvzt#@hy^AP76O4aP+(@E>!aSGV7TeusY@H30BYg-(k3M2-tOHYKgWTLq3QbYxs3uN6n~ zK2fhj9|KnVh>SMiwT83=&kcC30S%*`2;PtW59-6Zx`qv|$nyjb?z-!)6}G)%94qD- zK(~tVn}AbXqidvP1-}i<6ZZF+Dy7kXt+^{dFRNz7i3LWUT*ogLa=ehEw;aXMFF1JY z^p4az#b;`fDyB~{cWUMFxg z_!FCwo1O(9%p_MmOde;*+BNI+7>9EXbkrg`Uzy)UO&hu4;0^ANdQyE7a(vFOb?#%- zpy#=BZ)ePyu})BQZx*|H-~%66?Yr;3%KQ-L3(1SUhd%w5n0PVuaDO8fx}I3>YUuuB z{HU+t6Mh2t-wkX>0Q{G`4i1`fV*+(tgKeq}mkOP;s>?*8|`zvFU4obL?pe;mDc8~u-Y zxA@g9;^(L%WL(nvLF)#iRuEb*LpGKWpWFz|T_5GAz<2?0od$kB1dU$>P7XtdJPw#1 zj2zq@Tsen%4!p4`G1_eKHbWkw&OYisjemG%$QaLR$V1%MkXOKG;DsDeMUG;P_#=5f zVW);NV2AFvn~Q)RF}D`@WB!eG5Z2rYKe1TgKs*d;))^uTBk<00cxNfRa|J% z{Oz;PKGps1cfXqM2|ME{x04HQf!nAja_oa~X=~83Ua#YL6gbFw%esCPJe22wBk|PV z5?|nG#ClVB=nm+8D|rX!A6^BVmjLg1$jvF#V;&9tUxxm97JBtD@Xq~!eH-#EL*jsY zrwqP4U&5X|PuzDqIjI)3H^&qlFyt-Iz!5298#M zqo`NK?%V_qU5lK27Ts`nT2q}dl|OBpwZiH<>IjB8?uxvhAnfE5TaE)DTQL@c%tp8nIeg{>&71O$;Ctau9LNvI#JXzr+2=@3GuphjjZbk3wr>vh zV@&u9o^LXCb2rAMPDN)fg}$+l7XF6wt4Gyq``Ix~>rb+FTiz3HX)PUun;dA=b!)I<%He3b?GSF!b}d@dhe(YB#*tyk$iR32d>U>(DS&~=Dqk{UqJ<&G6y|0Cj8PL zxo;x#k4D~az+VWS2gayPkj_bKWdM1w4mg_d!(Rcvw3qJky7i9I+wnx<7B0uxvXLi_ z`t1HAV-t?SuXgi!zq#r+F;?oB)LCbrb+YiEciy>U!cSd5^^k`=WG1-@RNbqV5kEz} zIWiFSCDPg^tX=~@VfVy=ypP`%{*QAO z&vB0T&wugr)|b!x^2sNkdh(pFeC;b^!f)=1SaB1^XWovUUjh7CuN&}6Z(Bd?*p;Ze z*SAyOJ2yn#Bfkr~{jlc#`jxex_4<&GNiyCPYeX`}R<02lHP_bQi7UoUM&YQ$!FcDq zH)`#E^{ZdDPCw)HPk!Q)pP2L2uYYw+^$+}w9{lep;IC;c+_vO-ae;5$!O!lXU&6Q5 z#tXkPFZ_(B`zlTeXO$t&R3v|eg%!5kMFZNJWw%LVl40- z+n4_1!k@5PcP-r5)Ubor7ul>|Q}6fFUcQw^!qBT_h`RS)okD%?cm2(K23;HDw^4Th z>?8Ob7h&%oNls-`@&mC}F+Td3@Kcvj!%tpu75dBb+IaY=BkhG>c&)FpVKbtBSlQRs zNqcn{ z_HRts{Q_UNL5#Zze(%xvJ|pmZ&Hw7Xggt4`^FlXRH`J>yi+L#Mn_BOy!{vSTSMq)d zhp??qE1!|)!VfND&3fSeF8TKzi8~wUrwW>l3%g(9?>5NoY(nkQJCOYq$aB;-$@9v! z{*ADw+{^pm$vX9@o8mWdpR%vsQwGqtF=xXZfH96X0h=5=p*+YB_Fvjl2QY5)p8l4& zyXoeeI`4b``#Pt6@wAwqfd7FjdhWLPUX97byuuIt&Fu#K=(`p0d*n3H9c^HCu8zl; zE9D%8gx}nUcu+qY0}G?PuOCFb9JO)Q;3*&CNFT~vk+##hR>Wp8KStZB-=x2&|E7IY zXR0&C!;v^q27KSeKfKr)DQmROLl13h?SZgO=8u?9_-9jN_7>n-j;|YQivw${c?%v} zv{>I5o{Dvy(GxZ7>IZU=L3e4a4=l_!apb+iuPy0s;?9=#g}5VPO7h+jSBh)xtUi|h zwf+_LAvG^4U-G{-M&QHwLFXce+gMLB8Q8tYxR<%gy@!;c(J z34ZfF<~=yhBMv-_oc2d}{t4jWL|{7!o;Z!X-(Sr8*rcoQ+vn_yIzpdUo39;Iclf<< zO7p};9+jK^mfua~=(CMSk-LDO_n!y++gfWhS^8W1LykArD4?c)2KsO_bo&`X`^r1LgvZ2aSoz`wjv7KXL6uV80#QM_lOp zq_4RU=b|#^7P>s`oAArS!fbu8HPY6rTlYQP%{pd%5bQ?KU-*f=R}22cgZ2PlsKFS( z0&)WG&$1NQTkx`eK|6JxwoKTyXXIBy_v!Npzcd$S^hT_ikL+~FE!7P@)0wWOtwr{t zJ{A63WBApF@PPB>4g`ipz#VJ+3OjUnZNZRx>!XF;xlfGEh3?be7k>Dq!!w*$)^V;- zuQt2`UZ=I;vsojr?ycb`_q8oP=al(B>EBy(!#$2(1aI8|FUOp()b}a((q8{i+fS?! z@H@9x{fAH0L55=fS8x7Why2>KH1t%*md}%qrW1Z_fa_rm(f?PXzm@}k$i47q4&0om zK8o<0|1RN|{_?%F@5cf1;J8e|C8_ocLN(ZjQu+T*;)afW6ooV196^yfO0^sPUL*k{}nf-@1MBvchl8; zrcHaC@az9i)&EVn^9bzDw>2I-f^pFm$Z+flBfljMq-Xkp%7O8`<522A;~(iS{AKh0 zwb9lz{zT3(OhauNPl>` zVNcwa@Pq&J7<1fqD)E29oyS4&Yh%QL`dl28c^&0IAJ8!`b)b20zfWFKPUV-xM;@m` z4#chYIQ@U{e;)adZOI3$w*Lq1gZ{)nHT@I*!~rou`1ryiUG)Jnf8{v1_Ri-0>iNWl ze4{<^xTZ}VXp^_J|K`82!RIjsvn_t;bin`0-T8`p+Ped5>fRXp!w)_e__vu#{yX)49?gX!w@u)GJoNYrI(7sd7yHWM=eHPB zX%qLwn)dX`{Xc@9(pNf5cjKUb*v-}Vw-OhgCyx4$;>d9%^W8o>@ubYzz+cR7PWbV| zSDXIuUF^3)95f%AzY5qd#>e{|<7$5+x4j&iL|)u{IJAj9H-I_T+jk6(z6LKkc9G*W zj#Z2|&g1vl@;Cmzd`ACuzw6=C_qBMh`}Ll~c+)oYC&@YGqx462D+8|mv>EzqN8+6O zFc$D6@;pZ}ruqYDzLYT`*9&f;b93%@3%bSH|G?t>@0bH#%=^yy-{T!)PI%4@AM2R7 zzlP$8(MQe8&i~_g88UpHHpV41ACh zoYgv44@7M&}w+njvA?UuxGd}tpzJEFOFmHw@-iMAq5xG1K zyL3MK@JI0DuaMj8z{?HD@GZ34kl8zsm*w!xh?%oLO+b~Yn z01vALbN`R#&!6u)s#3(m*G;kE8Q+++S~)9M}x%EN9~X%%TsQpugvU zhi$Nn3*nEu!;||mcK2|OkA+X4%6Bi|p4Y)Y@1^gb0AF85kAD*x{vouy9GqPP&K99Z z{|dgAB)*XI72-_Xq35rM=T61`JrcQ}!`QF;=S}K)wk9@-mdkHPM4&3D7VA9MRTRy;4eyw;A)4Tv?G@d08DcKHLH zSYan(Z)|xG8duOi*2q*RLEo51PmJ8)yM}$H|L%Jcc!K8cP1-PjfgWk%PsEx4=$2t* zX&5}r053D~4{S5|JS2{RKi=iLsYhIEFi+*d$Vlu5f)5;fD54u;Ul4e{LPrO#$eUHz z(8~1$;N1%P$9e+d3^)T8O=?|&^%B@Su~YSe0jr$c*1K|HZ&`t(Ty}v!I@{n73o~#M z3l~)Ttz001l@wyZ1XgmmE`XZ5a-ju2AJzLDhiX>*ysBoc{CVtS<2UX(Gv0CTbt}K` zKQ8QD&*Of*&qwC5_uM1SM3JN5(o7Y!5!xu?NSI(|sK4eZ79ITqnbo zA1(|4dJ9yz5`>>6kdP+DdTVdox*yj^|G7@YV`v}rSJlq^ud3%B8i$SlHez5S1~yO( zEL^xS)-5I{6m#Oq%T?6p#Qs0zY-2wv=e0VQ|NqjT>y+I6?ss>dOU1m#sB4%d9PTP0iQM2tswquF#hQtT7f^#>-A5>6M2H*Lvc&KAlCLE zujIVq4T1;v-h1zu`|o^kYQ&q&jh@fE;K!05WZ31%_kx!_zst!7j1b$d zAnv&XU*3JPuBT4$*W|o^2v3~@Y^Q*uW8j@5fcNR-SRMiH?!&d+!R3zd&jMnn&G~L7 zxEiwYyC%7}rbqHo4RW!ukDKyqy`ntEG4!1|8~Kj>Rjjwectxy>!Pr5>?&Q(e+WIoe zlssdjcGUGkwr9PVcauN(8~tz%{}#EL$RGCRYUi36^?DKD&Amz8=jjgQ?Ka}OzYt&l zmYmzqz{Lgd-WQO+55QMPfV1ZS>*L|chk>)b!NU&7;+EXADfi6gd=_|~0bPd3r8lXm zZYaazkb8m$;o;aT4qnW)34_lV_Xz#B+Kkfo!;~r46G0yj!8_ZtrpkMu%ikDRi~Yc? zCjme1XXctBF~8EW0Qf0dv4%#jD^jkh5$EEMTtExnTY=o&4*qTd?|+2Y3`fwu>Mt38q59nfW4fS)E~MUe}cGD3<{j1Bb=u*hfzuM2=nG<~DHX+9cP3!^_eA--N%8 zMnCPr7-~~KTHQZ!qfaN_sEcVkpl{xzzH$7r9Iu2|W8V_^C-y&b}2&qYvYEZOL)9&?8>-ZEV=6 zA&xsCQ}35=7~gDRM`JwSF-^zwv8`S7Meb{-oVhpNC>$wky%xHu_?*}KkKWgRt^af0 zlg}J*Sw855+ui$F_@>YqONs2A#+LhQ;sJ_#W^SYoH)+SD=sf*4LT}10g>ZwJ@#& zBaVjg{T4D$=p*RjB|W~0y0~&I99fQfG;Gc&{FFF?m+Ez4v~j%_x?FueMvL{O#`rFO zGwFMJebBx-mU{(uY;Wx0r19fko{kIYLs=`vT!EdLM{+E2(h}1y(4qInA}G)_MTMUY<%CfmWX_>txL|gn@7+4n)Ab^?H=Dl>+pW}in;g}kxi+!sYPZ{gzJj}7a%j=WA$M;$1M<4VLuEZC(CpLFd z_@S;M_^__OQR4*}?%E3cw84q{e99+5d&UQ1|4CtG zoUF?@N}KT!TQ?iyOKj}^edylk%n9-1n6q*P?^u7n zGxbd$!7o@sTKQp7<_sg#HQp1ztif`tf2P8B21nn3%KA_)_e< z=#g={RT|f=>x%1ZdQb5#>!H-qSK<%d6CY_p{5UrY+*qHyEqeI<$k7sHCvXEEq9z|6 zDc7qByeMDrQ^=Y;1+NBv&>7Yl#oh;urO7XW7sg!!R>mBou9fk}*sIhdW0I>hu3P&Q z*Vpu(;$2bKhR(kd-E&XknF;Y@?F#y42JIQ>;2Y5|Bj}el@F&j%ufQ+$KB(e_7$^3? z^C&;ztBRjkLrPg!mgE`6T!T*-uPygRjr~!ne~P^qsX?muNiELnJyN|!om#ZM^D*x! zpOf#QPN03ol~))?UjcshW(;*g{Ge-Gw{;FViWA_SsOthpp>x24b9qA-i!VQ;ivlm$ z_1H_#&)CU`6V%V}j`Mv3H}Z^lk$&_oaNwK(>)~jzucJrm6$UkHhwJN%X?F*-j@PL1 zjqg0>d2w$%NBmxO^;I44(>~|iuV2AFm3y-W#)S6WJSRTjU5Uld!w-&mU-~qOBX}wB zB2R$}_YJJ;x~0VxMGWDs+tVwxMIp6J(q}=E_hH(WV|E_6>9HjPpmV zne=<-5?kkH15WqfiQkTMbpChVUmw9u{LUjSo|EUl{>`sjUk5**I^|Q7!Vmh`wK8@D zKNpnvDRBf|Iz8OPItqR#Zm^LtPtZ70{|nvI#!hKdqISH$e$ZOKtf#a7FKYrlxA9%9 zBjkO~{|1kN)5KvP{sM>n`03%c##P|?x|MhqSI~=fH^2G|_Q~Dr^wYmIA^)JCOZ>#V zIqX-+4!MBPGwK-eA@9&aCsRKkF&D9N$d>V_{ulVMzA@xVxu;LDXAOK4d;f}q9zN>5 zZNSs0bH4Yp_^Ypbjo-S*ZtM{Y{$d|tp9>#$;lbQPIQI|kf*V`#l1K4_eHg)iKIcQn zerP*$LKFFi$v+$~057r5Na9BwBaXyL4>#8KyVq!!cZ5#HMs|5moXbP#Wou=-^dt0* z__6QsLXDq(*h@TkJ_tXPxu?V-Jm@~f*6@Zb!+Y}12)g;N=!6%Mvz-kb6QQT-@y|{L ze#BAmkNC0m@Du(a&+U>EjeLf9LB_hsUc?#L__qF^{)ReP-3!0FM|AAVOg&ld!(8vh zOdV&@3z z#6O82Z5Oz4-Igx7)M(`Cy4bwfhm;sZo{D<(l6TO%U1dOdP&Vu<{kM&ReZc1_-$Tt~ z?%(9I^F8uU3z@$h8}e-Y*sZ`%({YgFKYIMM;75N)+*o@r?}#7pAN#CQ(^=!k9EW~y zKkq18J>H3a_iB`5FJ@{u$2wXIJ?cAtmwQns9;|ncYvQInPyFy+>#c9V*LfEB+1z|I z@>Ky(j1^6UAndzq9qojiU4X7}AJtLvrM?jt@M7%qEN*y5$P{^w*b9tUE%q{mHtv_! z*4I(*$UExJf_H=~=A{TrKm2{4>;0_zuE+0sxbRsuUh;hLlHj9Q0}1(dJ@Iq#Uw0rb zb)2Juf7~-_BGkn9;)gugj?BRjKWV>1@1!nJ;?WDes>u8@u-{z5P zbML81;U#Z!t+2!odRYH2d_etWeLvTU0w2zYZKGdepKZ=#4xsr%b07FkVf!6hAZBvU z>ab&Z-S`b#5$jEPk8y~04qgjiTK`6$M|~>pz=_Q|@KtK(y;iiiCqMV_<=Ro5CqC(k z%-j5ta~N90>?e?4nTtO^p*>H$qAcE=~SqXytS@H0ZJ8T+xT zOUSdewb|myqo0vq*BA)-0!JZ-`j3ob#yA)9q(2t9F!hp6+onAB{DzEA!ne}D8l#0T zs_&qEFrPwBG<+}RopGBkIyc4w%qJd_{q;>9OEA8qpmcTHeV)NuFaN zGWJ@=(mz8!=L@{&G~Ra_^gA6Hx!f^!;EeU@BVY6T6f9w}AhO*_F0bOHwzZ0&6 z-}`+=uhqB{e`S*|X<jTbfTU&nTd*pRwF!6H&e#czsHf8=Xe@G3FYnnBYwM`hq z*%CgQkIvYN{PR}$)!Q+-vH#{_ExaeuD1M;Zl<{M3m3hsv-kGrmIB>rd z=QlOLQInkXEXJ1iXYT7Ye9m=0f_G9cAd_9jxnukS9@dxdVlyJP?cpTw0B&QCXmvF$ z{DX0hQ@SU8v3#C7Gw}mYuQq@&D^Ut{+tk2$4`8Fg(uH;(1G*J$21se5|&k9rn% zF!u9Q|KN+AKrVYOd_86UN&I+pUz|-h-89yY17Abn=3e0GE5MbwiG32(DakwHMtx}9 zsy(I;&gTsLCR!gyYy6-SPsE>|GadNR-a}{C-oG!jz8bw6xItFh z$W*K~rf-dYinW%JtMHBW?aUn_Tkh!{YmR`M4tdFrIB`z6^P;f_?m=DeLk%rrKWeV^ zAM1Mte3$pu_w+vp-@leG@N)uw>s7?1 zXpY|8A$>468um+mN2hi1J-duMc7d}CPsUne=(KLxpi8%GeCNFT{%fOt<30Hd{FM4T ze`h?Se9>C+&vfC3XIqQhfF1`UTepHAb#mw(_{Um=+NP^}#E<#Je*7q3>Kn#Kg6|Vg z@`ALcbth<3x(9mJ&yx=3#!LK=lbRO(fgUlJA37h5{kRqTobghwWf;0y+ofIa(?9M< zZeBg~kGdIq*p-j)9lFSxxN0M7wysUQ<$2$6jqXAJgnuaiXupVsr$s-z)(0>&;n#zy zgIbKw5`$y`A);Jk@*jN6l3!TQ=g0 z@DEofz7QwnAAVs28{8!3I0XJ)49(lLSUZP)TFV=-8c&&fNL$t)f2p7KlfJ`3>?zb5(RwJJUtv`-D>1jvH4N!LH@_wsxlVisNgSf0S{%)NBtgl z(C=)1m*?e?>yZne%01Q~kL*zx_<@fO!FO4V4_vQR1&-vS(6!3A zd`zEeIkUFg{2?)X5X4R zy{f*UKD54%c=b2vuh=8i-)0kcHb3W)bM0mQd5rT>_msbPyoKCGLi)*9&ZGPk0d-ZR9miKxz{!08fz9W9H9czpq z?3VS2P3prB1|IQ~Yw6YUl{{49N4YmAP97@8m!VbER)VjnL39iT|1svLI5xs~b>!9b z4g9Uo^0~ri-iLU)XW9+THD+}<_EmyxxXQ27reumZHwGb$k%k>hqxlv86z)! zFmx#Klj}bQ9Lj{cSD9A_X*;wT)+bnZN?*F@!>DaBUbP;_@n!2b9KWMQosV@3<{Pzn z=!w83dB_+`b1a*@Qsn;iqkI?ik_Wr^_{QrU`q{fFEPH%c%t};@j>K% zjrqs%9`uIwz6Zj)H)DH7)T!Vi^eVIt`-4snzr}v*N9#X3mn7v&8>XLVtik$1QNJO6 z#EoO{v@z>j#9fI)>te*O&l2b2A9=AR-+5tCt3^I6@(I#O+QG|#AIF!;ZJfaP=^X6* z8smrf)VY}r@*BIt>)!w$%fUg5@xK=DY?*^s&p7_<8nxEFI8IL;nY9VlOS)!yo7dx>9xme@;3L+3#=$#Dn4|-I&!r z%0K8GWo#z7hzH@b91nk72p)bz{BRTFlFRUOVt*rJWM#@Z7w}80sR)lmy_T?HUyXt4 z8VtsJyE#_Q+IHPRt#?n}=du2M`K;c#G5V-F8Qy8VOVqZ|hZcM{g75rs^xqulx7v6q ze~5g?oCA)-$k!bBXM6B-FZk#2#C>nVHvE8m#!_lK+-JR|PKNi}^rfXfgr2eXDln9_ z7FmlC>#~ovj$!Y5;Aas2%4_1f{OoTN{~RN}pkK?Wk9s>bBb&Ki)O7sy_$T%WgMS+E zPlG&R6Wk1wm)i`Rvp0V88^GJ8$k;8^WiEwA%dn#>(913KPSiN}cs%?xaFuw8HT-~O zm9-6pFPre?`B=x^J;{gVZ^e_f8zbn$-!raz5cMF#=*Q_mPdvl@;^iZ3My!uvt*5nD z$dmK(htS!Z!&`fSqsPHp&nI8^YHDDPMmHVDd{5V`{0cn%9q{&J@OB0E{`csm8_`LB zLnkanAH_O}$^i0Uo+j44?7=K9U0ZSx4(n^ZduzOiN3Z!?cz6YV*frR~S3tjc;HW}J zPaA&nLC!@bMySZ8MqL`R6>B|UzZ%$e=Kv3rKb*<++2Ck1Z1NW9>bb=7^TCm8J1&I3 z??Ju71Brnijs1Tb`tk+XpjV;~jw0{yKKlI$=4zb5@d7?y%J+cwo8P0;ZiE*XWB->T zyUUQ>k(6EWX>O;7kKj#sG}`WSHNZs!95lc|1DrI`>q8uexjxLb8GJVre`glDYc_u47W97sx@<>& zzdN|y2bwW8T?t-)0)9WsJD$$* zuK4gXpi!*Bi2g~EuahI=DKQSM48lXPegm~Z6+9H{3j$}XIfy?{!9NxCbQS%Mbp?T= z0i4l17ni^jYcc|N6WT}PS`(Z!;iVz)GXs9ugnPH3ZHfQ0HJ|T_&fOUt><0XMfahKL zycKwv>GORjw5qTxvDV=_LCh3hVyy#XK(U@6wN;fg1eS{a2d;oQ*0KbySa%Tqi6i_I z>s@*scpKawYcz6y;M6z)KdXUlinT3~y#_k1!MJ2YAKClh)e8Qr;Oi;$c>TQ9In%@q zu^tBTL`Cc!a4|kx;fGepTCC%U4hwv$XKmsc{Tpj!;+w@$evuB?iQwh+6XLbgtNYyN zKCxbnJb}&)UK9`3Gux;G{DNL1Y3E&azWDGTCf*-Q|~+|Fe{$J zKdvv#a|pO!eLlg7>yRErV-eDN9nxy{8mC2k;>N#?7}$t`jTqR7fsGj0h=Gk5*oc9R z7}$t`jTqR7fsGiLHVn*}Gbh%vbNx)m2^kx#sHdx_8L1q*U_3sqSqI}9-FL=1-O~o_ z#s}3HaLsksKbNl3n%aUGccHeua_p0F;8=5lvAl|!eU;0y<6l?oC z9^!bD{K4;Hyu`6#<_$$X2DQ!AKmF4`#eP^D408T~JL-NPJMOq+th4QU+pJ?hjNadr zI>EWnbv`uS3YyMG_FZ>>E^{@vpiX2nYOyw@4s15^KZ`NO8H|lJ8Pg74p>`z3|G6iQ z)JMb~8P-wQsHLsEMtxoIibv`xVotVm*|j_BAIFNC%?X!3{0FAa+6B!$>2}#=msnpN znQXEK{U+3o??mn6evG~U2lcvdp+4alXmb>Es{j{3_V zFyHznYMYiq%VpFwEu}4{R_?Eid;fu2%U@CN^aH;8D!#$Vv}0(m!UjB-;}hYHM?*{b zV_*2=9?er{x+Lj?u$kp*J@2#bCbJYOAfPop;_j_KrgChgkDrOVUFY1nqBv1|!g^1+87jIM#BfzQH|9;bROb4O`g-RaZiJ5@<{AkEB)mQ^$2`fStFFZqMu^CBA-}CM7?*|7uJgz zjGTY)tI}S%*VapW_Bq-Txqm2o`kadGT@1csoqO;W`-He&jt%<9J_ztYy?=vq@p}7O zxVJ^{gzI}zL*)AD@bH zZ2udyelq&uQP`b*q3dqkyFEO$E%$E?U(H8n%!QY>z)oz&JeW;rv#>G4(74I(W8W_A zi*^J)j=DsBQESM&1}}yVkvDj6_^ICKcgDN=sIGVKo-DSZp`m{Wu8{WndOe*#guF}p zhtW>O-aF4Q_M1WOT%RoH4eebssopCD`sbc1xnD=Ue-Sz%_K6!)T`h$6|2PLWb(K_+0Bq zT2rSMt>gh}tm{2q&;hYO4)ULS4>`v&=2;dzQ1V0n`6~P&j}-i&4sku=JK&Gos1f@c z^t~Sb{0;Q}ANb>3?969qAK?7;Tzet3e>(JhJf9DM2Ob1(?1Mhp9i6Zc8Q&Iun2XQ4 z3HQ$AKKBnBhR(x$KZFi(|Ar>EqRFw5dI6s&Y)ks8>JIe?d=>sF_pY^l*VdG`(%zff z!R{yRABxRC6?+(R58R{Xr=xE}=KJZ79SHeP9!UCQ2WtAG2kL#N^1R0r$s23TAKDn# z(WH*t^%Pt9Aj|MUZl^Z*R&>Zs*qPs1c0cC28 z_<-RD^xJ^+1@6pakAG_Z;PXW15x;O>#4_}~_Emd!riCA}+*}BL$YS{8CiKCz_^3a| zW_${p@nr18_TY5b7(!ieXZ=b0?YG~)roFzNF`je z=r14i`+%hnQ1XDjzy{P}FGuKI$1(lqz~VilVqN(|Uctt+;E6kkBQC{f_*Z;{`QX@f zYVQ>CC++q1u=|nQ>CryyebOFXm9k&2f0D9~j~wd_O7E2alK%RDsRR0XKt9-jd0`OW zmV14UI`8pG?CVKzU{aELu zC;PFc1bMXD?koH7aI96@Pydn!q<=pTkSna?!hiJh9-l`JMBRWcXyGSZgB|!6e1SRI zfOYvdZ{EDhF|@8e_`9p<|I`Jg z9VmG~UGRUU75ps^xX*bDpWsI9z%z&+<|Ak8Y{G}M-(!zG9J@{0FM#$3Li;nJ{p}^~ zdp=*R-;w^ldcRyFj950-QkCA!6|Gx8{nHNoU*&t`WxH3 zX18e7f$WuVHaUoz_R?K@PoAgN z`O3VsSKni=a$UfBU0h%pNdNJ8KtAYi^2k4GD`0i3q)l9SGx^5D$Pa7<&etma?{>Gl zMcsz`Vj%xR92Zc#aS-in*7sU!e6OAF(Y;TGC zgLq&NjZ;_Tv0s;L=${iVj*gGEnbUqVKH%Zx2N!_%wN|*a`|i8Pekj)JF>X7=7}NsV zL97>gHu>kJyt^LDaV$^&zKrdZ_oTZtCw~!iC;u7i(4xO$|1aSii$(?PwN1!t`5V@b zaKDUbtOF72ZRU|R5MsaY4fU9Ccmzh**J_goxS71^;f$Ruz@J(x^w-aGeA;nG{JSB> zsTZ(z-GLm>X3T0S^ll;Jv6mM5-8FPa*>`oeoCjM|f&Jm|RcpENFy z(mQD`UZkz-@Ub>a-B?Q`_A>uRI3`@c82jE*=WsJ)*N2lkU4V>DJN;Acr9Jg4!>qHo zfOR?#q;BJE{EemXTnn9^YuDE6&Kl22cg8D5(LHHSE<5%|Qtq)`(a>e1=r3K9)=B5` zsGRrHTpGJam+M;E+>fekteq2UTuJ1K}osF(v$~aUDy1LK1d!xkuDBAL}jYap>q5pWYUeY}2%sNQ1mZ!i8#Wi7DSTavZb>LY7|bvNWz!UB99 z;B_qMX7F}6d7uU8-D#n}xgGO*#Pvhi`K{3T2P*gY^GlIw*Tn5W$85FzPCcH-q;(!k zn#(8ZhivkJYbKk+k^V{h^wsrywC!or)$ygQmo%5gtWOww-LuYK?CH*WeE%>_?LM{n4Sc>W(EATX_Rk=mTZ;eQQr8#sA85z>=`Y=-Z_->F zf&GXWFylb^fZB%`3rqT!c0T>O)b&Ywbz#bS(p*}zu4L>J&3cLTk##3yjp+^fnD79f zYnD3>cr)uQPb>X6JzX$VOK1dF43BHAUFn6F^*nDXzO{HzhcmHubx*H4XBc`7y zPoTr1o-gU2v0N$l`gPJ?U7s>v%6m!oq_gX@XJgIH?uObD29NMT2R^qx;O0|5-J}1T zr%nDF(0&f?R+Wo(mr*(w3p_Ir;^UBy&C&WPv+=88-tpA0}N_|?wzh{Wq(U}fYCMi z+h6(WS8Dpdc^c?%exI0s2)VxtIi919^N8hJ#Fq8G04cNTaOE~_xV(@$-fN|v_czkq zJW$!Z=5w_D__Cq@&Fkv-na5G~OWG^*`axsST^uFON*WBJ+hne}U&cg@^`N`c*~<5^ zH+=A1!c_18`u}I`GtW8$`k!+6NuM}r!F15y96$7Te`0n2m+|*wpHS(K4T!y&q?z_FMQN;l=N5j_4Sndq`h{&l=Y;!^iG^ zdVL^iF0G}9d$71C3G3X)zAfxE8heVkuZZVf_j~qli{|~4X={_NtM}~x<%O%RzN&NC zPcLhqe&*>no&4#O4?E$c6Q+&+`2L$Qp8s(C{!7U1u0ntLU=R;T^K28zy|h>Er9HK- zQNM3}i?XlnSNA9F_4P{Hs|%F{aVSltv3v2jUypkfvnF`gy=B$?(Wz?^!*1uc}*8|6F_RHJzXT{POl0XPt4=$)|qmuoF)FIP`zx8q2@> zANk*$+~58^`qz8Yr~K!!p9iFQwzT(Y^Yb?zllJbD#9W%t`}nbS?4Pzj>96c-?~Uv9 z@6>-O_sX{P8;kbRoxK^xZOJEtc*H%9JW8|x<>wx_evcyRXa0??t`u+4+Q<$kMz>ZE^RSp z`rBiVJNEJKdf&U|VyoAf{>Xo$kpD~3|6|I(vRvwblKx5iq`yaPgZ7>=>n`&eLiV-$ z(%-mmkp55lua5kebY;JrdS9~g`gET6^GMp6)FH_uXEB%rGEztjuAm=+F{YxGwY2JUHv?o^;HecCS_iOv* z0eydRnNiDY{zv<7+^64felLA~WBZBpzcO0VwWR%I&&%IW=lNuKWDI|`1O0>c_&(%T%lL!3lcQ*Y&b%D8G^b}p`#Zu59r!(HPmH`299?w6i6^f%W1j3@ir$nkvt z62F6Jv4LERJ!j47t`ksEd%M=?Z|;XSDsLyf`&%jh z<^ZK5eT=$JWncQM|83N(M6777pf%w(&#e)59;mV3cy@n~?5iu)nd;D_f6|#f8@t)^ z+MRLCK8$xP`W5s?r?t`hE69gkg^&DZe5HNC=a%4iSf3BPPYdmR$Zoss7XBakzwrN% z$H@Inmj24Vxqo%O<9X_R?RwH*9$?N=_zKnsXG{89A1-gG`^%iqAiFSw{kCF_Tn6G z-{3L7E1yxGkHr^xeKLHJ_vW$po3Q)vy<@yf@RyDuPP#jB^QPdjfe%$7C$VPKbkV+) zf9gITA^jQqYoq7u+<(8$FF&jEm3wKg-j~+e{gi!=#4ADTq`gP!pSs_=Vd<~!&zMiy zpD5?bZgmh_r#`j^k{KQH?*m2>H@{1eZ#iGhvtehR%GjUJtgZEP}58tYTK z{`GYKG4>bwU;4A|y6X$Hu`e<1SJJxwyrjMKD`j7uZ<80iZxHSE{nY*18GmceFUNZH z`5o&q<{M=9`+fdFvcI}?pXhh}G@s1pv3MbMh2L}TUh-}HJ=dxG9DeiNq5TYXKC(64 zWUrqm{Tct+f;nBQ&|m+qpYDE^ruuBky|ho+*X~RA^!d~W(zm3)dSBY>_o@4Rp7$B| zneWYf5B^U*&etFF>G!4VYx@V$zn?A>(RC`{_dk28pL_IS zZ5P&o8p7_^v|1Y{CH=ajrnYTCymqR zEA_tDQ~qJPk3odTo%se&%@emo{ay{?9cVl=qVE z(l2G-INyAa&3m-(%6$5JsrS7uZ<#mnxBC8$^Gjo8U)^s#fHuN)qr6|eL;M?k(8n~F z?EF|`M}0?stG#f1MjMg3L7XSe*}J~Gwp+ey&{4ivbp4|4bDsa4?zVT?wtM%x@6|oy ztS{@c=>NBof!i4mKN>x-6Y#C|MPc>-(f^yH|My4!FH!!XNk_Vr4LcNZnzT-OOSf#& zL)n+^nd_BLq?}y{fAJk8femT~gy5F23>-~3GPpC`2Ga5PXSXV-xP@ni* zb%}jdH?e+N)EO94>VH~eW{ruwq>Yis)GO)`^M~q>v>(zYX*L}^lF#Zt`abhruY3LL zy03ZdYr2f<8HaS>fi`@9JNoWu{J@>yfwfM5NYcH$FR%Fw z`9Ry{x%8*C$#LF}FMKrd&`#7vtabV$|E}k=IsX6t%=5eioLTqXhVC)Pi+ScDpQ+Q; z@5*`dLLU2N-|=2^`_e(0BwbSOwJY+NGV3$+{lt07zGFS=cj-M5&6CzXJ6pfsGSO#w zM1GXt?UOaltjihkt9-1UlOJ7^$+0SH)Z|&?RBevq5#}P(7a7my$OF>cdp!0&cR04; zx25<(?}P`|3H`1AU|kRE{~pBN1{Xu87C2~QYdhH5jsf&~Li9_|VIz=31&PUmo z{*DWm&nRi$PoJsMccT04=b$FvCJderYH2&QH>pdKPn`3lEmc;`d1(Xs>5nh;PISP+ zbwU50{5Prpp3lA*RPak^!>`5k7Iq-h)L%`I(;Jg-C5r!&y?@)=T$%Zy|Iii zC;jmg+QcqP*CqW81fBnd|34G^zY8@$|G~O~-$D;u2OnGyoo=9?H^2)wFlXlm?BZYG z>A%3+e}R^_AlD-tV@|k7Xx&M=>zjKn{e@ZFB<+=p^u?3~eZRE*%D%c%TPwemxa>bK zahrUyHjeq8$voS8%lq=T{YPcMyhlI%$#uLF9#|*xFa2Hb#XU&S0ken!wuS!pCGYT9 z{O%`Xe-A}}9||20C1?Lsa(Pc>E$64Q_S7@E_qFV!_G9J^tzd1CHut&~OuZgV(qG*# z-PDW1EbUYF)rqx?eg;x0L;o_R797qH&(SU)K0!zF+!Fdw<_g^Q3iYYcj{Q zp&W&6eWAZR;J!_)?-qLtxVAX59(&y(|8X=IO^z_u1*2x%y`8p3_McAs75BIC7dqfR z?7#F;E=$>0=PUR6eCA-3ea1K<&eIP{-EYpt9Ii2xIFg4-8JFhL*fC_AF`~J^4Xw%7 zgXm8#WSz^u^v^$a0rZXaUXk%Q8Yk)}_?hDnwqi?k0;=F)pF#KEj_kL!{m>@X1e0dc zzF+o}_Qr?GzV!j--t_&_?J4fWBWzfAeX| zzdWR@k41BQ(HIXfN9@?ZhR`ynEnNNnU(z2RV4d3klGgp_&^guyg9nC?_xad}M?wED z5+^K123yL#dLJEK(_Vi~+Lv};e=lio&P>_2e#ktJzF+!%%74;d8BwpNocGh)aUp!u zE`Dm4n%E7Z*;kuz4Wd7}uy;y-=ESTM|G%H!{hyI{?LmVWVRQV#htkeq?}^*#f6!i? z51pia)Qu(W_1)9w*Y4}@DfdZxW#4>}alZ6Vzfarm_`dS5eOIsJgTy#cKfN6r#82tc zpY^giemSVwUtw}gvh@GS4=-Kc=#Ss;I4U=aQB0T;3s#(E+D$bEynz+CA61lEYSLb-?TIZw2vy>g#)Pq{Di-}-w= z`;>jh)|7MUZ_X!W-*FP@uZ*bIrMWUAy;*~}rn&gU2k8=*tXGXZdUw2Lf92(|=ubX; zA$0)j1^v|3W{4UfKG z(qG!!)C=0llHST$(p>x!dvwV~by>Th%esXdOtZi8vtvMma# zgFYUC_M>E9`lswG_nG5O+1KY!e?RrUc3;^q>960X-nZUD`s){H+mqhP%pjVxUTK${ zRhJypz~*<;-Nt&?WUt#FZPtcBe{{e56yFUU@OABeLH{}@J5~BS4muwF&Q*Fzj?2Gy&=#apRb9&+Jkl;{`e^REBn(a|N4GY zmH*^{>6Y>7d|p3a`E32xvFJ|>u-@o@=s$#QP5P_*Z9(^>zj?aM^{D^T2BhzA+&>xn zFa1mVua8{%_@(_X?Sb~RZ0ox(U|+|x|Hl8+tgaXSANGF;8QTM#o`>%rwqN>}JRtqk z2AK0H{lGHzFL@w+0R8;Q`2YF>{r-PHKgbj7W9yFv?4xl_`v3TV9qT{f{q-*XC*S9q z@O#qEC*RlZ<$LOyPRC}{1E~Wt2ar5a>VPr^H2&8Q(9d`5Z&3Vij^Fs-yiex%%A8L> zKirvlfbrhlpC9mEVcJmWkNw&cn{_^8Eiukx?%L+KjLkf)`XKc{@<8SRQU^HZmpP!! z0SwCjW&YRvpW{2`eKW^j<^cQiLF&}?waKg5?4vMc{x9Xf%>S=1`Csz?t`EE?KI{49 zVzbUCax1tJ51davF6w-wiA@-6%BgxldZk~G_CPyO<^swwAay`F{$~!T z9RHD*H+z8vnP>e=6hu$qT;I_m{e1L#hD~M>+nF?-%|bdT;5SUH?(azUS0@4Y4=Cp0x8B zUvDFO9p%qf@`3UxPp3bSJdkl=>VV{d^aZ4U*8ijrIGOsNQZJ-F+E9+-%6Lio_vVMy z^uIIe|N3cOewO~^{`aKL_k8Sa8yV{;XUPM}2g+jFg5-nr2~!7T9f)HBW7Yqq4RBn@ z@g(htcED%Z+gobh-e zb;SC7ly`07qF?`)^j{bAzxruC=(F@^PtZLX2RfgeRU025_IWS;?6G)2om}bw>6y9V zLGypI23Q?nUZ9`uN&oVgdSQJ&Ce1x&Ka>8B|EB+!^d~M@XY+ps(Y(CY+y8q{c;I~U zEkXaRvz#msD38)C>qF#$)B)xEznuF!X#QW~uB82jb}sF+&*H%Nuk`<<|GJ+4SJHaW zx%4Lo9Q3CSr;QKTG4EnaKJb|KptJ=U7nV98c_8aUoI9TLf2{-52H4CCq^7VoelZP^Td#vHk--f%E^@8~QWPXNVl& zo{R&Zul$cie|5kh9*}<0PWcsnWm6tVUtqlTKQhKhzj7>INZlYm^z%gOi}m4H_RYL# zng8F=>7VwXHx--|Fi?89!Osxb%5}v3<$qEpj`jUJfL%dmK*k0*dv&hPrwy9^$pgx2(kE?q>cR8{2Ce@o54bLz_1!k>Wvrp- z=LKtM@?G**Li>Lh`VZ0pIZmk0rVemDB>kXV1J1Pov;)Qk z*3DWgYmKKhbMk`q!0H9(1z1mEU6^`7UdXmS)&OMRJlbFR)Aa^>>qB=qy8ho%e1i3o z{uBBC%3*(#&r=7;?>R=4c0l^OZklyajC<5;fJ%S&0@ijU-JR!QU1#!wHFffWdO=>0 z4{X|sth1TucxToM$)mzJ7X4WVcD<EWQN3DmkHo*)W0#5Y{5AipPqF`n8vp&c`3GSI)rC}d?6n{=IAr0sH`A+I+d7vo`05Wa*n@;{NjFj{wfpp`IG;p+#mLb z_w!GEz|Xi{oj-rufXILIPaZgSkmBBH9Z>H95T8HKnrE)~c$y=|90BhG5%&V{UO?2G zXD$i3g!CVLO8N;hh5aTOUt+yt`U!dI#3J!ekt65@n8)7WdC@npMU)4X3ddE2kI zOa9vL(HF#cS~FJb#-{bZ75kiU{44g`k`1;{eU|6{1UUeD=EGwERnMPiAMHPMKenHr zJ@y|lF!qqBdj1{{GXFeFo;}aid%*blv-Yl^KgZpcvVKAzjQs?8!hJG-m2pda7i<$` zN$e-ss>+inq$^XA+$>ytPUC2W+O*JkdfNAJ?R`$@=db?1r+(WdD0&H+n#K=}CR zU)MgSeR7{a#$btmlm7vO$nG-v&-0J$`}v!Fp0}U*S~+TYI$U?#52`-rzrnh_mM7d3 z@&sK)3?DttJO*M`^phx0-~e5Zo^k(>OilBa`Q2;ppS|B!!@qRlKTIV3&$@4tf%7G| z-lqQkm^fzszt{RqYrnuW@jRXj`?u2b z*KhXo-+7|gfAag9(p6ha{$Hei{Ggcrz3izcG={TU@w+vW;c2aK)`-?#9BZ^T`Wo%$ zx<)LpE^yi>h>>){95ilh?ui39xQEp6BdmZKi2I+LHVTm$kVv&Y2n4+JBQe zf8IV9Khy28ujPJ1-_UPP&tJamBVy<8r5hHAp9%5&rS}`i0NJcf`OAZ{XSS6N*iE+F zfs*}4N{^qa82c(oWy_YOwSndHHe?I5 zWC!*so-&|5Firf=((~U=<8`~rPdZ4?{uJr>zme^CkLIaJ9H00|x#D7EkxHM$nH)Pv4^~?w4BhHpzxQFD#Y3ehtlg{{p`os?;8-AkP9_$5V z-J_BRkINo-LVolU8UtkC`_+p5rGBxtPpp=FSgroBT6%IdZKb}jT76+P?N`zdx;@u* zf2n%Lo%&G4_tO3O*~`wM|NmZk|A(6M^b*-lbJU(K*-o46Irs916~}H!*7MvO;=7@B z-H-_ljl(o0F9sAJ+)A;aT_rP?%4c|nKD$EwK z-S&;L&yBXf3}4gFUibZke#_&s`TtYnTz{`;zmM$ZEws08LvhAl9>awAEbD|T4wUqR zY=egE1ndRu#(wz@gNhvuDd%e&`HVYi9fuSYkZbDGxY46YKsZ+JV$yHd+xbs(i0kIYl#1b_)oTje8{H84_dMdTCyMd zBn$dwD-1{$49ISnCi`KU;st~11C%Y)9@E9eOqDG)A8I>2|D7ZcSQ~3^#YhiSA6P2A zakON^Ns1$#p}ugw%B6b!Ld919LZACvwe4%wwr|%pZdAEdv@6~6XkbSy=?xDZ9&#cu!vEK|oYo2q~XOhl>dC9Kd>Tlhvzxy|m zZAa=J=V+g`LB&U!l6^_1jJ&&su z%e+Z_<5qqD)9PpU>RR8_+Wh~i=k`C6Gry3H@+;ys>L-s$fB!%95&Z?7Bwr@!CFBf6 zuX*qH`1k6Y-_rHopzEEYSlQ0H|5x?KMY#XP*AX z0)2lM^{3rc7V23YsB)N|)zei@)$==F^-7gLSNS_J{08-rtM&J9*56#EzNYST=Y9Iy z-_W!Dj>@<7`pYV}>iGZaGpFmid+9!B>)r>{_nQ1Jo{`X`H^!4?nJ!#}OCSMbs zh)hs?si85HhT5~CwoZLQZP`$pHpEmz>^H<|I@YsF=lPzVb?P_tGs&8!WC=2b{?XLm zXz6@Qaf%kUw`5G8&iCp0^eGNEpy!6HnJJktThBSk6!o>8)Gv0XpXmATrPuqa-yEdR zJyp+snQWG$RgR^oUmc-q9H@I{U(c=7r>9B&H1+Hox@JQ*Uqkw@e)L_mK(pCwP?TrW zkS&??iQ-HR{3S7+`iGutk_%!w=~AA#o^6sX^ds~P{wklNUm#2PEOLfEMSs$>O?`*= zkv$sMY@(l~CtCV^OV6-R=PCVqu9N|aY>NS&ub%rf9Z%CWr>P&IuVB4T{kO^AQ$I?7 zPyMZnUtND>G%dj1R>UflAJ|a7M)FaRE0!tfBgHCGf5Pw5ICj!UVl?#&J=cchcIp>A zH?iIj^TU0FW6tpzv7eqR{mBI#rstpDqo$w9=ShC@Xnt4y-SKaMU3cBJfsIP+6M2JO zf}BAvNEW0b&eOBy*<+7j$DyN;?-Y2KJZMOlq&SKE-|@fk`Y+TiP`5zc0(A@2El{^W z-2!zBY<4YBOu&C@`qsax#~SOOc&O26#!uYAQwt}q;B`2WUatGfnkQcmf8q(hZv3Bg zk;jH#KY8Neb+2dhfrr+;9^~~M>t3h(ykgz!berp5rh6Fv^E%J_>;Ak>=ymw>>2>(? z>Geb5dVKzl?DZAd>-bWikAI%)t@r2kdc8ld*X#Xxy?!XW-W?rYUy;2(-mlmDb86qV zul2mvdq01z=eyqfdj9LZ-X(i|boToHWUuwO*8BblUSAO}pzn|N^&Q#u9?D*?_x$zu z*6S~Nz1|64#}35ncmZC=Kfvod!XGSqeMR|YOM@8|t9 zG~kn3W!(p!e7#O$u2n-<_=;;^5BKn-4!DQ4AJ~QC^zWf`=IFJrR3(hoz0}b|nU-7c z&2f9Nh#Mn|P?@C7#;&|-GK3S5 zpl*S>1?m>4TcB=%x&`VMs9T_Jfw~3i7N}dGZh^W5>K3S5pl*S>1?m>4TcB=%x&`VM zs9T_Jfw~3i7N}dGZh^W5>K3S5pl*S>1?m>4TcB=%x&`VMs9T_Jfw~3i7N}dGZh^W5 z>K3S5pl*S>1?m>4TcB=%x&`VMs9T_Jfw~3i7N}dGZh^W5CTR;i=Q+) z>f5ecpl*Sx7C7v%!_q$3M<0E3^Mn&lXq|T2X{~e5J-6?oi!SQZK9~L4;wEta8pKEC^yw)pT@rsuA#cOGw zUvG~rD5N^`d{4wbqj2o7GU3N@!wpwY+0Z99~A#H#Q&D!e{1o- zo%XifL3)2jaXUx*N3pl8GE*&w1yacksm*Uwnl4KURAjA1`)K)Lw)qzV@}RJwf}SKV8fptvyYT z6#s|o_^IOmDUu5ZivRuenMLA%FY&*d_}}@8E3TNQ{n6)W|LpB_ovpQh_K@Vj43$B> z?w4%nlWo!Zr+@mVruIusMSBvaeROr5vjue>=&Jw7(qw2>aXB|LPW~TcGWg$|=WaA7gDndd`bgzg2tOf9zS$ zde%MK@BDu4cYeRv{e*b^xNL#z#OA+<_bVg^UMM;6T=@i-NH&}=hR=H4>t1)N_Mtpc zd!Qeqz0j9Qb{ryx57hS-soqVpVV?F1++LsAN}nClcV<5`Ww^q z{b~BnfcPJf3>m-|k-g9-{`+3=f*17ZzFO?PPSJ5w=P2DbNd3vW1vZlwV9(Em3l}yQ zFJ9cIeaolI_TN_Q?=JS2iv2TX16--&drvy)q(VMGp}j#1u~f(gC}hVMVzZF0FT`mf zehYD2NFEg0KlEYo`8}1di}6oL?|($^zh3OVN`ArR`rgGV=c$~o*C*=xM@d#JmCRV8 zvcJkAU3V{?-$S3-P5kd7{uhY0R#QY4gzlG{) zD*ZawC%d4fxJC1&FMa7|@?`6uS+_v@7Fe`sQA4G<|Ni^;N%v1b^w2|hl;6MqF~=Np z;?th?v_D<4WXV?~3yS5-mlulr72>B5V}<FE?I@$(64I~n`}{Z?Ut_Hl6+~&=7@31rmo%8{WW#%rmmf05|SNFUALj@H}Ey; ze{~B?))v@v&pjLa?YAF#zyIKa51t{re@EH<2TI?cAv@ro_1^EK_lpZJys(h&Ox&aM z;Z}QsC+@ZXcR?}#t}O?&A9#@$WP|nyFSI{+ar4bLC;4#AHP;kku@HlW^m?)@#BQND z;LlaQC;sk}%=tI{?e~cHH_D#4LUP~*k^|3?y|F^J#W|86r-|_s_5RT+hw1eao!?i? z@1f5wko=gVzp*Gr}U57B!|^qB+2|9;|sk@(+B{O>OQcM<;!Bu91<|2vBR?eyEX z(e-Cb2Fy~Kt}+dIpz|&L&8B>thOW`j-)+doXy{%WieEM)qZ+#2X4=#0pFPo9K)!xM z@jlqc-=86We~#E+a_q6ko-JG8dhuU8^O?^qF2DTpLTnA|efSp}$+nN&`#84);GdG~ zf4{~Cpyd4X+WdD@-+1GVNj`|@WIu>CVh@FwP4_PQ|3Q`erOQ`IZrm!r;Vt^i>%{z@ zNe(<;GT=FiFs@DIa>C^GT9M_=(`8%yZcD4?4cUDu%mpKZFH?6 zF+M}z+d^_=8b#Ncrq=`Fe?af`i~oLIt6$gZlYP=BS<%N>Cvrpbq$L?bAui$4(D6j; zHue2XffkrIZ(fS^X`HWL<9svZ>(7yYzxe4-fBM z`4_L3AM$cB{9O4C7fT+Tr*gW=NqT*>&My_?i^cmsk{^4j?5eV}jg@0}9E8Lbk&r;`IU96W@~lzg7I+BH3`I-hYMsiAz;3luvQ4 z?2qN*|5WjRvV4H!C1;M2tT<9KW2s^g2kY~TWlQWQIkQmmW)EF+7hQXv%8n}A>iV-4 zuA6cw$(@qSZs_@? zTnPC{6QTRn_pk|DV2?faXza7kK233+Vtvy4JBs~-6yG~XI{yaPC%&(~vL5@y`mOun z|CU>B8B_ip3oP>idi4XwQXb^jBHoD&@%FdBJ;foU(+jbjR&id?J$&c;C z`d0E!wp1BXnI-%P`0p40{fgU?50P>p zG#=WNUAGB)Vg08!MGNe-(@qVI@ejxPr1z7}kKPyi*URVMfPL$J*f;;ORon8P`~TPg zo%H`?;XjuL`RfmS-~-7wy6UQ{3fcaJ7#@yOGG;0se=IriUA5uevimlN^ zKF0Wn^=VvxiS+*28uL%FzFhB{ef5)J_R;;F__xg;>vsM>alm#lK=l8{^Z|0F$NDus z2IClFIN1>5wh*@|mjWL{GT{OF1z%N+;8vY~uk3}_$sYJ8$$%F~29Qg6sbs)~@=wl@ z%s4|bz_}1dNsb&YTjCJOfW@*w_LUsiOLoYvDm&?TdtG<7?2(zWJ+@FxVw%1`AUTre zZRtAwvQh9g`t)9({$`)`)3zU_YNe)yMOX{-Mu_dc%qUpJQ7NuJzv(@n|8 zAg>A;A^o0mA&?PbtPsQhrSd)54R@;Crt{Z{(btRDztU$fmo0Fy;tc1B-7_Q)PF6Wq z$A|0O5^=q+7~ezO?=1N-PuHKLdPlw9LHuv0_qG-P+vsy!>w2^Gy)AX^A<3dyk}1r~ zm@fXe5dSF`Lif|J(x=i=8I}dz^vn7)Ww&m0{wGolpcB92{XRYhF$i*{kPpNurOyk-F?cqT&p%WBfXbJ}>aAk-df5b5 zisP5bueeC|!?`NUb^J`(5hv;U$BF-A=N#VPjHwfENd_mHgF zMKQ_wy51a>?Nzo`*;2A-hRzS_{Q=!WpT0*PWr|Z0uhczy-j-vPDGvhQLo%hIdrWh^ zrCY`yh|TCP5bIl;)7!6{-Wlk9Y<`XLorB&t`-%sx7wszhC^5JJqNAA(xUo%BJkl&4|>o|EW9fxMM@PeaYr0ug|eQ^uA&M>#=XUpZJvZ zKkVna-?smz;(sc|07k;}Sbhf|gBXNj3Mp4g3@7;@yFQKk$cA`G&-=T2eW&JDe;V;#e_%xUO}uVwDG~?5pEN;(u@PzlUVPZu;yl`rZP` zlzH+`=8FFv#sBu=e;ZwYEAgLlDb??$sUH%btn;ZyC>9vsm+o(BoG-=t#C{szC)S6} z&ln#zKYHJ~zZ<_F-LL1Ad{AuAJm<%+?eoWawDEtB3)V8A`#8dAz{!1)JyB3{-@elz-SoV)Zb-3CvgaD2>cAOU&tRwbH2s$6XN+Y8lW$6kzkSc855(&F}GjVtvWxXT1*c`EB=C z>3+ugDERvn*k{bo?04e7EdLi@pj#iH8ymp=t*$qmH#u3_ggKqa2Yd|K14*yQ|NoBS zkpG|L#EGi*lV7mC`Wtg1TAGK}fr8ERZDM`+`^?{WtWR_I7q9jAlg(eoez&?G_9cUd z`N#ijXaB>0J0GB(4d6V$S_VvBu16|=upNjq$R2%Ey5?Uc15TFTu(xEuY}up(T5qzc z9JS38@`_*0{C#qIiS;pu*Reiqe#QB(SFT@Lr;9nf*89}$bieg}mF|cC4}S22mGQsP z!~yXMq710zz~(0h@E6oSS1Y!7h2jZEC>AhZ{LfS$?neexps?AUc3z*x@jaJkj`V(t z^)bdLc`(d=ZufVi`=i|-ZGXw*_4xnfCqG%lV*bng0Q&&#Y=ANu;MhQ2Ke<-IRBVT6 zH)z}def1ON6`ZYj!G6+3+p5nFN-nfyA8dB4=RbId9d>AlfAl`=&qD9RzV&_;`@QJ? z-0sKkNB5im$b5cm88A{mz_CGWf!rRLihaNSP3z>E<$&})v8T6bOyEfMy#lj?GR-kGJyOf_0@062Y9Ar!9wYttyI__X0zfw{@6Kl z<|OttXKz4j^1}W+v461GKVP}N@7MZ$iGBG=Y2B`9_jjxNZTH8RU)22?(@pDfSZHc&G< zF&G{1=YR~5%}-9i^W+08Q=ae~l|hxwhJVHQlHOMiAM6jw#$TW~|KW=BUnHC09?j?N zihW{!x!vC>$1k!^%-_17{7rnbD%Q)+oBt{sAh!i-Ik0&!-bsd_YczLgrN#l5Y0l6b zl|hxwf`4p&+50Wo`vZ#U!~T5j%WZ8m^ZA#zOPfBf7$yDG2YTVz5&Jbhh*dLEcTab z5AF-Kj^Dkq0n!}a80#yG^>?H9bDKYM&sZPan|+>#=4p+J|4uf56^C{NHesC)_XK z@5wq@+9Sq>i1navw2s(HjR7o^55Qh(gDO*wf93NuWb3!2^9N+_4{43g`Lg$yKI0kB zxLE$cy|VucbUr#h>iII}ZRkF;a`hm;j1I$$!RGCuzE56^5&TmQQ4~X+E zPdMR(ou%`ao_5-47s?*ESN4Ch^{wZvZFIN829%&{moB(>QjZw9e3PO)Metg!KXj{>GYgv$L_SW@zTrcW+ z`}eu7H}k|=(DU#fi`mEThkXjN+0Uxi+AMcdx4U-aoIdoK&wQpXle`Uhj+O)H0{WWP z6J4n>fMv1)=Bf;;ObPxquGdg}uO-F@#Ql)CpD*qYJ?pHqE|NWPuk8Qi)7zepti!nr zdcIp-AANdrU&g$3KK?#3II=%l{$V<2za8iCJ^BVZy^8lc@4U01eD<@SU9WuZbDt}w zQptZ`udnmA==J;Y^ZB)UeeG-U+>qgx0rU~&`V`traiwB_%VY!0RT)&7^!!WTH#DZ- zlFlEHtv_`7>8I~}=9y<6cHVjCtxz1`9-T|JJiayV7w!BqU5}oJ zcQX(7W$eR0{#oR5JddlG&sp!a-_@U=crp=LU>QK4VohPK54ch>z-6)l=Bf;;OltlW z$8X5TZ=HPd$pg~)L(7*hpMTCd=Nxvy1s7Z_f8gFzPdzn_)e)uvI*|hxim)SJeHX%K&7*#`@XEY^7p=%VY!0RT)&7l>E!jAJ+Tg zeCXVB&t34WXFcoii!Z+TBFTh%WdEo2wIatJhmSRk=f!?~uJ6ly`)=%e>-n;Jtod)p ze3`C~IzHz;?|b*&dv8&fiQfi(ZpZ@50Q>-r^|8muO2q(|X&i8_%Am@m;~#%t@w}GC z^ajNFko^4lQu&8odg-MXDF$$_?0}@(J?8G%9JPzb)SAG{WCP4q8C026{40+y z+5F1o8BlD0NcR5D7hQDGVOo=ag=~U*<@*oMt3zK$o$c57?H-e_s(bP6+u8S3%*XS@ zW=CrOck=6b?zZu(biMV3`wg}G67?6q_{F+Rf;RZlm%cRooT3~+#?uEh)?eIk!woAn z1~4i4mu_!pY_Fv_A9{b5*q^_a{fl8=K0wm%_Q%oFd9e=fr5=sGM>fO~x%cr%^nV%m zF@|sEsdMh_Bf@^0WcZ z4_Ux-MF!yOvG?$M-t(T7*IaYWGWh^=RR&ciJpan$ZK$-Q`v)|>7j6EFr1$U9SYIjo z<`6y0apVxLb9rDr@Au;8J$MK`Cw||em&$*9w zy>+~qH|Jmd>Q{?czV@}R6?K{TZQy4XWdMCaWBrMLjR7u`4=`6{P-Q~%kH4>2UlW^O zasFAd@rm^86`jY7B6h ze1N$sgDMl2e{y;?#@|$|uOELO_Ak8f!b2~+?6M2-_jNoxpBB#G$_z$M$NCuV{de*@ z=bo4&u|$^`kL0slOZHf44q&hBcgsEfA#!hh;eO-V{pssp|9V0B#y7r^$~V9H&0;DQ z|E`hNd0UM1I(#p`R*qZY7XB$u+KO><8;LEt!K^SSToP{M#6pB_(B|8KnB2n*&5*O_|M~ew)K$#RknU^ z=a+F$zi}VxweQuRpICAcnT;&xIm5qleTw(J?|mzk1F%eeZm!Cp%7oPa%IQt{J+l1= zmCwJe#`yPBtp6;<06&Y(PtFecIp*JbHQE5SZv5883h-?QwYw!Sy_++Qp{ZyCV% zvHytysv)#CVm^lXJ{EP+4xsJf0Mjk+5TI}@844~ zzT+he-a$?;dAm9P@MI3rskQ@RJrX%k#(r+&x8pwM7g-KO89@G@Y_h~Z>j1`F0Al_2 z`^~<`^UM7G(dd2K_p$HzIA{Lb-~M({Rlf6`?-Y}@RQ;x^^X-0T)py#RZ+E@?y>{2} z^YZiK*~0%@-zxoov-JPFC%*m{_l)&TSB~F2<@qdA-2bJD1wP6g9_RFS%Fji&=CYs{ z84zU$$GvjT{pBUf0AvhdkmHmIM?Eh;gp8c;myA8$r`xxsJ`-^1zpQSk9 zXBG1wUOyZC?>v2&iaOQ4fbD@YIRMYdg0fP^y|3k(zu~`WrmgGEe4J@y=hH&Xe^^W#~Xf8s-LecR;VUu$=!n7?9v+bXZ;sgeVKrkwvLJO>~BPci>y%3Q&v z{cH0|T_p!{-m7#y*Qny&d`ITQ)X|7FZr&*Sm0z66HoW-1GNy-pgM5KCSz){Xh7@4{pFe^8xJt^X#0*TgJZaeYiLK z*7+XGtKuI0VEf+vhB`9r{x??j#$x-s-~DbeRf^l}fd?N*&n7;rcE>#1uYBd-i%;G0 z$>Pn4e~teS^M952pIG@n;=if&x%;H=XKKuUH*tTu*6;s5YxJ1=SX&0bn)Pdy9LSmO z_BE`Q+4}x_=A3(p_r`I&Ki?zwM=qAeVhVIWv48dejQT(FA9cU&e(QbMkA8m6y>)#a z-z(GiWz4(ZP2@T<{=M&gub9e(-^#P-Rt|jY+uthg`{KRDzkTwy;w^7`OL5ctZd!Tm zyOsZUt@8h_RsP?^gx_ZNy)x35b6|4r|G&&q4B zyXHy$uX*R-Ro6_M{C{!ZP=Ws~v`6QT8Ur|3`9FWJ@&C5`=Xy5sX&FFmIgrN(%Va{C zpC8$eOqc0>v!CA^YcMe0kKJ$GPwo$UfHDuL9sjodt^2Fkx3151yjiC%<2~m(?{8D} z^+e;m+xz+6L$Y<&7Juh^-}~-*w!t^P`HkYPFWgnE`nQi4Z+-h)i}#rSYu-6m>`z4g z`?OE*OxgVNHQ(n5p$J`wDO@ACFFlZTO|1{O5oEXYu{-f4}&_4}LIQe)z*54j=PA z#eJ%-C!Q_P?wNcS8IbIN?-b_$V-PHchXxQhTxR)yS@%tI~>s9yT^P7Fg_Fy0GvGJ|rBlq+fa}V$T^ zwX7K**}`+b|AG4p?Eky(x%)}`Kk5G)pS1rcp#ERWf4}N2#s4140X|Xue}ug`;i%hE z77r+k3AU2~W$YtMqTS!k{ctbj_+azjeDlp|tlvIA>_@xbxj&BkJMNd;{oSx%rSr`_ z?6>3o=Rf~>;quF0{<3)Z;fE{BFMjch^jYLYnT#;w$ct`^ztfEjsXtRDL%x^d0qBDJ zzIb18+b2J&P`R6+ChF#E*%%Y1&v{9r$h`^PcAX!qmuTkjL^v(0Z`zfAAL65MrS z-}>I%!*wV2+sOsL$2GVX*SCzo-mo2kAJR!K)bgN=@%HEN1Ma{7J8Asylb^ah#s6=- z>4udW^IP_gtKL3GWl&|J^1qkt|C1F591;IzHUJ!(Yw9Zf@6S}R-!1>x{911<<@msU z^!anU-@4y^f6l*Se!1?Cu|C`V=ze^C3cAtkoBuMsKVIxx26U=(8G(G@KCx5mYgk6q zvY1O~v&$UVr&Ju6oDeiUrP5nWi!!`Ip`w760hpG8qtU z0CQedTklgx-S1=T_`K$Q)>^p!`s-P5A=&*=_dDhn{r*n;JMI_tf0^G;+{gUW4`2oT zYW8z~Kl=J(t@k@I-|PFx2=3AGh-gC~8{F^f`k^!~z?dL9;op`2bKC8=6^uK->$-P6 zTX_J7N*3&>GEHU5@(-70mD)U4@gC2&)BW+9Is5z#=2^o&v3}eA@Q>e5%-`dEIsdl* z?f;j>{XOOvWB%9xG47Z9{?`9_yf2USng6k{`Fmx1tUe!Qgkur>Zu=OUi)>(A5M4mO z_~MtosIlf-*#GO{tFFFk#T(!B#;5%A>;HLsl>wD0&3~B<0HcxhvSZ7N$a>W=e}jU| zfPJm8p5lE`_ea}5@^Am&<9>PGkLUVC{U7svoaf^_Ui|-@|J(+M_J5WBA1fXw+I6Cz z!EcX#1~P)Snkq5^{^=L^j?6QA)vI3h?YF<l z=E$wNZs!MdtNY`1&A!%FNj`tB`jz3`6@K)I|BogARek`>MmgZumJyNfcE@I4>nbL@pRvBE`=jmeoFB&k82_^k;4y$I z{;P6+c*gJ_<9~77KiB_N{6`runSFq6IUmjE%KQwEXH0}x1hHT8zZfghnjdNJU)lYC z{pPp4`Kj6mbj~aP;g!=>S}L0b|5bi~Sud;GG4J>A9kBVaukiU{-@2die%Oz(KlsmO zfNcQt&lmvf{^0*J_HWxC{-f<*7XK@=|LKo;46sc9*Zf!KIE+MAAR}l~k9m4LV`Ic3 z@Bz^a^dtJG*17nR*7`k5ap{GccfQr%{r%rf(>&MKgn?f-GM@Us$_6Oo-sjACRc-dQ zhGO#h8S5+4{qT?f@AzMt3~>IheSpY+Zu=wC8PkD(>we-q$ooA0k1y-^pT_{A|6gYR z;|J9Ge{5wznf#!Qofk2du?TEG`U7*s&_%@kRo<$-{*KnX(|O{5y5_v}sZ5yIA985C z`R`Q*RB_LFatByX8TO;yPkXbTU)24!0W1fI1t1Uj9DV{d?;#iP1&{&wZ0LV-f8am2 z{jK{W|5dp^QTOM0fAl*_)crO8O4!F2Bu|7mGksLNe?#nF zAl-j}^3k@I{XYQvn(H!=)c;1|Kl%aY+xot&_Gew zHxsY&r4s+d`{B78{$U$=@tW7XW_XSvvP9#uX^sH009%5b0sH~@FVp?b`;EGPw6=fE z|HRSxy~rATI%I&^$L1%dj82lR{~PV^`7+6YqowRT{SW_T zHh|?o8UH?K_K~aD{nq_4?icNUcz1zmzK7qyT1K&WO=H#rBvyk=AyxqYJkK)SAM^el z_oolEi~HBM|Kw!6ojkw>;F+WM(G{?dE|PuukoxG$q)(2M4A@irZzb*rWe>DejNF8( zHx~aRkpX63`=uuK;Xl{?j{RE(z&r&XAKlL1{nJ1F)8bG5%5-0!c_{f_%P=O3L=HtrW=fB5~m?O*%;n?^?b>Q}!i%1S%-d5`CZ{6|k<^Q-Tz zQNO%ReeSu^OGm4p?xp^;wfG;z?w9XBA$9-8wEy9dVx6DY*7vR>`?mX|?zin9`9}s& zunm|4$lo*fv5qnTI{@1R8vy^mjD5%ayYc%S_ebyNy5GJ(c7JXAk3aK~?O*@;*F`Ud z?^ekH#&NL^@fW3Qeyuq2zbKA;rj8F$-`iRJbt~~dDE?dWJ0~prk^lYo-+%U4=l_`b zyw2I@wYjH`?Az|Q?#IW1@5q0Y0oVt!xeBooS-*{ayIo(cy6#jwAKRp?&3Zjo)<)QB*n_McqkOWjD~J3g zvj0z!?RbFrpQC;`Q+;(n{I|sagk~T9#XY4z@~^!>Ml}C7=e+85&VOW|b-=OPvH2-w zy1$HnWB_qIO*SB5Fuicnm)cy3KSjzfY75Clt;mCrI z%l^(t&iQ&9tM2wUkM-yBw!xmmKNRmz$nL*Y`64UC|4|zATd1++9Wj&R|{KtRXQ3gc* z$thyo7XHcg%XPomcg(NTcwe`6f0f@q*8RBZdfo6__1(?ky!pphqYvO8%Fc)V8^!*) zdVPp;M|M`<*;@Q>A^!Um18AyGPI&Hpg9jXNKtrWpWj6e4{m+w^E?qjV`akj?*=J0i zI9#s#vHf8`=ihPwn;*Ro_b+|vONUE4Ip7!|@jv({hKud*b$-fneWLCs{_Anzk=p%b z`F=22#nx|r^P6H*6z(VgyN^8bNKsY%*{a_$SheB&AxSijQN-8ezQ;g#y7q(>HEmOkIQ60)cx?! z_+aF}o$ZhAkA6S#e)HdJ%+LBI)@H*DQN!79fBV}BQL31)I?w(4H%+#hI6pbP%ncz| zRQl(K>LnUM<~!rE)}$mn_&*w!l`Zr|I>iWgl6feLpGv zDzmHj$6lvY@!acq^PjUH`Gkk7e0-hrZ@VA%(fxns}AC#Yu&7Z5(N%cDC|788sK42e3|3^RF%=XH9{&`=s9s5!DOc zK_27F5eq^upo7#8ua^ElQLvBE`u6vu%@6x=%n#jf*2(vwsQpuoO~C%)?fAFu z&)LWBx9*33<^#b$^4_*Txqcq^%j5po{!#ajcD&Di|K`BIe`BtDH}&gyU-)M{W7dHo zFGP0cccl9-Q~z6{{pL-+U5dMk%#e6^W&m13$b-&ri?}vS2eqP%r&-06U zzGdTm=$g%ue|X!}%*VfP{?Y$G{n<~`^M-$M&z!S6RG+VYxWCw+J(c)B=%9ldD*Y<6 z&Hv$tAO2DFf6l#MkHiM(hW*^{S33{ud~@%b&%(6xeR8|MO!r&w!#;jL>?1?qpEW@2 z`$yZ~y5IBss^<8Zf9Lt-wm&+h9sllsn_C?j+|d~E*6e$@Tuom%ZbtpE8Ay50VLS#8~q-nY*m z?SA;@cSQbUzAt`%neIpb=f1z={nr1)k7Mi)_N(}(&uwnpm;K&N&Ap?0u zbgR~fKSOmIs3dW)BWUM5Qo7RqvkdI zqt`71%4*)X&u@Pp?(O&czTp)ej{bMtzsmN9TjT)p?3{DXDb70Utm488FHCaaxzBxW zLEc1Ou%%w|l9!}dC31-Q2FM(2Bh3*_`3J2jsHA zuSY5qF1!5FVqkD!n0?EE!;W5BJS;mPUYEAUr(;ft*k7eRVa||^w@_=u4yjBT```Ni zDNlLIY}x(E{vR#>uwTY@r*mbxAJ*YM7GwbN1o*C!0e&y{_su^x3jDK=i21kgAJ_Gc zw!d{hZ1TNx&pkJlOD?&j_=7+AgJcKf>=Q?&U>{Ik^r9CPFMjchOLG>mTP&xTlfZpx z?U=NlEb@jNbn=wgtAx3V+%LWcV-Um}krBiaHU}9IS?%_iy*V#=_9eyO;NY+fn6>4s z;$<)Y-|Ml@_3STv<*Q%823VzBfaMwwSSUF#q%vjr7xxX7{xbgQ@dTC+3kDfQ@dHuo{zA&->M}PE3$ri}RD|pSAMf6>wO%s0~zss=;>+TbGwvUK#++m11hKBEA}6}#KYotbJ~rRCzw_-4*f;;Q6SkN>yGrf2 zT=Bq#vd@N8rVRhq|Iz=q{?EB@_nI6!*3imxb$LyJZHnarGQov&yyx#a)^FW!_FW?b z=pR?Tkl)n{jKs*DvMot4`n2t$ICZ8kn zJ=$YrBQXH_gt%X&_E|1pV3F*uA(bh~zsLWH{}b10$9sGa7Ff5#@p_Nh@tVRozU4r> zI*#`f=R^0K`B)5G7+DH*aTx5_BkelJ<+XPAl875gzco?y-Ie#a*gjSQW;X2GW^H!|Cs;(tY70Nd^4fZy+=`;i045bg`cEdwGyoP(Fx&vW*%-}ya^ z{lh=~+x$D{$GRW>;huOLh4XyJ_P+IfWZq+vWvrX`c+cFgd5!lymdC!n>t3#nzd@T* zkbUHFlh=XVC$@`C##kBSpv25*OX8%AqcO%Y5q*w!vH<>(XT*V}?^j9gE!TM9BKZMB zDpQ94kpH`-=Kt<_;)y4o#QeXr&px{?|LAv{X`woPE&#rJES zJ`x^#VRt+~>)+toa)P$SmSBE1F(KlY_;?=YAU1)|L0e;6F&4V1e2y|XVE(y3$+K1R z1D5N47fA*TsZ1IE!~9?P-~EIWPB>omhoAY(XQpv{^R{@1Sm)2Di-xL+XtpQd#HZ_+w|>A6Ps&5YORg-2q| z6mncBQ4YXxtS!gM`Yf|^uO45`JDTkYs)kDJ@`kL!+#w2 zgMZkk5c`Y#b1tqsVjDm5p4;}3`TQQMc+dIq>#EPk^ZsnFb-cz%kK^BTyN|TyIZ@Cz zv^hBw_?yIz=_AqSKz@(Z=g4J1)c^ALSIM7QuH3CfQz;{@<(-t#)wrFow- z`<7!|i{C@P!f%Ct>;6vs-?jnBU7n7@f0LpG3yO?d;` z`9aRY4K^4$I`SXw|6KRCV?Vx^%K>8jBln&7kNwN{9`(L;Kl+04F6Qw>{)zFy zxySt@|HuUAA0Urx+vojmDl#9r8_(nT{Ni!h-^|;+o7dd1lY0P(|K^cL9yy@- ze_Jc3eV_BsKmT+c->y34xWJp`Cmdm8;RB%Ot@rKwNA{!5-)ZdMa)3B7V@j;+jeQPZ z=Dn;ogMRMx5%-xY_O1IP|JZuD?uUQI{^%>@&r#qX9a6^qXqk`SpXkRqi<|0x{oH%4 z8H4DSf5jG(|1Y~?NM*{z|FHl0$2j1z#~#}{_0&_RpLyn)bCuh^WW|aVXUZ1%fN}wT z|D5MMCyjRz=Y~OSTWn|S0C=TfqazdW4d9npE`@Oda?V`v%lIC}$LM(0^FtTIJkPR> z^|Et0|7PE@i(K!Uee&zk1H_)u|MvZ(?l=El*Bkyh$Cy^$-{}826TTPM`TM-C;wHcT zM0s6xzulbAe?vFl@n`byj`lTkDI5o=^8e`*8t-2P{~Cu_G*$UW21wsGW%KthU%q@u zbKB;L`^A@CcG*c6UwrXjOBURz`hWELQO$LEOnI-5DaZXWje$R={Fld7r=pyg$CVfN zxZZzUzQf~^8;|Qdk1J39aee>si!Qq8am5uLN2Z*2-g#?O3Y|}~h4J%z+`NqU{2ct- z*M=vvhObw~KJo?j(fy455z9jtkk=Ree%t=&|Hwc3-}?*G2kD>Y+J8H*{eG<7uc=4d zm+S98Ij^&qb{Gl&k^w_1Q%?WG{~2eTL1~Hq0qOmjVsv}WaoJtGFL~bco_Dm^ex}B} z&laZ_$QQp*eR+i#TOpoSh^JI!6QtLQ6RZ$>D`bDKkRD#aXZ36@7Q26-Jh>N(`>Qm@ z@FSJgT64HS4lrjX%7B<3Yq=25Sq{LzpS!uU-H)!1#q3-6!#}=!75~ori}pWq0pG+d z`)`)j{*3F$d>Qx1vAT?X8@PYOnlSV(I*Yl=rekV_-|f;S$M%REy7aP8=^0=S!3uw?v;^ zBDR;vE;v~Bz*5-~PnUc-U%3YVaPYwg|5)=4){t+Y^C_nWA0zUfADesE_~ATPc!ELO z{f;_ta&4+kkdw&6iI6V-Lc=#)g+~ z4*Vkn_$U9rA^uyk0s6%ya$u%xf!VU>>wL|2ig5QO0Mj5+G(eeXL!gl#~gFsA%`4tlja^idel)z6*`~h)8sZl zJN_9H;90^ytigYo-Ji3M-|zfXVtK6f8f}00hy61C$ycq?|7F}qox^d?e9k)dOkKvm z4Z7uD`M#SS|HuHv{*eJq$$*w*K%W>M5X;kK3k=E@7?cbc6zhYM1F3M#Io{(l`s|>- zgX|d8HMWqAzlCCp)1~XT)L6p;%`aqv4k-fd2R2E~_K+k#!$O=5yBb-&wzYa-FBKZU^}H_@Dj#TpnN( zM*igk45>`X_#eEF_dn$tGS=9~egoovKk@)y!N8P@+*&m4YW%LAK^*M8_udWZ zci8V2_cNvE=P3SvkjDMbmkn^e_+PEDg7l1dE@lK7ZI)c;>_^=nbA7D)+p&-BZ~j@^ z%DNx^&A!L|BmbO3X84}++T7cA@$bob=eL@7_fOUks>|rx!0RrS)vVh<8+XG$KB02{ zlK$5m;6*k6J%F!|vc9lleM#?YjBkeY{T#*lmnhfpY{mYsl25Q&@xoH}t@o{GZSTiA z#{3=ki@M+be$@Ne{pfydf5!e;cOvp1ZU1ihH}lky`<(eI-rY~>n{^r6Heh|WywJv- z{C{i%d_wrw+>qrp|GlxlaN$DuC*I$$vHqFT`E#W657HcivlaKdPX54ZjTv-gKk^=r zvHRhln7?&@jQN>;?0wt(k$rSOdHnFtdiv=9sQc~v=k~w#zd4U})b-J>w|=L#eviz@ z{>i#xbs66_puM~0Uparn{7VK5snqs=2T`zS(W1t_`|jHm=l$~YXNmoJ()kB#{O@dR ze*Asq3nlv(9cgaN5;iq@Kk^=r&Awy)x$d{!Z@mxyX5V%{x*z^oPmnb$^D%!o_qadt zf5-pI_~-ul9c9d$cj_|c%{uwdF0@TuM&1T)$Eun(@0EYe0a{e^-vNBRExsG#zNs32 zf7bEGA3sm)3OrTpUm)(^BYR+YzE7|0+uuj;=enP9Kl}YL)|a!7-H+~vf5!fqdsxOl z?8k9`^Upc_e`HnU9^2k}-pohdu{o{hBlG5*u@4vJRBW)1SbeVhHgP*v)yRcz_{Szh z|7#xLa`;ynQmOTS8!@0Uy{3G9Y<{zUh~^btAYcD3`TxT?{$=dj=a0IcW4O1@H~YEn zx9xA;Z@V8~pMu_x?4$ePpEU)w#!J%wG42<2f7Jh+$7kUFqd(t{`N%tc59ZxB%{9Id zMLAS;8K*XI8`JhR|7{>1;ak%C4e9)rbpCY3`Q}RRoBg|)i%f+n|=HJ@K5d!>kzM}lUpxo5d*1httIY71kZzC79epo}LC4YaKSl>o#i0?1Gf40W{KL`8hN9%ku@7nCg z@x3bcZTBj);0faU>?C+n$wfk5R=_MB)z|@<`EyKb8nG7kXXst zhk0{f7VERF&ujEP>^tTM`?mdKeqXftt@|VUFpM1!|H|=B{G<1y?l=Fe8JqJD`%%Z+ zuD5NEo{#o?&O7?u%)8IBr)XU+N%KH7cVt{@%|}UX%>2JR|0llY82?{6zsdiv^?$Wc z5c3V`eRThHtsOd7y8jT(=e=BGe2?I35hu%aJESA#y#v? z_s3ixbU*Byf7|@l`;mQO|Ey7}9Is^e=lVbT{y+cu&kG8%K&}PzRlJw!conezaSlJNjDdg*DZtTd3?N9d@Q-eqY1>?S=h3-k-<# ztnXbr<_G%}#`~@Nt89MQC*}wH=AX67mE%zw_bcNce}L4Ow_SNo-+_0bB7WN2ye`%|H=`i0i_D;vq?{{vGSud-Z=VSJX`?H=$|3`-d%m5X z&vm`Icc0goX;GKn+CZ_UqSr!ucf&t9VUGXR`oCH#ux7aI-kD;5Kl%NyU`>DG{pPz< zJs$ky^H=%(*#41!&FfD3zZd>T!hSpc&3&i7?9Wa1y3_9*?fb-^stVVx`LE`=*LO6x zk99t0$tONQ@&A8BzK+KCA8Y+j%s<-xHUGWo*zu4xqvgAs@7MhIN^BDBtC%sg~?QphYaa-%_dwaj3oZ&vA^+({~-g~#s3`hCl)|){4bCDdt5)p{Hx@^REXoT@&;5Nn{>m~oE=6^%(eMakhHZ;Gt zr9M5Re!p1j`z8LF^V3bfe=Zkd4xsY@um!4e0m%bE26*mY+1ww?0r<~jf#m=9lK;!t zAa;dw{+Z9~xqUI`-!cJNkjsPUFXXa-_<{X}x^ABj?O02@I<}$PmNxH3|Ht)zYW;8G z*RNUQS8IK+$JdZ_-eS!GxRSUG{C7L&C(3}_59l=aFXjT+25=sb?Erj%Tn0E7U^Mf8 znA_NC4v=jGYy;Z|(Kd*(AjSx$zs3TuB<>pL z{dql4<^WN!3v3&d%?pZtK(q(qd?5P()VU21=Kw|-5aR(J4`lu?^Z!}*!}EVU4v_l* z_yL^5hG4yqviZN32eu13*#=P-#N1)ag}NTud|y@0a*j zyDrvP;ClS$^ZtyfVq=C*ST#{L&Fx10E1^#AMif6FBV`+90!U-tJNlAV?K*BHQh>wL!benLO}1 zpmqJ^dZ?pq2ghYy)8;w<`P_eAv;R-M{&zX|KFglo+S9M4vDG2Psun92c%{YwHrU$( z8BkR$2deA<{DNE-cx=EnfPH{C7SK)xcy0h=fFoW1n>mi%uKQoMRv>nPZG&7M*k`Eg zv0D!v?kU)1z3|WeU+DjO{|{5YuGXI34XyvzQhr9_U$MZ%KkH+|hu8hAVn3co4p;`n zSU^0EaRFpNoG0l0KgbF4cwm(bunoXmfU5mJi1jhv=XHRX`)B)~d-c8ZJA07@whdy; zAo>cH3w6D2Pn6NN1?}thMi%$Vzu2$&Ux)qhk@opYYkw+_eMn<~ixmsJQe%L_d*PrT zb2)%asFDkC<(OdPJ|0II5c34>10V;Y9}s1L;{nbO^!{J?dS!b6U!+<0;O#!w0ST5Ywmx&|L+FmKY4<^KH2j}b1M@68Vk5mIRL|b z+%lkDZTVn+;K_b~i*bsHrNqcyoHrMpSPW(Um=%WSvYi;;d=3i?84XM=p z2mbfod+(0?`~S$bI(1A|FRfB&Od$uHUsvE z^B7%M$pXs(YTG!}(NC~XWc#45pY)r?qaA4XZuo!j!3W6=U8UUr<>G!(&3^!Y?crW~ z?bXm)|1IVG4=D#=vBmt-0@}wrqd{#{(ia=u`6rZ?*%fY=Gzol-U7ZE1Xy! z{3Gk(KiUA!2afT7_(x{=?^7cSa(Uo;bzNo`RLKL&g}Qz+PCQoaVA)H%ck=(y|2hB4 z1sGDP^?wipd+xbsL+kwx^RKbM#6LdPSjYgLS(zM&G9bnQ;=BOse`?PY_PC()13U4L z4Dc8Laljw^;0GJ@lg{4;Ky%K*!QytZtJvH%(2m{^PnU<+8D z^BiphI1ZSP1t1HmWB@h*V}Ox=+W=Mk6CZ$oGw=Bbe(kzS7UZ@8_is5+*Xv~BShhtj zN4Pfg|2pY^?faSHf6Dz`F28?K?f-8m4R+mi*Tlc({0zarasjT?9DtN->3oZB|O%>fwBwT?2N>Nwg1Wir6=0PKJ~77%R!Ggvl1*mi(rfa3tH4e+_oeJ=4&yx080 zc@_WB{`cRksx1Rt_bLm^>91HhO$^qPUz z|E}!|*ajdE2>yB2@NXL+jswQ^fH+Ug!2JoH&9?t`RqfBYZYK+T{ks0^;kF*jw&<3B z%?(|pxj)OL_ZQXre?tMVV8Mc6{*?o~Sh)aKvj1N%b2g%U=tc&_m>{u$G8@3Lz&JlJ zmjT!SR7ddpHE(ogn#7% z4yn}ke-H!n=g)6w4e*xc{0+gsashhg-?9Q*z`j8A1AJUIE&%^kHb6TWfFFPjKpqhM zE5|eOAAJDxALIXw4-hl7FPZl%_uI&Kl^lqliO0T1U5}qEShZ?ZSN4C@|26*s{I!Sh zuQk9E|C$4k_}3huw5~;*b8W`k)wTn=l>sppfDK?4BX5ocO={7UoBnhm3o0eLJS+5vG)&^7=Z@_gaWj8Rv~0BivG|IBATQz*x~Z43Yz zKp{Rz%rK5YA`5H}l*t3j0qXJU*Y$O~lO28*-SCf3SnL1xQUU(82S6+GuQ`B8|L1GA zAPXp#3x1v31da)o#R4n?91pY&5Pbk-06cV(0oVZK0DSt>pHBQc1`vG!=K)0ii5Xb_ zSoYW+aBX>z+Xn7`v98(ej@{9=6K&qD{{QW7f16@LHUI7T-)X0v691a>JFNe!_|N4* ze4X0~F&0o|2Ot9+3xq@1^Yf*S{B!JhK+Fvw2jGr7?il7DAHcZ)&IL64)Qk^cGa!eY zpAd7BkV6#90qQDQz&%DeP#=%2zaQH(_6v?b{_&5u_5W-B+jH-CbN-bJeC0^^w@qMM zAddx<$$-co4CXcf&p(#|_60l^KrS%+E5{?n02l|1{5uc8G64RO8IDo-9xR8VEU;~0 zd0;tE<|D-Z8T)O0JaU;3+cZD^*vCHB6aR|+Evn;xrhZ*Lmi!|F%s+MX1I(N4f7fL; zfa3r>^V|d<#{u#6%lJoTIFEt*;$G~J*e|eO;y8ir0?UFj zyCB|o-e2q2W0MD9f2>>nwKnW3t@*PY{i!GQj%RdN;QL%4C530BivG|Kuk>St!S210TS-fH4L@Y=H0BU$LKJ ze}MbxBnxu8ph_0Fuh#XG>nn_;9irUi`}WIjz4g|P`kyi3`|i6h@h|Rc{sZ?uH2+%j zW6bzBTb2X49gzD1oooR5K<*3J2FUs6nL7qx{+$Pa55Rlm4X|E6#deDA6W<$hpiCB& z`3bfS+&7~K>9Iq(5N6UfSE@&qUEEDQ_-P)?7X$$%VHX?0K$@%x3fAap33%~izZ<0M| z{>6RGf8gGSOSe=Y;eRGAIHbGIE`B?E{9ur?TLLBM|=12F&C z0LTCe{4;*YzP#)!X&J!2Qpf?{cPUwl*0GfB#v^nKNANtUG{G;>D zK6TB1fV|D&oH=t+{BJD%e=|g##{z6;+uzPv%58u$84zOu*z(K;myA#RdmIouAO7tF zAOk4m2w^v9ufw#jyk!7;RN5!7EU-NAZz!`1EW4sCz)zUW#jH)Fn)alP-Cy7z#%=eP z@lRi<^?w`q_11Xv-$@3P*#N!B0CE7$e;xyXe~Q_sCO*g*qV_r{wBJ#Z0oVfUEp4Bm zlPrkxz_E<{cUVuwKI^_a5$kxr6Yh8;%v;0HgL_(#{ne$9V-&a2*q|AP)Xs1^0U z)&L&1gQG4V&9RxWKVW+re*A3dcaE{y_j4?u%npF#$iIC6Y}3TwWc#MBN51zDGS!84q@Ar#KJbALbj82chF_(5 z|I6j~*ZzNr5ZGA!`?;BaGsAPubtiUbv;iCo$YlV20I@vgg6J6!#{ldDnE&Vlp#Qm^ z<~kLc@0jF();%7U11nan=qL+vKf%8(mvR2B6ScNKGtq0>kG91hBVLOPe*gR5Kg_>v zfZYG5A4L9@3pAus$Nz#H*qHpoNn|1F%PJcn+5zxSArHjkf#zTNT`2}&9{|p61HeDI z02Iz6TiD}-ea?^rTK6Co+XVOq+6y`P2G|9T6-K*&xM7u_;J5+5w=Sb=1KN@T^T=J= zoYF1-ci(+?(*NRqQO$nTx>^R!VwgGY!~x8|^1FulcMPD)2Vfi!J3ukvlt+5)wb!OK z0m&uCH$e7qZ!pam0s7yu0s92z-?iff@N8ZgPvAV`j1-Ptupc@V_jQj=aJ^V^c@p3A zasHXf_L}zOp7}krm)r6^?|IJ#{A2T@_bI>n)vuEN*WPfo{%<1{;`-mxb7}oQ*8lFr z?pVCx7h!W{lDV=AK1iW!FQ)?j0OMX^1)@~A0L2c zkNzj#ZyzA??>Pa?35@FlvqvcV1pnkGKS|}MKmBR(v!DGem7o9o=fy96@rzVA<~*Ne zeR1a&%im1-NW>W4`qsA=>`%a)1!5W4I_NQT2%nLEY>P5`qs-?p+kBtz!A100IHusc z*mmLC6h802<#Vq69<}9BJm+J-H{P}Xo_`-c8|C`zuTOeD#{FPF@=rc^&3}9T_uhN& zwEwr-H0}Sz{=dY-INYuF>Z-uAY)r8P)JvV}Qi}VBxB(t|HHC zn1A$t75^Rwg#RiT5aj@VK$#C_2J8*CreL1JDk?ZF-g ztcU)WU<`^f91dMDQvT7iwgKWkVYUNu{;>z5A5g}B?1%Yrx15jmbNpTI&2oY`2eJ>@$a;ya zpMl+koM7AoTML;?9Fymt+Y{z6ug$kPjy1fKX9=?|uuFW2!h78ozDLfM{L_N`G-50K z#@J4=t@-WPfi?dD_L4*G{o7F6n*Rg!%wC0_i0qnI>uhSy#S%Z??%3C=8uyEO-@bmV zo&U$&ALjnDmOr^*#OPxVK$ZR{21sn*x0i13pZCYuH+>xY zXg8nt_r|N{9{3%W6U0JjBYbD}RbZVxVr_4D!yD3G3)o!vYvdXcGsISm%*SK+hkNp@ zoNGnC6~*$PtoCQ9ou>)&+MBkJzA6;2F5dE%w`{;aZRGZ?`7eRJ`H-`u z{}0gf`$uHI8HQK0ij8hx9lg!@SfYIJag-69^R@WCZT?*6!+Y6UQLs?h6@VdxCaB zRw6@b-@ER*E9GF3lS5t=&jmTbGe%BeGhn-;>(Tq@a!SrVyjxaKlZOWPM;&!kp?zr! z?NeDCc;JDlX8tetl>Z*LVa=mchV%yJ%v zT`U{&nrrwRpXIw;3&t5kr>}TEkJrmbzcX&;*Ix63@qY9^eT;p)h@G?lXB_{l(*3#b zZ{3e=Y~63)KiB=X`>S++SzpZiW;d_he>ZmB?%vElzp2ei_BnfO|6Jb)bFRijfVAh-}RW5^IF<{ zmiMY;MHMS%rmW7tv#DNlZ^(%%*~@*!`}gab{{VTLL+O0@pQbWbGT^(AvG6|EN0z`oF>J2SbM}0{vRt1S>x=%rxzBC>81wHG^P{g->3*}@iP?$pel9os zyL_J4@tj{zl)C1>4d5N#66+0>ewD4o|Nfe9vRpC1FSF(XHapyT! z;?yvYZ6E!4Z2DMW-MpjcvF}|R=X0FjzJ84L)4%e*o^x;BV@_(jV}CxcCxSf4@2S)4 z{GKg0%IdrwNBcTwpX+hXCTGBF4ekAmuUX=7ZtN#jSXNKfc|$3kNr2W*WncVex&@vICcQnp+?8U zJMw{XCFav`efIi5-=o8=ug!8~IQE77*nP|WF80ybm&=Z0zwhSQ+?XNP-nS~R{eD@U z|Gl#Nt2!5dW4Fg{A8NkC-!HqbvUB;p^1AHa+TBb1`|;S%FMqD_HSz)5ll&j)p5@|x zp?uOIm74!@{u|=ICH+55Ibd6A?WzTe{~s*&PgVU|jRSl|G1!L{2lzcc05$;nAO7*t zVHQRi-}(IKKR+Ck;~5aIB|ncmc62}b8{LmChjHQo=yw-h^B$kUrXYrh-@rICV|Cc= zW$g3JV;{(m={N4n?u+izIfql_bvJCfEqbZVciHtvbI#W-tMmIqcJMs&=gez#0e0u- zKKHp*vPaKQ-&v?Kq*C)=!at|Pe?xOqTUu*nK)(Nw#{cKa{@+J2z$3-}8H)K|D*pdc z{J%yvz=!1f->3a|9+LilT=x1JbTzzUHe1Z9}xdD#s9V%&tIT1z=iSw4pJO&sn|bC zy8n2w{|t@YovAq8h4R(^LJYr2?A{{2zpnDI7=8kq0N!ER`X1XJJKwfGdLQ5k6Eh^+Mb zKjR75apZ-VfBXLS`>p@m$pG8_?lU$2zngHfuNS$&^FxOCdFC>JTu-r%Kl(1&pT{e1 zw3}qXOqH7d4*c`BVt)(L4FUpKF;MqCSVI-`=k3K|HKU7pO_!< ze&o7i{<#m($qvYE0Q%47tf!~SZ%1w*2ao~y0q6n7o!A#f{pS^$?|6jdzv8-z{%4z@N*34-ps!em z)PBIkvjuvUO~`WF0QiUajItpgkq>abbpK-6lH0344XQNT_3iq-?pr`SH^gjH{5Qpa zOZ@kV_kM9dpfXLeU<>g)Q|xagJ7Fi~@9r<3;W*_CT&h^&dz4%Bb8?HxEo3~AJa2OR z82cv{K>QCMfV=_neDDFva`*GRo^ItqEej?;_m&g30nq>0iujF+9e?J|JMTPE$Ghuz zOUZ))m74$V5%2nw((w)P-w^)|vEP&*@c*}WZn0HdR~Vj|bB=v{!vE_Q0^M>KtKF3sCj|*|0_?ZxIps*a*Sb~K<``o0=3UTYd+d{;J!a_F@tgk z;)VFP{_+)-e2^3y#Nz_x3@k1fKYSo=mfsil?b^ z6N)9o6Pj0uBa~khH)xNc@`;WU+#VCh2bMp)zdRuO>s=_{r|&{I6r) z-^u%KL^Ax1sL>tBcDFmW0DoH~Tw5gO7Z2pXe;$9|z&c|Ke^;cPdBF_k2y=)R7LYes z0>+nv_qE`^hZtZBdj_5&=eV1F1J8i*FR_pC5Oahh#01C4J-meO`&|DK`G_|;Kg0QN z(SN}4BF8I~`G~UD;DrI!8V86A2i-nH<&DG-iY3@L68&9KafJMf;|RqOE`AV4h#TaG zj1$I&6J%%ET<<~iLA@{h{NLd9ufqcyd52x#z6IRZzzMeIcgJYGcNM|E2mXCx07(E3 zWZ?nrH>%TqBi0BevQDU+VYt_bc%T#iKZktcJmP`*tUoM-6Bgs|m%<4vm>aAH3-@!hGQcV#Hp2#_L@B9`lG_pg+a= zX|DYVKXRTib&<0Fp=>`nhynJM-q81q?(dC?8?@f+@)266P%a`q-*9^t6-&rxRjxm3 zPGR$kTjLJdPMoV;aA}Y4e|cYTbAEt#w3hQO-lMQz3$F)?{qNl2*1CDoFLcqLpb1ci!n6!b>jFV>FCzTJ_|?nPj(UKlIOocjP`rp(~GPR zZRPzv%KPl#-A;hhYvuQ~-iM6F5Vd=Zfdv#3l=d9@;NJ)T0r(HVe@1Hv;6DTYGvGf9 z{-kx6hu z8!`=_Ka;W51vkut8y3I|i{XXG8E31&?>g}O1lZjQcAsJ_?gqd6n1dc5kMJz>gu`I@ z1>_h$>LsqfO1U3U{tfE?oN@au_dUxv{Uh@sQjV+sGrz=kauwbo4$%o zzkn^)fc9ME=P>$$sWH;)?-% zT)1CSYa#S8%3;vvFhcS7sA$Xil<#=Pl;B%iy2Yv|$6X8QIS7UC2Ik2arRI z^&^x$#`!nE{Yg0M$H-fppQZi39$xa4m~2OSvp{vyAH;&(PeY9{y>< zpSQqCt@!qKqyw4B?=CoMF1q>f)I$9I659GWG0jS1mbKu01MPi+_HN-`JHYl%;*~wL z_Ze`#pLpdU@ya2d_dM-9N-Xd)eR!QdoIrj;pHA`nH03^^{5j4qaQza;YaIKjJ3wCt z#SMxh=x^wY#S`>n*xz1td$8oM-8!oFShzWfVhs6niQ^5O>$=M5+b(eq?F{#FVEb$I z0ks@&6<^p%p%8gA3Z>jH&QI2ltwe-E(S|WnS(3`SF4c?$Y%IyJF*Me3uhfbp2O!p59WH2 z?^5q1JaCHpoI%dQ4d=xb$Q3a7De*)<&mF)Q4=Toxa301QTn{k~--PR`)Cpq_cqWWN zqzCWHbzDdOPTjY8)={3j9a)adrR`I|eiMDErB500F>>3sw+d!~@nQk+?y;A_FG;{} z@j(FoGvGhtzN-TNS@53)|2goV1OGMPUwhk>>sH<(5B~GuKM!{5z*8OguLuA2U?rTd zfY}Bx)CiWs`3lDtez$_DDd?snoyc5%&qo%adkm4!U4v`{|C^ER$WCN0vY+b*DRUS( zN}U&}|1w-~lIOpHPkxiOokq?g@6+}_lb5+jUoJ^FzeJxda{U}J(0jE1XK=_XaKb^_ zy$xB0bkqKJxTXm{sOA0{@E=gdus>b~v9)7VEdc(*JSO;$zN-Q+9$4|fiXY2a_~73M zTblR!;3u53fPWwS`QYCNKR)>J!Hf@fLIFoU{x?9E(HsP+Me6XSja-`mwkA@il`_KJ zH0n;L&Mag$(#?J5A@ez3h%83Glyb|EmDE{-tf&4)WE1ivvJKgRJdNx^b|ZUAqTf&R zOs(Pd(2iAbz@ulaJCJ~NNe1kPqH_s4Nf!KPsS^pf&LX*65%8Y_|MKx!aS`nbz<-$22mhX7 z|DFy5ySZ6lR4o7xc;Nn)1^jyw`)3v~3z!AW0%ifTfLXvSU=}b7m<7xNW&yK+S->n{ z7BCB#1n{7BCB#1AjQ^g-G9=c#FPBpWMjaNY6>a9pY-Q^QHoW!}OkayrM*@`%$S%Q@id* z1uAY(?tWCFGyaG|bU8X1*3Z7^a`_})ptpRvd=_hD`C|MmYC&c9ONF9NRCd3lkGgPE z_lpIhSDDa#m5B6(V)@Gd*187vRceaABMbCa(I=~;@t)HCNT1UE2yiLgkMt?skMxC< z_PH0>S4H1jMW3Q}&rj>V)2DUc>C?LJ^l9C9`a+fV^;OaLR?(-aOV3a3eo3F&{gOVl z`z3v9_e=UhmG<>j(f3x-r>cw3Pw#$FpWgkVKE3<5rcXCdvHsoa3sw4GP2X3gzUfm9 z6!O;y_6hlW9P2~>GeY}9|8*Do(0`6lznZ>B{&9r*$4Ax|-Aj7?qI*r(7u|EZzEh7M zp?y77^vCZ~A68F)e#yJ0w%_z4+y5c4Pr*z1SL%PNf4W6|s{bt2PxZeg{ZLBtir$k~ z*qc(o)h|@h4-F+Z!POrcO722gpKPMCKDh;DeP3b=%lh6b`b2ePpP`fpD7t@g_sjLG z>66VjsbebOt4vg6cGGC`DG z7Y!%ef0(}S<^sd?3Gb*=_jUgg8qni(rDNqSD%6!mh?&=w9M;Bo_g#T_wxP3pF?Loq kWKZmB?9_E6;qk6iXsh_!af;G0?C3D-RTQwFpBW4MAGqS=ZU6uP literal 0 HcmV?d00001 diff --git a/src/Makefile.mingw b/src/Makefile.mingw index a91fe441d..6c58d172a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -9,7 +9,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ + mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 277ffadcb..d9df84dbb 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -9,7 +9,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o rom.o rtc.o \ + mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ diff --git a/src/cpu.c b/src/cpu.c index af49feb4d..5172c4727 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -228,6 +228,17 @@ CPU cpus_ps1_m2011[] = {"", -1, 0, 0, 0, 0} }; +CPU cpus_ps2_m30_286[] = +{ + /*286*/ + {"286/10", CPU_286, 2, 10000000, 1, 0, 0, 0, 0, 0, 2,2,2,2}, + {"286/12", CPU_286, 3, 12000000, 1, 0, 0, 0, 0, 0, 3,3,3,3}, + {"286/16", CPU_286, 4, 16000000, 1, 0, 0, 0, 0, 0, 3,3,3,3}, + {"286/20", CPU_286, 5, 20000000, 1, 0, 0, 0, 0, 0, 4,4,4,4}, + {"286/25", CPU_286, 6, 25000000, 1, 0, 0, 0, 0, 0, 4,4,4,4}, + {"", -1, 0, 0, 0, 0} +}; + CPU cpus_i386SX[] = { /*i386SX*/ diff --git a/src/cpu.h b/src/cpu.h index a1775ecac..1159caefc 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -110,6 +110,7 @@ extern CPU cpus_pcjr[]; extern CPU cpus_pc1512[]; extern CPU cpus_ibmat[]; extern CPU cpus_ps1_m2011[]; +extern CPU cpus_ps2_m30_286[]; extern CPU cpus_acer[]; extern int cpu_iscyrix; diff --git a/src/ibm.h b/src/ibm.h index e88b108d3..d68e9ede6 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -397,6 +397,8 @@ enum ROM_AMI386DX_OPTI495, ROM_MR386DX_OPTI495, + ROM_IBMPS2_M30_286, + ROM_DTK486, /*DTK PKM-0038S E-2 / SiS 471 / Award BIOS / SiS 85C471*/ ROM_VLI486SV2G, /*ASUS VL/I-486SV2G / SiS 471 / Award BIOS / SiS 85C471*/ ROM_R418, /*Rise Computer R418 / SiS 496/497 / Award BIOS / SMC FDC37C665*/ @@ -627,3 +629,4 @@ uint8_t trc_read(uint16_t port, void *priv); void trc_write(uint16_t port, uint8_t val, void *priv); void trc_init(); +extern int enable_xtide; diff --git a/src/mem.c b/src/mem.c index def1e8c71..c1e6a101b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -48,6 +48,8 @@ static mem_mapping_t romext_mapping; int shadowbios,shadowbios_write; +int enable_xtide = 0; + static unsigned char isram[0x10000]; static uint8_t ff_array[0x1000]; @@ -132,7 +134,10 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } loadfont("roms/pc1512/40078.ic127", 2); return 1; case ROM_PC1640: @@ -149,7 +154,10 @@ int loadbios() f=romfopen("roms/pc1640/40100","rb"); if (!f) break; fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_PC200: f=romfopen("roms/pc200/pc20v2.1","rb"); @@ -162,7 +170,10 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } loadfont("roms/pc200/40109.bin", 1); return 1; case ROM_TANDY: @@ -170,7 +181,10 @@ int loadbios() if (!f) break; fread(rom,65536,1,f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_TANDY1000HX: f = romfopen("roms/tandy1000hx/v020000.u12", "rb"); @@ -178,7 +192,10 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_TANDY1000SL2: f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); @@ -193,7 +210,10 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; /* case ROM_IBMPCJR: f=fopen("pcjr/bios.rom","rb"); @@ -214,14 +234,20 @@ int loadbios() fread(rom + 0x8000, 0x8000, 1, ff); fclose(ff); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; } else { fread(rom,65536,1,f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; } break; @@ -238,14 +264,20 @@ int loadbios() if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_DTKXT: f=romfopen("roms/dtk/DTK_ERSO_2.42_2764.bin","rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_OLIM24: f = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); @@ -258,7 +290,10 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_PC2086: @@ -277,7 +312,10 @@ int loadbios() f = romfopen("roms/pc2086/40186.ic171", "rb"); if (!f) break; fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } biosmask = 0x3fff; return 1; @@ -289,7 +327,10 @@ int loadbios() f = romfopen("roms/pc3086/c000.bin", "rb"); if (!f) break; fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } biosmask = 0x3fff; return 1; @@ -398,7 +439,10 @@ int loadbios() fread(rom+0x8000,32768,1,f); fclose(f); // memset(romext,0x63,0x8000); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_IBMPC: @@ -423,7 +467,10 @@ int loadbios() if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_MEGAPC: @@ -573,7 +620,10 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_LTXT: @@ -581,7 +631,10 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_LXT3: @@ -589,7 +642,10 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_SPC4200P: /*Samsung SPC-4200P*/ @@ -624,7 +680,10 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } return 1; case ROM_JUKOPC: @@ -632,7 +691,18 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - mem_load_xtide_bios(); + if (enable_xtide) + { + mem_load_xtide_bios(); + } + return 1; + + case ROM_IBMPS2_M30_286: + f = romfopen("roms/ibmps2_m30_286/33f5381a.bin", "rb"); + fread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + mem_load_atide_bios(); return 1; case ROM_DTK486: diff --git a/src/model.c b/src/model.c index 0253cd97a..3e15c8018 100644 --- a/src/model.c +++ b/src/model.c @@ -55,6 +55,7 @@ #include "piix.h" #include "pit.h" #include "ps1.h" +#include "ps2.h" #include "scat.h" #include "serial.h" #include "sis496.h" @@ -84,6 +85,7 @@ void at_init(); void deskpro386_init(); void ps1_m2011_init(); void ps1_m2121_init(); +void ps2_m30_286_init(); void at_neat_init(); void at_scat_init(); void at_acer386sx_init(); @@ -152,6 +154,7 @@ MODEL models[] = {"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, {"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, {"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, @@ -379,6 +382,22 @@ void ps1_m2121_init() fdc_set_ps1(); } +void ps2_m30_286_init() +{ + AT = 1; + common_init(); + mem_add_bios(); + pit_set_out_func(1, pit_refresh_timer_at); + dma16_init(); + ide_init(); + keyboard_at_init(); + mouse_ps2_init(); + nvr_init(); + pic2_init(); + ps2board_init(); + fdc_set_dskchg_activelow(); +} + void at_neat_init() { at_init(); diff --git a/src/nvr.c b/src/nvr.c index 7e4e4223e..7c3844d5c 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -208,6 +208,8 @@ void loadnvr() case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "rb"); break; case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); /*nvrmask = 127; */break; case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; + case ROM_IBMPS2_M30_286: f = romfopen("nvr/ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; @@ -289,6 +291,8 @@ void savenvr() case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "wb"); break; case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "wb"); break; case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "wb"); break; + case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "wb"); break; + case ROM_IBMPS2_M30_286: f = romfopen("nvr/ibmps2_m30_286.nvr", "wb"); break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; diff --git a/src/pc.c b/src/pc.c index e0ab1e0db..42a764320 100644 --- a/src/pc.c +++ b/src/pc.c @@ -868,6 +868,8 @@ void loadconfig(char *fn) joystick_type = config_get_int(NULL, "joystick_type", 0); mouse_type = config_get_int(NULL, "mouse_type", 0); + enable_xtide = config_get_int(NULL, "enable_xtide", 1); + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { sprintf(s, "joystick_%i_nr", c); @@ -1050,6 +1052,8 @@ void saveconfig() config_set_int(NULL, "joystick_type", joystick_type); config_set_int(NULL, "mouse_type", mouse_type); + config_set_int(NULL, "enable_xtide", enable_xtide); + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { char s[80]; diff --git a/src/pc.rc b/src/pc.rc index 634a696d2..f22e897ae 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -380,11 +380,12 @@ BEGIN PUSHBUTTON "Configure", IDC_CONFIGUREMOD, 224, 16, 40, 14, WS_TABSTOP COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP - COMBOBOX IDC_COMBOCPUM,62,56,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOCPUM,62,56,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO3,62,76,102,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Dynamic Recompiler",IDC_CHECKDYNAREC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,76,99,10 + CONTROL "Enable XTIDE",IDC_CHECKXTIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,96,99,10 COMBOBOX IDC_COMBOWS, 62,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSPD,162,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOSPD,162,56,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOSND,62,116,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 116, 40, 14, WS_TABSTOP EDITTEXT IDC_MEMTEXT, 62, 136, 36, 14, ES_AUTOHSCROLL | ES_NUMBER @@ -416,7 +417,7 @@ BEGIN LTEXT "CPU type :",IDC_STATIC,15,56,34,10 LTEXT "CPU :",IDC_STATIC,15,76,34,10 LTEXT "Waitstates :",IDC_STATIC,15,96,40,10 - LTEXT "Vid.speed:",IDC_STATIC,125,96,34,10 + LTEXT "Vid.speed:",IDC_STATIC,125,56,34,10 LTEXT "Sound card :",IDC_STATIC,15,116,40,10 LTEXT "Network :",IDC_STATIC,125,136,34,10 COMBOBOX IDC_COMBONET,162,136,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -604,5 +605,10 @@ END 1 24 "86Box.manifest" +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON "86Box-RB.ico" +#else /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ 100 ICON "86Box.ico" +#endif diff --git a/src/ps2.c b/src/ps2.c new file mode 100644 index 000000000..0b6b08424 --- /dev/null +++ b/src/ps2.c @@ -0,0 +1,136 @@ +#include "ibm.h" +#include "mem.h" +#include "ps2.h" +#include "rom.h" +#include "lpt.h" + +static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; + +static struct +{ + uint8_t status, int_status; + uint8_t attention, ctrl; +} ps2_hd; + +uint8_t ps2_read(uint16_t port, void *p) +{ + uint8_t temp; + + switch (port) + { + case 0x91: + return 0; + case 0x92: + return ps2_92; + case 0x94: + return ps2_94; + case 0x102: + return ps2_102 | 8; + case 0x103: + return ps2_103; + case 0x104: + return ps2_104; + case 0x105: + return ps2_105; + case 0x190: + return ps2_190; + + case 0x322: + temp = ps2_hd.status; + break; + case 0x324: + temp = ps2_hd.int_status; + ps2_hd.int_status &= ~0x02; + break; + + default: + temp = 0xff; + break; + } + + return temp; +} + +void ps2_write(uint16_t port, uint8_t val, void *p) +{ + switch (port) + { + case 0x0092: + ps2_92 = val; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + case 0x94: + ps2_94 = val; + break; + case 0x102: + lpt1_remove(); + if (val & 0x04) + serial1_init(0x3f8, 4); + else + serial1_remove(); + if (val & 0x10) + { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps2_102 = val; + break; + case 0x103: + ps2_103 = val; + break; + case 0x104: + ps2_104 = val; + break; + case 0x105: + ps2_105 = val; + break; + case 0x190: + ps2_190 = val; + break; + + case 0x322: + ps2_hd.ctrl = val; + if (val & 0x80) + ps2_hd.status |= 0x02; + break; + case 0x324: + ps2_hd.attention = val & 0xf0; + if (ps2_hd.attention) + ps2_hd.status = 0x14; + break; + } +} + +void ps2board_init() +{ + io_sethandler(0x0091, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0094, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0102, 0x0004, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0190, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0320, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0322, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + io_sethandler(0x0324, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); + + ps2_190 = 0; + + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); + + serial1_remove(); + serial2_remove(); + + memset(&ps2_hd, 0, sizeof(ps2_hd)); +} diff --git a/src/ps2.h b/src/ps2.h new file mode 100644 index 000000000..92fb6e077 --- /dev/null +++ b/src/ps2.h @@ -0,0 +1 @@ +void ps2board_init(); diff --git a/src/resources.h b/src/resources.h index bc1aa903b..6e9c6a041 100644 --- a/src/resources.h +++ b/src/resources.h @@ -254,6 +254,7 @@ #define IDC_CHECKBUSLOGIC 1017 #define IDC_STATIC 1020 #define IDC_CHECKSYNC 1024 +#define IDC_CHECKXTIDE 1025 #define IDC_EDIT1 1030 #define IDC_EDIT2 1031 #define IDC_EDIT3 1032 diff --git a/src/vid_cga.c b/src/vid_cga.c index ab909b3f3..e5a9de837 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -59,6 +59,14 @@ void cga_out(uint16_t addr, uint8_t val, void *p) update_cga16_color(cga->cgamode); } cga->cgamode = val; +#ifndef __unix + cga_palette = (cga->rgb_type << 1); + if (!(cga->cgamode & 1) && (cga_palette > 0) && (cga_palette < 8)) + { + cga_palette--; + cgapal_rebuild(); + } +#endif return; case 0x3D9: cga->cgacol = val; @@ -466,7 +474,8 @@ void *cga_standalone_init() overscan_x = overscan_y = 16; #ifndef __unix - cga_palette = device_get_config_int("rgb_type"); + cga->rgb_type = device_get_config_int("rgb_type"); + cga_palette = (cga->rgb_type << 1); cgapal_rebuild(); #endif @@ -538,33 +547,25 @@ static device_config_t cga_config[] = .selection = { { - .description = "Full 16-color", + .description = "Color", .value = 0 }, { - .description = "Green, 4-color", + .description = "Green Monochrome", .value = 1 }, { - .description = "Green, 16-color", + .description = "Amber Monochrome", .value = 2 }, { - .description = "Amber, 4-color", + .description = "Gray Monochrome", .value = 3 }, { - .description = "Amber, 16-color", + .description = "Color (no brown)", .value = 4 }, - { - .description = "Gray, 4-color", - .value = 5 - }, - { - .description = "Gray, 16-color", - .value = 6 - }, { .description = "" } diff --git a/src/vid_cga.h b/src/vid_cga.h index e3b187777..ca513785d 100644 --- a/src/vid_cga.h +++ b/src/vid_cga.h @@ -34,6 +34,9 @@ typedef struct cga_t int revision; int composite; int snow_enabled; +#ifndef __unix + int rgb_type; +#endif } cga_t; void cga_init(cga_t *cga); diff --git a/src/vid_hercules.c b/src/vid_hercules.c index d3cd051e3..2c96a5654 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -346,7 +346,11 @@ void *hercules_init() overscan_x = overscan_y = 0; #ifndef __unix - cga_palette = device_get_config_int("rgb_type"); + cga_palette = device_get_config_int("rgb_type") << 1; + if (cga_palette > 6) + { + cga_palette = 0; + } cgapal_rebuild(); #endif @@ -378,20 +382,20 @@ static device_config_t hercules_config[] = .selection = { { - .description = "Default 4-color", + .description = "Default", .value = 0 }, { - .description = "Green, 4-color", + .description = "Green", .value = 1 }, { - .description = "Amber, 4-color", - .value = 3 + .description = "Amber", + .value = 2 }, { - .description = "Gray, 4-color", - .value = 5 + .description = "Gray", + .value = 3 }, { .description = "" diff --git a/src/vid_mda.c b/src/vid_mda.c index be38890bd..bf3b9e459 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -302,7 +302,11 @@ void *mda_init() overscan_x = overscan_y = 0; #ifndef __unix - cga_palette = device_get_config_int("rgb_type"); + cga_palette = device_get_config_int("rgb_type") << 1; + if (cga_palette > 6) + { + cga_palette = 0; + } cgapal_rebuild(); #endif @@ -334,20 +338,20 @@ static device_config_t mda_config[] = .selection = { { - .description = "Default 4-color", + .description = "Default", .value = 0 }, { - .description = "Green, 4-color", + .description = "Green", .value = 1 }, { - .description = "Amber, 4-color", - .value = 3 + .description = "Amber", + .value = 2 }, { - .description = "Gray, 4-color", - .value = 5 + .description = "Gray", + .value = 3 }, { .description = "" diff --git a/src/vid_vga.c b/src/vid_vga.c index 501643cf2..fbed319d7 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -105,7 +105,7 @@ void *vga_init() return vga; } -void *vga_chips_init() +/* void *vga_chips_init() { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); @@ -124,7 +124,7 @@ void *vga_chips_init() vga->svga.miscout = 1; return vga; -} +} */ void *trigem_unk_init() { @@ -222,7 +222,7 @@ device_t vga_device = vga_force_redraw, vga_add_status_info }; -device_t vga_chips_device = +/* device_t vga_chips_device = { "Chips VGA", 0, @@ -232,7 +232,7 @@ device_t vga_chips_device = vga_speed_changed, vga_force_redraw, vga_add_status_info -}; +}; */ device_t trigem_unk_device = { "VGA", diff --git a/src/vid_vga.h b/src/vid_vga.h index 77aff5056..1f8fbe700 100644 --- a/src/vid_vga.h +++ b/src/vid_vga.h @@ -2,6 +2,6 @@ see COPYING for more details */ extern device_t vga_device; -extern device_t vga_chips_device; +// extern device_t vga_chips_device; extern device_t trigem_unk_device; extern device_t ps1vga_device; diff --git a/src/video.c b/src/video.c index ee3bdf0d9..1764b8739 100644 --- a/src/video.c +++ b/src/video.c @@ -74,7 +74,7 @@ static VIDEO_CARD video_cards[] = {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, {"EGA", &ega_device, GFX_EGA}, {"Chips & Technologies SuperEGA", &sega_device, GFX_SUPER_EGA}, - {"Chips & Technologies VGA 451", &vga_chips_device, GFX_CHIPS_VGA}, + /* {"Chips & Technologies VGA 451", &vga_chips_device, GFX_CHIPS_VGA}, */ {"Compaq ATI VGA Wonder XL (ATI-28800-5)", &compaq_ati28800_device, GFX_VGAWONDERXL}, {"Compaq EGA", &cpqega_device, GFX_COMPAQ_EGA}, {"Compaq/Paradise VGA", &cpqvga_device, GFX_COMPAQ_VGA}, diff --git a/src/win-config.c b/src/win-config.c index a72391e1b..0ffb74c7c 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -58,7 +58,8 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR int temp_joystick_type; int cpu_type; int temp_mouse_type; - + int temp_xtide; + UDACCEL accel; // pclog("Dialog msg %i %08X\n",message,message); switch (message) @@ -201,6 +202,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR EnableWindow(h, TRUE); SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); + h=GetDlgItem(hdlg, IDC_CHECKXTIDE); + SendMessage(h, BM_SETCHECK, enable_xtide, 0); + h = GetDlgItem(hdlg, IDC_COMBOSPD); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"8-bit"); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Slow 16-bit"); @@ -414,6 +418,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h = GetDlgItem(hdlg, IDC_CHECKDYNAREC); temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECKXTIDE); + temp_xtide = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBONET); temp_network_card_current = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -433,7 +440,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_cpu != cpu || temp_cpu_m != cpu_manufacturer || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || - temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || + temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_xtide != enable_xtide || temp_voodoo != voodoo_enabled || temp_buslogic != buslogic_enabled || temp_dynarec != cpu_use_dynarec || temp_mouse_type != mouse_type || temp_fd1_type != fdd_get_type(0) || temp_fd2_type != fdd_get_type(1) || temp_fd3_type != fdd_get_type(2) || temp_fd4_type != fdd_get_type(3) || temp_network_card_current != network_card_current) { @@ -454,6 +461,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR buslogic_enabled = temp_buslogic; cpu_use_dynarec = temp_dynarec; mouse_type = temp_mouse_type; + enable_xtide = temp_xtide; fdd_set_type(0, temp_fd1_type); fdd_set_type(1, temp_fd2_type); diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index d6fad07c5..9f8f91b0a 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -85,12 +85,12 @@ PALETTE cgapal_mono[6] = {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, }, { // 4 - grey, 4-color-optimized contrast - {0x00,0x00,0x00},{0x0d,0x0d,0x0d},{0x15,0x15,0x15},{0x18,0x18,0x18},{0x24,0x24,0x24},{0x27,0x27,0x27},{0x33,0x33,0x33},{0x37,0x37,0x37}, - {0x08,0x08,0x08},{0x10,0x10,0x10},{0x1c,0x1c,0x1c},{0x20,0x20,0x20},{0x2c,0x2c,0x2c},{0x2f,0x2f,0x2f},{0x3b,0x3b,0x3b},{0x3f,0x3f,0x3f}, + {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, + {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, }, { // 5 - grey, 16-color-optimized contrast - {0x00,0x00,0x00},{0x0d,0x0d,0x0d},{0x12,0x12,0x12},{0x15,0x15,0x15},{0x1e,0x1e,0x1e},{0x20,0x20,0x20},{0x29,0x29,0x29},{0x2c,0x2c,0x2c}, - {0x1f,0x1f,0x1f},{0x23,0x23,0x23},{0x2b,0x2b,0x2b},{0x2d,0x2d,0x2d},{0x34,0x34,0x34},{0x36,0x36,0x36},{0x3d,0x3d,0x3d},{0x3f,0x3f,0x3f}, + {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, + {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, }, }; @@ -112,11 +112,15 @@ void cgapal_rebuild() int c; for (c = 0; c < 256; c++) pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); - if (cga_palette > 1) + if ((cga_palette > 1) && (cga_palette < 8)) { for (c = 0; c < 16; c++) pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); } + if (cga_palette == 8) + { + pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); + } } void d3d_fs_init(HWND h) From 2433771509b957af9f221ab5cebe065b26c5c8d0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 Feb 2017 00:19:29 +0100 Subject: [PATCH 101/392] Fixed a compile-breaking error in vid_vga.c. --- src/vid_vga.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vid_vga.c b/src/vid_vga.c index fbed319d7..da010a595 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -105,7 +105,8 @@ void *vga_init() return vga; } -/* void *vga_chips_init() +#if 0 +void *vga_chips_init() { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); @@ -124,7 +125,8 @@ void *vga_init() vga->svga.miscout = 1; return vga; -} */ +} +#endif void *trigem_unk_init() { From af037935332879322f7c87293d6b3e0a7fa90e31 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 20 Feb 2017 06:05:11 +0100 Subject: [PATCH 102/392] Added Hyundai Super-286TR; Fixed the emulation of the Intel 82335 chip used by the Phoenix 386 clone; Fixed a bug regarding the CGA RGB monitor type; The IBM PS/1 Model 2121 with ISA is now acknowledged in mem.c. --- src/i82335.c | 97 ++++++++++++++++++++++++++++++++++++++-------- src/ibm.h | 5 ++- src/mem.c | 8 ++++ src/model.c | 1 + src/nvr.c | 2 + src/vid_cga.c | 15 +++++-- src/vid_oti067.c | 27 ++++++++++++- src/vid_oti067.h | 1 + src/video.c | 1 + src/x86_ops_i686.h | 12 ++++++ 10 files changed, 146 insertions(+), 23 deletions(-) diff --git a/src/i82335.c b/src/i82335.c index 75a593484..981ea8f55 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -19,27 +19,87 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) { int i = 0; + int mem_write = 0; + + // pclog("i82335_write(%04X, %02X)\n", addr, val); + switch (addr) { case 0x22: + if ((val ^ i82335.reg_22) & 1) + { + if (val & 1) + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + shadowbios = 1; + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + shadowbios = 0; + } + } + + flushmmucache(); + } + i82335.reg_22 = val | 0xd8; - if (val & 1) - { - for (i = 0; i < 8; i++) - { - mem_mapping_enable(&bios_mapping[i]); - } - } - else - { - for (i = 0; i < 8; i++) - { - mem_mapping_disable(&bios_mapping[i]); - } - } break; case 0x23: - i82335.reg_23 = val | 0xd8; + i82335.reg_23 = val; + + if ((val ^ i82335.reg_22) & 2) + { + if (val & 2) + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xc0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + shadowbios = 1; + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xc0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + shadowbios = 0; + } + } + } + + if ((val ^ i82335.reg_22) & 0xc) + { + if (val & 2) + { + for (i = 0; i < 8; i++) + { + mem_write = (val & 8) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | mem_write); + shadowbios = 1; + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_write = (val & 8) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTERNAL; + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | mem_write); + shadowbios = 0; + } + } + } + + if ((val ^ i82335.reg_22) & 0xe) + { + flushmmucache(); + } + if (val & 0x80) { io_removehandler(0x0022, 0x0001, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); @@ -50,6 +110,7 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) uint8_t i82335_read(uint16_t addr, void *priv) { + // pclog("i82335_read(%04X)\n", addr); if (addr == 0x22) { return i82335.reg_22; @@ -58,13 +119,17 @@ uint8_t i82335_read(uint16_t addr, void *priv) { return i82335.reg_23; } + else + { + return 0; + } } void i82335_init() { memset(&i82335, 0, sizeof(i82335_t)); - i82335.reg_22 = 0xd9; + i82335.reg_22 = 0xd8; io_sethandler(0x0022, 0x0014, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); } diff --git a/src/ibm.h b/src/ibm.h index d68e9ede6..dd77bec81 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -422,6 +422,8 @@ enum ROM_IBMPS1_2121_ISA,/*IBM PS/1 Model 2121 with ISA expansion bus*/ ROM_SPC4200P, /*Samsung SPC-4200P / SCAT / Phoenix BIOS*/ + ROM_SUPER286TR, /*Hyundai Super-286TR / SCAT / Award BIOS*/ + ROM_MEGAPCDX, /*386DX mdoel of the Mega PC - Note by Tohka: The documentation (that I have in German) clearly says such a model exists.*/ ROM_MAX @@ -474,7 +476,8 @@ enum GFX_RIVATNT2, GFX_TRIGEM_UNK, - GFX_CHIPS_VGA, + GFX_OTI037, /*Oak OTI-037*/ + GFX_MAX }; diff --git a/src/mem.c b/src/mem.c index c1e6a101b..733bf0980 100644 --- a/src/mem.c +++ b/src/mem.c @@ -592,6 +592,7 @@ int loadbios() return 1; case ROM_IBMPS1_2121: + case ROM_IBMPS1_2121_ISA: f = romfopen("roms/ibmps1_2121/fc0000.bin", "rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); @@ -655,6 +656,13 @@ int loadbios() fclose(f); return 1; + case ROM_SUPER286TR: /*Hyundai Super-286TR*/ + f = romfopen("roms/super286tr/hyundai_award286.bin", "rb"); + if (!f) break; + fread(rom, 65536, 1, f); + fclose(f); + return 1; + case ROM_PX386: /*Phoenix 80386 BIOS*/ f=romfopen("roms/px386/3iip001l.bin","rb"); ff=romfopen("roms/px386/3iip001h.bin","rb"); diff --git a/src/model.c b/src/model.c index 3e15c8018..72e3011b7 100644 --- a/src/model.c +++ b/src/model.c @@ -150,6 +150,7 @@ MODEL models[] = {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"Samsung SPC-4200P", ROM_SPC4200P, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 7c3844d5c..abecfe029 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -214,6 +214,7 @@ void loadnvr() case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "rb"); nvrmask = 127; break; + case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; @@ -297,6 +298,7 @@ void savenvr() case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "wb"); break; + case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "wb"); break; case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; diff --git a/src/vid_cga.c b/src/vid_cga.c index e5a9de837..aeb0d3e73 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -58,15 +58,18 @@ void cga_out(uint16_t addr, uint8_t val, void *p) cga->cgamode = val; update_cga16_color(cga->cgamode); } - cga->cgamode = val; #ifndef __unix - cga_palette = (cga->rgb_type << 1); - if (!(cga->cgamode & 1) && (cga_palette > 0) && (cga_palette < 8)) + if ((cga->cgamode ^ val) & 1) { - cga_palette--; + cga_palette = (cga->rgb_type << 1); + if (!(val & 1) && (cga_palette > 0) && (cga_palette < 8)) + { + cga_palette--; + } cgapal_rebuild(); } #endif + cga->cgamode = val; return; case 0x3D9: cga->cgacol = val; @@ -94,6 +97,10 @@ void cga_write(uint32_t addr, uint8_t val, void *p) { cga_t *cga = (cga_t *)p; // pclog("CGA_WRITE %04X %02X\n", addr, val); + /* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */ + if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) return; + if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) return; + cga->vram[addr & 0x3fff] = val; if (cga->snow_enabled) { diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 6ded38b35..202da0466 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -189,6 +189,12 @@ void *oti067_common_init(char *bios_fn, int vram_size, int chip_id) return oti067; } +/* void *oti037_init() +{ + int vram_size = device_get_config_int("memory"); + return oti067_common_init("roms/hyundai_oti037c.bin", vram_size, 0); +} */ + void *oti067_init() { int vram_size = device_get_config_int("memory"); @@ -205,12 +211,17 @@ void *oti067_acer386_init() { oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512, 2); - if (oti067) - oti067->bios_rom.rom[0x5d] = 0x74; + /* if (oti067) + oti067->bios_rom.rom[0x5d] = 0x74; */ return oti067; } +/* static int oti037_available() +{ + return rom_present("roms/hyundai_oti037c.bin"); +} */ + static int oti067_available() { return rom_present("roms/oti067/bios.bin"); @@ -309,6 +320,18 @@ static device_config_t oti077_config[] = } }; +/* device_t oti037_device = +{ + "Oak OTI-037", + 0, + oti037_init, + oti067_close, + oti037_available, + oti067_speed_changed, + oti067_force_redraw, + oti067_add_status_info, + oti067_config +}; */ device_t oti067_device = { "Oak OTI-067", diff --git a/src/vid_oti067.h b/src/vid_oti067.h index 4ac802657..b9ac2dfcb 100644 --- a/src/vid_oti067.h +++ b/src/vid_oti067.h @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +extern device_t oti037_device; extern device_t oti067_device; extern device_t oti067_acer386_device; extern device_t oti077_device; diff --git a/src/video.c b/src/video.c index 1764b8739..6c3c00ab8 100644 --- a/src/video.c +++ b/src/video.c @@ -88,6 +88,7 @@ static VIDEO_CARD video_cards[] = {"nVidia RIVA TNT (Experimental)", &rivatnt_device, GFX_RIVATNT}, {"nVidia TNT2 (Experimental)", &rivatnt2_device, GFX_RIVATNT2}, + /* {"OAK OTI-037", &oti037_device, GFX_OTI037}, */ {"OAK OTI-067", &oti067_device, GFX_OTI067}, {"OAK OTI-077", &oti077_device, GFX_OTI077}, {"Paradise Bahamas 64 (S3 Vision864)", &s3_bahamas64_device, GFX_BAHAMAS64}, diff --git a/src/x86_ops_i686.h b/src/x86_ops_i686.h index 74f8a7810..0b6bec4de 100644 --- a/src/x86_ops_i686.h +++ b/src/x86_ops_i686.h @@ -33,16 +33,20 @@ static int opSYSENTER(uint32_t fetchdat) uint16_t sysenter_cs_seg_data[4]; uint16_t sysenter_ss_seg_data[4]; +#ifdef SYSENTER_LOG pclog("SYSENTER called\n"); +#endif if (!(cr0 & 1)) return internal_illegal("SYSENTER: CPU not in protected mode"); if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSENTER: CS MSR is zero"); +#ifdef SYSENTER_LOG pclog("SYSENTER started:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32); +#endif if (cpu_state.abrt) return 1; @@ -72,11 +76,13 @@ static int opSYSENTER(uint32_t fetchdat) CPU_BLOCK_END(); +#ifdef SYSENTER_LOG pclog("SYSENTER completed:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32); +#endif return 0; } @@ -86,17 +92,21 @@ static int opSYSEXIT(uint32_t fetchdat) uint16_t sysexit_cs_seg_data[4]; uint16_t sysexit_ss_seg_data[4]; +#ifdef SYSEXIT_LOG pclog("SYSEXIT called\n"); +#endif if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSEXIT: CS MSR is zero"); if (!(cr0 & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode"); if (CS & 3) return internal_illegal("SYSEXIT: CPL not 0"); +#ifdef SYSEXIT_LOG pclog("SYSEXIT start:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX); +#endif if (cpu_state.abrt) return 1; @@ -124,11 +134,13 @@ static int opSYSEXIT(uint32_t fetchdat) CPU_BLOCK_END(); +#ifdef SYSEXIT_LOG pclog("SYSEXIT completed:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX); +#endif return 0; } From 86d1b0f1ebac315a1d32249edd3dcfca43414496 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 21 Feb 2017 01:18:46 +0100 Subject: [PATCH 103/392] The emulator now tries to initialize the other renderer if the specified one fails, and only fatals if both fail to initialize; On Windows, fatal now displays a message box, based on old PCem-X patch by RichardG; Added emulation of the 287, 387, and 487SX floating point units and an option to enable them. --- src/cpu.c | 50 ++++- src/ibm.h | 2 + src/pc.c | 56 ++++- src/pc.rc | 3 +- src/resources.h | 1 + src/win-config.c | 12 +- src/win-d3d-fs.cc | 12 +- src/win-d3d-fs.h | 2 +- src/win-d3d.cc | 12 +- src/win-d3d.h | 2 +- src/win-ddraw-fs.cc | 20 +- src/win-ddraw-fs.h | 2 +- src/win-ddraw.cc | 24 ++- src/win-ddraw.h | 2 +- src/win.c | 14 +- src/x86_ops.h | 30 +++ src/x87_ops.h | 491 +++++++++++++++++++++++++++++++++++++++++++- 17 files changed, 695 insertions(+), 40 deletions(-) diff --git a/src/cpu.c b/src/cpu.c index 5172c4727..085f4e1b7 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -574,6 +574,8 @@ void cpu_set_edx() EDX = models[model].cpu[cpu_manufacturer].cpus[cpu].edx_reset; } +int enable_external_fpu = 0; + void cpu_set() { CPU *cpu_s; @@ -596,8 +598,8 @@ void cpu_set() is486 = (cpu_s->cpu_type >= CPU_i486SX) || (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_RAPIDCAD); is_pentium= (cpu_s->cpu_type >= CPU_WINCHIP); hasfpu = (cpu_s->cpu_type >= CPU_i486DX) || (cpu_s->cpu_type == CPU_RAPIDCAD); - cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); - cpu_16bitbus = cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC); + cpu_iscyrix = (cpu_s->cpu_type == CPU_486SLC || cpu_s->cpu_type == CPU_486DLC || cpu_s->cpu_type == CPU_Cx486S || cpu_s->cpu_type == CPU_Cx486DX || cpu_s->cpu_type == CPU_Cx5x86 || cpu_s->cpu_type == CPU_Cx6x86 || cpu_s->cpu_type == CPU_Cx6x86MX || cpu_s->cpu_type == CPU_Cx6x86L || cpu_s->cpu_type == CPU_CxGX1); + cpu_16bitbus = (cpu_s->cpu_type == CPU_286 || cpu_s->cpu_type == CPU_386SX || cpu_s->cpu_type == CPU_486SLC); if (cpu_s->multi) cpu_busspeed = cpu_s->rspeed / cpu_s->multi; cpu_multi = cpu_s->multi; @@ -607,6 +609,19 @@ void cpu_set() cpu_hasCR4 = 0; ccr0 = ccr1 = ccr2 = ccr3 = ccr4 = ccr5 = ccr6 = 0; + if ((cpu_s->cpu_type == CPU_286) || (cpu_s->cpu_type == CPU_386SX) || (cpu_s->cpu_type == CPU_386DX) || (cpu_s->cpu_type == CPU_i486SX)) + { + if (enable_external_fpu) + { + hasfpu = 1; + if (cpu_s->cpu_type == CPU_i486SX) + { + /* The 487SX is a full implementation of the 486DX and takes over the entire CPU's operation. */ + cpu_s->cpu_type = CPU_i486DX; + } + } + } + cpu_update_waitstates(); isa_cycles = (int)(((int64_t)cpu_s->rspeed << ISA_CYCLES_SHIFT) / 8000000ll); @@ -722,6 +737,37 @@ void cpu_set() case CPU_286: x86_setopcodes(ops_286, ops_286_0f, dynarec_ops_286, dynarec_ops_286_0f); + if (enable_external_fpu) + { + x86_dynarec_opcodes_d9_a16 = dynarec_ops_fpu_287_d9_a16; + x86_dynarec_opcodes_d9_a32 = dynarec_ops_fpu_287_d9_a32; + x86_dynarec_opcodes_da_a16 = dynarec_ops_fpu_287_da_a16; + x86_dynarec_opcodes_da_a32 = dynarec_ops_fpu_287_da_a32; + x86_dynarec_opcodes_db_a16 = dynarec_ops_fpu_287_db_a16; + x86_dynarec_opcodes_db_a32 = dynarec_ops_fpu_287_db_a32; + x86_dynarec_opcodes_dc_a16 = dynarec_ops_fpu_287_dc_a16; + x86_dynarec_opcodes_dc_a32 = dynarec_ops_fpu_287_dc_a32; + x86_dynarec_opcodes_dd_a16 = dynarec_ops_fpu_287_dd_a16; + x86_dynarec_opcodes_dd_a32 = dynarec_ops_fpu_287_dd_a32; + x86_dynarec_opcodes_de_a16 = dynarec_ops_fpu_287_de_a16; + x86_dynarec_opcodes_de_a32 = dynarec_ops_fpu_287_de_a32; + x86_dynarec_opcodes_df_a16 = dynarec_ops_fpu_287_df_a16; + x86_dynarec_opcodes_df_a32 = dynarec_ops_fpu_287_df_a32; + x86_opcodes_d9_a16 = ops_fpu_287_d9_a16; + x86_opcodes_d9_a32 = ops_fpu_287_d9_a32; + x86_opcodes_da_a16 = ops_fpu_287_da_a16; + x86_opcodes_da_a32 = ops_fpu_287_da_a32; + x86_opcodes_db_a16 = ops_fpu_287_db_a16; + x86_opcodes_db_a32 = ops_fpu_287_db_a32; + x86_opcodes_dc_a16 = ops_fpu_287_dc_a16; + x86_opcodes_dc_a32 = ops_fpu_287_dc_a32; + x86_opcodes_dd_a16 = ops_fpu_287_dd_a16; + x86_opcodes_dd_a32 = ops_fpu_287_dd_a32; + x86_opcodes_de_a16 = ops_fpu_287_de_a16; + x86_opcodes_de_a32 = ops_fpu_287_de_a32; + x86_opcodes_df_a16 = ops_fpu_287_df_a16; + x86_opcodes_df_a32 = ops_fpu_287_df_a32; + } timing_rr = 2; /*register dest - register src*/ timing_rm = 7; /*register dest - memory src*/ timing_mr = 7; /*memory dest - register src*/ diff --git a/src/ibm.h b/src/ibm.h index dd77bec81..c57e4abe8 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -425,6 +425,7 @@ enum ROM_SUPER286TR, /*Hyundai Super-286TR / SCAT / Award BIOS*/ ROM_MEGAPCDX, /*386DX mdoel of the Mega PC - Note by Tohka: The documentation (that I have in German) clearly says such a model exists.*/ + ROM_PX486, /*Phoenix 486 clone*/ ROM_MAX }; @@ -633,3 +634,4 @@ void trc_write(uint16_t port, uint8_t val, void *priv); void trc_init(); extern int enable_xtide; +extern int enable_external_fpu; diff --git a/src/pc.c b/src/pc.c index 42a764320..de8f5cc85 100644 --- a/src/pc.c +++ b/src/pc.c @@ -4,6 +4,14 @@ #include #include #include + +#ifndef __unix +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "win.h" +#endif + #include "86box.h" #include "ibm.h" #include "device.h" @@ -93,15 +101,59 @@ void pclog(const char *format, ...) #endif } +#ifndef __unix +#ifndef _LIBC +# define __builtin_expect(expr, val) (expr) +#endif + +#undef memmem + +/* Return the first occurrence of NEEDLE in HAYSTACK. */ +void *memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) +{ + const char *begin; + const char *const last_possible = (const char *) haystack + haystack_len - needle_len; + + if (needle_len == 0) + /* The first occurrence of the empty string is deemed to occur at + the beginning of the string. */ + return (void *) haystack; + + /* Sanity check, otherwise the loop might search through the whole + memory. */ + if (__builtin_expect (haystack_len < needle_len, 0)) + return NULL; + + for (begin = (const char *) haystack; begin <= last_possible; ++begin) + if (begin[0] == ((const char *) needle)[0] && !memcmp ((const void *) &begin[1], (const void *) ((const char *) needle + 1), needle_len - 1)) + return (void *) begin; + + return NULL; +} +#endif + void fatal(const char *format, ...) { + char msg[1024]; +#ifndef __unix + char *newline; +#endif va_list ap; va_start(ap, format); - vprintf(format, ap); + vsprintf(msg, format, ap); + printf(msg); va_end(ap); fflush(stdout); savenvr(); saveconfig(); +#ifndef __unix + newline = memmem(msg, strlen(msg), "\n", strlen("\n")); + if (newline != NULL) + { + *newline = 0; + } + MessageBox(ghwnd, msg, "86Box fatal error", MB_OK + MB_ICONERROR); +#endif dumppic(); dumpregs(); fflush(stdout); @@ -869,6 +921,7 @@ void loadconfig(char *fn) mouse_type = config_get_int(NULL, "mouse_type", 0); enable_xtide = config_get_int(NULL, "enable_xtide", 1); + enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { @@ -1053,6 +1106,7 @@ void saveconfig() config_set_int(NULL, "mouse_type", mouse_type); config_set_int(NULL, "enable_xtide", enable_xtide); + config_set_int(NULL, "enable_external_fpu", enable_external_fpu); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { diff --git a/src/pc.rc b/src/pc.rc index f22e897ae..18c05c9cf 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -383,7 +383,7 @@ BEGIN COMBOBOX IDC_COMBOCPUM,62,56,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO3,62,76,102,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Dynamic Recompiler",IDC_CHECKDYNAREC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,76,99,10 - CONTROL "Enable XTIDE",IDC_CHECKXTIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,96,99,10 + CONTROL "Enable 287/387 FPU",IDC_CHECKFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,96,99,10 COMBOBOX IDC_COMBOWS, 62,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOSPD,162,56,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOSND,62,116,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -395,6 +395,7 @@ BEGIN CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,208,102,10 CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,192,102,10 + CONTROL "En. XTIDE",IDC_CHECKXTIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,192,40,10 CONTROL "SCSI Controller",IDC_CHECKBUSLOGIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,208,102,10 PUSHBUTTON "Configure", IDC_CONFIGUREBUSLOGIC, 224, 208, 40, 14, WS_TABSTOP diff --git a/src/resources.h b/src/resources.h index 6e9c6a041..41b018c9f 100644 --- a/src/resources.h +++ b/src/resources.h @@ -255,6 +255,7 @@ #define IDC_STATIC 1020 #define IDC_CHECKSYNC 1024 #define IDC_CHECKXTIDE 1025 +#define IDC_CHECKFPU 1026 #define IDC_EDIT1 1030 #define IDC_EDIT2 1031 #define IDC_EDIT3 1032 diff --git a/src/win-config.c b/src/win-config.c index 0ffb74c7c..68a49c84c 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -56,9 +56,10 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR int temp_network_card_current; int temp_network_interface_current; int temp_joystick_type; - int cpu_type; int temp_mouse_type; + int cpu_type; int temp_xtide; + int temp_fpu; UDACCEL accel; // pclog("Dialog msg %i %08X\n",message,message); @@ -205,6 +206,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h=GetDlgItem(hdlg, IDC_CHECKXTIDE); SendMessage(h, BM_SETCHECK, enable_xtide, 0); + h=GetDlgItem(hdlg, IDC_CHECKFPU); + SendMessage(h, BM_SETCHECK, enable_external_fpu, 0); + h = GetDlgItem(hdlg, IDC_COMBOSPD); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"8-bit"); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Slow 16-bit"); @@ -421,6 +425,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h = GetDlgItem(hdlg, IDC_CHECKXTIDE); temp_xtide = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECKFPU); + temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBONET); temp_network_card_current = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -439,7 +446,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR temp_mouse_type = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_cpu != cpu || temp_cpu_m != cpu_manufacturer || - fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || + fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_fpu != enable_external_fpu || temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_xtide != enable_xtide || temp_voodoo != voodoo_enabled || temp_buslogic != buslogic_enabled || temp_dynarec != cpu_use_dynarec || temp_mouse_type != mouse_type || temp_fd1_type != fdd_get_type(0) || temp_fd2_type != fdd_get_type(1) || temp_fd3_type != fdd_get_type(2) || temp_fd4_type != fdd_get_type(3) || temp_network_card_current != network_card_current) @@ -462,6 +469,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR cpu_use_dynarec = temp_dynarec; mouse_type = temp_mouse_type; enable_xtide = temp_xtide; + enable_external_fpu = temp_fpu; fdd_set_type(0, temp_fd1_type); fdd_set_type(1, temp_fd2_type); diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 9f8f91b0a..b6597c37f 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -123,7 +123,7 @@ void cgapal_rebuild() } } -void d3d_fs_init(HWND h) +int d3d_fs_init(HWND h) { HRESULT hr; char emulator_title[200]; @@ -152,6 +152,10 @@ void d3d_fs_init(HWND h) ); d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (d3d == NULL) + { + return 0; + } memset(&d3dpp, 0, sizeof(d3dpp)); @@ -170,11 +174,17 @@ void d3d_fs_init(HWND h) d3dpp.BackBufferHeight = d3d_fs_h; hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(hr)) + { + return 0; + } d3d_fs_init_objects(); video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen; video_blit_memtoscreen_8_func = d3d_fs_blit_memtoscreen_8; + + return 1; } static void d3d_fs_close_objects() diff --git a/src/win-d3d-fs.h b/src/win-d3d-fs.h index 0c45c6e2d..41ca32e21 100644 --- a/src/win-d3d-fs.h +++ b/src/win-d3d-fs.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif - void d3d_fs_init(HWND h); + int d3d_fs_init(HWND h); void d3d_fs_close(); void d3d_fs_reset(); void d3d_fs_resize(int x, int y); diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 12c40351f..03292c61a 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -47,7 +47,7 @@ static CUSTOMVERTEX d3d_verts[] = {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; -void d3d_init(HWND h) +int d3d_init(HWND h) { int c; HRESULT hr; @@ -57,6 +57,10 @@ void d3d_init(HWND h) d3d_hwnd = h; d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (d3d == NULL) + { + return 0; + } memset(&d3dpp, 0, sizeof(d3dpp)); @@ -75,11 +79,17 @@ void d3d_init(HWND h) d3dpp.BackBufferHeight = 0; hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(hr)) + { + return 0; + } d3d_init_objects(); video_blit_memtoscreen_func = d3d_blit_memtoscreen; video_blit_memtoscreen_8_func = d3d_blit_memtoscreen_8; + + return 1; } void d3d_close_objects() diff --git a/src/win-d3d.h b/src/win-d3d.h index 4d4c341bc..7210d454b 100644 --- a/src/win-d3d.h +++ b/src/win-d3d.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif - void d3d_init(HWND h); + int d3d_init(HWND h); void d3d_close(); void d3d_reset(); void d3d_resize(int x, int y); diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index ed18c9b64..5920eb6fb 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -15,7 +15,7 @@ extern "C" void pclog(const char *format, ...); extern "C" void device_force_redraw(); -extern "C" void ddraw_fs_init(HWND h); +extern "C" int ddraw_fs_init(HWND h); extern "C" void ddraw_fs_close(); extern "C" void video_blit_complete(); @@ -34,7 +34,7 @@ static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; static int ddraw_w, ddraw_h; -void ddraw_fs_init(HWND h) +int ddraw_fs_init(HWND h) { int c; @@ -44,10 +44,10 @@ void ddraw_fs_init(HWND h) cgapal_rebuild(); if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - fatal("DirectDrawCreate failed\n"); + return 0; if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) - fatal("QueryInterface failed\n"); + return 0; lpdd->Release(); lpdd = NULL; @@ -56,10 +56,10 @@ void ddraw_fs_init(HWND h) if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW | DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT))) - fatal("SetCooperativeLevel failed\n"); + return 0; if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) - fatal("SetDisplayMode failed\n"); + return 0; // memset(&ddsd, 0, sizeof(ddsd)); // ddsd.dwSize = sizeof(ddsd); @@ -68,11 +68,11 @@ void ddraw_fs_init(HWND h) ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) - fatal("CreateSurface failed\n"); + return 0; ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2))) - fatal("CreateSurface back failed\n"); + return 0; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -82,12 +82,14 @@ void ddraw_fs_init(HWND h) ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - fatal("CreateSurface back failed\n"); + return 0; pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; video_blit_memtoscreen_func = ddraw_fs_blit_memtoscreen; video_blit_memtoscreen_8_func = ddraw_fs_blit_memtoscreen_8; + + return 1; } void ddraw_fs_close() diff --git a/src/win-ddraw-fs.h b/src/win-ddraw-fs.h index c94f2610f..048c9c160 100644 --- a/src/win-ddraw-fs.h +++ b/src/win-ddraw-fs.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif - void ddraw_fs_init(HWND h); + int ddraw_fs_init(HWND h); void ddraw_fs_close(); #ifdef __cplusplus } diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 8aadfac56..3f9e4f7e2 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -16,7 +16,7 @@ extern "C" void pclog(const char *format, ...); extern "C" void device_force_redraw(); -extern "C" void ddraw_init(HWND h); +extern "C" int ddraw_init(HWND h); extern "C" void ddraw_close(); extern "C" void video_blit_complete(); @@ -34,17 +34,17 @@ static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; -void ddraw_init(HWND h) +int ddraw_init(HWND h) { int c; cgapal_rebuild(); if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - fatal("DirectDrawCreate failed\n"); + return 0; if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) - fatal("QueryInterface failed\n"); + return 0; lpdd->Release(); lpdd = NULL; @@ -52,7 +52,7 @@ void ddraw_init(HWND h) atexit(ddraw_close); if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_NORMAL))) - fatal("SetCooperativeLevel failed\n"); + return 0; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -60,7 +60,7 @@ void ddraw_init(HWND h) ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) - fatal("CreateSurface failed\n"); + return 0; // memset(&ddsd, 0, sizeof(ddsd)); // ddsd.dwSize = sizeof(ddsd); @@ -70,7 +70,7 @@ void ddraw_init(HWND h) ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) - fatal("CreateSurface back failed\n"); + return 0; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -80,19 +80,21 @@ void ddraw_init(HWND h) ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) - fatal("CreateSurface back failed\n"); + return 0; if (FAILED(lpdd4->CreateClipper(0, &lpdd_clipper, NULL))) - fatal("CreateClipper failed\n"); + return 0; if (FAILED(lpdd_clipper->SetHWnd(0, h))) - fatal("SetHWnd failed\n"); + return 0; if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) - fatal("SetClipper failed\n"); + return 0; pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; video_blit_memtoscreen_func = ddraw_blit_memtoscreen; video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8; + + return 1; } void ddraw_close() diff --git a/src/win-ddraw.h b/src/win-ddraw.h index 65e8e2bb1..a4044899d 100644 --- a/src/win-ddraw.h +++ b/src/win-ddraw.h @@ -4,7 +4,7 @@ #ifdef __cplusplus extern "C" { #endif - void ddraw_init(HWND h); + int ddraw_init(HWND h); void ddraw_close(); #ifdef __cplusplus } diff --git a/src/win.c b/src/win.c index 4479b36aa..4df50eba7 100644 --- a/src/win.c +++ b/src/win.c @@ -61,7 +61,7 @@ static uint16_t scancode_map[65536]; static struct { - void (*init)(HWND h); + int (*init)(HWND h); void (*close)(); void (*resize)(int x, int y); } vid_apis[2][2] = @@ -649,7 +649,17 @@ int WINAPI WinMain (HINSTANCE hThisInstance, initpc(argc, argv); // pclog("Setting video API...\n"); - vid_apis[0][vid_api].init(ghwnd); + if (vid_apis[0][vid_api].init(ghwnd) == 0) + { + if (vid_apis[0][vid_api ^ 1].init(ghwnd) == 0) + { + fatal("Both DirectDraw and Direct3D renderers failed to initialize\n"); + } + else + { + vid_api ^= 1; + } + } // pclog("Resizing window...\n"); if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); diff --git a/src/x86_ops.h b/src/x86_ops.h index efaf7b717..389420921 100644 --- a/src/x86_ops.h +++ b/src/x86_ops.h @@ -46,6 +46,21 @@ extern OpFn dynarec_ops_k6_0f[1024]; extern OpFn dynarec_ops_pentiumpro_0f[1024]; extern OpFn dynarec_ops_pentium2d_0f[1024]; +extern OpFn dynarec_ops_fpu_287_d9_a16[256]; +extern OpFn dynarec_ops_fpu_287_d9_a32[256]; +extern OpFn dynarec_ops_fpu_287_da_a16[256]; +extern OpFn dynarec_ops_fpu_287_da_a32[256]; +extern OpFn dynarec_ops_fpu_287_db_a16[256]; +extern OpFn dynarec_ops_fpu_287_db_a32[256]; +extern OpFn dynarec_ops_fpu_287_dc_a16[32]; +extern OpFn dynarec_ops_fpu_287_dc_a32[32]; +extern OpFn dynarec_ops_fpu_287_dd_a16[256]; +extern OpFn dynarec_ops_fpu_287_dd_a32[256]; +extern OpFn dynarec_ops_fpu_287_de_a16[256]; +extern OpFn dynarec_ops_fpu_287_de_a32[256]; +extern OpFn dynarec_ops_fpu_287_df_a16[256]; +extern OpFn dynarec_ops_fpu_287_df_a32[256]; + extern OpFn dynarec_ops_fpu_d8_a16[32]; extern OpFn dynarec_ops_fpu_d8_a32[32]; extern OpFn dynarec_ops_fpu_d9_a16[256]; @@ -111,6 +126,21 @@ extern OpFn ops_k6_0f[1024]; extern OpFn ops_pentiumpro_0f[1024]; extern OpFn ops_pentium2d_0f[1024]; +extern OpFn ops_fpu_287_d9_a16[256]; +extern OpFn ops_fpu_287_d9_a32[256]; +extern OpFn ops_fpu_287_da_a16[256]; +extern OpFn ops_fpu_287_da_a32[256]; +extern OpFn ops_fpu_287_db_a16[256]; +extern OpFn ops_fpu_287_db_a32[256]; +extern OpFn ops_fpu_287_dc_a16[32]; +extern OpFn ops_fpu_287_dc_a32[32]; +extern OpFn ops_fpu_287_dd_a16[256]; +extern OpFn ops_fpu_287_dd_a32[256]; +extern OpFn ops_fpu_287_de_a16[256]; +extern OpFn ops_fpu_287_de_a32[256]; +extern OpFn ops_fpu_287_df_a16[256]; +extern OpFn ops_fpu_287_df_a32[256]; + extern OpFn ops_fpu_d8_a16[32]; extern OpFn ops_fpu_d8_a32[32]; extern OpFn ops_fpu_d9_a16[256]; diff --git a/src/x87_ops.h b/src/x87_ops.h index 704d0afca..15c0c22d1 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -335,6 +335,84 @@ OpFn OP_TABLE(fpu_d8_a32)[32] = opFADD, opFMUL, opFCOM, opFCOMP, opFSUB, opFSUBR, opFDIV, opFDIVR }; +OpFn OP_TABLE(fpu_287_d9_a16)[256] = +{ + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, + opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, + opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, + opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, opFLDCW_a16, + opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, + opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*Invalid*/ + opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + +OpFn OP_TABLE(fpu_287_d9_a32)[256] = +{ + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, + opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, + opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, + opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, opFLDCW_a32, + opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, + opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, + + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*Invalid*/ + opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS +}; + OpFn OP_TABLE(fpu_d9_a16)[256] = { opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, @@ -413,6 +491,83 @@ OpFn OP_TABLE(fpu_d9_a32)[256] = opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS }; +OpFn OP_TABLE(fpu_287_da_a16)[256] = +{ + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, + opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, opFMULil_a16, + opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, opFCOMil_a16, + opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, opFCOMPil_a16, + opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, opFSUBil_a16, + opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, opFSUBRil_a16, + opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, + opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, + + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; +OpFn OP_TABLE(fpu_287_da_a32)[256] = +{ + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, opFADDil_a32, + opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, opFMULil_a32, + opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, opFCOMil_a32, + opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, opFCOMPil_a32, + opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, opFSUBil_a32, + opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, opFSUBRil_a32, + opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, + opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, + + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + OpFn OP_TABLE(fpu_da_a16)[256] = { opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, opFADDil_a16, @@ -567,6 +722,83 @@ OpFn OP_TABLE(fpu_686_da_a32)[256] = ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; +OpFn OP_TABLE(fpu_287_db_a16)[256] = +{ + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, + opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, + + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; +OpFn OP_TABLE(fpu_287_db_a32)[256] = +{ + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, + opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, + + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + OpFn OP_TABLE(fpu_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, @@ -600,7 +832,7 @@ OpFn OP_TABLE(fpu_db_a16)[256] = ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -638,7 +870,7 @@ OpFn OP_TABLE(fpu_db_a32)[256] = ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -677,7 +909,7 @@ OpFn OP_TABLE(fpu_686_db_a16)[256] = opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, - ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -715,12 +947,27 @@ OpFn OP_TABLE(fpu_686_db_a32)[256] = opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, - ILLEGAL, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; +OpFn OP_TABLE(fpu_287_dc_a16)[32] = +{ + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, + opFADDr, opFMULr, ILLEGAL, ILLEGAL, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; +OpFn OP_TABLE(fpu_287_dc_a32)[32] = +{ + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, + opFADDr, opFMULr, ILLEGAL, ILLEGAL, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr +}; + OpFn OP_TABLE(fpu_dc_a16)[32] = { opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, @@ -736,6 +983,83 @@ OpFn OP_TABLE(fpu_dc_a32)[32] = opFADDr, opFMULr, opFCOM, opFCOMP, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr }; +OpFn OP_TABLE(fpu_287_dd_a16)[256] = +{ + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, + opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, + opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, + opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; +OpFn OP_TABLE(fpu_287_dd_a32)[256] = +{ + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, + opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, + opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, + opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, + + opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + OpFn OP_TABLE(fpu_dd_a16)[256] = { opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, @@ -813,7 +1137,7 @@ OpFn OP_TABLE(fpu_dd_a32)[256] = ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, }; -OpFn OP_TABLE(fpu_de_a16)[256] = +OpFn OP_TABLE(fpu_287_de_a16)[256] = { opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, @@ -852,7 +1176,7 @@ OpFn OP_TABLE(fpu_de_a16)[256] = opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, }; -OpFn OP_TABLE(fpu_de_a32)[256] = +OpFn OP_TABLE(fpu_287_de_a32)[256] = { opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, @@ -891,6 +1215,161 @@ OpFn OP_TABLE(fpu_de_a32)[256] = opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, }; +OpFn OP_TABLE(fpu_de_a16)[256] = +{ + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, opFADDiw_a16, + opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, opFMULiw_a16, + opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, opFCOMiw_a16, + opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, opFCOMPiw_a16, + opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, opFSUBiw_a16, + opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, opFSUBRiw_a16, + opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, opFDIViw_a16, + opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, opFDIVRiw_a16, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, + ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +OpFn OP_TABLE(fpu_de_a32)[256] = +{ + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, opFADDiw_a32, + opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, opFMULiw_a32, + opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, opFCOMiw_a32, + opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, opFCOMPiw_a32, + opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, opFSUBiw_a32, + opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, opFSUBRiw_a32, + opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, opFDIViw_a32, + opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, opFDIVRiw_a32, + + opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, + opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, + opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, + ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, + opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, + opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, + opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, opFDIVP, +}; + +OpFn OP_TABLE(fpu_287_df_a16)[256] = +{ + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, + opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, + FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, + FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; +OpFn OP_TABLE(fpu_287_df_a32)[256] = +{ + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, + opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, + FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, + FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, + + opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, +}; + OpFn OP_TABLE(fpu_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, From 02fbf2356bd858589ed6d1abd7a994285b8f0fd9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 21 Feb 2017 01:33:43 +0100 Subject: [PATCH 104/392] 86Box v1.00 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 6c58d172a..a0a0b1254 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index d9df84dbb..dcbb5e551 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ From 9db233e1c5fbacb00614fcbc0503282b050cefd7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 21 Feb 2017 02:15:07 +0100 Subject: [PATCH 105/392] Development build with version bumped to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index 312dd5500..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.00" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index a0a0b1254..6c58d172a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index dcbb5e551..d9df84dbb 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ From 4ddfa7c1db1a84228c41f0470b6260d24f963d3d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 23 Feb 2017 19:52:14 +0100 Subject: [PATCH 106/392] Changed version number to 1.01; IMG floppy image handler now fills the remaining bytes with 0xF6 if it has read less bytes than expected - fixes handling of truncated IMG's with a valid BPB; HDI files are now written with the correct header; FDC DUMP REGISTERS command is now implemented correctly, fixes FDC error on AMI 486 clone and AMI WinBIOS 486; Commented out the Acer 386SX and the Phoenix 386 clone; WinPCap code is now delayed loading (thanks to Rai-chan), the emulator should now be able to run without WinPCap installed if not using PCap; The IBM PS/2 Model 30 NVR file is now saved in the same directly as the other NVR files; Applied all the latest mainline PCem Voodoo commits. --- src/86box.h | 2 +- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 4 +- src/disc_img.c | 8 +- src/fdc.c | 29 ++-- src/mem.c | 6 + src/model.c | 14 +- src/nvr.c | 12 +- src/vid_voodoo.c | 368 ++++++++++++++++++++++++++++++++++++------- src/win-hdconf.c | 2 +- 10 files changed, 352 insertions(+), 97 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..57ac3cf02 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.01" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 6c58d172a..fc6c5a1c0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -6,7 +6,7 @@ CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loo DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ + device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ @@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lwpcap +LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lwpcapdelay 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index d9df84dbb..9c72c48c9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -6,7 +6,7 @@ CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loo DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i82335.o i430hx.o i430lx.o i430fx.o \ + device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ @@ -28,7 +28,7 @@ SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voi SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcap +LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcapdelay 86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) diff --git a/src/disc_img.c b/src/disc_img.c index fc84aa2b4..645505199 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -583,6 +583,8 @@ void img_seek(int drive, int track) int side; int current_xdft = img[drive].xdf_type - 1; + int read_bytes = 0; + uint8_t id[4] = { 0, 0, 0, 0 }; int is_t0, sector, current_pos, img_pos, sr, sside, total, array_sector, buf_side, buf_pos; @@ -616,7 +618,11 @@ void img_seek(int drive, int track) } else { - fread(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f); + read_bytes = fread(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f); + if (read_bytes < (img[drive].sectors * ssize)) + { + memset(img[drive].track_data[side] + read_bytes, 0xf6, (img[drive].sectors * ssize) - read_bytes); + } } } diff --git a/src/fdc.c b/src/fdc.c index 0784bd998..f23ce3252 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -1793,24 +1793,17 @@ void fdc_callback() return; case 0x0e: /*Dump registers*/ fdc.stat = (fdc.stat & 0xf) | 0xd0; - fdc.res[3] = fdc.pcn[0]; - fdc.res[4] = fdc.pcn[1]; - fdc.res[5] = fdc.pcn[2]; - fdc.res[6] = fdc.pcn[3]; - fdc.res[7] = fdc.specify[0]; - fdc.res[8] = fdc.specify[1]; - fdc.res[9] = fdc.eot[fdc.drive]; - fdc.res[10] = (fdc.perp & 0x7f) | ((fdc.lock) ? 0x80 : 0); - if (AT) - { - fdc.res[11] = fdc.config; - fdc.res[12] = fdc.pretrk; - paramstogo=12; - } - else - { - paramstogo=10; - } + fdc.res[1] = fdc.pcn[0]; + fdc.res[2] = fdc.pcn[1]; + fdc.res[3] = fdc.pcn[2]; + fdc.res[4] = fdc.pcn[3]; + fdc.res[5] = fdc.specify[0]; + fdc.res[6] = fdc.specify[1]; + fdc.res[7] = fdc.eot[fdc.drive]; + fdc.res[8] = (fdc.perp & 0x7f) | ((fdc.lock) ? 0x80 : 0); + fdc.res[9] = fdc.config; + fdc.res[10] = fdc.pretrk; + paramstogo = 10; discint=0; disctime = 0; return; diff --git a/src/mem.c b/src/mem.c index 733bf0980..c86f723ec 100644 --- a/src/mem.c +++ b/src/mem.c @@ -405,6 +405,7 @@ int loadbios() fclose(f); return 1; +#if 0 case ROM_ACER386: f=romfopen("roms/acer386/acer386.bin","rb"); if (!f) break; @@ -416,6 +417,7 @@ int loadbios() if (!f) break; fclose(f); return 1; +#endif case ROM_AMI286: f=romfopen("roms/ami286/amic206.bin","rb"); @@ -506,6 +508,7 @@ int loadbios() //is486=1; return 1; +#if 0 case ROM_PCI486: f=romfopen("roms/hot-433/hot-433.ami","rb"); if (!f) break; @@ -514,6 +517,7 @@ int loadbios() biosmask = 0x1ffff; //is486=1; return 1; +#endif case ROM_SIS496: f = romfopen("roms/sis496/SIS496-1.AWA", "rb"); @@ -663,6 +667,7 @@ int loadbios() fclose(f); return 1; +#if 0 case ROM_PX386: /*Phoenix 80386 BIOS*/ f=romfopen("roms/px386/3iip001l.bin","rb"); ff=romfopen("roms/px386/3iip001h.bin","rb"); @@ -675,6 +680,7 @@ int loadbios() fclose(ff); fclose(f); return 1; +#endif case ROM_DTK386: /*Uses NEAT chipset*/ f = romfopen("roms/dtk386/3cto001.bin", "rb"); diff --git a/src/model.c b/src/model.c index 72e3011b7..51689152f 100644 --- a/src/model.c +++ b/src/model.c @@ -13,7 +13,7 @@ #include "io.h" #include "rom.h" -#include "acer386sx.h" +// #include "acer386sx.h" #include "acerm3a.h" #include "ali1429.h" #include "amstrad.h" @@ -88,8 +88,8 @@ void ps1_m2121_init(); void ps2_m30_286_init(); void at_neat_init(); void at_scat_init(); -void at_acer386sx_init(); -void at_82335_init(); +// void at_acer386sx_init(); +// void at_82335_init(); void at_wd76c10_init(); void at_ali1429_init(); void at_headland_init(); @@ -157,9 +157,9 @@ MODEL models[] = {"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, +/* {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, */ {"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, - {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_82335_init, NULL}, +/* {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_82335_init, NULL}, */ {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ {"Amstrad MegaPC 386DX",ROM_MEGAPCDX, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, @@ -411,7 +411,7 @@ void at_scat_init() scat_init(); } -void at_acer386sx_init() +/* void at_acer386sx_init() { at_init(); acer386sx_init(); @@ -421,7 +421,7 @@ void at_82335_init() { at_init(); i82335_init(); -} +} */ void at_wd76c10_init() { diff --git a/src/nvr.c b/src/nvr.c index abecfe029..4f83c9c2e 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -209,7 +209,7 @@ void loadnvr() case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); /*nvrmask = 127; */break; case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M30_286: f = romfopen("nvr/ibmps2_m30_286.nvr", "rb"); /*nvrmask = 127; */break; + case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); /*nvrmask = 127; */break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; @@ -218,7 +218,7 @@ void loadnvr() case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; - case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break; + /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break; */ case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "rb"); nvrmask = 127; break; case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "rb"); nvrmask = 127; break; @@ -229,7 +229,7 @@ void loadnvr() case ROM_430VX: f = romfopen(nvr_concat("430vx.nvr"), "rb"); nvrmask = 127; break; case ROM_REVENGE: f = romfopen(nvr_concat("revenge.nvr"), "rb"); nvrmask = 127; break; case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "rb"); nvrmask = 127; break; - case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "rb"); nvrmask = 127; break; + /* case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "rb"); nvrmask = 127; break; */ case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "rb"); nvrmask = 127; break; case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "rb"); nvrmask = 127; break; @@ -293,7 +293,7 @@ void savenvr() case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "wb"); break; case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "wb"); break; case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "wb"); break; - case ROM_IBMPS2_M30_286: f = romfopen("nvr/ibmps2_m30_286.nvr", "wb"); break; + case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "wb"); break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; @@ -302,7 +302,7 @@ void savenvr() case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; - case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break; + /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break; */ case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "wb"); break; case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "wb"); break; case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "wb"); break; @@ -313,7 +313,7 @@ void savenvr() case ROM_430VX: f = romfopen(nvr_concat("430vx.nvr"), "wb"); break; case ROM_REVENGE: f = romfopen(nvr_concat("revenge.nvr"), "wb"); break; case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "wb"); break; - case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "wb"); break; + /* case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "wb"); break; */ case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "wb"); break; case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "wb"); break; case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "wb"); break; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index deb9e69e7..98b21e7c7 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -181,6 +181,8 @@ typedef struct voodoo_params_t uint32_t front_offset; uint32_t swapbufferCMD; + + uint32_t stipple; } voodoo_params_t; typedef struct texture_t @@ -383,7 +385,7 @@ typedef struct voodoo_t uint8_t thefilterb[256][256]; // for blue /* the voodoo adds purple lines for some reason */ - uint16_t purpleline[1024]; + uint16_t purpleline[256][3]; texture_t texture_cache[2][TEX_CACHE_MAX]; uint8_t texture_present[2][4096]; @@ -494,7 +496,7 @@ enum SST_chromaKey = 0x134, SST_userIntrCMD = 0x13c, - + SST_stipple = 0x140, SST_color0 = 0x144, SST_color1 = 0x148, @@ -4508,7 +4510,9 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.chromaKey_b = val & 0xff; voodoo->params.chromaKey = val & 0xffffff; break; - + case SST_stipple: + voodoo->params.stipple = val; + break; case SST_color0: voodoo->params.color0 = val; break; @@ -5630,6 +5634,18 @@ static uint16_t voodoo_readw(uint32_t addr, void *p) return 0xffff; } +static void voodoo_flush(voodoo_t *voodoo) +{ + voodoo->flush = 1; + while (!FIFO_EMPTY) + { + wake_fifo_thread_now(voodoo); + thread_wait_event(voodoo->fifo_not_full_event, 1); + } + wait_for_render_thread_idle(voodoo); + voodoo->flush = 0; +} + static uint32_t voodoo_readl(uint32_t addr, void *p) { voodoo_t *voodoo = (voodoo_t *)p; @@ -5675,19 +5691,48 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) if (!voodoo->voodoo_busy) wake_fifo_thread(voodoo); break; - - case SST_lfbMode: - voodoo->flush = 1; - while (!FIFO_EMPTY) - { - wake_fifo_thread_now(voodoo); - thread_wait_event(voodoo->fifo_not_full_event, 1); - } - wait_for_render_thread_idle(voodoo); - voodoo->flush = 0; + case SST_fbzColorPath: + voodoo_flush(voodoo); + temp = voodoo->params.fbzColorPath; + break; + case SST_fogMode: + voodoo_flush(voodoo); + temp = voodoo->params.fogMode; + break; + case SST_alphaMode: + voodoo_flush(voodoo); + temp = voodoo->params.alphaMode; + break; + case SST_fbzMode: + voodoo_flush(voodoo); + temp = voodoo->params.fbzMode; + break; + case SST_lfbMode: + voodoo_flush(voodoo); temp = voodoo->lfbMode; break; + case SST_clipLeftRight: + voodoo_flush(voodoo); + temp = voodoo->params.clipRight | (voodoo->params.clipLeft << 16); + break; + case SST_clipLowYHighY: + voodoo_flush(voodoo); + temp = voodoo->params.clipHighY | (voodoo->params.clipLowY << 16); + break; + + case SST_stipple: + voodoo_flush(voodoo); + temp = voodoo->params.stipple; + break; + case SST_color0: + voodoo_flush(voodoo); + temp = voodoo->params.color0; + break; + case SST_color1: + voodoo_flush(voodoo); + temp = voodoo->params.color1; + break; case SST_fbiPixelsIn: temp = voodoo->fbiPixelsIn & 0xffffff; @@ -6470,11 +6515,16 @@ static void voodoo_calc_clutData(voodoo_t *voodoo) static int FILTCAP, FILTCAPG, FILTCAPB = 0; /* color filter threshold values */ -static void voodoo_generate_filter(voodoo_t *voodoo) +static void voodoo_generate_filter_v1(voodoo_t *voodoo) { int g, h; float difference, diffg, diffb; float thiscol, thiscolg, thiscolb, lined; + float fcr, fcg, fcb; + + fcr = FILTCAP * 5; + fcg = FILTCAPG * 6; + fcb = FILTCAPB * 5; for (g=0;g FILTCAP) difference = FILTCAP; if (difference < -FILTCAP) @@ -6498,10 +6550,18 @@ static void voodoo_generate_filter(voodoo_t *voodoo) diffb = FILTCAPB; if (diffb < -FILTCAPB) diffb = -FILTCAPB; - - thiscol = g + (difference / 2); - thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ - thiscolb = g + (diffb / 2); + + // hack - to make it not bleed onto black + //if (g == 0){ + //difference = diffg = diffb = 0; + //} + + if ((difference < fcr) || (-difference > -fcr)) + thiscol = g + (difference / 2); + if ((diffg < fcg) || (-diffg > -fcg)) + thiscolg = g + (diffg / 2); /* need these divides so we can actually undither! */ + if ((diffb < fcb) || (-diffb > -fcb)) + thiscolb = g + (diffb / 2); if (thiscol < 0) thiscol = 0; @@ -6523,10 +6583,115 @@ static void voodoo_generate_filter(voodoo_t *voodoo) voodoo->thefilterb[g][h] = thiscolb; } + lined = g + 4; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][2] = lined; + + lined = g + 0; + if (lined > 255) + lined = 255; + voodoo->purpleline[g][1] = lined; + } +} + +static void voodoo_generate_filter_v2(voodoo_t *voodoo) +{ + int g, h; + float difference; + float thiscol, thiscolg, thiscolb, lined; + float clr, clg, clb = 0; + float fcr, fcg, fcb = 0; + + // pre-clamping + + fcr = FILTCAP; + fcg = FILTCAPG; + fcb = FILTCAPB; + + if (fcr > 32) fcr = 32; + if (fcg > 32) fcg = 32; + if (fcb > 32) fcb = 32; + + for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into + { + for (h=0;h<256;h++) // pixel 2 - our main pixel + { + float avg; + float avgdiff; + + difference = (float)(g - h); + avg = (float)((g + g + g + g + h) / 5); + avgdiff = avg - (float)((g + h + h + h + h) / 5); + if (avgdiff < 0) avgdiff *= -1; + if (difference < 0) difference *= -1; + + thiscol = thiscolg = thiscolb = g; + + // try lighten + if (h > g) + { + clr = clg = clb = avgdiff; + + if (clr>fcr) clr=fcr; + if (clg>fcg) clg=fcg; + if (clb>fcb) clb=fcb; + + + thiscol = g + clr; + thiscolg = g + clg; + thiscolb = g + clb; + + if (thiscol>g+FILTCAP) + thiscol=g+FILTCAP; + if (thiscolg>g+FILTCAPG) + thiscolg=g+FILTCAPG; + if (thiscolb>g+FILTCAPB) + thiscolb=g+FILTCAPB; + + + if (thiscol>g+avgdiff) + thiscol=g+avgdiff; + if (thiscolg>g+avgdiff) + thiscolg=g+avgdiff; + if (thiscolb>g+avgdiff) + thiscolb=g+avgdiff; + + } + + if (difference > FILTCAP) + thiscol = g; + if (difference > FILTCAPG) + thiscolg = g; + if (difference > FILTCAPB) + thiscolb = g; + + // clamp + if (thiscol < 0) thiscol = 0; + if (thiscolg < 0) thiscolg = 0; + if (thiscolb < 0) thiscolb = 0; + + if (thiscol > 255) thiscol = 255; + if (thiscolg > 255) thiscolg = 255; + if (thiscolb > 255) thiscolb = 255; + + // add to the table + voodoo->thefilter[g][h] = (thiscol); + voodoo->thefilterg[g][h] = (thiscolg); + voodoo->thefilterb[g][h] = (thiscolb); + + // debug the ones that don't give us much of a difference + //if (difference < FILTCAP) + //pclog("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); + } + lined = g + 3; if (lined > 255) lined = 255; - voodoo->purpleline[g] = lined; + voodoo->purpleline[g][0] = lined; + voodoo->purpleline[g][1] = 0; + voodoo->purpleline[g][2] = lined; } } @@ -6551,51 +6716,32 @@ static void voodoo_threshold_check(voodoo_t *voodoo) pclog("Voodoo Filter Threshold Check: %06x - RED %i GREEN %i BLUE %i\n", voodoo->scrfilterThreshold, r, g, b); voodoo->scrfilterThresholdOld = voodoo->scrfilterThreshold; - voodoo_generate_filter(voodoo); + + if (voodoo->type == VOODOO_2) + voodoo_generate_filter_v2(voodoo); + else + voodoo_generate_filter_v1(voodoo); } } -static void voodoo_filterline(voodoo_t *voodoo, uint16_t *fil, int column, uint16_t *src, int line) +static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) { int x; + // Scratchpad for avoiding feedback streaks + uint8_t fil3[(voodoo->h_disp) * 3]; + /* 16 to 32-bit */ for (x=0; x> 5) & 63) << 2); /* Shift to 32-bit */ - fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - } + fil[x*3] = ((src[x] & 31) << 3); + fil[x*3+1] = (((src[x] >> 5) & 63) << 2); + fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - fil[x*3] = 0; - fil[x*3+1] = 0; /* Keep the compiler happy */ - fil[x*3+2] = 0; - - /* filtering time */ - - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil[(x-1)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil[(x-1)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - for (x=0; xthefilterb[fil[x*3]][fil[ (x+1) *3]]; - fil[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x+1) *3+1]]; - fil[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x+1) *3+2]]; - } - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil[(x-1)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil[(x-1)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; - } - for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; - fil[(x-1)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; - fil[(x-1)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; + // Copy to our scratchpads + fil3[x*3+0] = fil[x*3+0]; + fil3[x*3+1] = fil[x*3+1]; + fil3[x*3+2] = fil[x*3+2]; } @@ -6605,12 +6751,110 @@ static void voodoo_filterline(voodoo_t *voodoo, uint16_t *fil, int column, uint1 { for (x=0; xpurpleline[fil[x*3]]; - fil[x*3+2] = voodoo->purpleline[fil[x*3+2]]; + fil[x*3] = voodoo->purpleline[fil[x*3]][0]; + fil[x*3+1] = voodoo->purpleline[fil[x*3+1]][1]; + fil[x*3+2] = voodoo->purpleline[fil[x*3+2]][2]; } } + + + /* filtering time */ + + for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; + fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; + fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; + } + + for (x=1; xthefilterb[fil3[x*3]][fil3[ (x-1) *3]]; + fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x-1) *3+1]]; + fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x-1) *3+2]]; + } + + for (x=1; xthefilterb[fil[x*3]][fil[ (x-1) *3]]; + fil3[(x)*3+1] = voodoo->thefilterg[fil[x*3+1]][fil[ (x-1) *3+1]]; + fil3[(x)*3+2] = voodoo->thefilter[fil[x*3+2]][fil[ (x-1) *3+2]]; + } + + for (x=0; xthefilterb[fil3[x*3]][fil3[ (x+1) *3]]; + fil[(x)*3+1] = voodoo->thefilterg[fil3[x*3+1]][fil3[ (x+1) *3+1]]; + fil[(x)*3+2] = voodoo->thefilter[fil3[x*3+2]][fil3[ (x+1) *3+2]]; + } } + +static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uint16_t *src, int line) +{ + int x; + + // Scratchpad for blending filter + uint8_t fil3[(voodoo->h_disp) * 3]; + + /* 16 to 32-bit */ + for (x=0; x> 5) & 63) << 2); + fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); + } + + /* filtering time */ + + for (x=1; xthefilterb [((src[x+3] & 31) << 3)] [((src[x] & 31) << 3)]; + fil3[(x+3)*3+1] = voodoo->thefilterg [(((src[x+3] >> 5) & 63) << 2)] [(((src[x] >> 5) & 63) << 2)]; + fil3[(x+3)*3+2] = voodoo->thefilter [(((src[x+3] >> 11) & 31) << 3)] [(((src[x] >> 11) & 31) << 3)]; + + fil[(x+2)*3] = voodoo->thefilterb [fil3[(x+2)*3]][((src[x] & 31) << 3)]; + fil[(x+2)*3+1] = voodoo->thefilterg [fil3[(x+2)*3+1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x+2)*3+2] = voodoo->thefilter [fil3[(x+2)*3+2]][(((src[x] >> 11) & 31) << 3)]; + + fil3[(x+1)*3] = voodoo->thefilterb [fil[(x+1)*3]][((src[x] & 31) << 3)]; + fil3[(x+1)*3+1] = voodoo->thefilterg [fil[(x+1)*3+1]][(((src[x] >> 5) & 63) << 2)]; + fil3[(x+1)*3+2] = voodoo->thefilter [fil[(x+1)*3+2]][(((src[x] >> 11) & 31) << 3)]; + + fil[(x-1)*3] = voodoo->thefilterb [fil3[(x-1)*3]][((src[x] & 31) << 3)]; + fil[(x-1)*3+1] = voodoo->thefilterg [fil3[(x-1)*3+1]][(((src[x] >> 5) & 63) << 2)]; + fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; + } + + // unroll for edge cases + + fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; + fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; + fil3[(column-3)*3+2] = voodoo->thefilter [(((src[column-3] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; + + fil3[(column-2)*3] = voodoo->thefilterb [((src[column-2] & 31) << 3)] [((src[column] & 31) << 3)]; + fil3[(column-2)*3+1] = voodoo->thefilterg [(((src[column-2] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; + fil3[(column-2)*3+2] = voodoo->thefilter [(((src[column-2] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; + + fil3[(column-1)*3] = voodoo->thefilterb [((src[column-1] & 31) << 3)] [((src[column] & 31) << 3)]; + fil3[(column-1)*3+1] = voodoo->thefilterg [(((src[column-1] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; + fil3[(column-1)*3+2] = voodoo->thefilter [(((src[column-1] >> 11) & 31) << 3)] [(((src[column] >> 11) & 31) << 3)]; + + fil[(column-2)*3] = voodoo->thefilterb [fil3[(column-2)*3]][((src[column] & 31) << 3)]; + fil[(column-2)*3+1] = voodoo->thefilterg [fil3[(column-2)*3+1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column-2)*3+2] = voodoo->thefilter [fil3[(column-2)*3+2]][(((src[column] >> 11) & 31) << 3)]; + + fil[(column-1)*3] = voodoo->thefilterb [fil3[(column-1)*3]][((src[column] & 31) << 3)]; + fil[(column-1)*3+1] = voodoo->thefilterg [fil3[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; + fil[(column-1)*3+2] = voodoo->thefilter [fil3[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; + + fil3[(column-1)*3] = voodoo->thefilterb [fil[(column-1)*3]][((src[column] & 31) << 3)]; + fil3[(column-1)*3+1] = voodoo->thefilterg [fil[(column-1)*3+1]][(((src[column] >> 5) & 63) << 2)]; + fil3[(column-1)*3+2] = voodoo->thefilter [fil[(column-1)*3+2]][(((src[column] >> 11) & 31) << 3)]; +} + + void voodoo_callback(void *p) { voodoo_t *voodoo = (voodoo_t *)p; @@ -6640,9 +6884,12 @@ void voodoo_callback(void *p) if (voodoo->scrfilter && voodoo->scrfilterEnabled) { int j, offset; - uint16_t fil[(voodoo->h_disp + 1) * 3]; /* interleaved 24-bit RGB */ + uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ - voodoo_filterline(voodoo, fil, voodoo->h_disp, src, voodoo->line); + if (voodoo->type == VOODOO_2) + voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line); + else + voodoo_filterline_v1(voodoo, fil, voodoo->h_disp, src, voodoo->line); for (x = 0; x < voodoo->h_disp; x++) { @@ -6790,7 +7037,10 @@ void *voodoo_init() break; } - voodoo_generate_filter(voodoo); /*generate filter lookup tables*/ + if (voodoo->type == VOODOO_2) /*generate filter lookup tables*/ + voodoo_generate_filter_v2(voodoo); + else + voodoo_generate_filter_v1(voodoo); pci_add(voodoo_pci_read, voodoo_pci_write, voodoo); diff --git a/src/win-hdconf.c b/src/win-hdconf.c index a5f241a3d..98d5dc42e 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -309,7 +309,7 @@ BOOL CALLBACK hdconf_common_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&full_size_bytes, 1, 8, f); /* 0000000C: Full size of the data (32-bit) */ + fwrite(&full_size_bytes, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ fwrite(&hd_new_spt, 1, 4, f); /* 00000014: Sectors per cylinder */ fwrite(&hd_new_hpc, 1, 4, f); /* 00000018: Heads per cylinder */ From 400be1286e161f7e74db4c3ee81382e59478b59b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 23 Feb 2017 20:16:24 +0100 Subject: [PATCH 107/392] 86Box v1.01 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc6c5a1c0..78e84209c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9c72c48c9..50fed4459 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 1057a7c07bc895082888d70b981200ff93a1f356 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 23 Feb 2017 20:35:16 +0100 Subject: [PATCH 108/392] Version bump to v1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index 57ac3cf02..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.01" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 78e84209c..fc6c5a1c0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 50fed4459..9c72c48c9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From a7d949070105549036672e490e1a95df1bb46a5a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 Feb 2017 00:15:24 +0100 Subject: [PATCH 109/392] Fixed reading of sector-based floppy images; Changed version to 1.02. --- src/86box.h | 2 +- src/disc_img.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..808d46dac 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.02" diff --git a/src/disc_img.c b/src/disc_img.c index 645505199..f7b88e882 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -618,7 +618,7 @@ void img_seek(int drive, int track) } else { - read_bytes = fread(img[drive].track_data[side], img[drive].sectors * ssize, 1, img[drive].f); + read_bytes = fread(img[drive].track_data[side], 1, img[drive].sectors * ssize, img[drive].f); if (read_bytes < (img[drive].sectors * ssize)) { memset(img[drive].track_data[side] + read_bytes, 0xf6, (img[drive].sectors * ssize) - read_bytes); From f305af6416d13f82b8d1f6199af9a00687aa4368 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 Feb 2017 00:54:30 +0100 Subject: [PATCH 110/392] 86Box v1.02 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc6c5a1c0..78e84209c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9c72c48c9..50fed4459 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 1d281ab0c3f858bb4886be89f2572eb0e47dc159 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 24 Feb 2017 01:57:54 +0100 Subject: [PATCH 111/392] Version changed to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index 808d46dac..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.02" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 78e84209c..fc6c5a1c0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 50fed4459..9c72c48c9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From ef41672b2057f73dbe7c2aa4e5bc5b4987b69d16 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 25 Feb 2017 20:18:45 +0100 Subject: [PATCH 112/392] WIN_SPECIFY command is now no longer strict on translation parameters with HDX images, fixes > 503 MB HDX images on 440FX; Applied all mainline PCem commits (changes configuration files!); Fixed EGA and (S)VGA overscan border drawing; Added ability to invert the colors when using a (S)VGA graphics card, to appear like an early laptop monitor; Changed version to 1.03. --- src/86box.h | 2 +- src/ibm.h | 4 + src/ide.c | 8 +- src/model.c | 145 ++++++++++++++++-------------- src/model.h | 5 +- src/pc.c | 16 +++- src/pc.rc | 5 +- src/resources.h | 13 +-- src/vid_ega.c | 10 +-- src/vid_svga.c | 14 +-- src/vid_svga_render.c | 200 +++++++++++++++++++++++------------------- src/video.c | 102 ++++++++++++--------- src/video.h | 2 + src/win.c | 5 ++ 14 files changed, 301 insertions(+), 230 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..e3971f3c3 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.03" diff --git a/src/ibm.h b/src/ibm.h index c57e4abe8..eebb072b4 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -635,3 +635,7 @@ void trc_init(); extern int enable_xtide; extern int enable_external_fpu; + +extern int invert_display; + +uint32_t svga_color_transform(uint32_t color); diff --git a/src/ide.c b/src/ide.c index db88e534d..2750802b8 100644 --- a/src/ide.c +++ b/src/ide.c @@ -2064,8 +2064,8 @@ void callbackide(int ide_board) { goto abort_cmd; } - if (((hdc[cur_ide[ide->board]].at_hpc == 0) && (hdc[cur_ide[ide->board]].at_spt == 0)) || (ide->hdi != 2)) - { + /* if (((hdc[cur_ide[ide->board]].at_hpc == 0) && (hdc[cur_ide[ide->board]].at_spt == 0)) || (ide->hdi != 2)) + { */ full_size /= (ide->head+1); full_size /= ide->secount; ide->specify_success = 1; @@ -2077,7 +2077,7 @@ void callbackide(int ide_board) fwrite(&(hdc[cur_ide[ide->board]].at_spt), 1, 4, ide->hdfile); fwrite(&(hdc[cur_ide[ide->board]].at_hpc), 1, 4, ide->hdfile); } - } + /* } else { if ((hdc[cur_ide[ide->board]].at_hpc == (ide->head + 1)) && (hdc[cur_ide[ide->board]].at_spt == ide->secount)) @@ -2089,7 +2089,7 @@ void callbackide(int ide_board) ide_log("WIN_SPECIFY error (%04X, %04X)\n", ide->head + 1, ide->secount); ide->specify_success = 0; } - } + } */ ide->spt=ide->secount; ide->hpc=ide->head+1; ide->atastat = READY_STAT | DSC_STAT; diff --git a/src/model.c b/src/model.c index 51689152f..41dde94d3 100644 --- a/src/model.c +++ b/src/model.c @@ -125,74 +125,66 @@ PCI_RESET pci_reset_handler; MODEL models[] = { - {"IBM PC", ROM_IBMPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, { "", cpus_pcjr, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT",ROM_LTXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, { "", cpus_8088, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, { "", cpus_8088, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2,{ "", cpus_8086, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, { "", cpus_pc1512, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Euro PC", ROM_EUROPC, { "", cpus_8086, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, { "", cpus_8086, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, { "", cpus_ibmat, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121+ISA", ROM_IBMPS1_2121_ISA, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, { "", cpus_ps2_m30_286, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, -/* {"Acer 386SX25/N", ROM_ACER386, { "Intel", cpus_acer, "", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_acer386sx_init, NULL}, */ - {"DTK 386SX clone", ROM_DTK386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, -/* {"Phoenix 386 clone", ROM_PX386, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 16, 1, at_82335_init, NULL}, */ - {"Amstrad MegaPC", ROM_MEGAPC, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, + {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, + {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, + {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ - {"Amstrad MegaPC 386DX",ROM_MEGAPCDX, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 486 clone", ROM_AMI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, -/* {"AMI WinBIOS 486 PCI", ROM_PCI486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_um8881f_init, NULL},*/ - {"DTK PKM-0038S E-2", ROM_DTK486, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_dtk486_init, NULL}, - {"Award SiS 496/497", ROM_SIS496, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_sis496_init, NULL}, - {"Rise Computer R418", ROM_R418, { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486}, 0, MODEL_AT, 1, 256, 1, at_r418_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, { "Intel", cpus_Pentium5V, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_batman_init, NULL}, - {"Micro Star 586MC1", ROM_586MC1, { "Intel", cpus_Pentium5V50, "",NULL, "", NULL}, 0, MODEL_AT, 1, 128, 1, at_586mc1_init, NULL}, - {"Intel Premiere/PCI II",ROM_PLATO, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, -#if 0 - {"NEC PowerMate V", ROM_POWERMATE_V, { "Intel", cpus_PentiumS5,"IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 128, 1, at_powermate_v_init, NULL}, -#endif - {"Intel Advanced/ATX", ROM_THOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL}, - // {"Intel Advanced/ML", ROM_MARL, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_marl_init, NULL}, - {"Acer M3a", ROM_ACERM3A, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_acerm3a_init, NULL}, - {"Acer V35N", ROM_ACERV35N, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 512, 1, at_p55t2p4_init, NULL}, - {"Award 430VX PCI", ROM_430VX, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_i430vx_init, NULL}, - {"Epox P55-VA", ROM_P55VA, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 256, 1, at_p55tvp4_init, NULL}, - {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro, "", NULL, "", NULL}, 0, MODEL_AT|MODEL_PS2, 1, 1024, 1, at_i440fx_init, NULL}, - // {"Award 440FX PCI", ROM_440FX, { "Intel", cpus_PentiumPro,"Klamath", cpus_Pentium2, "Deschutes", cpus_Pentium2D}, 0, MODEL_AT|MODEL_PS2, 1, 1024, 1, at_i440fx_init, NULL}, - {"", -1, {"", 0, "", 0, "", 0}, 0,0,0, 0} + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, + {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, + {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_dtk486_init, NULL}, + {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_sis496_init, NULL}, + {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_r418_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_batman_init, NULL}, + {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 128, 1, at_586mc1_init, NULL}, + {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, + {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_acerm3a_init, NULL}, + {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_acerv35n_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_p55t2p4_init, NULL}, + {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_i430vx_init, NULL}, + {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_p55va_init, NULL}, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_p55tvp4_init, NULL}, + {"Award 440FX PCI", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 1024, 1, at_i440fx_init, NULL}, + {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; int model_count() @@ -230,6 +222,25 @@ device_t *model_getdevice(int model) return models[model].device; } +char *model_get_internal_name() +{ + return models[model].internal_name; +} + +int model_get_model_from_internal_name(char *s) +{ + int c = 0; + + while (models[c].id != -1) + { + if (!strcmp(models[c].internal_name, s)) + return c; + c++; + } + + return 0; +} + void common_init() { dma_init(); diff --git a/src/model.h b/src/model.h index 8eb2cc152..eceda3a39 100644 --- a/src/model.h +++ b/src/model.h @@ -11,8 +11,9 @@ typedef struct { - char name[24]; + char name[32]; int id; + char internal_name[24]; struct { char name[16]; @@ -34,5 +35,7 @@ int model_count(); int model_getromset(); int model_getmodel(int romset); char *model_getname(); +char *model_get_internal_name(); +int model_get_model_from_internal_name(char *s); void model_init(); struct device_t *model_getdevice(int model); diff --git a/src/pc.c b/src/pc.c index de8f5cc85..511de3999 100644 --- a/src/pc.c +++ b/src/pc.c @@ -745,7 +745,11 @@ void loadconfig(char *fn) inum = ethif + 1; network_card_current = config_get_int(NULL, "netcard", NE2000); - model = config_get_int(NULL, "model", 14); + p = (char *)config_get_string(NULL, "model", ""); + if (p) + model = model_get_model_from_internal_name(p); + else + model = 0; if (model >= model_count()) model = model_count() - 1; @@ -757,7 +761,11 @@ void loadconfig(char *fn) cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); - gfxcard = config_get_int(NULL, "gfxcard", 0); + p = (char *)config_get_string(NULL, "gfxcard", ""); + if (p) + gfxcard = video_get_video_from_internal_name(p); + else + gfxcard = 0; video_speed = config_get_int(NULL, "video_speed", 3); sound_card_current = config_get_int(NULL, "sndcard", SB2); @@ -986,13 +994,13 @@ void saveconfig() config_set_int(NULL, "netinterface", ethif); config_set_int(NULL, "netcard", network_card_current); - config_set_int(NULL, "model", model); + config_set_string(NULL, "model", model_get_internal_name()); config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); config_set_int(NULL, "cpu", cpu); config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); config_set_int(NULL, "cpu_waitstates", cpu_waitstates); - config_set_int(NULL, "gfxcard", gfxcard); + config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); config_set_int(NULL, "video_speed", video_speed); config_set_int(NULL, "sndcard", sound_card_current); config_set_int(NULL, "cpu_speed", cpuspeed); diff --git a/src/pc.rc b/src/pc.rc index 18c05c9cf..4b7297461 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -293,6 +293,8 @@ BEGIN MENUITEM "&DirectDraw", IDM_VID_DDRAW MENUITEM "Direct&3D 9", IDM_VID_D3D MENUITEM SEPARATOR + MENUITEM "D&isc activity flash", IDM_VID_FLASH + MENUITEM SEPARATOR MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" BEGIN @@ -301,12 +303,11 @@ BEGIN MENUITEM "&Square pixels", IDM_VID_FS_SQ MENUITEM "&Integer scale", IDM_VID_FS_INT END + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT MENUITEM SEPARATOR MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN MENUITEM SEPARATOR - MENUITEM "D&isc activity flash", IDM_VID_FLASH - MENUITEM SEPARATOR MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END MENUITEM "&Status", IDM_STATUS diff --git a/src/resources.h b/src/resources.h index 41b018c9f..d216f0f7e 100644 --- a/src/resources.h +++ b/src/resources.h @@ -30,12 +30,13 @@ #define IDM_VID_OVERSCAN 40076 #define IDM_VID_FLASH 40077 #define IDM_VID_SCREENSHOT 40078 -#define IDM_DISC_3 40079 -#define IDM_DISC_4 40080 -#define IDM_EJECT_3 40081 -#define IDM_EJECT_4 40082 -#define IDM_DISC_3_WP 40083 -#define IDM_DISC_4_WP 40084 +#define IDM_VID_INVERT 40079 +#define IDM_DISC_3 40081 +#define IDM_DISC_4 40082 +#define IDM_EJECT_3 40083 +#define IDM_EJECT_4 40084 +#define IDM_DISC_3_WP 40085 +#define IDM_DISC_4_WP 40086 #define IDM_CDROM_1_ISO 40100 #define IDM_CDROM_1_RELOAD 40101 #define IDM_CDROM_1_EMPTY 40200 diff --git a/src/vid_ega.c b/src/vid_ega.c index dc8ec33a8..a900b3e49 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -597,10 +597,10 @@ void ega_poll(void *p) { if ((x >= 160) && ((ega->lastline - ega->firstline) >= 120)) { - for (i = 0; i < 14; i++) + for (i = 0; i < y_add; i++) { q = &((uint32_t *)buffer32->line[i])[32]; - r = &((uint32_t *)buffer32->line[ysize + y_add_ex - 1 - i])[32]; + r = &((uint32_t *)buffer32->line[ysize + y_add + i])[32]; for (j = 0; j < (xsize + x_add_ex); j++) { @@ -609,14 +609,14 @@ void ega_poll(void *p) } } - for (i = 14; i < (ysize + 14); i ++) + for (i = y_add; i < (ysize + y_add); i ++) { q = &((uint32_t *)buffer32->line[i])[32]; - for (j = 0; j < 8; j++) + for (j = 0; j < x_add; j++) { q[j] = ega->pallook[ega->attrregs[0x11]]; - q[xsize + x_add_ex - 1 - j] = ega->pallook[ega->attrregs[0x11]]; + q[xsize + x_add + j] = ega->pallook[ega->attrregs[0x11]]; } } } diff --git a/src/vid_svga.c b/src/vid_svga.c index 0a8970b43..57999469f 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -1605,26 +1605,26 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { if ((wx >= 160) && ((wy + 1) >= 120)) { - for (i = 0; i < 16; i++) + for (i = 0; i < (y_add >> 1); i++) { p = &((uint32_t *)buffer32->line[i])[32]; - q = &((uint32_t *)buffer32->line[ysize + y_add - 1 - i])[32]; + q = &((uint32_t *)buffer32->line[ysize + (y_add >> 1) + i])[32]; for (j = 0; j < (xsize + x_add); j++) { - p[j] = svga->pallook[svga->attrregs[0x11]]; - q[j] = svga->pallook[svga->attrregs[0x11]]; + p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + q[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); } } - for (i = 16; i < (ysize + 16); i ++) + for (i = (y_add >> 1); i < (ysize + (y_add >> 1)); i ++) { p = &((uint32_t *)buffer32->line[i])[32]; for (j = 0; j < 8; j++) { - p[j] = svga->pallook[svga->attrregs[0x11]]; - p[xsize + x_add - 1 - j] = svga->pallook[svga->attrregs[0x11]]; + p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + p[xsize + (x_add >> 1) + j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); } } } diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 0565b0281..56907c4ba 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -8,6 +8,24 @@ #include "vid_svga_render.h" #include +int invert_display = 0; + +uint32_t svga_color_transform(uint32_t color) +{ + uint32_t temp = 0; + if (invert_display) + { + temp |= (0xff - (color & 0xff)); + temp |= (0xff00 - (color & 0xff00)); + temp |= (0xff0000 - (color & 0xff0000)); + } + else + { + temp = color; + } + return temp; +} + void svga_render_blank(svga_t *svga) { int x, xx; @@ -23,16 +41,16 @@ void svga_render_blank(svga_t *svga) switch (svga->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); break; case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); break; case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); break; case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); break; } } @@ -86,16 +104,16 @@ void svga_render_text_40(svga_t *svga) if (svga->seqregs[1] & 1) { for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? svga_color_transform(fg) : svga_color_transform(bg); } else { for (xx = 0; xx < 16; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg; + p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? svga_color_transform(fg) : svga_color_transform(bg); if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[16] = p[17] = bg; + p[16] = p[17] = svga_color_transform(bg); else - p[16] = p[17] = (dat & 1) ? fg : bg; + p[16] = p[17] = (dat & 1) ? svga_color_transform(fg) : svga_color_transform(bg); } svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); @@ -151,7 +169,7 @@ void svga_render_text_40_12(svga_t *svga) dat = *(uint16_t *) &(svga->vram[charaddr + (svga->sc << 2) - 1]); for (xx = 0; xx < 24; xx += 2) - p[xx] = p[xx + 1] = (dat & (0x800 >> (xx >> 1))) ? fg : bg; + p[xx] = p[xx + 1] = (dat & (0x800 >> (xx >> 1))) ? svga_color_transform(fg) : svga_color_transform(bg); svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); p += xinc; @@ -207,16 +225,16 @@ void svga_render_text_80(svga_t *svga) if (svga->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + p[xx] = (dat & (0x80 >> xx)) ? svga_color_transform(fg) : svga_color_transform(bg); } else { for (xx = 0; xx < 8; xx++) - p[xx] = (dat & (0x80 >> xx)) ? fg : bg; + p[xx] = (dat & (0x80 >> xx)) ? svga_color_transform(fg) : svga_color_transform(bg); if ((chr & ~0x1F) != 0xC0 || !(svga->attrregs[0x10] & 4)) - p[8] = bg; + p[8] = svga_color_transform(bg); else - p[8] = (dat & 1) ? fg : bg; + p[8] = (dat & 1) ? svga_color_transform(fg) : svga_color_transform(bg); } svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); @@ -273,7 +291,7 @@ void svga_render_text_80_12(svga_t *svga) dat = svga->vram[charaddr + (svga->sc << 2)] << 4; dat |= ((svga->vram[charaddr + (svga->sc << 2) + 1]) >> 4); for (xx = 0; xx < 12; xx++) - p[xx] = (dat & (0x800 >> xx)) ? fg : bg; + p[xx] = (dat & (0x800 >> xx)) ? svga_color_transform(fg) : svga_color_transform(bg); svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); p += xinc; @@ -319,14 +337,14 @@ void svga_render_2bpp_lowres(svga_t *svga) svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); - p[0] = p[1] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]; - p[2] = p[3] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]; - p[4] = p[5] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask]; - p[6] = p[7] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]; - p[8] = p[9] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]; - p[10] = p[11] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]; - p[12] = p[13] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]; - p[14] = p[15] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]; + p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]); + p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]); + p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask]); + p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]); + p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]); + p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]); + p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]); + p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]); p += 16; } @@ -371,14 +389,14 @@ void svga_render_2bpp_highres(svga_t *svga) svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); - p[0] = svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]; - p[1] = svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]; - p[2] = svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask]; - p[3] = svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]; - p[4] = svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]; - p[5] = svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]; - p[6] = svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]; - p[7] = svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]; + p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 6) & 3] & svga->dac_mask]); + p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 4) & 3] & svga->dac_mask]); + p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat[0] >> 2) & 3] & svga->dac_mask]); + p[3] = svga_color_transform(svga->pallook[svga->egapal[dat[0] & 3] & svga->dac_mask]); + p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 6) & 3] & svga->dac_mask]); + p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 4) & 3] & svga->dac_mask]); + p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat[1] >> 2) & 3] & svga->dac_mask]); + p[7] = svga_color_transform(svga->pallook[svga->egapal[dat[1] & 3] & svga->dac_mask]); p += 8; } @@ -410,17 +428,17 @@ void svga_render_4bpp_lowres(svga_t *svga) svga->ma = svga_mask_addr(svga->ma, svga); dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = p[1] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[2] = p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[0] = p[1] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[2] = p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[4] = p[5] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[6] = p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[4] = p[5] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[6] = p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[8] = p[9] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[10] = p[11] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[8] = p[9] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[10] = p[11] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[12] = p[13] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[14] = p[15] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[12] = p[13] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[14] = p[15] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); p += 16; } @@ -467,17 +485,17 @@ void svga_render_4bpp_highres(svga_t *svga) svga->ma = svga_mask_addr(svga->ma, svga); dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - p[0] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[1] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[0] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[1] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - p[2] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[3] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[2] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[3] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - p[4] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[5] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[4] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[5] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - p[6] = svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]; - p[7] = svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]; + p[6] = svga_color_transform(svga->pallook[svga->egapal[(dat >> 4) & svga->plane_mask] & svga->dac_mask]); + p[7] = svga_color_transform(svga->pallook[svga->egapal[dat & svga->plane_mask] & svga->dac_mask]); p += 8; } @@ -503,10 +521,10 @@ void svga_render_8bpp_lowres(svga_t *svga) { uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma]); - p[0] = p[1] = svga->pallook[dat & svga->dac_mask]; - p[2] = p[3] = svga->pallook[(dat >> 8) & svga->dac_mask]; - p[4] = p[5] = svga->pallook[(dat >> 16) & svga->dac_mask]; - p[6] = p[7] = svga->pallook[(dat >> 24) & svga->dac_mask]; + p[0] = p[1] = svga_color_transform(svga->pallook[dat & svga->dac_mask]); + p[2] = p[3] = svga_color_transform(svga->pallook[(dat >> 8) & svga->dac_mask]); + p[4] = p[5] = svga_color_transform(svga->pallook[(dat >> 16) & svga->dac_mask]); + p[6] = p[7] = svga_color_transform(svga->pallook[(dat >> 24) & svga->dac_mask]); svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); @@ -536,16 +554,16 @@ void svga_render_8bpp_highres(svga_t *svga) { uint32_t dat; dat = *(uint32_t *)(&svga->vram[svga->ma]); - p[0] = svga->pallook[dat & svga->dac_mask]; - p[1] = svga->pallook[(dat >> 8) & svga->dac_mask]; - p[2] = svga->pallook[(dat >> 16) & svga->dac_mask]; - p[3] = svga->pallook[(dat >> 24) & svga->dac_mask]; + p[0] = svga_color_transform(svga->pallook[dat & svga->dac_mask]); + p[1] = svga_color_transform(svga->pallook[(dat >> 8) & svga->dac_mask]); + p[2] = svga_color_transform(svga->pallook[(dat >> 16) & svga->dac_mask]); + p[3] = svga_color_transform(svga->pallook[(dat >> 24) & svga->dac_mask]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 4, svga)]); - p[4] = svga->pallook[dat & svga->dac_mask]; - p[5] = svga->pallook[(dat >> 8) & svga->dac_mask]; - p[6] = svga->pallook[(dat >> 16) & svga->dac_mask]; - p[7] = svga->pallook[(dat >> 24) & svga->dac_mask]; + p[4] = svga_color_transform(svga->pallook[dat & svga->dac_mask]); + p[5] = svga_color_transform(svga->pallook[(dat >> 8) & svga->dac_mask]); + p[6] = svga_color_transform(svga->pallook[(dat >> 16) & svga->dac_mask]); + p[7] = svga_color_transform(svga->pallook[(dat >> 24) & svga->dac_mask]); svga->ma += 8; svga->ma = svga_mask_addr(svga->ma, svga); @@ -575,13 +593,13 @@ void svga_render_15bpp_lowres(svga_t *svga) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1), svga)]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + p[x] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 4, svga)]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + p[x] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); } svga->ma += x << 1; svga->ma = svga_mask_addr(svga->ma, svga); @@ -606,20 +624,20 @@ void svga_render_15bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1), svga)]); - p[x] = video_15to32[dat & 0xffff]; - p[x + 1] = video_15to32[dat >> 16]; + p[x] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 4, svga)]); - p[x + 2] = video_15to32[dat & 0xffff]; - p[x + 3] = video_15to32[dat >> 16]; + p[x + 2] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 3] = svga_color_transform(video_15to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 8, svga)]); - p[x + 4] = video_15to32[dat & 0xffff]; - p[x + 5] = video_15to32[dat >> 16]; + p[x + 4] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 5] = svga_color_transform(video_15to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 12, svga)]); - p[x + 6] = video_15to32[dat & 0xffff]; - p[x + 7] = video_15to32[dat >> 16]; + p[x + 6] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 7] = svga_color_transform(video_15to32[dat >> 16]); } svga->ma += x << 1; svga->ma = svga_mask_addr(svga->ma, svga); @@ -645,13 +663,13 @@ void svga_render_16bpp_lowres(svga_t *svga) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1), svga)]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + p[x] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 4, svga)]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + p[x] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); } svga->ma += x << 1; svga->ma = svga_mask_addr(svga->ma, svga); @@ -676,20 +694,20 @@ void svga_render_16bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1), svga)]); - p[x] = video_16to32[dat & 0xffff]; - p[x + 1] = video_16to32[dat >> 16]; + p[x] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 4, svga)]); - p[x + 2] = video_16to32[dat & 0xffff]; - p[x + 3] = video_16to32[dat >> 16]; + p[x + 2] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 3] = svga_color_transform(video_16to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 8, svga)]); - p[x + 4] = video_16to32[dat & 0xffff]; - p[x + 5] = video_16to32[dat >> 16]; + p[x + 4] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 5] = svga_color_transform(video_16to32[dat >> 16]); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 12, svga)]); - p[x + 6] = video_16to32[dat & 0xffff]; - p[x + 7] = video_16to32[dat >> 16]; + p[x + 6] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 7] = svga_color_transform(video_16to32[dat >> 16]); } svga->ma += x << 1; svga->ma = svga_mask_addr(svga->ma, svga); @@ -716,7 +734,7 @@ void svga_render_24bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga_mask_addr(svga->ma + 1, svga)] << 8) | (svga->vram[svga_mask_addr(svga->ma + 2, svga)] << 16); svga->ma += 3; svga->ma = svga_mask_addr(svga->ma, svga); - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = fg; + ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); } } } @@ -739,16 +757,16 @@ void svga_render_24bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 4) { uint32_t dat = *(uint32_t *)(&svga->vram[svga->ma]); - p[x] = dat & 0xffffff; + p[x] = svga_color_transform(dat & 0xffffff); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 3, svga)]); - p[x + 1] = dat & 0xffffff; + p[x + 1] = svga_color_transform(dat & 0xffffff); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 6, svga)]); - p[x + 2] = dat & 0xffffff; + p[x + 2] = svga_color_transform(dat & 0xffffff); dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + 9, svga)]); - p[x + 3] = dat & 0xffffff; + p[x + 3] = svga_color_transform(dat & 0xffffff); svga->ma += 12; svga->ma = svga_mask_addr(svga->ma, svga); @@ -776,7 +794,7 @@ void svga_render_32bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga_mask_addr(svga->ma + 1, svga)] << 8) | (svga->vram[svga_mask_addr(svga->ma + 2, svga)] << 16); svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = fg; + ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); } } } @@ -801,7 +819,7 @@ void svga_render_32bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 2), svga)]); - p[x] = dat & 0xffffff; + p[x] = svga_color_transform(dat & 0xffffff); } svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); @@ -826,7 +844,7 @@ void svga_render_ABGR8888_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 2), svga)]); - p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); + p[x] = svga_color_transform(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); } svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); @@ -851,7 +869,7 @@ void svga_render_RGBA8888_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x++) { uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 2), svga)]); - p[x] = dat >> 8; + p[x] = svga_color_transform(dat >> 8); } svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); diff --git a/src/video.c b/src/video.c index 6c3c00ab8..6dd8883a0 100644 --- a/src/video.c +++ b/src/video.c @@ -4,7 +4,7 @@ #include #include #include -#include 1 +#include #include "ibm.h" #include "config.h" #include "device.h" @@ -57,54 +57,53 @@ int cga_palette = 0; typedef struct { char name[64]; + char internal_name[24]; device_t *device; int legacy_id; } VIDEO_CARD; static VIDEO_CARD video_cards[] = { - {"ATI Graphics Pro Turbo (Mach64 GX)", &mach64gx_device, GFX_MACH64GX}, - {"ATI VGA Charger (ATI-28800-5)", &ati28800_device, GFX_VGACHARGER}, - {"ATI VGA Wonder XL24 (ATI-28800-6)", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24}, - {"ATI VGA Edge-16 (ATI-18800)", &ati18800_device, GFX_VGAEDGE16}, - {"CGA", &cga_device, GFX_CGA}, - {"Cirrus Logic CL-GD5429", &gd5429_device, GFX_CL_GD5429}, - {"Diamond Stealth 32 (Tseng ET4000/w32p)", &et4000w32p_device, GFX_ET4000W32}, - {"Diamond Stealth 64 DRAM (S3 Vision864)", &s3_diamond_stealth64_device,GFX_STEALTH64}, - {"Diamond Stealth 3D 2000 (S3 ViRGE)", &s3_virge_device, GFX_VIRGE}, - {"EGA", &ega_device, GFX_EGA}, - {"Chips & Technologies SuperEGA", &sega_device, GFX_SUPER_EGA}, - /* {"Chips & Technologies VGA 451", &vga_chips_device, GFX_CHIPS_VGA}, */ - {"Compaq ATI VGA Wonder XL (ATI-28800-5)", &compaq_ati28800_device, GFX_VGAWONDERXL}, - {"Compaq EGA", &cpqega_device, GFX_COMPAQ_EGA}, - {"Compaq/Paradise VGA", &cpqvga_device, GFX_COMPAQ_VGA}, - {"Hercules", &hercules_device, GFX_HERCULES}, - {"Hercules Plus", &herculesplus_device, GFX_HERCULESPLUS}, - {"Hercules InColor", &incolor_device, GFX_INCOLOR}, - {"MDA", &mda_device, GFX_MDA}, - {"Miro Crystal S3 Vision964", &s3_miro_vision964_device, GFX_MIRO_VISION964}, - {"Number Nine 9FX (S3 Trio64)", &s3_9fx_device, GFX_N9_9FX}, - {"nVidia RIVA 128 (Experimental)", &riva128_device, GFX_RIVA128}, - {"nVidia RIVA TNT (Experimental)", &rivatnt_device, GFX_RIVATNT}, - {"nVidia TNT2 (Experimental)", &rivatnt2_device, GFX_RIVATNT2}, + {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64x", &mach64gx_device, GFX_MACH64GX}, + {"ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER}, + {"ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24}, + {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16}, + {"CGA", "cga", &cga_device, GFX_CGA}, + {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429}, + {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32}, + {"Diamond Stealth 64 DRAM (S3 Vision864)", "stealth64d", &s3_diamond_stealth64_device,GFX_STEALTH64}, + {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE}, + {"EGA", "ega", &ega_device, GFX_EGA}, + {"Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA}, + {"Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL}, + {"Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA}, + {"Compaq/Paradise VGA", "compaq_vga", &cpqvga_device, GFX_COMPAQ_VGA}, + {"Hercules", "hercules", &hercules_device, GFX_HERCULES}, + {"Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS}, + {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR}, + {"MDA", "mda", &mda_device, GFX_MDA}, + {"Miro Crystal S3 Vision964", "mc_vision964", &s3_miro_vision964_device, GFX_MIRO_VISION964}, + {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX}, + {"nVidia RIVA 128 (Experimental)", "nv_riva128", &riva128_device, GFX_RIVA128}, + {"nVidia RIVA TNT (Experimental)", "nv_rivatnt", &rivatnt_device, GFX_RIVATNT}, + {"nVidia RIVA TNT2 (Experimental)", "nv_rivatnt2", &rivatnt2_device, GFX_RIVATNT2}, - /* {"OAK OTI-037", &oti037_device, GFX_OTI037}, */ - {"OAK OTI-067", &oti067_device, GFX_OTI067}, - {"OAK OTI-077", &oti077_device, GFX_OTI077}, - {"Paradise Bahamas 64 (S3 Vision864)", &s3_bahamas64_device, GFX_BAHAMAS64}, - {"Paradise WD90C11", ¶dise_wd90c11_device, GFX_WD90C11}, - {"Phoenix S3 Vision864", &s3_phoenix_vision864_device,GFX_PHOENIX_VISION864}, - {"Phoenix S3 Trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32}, - {"Phoenix S3 Trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64}, - {"Plantronics ColorPlus", &colorplus_device, GFX_COLORPLUS}, - {"S3 ViRGE/DX", &s3_virge_375_device, GFX_VIRGEDX}, - {"Trident TGUI9440", &tgui9440_device, GFX_TGUI9440}, - {"Trident TVGA8900D", &tvga8900d_device, GFX_TVGA}, - {"TriGem Unknown Adapter", &trigem_unk_device, GFX_TRIGEM_UNK}, - {"Tseng ET4000AX", &et4000_device, GFX_ET4000}, - {"VGA", &vga_device, GFX_VGA}, - {"Wyse 700", &wy700_device, GFX_WY700}, - {"", NULL, 0} + {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067}, + {"OAK OTI-077", "oti077", &oti077_device, GFX_OTI077}, + {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64}, + {"Paradise WD90C11", "wd90c11", ¶dise_wd90c11_device, GFX_WD90C11}, + {"Phoenix S3 Vision864", "px_vision864", &s3_phoenix_vision864_device,GFX_PHOENIX_VISION864}, + {"Phoenix S3 Trio32", "px_trio32", &s3_phoenix_trio32_device, GFX_PHOENIX_TRIO32}, + {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64}, + {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS}, + {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX}, + {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440}, + {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA}, + {"TriGem Unknown Adapter", "trigem_unk", &trigem_unk_device, GFX_TRIGEM_UNK}, + {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000}, + {"VGA", "vga", &vga_device, GFX_VGA}, + {"Wyse 700", "wy700", &wy700_device, GFX_WY700}, + {"", "", NULL, 0} }; int video_card_available(int card) @@ -163,6 +162,25 @@ int video_new_to_old(int card) return video_cards[card].legacy_id; } +char *video_get_internal_name(int card) +{ + return video_cards[card].internal_name; +} + +int video_get_video_from_internal_name(char *s) +{ + int c = 0; + + while (video_cards[c].legacy_id != -1) + { + if (!strcmp(video_cards[c].internal_name, s)) + return video_cards[c].legacy_id; + c++; + } + + return 0; +} + int video_fullscreen = 0, video_fullscreen_scale, video_fullscreen_first; uint32_t *video_6to8, *video_15to32, *video_16to32; diff --git a/src/video.h b/src/video.h index effcfb7e3..c01bb812b 100644 --- a/src/video.h +++ b/src/video.h @@ -39,6 +39,8 @@ int video_card_has_config(int card); int video_card_getid(char *s); int video_old_to_new(int card); int video_new_to_old(int card); +char *video_get_internal_name(int card); +int video_get_video_from_internal_name(char *s); extern int video_fullscreen, video_fullscreen_scale, video_fullscreen_first; diff --git a/src/win.c b/src/win.c index 4df50eba7..2cf0b78c9 100644 --- a/src/win.c +++ b/src/win.c @@ -757,6 +757,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_FLASH, enable_flash ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); // pclog("Checking video resize menu item...\n"); if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); @@ -1428,6 +1429,10 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); break; + case IDM_VID_INVERT: + video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); + break; + case IDM_VID_OVERSCAN: video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); break; From be77f5aebebea3803355235abf09586f13a1419a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 01:32:27 +0100 Subject: [PATCH 113/392] 86Box v1.03 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- src/win-ddraw-fs.cc | 24 ++++++++++++------------ src/win-ddraw-screenshot.cc | 4 ++-- src/win-ddraw-screenshot.h | 2 +- src/win-ddraw.cc | 26 +++++++++++++------------- 6 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc6c5a1c0..78e84209c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9c72c48c9..50fed4459 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index 5920eb6fb..b64447b51 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -24,10 +24,10 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); static LPDIRECTDRAW lpdd = NULL; -static LPDIRECTDRAW4 lpdd4 = NULL; -static LPDIRECTDRAWSURFACE4 lpdds_pri = NULL; -static LPDIRECTDRAWSURFACE4 lpdds_back = NULL; -static LPDIRECTDRAWSURFACE4 lpdds_back2 = NULL; +static LPDIRECTDRAW7 lpdd7 = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; static DDSURFACEDESC2 ddsd; @@ -46,7 +46,7 @@ int ddraw_fs_init(HWND h) if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) return 0; - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) + if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) return 0; lpdd->Release(); @@ -54,11 +54,11 @@ int ddraw_fs_init(HWND h) atexit(ddraw_fs_close); - if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW | + if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW | DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT))) return 0; - if (FAILED(lpdd4->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) + if (FAILED(lpdd7->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) return 0; // memset(&ddsd, 0, sizeof(ddsd)); @@ -67,7 +67,7 @@ int ddraw_fs_init(HWND h) ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) return 0; ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; @@ -81,7 +81,7 @@ int ddraw_fs_init(HWND h) ddsd.dwWidth = 2048; ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) return 0; pclog("DDRAW_INIT complete\n"); @@ -114,10 +114,10 @@ void ddraw_fs_close() lpdd_clipper->Release(); lpdd_clipper = NULL; } - if (lpdd4) + if (lpdd7) { - lpdd4->Release(); - lpdd4 = NULL; + lpdd7->Release(); + lpdd7 = NULL; } } diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc index 1942c30cb..353b00705 100644 --- a/src/win-ddraw-screenshot.cc +++ b/src/win-ddraw-screenshot.cc @@ -21,7 +21,7 @@ HBITMAP hbitmap; int xs, ys, ys2; -void CopySurface(IDirectDrawSurface4 *pDDSurface) +void CopySurface(IDirectDrawSurface7 *pDDSurface) { HDC hdc, hmemdc; @@ -151,7 +151,7 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) if(fp) fclose(fp); } -void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface4 *pDDSurface) +void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface7 *pDDSurface) { xs = xsize; ys = ys2 = ysize; diff --git a/src/win-ddraw-screenshot.h b/src/win-ddraw-screenshot.h index 0d5b7cc7b..7c56e5f96 100644 --- a/src/win-ddraw-screenshot.h +++ b/src/win-ddraw-screenshot.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface4 *pDDSurface); +void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 3f9e4f7e2..6b7ca19e9 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -25,10 +25,10 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h); static LPDIRECTDRAW lpdd = NULL; -static LPDIRECTDRAW4 lpdd4 = NULL; -static LPDIRECTDRAWSURFACE4 lpdds_pri = NULL; -static LPDIRECTDRAWSURFACE4 lpdds_back = NULL; -static LPDIRECTDRAWSURFACE4 lpdds_back2 = NULL; +static LPDIRECTDRAW7 lpdd7 = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; static DDSURFACEDESC2 ddsd; @@ -43,7 +43,7 @@ int ddraw_init(HWND h) if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) return 0; - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4))) + if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) return 0; lpdd->Release(); @@ -51,7 +51,7 @@ int ddraw_init(HWND h) atexit(ddraw_close); - if (FAILED(lpdd4->SetCooperativeLevel(h, DDSCL_NORMAL))) + if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_NORMAL))) return 0; memset(&ddsd, 0, sizeof(ddsd)); @@ -59,7 +59,7 @@ int ddraw_init(HWND h) ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_pri, NULL))) + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) return 0; // memset(&ddsd, 0, sizeof(ddsd)); @@ -69,7 +69,7 @@ int ddraw_init(HWND h) ddsd.dwWidth = 2048; ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back, NULL))) + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) return 0; memset(&ddsd, 0, sizeof(ddsd)); @@ -79,10 +79,10 @@ int ddraw_init(HWND h) ddsd.dwWidth = 2048; ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd4->CreateSurface(&ddsd, &lpdds_back2, NULL))) + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) return 0; - if (FAILED(lpdd4->CreateClipper(0, &lpdd_clipper, NULL))) + if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL))) return 0; if (FAILED(lpdd_clipper->SetHWnd(0, h))) return 0; @@ -119,10 +119,10 @@ void ddraw_close() lpdd_clipper->Release(); lpdd_clipper = NULL; } - if (lpdd4) + if (lpdd7) { - lpdd4->Release(); - lpdd4 = NULL; + lpdd7->Release(); + lpdd7 = NULL; } } From 536443858a6d4a51a85b66c0122af6cd6f87bfdf Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 25 Feb 2017 18:42:34 -0600 Subject: [PATCH 114/392] Add more PGRAPH registers --- src/vid_nv_riva128.c | 130 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 04555910a..d98bbe4f7 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -160,12 +160,25 @@ typedef struct riva128_t uint32_t src_canvas_min, src_canvas_max; uint32_t dst_canvas_min, dst_canvas_max; + uint8_t rop; + + uint32_t chroma; + uint32_t beta; uint32_t notify; + uint32_t surf_base[6] + uint32_t surf_limit[6]; + + uint32_t cliprect_min[2]; + uint32_t cliprect_max[2]; + uint32_t cliprect_ctrl; + uint32_t instance; + uint32_t dma_intr, dma_intr_en; + struct { uint32_t point_color; @@ -1169,6 +1182,31 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p) case 0x4006a4: ret = riva128->pgraph.fifo_enable & 1; break; + + case 0x401100: + ret = riva128->pgraph.dma_intr & 0xff; + break; + case 0x401101: + ret = (riva128->pgraph.dma_intr >> 8) & 0xff; + break; + case 0x401102: + ret = (riva128->pgraph.dma_intr >> 16) & 0xff; + break; + case 0x401103: + ret = (riva128->pgraph.dma_intr >> 24) & 0xff; + break; + case 0x401140: + ret = riva128->pgraph.dma_intr_en & 0xff; + break; + case 0x401141: + ret = (riva128->pgraph.dma_intr_en >> 8) & 0xff; + break; + case 0x401142: + ret = (riva128->pgraph.dma_intr_en >> 16) & 0xff; + break; + case 0x401143: + ret = (riva128->pgraph.dma_intr_en >> 24) & 0xff; + break; } if(riva128->card_id == 0x03) switch(addr) @@ -1269,6 +1307,21 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p) case 0x40056f: ret = (riva128->pgraph.oclip_ymax >> 24) & 0xff; break; + case 0x400624: + ret = riva128->pgraph.rop; + break; + case 0x40062c: + ret = riva128->pgraph.beta & 0xff; + break; + case 0x40062d: + ret = (riva128->pgraph.beta >> 8) & 0xff; + break; + case 0x40062e: + ret = (riva128->pgraph.beta >> 16) & 0xff; + break; + case 0x40062f: + ret = (riva128->pgraph.beta >> 24) & 0xff; + break; case 0x400640: ret = riva128->pgraph.beta & 0xff; break; @@ -1293,6 +1346,66 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p) case 0x400687: ret = (riva128->pgraph.notify >> 24) & 0xff; break; + case 0x400690: + ret = riva128->pgraph.cliprect_min[0] & 0xff; + break; + case 0x400691: + ret = (riva128->pgraph.cliprect_min[0] >> 8) & 0xff; + break; + case 0x400692: + ret = (riva128->pgraph.cliprect_min[0] >> 16) & 0xff; + break; + case 0x400693: + ret = (riva128->pgraph.cliprect_min[0] >> 24) & 0xff; + break; + case 0x400694: + ret = riva128->pgraph.cliprect_max[0] & 0xff; + break; + case 0x400695: + ret = (riva128->pgraph.cliprect_max[0] >> 8) & 0xff; + break; + case 0x400696: + ret = (riva128->pgraph.cliprect_max[0] >> 16) & 0xff; + break; + case 0x400697: + ret = (riva128->pgraph.cliprect_max[0] >> 24) & 0xff; + break; + case 0x400698: + ret = riva128->pgraph.cliprect_min[1] & 0xff; + break; + case 0x400699: + ret = (riva128->pgraph.cliprect_min[1] >> 8) & 0xff; + break; + case 0x40069a: + ret = (riva128->pgraph.cliprect_min[1] >> 16) & 0xff; + break; + case 0x40069b: + ret = (riva128->pgraph.cliprect_min[1] >> 24) & 0xff; + break; + case 0x40069c: + ret = riva128->pgraph.cliprect_max[1] & 0xff; + break; + case 0x40069d: + ret = (riva128->pgraph.cliprect_max[1] >> 8) & 0xff; + break; + case 0x40069e: + ret = (riva128->pgraph.cliprect_max[1] >> 16) & 0xff; + break; + case 0x40069f: + ret = (riva128->pgraph.cliprect_max[1] >> 24) & 0xff; + break; + case 0x4006a0: + ret = riva128->pgraph.cliprect_ctrl & 0xff; + break; + case 0x4006a1: + ret = (riva128->pgraph.cliprect_ctrl >> 8) & 0xff; + break; + case 0x4006a2: + ret = (riva128->pgraph.cliprect_ctrl >> 16) & 0xff; + break; + case 0x4006a3: + ret = (riva128->pgraph.cliprect_ctrl >> 24) & 0xff; + break; } return ret; @@ -1389,6 +1502,12 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x40056c: riva128->pgraph.oclip_ymax = val & 0x3ffff; break; + case 0x400624: + riva128->pgraph.rop = val & 0xff; + break; + case 0x40062c: + riva128->pgraph.chroma = val & 0x7fffffff; + break; case 0x400640: { uint32_t tmp = val & 0x7f800000; @@ -1399,9 +1518,18 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x400684: riva128->pgraph.notify = val & 0x0011ffff; break; + case 0x4006a0: + riva128->pgraph.cliprect_ctrl = val & 0x113; + break; case 0x4006a4: riva128->pgraph.fifo_enable = val & 1; break; + case 0x401100: + riva128->pgraph.dma_intr &= ~val; + break; + case 0x401140: + riva128->pgraph.dma_intr_en = val & 0x00011111; + break; } else if(riva128->card_id < 0x10) switch(addr) { @@ -1736,7 +1864,7 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) addr &= 0xffffff; //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. - if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { From 6e33da50564ea744a8a03250ed35034fb9aa751b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 01:46:23 +0100 Subject: [PATCH 115/392] Changed version to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index e3971f3c3..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.03" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 78e84209c..fc6c5a1c0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 50fed4459..9c72c48c9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From bca4b293cf2f20339cab0b5e58e878a0573d91f4 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 25 Feb 2017 18:52:50 -0600 Subject: [PATCH 116/392] Fix compile --- src/vid_nv_riva128.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index d98bbe4f7..e6bf9dc64 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -168,7 +168,7 @@ typedef struct riva128_t uint32_t notify; - uint32_t surf_base[6] + uint32_t surf_base[6]; uint32_t surf_limit[6]; uint32_t cliprect_min[2]; From 51b085c13e2a1375f4279839bf9bb3a438520ccb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 06:36:52 +0100 Subject: [PATCH 117/392] Fixed RAM mask on resetx86(), fixes soft reset triggered by MS-DOS Setup; Changed version to 1.04. --- src/808x.c | 9 +-------- src/86box.h | 2 +- src/mem.c | 12 +++++------- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/808x.c b/src/808x.c index 36a4e1467..20f6e3b93 100644 --- a/src/808x.c +++ b/src/808x.c @@ -645,14 +645,7 @@ void resetx86() eflags=0; cgate32=0; loadcs(0xFFFF); - if (AT) - { - rammask = mem_a20_state ? 0xffffffff : 0xffefffff; - } - else - { - rammask = 0xfffff; - } + rammask = AT ? 0xFFFFFFFF : 0xfffff; idt.base = 0; flags=2; makeznptable(); diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..87b2e57da 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.04" diff --git a/src/mem.c b/src/mem.c index c86f723ec..e98542f14 100644 --- a/src/mem.c +++ b/src/mem.c @@ -2250,22 +2250,20 @@ void mem_a20_recalc() static uint8_t port_92_read(uint16_t port, void *priv) { - return (port_92_reg & 3) | 0x24; + return port_92_reg; } static void port_92_write(uint16_t port, uint8_t val, void *priv) { - mem_a20_alt = val & 2; - mem_a20_recalc(); - - if (!(port_92_reg & 1) && (val & 1)) + if (val & 1) { - // pclog("Port 92: Soft reset\n"); softresetx86(); + cpu_set_edx(); } - port_92_reg = val & 3; + port_92_reg = val & ~-1; + mem_a20_alt = val & 2; mem_a20_recalc(); } From c9f61dfb94f6abbd4cd3e3500fc116c404cdca9a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 06:44:45 +0100 Subject: [PATCH 118/392] 86Box v1.04 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc6c5a1c0..78e84209c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9c72c48c9..50fed4459 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 0d7c980887785f36d1e4798a3a9436338529c24c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 06:50:44 +0100 Subject: [PATCH 119/392] Changed version to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index 87b2e57da..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.04" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 78e84209c..fc6c5a1c0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 50fed4459..9c72c48c9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From f98a8104a54a067aa9a66c6ef4ff1c1f365ef58c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 07:17:13 +0100 Subject: [PATCH 120/392] 86Box v1.04 Recommended Build. --- src/86box.h | 2 +- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..87b2e57da 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.04" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc6c5a1c0..78e84209c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9c72c48c9..50fed4459 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 9351cf4474c660af6ddbb245008558cb6a2545b8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 07:40:59 +0100 Subject: [PATCH 121/392] Changed version to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index 87b2e57da..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.04" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 78e84209c..fc6c5a1c0 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 50fed4459..9c72c48c9 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From e4dd05d9e9ff4d9661b2590a9eb637045a3be1e7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 18:19:23 +0100 Subject: [PATCH 122/392] Disabled crash dumper, fixes Direct3D; Changed version to 1.05. --- src/86box.h | 2 +- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- src/win.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..e95cf967e 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.05" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fc6c5a1c0..fdafe9849 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ - vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-crashdump.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ + vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-video.o x86seg.o x87.o xtide.o pc.res DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 9c72c48c9..90874a262 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -19,7 +19,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429 vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ - vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-crashdump.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ + vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-video.o x86seg.o x87.o xtide.o pc.res DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o diff --git a/src/win.c b/src/win.c index 2cf0b78c9..d4f670530 100644 --- a/src/win.c +++ b/src/win.c @@ -568,7 +568,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ - InitCrashDump(); // First thing to do before anything else is to make sure crash dumps get created. + // InitCrashDump(); // First thing to do before anything else is to make sure crash dumps get created. process_command_line(); From 67c3eb1c78f518f811b222767a7a2d7a34e1c1ac Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 18:35:12 +0100 Subject: [PATCH 123/392] 86Box v1.05 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fdafe9849..65946b4fd 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 90874a262..0acc20863 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 99de4f11b648791a79ec5fcdd4177dde03acd991 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 26 Feb 2017 18:46:12 +0100 Subject: [PATCH 124/392] Changed version to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index e95cf967e..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.05" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 65946b4fd..fdafe9849 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 0acc20863..90874a262 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 13683628a5e1dc88ea15e26984b2d8997e9b6898 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 1 Mar 2017 23:23:52 +0100 Subject: [PATCH 125/392] ATAPI CD-ROM no longer lowers IRQ at the wrong time, fixes booting of some CD's; Fixed DMA emulation, fixes Olivetti M24; (S)VGA emulation for PS/1 and PS/2 machines now uses the old, less accurate sense switches, fixes display error on POST; Bit 2 of the AT keyboard input port is now always held active, fixes PS/2 mouse on PS/1 and PS/2 machines; Fixed mouse type selection on non-AT boards; Fixed RAM type selection; The entire palette is now overwritten when a monochrome monitor type is selected, fixes graphics mode on Hercules; Applied updated SCAT emulation patch from PCem forum; Nvidia Riva and S3 Virge IRQ is now configurable; Properly applied the mainline PCem commit that fixed the Bahamas64 on the Intel AMI BIOS boards; Commented out the Diamond Stealth 64 and the Miro Crystal S3 Vision 964 due to their non-working state; Changed version to 1.06. --- src/86box.h | 2 +- src/cdrom.c | 10 --- src/dma.c | 67 +++++++++------- src/keyboard_at.c | 9 ++- src/mem.c | 120 +++++++++++++++++++++++++--- src/mem.h | 5 ++ src/model.c | 4 +- src/ps1.c | 5 +- src/scat.c | 53 ++++++++++--- src/vid_nv_riva128.c | 176 ++++++++++++++++++++++++++++++++++++++--- src/vid_olivetti_m24.c | 2 +- src/vid_s3.c | 41 +++++----- src/vid_s3.h | 4 +- src/vid_s3_virge.c | 61 +++++++++++++- src/vid_svga.c | 28 +++++-- src/video.c | 4 +- src/win-config.c | 19 ++--- src/win-d3d-fs.cc | 13 ++- 18 files changed, 498 insertions(+), 125 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..3912cea8e 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.06" diff --git a/src/cdrom.c b/src/cdrom.c index e97c946d1..93fc0b85c 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2745,14 +2745,6 @@ int cdrom_block_check(uint8_t id) int alloc_length = 0; int ret = 0; - if (!cdrom_drives[id].bus_type) - { - cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); - ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); - } - - cdrom[id].status = BUSY_STAT; - /* If this is a media access command, and we hit the end of the block but not the entire length, read the next block. */ if (cdrom_is_media_access(id)) @@ -2808,7 +2800,6 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ int ret = 0; int old_pos = 0; -#if 0 if (!cdrom_drives[id].bus_type) { cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); @@ -2816,7 +2807,6 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ } cdrom[id].status = BUSY_STAT; -#endif if (cdrom[id].total_read >= cdrom[id].packet_len) { diff --git a/src/dma.c b/src/dma.c index 59ae03401..a6d43550f 100644 --- a/src/dma.c +++ b/src/dma.c @@ -70,7 +70,8 @@ uint8_t dma_read(uint16_t addr, void *priv) return temp; case 0xd: /*Temporary register*/ - return dmaregs[addr & 0xd]; + // return dmaregs[addr & 0xd]; + return 0; case 0xf: /*Mask register*/ return dma16.m; @@ -89,16 +90,20 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) { case 0: case 2: case 4: case 6: /*Address registers*/ dma.wp ^= 1; - if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00) | val; - else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8); + // if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00) | val; + // else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8); + if (dma.wp) dma.ab[(addr >> 1) & 3] = val; + else dma.ab[(addr >> 1) & 3] |= (((uint16_t) val) << 8); dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3] & 0xffff; dmaon[(addr >> 1) & 3] = 1; return; case 1: case 3: case 5: case 7: /*Count registers*/ dma.wp ^= 1; - if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val; - else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); + // if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val; + // else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); + if (dma.wp) dma.cb[(addr >> 1) & 3] = val; + else dma.cb[(addr >> 1) & 3] |= (((uint16_t) val) << 8); dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3] & 0xffff; // pclog("DMA count for channel %i now: %02X\n", (addr >> 1) & 3, dma.cc[(addr >> 1) & 3]); dmaon[(addr >> 1) & 3] = 1; @@ -111,15 +116,11 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) case 9: /*Request register*/ if (val & 4) { - dma.request |= (1 << (channel + 4)); - if (dma.command & 1) - { - dma.request |= (1 << channel); - } + dma.stat |= (1 << (channel + 4)); } else { - dma.request &= ~(1 << (channel + 4)); + dma.stat &= ~(1 << (channel + 4)); } return; @@ -138,9 +139,10 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) return; case 0xd: /*Master clear*/ - dma.wp = 0; - dma.stat = 0; dma.m = 0xf; + dma.command = 0; + dma.stat = 0; + dma.wp = 0; return; case 0xe: /*Mask reset*/ @@ -178,7 +180,8 @@ uint8_t dma16_read(uint16_t addr, void *priv) return temp; case 0xd: /*Temporary register*/ - return dma16regs[addr & 0xd]; + // return dma16regs[addr & 0xd]; + return 0; case 0xf: /*Mask register*/ return dma16.m; @@ -198,16 +201,20 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) { case 0: case 2: case 4: case 6: /*Address registers*/ dma16.wp ^= 1; - if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00) | val; - else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8); + // if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00) | val; + // else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8); + if (dma16.wp) dma16.ab[(addr >> 1) & 3] = val; + else dma16.ab[(addr >> 1) & 3] |= (((uint16_t) val) << 8); dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3] & 0xffff; dma16on[(addr >> 1) & 3] = 1; return; case 1: case 3: case 5: case 7: /*Count registers*/ dma16.wp ^= 1; - if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val; - else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); + // if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val; + // else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); + if (dma16.wp) dma16.cb[(addr >> 1) & 3] = val; + else dma16.cb[(addr >> 1) & 3] |= (((uint16_t) val) << 8); dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3] & 0xffff; dma16on[(addr >> 1) & 3] = 1; return; @@ -219,15 +226,11 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) case 9: /*Request register*/ if (val & 4) { - dma16.request |= (1 << (channel + 4)); - if (dma16.command & 1) - { - dma16.request |= (1 << channel); - } + dma16.stat |= (1 << (channel + 4)); } else { - dma16.request &= ~(1 << (channel + 4)); + dma16.stat &= ~(1 << (channel + 4)); } return; @@ -246,9 +249,10 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xd: /*Master clear*/ - dma16.wp = 0; - dma16.stat = 0; dma16.m = 0xf; + dma16.command = 0; + dma16.stat = 0; + dma16.wp = 0; return; case 0xe: /*Mask reset*/ @@ -278,10 +282,7 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) dma.page[1] = (AT) ? val : val & 0xf; break; case 0x7: - if (is386) - { - dma.page[0] = (AT) ? val : val & 0xf; - } + dma.page[0] = (AT) ? val : val & 0xf; break; case 0x9: dma16.page[2] = val; @@ -292,6 +293,12 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) case 0xb: dma16.page[1] = val; break; + case 0xf: + dma16.page[0] = val; + break; + default: + pclog("DMA write to extra page register: %02X\n", addr & 0xf); + break; } } diff --git a/src/keyboard_at.c b/src/keyboard_at.c index edeeeb39e..24cabb4f9 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -642,9 +642,7 @@ bad_command: break; case 0xc0: /*Read input port*/ - keyboard_at_adddata((keyboard_at.input_port & 0xf0) | 0x80); - // keyboard_at_adddata(keyboard_at.input_port | 4); - // keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc); + keyboard_at_adddata((keyboard_at.input_port & 0xfc) | 0x84); break; case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ @@ -726,13 +724,16 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) case 0x60: temp = keyboard_at.out; keyboard_at.status &= ~(STAT_OFULL/* | STAT_MFULL*/); - picintc(keyboard_at.last_irq); if (PCI) { /* The PIIX/PIIX3 datasheet mandates that both of these interrupts are cleared on any read of port 0x60. */ picintc(1 << 1); picintc(1 << 12); } + else + { + picintc(keyboard_at.last_irq); + } keyboard_at.last_irq = 0; break; diff --git a/src/mem.c b/src/mem.c index e98542f14..015f325cf 100644 --- a/src/mem.c +++ b/src/mem.c @@ -62,6 +62,8 @@ int cachesize=256; uint8_t *ram,*rom; uint8_t romext[32768]; +uint32_t ram_mapped_addr[64]; + static void mem_load_xtide_bios() { FILE *f; @@ -351,7 +353,10 @@ int loadbios() } fclose(ff); fclose(f); - mem_load_atide_bios(); + if (enable_xtide) + { + mem_load_atide_bios(); + } return 1; case ROM_CMDPC30: f = romfopen("roms/cmdpc30/commodore pc 30 iii even.bin", "rb"); @@ -592,7 +597,10 @@ int loadbios() fclose(f); //#endif biosmask = 0x1ffff; - mem_load_atide115_bios(); + if (enable_xtide) + { + mem_load_atide115_bios(); + } return 1; case ROM_IBMPS1_2121: @@ -617,7 +625,10 @@ int loadbios() fclose(ff); fclose(f); biosmask = 0x7fff; - mem_load_atide_bios(); + if (enable_xtide) + { + mem_load_atide_bios(); + } return 1; case ROM_AMIXT: @@ -716,7 +727,10 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - mem_load_atide_bios(); + if (enable_xtide) + { + mem_load_atide_bios(); + } return 1; case ROM_DTK486: @@ -1241,6 +1255,12 @@ uint8_t *getpccache(uint32_t a) { uint32_t a2=a; + if (a2 < 0x100000 && ram_mapped_addr[a2 >> 14]) + { + a = (ram_mapped_addr[a2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? a2 : (ram_mapped_addr[a2 >> 14] & ~0x3FFF) + (a2 & 0x3FFF); + return &ram[(uintptr_t)(a & 0xFFFFF000) - (uintptr_t)(a2 & ~0xFFF)]; + } + if (cr0>>31) { pctrans=1; @@ -1272,6 +1292,12 @@ uint32_t mem_logical_addr; uint8_t readmembl(uint32_t addr) { mem_logical_addr = addr; + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) + { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); + if(addr < mem_size * 1024) return ram[addr]; + return 0xFF; + } if (cr0 >> 31) { addr = mmutranslate_read(addr); @@ -1288,6 +1314,12 @@ void writemembl(uint32_t addr, uint8_t val) { mem_logical_addr = addr; + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) + { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); + if(addr < mem_size * 1024) ram[addr] = val; + return; + } if (page_lookup[addr>>12]) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); @@ -1317,6 +1349,12 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr) { return ram[readlookup2[mem_logical_addr >> 12] + (mem_logical_addr & 0xFFF)]; }*/ + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) + { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); + if(addr < mem_size * 1024) return ram[addr]; + return 0xFF; + } if (cr0 >> 31) { @@ -1341,6 +1379,12 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) } mem_logical_addr = addr = addr + seg; + if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) + { + addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); + if(addr < mem_size * 1024) ram[addr] = val; + return; + } if (page_lookup[addr>>12]) { page_lookup[addr>>12]->write_b(addr, val, page_lookup[addr>>12]); @@ -1366,6 +1410,10 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) uint32_t addr2 = mem_logical_addr = seg + addr; if ((addr2&0xFFF)>0xFFE) { + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14] && ram_mapped_addr[(addr2+1) >> 14]) + { + return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); + } if (cr0>>31) { if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; @@ -1380,6 +1428,12 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) // printf("NULL segment! rw %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return -1; } + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); + if(addr < mem_size * 1024) return *((uint16_t *)&ram[addr]); + return 0xFFFF; + } if (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1404,6 +1458,12 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) uint32_t addr2 = mem_logical_addr = seg + addr; if ((addr2&0xFFF)>0xFFE) { + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + writemembl(seg+addr,val); + writemembl(seg+addr+1,val>>8); + return; + } if (cr0>>31) { if (mmutranslate_write(addr2) == 0xffffffff) return; @@ -1428,6 +1488,12 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) // printf("NULL segment! ww %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); + if(addr < mem_size * 1024) *((uint16_t *)&ram[addr]) = val; + return; + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); @@ -1464,6 +1530,10 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) uint32_t addr2 = mem_logical_addr = seg + addr; if ((addr2&0xFFF)>0xFFC) { + if (addr2 < 0x100000 && (ram_mapped_addr[addr2 >> 14] || ram_mapped_addr[(addr2+3) >> 14])) + { + return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + } if (cr0>>31) { if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; @@ -1479,6 +1549,12 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) return -1; } + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); + if(addr < mem_size * 1024) return *((uint32_t *)&ram[addr]); + return 0xFFFFFFFF; + } if (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1518,6 +1594,12 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) // printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); + if(addr < mem_size * 1024) *((uint32_t *)&ram[addr]) = val; + return; + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); @@ -1576,10 +1658,16 @@ uint64_t readmemql(uint32_t seg, uint32_t addr) return -1; } + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); + if(addr < mem_size * 1024) return *((uint64_t *)&ram[addr]); + return -1; + } if (cr0>>31) { addr2 = mmutranslate_read(addr2); - if (addr2==0xFFFFFFFF) return 0xFFFFFFFF; + if (addr2==0xFFFFFFFF) return -1; } addr2&=rammask; @@ -1612,6 +1700,12 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) // printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } + if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) + { + addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); + if(addr < mem_size * 1024) *((uint64_t *)&ram[addr]) = val; + return; + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); @@ -2068,6 +2162,8 @@ void mem_init() memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); + + memset(ram_mapped_addr, 0, 64 * sizeof(uint32_t)); for (c = 0; c < (((mem_size + 384) * 1024) >> 12); c++) { @@ -2078,7 +2174,7 @@ void mem_init() } memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 256); c++) + for (c = 0; c < (mem_size / 64); c++) { isram[c] = 1; if (c >= 0xa && c <= 0xf) @@ -2101,7 +2197,10 @@ void mem_init() mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (mem_size > 1024) + { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL); if (mem_size > 1024) @@ -2156,7 +2255,7 @@ void mem_resize() } memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 256); c++) + for (c = 0; c < (mem_size / 64); c++) { isram[c] = 1; if (c >= 0xa && c <= 0xf) @@ -2177,7 +2276,10 @@ void mem_resize() mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + if (mem_size > 1024) + { + mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + } mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL); if (mem_size > 1024) diff --git a/src/mem.h b/src/mem.h index ada252529..8f489411c 100644 --- a/src/mem.h +++ b/src/mem.h @@ -39,6 +39,11 @@ extern int memspeed[11]; extern int nopageerrors; extern uint32_t biosmask; +#define MEM_MAP_TO_SHADOW_RAM_MASK 1 +#define MEM_MAP_TO_RAM_ADDR_MASK 2 + +extern uint32_t ram_mapped_addr[64]; + void mem_mapping_add(mem_mapping_t *mapping, uint32_t base, uint32_t size, diff --git a/src/model.c b/src/model.c index 41dde94d3..c5a7a79aa 100644 --- a/src/model.c +++ b/src/model.c @@ -379,6 +379,7 @@ void ps1_common_init() device_add(&ps1_audio_device); /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ if (joystick_type != 7) device_add(&gameport_201_device); + fdc_set_ps1(); } void ps1_m2011_init() @@ -391,7 +392,6 @@ void ps1_m2121_init() { ps1_common_init(); ps1mb_m2121_init(); - fdc_set_ps1(); } void ps2_m30_286_init() @@ -403,11 +403,11 @@ void ps2_m30_286_init() dma16_init(); ide_init(); keyboard_at_init(); - mouse_ps2_init(); nvr_init(); pic2_init(); ps2board_init(); fdc_set_dskchg_activelow(); + fdc_set_ps1(); } void at_neat_init() diff --git a/src/ps1.c b/src/ps1.c index 3fb016b45..8da00c91a 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -129,13 +129,16 @@ void ps1mb_init() io_sethandler(0x0322, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); io_sethandler(0x0324, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); - rom_init(&ps1_high_rom, + if (!enable_xtide) + { + rom_init(&ps1_high_rom, "roms/ibmps1es/f80000_shell.bin", 0xf80000, 0x80000, 0x7ffff, 0, MEM_MAPPING_EXTERNAL); + } /* rom_init_interleaved(&ps1_high_rom, "roms/ibmps1es/ibm_1057757_24-05-90.bin", "roms/ibmps1es/ibm_1057757_29-15-90.bin", diff --git a/src/scat.c b/src/scat.c index af50ce936..fad281b65 100644 --- a/src/scat.c +++ b/src/scat.c @@ -22,10 +22,18 @@ void scat_shadow_state_update() { int i, val, val2; - // TODO - Segment A000 to BFFF shadow ram enable features and ROM enable features should be implemented later. - for (i = 8; i < 24; i++) + for (i = 0; i < 24; i++) { - val = ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_READ_INTERNAL : MEM_READ_EXTERNAL; + if((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) + { + val = MEM_READ_INTERNAL; + ram_mapped_addr[i + 40] |= 1; + } + else + { + val = MEM_READ_EXTERNAL; + ram_mapped_addr[i + 40] &= ~1; + } if (i < 8) { val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; @@ -123,6 +131,7 @@ void scat_set_xms_bound(uint8_t val) uint32_t get_scat_addr(uint32_t addr, scat_t *p) { + uint32_t addr2 = addr; if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) { addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; @@ -222,6 +231,16 @@ void scat_write(uint16_t port, uint8_t val, void *priv) pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x8 = val; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x30000; + + if(scat_stat[index].regs_2x9 & 0x80) + { + ram_mapped_addr[base_addr >> 14] &= 0xFFC000FF; + ram_mapped_addr[base_addr >> 14] |= val << 14; + flushmmucache(); + } } break; case 0x209: @@ -234,18 +253,18 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if(index >= 24) base_addr += 0x30000; + ram_mapped_addr[base_addr >> 14] &= 1; if (val & 0x80) { virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14; - mem_mapping_enable(&scat_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + get_scat_addr(virt_addr, &scat_stat[index])); pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + ram_mapped_addr[base_addr >> 14] |= virt_addr | 2; } else { - mem_mapping_disable(&scat_mapping[index]); pclog("Unmap page %d(address %06X)\n", scat_ems_reg_2xA & 0x1f, base_addr); } + flushmmucache(); if (scat_ems_reg_2xA & 0x80) { @@ -267,6 +286,16 @@ void scat_write(uint16_t port, uint8_t val, void *priv) pclog("Write SCAT EMS Control Port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); index = scat_ems_reg_2xA & 0x1F; scat_stat[index].regs_2x8 = val; + base_addr = (index + 16) << 14; + if(index >= 24) + base_addr += 0x30000; + + if(scat_stat[index].regs_2x9 & 0x80) + { + ram_mapped_addr[base_addr >> 14] &= 0xFFC000FF; + ram_mapped_addr[base_addr >> 14] |= val << 14; + flushmmucache(); + } } break; case 0x219: @@ -282,15 +311,14 @@ void scat_write(uint16_t port, uint8_t val, void *priv) if (val & 0x80) { virt_addr = (((scat_stat[index].regs_2x9 & 3) << 8) | scat_stat[index].regs_2x8) << 14; - mem_mapping_enable(&scat_mapping[index]); - mem_mapping_set_exec(&scat_mapping[index], ram + get_scat_addr(virt_addr, &scat_stat[index])); pclog("Map page %d(address %05X) to address %06X\n", scat_ems_reg_2xA & 0x1f, base_addr, virt_addr); + ram_mapped_addr[base_addr >> 14] |= virt_addr | 2; } else { - mem_mapping_disable(&scat_mapping[index]); pclog("Unmap page %d(address %05X)\n", scat_ems_reg_2xA & 0x1f, base_addr); } + flushmmucache(); if (scat_ems_reg_2xA & 0x80) { @@ -454,6 +482,11 @@ void scat_init() scat_regs[i] = 0xff; } + for (i = 0; i < 64; i++) + { + ram_mapped_addr[i] = 0; + } + scat_regs[SCAT_DMA_WAIT_STATE_CONTROL] = 0; scat_regs[SCAT_VERSION] = 10; scat_regs[SCAT_CLOCK_CONTROL] = 2; @@ -473,8 +506,6 @@ void scat_init() { scat_stat[i].regs_2x8 = 0xff; scat_stat[i].regs_2x9 = 0x03; - mem_mapping_add(&scat_mapping[i], (i + (i >= 24 ? 28 : 16)) << 14, 0x04000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram + ((i + (i >= 24 ? 28 : 16)) << 14), 0, &scat_stat[i]); - mem_mapping_disable(&scat_mapping[i]); } // TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later. diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index e6bf9dc64..152b2f963 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -457,8 +457,7 @@ static void riva128_pmc_interrupt(int num, void *p) riva128->pmc.intr |= (1 << num); - // picint(1 << riva128->pci_regs[0x3c]); - picint(1 << 3); + picint(1 << riva128->pci_regs[0x3c]); } static uint8_t riva128_pbus_read(uint32_t addr, void *p) @@ -2379,8 +2378,7 @@ static uint8_t riva128_pci_read(int func, int addr, void *p) break; case 0x3c: - // ret = riva128->pci_regs[0x3c]; - ret = 0x03; + ret = riva128->pci_regs[0x3c]; break; case 0x3d: @@ -2522,9 +2520,9 @@ static void riva128_pci_write(int func, int addr, uint8_t val, void *p) } return; - case 0x3c: + /* case 0x3c: riva128->pci_regs[0x3c] = val & 0x0f; - return; + return; */ case 0x40: case 0x41: @@ -2631,9 +2629,9 @@ static void rivatnt_pci_write(int func, int addr, uint8_t val, void *p) } return; - case 0x3c: + /* case 0x3c: riva128->pci_regs[0x3c] = val & 0x0f; - return; + return; */ case 0x40: case 0x41: @@ -2798,7 +2796,7 @@ static void *riva128_init() riva128->pci_regs[0x32] = 0x0c; riva128->pci_regs[0x33] = 0x00; - //riva128->pci_regs[0x3c] = 3; + riva128->pci_regs[0x3c] = device_get_config_int("irq"); riva128->pmc.intr = 0; riva128->pbus.intr = 0; @@ -2942,6 +2940,58 @@ static device_config_t riva128zx_config[] = }, .default_int = 4 }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 4", + .value = 4 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 9", + .value = 9 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 12", + .value = 12 + }, + { + .description = "IRQ 14", + .value = 14 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 3 + }, { .type = -1 } @@ -3020,7 +3070,7 @@ static void *rivatnt_init() riva128->pci_regs[0x32] = 0x0c; riva128->pci_regs[0x33] = 0x00; - //riva128->pci_regs[0x3c] = 3; + riva128->pci_regs[0x3c] = device_get_config_int("irq"); riva128->pmc.intr = 0; riva128->pbus.intr = 0; @@ -3108,6 +3158,58 @@ static device_config_t rivatnt_config[] = }, .default_int = 16 }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 4", + .value = 4 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 9", + .value = 9 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 12", + .value = 12 + }, + { + .description = "IRQ 14", + .value = 14 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 3 + }, { .type = -1 } @@ -3199,7 +3301,7 @@ static void *rivatnt2_init() riva128->pci_regs[0x32] = 0x0c; riva128->pci_regs[0x33] = 0x00; - //riva128->pci_regs[0x3c] = 3; + riva128->pci_regs[0x3c] = device_get_config_int("irq"); riva128->pmc.intr = 0; riva128->pbus.intr = 0; @@ -3312,6 +3414,58 @@ static device_config_t rivatnt2_config[] = }, .default_int = 32 }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 4", + .value = 4 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 9", + .value = 9 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 12", + .value = 12 + }, + { + .description = "IRQ 14", + .value = 14 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 3 + }, { .type = -1 } diff --git a/src/vid_olivetti_m24.c b/src/vid_olivetti_m24.c index cc80b7f12..c60061e62 100644 --- a/src/vid_olivetti_m24.c +++ b/src/vid_olivetti_m24.c @@ -160,7 +160,7 @@ void m24_poll(void *p) m24->sc = (m24->sc << 1) & 7; if (m24->dispon) { - pclog("dispon %i\n", m24->linepos); + // pclog("dispon %i\n", m24->linepos); if (m24->displine < m24->firstline) { m24->firstline = m24->displine; diff --git a/src/vid_s3.c b/src/vid_s3.c index 4cb3134e6..18e9a7607 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -20,7 +20,7 @@ enum { S3_VISION864, - S3_VISION964, + /* S3_VISION964, */ S3_TRIO32, S3_TRIO64 }; @@ -71,7 +71,7 @@ typedef struct s3_t svga_t svga; sdac_ramdac_t ramdac; - bt485_ramdac_t bt485_ramdac; + // bt485_ramdac_t bt485_ramdac; uint8_t bank; uint8_t ma_ext; @@ -789,11 +789,11 @@ void s3_out(uint16_t addr, uint8_t val, void *p) case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: // pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - if (s3->chip != S3_VISION964) + /* if (s3->chip != S3_VISION964) */ sdac_ramdac_out(addr, val, &s3->ramdac, svga); - else + /* else bt485_ramdac_out(addr, val, &s3->bt485_ramdac, svga); - return; + return; */ case 0x3D4: svga->crtcreg = val & 0x7f; @@ -906,6 +906,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) } } break; +#if 0 case 0x55: case 0x43: if (s3->chip == S3_VISION964) { @@ -922,6 +923,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) pclog("RS2 is now %i, RS3 is now %i\n", s3->bt485_ramdac.rs2, s3->bt485_ramdac.rs3); } break; +#endif // pclog("Write CRTC R%02X %02X\n", crtcreg, val); } if (old != val) @@ -960,10 +962,10 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: // pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - if (s3->chip != S3_VISION964) + // if (s3->chip != S3_VISION964) return sdac_ramdac_in(addr, &s3->ramdac, svga); - else - return bt485_ramdac_in(addr, &s3->bt485_ramdac, svga); + /* else + return bt485_ramdac_in(addr, &s3->bt485_ramdac, svga); */ case 0x3d4: return svga->crtcreg; @@ -2287,7 +2289,7 @@ static void *s3_init(char *bios_fn, int chip) svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); /* Set video BIOS to 32k (bit 2 = set). */ svga->crtc[0x37] = 5 | (7 << 5); - if (s3->chip == S3_VISION964) svga->crtc[0x37] |= 0xe; + // if (s3->chip == S3_VISION964) svga->crtc[0x37] |= 0xe; s3_io_set(s3); @@ -2315,7 +2317,7 @@ void *s3_bahamas64_init() s3_t *s3 = s3_init("roms/bahamas64.BIN", S3_VISION864); s3->id = 0xc0; /*Vision864P*/ - s3->id_ext = s3->id_ext_pci = 0xc1; + s3->id_ext = s3->id_ext_pci = 0xc0; s3->packed_mmio = 0; s3->getclock = sdac_getclock; @@ -2393,7 +2395,7 @@ void *s3_phoenix_vision864_init() { s3_t *s3 = s3_init("roms/86c864p.bin", S3_VISION864); - s3->id = 0xc0; /*Vision864P*/ + s3->id = 0xc1; /*Vision864P*/ s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; @@ -2408,12 +2410,12 @@ int s3_phoenix_vision864_available() return rom_present("roms/86c864p.BIN"); } -void *s3_diamond_stealth64_init() +/* void *s3_diamond_stealth64_init() { s3_t *s3 = s3_init("roms/STEALT64.BIN", S3_VISION864); svga_t *svga = &s3->svga; - s3->id = 0xc0; /*Vision864P*/ + s3->id = 0xc0; s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; @@ -2432,7 +2434,7 @@ void *s3_miro_vision964_init() { s3_t *s3 = s3_init("roms/mirocrystal.VBI", S3_VISION964); - s3->id = 0xd0; /*Vision964P*/ + s3->id = 0xd0; s3->id_ext = s3->id_ext_pci = 0xd1; s3->packed_mmio = 1; @@ -2445,7 +2447,7 @@ void *s3_miro_vision964_init() int s3_miro_vision964_available() { return rom_present("roms/mirocrystal.VBI"); -} +} */ void s3_close(void *p) { @@ -2649,7 +2651,7 @@ static device_config_t s3_phoenix_vision864_config[] = } }; -static device_config_t s3_diamond_stealth64_config[] = +/* static device_config_t s3_diamond_stealth64_config[] = { { .name = "memory", @@ -2720,7 +2722,6 @@ static device_config_t s3_miro_vision964_config[] = .description = "8 MB", .value = 8 }, - /*Vision864 also supports 8 MB, however the Paradise BIOS is buggy (VESA modes don't work correctly)*/ { .description = "" } @@ -2730,7 +2731,7 @@ static device_config_t s3_miro_vision964_config[] = { .type = -1 } -}; +}; */ device_t s3_bahamas64_device = { @@ -2797,7 +2798,7 @@ device_t s3_phoenix_vision864_device = s3_phoenix_vision864_config }; -device_t s3_diamond_stealth64_device = +/* device_t s3_diamond_stealth64_device = { "S3 Vision864 (Diamond Stealth64)", 0, @@ -2821,4 +2822,4 @@ device_t s3_miro_vision964_device = s3_force_redraw, s3_add_status_info, s3_miro_vision964_config -}; +}; */ diff --git a/src/vid_s3.h b/src/vid_s3.h index 2a1a01f25..34ae21b47 100644 --- a/src/vid_s3.h +++ b/src/vid_s3.h @@ -6,5 +6,5 @@ device_t s3_9fx_device; device_t s3_phoenix_trio32_device; device_t s3_phoenix_trio64_device; device_t s3_phoenix_vision864_device; -device_t s3_diamond_stealth64_device; -device_t s3_miro_vision964_device; +/* device_t s3_diamond_stealth64_device; +device_t s3_miro_vision964_device; */ diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index a01fc04e8..6319a3950 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3686,8 +3686,7 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x32: ret = virge->pci_regs[0x32]; break; case 0x33: ret = virge->pci_regs[0x33]; break; - // case 0x3c: ret = virge->pci_regs[0x3c]; break; - case 0x3c: ret = 0x03; break; + case 0x3c: ret = virge->pci_regs[0x3c]; break; case 0x3d: ret = 0x01; break; /*INTA*/ @@ -3749,9 +3748,9 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&virge->bios_rom.mapping); } return; - case 0x3c: + /* case 0x3c: virge->pci_regs[0x3c] = val; - return; + return; */ } } @@ -3809,6 +3808,7 @@ static void *s3_virge_init() virge->pci_regs[6] = 0; virge->pci_regs[7] = 2; virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3c] = device_get_config_int("irq"); virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; @@ -3903,6 +3903,7 @@ static void *s3_virge_375_init() virge->pci_regs[6] = 0; virge->pci_regs[7] = 2; virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3c] = device_get_config_int("irq"); virge->pci_regs[0x3d] = 1; virge->pci_regs[0x3e] = 4; virge->pci_regs[0x3f] = 0xff; @@ -4043,6 +4044,58 @@ static device_config_t s3_virge_config[] = .type = CONFIG_BINARY, .default_int = 1 }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 4", + .value = 4 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 9", + .value = 9 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 12", + .value = 12 + }, + { + .description = "IRQ 14", + .value = 14 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 3 + }, { .type = -1 } diff --git a/src/vid_svga.c b/src/vid_svga.c index 57999469f..0ee6b0c7b 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -382,22 +382,40 @@ uint8_t svga_in(uint16_t addr, void *p) case 0x3C1: return svga->attrregs[svga->attraddr]; case 0x3c2: - if (gfxcard == GFX_RIVA128) + if ((romset == ROM_IBMPS1_2011) || (romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS2_M30_286)) { - if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) + { temp = 0; + } else + { temp = 0x10; + } } else { - if (svga_get_input_status_0_ss(svga)) + if (gfxcard == GFX_RIVA128) { - temp |= 0x10; + if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x4e) + { + temp = 0; + } + else + { + temp = 0x10; + } } else { - temp &= ~0x10; + if (svga_get_input_status_0_ss(svga)) + { + temp = 0x10; + } + else + { + temp = 0; + } } } return temp; diff --git a/src/video.c b/src/video.c index 6dd8883a0..7af00d173 100644 --- a/src/video.c +++ b/src/video.c @@ -71,7 +71,7 @@ static VIDEO_CARD video_cards[] = {"CGA", "cga", &cga_device, GFX_CGA}, {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32}, - {"Diamond Stealth 64 DRAM (S3 Vision864)", "stealth64d", &s3_diamond_stealth64_device,GFX_STEALTH64}, + /* {"Diamond Stealth 64 DRAM (S3 Vision864)", "stealth64d", &s3_diamond_stealth64_device,GFX_STEALTH64}, */ {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE}, {"EGA", "ega", &ega_device, GFX_EGA}, {"Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA}, @@ -82,7 +82,7 @@ static VIDEO_CARD video_cards[] = {"Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS}, {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR}, {"MDA", "mda", &mda_device, GFX_MDA}, - {"Miro Crystal S3 Vision964", "mc_vision964", &s3_miro_vision964_device, GFX_MIRO_VISION964}, + /* {"Miro Crystal S3 Vision964", "mc_vision964", &s3_miro_vision964_device, GFX_MIRO_VISION964}, */ {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX}, {"nVidia RIVA 128 (Experimental)", "nv_riva128", &riva128_device, GFX_RIVA128}, {"nVidia RIVA TNT (Experimental)", "nv_rivatnt", &rivatnt_device, GFX_RIVATNT}, diff --git a/src/win-config.c b/src/win-config.c index 68a49c84c..a1894ee9e 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -33,11 +33,11 @@ static int settings_network_to_list[20], settings_list_to_network[20]; static int mouse_valid(int type, int model) { - if ((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2 && !(models[model].flags & MODEL_PS2)) + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2) && !(models[model].flags & MODEL_PS2)) return 0; - if ((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD && !(models[model].flags & MODEL_AMSTRAD)) + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD) && !(models[model].flags & MODEL_AMSTRAD)) return 0; - if ((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24 && !(models[model].flags & MODEL_OLIM24)) + if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24) && !(models[model].flags & MODEL_OLIM24)) return 0; return 1; } @@ -221,13 +221,13 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h = GetDlgItem(hdlg, IDC_MEMSPIN); SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[romset]].min_ram << 16) | models[romstomodel[romset]].max_ram); - if (!models[model].flags & MODEL_AT) - SendMessage(h, UDM_SETPOS, 0, mem_size); - else - SendMessage(h, UDM_SETPOS, 0, mem_size / 1024); accel.nSec = 0; accel.nInc = models[model].ram_granularity; SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); + if (!(models[model].flags & MODEL_AT)) + SendMessage(h, UDM_SETPOS, 0, mem_size); + else + SendMessage(h, UDM_SETPOS, 0, mem_size / 1024); h = GetDlgItem(hdlg, IDC_CONFIGUREMOD); if (model_getdevice(model)) @@ -339,7 +339,7 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"7 W/S"); SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); cpu_type = models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) EnableWindow(h, TRUE); else EnableWindow(h, FALSE); @@ -355,8 +355,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR break; type = mouse_get_type(c); + settings_mouse_to_list[c] = d; - + if (mouse_valid(type, model)) { SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index b6597c37f..6a4c2acbb 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -111,15 +111,22 @@ void cgapal_rebuild() { int c; for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); + { + pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); + } if ((cga_palette > 1) && (cga_palette < 8)) { for (c = 0; c < 16; c++) - pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + { + pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + } } if (cga_palette == 8) { - pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); + pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); } } From 64c941320f4a4b6d79a2729edd2a1c7dddd6b401 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Mar 2017 04:49:53 +0100 Subject: [PATCH 126/392] IBM PS/2 Model 30-286 now uses XTIDE version 1.1.5; The 287 FPU is now correctly detected as such; Added two instructions that were incorrectly missing from the 286, fixes Standard Mode Windows. --- src/mem.c | 6 +++++- src/x86_ops_fpu.h | 8 +++++++ src/x87_ops.h | 52 +++++++++++++++++++++++++++++++++++++++------ src/x87_ops_arith.h | 2 +- 4 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/mem.c b/src/mem.c index 015f325cf..8f170b626 100644 --- a/src/mem.c +++ b/src/mem.c @@ -611,6 +611,10 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; + if (enable_xtide) + { + mem_load_atide115_bios(); + } return 1; case ROM_DESKPRO_386: @@ -729,7 +733,7 @@ int loadbios() biosmask = 0x1ffff; if (enable_xtide) { - mem_load_atide_bios(); + mem_load_atide115_bios(); } return 1; diff --git a/src/x86_ops_fpu.h b/src/x86_ops_fpu.h index a1976f268..10102a4aa 100644 --- a/src/x86_ops_fpu.h +++ b/src/x86_ops_fpu.h @@ -3,6 +3,7 @@ */ static int opESCAPE_d8_a16(uint32_t fetchdat) { + pclog("D8 %02X\n", fetchdat & 0xff); return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_d8_a32(uint32_t fetchdat) @@ -12,6 +13,7 @@ static int opESCAPE_d8_a32(uint32_t fetchdat) static int opESCAPE_d9_a16(uint32_t fetchdat) { + pclog("D9 %02X\n", fetchdat & 0xff); return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_d9_a32(uint32_t fetchdat) @@ -21,6 +23,7 @@ static int opESCAPE_d9_a32(uint32_t fetchdat) static int opESCAPE_da_a16(uint32_t fetchdat) { + pclog("DA %02X\n", fetchdat & 0xff); return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_da_a32(uint32_t fetchdat) @@ -30,6 +33,7 @@ static int opESCAPE_da_a32(uint32_t fetchdat) static int opESCAPE_db_a16(uint32_t fetchdat) { + pclog("DB %02X\n", fetchdat & 0xff); return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_db_a32(uint32_t fetchdat) @@ -39,6 +43,7 @@ static int opESCAPE_db_a32(uint32_t fetchdat) static int opESCAPE_dc_a16(uint32_t fetchdat) { + pclog("DC %02X\n", fetchdat & 0xff); return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_dc_a32(uint32_t fetchdat) @@ -48,6 +53,7 @@ static int opESCAPE_dc_a32(uint32_t fetchdat) static int opESCAPE_dd_a16(uint32_t fetchdat) { + pclog("DD %02X\n", fetchdat & 0xff); return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_dd_a32(uint32_t fetchdat) @@ -57,6 +63,7 @@ static int opESCAPE_dd_a32(uint32_t fetchdat) static int opESCAPE_de_a16(uint32_t fetchdat) { + pclog("DE %02X\n", fetchdat & 0xff); return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_de_a32(uint32_t fetchdat) @@ -66,6 +73,7 @@ static int opESCAPE_de_a32(uint32_t fetchdat) static int opESCAPE_df_a16(uint32_t fetchdat) { + pclog("DF %02X\n", fetchdat & 0xff); return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_df_a32(uint32_t fetchdat) diff --git a/src/x87_ops.h b/src/x87_ops.h index 15c0c22d1..2121e0b0b 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -209,6 +209,28 @@ static inline uint16_t x87_compare(double a, double b) { #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 uint32_t out; + + if (!is386) + { + if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) + { + // pclog("Comparing infinity\n"); + + asm volatile ("" : : : "memory"); + + asm( + "fldl %2\n" + "fldl %1\n" + "fclex\n" + "fcompp\n" + "fnstsw %0\n" + : "=m" (out) + : "m" (a), "m" (a) + ); + + return out & (C0|C2|C3); + } + } /* Memory barrier, to force GCC to write to the input parameters * before the compare rather than after */ @@ -229,11 +251,27 @@ static inline uint16_t x87_compare(double a, double b) /* Generic C version is known to give incorrect results in some * situations, eg comparison of infinity (Unreal) */ uint32_t out = 0; - - if (a == b) - out |= C3; - else if (a < b) - out |= C0; + + if (is386) + { + if ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)) + { + out |= C3; + return out; + } + + if (a == b) + out |= C3; + else if (a < b) + out |= C0; + } + else + { + if (a == b) + out |= C3; + else if (a < b) + out |= C0; + } return out; #endif @@ -755,7 +793,7 @@ OpFn OP_TABLE(fpu_287_db_a16)[256] = ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFNOP, opFNOP, opFCLEX, opFINIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, @@ -793,7 +831,7 @@ OpFn OP_TABLE(fpu_287_db_a32)[256] = ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFNOP, opFNOP, opFCLEX, opFINIT, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, diff --git a/src/x87_ops_arith.h b/src/x87_ops_arith.h index 48a141e2f..1313839bb 100644 --- a/src/x87_ops_arith.h +++ b/src/x87_ops_arith.h @@ -169,7 +169,7 @@ static int opFCOMPP(uint32_t fetchdat) cpu_state.pc++; if (fplog) pclog("FCOMPP\n"); cpu_state.npxs &= ~(C0|C2|C3); - if (*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0) + if ((*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0) && is386) cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ else cpu_state.npxs |= x87_compare(ST(0), ST(1)); From 8e055b75209873c2970f38d1c5d861d5b1f1103f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 5 Mar 2017 19:42:56 +0100 Subject: [PATCH 127/392] Commented out excess FPU logging; SCSI controller is now reset on x86 soft reset, fixes DOS driver hangs after soft reset; SCSI controller reset control is now implemented more accurately, on a 50 ms timer; For the PS/1 Model 2011, the Keyboard Input Port bit 6 now correctly reports if the currently selected (in FDC DOR) floppy drive is 3.5" or 5.25"; Commented out excess DMA logging; Added support for FDF floppy images; Fixed handling of CDB allocated length field for the CD-ROM INQUIRY command; (S)VGA port 03C1 write is back again (it was incorrectly gone in some builds); Commented out Compaq/Paradise VGA; PS/1 Model 2121+ISA now correctly allows selecting graphics card. --- src/808x.c | 2 + src/Makefile.mingw | 4 +- src/buslogic.c | 57 ++++++++-- src/cdrom.c | 6 +- src/disc.c | 1 + src/disc_img.c | 259 ++++++++++++++++++++++++++++++++++++++++----- src/dma.c | 2 +- src/fdc.c | 12 +++ src/keyboard_at.c | 24 ++++- src/model.c | 4 +- src/vid_paradise.c | 8 +- src/vid_paradise.h | 2 +- src/vid_ps1_svga.c | 5 - src/vid_svga.c | 25 +++-- src/video.c | 2 +- src/win.c | 2 +- src/x86_ops_fpu.h | 8 -- 17 files changed, 352 insertions(+), 71 deletions(-) diff --git a/src/808x.c b/src/808x.c index 20f6e3b93..dd7228ed6 100644 --- a/src/808x.c +++ b/src/808x.c @@ -662,6 +662,7 @@ void resetx86() codegen_reset(); x86_was_reset = 1; port_92_clear_reset(); + BuslogicSoftReset(); } void softresetx86() @@ -685,6 +686,7 @@ void softresetx86() x86seg_reset(); x86_was_reset = 1; port_92_clear_reset(); + BuslogicSoftReset(); } static void setznp8(uint8_t val) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fdafe9849..9ac7152bc 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -33,8 +33,8 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) sleep 10 - strip "86Box.exe" - sleep 10 +strip "86Box.exe" +sleep 10 all : 86Box.exe diff --git a/src/buslogic.c b/src/buslogic.c index 9248c636d..b45ea65e3 100644 --- a/src/buslogic.c +++ b/src/buslogic.c @@ -29,6 +29,8 @@ #include "buslogic.h" +#define BUSLOGIC_RESET_DURATION_NS UINT64_C(50000000) + typedef struct __attribute__((packed)) { uint8_t hi; @@ -531,7 +533,9 @@ typedef struct __attribute__((packed)) Buslogic_t int scsi_model = 1; +int BuslogicResetCallback = 0; int BuslogicCallback = 0; + int BuslogicInOperation = 0; /** Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ @@ -621,9 +625,12 @@ static void BuslogicLocalRam(Buslogic_t *Buslogic) /** @todo calculate checksum? */ } +static Buslogic_t *BuslogicResetDevice; + static void BuslogicReset(Buslogic_t *Buslogic) { BuslogicCallback = 0; + BuslogicResetCallback = 0; Buslogic->Status = STAT_IDLE | STAT_INIT; Buslogic->Geometry = 0x80; Buslogic->Command = 0xFF; @@ -644,6 +651,14 @@ static void BuslogicReset(Buslogic_t *Buslogic) BuslogicLocalRam(Buslogic); } +void BuslogicSoftReset() +{ + if (BuslogicResetDevice != NULL) + { + BuslogicReset(BuslogicResetDevice); + } +} + static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset) { BuslogicReset(Buslogic); @@ -652,6 +667,7 @@ static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset) Buslogic->Status |= STAT_STST; Buslogic->Status &= ~STAT_IDLE; } + BuslogicResetCallback = BUSLOGIC_RESET_DURATION_NS * TIMER_USEC; } static void BuslogicCommandComplete(Buslogic_t *Buslogic) @@ -1056,12 +1072,19 @@ uint8_t BuslogicRead(uint16_t Port, void *p) { case 0: Temp = Buslogic->Status; +#if 0 if (Buslogic->Status & STAT_STST) { Buslogic->Status &= ~STAT_STST; Buslogic->Status |= STAT_IDLE; - Temp = Buslogic->Status; + + if (BuslogicResetCallback <= 0) + { + Temp = Buslogic->Status; + BuslogicResetCallback; + } } +#endif break; case 1: @@ -1246,6 +1269,9 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x8C: + Buslogic->CmdParamLeft = scsi_model ? 1 : 0; + break; + case 0x95: //Valid only for PCI Buslogic->CmdParamLeft = BuslogicIsPCI() ? 1 : 0; break; @@ -1336,7 +1362,7 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x0A: memset(Buslogic->DataBuf, 0, 8); - for (i = 0; i < 6; i++) + for (i = 0; i < 7; i++) { for (j = 0; j < 8; j++) { @@ -1646,14 +1672,12 @@ void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x8C: - if (BuslogicIsPCI()) + // if (BuslogicIsPCI()) + if (scsi_model) { int i = 0; Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; - for (i = 0; i < Buslogic->DataReplyLeft; i++) - { - Buslogic->DataBuf[0] = 0; - } + memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft); } else { @@ -2156,6 +2180,16 @@ static int BuslogicProcessMailbox(Buslogic_t *Buslogic) return ret; } +void BuslogicResetPoll(void *p) +{ + Buslogic_t *Buslogic = (Buslogic_t *)p; + + Buslogic->Status &= ~STAT_STST; + Buslogic->Status |= STAT_IDLE; + + BuslogicResetCallback = 0; +} + void BuslogicCommandCallback(void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; @@ -2169,7 +2203,7 @@ void BuslogicCommandCallback(void *p) if (BuslogicInOperation == 0) { - BuslogicLog("BusLogic Callback: Start outgoing mailbox\n"); + // BuslogicLog("BusLogic Callback: Start outgoing mailbox\n"); if (Buslogic->MailboxCount) { ret = BuslogicProcessMailbox(Buslogic); @@ -2395,6 +2429,8 @@ void *BuslogicInit() Buslogic_t *Buslogic = malloc(sizeof(Buslogic_t)); memset(Buslogic, 0, sizeof(Buslogic_t)); + BuslogicResetDevice = Buslogic; + scsi_model = device_get_config_int("model"); Buslogic->Base = device_get_config_int("addr"); Buslogic->PCIBase = 0; @@ -2406,10 +2442,11 @@ void *BuslogicInit() { if (BuslogicIsPCI()) { + io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); } else { - io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); + io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, NULL, BuslogicWrite, BuslogicWriteW, NULL, Buslogic); } } @@ -2424,6 +2461,7 @@ void *BuslogicInit() } } + timer_add(BuslogicResetPoll, &BuslogicResetCallback, &BuslogicResetCallback, Buslogic); timer_add(BuslogicCommandCallback, &BuslogicCallback, &BuslogicCallback, Buslogic); if (BuslogicIsPCI()) @@ -2455,6 +2493,7 @@ void BuslogicClose(void *p) { Buslogic_t *Buslogic = (Buslogic_t *)p; free(Buslogic); + BuslogicResetDevice = NULL; } static device_config_t BuslogicConfig[] = diff --git a/src/cdrom.c b/src/cdrom.c index 93fc0b85c..fdfd6cd65 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2585,6 +2585,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_INQUIRY: + max_len = cdb[3]; + max_len <<= 8; + max_len |= cdb[4]; + if (cdb[1] & 1) { preamble_len = 4; @@ -2658,7 +2662,7 @@ atapi_out: cdbufferb[size_idx] = idx - preamble_len; len=idx; - cdrom_data_command_finish(id, len, len, cdb[4], 0); + cdrom_data_command_finish(id, len, len, max_len, 0); break; case GPCMD_PREVENT_REMOVAL: diff --git a/src/disc.c b/src/disc.c index ed3d7d1d2..e5d202775 100644 --- a/src/disc.c +++ b/src/disc.c @@ -83,6 +83,7 @@ loaders[]= {"CQM", 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}, diff --git a/src/disc_img.c b/src/disc_img.c index f7b88e882..5bbe87526 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -29,8 +29,9 @@ static struct uint16_t sector_pos[2][256]; uint8_t current_sector_pos_side; uint16_t current_sector_pos; - uint8_t *cqm_data; + uint8_t *disk_data; uint8_t is_cqm; + uint8_t disk_at_once; uint8_t interleave; uint8_t skew; } img[FDD_NUM]; @@ -225,10 +226,15 @@ int first_byte_is_valid(uint8_t first_byte) } } +double bit_rate_300; + +char ext[4]; + +uint8_t first_byte, second_byte, third_byte, fourth_byte; + void img_load(int drive, char *fn) { int size; - double bit_rate_300; uint16_t bpb_bps; uint16_t bpb_total; uint8_t bpb_mid; /* Media type ID. */ @@ -237,14 +243,17 @@ void img_load(int drive, char *fn) uint32_t bpt; uint8_t max_spt; /* Used for XDF detection. */ int temp_rate; - char ext[4]; - int fdi, cqm; + uint8_t fdi, cqm, fdf; int i; - uint8_t first_byte, second_byte; uint16_t comment_len = 0; int16_t block_len = 0; uint32_t cur_pos = 0; uint8_t rep_byte = 0; + uint8_t run = 0; + uint8_t real_run = 0; + uint8_t *bpos; + uint16_t track_bytes = 0; + uint8_t *literal; ext[0] = fn[strlen(fn) - 3] | 0x60; ext[1] = fn[strlen(fn) - 2] | 0x60; @@ -291,22 +300,218 @@ void img_load(int drive, char *fn) fseek(img[drive].f, 0x18, SEEK_SET); bpb_sides = fgetc(img[drive].f); + fseek(img[drive].f, img[drive].base, SEEK_SET); + first_byte = fgetc(img[drive].f); + fdi = 1; cqm = 0; + img[drive].disk_at_once = 0; + fdf = 0; } else { - /* Read the first type bytes. */ + /* Read the first four bytes. */ fseek(img[drive].f, 0x00, SEEK_SET); first_byte = fgetc(img[drive].f); fseek(img[drive].f, 0x01, SEEK_SET); second_byte = fgetc(img[drive].f); + fseek(img[drive].f, 0x02, SEEK_SET); + third_byte = fgetc(img[drive].f); + fseek(img[drive].f, 0x03, SEEK_SET); + fourth_byte = fgetc(img[drive].f); + + if ((first_byte == 0x1A) && (second_byte == 'F') && (third_byte == 'D') && (fourth_byte == 'F')) + { + /* This is a FDF image. */ + pclog("img_load(): File is a FDF image...\n"); + fwriteprot[drive] = writeprot[drive] = 1; + fclose(img[drive].f); + img[drive].f = fopen(fn, "rb"); + + fdf = 1; + + cqm = 0; + img[drive].disk_at_once = 1; + + fseek(img[drive].f, 0x50, SEEK_SET); + fread(&img[drive].tracks, 1, 4, img[drive].f); + + /* Decode the entire file - pass 1, no write to buffer, determine length. */ + fseek(img[drive].f, 0x80, SEEK_SET); + size = 0; + track_bytes = 0; + bpos = img[drive].disk_data; + while(!feof(img[drive].f)) + { + if (!track_bytes) + { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(img[drive].f); + fread(&track_bytes, 1, 2, img[drive].f); + pclog("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + fread(&track_bytes, 1, 2, img[drive].f); + pclog("%04X\n", track_bytes); + } + + if (feof(img[drive].f)) + { + break; + } + + if (first_byte == 0xFF) + { + break; + } + + if (first_byte) + { + run = fgetc(img[drive].f); + + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; + + if (run & 0x80) + { + /* Repeat. */ + track_bytes--; + rep_byte = fgetc(img[drive].f); + } + else + { + /* Literal. */ + track_bytes -= (run & 0x7f); + literal = (uint8_t *) malloc(run & 0x7f); + fread(literal, 1, (run & 0x7f), img[drive].f); + free(literal); + } + size += (run & 0x7f); + if (!track_bytes) + { + size--; + } + } + else + { + /* Literal block. */ + size += (track_bytes - 1); + literal = (uint8_t *) malloc(track_bytes); + fread(literal, 1, track_bytes, img[drive].f); + free(literal); + track_bytes = 0; + } + + if (feof(img[drive].f)) + { + break; + } + } + + /* Allocate the buffer. */ + img[drive].disk_data = (uint8_t *) malloc(size); + + /* Decode the entire file - pass 2, write to buffer. */ + fseek(img[drive].f, 0x80, SEEK_SET); + track_bytes = 0; + bpos = img[drive].disk_data; + while(!feof(img[drive].f)) + { + if (!track_bytes) + { + /* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */ + first_byte = fgetc(img[drive].f); + fread(&track_bytes, 1, 2, img[drive].f); + pclog("Block header: %02X %04X ", first_byte, track_bytes); + /* Read the length of encoded data block. */ + fread(&track_bytes, 1, 2, img[drive].f); + pclog("%04X\n", track_bytes); + } + + if (feof(img[drive].f)) + { + break; + } + + if (first_byte == 0xFF) + { + break; + } + + if (first_byte) + { + run = fgetc(img[drive].f); + real_run = (run & 0x7f); + + /* I *HAVE* to read something because fseek tries to be smart and never hits EOF, causing an infinite loop. */ + track_bytes--; + + if (run & 0x80) + { + /* Repeat. */ + track_bytes--; + if (!track_bytes) + { + real_run--; + } + rep_byte = fgetc(img[drive].f); + if (real_run) + { + memset(bpos, rep_byte, real_run); + } + } + else + { + /* Literal. */ + track_bytes -= real_run; + literal = (uint8_t *) malloc(real_run); + fread(literal, 1, real_run, img[drive].f); + if (!track_bytes) + { + real_run--; + } + if (run & 0x7f) + { + memcpy(bpos, literal, real_run); + } + free(literal); + } + bpos += real_run; + } + else + { + /* Literal block. */ + literal = (uint8_t *) malloc(track_bytes); + fread(literal, 1, track_bytes, img[drive].f); + memcpy(bpos, literal, track_bytes - 1); + free(literal); + bpos += (track_bytes - 1); + track_bytes = 0; + } + + if (feof(img[drive].f)) + { + break; + } + } + + first_byte = *img[drive].disk_data; + + bpb_bps = *(uint16_t *) (img[drive].disk_data + 0x0B); + bpb_total = *(uint16_t *) (img[drive].disk_data + 0x13); + bpb_mid = *(img[drive].disk_data + 0x15); + bpb_sectors = *(img[drive].disk_data + 0x18); + bpb_sides = *(img[drive].disk_data + 0x1A); + + /* Jump ahead to determine the image's geometry and finish the loading. */ + goto jump_if_fdf; + } if (((first_byte == 'C') && (second_byte == 'Q')) || ((first_byte == 'c') && (second_byte == 'q'))) { pclog("img_load(): File is a CopyQM image...\n"); - fwriteprot[drive] = writeprot[drive] = 1; + fclose(img[drive].f); + img[drive].f = fopen(fn, "rb"); fseek(img[drive].f, 0x03, SEEK_SET); fread(&bpb_bps, 1, 2, img[drive].f); @@ -326,8 +531,8 @@ void img_load(int drive, char *fn) fseek(img[drive].f, 0x76, SEEK_SET); img[drive].skew = fgetc(img[drive].f); - img[drive].cqm_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); - memset(img[drive].cqm_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + img[drive].disk_data = (uint8_t *) malloc(((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); + memset(img[drive].disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)); fseek(img[drive].f, 0x6F, SEEK_SET); fread(&comment_len, 1, 2, img[drive].f); @@ -352,12 +557,12 @@ void img_load(int drive, char *fn) if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - memset(img[drive].cqm_data + cur_pos, rep_byte, block_len); + memset(img[drive].disk_data + cur_pos, rep_byte, block_len); break; } else { - memset(img[drive].cqm_data + cur_pos, rep_byte, block_len); + memset(img[drive].disk_data + cur_pos, rep_byte, block_len); cur_pos += block_len; } } @@ -366,12 +571,12 @@ void img_load(int drive, char *fn) if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) { block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos; - fread(img[drive].cqm_data + cur_pos, 1, block_len, img[drive].f); + fread(img[drive].disk_data + cur_pos, 1, block_len, img[drive].f); break; } else { - fread(img[drive].cqm_data + cur_pos, 1, block_len, img[drive].f); + fread(img[drive].disk_data + cur_pos, 1, block_len, img[drive].f); cur_pos += block_len; } } @@ -380,9 +585,13 @@ void img_load(int drive, char *fn) printf("Finished reading CopyQM image data\n"); cqm = 1; + img[drive].disk_at_once = 1; + fdf = 0; + first_byte = *img[drive].disk_data; } else { + img[drive].disk_at_once = 0; /* Read the BPB */ pclog("img_load(): File is a raw image...\n"); fseek(img[drive].f, 0x0B, SEEK_SET); @@ -399,11 +608,12 @@ void img_load(int drive, char *fn) cqm = 0; } - img[drive].base = 0; - fdi = 0; - fseek(img[drive].f, -1, SEEK_END); size = ftell(img[drive].f) + 1; + +jump_if_fdf: + img[drive].base = 0; + fdi = 0; } img[drive].sides = 2; @@ -432,7 +642,7 @@ void img_load(int drive, char *fn) else if (size <= (1120*1024)) { img[drive].sectors = 14; img[drive].tracks = 80; } /*Double density*/ else if (size <= 1228800) { img[drive].sectors = 15; img[drive].tracks = 80; } /*High density 1.2MB*/ else if (size <= 1261568) { img[drive].sectors = 8; img[drive].tracks = 77; img[drive].sector_size = 3; } /*High density 1.25MB Japanese format*/ - else if (size <= (0x1A4000-1)) { img[drive].sectors = 18; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/ + else if (size <= 1474560) { img[drive].sectors = 18; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/ else if (size <= 1556480) { img[drive].sectors = 19; img[drive].tracks = 80; } /*High density (not supported by Tandy 1000)*/ else if (size <= 1638400) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ else if (size <= 1720320) { img[drive].sectors = 21; img[drive].tracks = 80; } /*DMF format - used by Windows 95 */ @@ -467,7 +677,7 @@ void img_load(int drive, char *fn) } else { - if (!cqm) + if (!cqm && !fdf) { /* Number of tracks = number of total sectors divided by sides times sectors per track. */ img[drive].tracks = ((uint32_t) bpb_total) / (((uint32_t) bpb_sides) * ((uint32_t) bpb_sectors)); @@ -552,9 +762,10 @@ void img_close(int drive) d86f_unregister(drive); if (img[drive].f) fclose(img[drive].f); - if (img[drive].cqm_data) - free(img[drive].cqm_data); + if (img[drive].disk_data) + free(img[drive].disk_data); img[drive].f = NULL; + img[drive].disk_data = NULL; } #define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] @@ -602,18 +813,18 @@ void img_seek(int drive, int track) is_t0 = (track == 0) ? 1 : 0; - if (!img[drive].is_cqm) + if (!img[drive].disk_at_once) { fseek(img[drive].f, img[drive].base + (track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET); } for (side = 0; side < img[drive].sides; side++) { - if (img[drive].is_cqm) + if (img[drive].disk_at_once) { cur_pos = (track * img[drive].sectors * ssize * img[drive].sides) + (side * img[drive].sectors * ssize); // pclog("Current position: %i... ", cur_pos); - memcpy(img[drive].track_data[side], img[drive].cqm_data + cur_pos, img[drive].sectors * ssize); + memcpy(img[drive].track_data[side], img[drive].disk_data + cur_pos, img[drive].sectors * ssize); // pclog("done!\n"); } else @@ -753,7 +964,7 @@ void img_writeback(int drive) if (!img[drive].f) return; - if (img[drive].is_cqm) + if (img[drive].disk_at_once) return; fseek(img[drive].f, img[drive].base + (img[drive].track * img[drive].sectors * ssize * img[drive].sides), SEEK_SET); diff --git a/src/dma.c b/src/dma.c index a6d43550f..391121c18 100644 --- a/src/dma.c +++ b/src/dma.c @@ -297,7 +297,7 @@ void dma_page_write(uint16_t addr, uint8_t val, void *priv) dma16.page[0] = val; break; default: - pclog("DMA write to extra page register: %02X\n", addr & 0xf); + // pclog("DMA write to extra page register: %02X\n", addr & 0xf); break; } } diff --git a/src/fdc.c b/src/fdc.c index f23ce3252..42ea7ff49 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -156,6 +156,18 @@ sector_id_t fdc_get_read_track_sector() return fdc.read_track_sector; } +int fdc_ps1_525() +{ + if ((romset == ROM_IBMPS1_2011) && fdd_is_525(real_drive(fdc.dor & 3))) + { + return 0x40; + } + else + { + return 0; + } +} + int fdc_get_compare_condition() { switch (discint) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 24cabb4f9..9d9857945 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -642,17 +642,17 @@ bad_command: break; case 0xc0: /*Read input port*/ - keyboard_at_adddata((keyboard_at.input_port & 0xfc) | 0x84); + keyboard_at_adddata((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()); break; case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ keyboard_at.status &= 0xf; - keyboard_at.status |= ((keyboard_at.input_port & 0xf) << 4); + keyboard_at.status |= ((((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf) << 4); break; case 0xc2: /*Copy bits 4 to 7 of input port to status bits 4 to 7*/ keyboard_at.status &= 0xf; - keyboard_at.status |= (keyboard_at.input_port & 0xf0); + keyboard_at.status |= (((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()) & 0xf0); break; case 0xc9: /*AMI - block P22 and P23 ??? */ @@ -689,7 +689,23 @@ bad_command: case 0xd4: /*Write to mouse*/ keyboard_at.want60 = 1; break; - + + case 0xdd: /* Disable A20 Address Line */ + keyboard_at.output_port &= ~0x02; + mem_a20_key = 0; + mem_a20_recalc(); + // pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); + flushmmucache(); + break; + + case 0xdf: /* Enable A20 Address Line */ + keyboard_at.output_port |= 0x02; + mem_a20_key = 2; + mem_a20_recalc(); + // pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); + flushmmucache(); + break; + case 0xe0: /*Read test inputs*/ keyboard_at_adddata(0x00); break; diff --git a/src/model.c b/src/model.c index c5a7a79aa..191aec7fd 100644 --- a/src/model.c +++ b/src/model.c @@ -155,7 +155,7 @@ MODEL models[] = {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, @@ -379,7 +379,6 @@ void ps1_common_init() device_add(&ps1_audio_device); /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ if (joystick_type != 7) device_add(&gameport_201_device); - fdc_set_ps1(); } void ps1_m2011_init() @@ -392,6 +391,7 @@ void ps1_m2121_init() { ps1_common_init(); ps1mb_m2121_init(); + fdc_set_ps1(); } void ps2_m30_286_init() diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 218f6683d..e6ce2ee06 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -366,7 +366,7 @@ static int paradise_wd90c11_standalone_available() return rom_present("roms/megapc/41651-bios lo.u18") && rom_present("roms/megapc/211253-bios hi.u19"); } -static void *cpqvga_init() +/* static void *cpqvga_init() { paradise_t *paradise = paradise_pvga1a_init(); @@ -379,7 +379,7 @@ static void *cpqvga_init() static int cpqvga_standalone_available() { return rom_present("roms/1988-05-18.rom"); -} +} */ void paradise_close(void *p) { @@ -455,7 +455,7 @@ device_t paradise_wd90c11_device = paradise_force_redraw, paradise_add_status_info }; -device_t cpqvga_device = +/* device_t cpqvga_device = { "Compaq/Paradise VGA", 0, @@ -465,4 +465,4 @@ device_t cpqvga_device = paradise_speed_changed, paradise_force_redraw, paradise_add_status_info -}; +}; */ diff --git a/src/vid_paradise.h b/src/vid_paradise.h index 63503670c..e28bb4fae 100644 --- a/src/vid_paradise.h +++ b/src/vid_paradise.h @@ -5,4 +5,4 @@ extern device_t paradise_pvga1a_pc2086_device; extern device_t paradise_pvga1a_pc3086_device; extern device_t paradise_wd90c11_megapc_device; extern device_t paradise_wd90c11_device; -extern device_t cpqvga_device; +// extern device_t cpqvga_device; diff --git a/src/vid_ps1_svga.c b/src/vid_ps1_svga.c index 700582938..4c0ce9963 100644 --- a/src/vid_ps1_svga.c +++ b/src/vid_ps1_svga.c @@ -1,6 +1,3 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ /*Emulation of the SVGA chip in the IBM PS/1 Model 2121, or at least the 20 MHz version. @@ -48,8 +45,6 @@ void ps1_m2121_svga_out(uint16_t addr, uint8_t val, void *p) svga->crtcreg = val & 0x1f; return; case 0x3D5: - if (svga->crtcreg <= 0x18) - val &= mask_crtc[svga->crtcreg]; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) diff --git a/src/vid_svga.c b/src/vid_svga.c index 0ee6b0c7b..2e2b34da7 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -64,7 +64,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = (svga_t *)p; int c; uint8_t o; -// printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,pc); + // printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); switch (addr) { case 0x32CB: @@ -102,7 +102,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) return; case 0x3C0: - // case 0x3C1: + case 0x3C1: if (!svga->attrff) { svga->attraddr = val & 31; @@ -170,8 +170,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) if (svga->seqaddr > 0xf) return; o = svga->seqregs[svga->seqaddr & 0xf]; /* Sanitize value for the first 5 sequencer registers. */ - if ((svga->seqaddr & 0xf) <= 4) - val &= mask_seq[svga->seqaddr & 0xf]; + /* if ((svga->seqaddr & 0xf) <= 4) + val &= mask_seq[svga->seqaddr & 0xf]; */ svga->seqregs[svga->seqaddr & 0xf] = val; if (o != val && (svga->seqaddr & 0xf) == 1) svga_recalctimings(svga); @@ -236,7 +236,16 @@ void svga_out(uint16_t addr, uint8_t val, void *p) if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[svga->dac_write] = makecol32(svga->vgapal[svga->dac_write].r, svga->vgapal[svga->dac_write].g, svga->vgapal[svga->dac_write].b); else - svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r], video_6to8[svga->vgapal[svga->dac_write].g], video_6to8[svga->vgapal[svga->dac_write].b]); + { + if ((romset == ROM_IBMPS1_2011) || (romset == ROM_IBMPS1_2121) || (romset == ROM_IBMPS2_M30_286)) + { + svga->pallook[svga->dac_write] = makecol32((svga->vgapal[svga->dac_write].r & 0x3f) * 4, (svga->vgapal[svga->dac_write].g & 0x3f) * 4, (svga->vgapal[svga->dac_write].b & 0x3f) * 4); + } + else + { + svga->pallook[svga->dac_write] = makecol32(video_6to8[svga->vgapal[svga->dac_write].r], video_6to8[svga->vgapal[svga->dac_write].g], video_6to8[svga->vgapal[svga->dac_write].b]); + } + } svga->dac_pos = 0; svga->dac_write = (svga->dac_write + 1) & 255; break; @@ -247,8 +256,8 @@ void svga_out(uint16_t addr, uint8_t val, void *p) break; case 0x3CF: /* Sanitize the first 9 GDC registers. */ - if ((svga->gdcaddr & 15) <= 8) - val &= mask_gdc[svga->gdcaddr & 15]; + /* if ((svga->gdcaddr & 15) <= 8) + val &= mask_gdc[svga->gdcaddr & 15]; */ o = svga->gdcreg[svga->gdcaddr & 15]; switch (svga->gdcaddr & 15) { @@ -340,7 +349,7 @@ uint8_t svga_in(uint16_t addr, void *p) { svga_t *svga = (svga_t *)p; uint8_t temp; -// if (addr!=0x3da) pclog("Read port %04X\n",addr); + // if (addr!=0x3da) pclog("Read port %04X\n",addr); switch (addr) { case 0x22CA: diff --git a/src/video.c b/src/video.c index 7af00d173..9ac3a3040 100644 --- a/src/video.c +++ b/src/video.c @@ -77,7 +77,7 @@ static VIDEO_CARD video_cards[] = {"Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA}, {"Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL}, {"Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA}, - {"Compaq/Paradise VGA", "compaq_vga", &cpqvga_device, GFX_COMPAQ_VGA}, + /* {"Compaq/Paradise VGA", "compaq_vga", &cpqvga_device, GFX_COMPAQ_VGA}, */ {"Hercules", "hercules", &hercules_device, GFX_HERCULES}, {"Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS}, {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR}, diff --git a/src/win.c b/src/win.c index d4f670530..4b5f87f32 100644 --- a/src/win.c +++ b/src/win.c @@ -1084,7 +1084,7 @@ void cdrom_close(uint8_t id) } } -char *floppy_image_extensions = "All floppy images (*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0"; +char *floppy_image_extensions = "All floppy images (*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0"; int ide_ter_set_irq(HMENU hmenu, int irq, int id) { diff --git a/src/x86_ops_fpu.h b/src/x86_ops_fpu.h index 10102a4aa..a1976f268 100644 --- a/src/x86_ops_fpu.h +++ b/src/x86_ops_fpu.h @@ -3,7 +3,6 @@ */ static int opESCAPE_d8_a16(uint32_t fetchdat) { - pclog("D8 %02X\n", fetchdat & 0xff); return x86_opcodes_d8_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_d8_a32(uint32_t fetchdat) @@ -13,7 +12,6 @@ static int opESCAPE_d8_a32(uint32_t fetchdat) static int opESCAPE_d9_a16(uint32_t fetchdat) { - pclog("D9 %02X\n", fetchdat & 0xff); return x86_opcodes_d9_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_d9_a32(uint32_t fetchdat) @@ -23,7 +21,6 @@ static int opESCAPE_d9_a32(uint32_t fetchdat) static int opESCAPE_da_a16(uint32_t fetchdat) { - pclog("DA %02X\n", fetchdat & 0xff); return x86_opcodes_da_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_da_a32(uint32_t fetchdat) @@ -33,7 +30,6 @@ static int opESCAPE_da_a32(uint32_t fetchdat) static int opESCAPE_db_a16(uint32_t fetchdat) { - pclog("DB %02X\n", fetchdat & 0xff); return x86_opcodes_db_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_db_a32(uint32_t fetchdat) @@ -43,7 +39,6 @@ static int opESCAPE_db_a32(uint32_t fetchdat) static int opESCAPE_dc_a16(uint32_t fetchdat) { - pclog("DC %02X\n", fetchdat & 0xff); return x86_opcodes_dc_a16[(fetchdat >> 3) & 0x1f](fetchdat); } static int opESCAPE_dc_a32(uint32_t fetchdat) @@ -53,7 +48,6 @@ static int opESCAPE_dc_a32(uint32_t fetchdat) static int opESCAPE_dd_a16(uint32_t fetchdat) { - pclog("DD %02X\n", fetchdat & 0xff); return x86_opcodes_dd_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_dd_a32(uint32_t fetchdat) @@ -63,7 +57,6 @@ static int opESCAPE_dd_a32(uint32_t fetchdat) static int opESCAPE_de_a16(uint32_t fetchdat) { - pclog("DE %02X\n", fetchdat & 0xff); return x86_opcodes_de_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_de_a32(uint32_t fetchdat) @@ -73,7 +66,6 @@ static int opESCAPE_de_a32(uint32_t fetchdat) static int opESCAPE_df_a16(uint32_t fetchdat) { - pclog("DF %02X\n", fetchdat & 0xff); return x86_opcodes_df_a16[fetchdat & 0xff](fetchdat); } static int opESCAPE_df_a32(uint32_t fetchdat) From ee69d5dec05dfe7c5907cdbc613d37b5c61357c2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 5 Mar 2017 19:48:09 +0100 Subject: [PATCH 128/392] Fixed (hopefully) the makefile. --- src/Makefile.mingw | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 9ac7152bc..fdafe9849 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -33,8 +33,8 @@ LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) sleep 10 -strip "86Box.exe" -sleep 10 + strip "86Box.exe" + sleep 10 all : 86Box.exe From b6c48c1486d363917bbba5a9327ed5726b4bf1d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 5 Mar 2017 20:15:36 +0100 Subject: [PATCH 129/392] 86Box v1.06 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fdafe9849..65946b4fd 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 90874a262..0acc20863 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 9d33905d85f4622d9c7df595c21a50df0473f682 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 7 Mar 2017 06:17:16 +0100 Subject: [PATCH 130/392] Version changed to 1.10. --- src/86box.h | 2 +- src/Makefile.mingw | 5 ++--- src/Makefile.mingw64 | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/86box.h b/src/86box.h index 3912cea8e..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.06" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 65946b4fd..fdafe9849 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 0acc20863..90874a262 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,9 +2,8 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From a57aa0ffcc320f868012105739a02545c3779d71 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 14 Mar 2017 00:38:25 +0100 Subject: [PATCH 131/392] Version changed to 1.07; Added Intel Advanced/ZP; Added Commodore PC 60 III; Fixed Force 4:3 option when overscan is not enabled; Added option to scale (0.5x, 1x, 1.5x, 2x) the video output; Added ability to disable ATAPI DMA for CD-ROM drives; Applied all mainline PCem commits; Store network card in config file as name rather than number; Fixed NVR storing for IBM PS/2 Models 2121 and 2121+ISA. --- src/86box.h | 2 +- src/cdrom.c | 2 +- src/cdrom.h | 1 + src/ibm.h | 6 +++- src/intel_flash.c | 3 ++ src/mem.c | 29 +++++++++++++++++++ src/model.c | 4 ++- src/nethandler.c | 28 +++++++++++++++--- src/nethandler.h | 2 ++ src/nvr.c | 12 +++++--- src/pc.c | 28 ++++++++++++++---- src/pc.rc | 15 +++++++++- src/resources.h | 8 ++++++ src/sound.c | 48 ++++++++++++++++++++++--------- src/sound.h | 2 ++ src/win.c | 73 +++++++++++++++++++++++++++++++++++++++++------ 16 files changed, 223 insertions(+), 40 deletions(-) diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..80227a810 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.07" diff --git a/src/cdrom.c b/src/cdrom.c index fdfd6cd65..24a00cbeb 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -331,7 +331,7 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type) cdrom[id].cd_status = CD_STATUS_EMPTY; cdrom[id].sense[0] = 0xf0; cdrom[id].sense[7] = 10; - cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : 3; + cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : (cdrom_drives[id].atapi_dma ? 3 : 1); cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode); if (!cdrom_drives[id].bus_type) { diff --git a/src/cdrom.h b/src/cdrom.h index 78731c317..2902fd39d 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -139,6 +139,7 @@ typedef struct __attribute__((__packed__)) uint8_t scsi_device_lun; uint8_t sound_on; + uint8_t atapi_dma; } cdrom_drive_t; extern cdrom_drive_t cdrom_drives[CDROM_NUM]; diff --git a/src/ibm.h b/src/ibm.h index eebb072b4..8f9cdfabd 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -425,7 +425,9 @@ enum ROM_SUPER286TR, /*Hyundai Super-286TR / SCAT / Award BIOS*/ ROM_MEGAPCDX, /*386DX mdoel of the Mega PC - Note by Tohka: The documentation (that I have in German) clearly says such a model exists.*/ - ROM_PX486, /*Phoenix 486 clone*/ + ROM_ZAPPA, /*Intel Advanced/ZP / 430FX / AMI BIOS / National Semiconductors PC87306*/ + + ROM_CMDPC60, ROM_MAX }; @@ -639,3 +641,5 @@ extern int enable_external_fpu; extern int invert_display; uint32_t svga_color_transform(uint32_t color); + +extern int scale; diff --git a/src/intel_flash.c b/src/intel_flash.c index 19d7a7864..de8fe15a5 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -216,6 +216,9 @@ void *intel_flash_init(uint8_t type) case ROM_MRTHOR: strcpy(flash_path, "roms/mrthor/"); break; + case ROM_ZAPPA: + strcpy(flash_path, "roms/zappa/"); + break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); } diff --git a/src/mem.c b/src/mem.c index 8f170b626..0619e717a 100644 --- a/src/mem.c +++ b/src/mem.c @@ -371,6 +371,19 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; + case ROM_CMDPC60: + f = romfopen("roms/cmdpc60/cbm-pc60c-bios-lo-v1.36-390473-07.bin", "rb"); + ff = romfopen("roms/cmdpc60/cbm-pc60c-bios-hi-v1.36-390474-07.bin", "rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x20000; c += 2) + { + rom[c] = getc(f); + rom[c + 1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; case ROM_DELL200: f=romfopen("roms/dells200/dell0.bin","rb"); ff=romfopen("roms/dells200/dell1.bin","rb"); @@ -728,6 +741,7 @@ int loadbios() case ROM_IBMPS2_M30_286: f = romfopen("roms/ibmps2_m30_286/33f5381a.bin", "rb"); + if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; @@ -889,6 +903,21 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; + + case ROM_ZAPPA: + f = romfopen("roms/zappa/1006BS0_.BIO", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + fread(rom + 0x10000, 0x10000, 1, f); + fclose(f); + f = romfopen("roms/zappa/1006BS0_.BI1", "rb"); + if (!f) break; + fseek(f, 0x80, SEEK_SET); + fread(rom, 0x10000, 1, f); + fclose(f); + biosmask = 0x1ffff; + //is486=1; + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 191aec7fd..133c32ca5 100644 --- a/src/model.c +++ b/src/model.c @@ -159,9 +159,10 @@ MODEL models[] = {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, + {"Commodore PC 60 III", ROM_CMDPC60, "cmdpc60", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, @@ -173,6 +174,7 @@ MODEL models[] = {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 128, 1, at_586mc1_init, NULL}, {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, diff --git a/src/nethandler.c b/src/nethandler.c index 90d3e0f82..eec4934bf 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -21,15 +21,16 @@ static int network_card_last = 0; typedef struct { - char name[32]; + char name[64]; + char internal_name[32]; device_t *device; } NETWORK_CARD; static NETWORK_CARD network_cards[] = { - {"None", NULL}, - {"Novell NE2000", &ne2000_device}, - {"Realtek RTL8029AS", &rtl8029as_device}, + {"None", "none", NULL}, + {"Novell NE2000", "ne2k", &ne2000_device}, + {"Realtek RTL8029AS", "ne2kpci", &rtl8029as_device}, {"", NULL} }; @@ -58,6 +59,25 @@ int network_card_has_config(int card) return network_cards[card].device->config ? 1 : 0; } +char *network_card_get_internal_name(int card) +{ + return network_cards[card].internal_name; +} + +int network_card_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(network_cards[c].internal_name)) + { + if (!strcmp(network_cards[c].internal_name, s)) + return c; + c++; + } + + return 0; +} + void network_card_init() { if (network_cards[network_card_current].device) diff --git a/src/nethandler.h b/src/nethandler.h index a6e6c5c77..477ecbd81 100644 --- a/src/nethandler.h +++ b/src/nethandler.h @@ -12,6 +12,8 @@ int network_card_available(int card); char *network_card_getname(int card); struct device_t *network_card_getdevice(int card); int network_card_has_config(int card); +char *network_card_get_internal_name(int card); +int network_card_get_from_internal_name(char *s); void network_card_init(); void initpcap(); diff --git a/src/nvr.c b/src/nvr.c index 4f83c9c2e..f94dc029e 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -206,10 +206,10 @@ void loadnvr() case ROM_PC2086: f = romfopen(nvr_concat("pc2086.nvr"), "rb"); break; case ROM_PC3086: f = romfopen(nvr_concat("pc3086.nvr"), "rb"); break; case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "rb"); break; - case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); /*nvrmask = 127; */break; - case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); /*nvrmask = 127; */break; + case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); break; + case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); break; + case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); break; + case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; @@ -253,6 +253,8 @@ void loadnvr() #endif case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "rb"); nvrmask = 127; break; case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "rb"); nvrmask = 127; break; + case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "rb"); nvrmask = 127; break; + case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "rb"); nvrmask = 127; break; default: return; } if (!f) @@ -337,6 +339,8 @@ void savenvr() #endif case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "wb"); break; case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "wb"); break; + case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "wb"); break; + case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/pc.c b/src/pc.c index 511de3999..37f12430a 100644 --- a/src/pc.c +++ b/src/pc.c @@ -743,7 +743,11 @@ void loadconfig(char *fn) ethif = config_get_int(NULL, "netinterface", 1); if (ethif >= inum) inum = ethif + 1; - network_card_current = config_get_int(NULL, "netcard", NE2000); + p = (char *)config_get_string(NULL, "netcard", ""); + if (p) + network_card_current = network_card_get_from_internal_name(p); + else + network_card_current = 0; p = (char *)config_get_string(NULL, "model", ""); if (p) @@ -767,8 +771,12 @@ void loadconfig(char *fn) else gfxcard = 0; video_speed = config_get_int(NULL, "video_speed", 3); - sound_card_current = config_get_int(NULL, "sndcard", SB2); - + p = (char *)config_get_string(NULL, "sndcard", ""); + if (p) + sound_card_current = sound_card_get_from_internal_name(p); + else + sound_card_current = 0; + // d86f_unregister(0); // d86f_unregister(1); @@ -801,6 +809,7 @@ void loadconfig(char *fn) cdrom_drives[0].enabled = config_get_int(NULL, "cdrom_1_enabled", 0); cdrom_drives[0].sound_on = config_get_int(NULL, "cdrom_1_sound_on", 1); cdrom_drives[0].bus_type = config_get_int(NULL, "cdrom_1_bus_type", 0); + cdrom_drives[0].atapi_dma = config_get_int(NULL, "cdrom_1_atapi_dma", 1); cdrom_drives[0].ide_channel = config_get_int(NULL, "cdrom_1_ide_channel", 2); cdrom_drives[0].scsi_device_id = config_get_int(NULL, "cdrom_1_scsi_device_id", 2); cdrom_drives[0].scsi_device_lun = config_get_int(NULL, "cdrom_1_scsi_device_lun", 0); @@ -814,6 +823,7 @@ void loadconfig(char *fn) cdrom_drives[1].enabled = config_get_int(NULL, "cdrom_2_enabled", 0); cdrom_drives[1].sound_on = config_get_int(NULL, "cdrom_2_sound_on", 1); cdrom_drives[1].bus_type = config_get_int(NULL, "cdrom_2_bus_type", 0); + cdrom_drives[1].atapi_dma = config_get_int(NULL, "cdrom_2_atapi_dma", 1); cdrom_drives[1].ide_channel = config_get_int(NULL, "cdrom_2_ide_channel", 3); cdrom_drives[1].scsi_device_id = config_get_int(NULL, "cdrom_2_scsi_device_id", 3); cdrom_drives[1].scsi_device_lun = config_get_int(NULL, "cdrom_2_scsi_device_lun", 0); @@ -827,6 +837,7 @@ void loadconfig(char *fn) cdrom_drives[2].enabled = config_get_int(NULL, "cdrom_3_enabled", 0); cdrom_drives[2].sound_on = config_get_int(NULL, "cdrom_3_sound_on", 1); cdrom_drives[2].bus_type = config_get_int(NULL, "cdrom_3_bus_type", 0); + cdrom_drives[2].atapi_dma = config_get_int(NULL, "cdrom_3_atapi_dma", 1); cdrom_drives[2].ide_channel = config_get_int(NULL, "cdrom_3_ide_channel", 4); cdrom_drives[2].scsi_device_id = config_get_int(NULL, "cdrom_3_scsi_device_id", 4); cdrom_drives[2].scsi_device_lun = config_get_int(NULL, "cdrom_3_scsi_device_lun", 0); @@ -840,6 +851,7 @@ void loadconfig(char *fn) cdrom_drives[3].enabled = config_get_int(NULL, "cdrom_4_enabled", 0); cdrom_drives[3].sound_on = config_get_int(NULL, "cdrom_4_sound_on", 1); cdrom_drives[3].bus_type = config_get_int(NULL, "cdrom_4_bus_type", 0); + cdrom_drives[3].atapi_dma = config_get_int(NULL, "cdrom_4_atapi_dma", 1); cdrom_drives[3].ide_channel = config_get_int(NULL, "cdrom_4_ide_channel", 5); cdrom_drives[3].scsi_device_id = config_get_int(NULL, "cdrom_4_scsi_device_id", 5); cdrom_drives[3].scsi_device_lun = config_get_int(NULL, "cdrom_4_scsi_device_lun", 0); @@ -913,6 +925,7 @@ void loadconfig(char *fn) fdd_set_type(3, config_get_int(NULL, "drive_4_type", 1)); force_43 = config_get_int(NULL, "force_43", 0); + scale = config_get_int(NULL, "scale", 1); enable_overscan = config_get_int(NULL, "enable_overscan", 0); enable_flash = config_get_int(NULL, "enable_flash", 1); @@ -992,7 +1005,7 @@ void saveconfig() config_set_int(NULL, "buslogic", buslogic_enabled); config_set_int(NULL, "netinterface", ethif); - config_set_int(NULL, "netcard", network_card_current); + config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); config_set_string(NULL, "model", model_get_internal_name()); config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); @@ -1002,7 +1015,7 @@ void saveconfig() config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); config_set_int(NULL, "video_speed", video_speed); - config_set_int(NULL, "sndcard", sound_card_current); + config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); config_set_int(NULL, "cpu_speed", cpuspeed); config_set_int(NULL, "has_fpu", hasfpu); config_set_string(NULL, "disc_a", discfns[0]); @@ -1019,6 +1032,7 @@ void saveconfig() config_set_int(NULL, "cdrom_1_enabled", cdrom_drives[0].enabled); config_set_int(NULL, "cdrom_1_sound_on", cdrom_drives[0].sound_on); config_set_int(NULL, "cdrom_1_bus_type", cdrom_drives[0].bus_type); + config_set_int(NULL, "cdrom_1_atapi_dma", cdrom_drives[0].atapi_dma); config_set_int(NULL, "cdrom_1_ide_channel", cdrom_drives[0].ide_channel); config_set_int(NULL, "cdrom_1_scsi_device_id", cdrom_drives[0].scsi_device_id); config_set_int(NULL, "cdrom_1_scsi_device_lun", cdrom_drives[0].scsi_device_lun); @@ -1030,6 +1044,7 @@ void saveconfig() config_set_int(NULL, "cdrom_2_sound_on", cdrom_drives[1].sound_on); config_set_int(NULL, "cdrom_2_bus_type", cdrom_drives[1].bus_type); config_set_int(NULL, "cdrom_2_ide_channel", cdrom_drives[1].ide_channel); + config_set_int(NULL, "cdrom_2_atapi_dma", cdrom_drives[1].atapi_dma); config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id); config_set_int(NULL, "cdrom_2_scsi_device_lun", cdrom_drives[1].scsi_device_lun); @@ -1039,6 +1054,7 @@ void saveconfig() config_set_int(NULL, "cdrom_3_enabled", cdrom_drives[2].enabled); config_set_int(NULL, "cdrom_3_sound_on", cdrom_drives[2].sound_on); config_set_int(NULL, "cdrom_3_bus_type", cdrom_drives[2].bus_type); + config_set_int(NULL, "cdrom_3_atapi_dma", cdrom_drives[2].atapi_dma); config_set_int(NULL, "cdrom_3_ide_channel", cdrom_drives[2].ide_channel); config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id); config_set_int(NULL, "cdrom_3_scsi_device_lun", cdrom_drives[2].scsi_device_lun); @@ -1049,6 +1065,7 @@ void saveconfig() config_set_int(NULL, "cdrom_4_enabled", cdrom_drives[3].enabled); config_set_int(NULL, "cdrom_4_sound_on", cdrom_drives[3].sound_on); config_set_int(NULL, "cdrom_4_bus_type", cdrom_drives[3].bus_type); + config_set_int(NULL, "cdrom_4_atapi_dma", cdrom_drives[3].atapi_dma); config_set_int(NULL, "cdrom_4_ide_channel", cdrom_drives[3].ide_channel); config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id); config_set_int(NULL, "cdrom_4_scsi_device_lun", cdrom_drives[3].scsi_device_lun); @@ -1104,6 +1121,7 @@ void saveconfig() config_set_int(NULL, "drive_4_type", fdd_get_type(3)); config_set_int(NULL, "force_43", force_43); + config_set_int(NULL, "scale", scale); config_set_int(NULL, "enable_overscan", enable_overscan); config_set_int(NULL, "enable_flash", enable_flash); diff --git a/src/pc.rc b/src/pc.rc index 4b7297461..4de2f70a0 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -41,6 +41,7 @@ BEGIN MENUITEM "S&ound enabled", IDM_CDROM_1_SOUND_ON MENUITEM SEPARATOR MENUITEM "&SCSI", IDM_CDROM_1_SCSI + MENUITEM "Atapi &DMA enabled", IDM_CDROM_1_DMA MENUITEM SEPARATOR MENUITEM "E&mpty",IDM_CDROM_1_EMPTY MENUITEM "&Reload previous disc",IDM_CDROM_1_RELOAD @@ -95,6 +96,7 @@ BEGIN MENUITEM "S&ound enabled", IDM_CDROM_2_SOUND_ON MENUITEM SEPARATOR MENUITEM "&SCSI", IDM_CDROM_2_SCSI + MENUITEM "Atapi &DMA enabled", IDM_CDROM_2_DMA MENUITEM SEPARATOR MENUITEM "E&mpty",IDM_CDROM_2_EMPTY MENUITEM "&Reload previous disc",IDM_CDROM_2_RELOAD @@ -149,6 +151,7 @@ BEGIN MENUITEM "S&ound enabled", IDM_CDROM_3_SOUND_ON MENUITEM SEPARATOR MENUITEM "&SCSI", IDM_CDROM_3_SCSI + MENUITEM "Atapi &DMA enabled", IDM_CDROM_3_DMA MENUITEM SEPARATOR MENUITEM "E&mpty",IDM_CDROM_3_EMPTY MENUITEM "&Reload previous disc",IDM_CDROM_3_RELOAD @@ -203,6 +206,8 @@ BEGIN MENUITEM "S&ound enabled", IDM_CDROM_4_SOUND_ON MENUITEM SEPARATOR MENUITEM "&SCSI", IDM_CDROM_4_SCSI + MENUITEM "Atapi &DMA enabled", IDM_CDROM_4_DMA + MENUITEM SEPARATOR MENUITEM "E&mpty",IDM_CDROM_4_EMPTY MENUITEM "&Reload previous disc",IDM_CDROM_4_RELOAD MENUITEM SEPARATOR @@ -290,10 +295,18 @@ BEGIN MENUITEM "&Resizeable window",IDM_VID_RESIZE MENUITEM "R&emember size && position",IDM_VID_REMEMBER MENUITEM SEPARATOR + MENUITEM "D&isc activity flash", IDM_VID_FLASH + MENUITEM SEPARATOR MENUITEM "&DirectDraw", IDM_VID_DDRAW MENUITEM "Direct&3D 9", IDM_VID_D3D MENUITEM SEPARATOR - MENUITEM "D&isc activity flash", IDM_VID_FLASH + POPUP "&Window scale factor" + BEGIN + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + END MENUITEM SEPARATOR MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" diff --git a/src/resources.h b/src/resources.h index d216f0f7e..0722f2ebc 100644 --- a/src/resources.h +++ b/src/resources.h @@ -21,6 +21,10 @@ #define IDM_VID_REMEMBER 40051 #define IDM_VID_DDRAW 40060 #define IDM_VID_D3D 40061 +#define IDM_VID_SCALE_1X 40064 +#define IDM_VID_SCALE_2X 40065 +#define IDM_VID_SCALE_3X 40066 +#define IDM_VID_SCALE_4X 40067 #define IDM_VID_FULLSCREEN 40070 #define IDM_VID_FS_FULL 40071 #define IDM_VID_FS_43 40072 @@ -44,6 +48,7 @@ #define IDM_CDROM_1_ENABLED 40300 #define IDM_CDROM_1_SOUND_ON 40400 #define IDM_CDROM_1_SCSI 40500 +#define IDM_CDROM_1_DMA 40501 #define IDM_CDROM_1_C 40600 #define IDM_CDROM_1_D 40601 #define IDM_CDROM_1_E 40602 @@ -82,6 +87,7 @@ #define IDM_CDROM_2_ENABLED 41300 #define IDM_CDROM_2_SOUND_ON 41400 #define IDM_CDROM_2_SCSI 41500 +#define IDM_CDROM_2_DMA 41501 #define IDM_CDROM_2_C 41600 #define IDM_CDROM_2_D 41601 #define IDM_CDROM_2_E 41602 @@ -120,6 +126,7 @@ #define IDM_CDROM_3_ENABLED 42300 #define IDM_CDROM_3_SOUND_ON 42400 #define IDM_CDROM_3_SCSI 42500 +#define IDM_CDROM_3_DMA 42501 #define IDM_CDROM_3_C 42600 #define IDM_CDROM_3_D 42601 #define IDM_CDROM_3_E 42602 @@ -158,6 +165,7 @@ #define IDM_CDROM_4_ENABLED 43300 #define IDM_CDROM_4_SOUND_ON 43400 #define IDM_CDROM_4_SCSI 43500 +#define IDM_CDROM_4_DMA 43501 #define IDM_CDROM_4_C 43600 #define IDM_CDROM_4_D 43601 #define IDM_CDROM_4_E 43602 diff --git a/src/sound.c b/src/sound.c index e6b51d6d0..53b6ae732 100644 --- a/src/sound.c +++ b/src/sound.c @@ -27,25 +27,26 @@ static int sound_card_last = 0; typedef struct { - char name[32]; + char name[64]; + char internal_name[24]; device_t *device; } SOUND_CARD; static SOUND_CARD sound_cards[] = { - {"None", NULL}, - {"Adlib", &adlib_device}, - {"Sound Blaster 1.0", &sb_1_device}, - {"Sound Blaster 1.5", &sb_15_device}, - {"Sound Blaster 2.0", &sb_2_device}, - {"Sound Blaster Pro v1", &sb_pro_v1_device}, - {"Sound Blaster Pro v2", &sb_pro_v2_device}, - {"Sound Blaster 16", &sb_16_device}, - {"Sound Blaster AWE32", &sb_awe32_device}, - {"Adlib Gold", &adgold_device}, - {"Windows Sound System", &wss_device}, - {"Pro Audio Spectrum 16", &pas16_device}, - {"", NULL} + {"None", "none", NULL}, + {"Adlib", "adlib", &adlib_device}, + {"Sound Blaster 1.0", "sb", &sb_1_device}, + {"Sound Blaster 1.5", "sb1.5", &sb_15_device}, + {"Sound Blaster 2.0", "sb2.0", &sb_2_device}, + {"Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device}, + {"Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device}, + {"Sound Blaster 16", "sb16", &sb_16_device}, + {"Sound Blaster AWE32", "sbawe32", &sb_awe32_device}, + {"Adlib Gold", "adlibgold", &adgold_device}, + {"Windows Sound System", "wss", &wss_device}, + {"Pro Audio Spectrum 16", "pas16", &pas16_device}, + {"", "", NULL} }; int sound_card_available(int card) @@ -73,6 +74,25 @@ int sound_card_has_config(int card) return sound_cards[card].device->config ? 1 : 0; } +char *sound_card_get_internal_name(int card) +{ + return sound_cards[card].internal_name; +} + +int sound_card_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(sound_cards[c].internal_name)) + { + if (!strcmp(sound_cards[c].internal_name, s)) + return c; + c++; + } + + return 0; +} + void sound_card_init() { if (sound_cards[sound_card_current].device) diff --git a/src/sound.h b/src/sound.h index 8ef488ee1..1878c4729 100644 --- a/src/sound.h +++ b/src/sound.h @@ -8,6 +8,8 @@ int sound_card_available(int card); char *sound_card_getname(int card); struct device_t *sound_card_getdevice(int card); int sound_card_has_config(int card); +char *sound_card_get_internal_name(int card); +int sound_card_get_from_internal_name(char *s); void sound_card_init(); void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); diff --git a/src/win.c b/src/win.c index 4b5f87f32..ac2dd3a19 100644 --- a/src/win.c +++ b/src/win.c @@ -114,6 +114,11 @@ static int win_doresize = 0; static int leave_fullscreen_flag = 0; +static int unscaled_size_x = 0; +static int unscaled_size_y = 0; + +int scale = 0; + void updatewindowsize(int x, int y) { RECT r; @@ -130,7 +135,7 @@ void updatewindowsize(int x, int y) temp_overscan_x = temp_overscan_y = 0; } - winsizex=x; efwinsizey=y; + unscaled_size_x=x; efwinsizey=y; if (force_43) { @@ -138,30 +143,50 @@ void updatewindowsize(int x, int y) if (temp_overscan_y == 16) { /* CGA */ - winsizey = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; + unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; } else if (temp_overscan_y < 16) { /* MDA/Hercules */ - winsizey = efwinsizey; + unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); } else { if (enable_overscan) { /* EGA/(S)VGA with overscan */ - winsizey = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; + unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; } else { /* EGA/(S)VGA without overscan */ - winsizey = efwinsizey; + unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); } } } else { - winsizey = efwinsizey; + unscaled_size_y = efwinsizey; + } + + switch(scale) + { + case 0: + winsizex = unscaled_size_x >> 1; + winsizey = unscaled_size_y >> 1; + break; + case 1: + winsizex = unscaled_size_x; + winsizey = unscaled_size_y; + break; + case 2: + winsizex = (unscaled_size_x * 3) >> 1; + winsizey = (unscaled_size_y * 3) >> 1; + break; + case 3: + winsizex = unscaled_size_x << 1; + winsizey = unscaled_size_y << 1; + break; } win_doresize = 1; @@ -169,7 +194,7 @@ void updatewindowsize(int x, int y) void uws_natural() { - updatewindowsize(winsizex, efwinsizey); + updatewindowsize(unscaled_size_x, efwinsizey); } void releasemouse() @@ -681,6 +706,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (cdrom_drives[e].bus_type) CheckMenuItem(menu, IDM_CDROM_1_SCSI + (e * 1000), MF_CHECKED); + if (cdrom_drives[e].atapi_dma) + CheckMenuItem(menu, IDM_CDROM_1_DMA + (e * 1000), MF_CHECKED); + if (!find_in_array(valid_ide_channels, cdrom_drives[e].ide_channel, 8, IDM_CDROM_1_C + (e * 1000))) { fatal("CD-ROM %i: Invalid IDE channel\n", e); @@ -767,7 +795,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); // set_display_switch_mode(SWITCH_BACKGROUND); - + CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + // pclog("Preparing ROM sets...\n"); d=romset; for (c=0;c Date: Tue, 14 Mar 2017 00:44:31 +0100 Subject: [PATCH 132/392] 86Box v1.07 Recommended Build. --- src/Makefile.mingw | 5 +++-- src/Makefile.mingw64 | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index fdafe9849..65946b4fd 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 90874a262..0acc20863 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,8 +2,9 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD +RFLAGS = -DRELEASE_BUILD OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ From 8452458c1a0c4670d026b1db014595b24b4d06d5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 15 Mar 2017 01:37:09 +0100 Subject: [PATCH 133/392] Changed version to 1.10; Applied mainline PCem commit that adds MFM hard disk emulation; Commented out the Commodore PC III 60. --- src/86box.h | 2 +- src/Makefile.mingw | 9 +- src/Makefile.mingw64 | 9 +- src/device.h | 3 +- src/disc_img.c | 15 +- src/hdd.c | 93 +++++++ src/hdd.h | 8 + src/mem.c | 134 +-------- src/mfm_at.c | 645 +++++++++++++++++++++++++++++++++++++++++++ src/mfm_at.h | 1 + src/model.c | 181 ++++++------ src/model.h | 7 +- src/nvr.c | 12 +- src/pc.c | 12 +- src/pc.rc | 140 ++++++++-- src/resources.h | 7 +- src/win-config.c | 83 +++++- src/win-hdconf.c | 5 +- src/xtide.c | 95 ++++++- src/xtide.h | 6 +- 20 files changed, 1177 insertions(+), 290 deletions(-) create mode 100644 src/hdd.c create mode 100644 src/hdd.h create mode 100644 src/mfm_at.c create mode 100644 src/mfm_at.h diff --git a/src/86box.h b/src/86box.h index 80227a810..0b4ca1f9c 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.07" +#define emulator_version "1.10" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 65946b4fd..e780126a3 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -2,14 +2,13 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ + device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o hdd.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ - keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o mfm_at.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 0acc20863..2b285a556 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -2,14 +2,13 @@ VPATH = . dosbox lzf resid-fp slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DRELEASE_BUILD -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -DRELEASE_BUILD -RFLAGS = -DRELEASE_BUILD +CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign +DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o headland.o i430hx.o i430lx.o i430fx.o \ + device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o hdd.o headland.o i430hx.o i430lx.o i430fx.o \ i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ - keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o model.o mouse.o mouse_ps2.o \ + keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o mfm_at.o model.o mouse.o mouse_ps2.o \ mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ diff --git a/src/device.h b/src/device.h index 970b4067f..6ac7628d7 100644 --- a/src/device.h +++ b/src/device.h @@ -46,7 +46,8 @@ char *device_get_config_string(char *name); enum { - DEVICE_NOT_WORKING = 1 /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_AT = 2 /*Device requires an AT-compatible system*/ }; int model_get_config_int(char *s); diff --git a/src/disc_img.c b/src/disc_img.c index 5bbe87526..94bf48014 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -232,6 +232,9 @@ char ext[4]; uint8_t first_byte, second_byte, third_byte, fourth_byte; +/* This is hard-coded to 0 - if you really need to read those NT 3.1 Beta floppy images, change this to 1 and recompile the emulator. */ +uint8_t fdf_suppress_final_byte = 0; + void img_load(int drive, char *fn) { int size; @@ -388,13 +391,13 @@ void img_load(int drive, char *fn) size += (run & 0x7f); if (!track_bytes) { - size--; + size -= fdf_suppress_final_byte; } } else { /* Literal block. */ - size += (track_bytes - 1); + size += (track_bytes - fdf_suppress_final_byte); literal = (uint8_t *) malloc(track_bytes); fread(literal, 1, track_bytes, img[drive].f); free(literal); @@ -451,7 +454,7 @@ void img_load(int drive, char *fn) track_bytes--; if (!track_bytes) { - real_run--; + real_run -= fdf_suppress_final_byte; } rep_byte = fgetc(img[drive].f); if (real_run) @@ -467,7 +470,7 @@ void img_load(int drive, char *fn) fread(literal, 1, real_run, img[drive].f); if (!track_bytes) { - real_run--; + real_run -= fdf_suppress_final_byte; } if (run & 0x7f) { @@ -482,9 +485,9 @@ void img_load(int drive, char *fn) /* Literal block. */ literal = (uint8_t *) malloc(track_bytes); fread(literal, 1, track_bytes, img[drive].f); - memcpy(bpos, literal, track_bytes - 1); + memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte); free(literal); - bpos += (track_bytes - 1); + bpos += (track_bytes - fdf_suppress_final_byte); track_bytes = 0; } diff --git a/src/hdd.c b/src/hdd.c new file mode 100644 index 000000000..219c381f6 --- /dev/null +++ b/src/hdd.c @@ -0,0 +1,93 @@ +#include "ibm.h" +#include "device.h" +#include "hdd.h" + +#include "mfm_at.h" +#include "xtide.h" + +char hdd_controller_name[16]; + +static device_t null_hdd_device; + +static int hdd_controller_current; + +static struct +{ + char name[50]; + char internal_name[16]; + device_t *device; + int is_mfm; +} hdd_controllers[] = +{ + {"None", "none", &null_hdd_device, 0}, + {"AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1}, + {"XTIDE", "xtide", &xtide_device, 0}, + {"XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, + {"", "", NULL, 0} +}; + +char *hdd_controller_get_name(int hdd) +{ + return hdd_controllers[hdd].name; +} + +char *hdd_controller_get_internal_name(int hdd) +{ + return hdd_controllers[hdd].internal_name; +} + +int hdd_controller_get_flags(int hdd) +{ + return hdd_controllers[hdd].device->flags; +} + +int hdd_controller_available(int hdd) +{ + return device_available(hdd_controllers[hdd].device); +} + +int hdd_controller_current_is_mfm() +{ + return hdd_controllers[hdd_controller_current].is_mfm; +} + +void hdd_controller_init(char *internal_name) +{ + int c = 0; + + while (hdd_controllers[c].device) + { + if (!strcmp(internal_name, hdd_controllers[c].internal_name)) + { + hdd_controller_current = c; + if (strcmp(internal_name, "none")) + device_add(hdd_controllers[c].device); + return; + } + c++; + } + fatal("Could not find hdd_controller %s\n", internal_name); +} + + +static void *null_hdd_init() +{ + return NULL; +} + +static void null_hdd_close(void *p) +{ +} + +static device_t null_hdd_device = +{ + "Null HDD controller", + 0, + null_hdd_init, + null_hdd_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/hdd.h b/src/hdd.h new file mode 100644 index 000000000..605118623 --- /dev/null +++ b/src/hdd.h @@ -0,0 +1,8 @@ +char *hdd_controller_get_name(int hdd); +char *hdd_controller_get_internal_name(int hdd); +int hdd_controller_get_flags(int hdd); +int hdd_controller_available(int hdd); +int hdd_controller_current_is_mfm(); +void hdd_controller_init(char *internal_name); + +extern char hdd_controller_name[16]; diff --git a/src/mem.c b/src/mem.c index 0619e717a..f523d5d93 100644 --- a/src/mem.c +++ b/src/mem.c @@ -48,12 +48,12 @@ static mem_mapping_t romext_mapping; int shadowbios,shadowbios_write; -int enable_xtide = 0; - static unsigned char isram[0x10000]; static uint8_t ff_array[0x1000]; +int enable_xtide = 0; + int mem_size; uint32_t biosmask; int readlnum=0,writelnum=0; @@ -64,34 +64,6 @@ uint8_t romext[32768]; uint32_t ram_mapped_addr[64]; -static void mem_load_xtide_bios() -{ - FILE *f; - f=romfopen("roms/ide_xt.bin","rb"); - -// is486=0; - if (f) - { - fread(romext,16384,1,f); - mem_mapping_enable(&romext_mapping); - fclose(f); - } -} - -static void mem_load_atide_bios() -{ - FILE *f; - f=romfopen("roms/ide_at.bin","rb"); - -// is486=0; - if (f) - { - fread(romext,16384,1,f); - mem_mapping_enable(&romext_mapping); - fclose(f); - } -} - static void mem_load_atide115_bios() { FILE *f; @@ -136,10 +108,6 @@ int loadbios() } fclose(ff); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } loadfont("roms/pc1512/40078.ic127", 2); return 1; case ROM_PC1640: @@ -156,10 +124,6 @@ int loadbios() f=romfopen("roms/pc1640/40100","rb"); if (!f) break; fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_PC200: f=romfopen("roms/pc200/pc20v2.1","rb"); @@ -172,10 +136,6 @@ int loadbios() } fclose(ff); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } loadfont("roms/pc200/40109.bin", 1); return 1; case ROM_TANDY: @@ -183,10 +143,6 @@ int loadbios() if (!f) break; fread(rom,65536,1,f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_TANDY1000HX: f = romfopen("roms/tandy1000hx/v020000.u12", "rb"); @@ -194,10 +150,6 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_TANDY1000SL2: f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); @@ -212,10 +164,6 @@ int loadbios() } fclose(ff); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; /* case ROM_IBMPCJR: f=fopen("pcjr/bios.rom","rb"); @@ -236,20 +184,12 @@ int loadbios() fread(rom + 0x8000, 0x8000, 1, ff); fclose(ff); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; } else { fread(rom,65536,1,f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; } break; @@ -266,20 +206,12 @@ int loadbios() if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_DTKXT: f=romfopen("roms/dtk/DTK_ERSO_2.42_2764.bin","rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_OLIM24: f = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); @@ -292,10 +224,6 @@ int loadbios() } fclose(ff); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_PC2086: @@ -314,10 +242,6 @@ int loadbios() f = romfopen("roms/pc2086/40186.ic171", "rb"); if (!f) break; fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } biosmask = 0x3fff; return 1; @@ -329,10 +253,6 @@ int loadbios() f = romfopen("roms/pc3086/c000.bin", "rb"); if (!f) break; fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } biosmask = 0x3fff; return 1; @@ -353,10 +273,6 @@ int loadbios() } fclose(ff); fclose(f); - if (enable_xtide) - { - mem_load_atide_bios(); - } return 1; case ROM_CMDPC30: f = romfopen("roms/cmdpc30/commodore pc 30 iii even.bin", "rb"); @@ -371,6 +287,7 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; +#if 0 case ROM_CMDPC60: f = romfopen("roms/cmdpc60/cbm-pc60c-bios-lo-v1.36-390473-07.bin", "rb"); ff = romfopen("roms/cmdpc60/cbm-pc60c-bios-hi-v1.36-390474-07.bin", "rb"); @@ -384,6 +301,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; +#endif case ROM_DELL200: f=romfopen("roms/dells200/dell0.bin","rb"); ff=romfopen("roms/dells200/dell1.bin","rb"); @@ -459,10 +377,6 @@ int loadbios() fread(rom+0x8000,32768,1,f); fclose(f); // memset(romext,0x63,0x8000); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_IBMPC: @@ -487,10 +401,6 @@ int loadbios() if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_MEGAPC: @@ -609,11 +519,11 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); //#endif - biosmask = 0x1ffff; if (enable_xtide) { - mem_load_atide115_bios(); + mem_load_atide115_bios(); } + biosmask = 0x1ffff; return 1; case ROM_IBMPS1_2121: @@ -623,11 +533,11 @@ int loadbios() fseek(f, 0x20000, SEEK_SET); fread(rom, 0x20000, 1, f); fclose(f); - biosmask = 0x1ffff; if (enable_xtide) { - mem_load_atide115_bios(); + mem_load_atide115_bios(); } + biosmask = 0x1ffff; return 1; case ROM_DESKPRO_386: @@ -642,10 +552,6 @@ int loadbios() fclose(ff); fclose(f); biosmask = 0x7fff; - if (enable_xtide) - { - mem_load_atide_bios(); - } return 1; case ROM_AMIXT: @@ -653,10 +559,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_LTXT: @@ -664,10 +566,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_LXT3: @@ -675,10 +573,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_SPC4200P: /*Samsung SPC-4200P*/ @@ -722,10 +616,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_JUKOPC: @@ -733,10 +623,6 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - if (enable_xtide) - { - mem_load_xtide_bios(); - } return 1; case ROM_IBMPS2_M30_286: @@ -744,11 +630,11 @@ int loadbios() if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); - biosmask = 0x1ffff; if (enable_xtide) { - mem_load_atide115_bios(); + mem_load_atide115_bios(); } + biosmask = 0x1ffff; return 1; case ROM_DTK486: diff --git a/src/mfm_at.c b/src/mfm_at.c new file mode 100644 index 000000000..a6623c92c --- /dev/null +++ b/src/mfm_at.c @@ -0,0 +1,645 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include + +#include + +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "pic.h" +#include "timer.h" + +#include "mfm_at.h" + + +#define IDE_TIME (TIMER_USEC*10)//(5 * 100 * (1 << TIMER_SHIFT)) + +#define STAT_ERR 0x01 +#define STAT_INDEX 0x02 +#define STAT_CORRECTED_DATA 0x04 +#define STAT_DRQ 0x08 /* Data request */ +#define STAT_DSC 0x10 +#define STAT_SEEK_COMPLETE 0x20 +#define STAT_READY 0x40 +#define STAT_BUSY 0x80 + +#define ERR_DAM_NOT_FOUND 0x01 /*Data Address Mark not found*/ +#define ERR_TR000 0x02 /*Track 0 not found*/ +#define ERR_ABRT 0x04 /*Command aborted*/ +#define ERR_ID_NOT_FOUND 0x10 /*ID not found*/ +#define ERR_DATA_CRC 0x40 /*Data CRC error*/ +#define ERR_BAD_BLOCK 0x80 /*Bad Block detected*/ + +#define CMD_RESTORE 0x10 +#define CMD_READ 0x20 +#define CMD_WRITE 0x30 +#define CMD_VERIFY 0x40 +#define CMD_FORMAT 0x50 +#define CMD_SEEK 0x70 +#define CMD_DIAGNOSE 0x90 +#define CMD_SET_PARAMETERS 0x91 + +extern char ide_fn[4][512]; + +typedef struct mfm_drive_t +{ + int spt, hpc; + int tracks; + int cfg_spt; + int cfg_hpc; + int current_cylinder; + FILE *hdfile; +} mfm_drive_t; + +typedef struct mfm_t +{ + uint8_t status; + uint8_t error; + int secount,sector,cylinder,head,cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; + + int drive_sel; + int reset; + uint16_t buffer[256]; + int irqstat; + + int callback; + + mfm_drive_t drives[2]; +} mfm_t; + +uint16_t mfm_readw(uint16_t port, void *p); +void mfm_writew(uint16_t port, uint16_t val, void *p); + +static inline void mfm_irq_raise(mfm_t *mfm) +{ +// pclog("IDE_IRQ_RAISE\n"); + if (!(mfm->fdisk&2)) + picint(1 << 14); + + mfm->irqstat=1; +} + +static inline void mfm_irq_lower(mfm_t *mfm) +{ + picintc(1 << 14); +} + +void mfm_irq_update(mfm_t *mfm) +{ + if (mfm->irqstat && !((pic2.pend|pic2.ins)&0x40) && !(mfm->fdisk & 2)) + picint(1 << 14); +} + +/* + * Return the sector offset for the current register values + */ +static int mfm_get_sector(mfm_t *mfm, off64_t *addr) +{ + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + int heads = drive->cfg_hpc; + int sectors = drive->cfg_spt; + + if (drive->current_cylinder != mfm->cylinder) + { + pclog("mfm_get_sector: wrong cylinder\n"); + return 1; + } + if (mfm->head > heads) + { + pclog("mfm_get_sector: past end of configured heads\n"); + return 1; + } + if (mfm->sector >= sectors+1) + { + pclog("mfm_get_sector: past end of configured sectors\n"); + return 1; + } + if (mfm->head > drive->hpc) + { + pclog("mfm_get_sector: past end of heads\n"); + return 1; + } + if (mfm->sector >= drive->spt+1) + { + pclog("mfm_get_sector: past end of sectors\n"); + return 1; + } + + *addr = ((((off64_t) mfm->cylinder * heads) + mfm->head) * + sectors) + (mfm->sector - 1); + + return 0; +} + +/** + * Move to the next sector using CHS addressing + */ +static void mfm_next_sector(mfm_t *mfm) +{ + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + + mfm->sector++; + if (mfm->sector == (drive->cfg_spt + 1)) + { + mfm->sector = 1; + mfm->head++; + if (mfm->head == drive->cfg_hpc) + { + mfm->head = 0; + mfm->cylinder++; + if (drive->current_cylinder < drive->tracks) + drive->current_cylinder++; + } + } +} + +static void loadhd(mfm_t *mfm, int d, const char *fn) +{ + mfm_drive_t *drive = &mfm->drives[d]; + + if (drive->hdfile == NULL) + { + /* Try to open existing hard disk image */ + drive->hdfile = fopen64(fn, "rb+"); + if (drive->hdfile == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + drive->hdfile = fopen64(fn, "wb+"); + if (drive->hdfile == NULL) + { + pclog("Cannot create file '%s': %s", + fn, strerror(errno)); + return; + } + } + else + { + /* Failed for another reason */ + pclog("Cannot open file '%s': %s", + fn, strerror(errno)); + return; + } + } + } + + drive->spt = hdc[d].spt; + drive->hpc = hdc[d].hpc; + drive->tracks = hdc[d].tracks; +} + + + +void mfm_write(uint16_t port, uint8_t val, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + +// pclog("mfm_write: addr=%04x val=%02x\n", port, val); + switch (port) + { + case 0x1F0: /* Data */ + mfm_writew(port, val | (val << 8), p); + return; + + case 0x1F1: /* Write precompenstation */ + mfm->cylprecomp = val; + return; + + case 0x1F2: /* Sector count */ + mfm->secount = val; + return; + + case 0x1F3: /* Sector */ + mfm->sector = val; + return; + + case 0x1F4: /* Cylinder low */ + mfm->cylinder = (mfm->cylinder & 0xFF00) | val; + return; + + case 0x1F5: /* Cylinder high */ + mfm->cylinder = (mfm->cylinder & 0xFF) | (val << 8); + return; + + case 0x1F6: /* Drive/Head */ + mfm->head = val & 0xF; + mfm->drive_sel = (val & 0x10) ? 1 : 0; + if (mfm->drives[mfm->drive_sel].hdfile == NULL) + mfm->status = 0; + else + mfm->status = STAT_READY | STAT_DSC; + return; + + case 0x1F7: /* Command register */ + if (mfm->drives[mfm->drive_sel].hdfile == NULL) + fatal("Command on non-present drive\n"); + + mfm_irq_lower(mfm); + mfm->command = val; + mfm->error = 0; + + switch (val & 0xf0) + { + case CMD_RESTORE: +// pclog("Restore\n"); + mfm->command &= ~0x0f; /*Mask off step rate*/ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_SEEK: +// pclog("Seek to cylinder %i\n", mfm->cylinder); + mfm->command &= ~0x0f; /*Mask off step rate*/ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + default: + switch (val) + { + case CMD_READ: case CMD_READ+1: + case CMD_READ+2: case CMD_READ+3: +// pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head,ins); + mfm->command &= ~3; + if (val & 2) + fatal("Read with ECC\n"); + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_WRITE: case CMD_WRITE+1: + case CMD_WRITE+2: case CMD_WRITE+3: +// pclog("Write %i sectors to sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); + mfm->command &= ~3; + if (val & 2) + fatal("Write with ECC\n"); + mfm->status = STAT_DRQ | STAT_DSC;// | STAT_BUSY; + mfm->pos=0; + break; + + case CMD_VERIFY: case CMD_VERIFY+1: +// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); + mfm->command &= ~1; + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200 * IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_FORMAT: +// pclog("Format track %i head %i\n", mfm->cylinder, mfm->head); + mfm->status = STAT_DRQ | STAT_BUSY; + mfm->pos=0; + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 30*IDE_TIME; + timer_update_outstanding(); + break; + + case CMD_DIAGNOSE: /* Execute Drive Diagnostics */ + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + + default: + pclog("Bad MFM command %02X\n", val); + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 200*IDE_TIME; + timer_update_outstanding(); + break; + } + } + break; + + case 0x3F6: /* Device control */ + if ((mfm->fdisk & 4) && !(val & 4)) + { + timer_process(); + mfm->callback = 500*IDE_TIME; + timer_update_outstanding(); + mfm->reset = 1; + mfm->status = STAT_BUSY; +// pclog("MFM Reset\n"); + } + if (val & 4) + { + /*Drive held in reset*/ + timer_process(); + mfm->callback = 0; + timer_update_outstanding(); + mfm->status = STAT_BUSY; + } + mfm->fdisk = val; + mfm_irq_update(mfm); + return; + } +// fatal("Bad IDE write %04X %02X\n", addr, val); +} + +void mfm_writew(uint16_t port, uint16_t val, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + +// pclog("Write IDEw %04X\n",val); + mfm->buffer[mfm->pos >> 1] = val; + mfm->pos += 2; + + if (mfm->pos >= 512) + { + mfm->pos = 0; + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 6*IDE_TIME; + timer_update_outstanding(); + } +} + +uint8_t mfm_read(uint16_t port, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + uint8_t temp; + + switch (port) + { + case 0x1F0: /* Data */ + temp = mfm_readw(port, mfm) & 0xff; + break; + + case 0x1F1: /* Error */ + temp = mfm->error; + break; + + case 0x1F2: /* Sector count */ + temp = (uint8_t)mfm->secount; + break; + + case 0x1F3: /* Sector */ + temp = (uint8_t)mfm->sector; + break; + + case 0x1F4: /* Cylinder low */ + temp = (uint8_t)(mfm->cylinder&0xFF); + break; + + case 0x1F5: /* Cylinder high */ + temp = (uint8_t)(mfm->cylinder>>8); + break; + + case 0x1F6: /* Drive/Head */ + temp = (uint8_t)(mfm->head | (mfm->drive_sel ? 0x10 : 0) | 0xa0); + break; + + case 0x1F7: /* Status */ + mfm_irq_lower(mfm); + temp = mfm->status; + break; + } + +// pclog("mfm_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); + return temp; +} + +uint16_t mfm_readw(uint16_t port, void *p) +{ + mfm_t *mfm = (mfm_t *)p; + uint16_t temp; + + temp = mfm->buffer[mfm->pos >> 1]; + mfm->pos += 2; + + if (mfm->pos >= 512) + { +// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); + mfm->pos=0; + mfm->status = STAT_READY | STAT_DSC; + if (mfm->command == CMD_READ) + { + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) + { + mfm_next_sector(mfm); + mfm->status = STAT_BUSY; + timer_process(); + mfm->callback = 6*IDE_TIME; + timer_update_outstanding(); + } + } + } + +// pclog("mem_readw: temp=%04x %i\n", temp, mfm->pos); + return temp; +} + +static void do_seek(mfm_t *mfm) +{ + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + + if (mfm->cylinder < drive->tracks) + drive->current_cylinder = mfm->cylinder; + else + drive->current_cylinder = drive->tracks-1; +} + +void mfm_callback(void *p) +{ + mfm_t *mfm = (mfm_t *)p; + mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; + off64_t addr; + int c; + +// pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); + mfm->callback = 0; + if (mfm->reset) + { + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; + mfm->secount = 1; + mfm->sector = 1; + mfm->head = 0; + mfm->cylinder = 0; + mfm->reset = 0; +// pclog("Reset callback\n"); + return; + } + switch (mfm->command) + { + case CMD_RESTORE: + drive->current_cylinder = 0; + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + case CMD_SEEK: + do_seek(mfm); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + case CMD_READ: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) + { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + +// pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + fread(mfm->buffer, 512, 1, drive->hdfile); + mfm->pos = 0; + mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; +// pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); +// if (addr) output=3; + mfm_irq_raise(mfm); + readflash = 1; + break; + + case CMD_WRITE: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) + { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + fwrite(mfm->buffer, 512, 1, drive->hdfile); + mfm_irq_raise(mfm); + mfm->secount = (mfm->secount - 1) & 0xff; + if (mfm->secount) + { + mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; + mfm->pos = 0; + mfm_next_sector(mfm); + } + else + mfm->status = STAT_READY | STAT_DSC; + readflash = 1; + break; + + case CMD_VERIFY: + do_seek(mfm); + mfm->pos = 0; + mfm->status = STAT_READY | STAT_DSC; +// pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); + mfm_irq_raise(mfm); + readflash=1; + break; + + case CMD_FORMAT: + do_seek(mfm); + if (mfm_get_sector(mfm, &addr)) + { + mfm->error = ERR_ID_NOT_FOUND; + mfm->status = STAT_READY | STAT_DSC | STAT_ERR; + mfm_irq_raise(mfm); + break; + } + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + memset(mfm->buffer, 0, 512); + for (c = 0; c < mfm->secount; c++) + { + fwrite(mfm->buffer, 512, 1, drive->hdfile); + } + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + readflash = 1; + break; + + case CMD_DIAGNOSE: + mfm->error = 1; /*No error detected*/ + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + case CMD_SET_PARAMETERS: /* Initialize Drive Parameters */ + drive->cfg_spt = mfm->secount; + drive->cfg_hpc = mfm->head+1; + pclog("Parameters: spt=%i hpc=%i\n", drive->cfg_spt,drive->cfg_hpc); + mfm->status = STAT_READY | STAT_DSC; + mfm_irq_raise(mfm); + break; + + default: + pclog("Callback on unknown command %02x\n", mfm->command); + mfm->status = STAT_READY | STAT_ERR | STAT_DSC; + mfm->error = ERR_ABRT; + mfm_irq_raise(mfm); + break; + } +} + +void *mfm_init() +{ + mfm_t *mfm = malloc(sizeof(mfm_t)); + memset(mfm, 0, sizeof(mfm_t)); + + loadhd(mfm, 0, ide_fn[0]); + loadhd(mfm, 1, ide_fn[1]); + + mfm->status = STAT_READY | STAT_DSC; + mfm->error = 1; /*No errors*/ + + io_sethandler(0x01f0, 0x0001, mfm_read, mfm_readw, NULL, mfm_write, mfm_writew, NULL, mfm); + io_sethandler(0x01f1, 0x0007, mfm_read, NULL, NULL, mfm_write, NULL, NULL, mfm); + io_sethandler(0x03f6, 0x0001, NULL, NULL, NULL, mfm_write, NULL, NULL, mfm); + + timer_add(mfm_callback, &mfm->callback, &mfm->callback, mfm); + + return mfm; +} + +void mfm_close(void *p) +{ + mfm_t *mfm = (mfm_t *)p; + int d; + + for (d = 0; d < 2; d++) + { + mfm_drive_t *drive = &mfm->drives[d]; + + if (drive->hdfile != NULL) + fclose(drive->hdfile); + } + + free(mfm); +} + +device_t mfm_at_device = +{ + "IBM PC AT Fixed Disk Adapter", + DEVICE_AT, + mfm_init, + mfm_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/mfm_at.h b/src/mfm_at.h new file mode 100644 index 000000000..67907af23 --- /dev/null +++ b/src/mfm_at.h @@ -0,0 +1 @@ +extern device_t mfm_at_device; diff --git a/src/model.c b/src/model.c index 133c32ca5..495f75d8b 100644 --- a/src/model.c +++ b/src/model.c @@ -72,7 +72,6 @@ #include "vid_tandy.h" #include "w83877f.h" #include "wd76c10.h" -#include "xtide.h" void xt_init(); void pcjr_init(); @@ -82,6 +81,7 @@ void ams_init(); void europc_init(); void olim24_init(); void at_init(); +void at_ide_init(); void deskpro386_init(); void ps1_m2011_init(); void ps1_m2121_init(); @@ -125,67 +125,66 @@ PCI_RESET pci_reset_handler; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_headland_init, NULL}, - {"Commodore PC 60 III", ROM_CMDPC60, "cmdpc60", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, + {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, + {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, + {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, + {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, at_wd76c10_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_ali1429_init, NULL}, - {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_dtk486_init, NULL}, - {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_sis496_init, NULL}, - {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT, 1, 256, 1, at_r418_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_batman_init, NULL}, - {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 128, 1, at_586mc1_init, NULL}, - {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 128, 1, at_mb500n_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_p54tp4xe_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_acerm3a_init, NULL}, - {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 512, 1, at_p55t2p4_init, NULL}, - {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_i430vx_init, NULL}, - {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 256, 1, at_p55tvp4_init, NULL}, - {"Award 440FX PCI", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 1024, 1, at_i440fx_init, NULL}, + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, + {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, + {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_dtk486_init, NULL}, + {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, + {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_r418_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, + {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 128, 1, at_586mc1_init, NULL}, + {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_plato_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, + {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_mb500n_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_endeavor_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_p54tp4xe_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_acerm3a_init, NULL}, + {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_acerv35n_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_p55t2p4_init, NULL}, + {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, + {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_p55va_init, NULL}, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_p55tvp4_init, NULL}, + {"Award 440FX PCI", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 1024, 1, at_i440fx_init, NULL}, {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; @@ -260,7 +259,6 @@ void xt_init() mem_add_bios(); pit_set_out_func(1, pit_refresh_timer_xt); keyboard_xt_init(); - xtide_init(); nmi_init(); if (joystick_type != 7) device_add(&gameport_device); } @@ -288,7 +286,6 @@ void tandy1k_init() device_add(&sn76489_device); else device_add(&ncr8496_device); - xtide_init(); nmi_init(); if (romset != ROM_TANDY) device_add(&tandy_eeprom_device); @@ -301,7 +298,6 @@ void tandy1ksl2_init() mem_add_bios(); keyboard_tandy_init(); device_add(&pssj_device); - xtide_init(); nmi_init(); device_add(&tandy_rom_device); device_add(&tandy_eeprom_device); @@ -316,7 +312,6 @@ void ams_init() amstrad_init(); keyboard_amstrad_init(); nvr_init(); - xtide_init(); nmi_init(); fdc_set_dskchg_activelow(); if (joystick_type != 7) device_add(&gameport_device); @@ -328,7 +323,6 @@ void europc_init() mem_add_bios(); jim_init(); keyboard_xt_init(); - xtide_init(); nmi_init(); if (joystick_type != 7) device_add(&gameport_device); } @@ -340,7 +334,6 @@ void olim24_init() keyboard_olim24_init(); nvr_init(); olivetti_m24_init(); - xtide_init(); nmi_init(); if (joystick_type != 7) device_add(&gameport_device); } @@ -360,6 +353,12 @@ void at_init() if (joystick_type != 7) device_add(&gameport_device); } +void at_ide_init() +{ + at_init(); + ide_init(); +} + void deskpro386_init() { at_init(); @@ -414,43 +413,43 @@ void ps2_m30_286_init() void at_neat_init() { - at_init(); + at_ide_init(); neat_init(); } void at_scat_init() { - at_init(); + at_ide_init(); scat_init(); } /* void at_acer386sx_init() { - at_init(); + at_ide_init(); acer386sx_init(); } void at_82335_init() { - at_init(); + at_ide_init(); i82335_init(); } */ void at_wd76c10_init() { - at_init(); + at_ide_init(); wd76c10_init(); } void at_headland_init() { - at_init(); + at_ide_init(); headland_init(); } void at_opti495_init() { - at_init(); + at_ide_init(); opti495_init(); } @@ -472,7 +471,7 @@ void secondary_ide_check() void at_ali1429_init() { - at_init(); + at_ide_init(); ali1429_init(); secondary_ide_check(); @@ -480,14 +479,14 @@ void at_ali1429_init() /* void at_um8881f_init() { - at_init(); + at_ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); um8881f_init(); } */ void at_dtk486_init() { - at_init(); + at_ide_init(); memregs_init(); sis85c471_init(); secondary_ide_check(); @@ -495,7 +494,7 @@ void at_dtk486_init() void at_sis496_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); device_add(&sis496_device); @@ -509,7 +508,7 @@ void at_r418_init() void at_premiere_common_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); sio_init(1); @@ -526,7 +525,7 @@ void at_batman_init() void at_586mc1_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); i430lx_init(); @@ -543,7 +542,7 @@ void at_plato_init() void at_advanced_common_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); i430fx_init(); @@ -567,7 +566,7 @@ void at_marl_init() void at_mb500n_init() { - at_init(); + at_ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); i430fx_init(); piix_init(7); @@ -578,7 +577,7 @@ void at_mb500n_init() #if 0 void at_powermate_v_init() { - at_init(); + at_ide_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430fx_init(); @@ -591,7 +590,7 @@ void at_powermate_v_init() void at_p54tp4xe_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); i430fx_init(); @@ -602,7 +601,7 @@ void at_p54tp4xe_init() void at_acerm3a_init() { - at_init(); + at_ide_init(); memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); @@ -615,7 +614,7 @@ void at_acerm3a_init() void at_acerv35n_init() { - at_init(); + at_ide_init(); memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); @@ -628,7 +627,7 @@ void at_acerv35n_init() void at_p55t2p4_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430hx_init(); @@ -639,7 +638,7 @@ void at_p55t2p4_init() void at_i430vx_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430vx_init(); @@ -650,7 +649,7 @@ void at_i430vx_init() void at_p55tvp4_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430vx_init(); @@ -661,7 +660,7 @@ void at_p55tvp4_init() void at_p55va_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i430vx_init(); @@ -672,7 +671,7 @@ void at_p55va_init() void at_i440fx_init() { - at_init(); + at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); i440fx_init(); diff --git a/src/model.h b/src/model.h index eceda3a39..272770732 100644 --- a/src/model.h +++ b/src/model.h @@ -5,9 +5,10 @@ #define MODEL_PS2 2 #define MODEL_AMSTRAD 4 #define MODEL_OLIM24 8 -#define MODEL_NEC 16 -#define MODEL_FUJITSU 32 -#define MODEL_RM 64 +#define MODEL_HAS_IDE 16 +#define MODEL_NEC 32 +#define MODEL_FUJITSU 64 +#define MODEL_RM 128 typedef struct { diff --git a/src/nvr.c b/src/nvr.c index f94dc029e..3a1520c61 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -206,10 +206,10 @@ void loadnvr() case ROM_PC2086: f = romfopen(nvr_concat("pc2086.nvr"), "rb"); break; case ROM_PC3086: f = romfopen(nvr_concat("pc3086.nvr"), "rb"); break; case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "rb"); break; - case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); break; - case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); break; - case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); break; - case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); break; + case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; + case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); nvrmask = 127; break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; @@ -254,7 +254,9 @@ void loadnvr() case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "rb"); nvrmask = 127; break; case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "rb"); nvrmask = 127; break; case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "rb"); nvrmask = 127; break; +#if 0 case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "rb"); nvrmask = 127; break; +#endif default: return; } if (!f) @@ -340,7 +342,9 @@ void savenvr() case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "wb"); break; case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "wb"); break; case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "wb"); break; +#if 0 case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "wb"); break; +#endif default: return; } fwrite(nvrram,128,1,f); diff --git a/src/pc.c b/src/pc.c index 37f12430a..1b46fcba9 100644 --- a/src/pc.c +++ b/src/pc.c @@ -56,6 +56,7 @@ #include "vid_voodoo.h" #include "video.h" #include "amstrad.h" +#include "hdd.h" #include "nethandler.h" #define NE2000 1 #define RTL8029AS 2 @@ -522,7 +523,8 @@ void resetpchard() if (SSI2001) device_add(&ssi2001_device); if (voodoo_enabled) - device_add(&voodoo_device); + device_add(&voodoo_device); + hdd_controller_init(hdd_controller_name); pc_reset(); loadnvr(); @@ -800,6 +802,12 @@ void loadconfig(char *fn) else strcpy(discfns[3], ""); ui_writeprot[3] = config_get_int(NULL, "disc_4_writeprot", 0); + p = (char *)config_get_string(NULL, "hdd_controller", ""); + if (p) + strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); + else + strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); + mem_size = config_get_int(NULL, "mem_size", 4096); if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); @@ -1026,6 +1034,8 @@ void saveconfig() config_set_int(NULL, "disc_3_writeprot", ui_writeprot[2]); config_set_string(NULL, "disc_4", discfns[3]); config_set_int(NULL, "disc_4_writeprot", ui_writeprot[3]); + config_set_string(NULL, "hdd_controller", hdd_controller_name); + config_set_int(NULL, "mem_size", mem_size); config_set_int(NULL, "cdrom_1_host_drive", cdrom_drives[0].host_drive); diff --git a/src/pc.rc b/src/pc.rc index 4de2f70a0..bf041602e 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -383,13 +383,13 @@ BEGIN VK_F12, IDM_FILE_RESET_CAD, CONTROL, VIRTKEY END -ConfigureDlg DIALOGEX 0, 0, 252+40, 236+80 +ConfigureDlg DIALOGEX 0, 0, 252+40, 236+100 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Configure 86Box" FONT 9, "Segoe UI" BEGIN - DEFPUSHBUTTON "OK",IDOK,64,292,50,14, WS_TABSTOP - PUSHBUTTON "Cancel",IDCANCEL,128,292,50,14, WS_TABSTOP + DEFPUSHBUTTON "OK",IDOK,64,312,50,14, WS_TABSTOP + PUSHBUTTON "Cancel",IDCANCEL,128,312,50,14, WS_TABSTOP COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGUREMOD, 224, 16, 40, 14, WS_TABSTOP COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -405,27 +405,27 @@ BEGIN EDITTEXT IDC_MEMTEXT, 62, 136, 36, 14, ES_AUTOHSCROLL | ES_NUMBER CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 136, 12, 14 LTEXT "MB", IDC_TEXT_MB, 98, 136, 10, 10 - CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,192,102,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,208,102,10 + CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,212,102,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,228,102,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,192,102,10 - CONTROL "En. XTIDE",IDC_CHECKXTIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,192,40,10 - CONTROL "SCSI Controller",IDC_CHECKBUSLOGIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,208,102,10 - PUSHBUTTON "Configure", IDC_CONFIGUREBUSLOGIC, 224, 208, 40, 14, WS_TABSTOP + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,212,102,10 + CONTROL "En. XTIDE",IDC_CHECKXTIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,212,40,10 + CONTROL "SCSI Controller",IDC_CHECKBUSLOGIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,228,102,10 + PUSHBUTTON "Configure", IDC_CONFIGUREBUSLOGIC, 224, 228, 40, 14, WS_TABSTOP - CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,224,102,10 - CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,224,102,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 224, 40, 14, WS_TABSTOP + CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,244,102,10 + CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,244,102,10 + PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 244, 40, 14, WS_TABSTOP - LTEXT "Mouse :",IDC_STATIC,15,240,40,10 - COMBOBOX IDC_COMBOMOUSE,62,240,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Mouse :",IDC_STATIC,15,260,40,10 + COMBOBOX IDC_COMBOMOUSE,62,260,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Joystick :",IDC_STATIC,15,260,40,10 - COMBOBOX IDC_COMBOJOY,62,260,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,276,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 2...",IDC_JOY2,80,276,50,14, WS_TABSTOP - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,276,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 4...",IDC_JOY4,208,276,50,14, WS_TABSTOP + LTEXT "Joystick :",IDC_STATIC,15,280,40,10 + COMBOBOX IDC_COMBOJOY,62,280,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,296,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 2...",IDC_JOY2,80,296,50,14, WS_TABSTOP + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,296,50,14, WS_TABSTOP + PUSHBUTTON "Joystick 4...",IDC_JOY4,208,296,50,14, WS_TABSTOP LTEXT "Machine :",IDC_STATIC,15,16,40,10 LTEXT "Video :",IDC_STATIC,15,36,34,10 @@ -438,14 +438,16 @@ BEGIN COMBOBOX IDC_COMBONET,162,136,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure", IDC_CONFIGURENET, 224, 136, 40, 14, WS_TABSTOP LTEXT "Memory :",IDC_STATIC,15,136,40,10 - LTEXT "FDD 1 :",IDC_STATIC,15,156,40,10 - LTEXT "FDD 2 :",IDC_STATIC,125,156,40,10 - COMBOBOX IDC_COMBODR1,62,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBODR2,162,156,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "FDD 3 :",IDC_STATIC,15,176,40,10 - LTEXT "FDD 4 :",IDC_STATIC,125,176,40,10 - COMBOBOX IDC_COMBODR3,62,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBODR4,162,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "HDD :",IDC_STATIC,15,156,40,10 + COMBOBOX IDC_COMBOHDD, 62,156,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "FDD 1 :",IDC_STATIC,15,176,40,10 + LTEXT "FDD 2 :",IDC_STATIC,125,176,40,10 + COMBOBOX IDC_COMBODR1,62,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBODR2,162,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "FDD 3 :",IDC_STATIC,15,196,40,10 + LTEXT "FDD 4 :",IDC_STATIC,125,196,40,10 + COMBOBOX IDC_COMBODR3,62,196,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBODR4,162,196,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT @@ -609,6 +611,88 @@ BEGIN LTEXT "Type:",IDC_STATIC,94,39,17,8 END +HdConfDlgMfm DIALOGEX 0, 0, 210, 172 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Configure Hard Discs" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,31+12,152,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101+12,152,50,14 + + LTEXT "C:",IDC_STATIC,7,6,27,10 + EDITTEXT IDC_EDIT_C_FN, 7, 22, 136, 12, WS_DISABLED + PUSHBUTTON "...",IDC_CFILE,7 + 136, 22, 16, 14 + PUSHBUTTON "New",IDC_CNEW,7 + 136 + 16, 22, 24, 14 + PUSHBUTTON "Eject", IDC_EJECTC, 7 + 136 + 16 + 24, 22, 24, 14 + + EDITTEXT IDC_EDIT_C_SPT,36,38,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_C_HPC,94,38,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_C_CYL,152,38,28,12, WS_DISABLED + LTEXT "Sectors:",IDC_STATIC,7,38,27,10 + LTEXT "Heads:",IDC_STATIC,63,38,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,38,32,12 + LTEXT "", IDC_TEXT_C_SIZE, 7, 54, 136, 12 + + LTEXT "D:",IDC_STATIC,7,76,27,10 + EDITTEXT IDC_EDIT_D_FN, 7, 92, 136, 12, WS_DISABLED + PUSHBUTTON "...",IDC_DFILE,7 + 136, 92, 16, 14 + PUSHBUTTON "New",IDC_DNEW,7 + 136 + 16, 92, 24, 14 + PUSHBUTTON "Eject", IDC_EJECTD, 7 + 136 + 16 + 24, 92, 24, 14 + + EDITTEXT IDC_EDIT_D_SPT,36,108,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_D_HPC,94,108,16,12, WS_DISABLED + EDITTEXT IDC_EDIT_D_CYL,152,108,28,12, WS_DISABLED + LTEXT "Sectors:",IDC_STATIC,7,108,27,10 + LTEXT "Heads:",IDC_STATIC,63,108,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,108,32,12 + LTEXT "", IDC_TEXT_D_SIZE, 7, 124, 136, 12 +END + +HdNewDlgMfm DIALOGEX 0, 0, 186, 102 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "New Hard Disc" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,31,82,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101,82,50,14 + + EDITTEXT IDC_EDITC, 7, 6, 136, 12 + PUSHBUTTON "...",IDC_CFILE,7 + 136, 6, 16, 14 + + EDITTEXT IDC_EDIT1,36,22,16,12 + EDITTEXT IDC_EDIT2,94,22,16,12 + EDITTEXT IDC_EDIT3,152,22,28,12 + LTEXT "Sectors:",IDC_STATIC,7,22,27,10 + LTEXT "Heads:",IDC_STATIC,63,22,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,22,32,12 + LTEXT "", IDC_TEXT1, 7, 38, 136, 12 + + COMBOBOX IDC_HDTYPE, 7,54,172,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + +END + +HdSizeDlgMfm DIALOGEX 0, 0, 186, 102 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Hard disc parameters" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,31,82,50,14 + PUSHBUTTON "Cancel",IDCANCEL,101,82,50,14 + + LTEXT "Initial settings are based on file size",IDC_STATIC,7,6,170,10 + + EDITTEXT IDC_EDIT1,36,22,16,12 + EDITTEXT IDC_EDIT2,94,22,16,12 + EDITTEXT IDC_EDIT3,152,22,28,12 + LTEXT "Sectors:",IDC_STATIC,7,22,27,10 + LTEXT "Heads:",IDC_STATIC,63,22,29,8 + LTEXT "Cylinders:",IDC_STATIC,120,22,32,12 + LTEXT "", IDC_TEXT1, 7, 38, 136, 12 + + COMBOBOX IDC_HDTYPE, 7,54,172,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + +END + StatusDlg DIALOGEX 0,0,186,186+20+180 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Status" diff --git a/src/resources.h b/src/resources.h index 0722f2ebc..4df7017c2 100644 --- a/src/resources.h +++ b/src/resources.h @@ -251,8 +251,9 @@ #define IDC_COMBOJOY 1064 #define IDC_COMBOWS 1065 #define IDC_COMBOMOUSE 1066 -#define IDC_COMBODR3 1067 -#define IDC_COMBODR4 1068 +#define IDC_COMBOHDD 1067 +#define IDC_COMBODR3 1068 +#define IDC_COMBODR4 1069 #define IDC_CHECK1 1010 #define IDC_CHECK2 1011 #define IDC_CHECK3 1012 @@ -353,6 +354,8 @@ #define IDC_EDIT_J_FN 1237 #define IDC_TEXT_J_SIZE 1247 +#define IDC_HDTYPE 1280 + #define IDC_MEMSPIN 1100 #define IDC_MEMTEXT 1101 #define IDC_STEXT1 1102 diff --git a/src/win-config.c b/src/win-config.c index a1894ee9e..f209635f4 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -16,6 +16,7 @@ #include "buslogic.h" #include "fdd.h" #include "gameport.h" +#include "hdd.h" #include "model.h" #include "mouse.h" #include "nvr.h" @@ -30,6 +31,7 @@ static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], mode static int settings_sound_to_list[20], settings_list_to_sound[20]; static int settings_mouse_to_list[20], settings_list_to_mouse[20]; static int settings_network_to_list[20], settings_list_to_network[20]; +static char *hdd_names[16]; static int mouse_valid(int type, int model) { @@ -42,6 +44,71 @@ static int mouse_valid(int type, int model) return 1; } +static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) +{ + HWND h; + + h = GetDlgItem(hdlg, IDC_COMBOHDD); + + if (models[model].flags & MODEL_HAS_IDE) + { + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Internal IDE"); + EnableWindow(h, FALSE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } + else + { + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + if (use_selected_hdd) + { + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + strncpy(old_name, hdd_names[c], sizeof(old_name)-1); + else + strcpy(old_name, "none"); + } + else + strncpy(old_name, hdd_controller_name, sizeof(old_name)-1); + + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + s = hdd_controller_get_name(c); + if (s[0] == 0) + break; + if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + SendMessage(h, CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + SendMessage(h, CB_SETCURSEL, 0, 0); + } +} + static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { char temp_str[256]; @@ -369,6 +436,9 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR } SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); + + recalc_hdd_list(hdlg, romstomodel[romset], 0); + return TRUE; case WM_COMMAND: @@ -446,11 +516,15 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR h = GetDlgItem(hdlg, IDC_COMBOMOUSE); temp_mouse_type = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + h = GetDlgItem(hdlg, IDC_COMBOHDD); + c = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_cpu != cpu || temp_cpu_m != cpu_manufacturer || fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_fpu != enable_external_fpu || temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_xtide != enable_xtide || temp_voodoo != voodoo_enabled || temp_buslogic != buslogic_enabled || temp_dynarec != cpu_use_dynarec || temp_mouse_type != mouse_type || - temp_fd1_type != fdd_get_type(0) || temp_fd2_type != fdd_get_type(1) || temp_fd3_type != fdd_get_type(2) || temp_fd4_type != fdd_get_type(3) || temp_network_card_current != network_card_current) + temp_fd1_type != fdd_get_type(0) || temp_fd2_type != fdd_get_type(1) || temp_fd3_type != fdd_get_type(2) || temp_fd4_type != fdd_get_type(3) || + temp_network_card_current != network_card_current || strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1)) { if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL)==IDOK) { @@ -479,6 +553,11 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR network_card_current = temp_network_card_current; + if (hdd_names[c]) + strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); + else + strcpy(hdd_controller_name, "none"); + mem_resize(); loadbios(); resetpchard(); @@ -643,6 +722,8 @@ static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); else SendMessage(h, CB_SETCURSEL, 0, 0); + + recalc_hdd_list(hdlg, temp_model, 1); } break; case IDC_COMBOCPUM: diff --git a/src/win-hdconf.c b/src/win-hdconf.c index 98d5dc42e..73df0c97f 100644 --- a/src/win-hdconf.c +++ b/src/win-hdconf.c @@ -657,5 +657,8 @@ static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR void hdconf_open(HWND hwnd) { - DialogBox(hinstance, TEXT("HdConfDlg"), hwnd, hdconf_dlgproc); + if (hdd_controller_current_is_mfm()) + DialogBox(hinstance, TEXT("HdConfDlgMfm"), hwnd, hdconf_dlgproc); + else + DialogBox(hinstance, TEXT("HdConfDlg"), hwnd, hdconf_dlgproc); } diff --git a/src/xtide.c b/src/xtide.c index b464d0231..14c7bf95e 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,20 +1,26 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ #include "ibm.h" +#include "device.h" #include "io.h" #include "ide.h" +#include "mem.h" +#include "rom.h" #include "xtide.h" -uint8_t xtide_high; - -void xtide_write(uint16_t port, uint8_t val, void *priv) +typedef struct xtide_t { + uint8_t data_high; + rom_t bios_rom; +} xtide_t; + +static void xtide_write(uint16_t port, uint8_t val, void *p) +{ + xtide_t *xtide = (xtide_t *)p; + switch (port & 0xf) { case 0x0: - writeidew(0, val | (xtide_high << 8)); + writeidew(0, val | (xtide->data_high << 8)); return; case 0x1: case 0x2: case 0x3: @@ -23,7 +29,7 @@ void xtide_write(uint16_t port, uint8_t val, void *priv) return; case 0x8: - xtide_high = val; + xtide->data_high = val; return; case 0xe: @@ -32,14 +38,16 @@ void xtide_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t xtide_read(uint16_t port, void *priv) +static uint8_t xtide_read(uint16_t port, void *p) { + xtide_t *xtide = (xtide_t *)p; uint16_t tempw; + switch (port & 0xf) { case 0x0: tempw = readidew(0); - xtide_high = tempw >> 8; + xtide->data_high = tempw >> 8; return tempw & 0xff; case 0x1: case 0x2: case 0x3: @@ -47,15 +55,76 @@ uint8_t xtide_read(uint16_t port, void *priv) return readide(0, (port & 0xf) | 0x1f0); case 0x8: - return xtide_high; + return xtide->data_high; case 0xe: return readide(0, 0x3f6); } } -void xtide_init() +static void *xtide_init() { + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, "roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); - io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, NULL); + ide_pri_disable(); + ide_sec_disable(); + io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); + + return xtide; } + +static void *xtide_at_init() +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, "roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + ide_init(); + + return xtide; +} + +static void xtide_close(void *p) +{ + xtide_t *xtide = (xtide_t *)p; + + free(xtide); +} + +static int xtide_available() +{ + return rom_present("roms/ide_xt.bin"); +} + +static int xtide_at_available() +{ + return rom_present("roms/ide_at.bin"); +} + +device_t xtide_device = +{ + "XTIDE", + 0, + xtide_init, + xtide_close, + xtide_available, + NULL, + NULL, + NULL, + NULL +}; +device_t xtide_at_device = +{ + "XTIDE (AT)", + DEVICE_AT, + xtide_at_init, + xtide_close, + xtide_at_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/xtide.h b/src/xtide.h index bc1761369..6780844f6 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -1,4 +1,2 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void xtide_init(); +extern device_t xtide_device; +extern device_t xtide_at_device; From 55de61d58d3c2c470861f320cafd1a16c103bb25 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 15 Mar 2017 03:05:21 +0100 Subject: [PATCH 134/392] Removed ide_init(); from at_init(). --- src/model.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/model.c b/src/model.c index 495f75d8b..c6b76af2b 100644 --- a/src/model.c +++ b/src/model.c @@ -346,7 +346,6 @@ void at_init() mem_add_bios(); pit_set_out_func(1, pit_refresh_timer_at); dma16_init(); - ide_init(); keyboard_at_init(); nvr_init(); pic2_init(); From c1757b1742547fb7c94d5cd16e48669361943e33 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 15 Mar 2017 19:32:54 +0100 Subject: [PATCH 135/392] Added Compaq Portable, Portable II, and Portable III (both 286 and 386DX of the latter). Currently the original Portable has issues with CGA but works with the CGA-compatible Wyse 700 and EGA and higher). IBM PS/1 2011 and PS/2 30-286 now default to XTIDE 1.1.5 when selected. --- src/hdd.c | 1 - src/ibm.h | 6 +++++- src/mem.c | 38 ++++++++++++++++++++++++++++++++++---- src/model.c | 21 +++++++++++++++------ src/model.h | 1 + src/nvr.c | 8 +++++++- src/win-config.c | 9 ++++++++- src/xtide.c | 29 +++++++++++++++++++++++++++++ src/xtide.h | 1 + 9 files changed, 100 insertions(+), 14 deletions(-) diff --git a/src/hdd.c b/src/hdd.c index 219c381f6..eed719db5 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -66,7 +66,6 @@ void hdd_controller_init(char *internal_name) } c++; } - fatal("Could not find hdd_controller %s\n", internal_name); } diff --git a/src/ibm.h b/src/ibm.h index 8f9cdfabd..f2fd339cb 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -391,7 +391,11 @@ enum ROM_ENDEAVOR, ROM_REVENGE, ROM_IBMPS1_2011, - ROM_DESKPRO_386, + ROM_DESKPRO_386, + ROM_PORTABLE, + ROM_PORTABLEII, + ROM_PORTABLEIII, + ROM_PORTABLEIII386, //The original Compaq Portable III shipped with an Intel 80286 CPU, but later switched to a 386DX. ROM_IBMPS1_2121, ROM_AMI386DX_OPTI495, diff --git a/src/mem.c b/src/mem.c index f523d5d93..1f5ec3836 100644 --- a/src/mem.c +++ b/src/mem.c @@ -201,6 +201,40 @@ int loadbios() fclose(f); return 1; + case ROM_PORTABLE: + f=romfopen("roms/portable/Compaq Portable Plus 100666-001 Rev C u47.bin","rb"); + if (!f) break; + fread(rom+0xE000,8192,1,f); + fclose(f); + return 1; + + case ROM_PORTABLEII: + f = romfopen("roms/portableii/62x0820.u27", "rb"); + ff =romfopen("roms/portableii/62x0821.u47", "rb"); + if (!f || !ff) break; + for (c=0x0000;c<0x10000;c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + return 1; + + case ROM_PORTABLEIII: + case ROM_PORTABLEIII386: + f = romfopen("roms/portableiii/62x0820.u27", "rb"); + ff =romfopen("roms/portableiii/62x0821.u47", "rb"); + if (!f || !ff) break; + for (c=0x0000;c<0x10000;c+=2) + { + rom[c]=getc(f); + rom[c+1]=getc(ff); + } + fclose(ff); + fclose(f); + return 1; + case ROM_GENXT: f=romfopen("roms/genxt/pcxt.rom","rb"); if (!f) break; @@ -519,10 +553,6 @@ int loadbios() fread(rom, 0x20000, 1, f); fclose(f); //#endif - if (enable_xtide) - { - mem_load_atide115_bios(); - } biosmask = 0x1ffff; return 1; diff --git a/src/model.c b/src/model.c index c6b76af2b..fc34456dd 100644 --- a/src/model.c +++ b/src/model.c @@ -72,6 +72,7 @@ #include "vid_tandy.h" #include "w83877f.h" #include "wd76c10.h" +#include "xtide.h" void xt_init(); void pcjr_init(); @@ -108,6 +109,7 @@ void at_mb500n_init(); #if 0 void at_powermate_v_init(); #endif +void at_compaq_2000_init(); void at_p54tp4xe_init(); void at_acerm3a_init(); void at_acerv35n_init(); @@ -127,6 +129,7 @@ MODEL models[] = { {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, xt_init, NULL}, {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, @@ -146,17 +149,20 @@ MODEL models[] = {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, + {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_init, NULL}, {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2, 1, 16, 1, ps2_m30_286_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps2_m30_286_init, NULL}, {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL}, @@ -175,8 +181,8 @@ MODEL models[] = {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_mb500n_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_endeavor_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_endeavor_init, NULL}, {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_p54tp4xe_init, NULL}, {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_acerm3a_init, NULL}, {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_acerv35n_init, NULL}, @@ -371,7 +377,10 @@ void ps1_common_init() mem_add_bios(); pit_set_out_func(1, pit_refresh_timer_at); dma16_init(); - ide_init(); + if (romset == ROM_IBMPS1_2011) + device_add(&xtide_ps2_device); + else + ide_init(); keyboard_at_init(); nvr_init(); pic2_init(); @@ -401,7 +410,7 @@ void ps2_m30_286_init() mem_add_bios(); pit_set_out_func(1, pit_refresh_timer_at); dma16_init(); - ide_init(); + device_add(&xtide_ps2_device); keyboard_at_init(); nvr_init(); pic2_init(); diff --git a/src/model.h b/src/model.h index 272770732..9a627a3d1 100644 --- a/src/model.h +++ b/src/model.h @@ -9,6 +9,7 @@ #define MODEL_NEC 32 #define MODEL_FUJITSU 64 #define MODEL_RM 128 +#define MODEL_PS2_HDD 256 typedef struct { diff --git a/src/nvr.c b/src/nvr.c index 3a1520c61..4fea45468 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -211,6 +211,8 @@ void loadnvr() case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); nvrmask = 127; break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; + case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "rb"); break; + case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "rb"); break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "rb"); nvrmask = 127; break; @@ -218,6 +220,7 @@ void loadnvr() case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; + case ROM_PORTABLEIII386: f = romfopen(nvr_concat("portableiii386.nvr"), "rb"); break; /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break; */ case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "rb"); nvrmask = 127; break; case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "rb"); nvrmask = 127; break; @@ -298,7 +301,9 @@ void savenvr() case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "wb"); break; case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "wb"); break; case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "wb"); break; - case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; + case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; + case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "wb"); break; + case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "wb"); break; case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "wb"); break; @@ -306,6 +311,7 @@ void savenvr() case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; + case ROM_PORTABLEIII386: f = romfopen(nvr_concat("portableiii386.nvr"), "wb"); break; /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break; */ case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "wb"); break; case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "wb"); break; diff --git a/src/win-config.c b/src/win-config.c index f209635f4..66c99315c 100644 --- a/src/win-config.c +++ b/src/win-config.c @@ -50,7 +50,14 @@ static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) h = GetDlgItem(hdlg, IDC_COMBOHDD); - if (models[model].flags & MODEL_HAS_IDE) + if (models[model].flags & MODEL_PS2_HDD) + { + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"XTIDE for PS/2"); + EnableWindow(h, FALSE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } + else if (models[model].flags & MODEL_HAS_IDE) { SendMessage(h, CB_RESETCONTENT, 0, 0); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Internal IDE"); diff --git a/src/xtide.c b/src/xtide.c index 14c7bf95e..fc3b70f75 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -87,6 +87,17 @@ static void *xtide_at_init() return xtide; } +static void *xtide_ps2_init() +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + + rom_init(&xtide->bios_rom, "roms/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + ide_init(); + + return xtide; +} + static void xtide_close(void *p) { xtide_t *xtide = (xtide_t *)p; @@ -104,6 +115,11 @@ static int xtide_at_available() return rom_present("roms/ide_at.bin"); } +static int xtide_ps2_available() +{ + return rom_present("roms/ide_at_1_1_5.bin"); +} + device_t xtide_device = { "XTIDE", @@ -128,3 +144,16 @@ device_t xtide_at_device = NULL, NULL }; + +device_t xtide_ps2_device = +{ + "XTIDE (PS/2)", + DEVICE_AT, + xtide_ps2_init, + xtide_close, + xtide_ps2_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/xtide.h b/src/xtide.h index 6780844f6..d74dc76c2 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -1,2 +1,3 @@ extern device_t xtide_device; extern device_t xtide_at_device; +extern device_t xtide_ps2_device; From af1332b1875fd05630d8a7dd7acda95efdecfcab Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 17 Mar 2017 08:16:19 +0100 Subject: [PATCH 136/392] Added the ability to load 22 sector per track 2HD raw floppy images. --- src/disc_img.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/disc_img.c b/src/disc_img.c index 94bf48014..7f8417196 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -84,7 +84,7 @@ xdf_sector_t xdf_disk_layout[2][2][38] = { { { 0x0100, 0x0200, 0x8100, 0x8800, 0 Disks formatted at 300 kbps @ 300 RPM can be read with any 300 RPM single-RPM drive by setting the rate rate to 300 kbps. */ static uint8_t maximum_sectors[8][6] = { { 26, 31, 38, 53, 64, 118 }, /* 128 */ { 15, 19, 23, 32, 38, 73 }, /* 256 */ - { 7, 10, 12, 17, 21, 41 }, /* 512 */ + { 7, 10, 12, 17, 22, 41 }, /* 512 */ { 3, 5, 6, 9, 11, 22 }, /* 1024 */ { 2, 2, 3, 4, 5, 11 }, /* 2048 */ { 1, 1, 1, 2, 2, 5 }, /* 4096 */ @@ -120,6 +120,7 @@ int gap3_sizes[5][8][256] = { [0][1][16] = 0x54, [0][2][19] = 0x48, [0][2][20] = 0x2A, [0][2][21] = 0x08, /* Microsoft DMFWRITE.EXE uses this, 0x0C is used by FDFORMAT. */ + [0][2][22] = 0x02, [0][2][23] = 0x01, [0][3][10] = 0x83, [0][3][11] = 0x26, @@ -136,6 +137,7 @@ int gap3_sizes[5][8][256] = { [0][1][16] = 0x54, [2][2][9] = 0x50, [2][2][10] = 0x2E, [2][2][21] = 0x1C, + [2][2][22] = 0x1C, [2][3][4] = 0xF0, [2][3][5] = 0x74, [3][2][36] = 0x53, @@ -651,7 +653,8 @@ jump_if_fdf: else if (size <= 1720320) { img[drive].sectors = 21; img[drive].tracks = 80; } /*DMF format - used by Windows 95 */ else if (size <= 1741824) { img[drive].sectors = 21; img[drive].tracks = 81; } else if (size <= 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; } - else if (size <= 1802240) { img[drive].sectors = 11; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ + // else if (size <= 1802240) { img[drive].sectors = 11; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ + else if (size <= 1802240) { img[drive].sectors = 22; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; } /*XDF format - used by OS/2 Warp*/ else if (size <= 2949120) { img[drive].sectors = 36; img[drive].tracks = 80; } /*E density*/ else if (size <= 3194880) { img[drive].sectors = 39; img[drive].tracks = 80; } /*E density*/ @@ -710,6 +713,11 @@ jump_if_fdf: } else { + if ((bit_rate_300 == 500.0) && (img[drive].sectors == 22) && (img[drive].sector_size == 2) && (img[drive].tracks >= 80) && (img[drive].tracks <= 82) && (img[drive].sides == 2)) + { + /* This is marked specially because of the track flag (a RPM slow down is needed). */ + img[drive].interleave = 2; + } img[drive].dmf = 0; } @@ -744,6 +752,11 @@ jump_if_fdf: img[drive].track_width = 0; if (img[drive].tracks > 43) img[drive].track_width = 1; /* If the image has more than 43 tracks, then the tracks are thin (96 tpi). */ if (img[drive].sides == 2) img[drive].disk_flags |= 8; /* If the has 2 sides, mark it as such. */ + if (img[drive].interleave == 2) + { + img[drive].interleave = 1; + img[drive].disk_flags |= 0x60; + } img[drive].track_flags = 0x08; /* IMG files are always assumed to be MFM-encoded. */ img[drive].track_flags |= temp_rate & 3; /* Data rate. */ From e26ed9907db060d12b2501836f03f09a9b8d1392 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 18 Mar 2017 20:44:46 -0500 Subject: [PATCH 137/392] CMake builds compile now, but segfault at start --- src/808x.c | 10 +++++----- src/CMakeLists.txt | 18 +++++++++--------- src/vid_cl_gd_blit.c | 4 ++-- src/vid_cl_gd_vga_rop.h | 6 +++--- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/808x.c b/src/808x.c index dd7228ed6..07f8ed95b 100644 --- a/src/808x.c +++ b/src/808x.c @@ -116,7 +116,7 @@ int fetchcycles=0,memcycs,fetchclocks; uint8_t prefetchqueue[6]; uint16_t prefetchpc; int prefetchw=0; -inline uint8_t FETCH() +static inline uint8_t FETCH() { uint8_t temp; /* temp=prefetchqueue[0]; @@ -170,7 +170,7 @@ inline uint8_t FETCH() return temp; } -inline void FETCHADD(int c) +static inline void FETCHADD(int c) { int d; // if (output) printf("FETCHADD %i\n",c); @@ -225,7 +225,7 @@ void FETCHCOMPLETE() fetchcycles+=(4-(fetchcycles&3)); } -inline void FETCHCLEAR() +static inline void FETCHCLEAR() { /* int c; fetchcycles=0; @@ -270,13 +270,13 @@ r16(/r) AX CX DX BX SP BP SI DI r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI /digit (Opcode) 0 1 2 3 4 5 6 7 REG = 000 001 010 011 100 101 110 111 - ÚÄÄÄAddress + ����Address disp8 denotes an 8-bit displacement following the ModR/M byte, to be sign-extended and added to the index. disp16 denotes a 16-bit displacement following the ModR/M byte, to be added to the index. Default segment register is SS for the effective addresses containing a BP index, DS for other effective addresses. - ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿ + �Ŀ �Mod R/M� ���������ModR/M Values in Hexadecimal�������Ŀ [BX + SI] 000 00 08 10 18 20 28 30 38 [BX + DI] 001 01 09 11 19 21 29 31 39 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 275c04819..709eb3728 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,22 +4,22 @@ project(86box) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeModules) set(SRCS -386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c acerm3a.c aha154x.c ali1429.c amstrad.c cdrom-ioctl.c cdrom-iso.c +386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c acerm3a.c ali1429.c amstrad.c buslogic.c cdrom.c cdrom-ioctl.c cdrom-iso.c cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c dac.c -device.c disc.c disc_86f.c disc_fdi.c disc_imd.c disc_img.c disc_random.c disc_td0.c dma.c fdc.c fdc37c665.c fdc37c932fr.c fdd.c fdi2raw.c gameport.c headland.c i430hx.c i430lx.c i430fx.c +device.c disc.c disc_86f.c disc_fdi.c disc_imd.c disc_img.c disc_random.c disc_td0.c dma.c fdc.c fdc37c665.c fdc37c932fr.c fdd.c fdi2raw.c gameport.c hdd.c headland.c i430hx.c i430lx.c i430fx.c i430nx.c i430vx.c i440fx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c -keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c lpt.c mcr.c mem.c memregs.c model.c mouse.c mouse_amstrad.c mouse_ps2.c -mouse_serial.c ne2000.c neat.c nethandler.c nmi.c nvr.c olivetti_m24.c opti.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c rtc.c -scat.c scattergather.c scsi.c scsi_cdrom.c serial.c sis496.c sis85c471.c sio.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c +keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c lpt.c mcr.c mem.c memregs.c mfm_at.c model.c mouse.c mouse_ps2.c +mouse_serial.c ne2000.c neat.c nethandler.c nmi.c nvr.c olivetti_m24.c opti495.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c rom.c rtc.c +scat.c scsi.c serial.c sis496.c sis85c471.c sio.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_dbopl.cc sound_emu8k.c sound_gus.c sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_resid.cc sound_sb.c sound_sb_dsp.c sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c -soundopenal.c tandy_eeprom.c tandy_rom.c timer.c um8669f.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c +soundopenal.c tandy_eeprom.c tandy_rom.c timer.c um8669f.c usb.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c vid_ati68860_ramdac.c vid_bt485_ramdac.c vid_cga.c vid_cl_gd.c vid_cl_gd_blit.c vid_cl_ramdac.c vid_colorplus.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_hercules.c vid_herculesplus.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_nv_riva128.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc1512.c vid_pc1640.c vid_pc200.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c -vid_vga.c vid_voodoo.c video.c wd76c10.c win.c win-config.c win-d3d.cc win-d3d-fs.cc win-ddraw.cc +vid_vga.c vid_wy700.c vid_voodoo.c video.c w83877f.c wd76c10.c win.c win-config.c win-d3d.cc win-d3d-fs.cc win-ddraw.cc win-ddraw-fs.cc win-ddraw-screenshot.cc win-deviceconfig.c win-hdconf.c win-joystick.cc win-joystickconfig.c win-keyboard.cc win-midi.c win-mouse.cc win-status.c win-video.c x86seg.c x87.c xtide.c pc.rc dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c @@ -48,8 +48,8 @@ codegen_x86-64.c ) endif() -add_definitions(-msse2 -mstackrealign -mwindows) +add_definitions(-msse2 -mstackrealign -mwindows -g) add_executable(86box ${SRCS}) -target_link_libraries(86box winmm openal.dll openal ddraw dinput8 dxguid d3d9 d3dx9 wsock32 iphlpapi stdc++) \ No newline at end of file +target_link_libraries(86box winmm openal.dll openal ddraw dinput8 dxguid d3d9 d3dx9 wsock32 iphlpapi stdc++ psapi wpcapdelay comdlg32 gdi32) \ No newline at end of file diff --git a/src/vid_cl_gd_blit.c b/src/vid_cl_gd_blit.c index 0a5348629..fbf63d72c 100644 --- a/src/vid_cl_gd_blit.c +++ b/src/vid_cl_gd_blit.c @@ -346,7 +346,7 @@ const cirrus_fill_t cirrus_fill[16][4] = { ROP2(cirrus_fill_notsrc_and_notdst), }; -inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) +static inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) { unsigned int color; switch (clgd->blt.pixel_width) @@ -369,7 +369,7 @@ inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) } } -inline void cirrus_bitblt_bgcol(clgd_t *clgd, svga_t *svga) +static inline void cirrus_bitblt_bgcol(clgd_t *clgd, svga_t *svga) { unsigned int color; switch (clgd->blt.pixel_width) diff --git a/src/vid_cl_gd_vga_rop.h b/src/vid_cl_gd_vga_rop.h index d03516ba3..2b2b263fc 100644 --- a/src/vid_cl_gd_vga_rop.h +++ b/src/vid_cl_gd_vga_rop.h @@ -22,17 +22,17 @@ * THE SOFTWARE. */ -inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src) +static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src) { *dst = ROP_FN(*dst, src); } -inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) +static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) { *dst = ROP_FN(*dst, src); } -inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) +static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) { *dst = ROP_FN(*dst, src); } From 53bd6f4609cc2185ff6d17524af068088dac4238 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sat, 18 Mar 2017 20:53:52 -0500 Subject: [PATCH 138/392] CMake builds work fully now --- src/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 709eb3728..dc84277c5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,6 +3,10 @@ project(86box) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeModules) +ENABLE_LANGUAGE(RC) + +set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILER} -O coff -I${CMAKE_CURRENT_SOURCE_DIR} ") + set(SRCS 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c acerm3a.c ali1429.c amstrad.c buslogic.c cdrom.c cdrom-ioctl.c cdrom-iso.c cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c dac.c From 212932baf23f08068796c46cafa5a7312da30686 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sun, 2 Apr 2017 18:32:20 -0500 Subject: [PATCH 139/392] Fix a lil MMIO bug --- src/vid_nv_riva128.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 152b2f963..eb6fe88a5 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1972,6 +1972,12 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 0x009000 ... 0x009fff: riva128_ptimer_write(addr, val, riva128); break; + case 0x0c03c4 ... 0x0c03c5: case 0x0c03cc ... 0x0c03cf: + riva128_mmio_write(addr, val & 0xff, riva128); + riva128_mmio_write(addr+1, (val >> 8) & 0xff, riva128); + riva128_mmio_write(addr+2, (val >> 16) & 0xff, riva128); + riva128_mmio_write(addr+3, (val >> 24) & 0xff, riva128); + break; case 0x100000 ... 0x100fff: riva128_pfb_write(addr, val, riva128); break; From d1e4d8bf0de55762181e39e8d7bee292390bf182 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 6 Apr 2017 16:59:45 -0500 Subject: [PATCH 140/392] Fix a bug --- src/vid_nv_riva128.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index eb6fe88a5..4bc78e56b 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1863,7 +1863,7 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) addr &= 0xffffff; //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. - if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000)) && !((addr >= 0x0c0000) && (addr <= 0x0cffff)) && !((addr >= 0x110000) && (addr <= 0x11ffff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { @@ -1956,7 +1956,7 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) addr &= 0xffffff; //DO NOT REMOVE. This fixes a monstrous log blowup in win9x's drivers when accessing PFIFO. - if(!((addr >= 0x002000) && (addr <= 0x003fff))) pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + if(!((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0xc0000) && (addr <= 0xcffff))) pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) { @@ -1973,10 +1973,10 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) riva128_ptimer_write(addr, val, riva128); break; case 0x0c03c4 ... 0x0c03c5: case 0x0c03cc ... 0x0c03cf: - riva128_mmio_write(addr, val & 0xff, riva128); - riva128_mmio_write(addr+1, (val >> 8) & 0xff, riva128); - riva128_mmio_write(addr+2, (val >> 16) & 0xff, riva128); - riva128_mmio_write(addr+3, (val >> 24) & 0xff, riva128); + riva128_out(addr & 0xfff, val & 0xff, p); + riva128_out((addr+1) & 0xfff, (val>>8) & 0xff, p); + riva128_out((addr+2) & 0xfff, (val>>16) & 0xff, p); + riva128_out((addr+3) & 0xfff, (val>>24) & 0xff, p); break; case 0x100000 ... 0x100fff: riva128_pfb_write(addr, val, riva128); From 0c6622d4c0af8db7b49a59f3879f7391d9a8a9e3 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 6 Apr 2017 17:01:49 -0500 Subject: [PATCH 141/392] Fix ridiculous line length --- src/vid_nv_riva128.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 4bc78e56b..a9eb08a54 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -1863,7 +1863,9 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) addr &= 0xffffff; //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. - if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000)) && !((addr >= 0x0c0000) && (addr <= 0x0cffff)) && !((addr >= 0x110000) && (addr <= 0x11ffff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) + && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000)) && !((addr >= 0x0c0000) && (addr <= 0x0cffff)) + && !((addr >= 0x110000) && (addr <= 0x11ffff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { From d1e750dd5574e14bd9ca425f670f081b7d2be16b Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 6 Apr 2017 17:45:26 -0500 Subject: [PATCH 142/392] Fix various bugs --- src/vid_nv_riva128.c | 88 +++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index a9eb08a54..4040459c4 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -850,6 +850,14 @@ static void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p) if((val & 0xffff) > riva128->ptimer.clock_div) val = riva128->ptimer.clock_div; riva128->ptimer.clock_mul = val & 0xffff; break; + case 0x009400: + riva128->ptimer.time &= 0x0fffffff00000000ULL; + riva128->ptimer.time |= val & 0xffffffe0; + break; + case 0x009410: + riva128->ptimer.time &= 0xffffffe0; + riva128->ptimer.time |= val & 0x0fffffff00000000ULL; + break; case 0x009420: riva128->ptimer.alarm = val & 0xffffffe0; break; @@ -2007,7 +2015,7 @@ static void riva128_ptimer_tick(void *p) uint64_t tmp = riva128->ptimer.time; riva128->ptimer.time += time << 5; - if((tmp < riva128->ptimer.alarm) && (riva128->ptimer.time >= riva128->ptimer.alarm)) riva128_ptimer_interrupt(0, riva128); + if(((uint32_t)tmp < riva128->ptimer.alarm) && ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm)) riva128_ptimer_interrupt(0, riva128); } static void riva128_mclk_poll(void *p) @@ -2025,7 +2033,7 @@ static void riva128_nvclk_poll(void *p) riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - if(riva128->card_id > 0x40 && riva128->card_id != 0x03) riva128_ptimer_tick(riva128); + if(riva128->card_id < 0x40 && riva128->card_id != 0x03) riva128_ptimer_tick(riva128); riva128->nvtime += cpuclock / riva128->nvfreq; } @@ -2743,8 +2751,6 @@ static void *riva128_init() riva128->memory_size = device_get_config_int("memory"); - riva128->pgraph.pgraph_speedhack = device_get_config_int("pgraph_speedhack"); - svga_init(&riva128->svga, riva128, riva128->memory_size << 20, riva128_recalctimings, riva128_in, riva128_out, @@ -2810,6 +2816,7 @@ static void *riva128_init() riva128->pbus.intr = 0; riva128->pfifo.intr = 0; riva128->pgraph.intr = 0; + riva128->ptimer.intr = 0; pci_add(riva128_pci_read, riva128_pci_write, riva128); @@ -2892,6 +2899,58 @@ static device_config_t riva128_config[] = }, .default_int = 4 }, + { + .name = "irq", + .description = "IRQ", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "IRQ 3", + .value = 3 + }, + { + .description = "IRQ 4", + .value = 4 + }, + { + .description = "IRQ 5", + .value = 5 + }, + { + .description = "IRQ 7", + .value = 7 + }, + { + .description = "IRQ 9", + .value = 9 + }, + { + .description = "IRQ 10", + .value = 10 + }, + { + .description = "IRQ 11", + .value = 11 + }, + { + .description = "IRQ 12", + .value = 12 + }, + { + .description = "IRQ 14", + .value = 14 + }, + { + .description = "IRQ 15", + .value = 15 + }, + { + .description = "" + } + }, + .default_int = 3 + }, { .type = -1 } @@ -2899,27 +2958,6 @@ static device_config_t riva128_config[] = static device_config_t riva128zx_config[] = { - { - .name = "pgraph_speedhack", - .description = "PGRAPH speedhack", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Off", - .value = 0, - }, - { - .description = "On", - .value = 1, - }, - { - .description = "" - } - }, - //DO NOT TURN THIS OFF YET. THE PGRAPH SPEEDHACK IS CURRENTLY NECESSARY FOR WORKING EMULATION. - .default_int = 1 - }, { .name = "memory", .description = "Memory size", From 62463f86b06f569049974ca0212262cc92a69c29 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 20 Apr 2017 20:41:38 -0500 Subject: [PATCH 143/392] Fixes --- src/vid_nv_riva128.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 4040459c4..98a1ec13a 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -452,6 +452,7 @@ static void riva128_pmc_write(uint32_t addr, uint32_t val, void *p) static void riva128_pmc_interrupt(int num, void *p) { + pclog("RIVA 128 PMC interrupt #%d fired!", num); riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; @@ -866,6 +867,7 @@ static void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p) static void riva128_ptimer_interrupt(int num, void *p) { + pclog("RIVA 128 PTIMER interrupt #%d fired!", num); riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; @@ -2008,14 +2010,18 @@ static void riva128_ptimer_tick(void *p) riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; - uint64_t time = riva128->ptimer.clock_mul - riva128->ptimer.clock_div; + double time = (double)riva128->ptimer.clock_mul / (double)riva128->ptimer.clock_div; time *= 1000; uint64_t tmp = riva128->ptimer.time; - riva128->ptimer.time += time << 5; + riva128->ptimer.time += (uint64_t)time << 5; - if(((uint32_t)tmp < riva128->ptimer.alarm) && ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm)) riva128_ptimer_interrupt(0, riva128); + if(((uint32_t)tmp < riva128->ptimer.alarm) && ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm)) + { + pclog("RIVA 128 PTIMER ALARM interrupt fired!"); + riva128_ptimer_interrupt(0, riva128); + } } static void riva128_mclk_poll(void *p) @@ -2820,6 +2826,9 @@ static void *riva128_init() pci_add(riva128_pci_read, riva128_pci_write, riva128); + riva128->ptimer.clock_mul = 1; + riva128->ptimer.clock_div = 1; + //Some bullshit default values so that the emulator won't shit itself trying to boot. These'll be overwritten by the video BIOS anyway. riva128->pramdac.m_m = 0x03; riva128->pramdac.m_n = 0xc2; From 25643e498c6a874b9e9f19c985579379529dbfef Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Fri, 21 Apr 2017 18:36:40 -0500 Subject: [PATCH 144/392] Moar fixes --- src/vid_nv_riva128.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 98a1ec13a..4372d50aa 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -211,6 +211,7 @@ typedef struct riva128_t int scl; int sda; uint8_t addr; //actually 7 bits + uint8_t data; } i2c; int mtime, mfreq; @@ -452,13 +453,13 @@ static void riva128_pmc_write(uint32_t addr, uint32_t val, void *p) static void riva128_pmc_interrupt(int num, void *p) { - pclog("RIVA 128 PMC interrupt #%d fired!", num); + //pclog("RIVA 128 PMC interrupt #%d fired!\n", num); riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; riva128->pmc.intr |= (1 << num); - picint(1 << riva128->pci_regs[0x3c]); + if(riva128->pmc.intr_en & 1) picint(1 << riva128->pci_regs[0x3c]); } static uint8_t riva128_pbus_read(uint32_t addr, void *p) @@ -867,7 +868,7 @@ static void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p) static void riva128_ptimer_interrupt(int num, void *p) { - pclog("RIVA 128 PTIMER interrupt #%d fired!", num); + //pclog("RIVA 128 PTIMER interrupt #%d fired!\n", num); riva128_t *riva128 = (riva128_t *)p; svga_t *svga = &riva128->svga; @@ -1875,7 +1876,7 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) //This logging condition is necessary to prevent A CATASTROPHIC LOG BLOWUP when polling PTIMER or PFIFO. DO NOT REMOVE. if(!((addr >= 0x009000) && (addr <= 0x009fff)) && !((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0x000000) && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000)) && !((addr >= 0x0c0000) && (addr <= 0x0cffff)) - && !((addr >= 0x110000) && (addr <= 0x11ffff))) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + && !((addr >= 0x110000) && (addr <= 0x11ffff)) && !(addr <= 0x000fff) && (addr >= 0x000000)) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); switch(addr) { @@ -1908,8 +1909,9 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) break; case 0x6013b4 ... 0x6013b5: case 0x6013d4 ... 0x6013d5: + case 0x6013da: case 0x0c03c2 ... 0x0c03c5: - case 0x0c03cc ... 0x0c03cf: + case 0x6813c6 ... 0x6813cc: ret = riva128_in(addr & 0xfff, riva128); break; case 0x680000 ... 0x680fff: @@ -1937,7 +1939,7 @@ static void riva128_mmio_write(uint32_t addr, uint8_t val, void *p) { addr &= 0xffffff; //pclog("RIVA 128 MMIO write %08X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); - if(addr != 0x6013d4 && addr != 0x6013d5 && addr != 0x6013b4 && addr != 0x6013b5) + if(addr != 0x6013d4 && addr != 0x6013d5 && addr != 0x6013b4 && addr != 0x6013b5 && addr != 0x6013da && !((addr >= 0x6813c6) && (addr <= 0x6813cc))) { uint32_t tmp = riva128_mmio_read_l(addr,p); tmp &= ~(0xff << ((addr & 3) << 3)); @@ -1968,7 +1970,7 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) addr &= 0xffffff; //DO NOT REMOVE. This fixes a monstrous log blowup in win9x's drivers when accessing PFIFO. - if(!((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0xc0000) && (addr <= 0xcffff))) pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + if(!((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0xc0000) && (addr <= 0xcffff)) && (addr != 0x000140)) pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) { @@ -1984,7 +1986,11 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) case 0x009000 ... 0x009fff: riva128_ptimer_write(addr, val, riva128); break; - case 0x0c03c4 ... 0x0c03c5: case 0x0c03cc ... 0x0c03cf: + case 0x6013b4 ... 0x6013b5: + case 0x6013d4 ... 0x6013d5: + case 0x6013da: + case 0x0c03c2 ... 0x0c03c5: + case 0x6813c6 ... 0x6813cc: riva128_out(addr & 0xfff, val & 0xff, p); riva128_out((addr+1) & 0xfff, (val>>8) & 0xff, p); riva128_out((addr+2) & 0xfff, (val>>16) & 0xff, p); @@ -2012,14 +2018,16 @@ static void riva128_ptimer_tick(void *p) double time = (double)riva128->ptimer.clock_mul / (double)riva128->ptimer.clock_div; - time *= 1000; + time *= 10000; uint64_t tmp = riva128->ptimer.time; riva128->ptimer.time += (uint64_t)time << 5; - if(((uint32_t)tmp < riva128->ptimer.alarm) && ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm)) + int alarm_check = ((uint32_t)tmp < riva128->ptimer.alarm) || ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm); + + if(alarm_check) { - pclog("RIVA 128 PTIMER ALARM interrupt fired!"); + //pclog("RIVA 128 PTIMER ALARM interrupt fired!\n"); riva128_ptimer_interrupt(0, riva128); } } @@ -2171,6 +2179,9 @@ static uint8_t riva128_in(uint16_t addr, void *p) case 0x3e: ret = (riva128->i2c.sda << 3) | (riva128->i2c.scl << 2); break; + case 0x28: + ret = svga->crtc[0x28] & 3; + break; default: ret = svga->crtc[svga->crtcreg]; break; @@ -2721,7 +2732,7 @@ static void riva128_recalctimings(svga_t *svga) svga->clock = cpuclock / freq; } - freq = 13500.0; + freq = 1350.0; if(riva128->pramdac.nv_m == 0) freq = 0; else @@ -2732,7 +2743,7 @@ static void riva128_recalctimings(svga_t *svga) riva128->mfreq = freq; - freq = 13500.0; + freq = 1350.0; if(riva128->pramdac.m_m == 0) freq = 0; else From 7ef86551b5ff6172240e586a3b696d2504772f09 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Wed, 26 Apr 2017 20:26:47 -0500 Subject: [PATCH 145/392] Add VBLANK interrupt for nvidia cards --- src/vid_nv_riva128.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 4372d50aa..698e3317c 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -216,7 +216,6 @@ typedef struct riva128_t int mtime, mfreq; int nvtime, nvfreq; - } riva128_t; //Internally, the RIVA 128 operates in a weird 38-bit color depth, with 10 bits for RGB, and 8 bits for alpha, according to envytools. @@ -2052,6 +2051,14 @@ static void riva128_nvclk_poll(void *p) riva128->nvtime += cpuclock / riva128->nvfreq; } +static void riva128_vblank_poll(void *p) +{ + riva128_t *riva128 = (riva128_t *)p; + svga_t *svga = &riva128->svga; + + if(svga->vc == svga->dispend) riva128_pmc_interrupt(24, riva128); +} + static uint8_t riva128_rma_in(uint16_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; @@ -2851,6 +2858,7 @@ static void *riva128_init() timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + timer_add(riva128_vblank_poll, &riva128->svga.vidtime, TIMER_ALWAYS_ENABLED, riva128); return riva128; } @@ -3156,6 +3164,7 @@ static void *rivatnt_init() timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + timer_add(riva128_vblank_poll, &riva128->svga.vidtime, TIMER_ALWAYS_ENABLED, riva128); return riva128; } @@ -3387,6 +3396,7 @@ static void *rivatnt2_init() timer_add(riva128_mclk_poll, &riva128->mtime, TIMER_ALWAYS_ENABLED, riva128); timer_add(riva128_nvclk_poll, &riva128->nvtime, TIMER_ALWAYS_ENABLED, riva128); + timer_add(riva128_vblank_poll, &riva128->svga.vidtime, TIMER_ALWAYS_ENABLED, riva128); return riva128; } From 726f9c8771575e78e1a118468fcfc23acb3b885d Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sun, 30 Apr 2017 12:56:39 -0500 Subject: [PATCH 146/392] Fix a BUNCH of warnings --- src/vid_nv_riva128.c | 75 +++++++++----------------------------------- src/vid_svga.h | 1 + 2 files changed, 16 insertions(+), 60 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 698e3317c..77fb7301c 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -8,6 +8,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "pic.h" #include "rom.h" #include "thread.h" #include "timer.h" @@ -243,7 +244,7 @@ const char* riva128_pfifo_interrupts[32] = }; static uint32_t riva128_ramht_lookup(uint32_t handle, void *p); -static void riva128_pgraph_volatile_reset(void *p); +//static void riva128_pgraph_volatile_reset(void *p); static uint8_t riva128_pci_read(int func, int addr, void *p); static void riva128_pci_write(int func, int addr, uint8_t val, void *p); @@ -253,7 +254,7 @@ static void riva128_out(uint16_t addr, uint8_t val, void *p); static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p); -static riva128_color_t riva128_pgraph_expand_color(uint32_t ctx, uint32_t color) +/*static riva128_color_t riva128_pgraph_expand_color(uint32_t ctx, uint32_t color) { riva128_color_t ret; int format = ctx & 7; @@ -320,12 +321,11 @@ static uint32_t riva128_pgraph_do_blend(uint32_t factor, uint32_t dst, uint32_t dst &= 0xf8; } return ((dst * (0x100 - factor)) + (src * factor)) >> 6; -} +}*/ static uint8_t riva128_pmc_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; //pclog("RIVA 128 PMC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -433,7 +433,6 @@ static uint8_t riva128_pmc_read(uint32_t addr, void *p) static void riva128_pmc_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; //pclog("RIVA 128 PMC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -454,7 +453,6 @@ static void riva128_pmc_interrupt(int num, void *p) { //pclog("RIVA 128 PMC interrupt #%d fired!\n", num); riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; riva128->pmc.intr |= (1 << num); @@ -464,7 +462,6 @@ static void riva128_pmc_interrupt(int num, void *p) static uint8_t riva128_pbus_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; //pclog("RIVA 128 PBUS read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -506,7 +503,6 @@ static uint8_t riva128_pbus_read(uint32_t addr, void *p) static void riva128_pbus_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; //pclog("RIVA 128 PBUS write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -529,7 +525,6 @@ static void riva128_pbus_write(uint32_t addr, uint32_t val, void *p) static uint8_t riva128_pfifo_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; // pclog("RIVA 128 PFIFO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -659,7 +654,6 @@ static uint8_t riva128_pfifo_read(uint32_t addr, void *p) static void riva128_pfifo_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; // pclog("RIVA 128 PFIFO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -720,7 +714,6 @@ static void riva128_pfifo_write(uint32_t addr, uint32_t val, void *p) static void riva128_pfifo_interrupt(int num, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; riva128->pfifo.intr |= (1 << num); @@ -730,7 +723,6 @@ static void riva128_pfifo_interrupt(int num, void *p) static uint8_t riva128_ptimer_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; //pclog("RIVA 128 PTIMER read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -832,7 +824,6 @@ static uint8_t riva128_ptimer_read(uint32_t addr, void *p) static void riva128_ptimer_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; pclog("RIVA 128 PTIMER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -869,7 +860,6 @@ static void riva128_ptimer_interrupt(int num, void *p) { //pclog("RIVA 128 PTIMER interrupt #%d fired!\n", num); riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; riva128->ptimer.intr |= (1 << num); @@ -879,7 +869,6 @@ static void riva128_ptimer_interrupt(int num, void *p) static uint8_t riva128_pfb_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; //pclog("RIVA 128 PFB read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -949,7 +938,6 @@ static uint8_t riva128_pfb_read(uint32_t addr, void *p) static void riva128_pfb_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; //pclog("RIVA 128 PFB write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -975,8 +963,7 @@ static void riva128_pfb_write(uint32_t addr, uint32_t val, void *p) static uint8_t riva128_pextdev_read(uint32_t addr, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + //riva128_t *riva128 = (riva128_t *)p; uint8_t ret = 0; //pclog("RIVA 128 PEXTDEV read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -997,7 +984,6 @@ static uint8_t riva128_pextdev_read(uint32_t addr, void *p) static void rivatnt_pgraph_ctx_switch(void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; if(!(riva128->pgraph.fifo_st2_addr & 1)) return; @@ -1027,7 +1013,7 @@ static void rivatnt_pgraph_ctx_switch(void *p) if(reset) { riva128->pgraph.debug[1] |= 1; - riva128_pgraph_volatile_reset(riva128); + //riva128_pgraph_volatile_reset(riva128); } else riva128->pgraph.debug[1] &= ~1; @@ -1041,7 +1027,6 @@ static void rivatnt_pgraph_ctx_switch(void *p) static uint8_t riva128_pgraph_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; pclog("RIVA 128 PGRAPH read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -1423,7 +1408,6 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p) static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; pclog("RIVA 128 PGRAPH write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -1570,7 +1554,6 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) static void riva128_pgraph_interrupt(int num, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; riva128->pgraph.intr |= (1 << num); @@ -1580,25 +1563,15 @@ static void riva128_pgraph_interrupt(int num, void *p) static void riva128_pgraph_invalid_interrupt(int num, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; riva128->pgraph.invalid |= (1 << num); riva128_pgraph_interrupt(0, riva128); } -static void riva128_pgraph_volatile_reset(void *p) -{ - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; - - //TODO -} - static uint8_t riva128_pramdac_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; //pclog("RIVA 128 PRAMDAC read %08X %04X:%08X\n", addr, CS, cpu_state.pc); @@ -1673,7 +1646,7 @@ static uint8_t riva128_pramdac_read(uint32_t addr, void *p) static void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + svga_t* svga = &riva128->svga; //pclog("RIVA 128 PRAMDAC write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); switch(addr) @@ -1711,7 +1684,6 @@ static void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p) static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; pclog("RIVA 128 RAMHT lookup with handle %08X %04X:%08X\n", handle, CS, cpu_state.pc); uint32_t ramht_base = riva128->pfifo.ramht_addr; @@ -1747,7 +1719,6 @@ static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) static void riva128_puller_exec_method(int chanid, int subchanid, int offset, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; pclog("RIVA 128 Puller executing method %04X on channel %01X[%01X] %04X:%08X\n", offset, chanid, subchanid, val, CS, cpu_state.pc); if(riva128->card_id == 0x03) @@ -1766,7 +1737,7 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui if(riva128->pgraph.debug[1] & 0x100000) riva128->pgraph.ctx_switch[0] = riva128->pgraph.ctx_cache[new_subc][0]; if(riva128->pgraph.debug[2] & 0x10000000) { - riva128_pgraph_volatile_reset(riva128); + //riva128_pgraph_volatile_reset(riva128); riva128->pgraph.debug[1] |= 1; } else riva128->pgraph.debug[1] &= ~1; @@ -1804,7 +1775,7 @@ static void riva128_pusher_run(int chanid, void *p) { uint32_t dmaget = riva128->pfifo.channels[chanid].dmaget; uint32_t cmd = ((uint32_t*)svga->vram)[dmaget >> 2]; - uint32_t* params = ((uint32_t*)svga->vram)[(dmaget + 4) >> 2]; + uint32_t* params = ((uint32_t*)svga->vram + ((dmaget + 4) >> 2)); if(((cmd & 0xe0000003) == 0x20000000) && (riva128->card_id >= 0x04)) { //old nv4 jump command @@ -1834,13 +1805,12 @@ static void riva128_pusher_run(int chanid, void *p) static void riva128_user_write(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; pclog("RIVA 128 USER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); addr -= 0x800000; int chanid = (addr >> 16) & 0xf; - int subchanid = (addr >> 13) & 0x7; + //int subchanid = (addr >> 13) & 0x7; int offset = addr & 0x1fff; if(riva128->pfifo.chan_mode & (1 << chanid)) @@ -1867,7 +1837,6 @@ static void riva128_user_write(uint32_t addr, uint32_t val, void *p) static uint8_t riva128_mmio_read(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; addr &= 0xffffff; @@ -1964,7 +1933,6 @@ static void riva128_mmio_write_w(uint32_t addr, uint16_t val, void *p) static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; addr &= 0xffffff; @@ -2013,7 +1981,6 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) static void riva128_ptimer_tick(void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; double time = (double)riva128->ptimer.clock_mul / (double)riva128->ptimer.clock_div; @@ -2034,7 +2001,6 @@ static void riva128_ptimer_tick(void *p) static void riva128_mclk_poll(void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; if(riva128->card_id == 0x03) riva128_ptimer_tick(riva128); @@ -2044,7 +2010,6 @@ static void riva128_mclk_poll(void *p) static void riva128_nvclk_poll(void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; if(riva128->card_id < 0x40 && riva128->card_id != 0x03) riva128_ptimer_tick(riva128); @@ -2062,7 +2027,6 @@ static void riva128_vblank_poll(void *p) static uint8_t riva128_rma_in(uint16_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; addr &= 0xff; @@ -2097,7 +2061,7 @@ static uint8_t riva128_rma_in(uint16_t addr, void *p) static void riva128_rma_out(uint16_t addr, uint8_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + svga_t* svga = &riva128->svga; addr &= 0xff; @@ -2159,7 +2123,7 @@ static void riva128_rma_out(uint16_t addr, uint8_t val, void *p) static uint8_t riva128_in(uint16_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + svga_t* svga = &riva128->svga; uint8_t ret = 0; switch (addr) @@ -2288,7 +2252,6 @@ static void riva128_out(uint16_t addr, uint8_t val, void *p) static uint32_t riva128_ramin_readl(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; return ret; } @@ -2296,7 +2259,6 @@ static uint32_t riva128_ramin_readl(uint32_t addr, void *p) static uint8_t riva128_ramin_readb(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; ret >>= 24 - ((addr & 3) << 3); return ret; @@ -2305,7 +2267,6 @@ static uint8_t riva128_ramin_readb(uint32_t addr, void *p) static uint16_t riva128_ramin_readw(uint32_t addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint32_t ret = riva128->pramin[(addr & 0x1ffffc) >> 2]; ret >>= 16 - ((addr & 2) << 3); return ret; @@ -2314,14 +2275,11 @@ static uint16_t riva128_ramin_readw(uint32_t addr, void *p) static void riva128_ramin_writel(uint32_t addr, uint32_t val, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; riva128->pramin[(addr & 0x1ffffc) >> 2] = val; } static void riva128_ramin_writeb(uint32_t addr, uint8_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint32_t tmp = riva128_ramin_readl(addr,p); tmp &= ~(0xff << ((addr & 3) << 3)); tmp |= val << ((addr & 3) << 3); @@ -2330,8 +2288,6 @@ static void riva128_ramin_writeb(uint32_t addr, uint8_t val, void *p) static void riva128_ramin_writew(uint32_t addr, uint16_t val, void *p) { - riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint32_t tmp = riva128_ramin_readl(addr,p); tmp &= ~(0xffff << ((addr & 2) << 4)); tmp |= val << ((addr & 2) << 4); @@ -2341,7 +2297,6 @@ static void riva128_ramin_writew(uint32_t addr, uint16_t val, void *p) static uint8_t riva128_pci_read(int func, int addr, void *p) { riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; uint8_t ret = 0; //pclog("RIVA 128 PCI read %02X %04X:%08X\n", addr, CS, cpu_state.pc); switch (addr) @@ -2464,7 +2419,7 @@ static void riva128_pci_write(int func, int addr, uint8_t val, void *p) { //pclog("RIVA 128 PCI write %02X %02X %04X:%08X\n", addr, val, CS, cpu_state.pc); riva128_t *riva128 = (riva128_t *)p; - svga_t *svga = &riva128->svga; + svga_t* svga = &riva128->svga; switch (addr) { case 0x00: @@ -2984,7 +2939,7 @@ static device_config_t riva128_config[] = } }; -static device_config_t riva128zx_config[] = +/*static device_config_t riva128zx_config[] = { { .name = "memory", @@ -3069,7 +3024,7 @@ static device_config_t riva128zx_config[] = { .type = -1 } -}; +};*/ device_t riva128_device = { diff --git a/src/vid_svga.h b/src/vid_svga.h index dce4278be..7b440f931 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -127,6 +127,7 @@ extern int svga_init(svga_t *svga, void *p, int memsize, void (*hwcursor_draw)(struct svga_t *svga, int displine), void (*overlay_draw)(struct svga_t *svga, int displine)); extern void svga_recalctimings(svga_t *svga); +extern void svga_close(svga_t *svga); uint8_t svga_read(uint32_t addr, void *p); From b529a2062d53a4d8a3277b757d2947e460ef16b3 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sun, 30 Apr 2017 13:23:02 -0500 Subject: [PATCH 147/392] Fixed EVEN MOAR warnings --- src/ibm.h | 4 +- src/vid_nv_riva128.c | 115 ++++++++++++++++--------------------------- src/video.h | 2 +- 3 files changed, 45 insertions(+), 76 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index f2fd339cb..ec5737985 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -171,9 +171,9 @@ struct #define cycles cpu_state._cycles -#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; +//#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; -COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); +//COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); #define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 77fb7301c..dd692e035 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -492,11 +492,10 @@ static uint8_t riva128_pbus_read(uint32_t addr, void *p) case 0x001143: ret = (riva128->pbus.intr_en >> 24) & 0xff; break; - case 0x001800 ... 0x0018ff: - ret = riva128_pci_read(0, addr - 0x1800, riva128); - break; } + if((addr >= 0x001800) && (addr <= 0x0018ff)) ret = riva128_pci_read(0, addr - 0x1800, riva128); + return ret; } @@ -513,12 +512,14 @@ static void riva128_pbus_write(uint32_t addr, uint32_t val, void *p) case 0x001140: riva128->pbus.intr_en = val; break; - case 0x001800 ... 0x0018ff: + } + + if((addr >= 0x001800) && (addr <= 0x0018ff)) + { riva128_pci_write(0, (addr & 0xfc) + 0, (val >> 0) & 0xff, riva128); riva128_pci_write(0, (addr & 0xfc) + 1, (val >> 8) & 0xff, riva128); riva128_pci_write(0, (addr & 0xfc) + 2, (val >> 16) & 0xff, riva128); riva128_pci_write(0, (addr & 0xfc) + 3, (val >> 24) & 0xff, riva128); - break; } } @@ -1169,7 +1170,10 @@ static uint8_t riva128_pgraph_read(uint32_t addr, void *p) ret = (riva128->pgraph.ctx_user >> 24) & 0xff; break; - case 0x4001a0 ... 0x4001bf: + case 0x4001a0: case 0x4001a1: case 0x4001a2: case 0x4001a3: case 0x4001a4: case 0x4001a5: case 0x4001a6: case 0x4001a7: + case 0x4001a8: case 0x4001a9: case 0x4001aa: case 0x4001ab: case 0x4001ac: case 0x4001ad: case 0x4001ae: case 0x4001af: + case 0x4001b0: case 0x4001b1: case 0x4001b2: case 0x4001b3: case 0x4001b4: case 0x4001b5: case 0x4001b6: case 0x4001b7: + case 0x4001b8: case 0x4001b9: case 0x4001ba: case 0x4001bb: case 0x4001bc: case 0x4001bd: case 0x4001be: case 0x4001bf: ret = (riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] >> ((addr & 3) << 3)) & 0xff; break; @@ -1456,7 +1460,7 @@ static void riva128_pgraph_write(uint32_t addr, uint32_t val, void *p) case 0x400194: riva128->pgraph.ctx_user = val & 0x7f1fe000; break; - case 0x4001a0 ... 0x4001bc: + case 0x4001a0: case 0x4001a4: case 0x4001a8: case 0x4001ac: case 0x4001b0: case 0x4001b4: case 0x4001b8: case 0x4001bc: riva128->pgraph.ctx_cache[(addr & 0x1c) >> 2][0] = val & 0x3ff3f71f; break; case 0x40053c: @@ -1846,45 +1850,26 @@ static uint8_t riva128_mmio_read(uint32_t addr, void *p) && (addr <= 0x000003)) && !((addr <= 0x680fff) && (addr >= 0x680000)) && !((addr >= 0x0c0000) && (addr <= 0x0cffff)) && !((addr >= 0x110000) && (addr <= 0x11ffff)) && !(addr <= 0x000fff) && (addr >= 0x000000)) pclog("RIVA 128 MMIO read %08X %04X:%08X\n", addr, CS, cpu_state.pc); + if((addr >= 0x000000) && (addr <= 0x000fff)) ret = riva128_pmc_read(addr, riva128); + if((addr >= 0x001000) && (addr <= 0x001fff)) ret = riva128_pbus_read(addr, riva128); + if((addr >= 0x002000) && (addr <= 0x002fff)) ret = riva128_pfifo_read(addr, riva128); + if((addr >= 0x009000) && (addr <= 0x009fff)) ret = riva128_ptimer_read(addr, riva128); + if((addr >= 0x100000) && (addr <= 0x100fff)) ret = riva128_pfb_read(addr, riva128); + if((addr >= 0x101000) && (addr <= 0x101fff)) ret = riva128_pextdev_read(addr, riva128); + if((addr >= 0x110000) && (addr <= 0x11ffff) && (riva128->card_id == 0x03)) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; + if((addr >= 0x300000) && (addr <= 0x30ffff) && (riva128->card_id >= 0x04)) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; + if((addr >= 0x400000) && (addr <= 0x400fff)) ret = riva128_pgraph_read(addr, riva128); + if((addr >= 0x680000) && (addr <= 0x680fff)) ret = riva128_pramdac_read(addr, riva128); + switch(addr) { - case 0x000000 ... 0x000fff: - ret = riva128_pmc_read(addr, riva128); - break; - case 0x001000 ... 0x001fff: - ret = riva128_pbus_read(addr, riva128); - break; - case 0x002000 ... 0x002fff: - ret = riva128_pfifo_read(addr, riva128); - break; - case 0x009000 ... 0x009fff: - ret = riva128_ptimer_read(addr, riva128); - break; - case 0x100000 ... 0x100fff: - ret = riva128_pfb_read(addr, riva128); - break; - case 0x101000 ... 0x101fff: - ret = riva128_pextdev_read(addr, riva128); - break; - case 0x110000 ... 0x11ffff: - if(riva128->card_id == 0x03) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; - break; - case 0x300000 ... 0x30ffff: - if(riva128->card_id >= 0x04) ret = riva128->bios_rom.rom[addr & riva128->bios_rom.mask]; - break; - case 0x400000 ... 0x401fff: - ret = riva128_pgraph_read(addr, riva128); - break; - case 0x6013b4 ... 0x6013b5: - case 0x6013d4 ... 0x6013d5: + case 0x6013b4: case 0x6013b5: + case 0x6013d4: case 0x6013d5: case 0x6013da: - case 0x0c03c2 ... 0x0c03c5: - case 0x6813c6 ... 0x6813cc: + case 0x0c03c2: case 0x0c03c3: case 0x0c03c4: case 0x0c03c5: + case 0x6813c6: case 0x6813c7: case 0x6813c8: case 0x6813c9: case 0x6813ca: case 0x6813cb: case 0x6813cc: ret = riva128_in(addr & 0xfff, riva128); break; - case 0x680000 ... 0x680fff: - ret = riva128_pramdac_read(addr, riva128); - break; } return ret; } @@ -1939,42 +1924,28 @@ static void riva128_mmio_write_l(uint32_t addr, uint32_t val, void *p) //DO NOT REMOVE. This fixes a monstrous log blowup in win9x's drivers when accessing PFIFO. if(!((addr >= 0x002000) && (addr <= 0x003fff)) && !((addr >= 0xc0000) && (addr <= 0xcffff)) && (addr != 0x000140)) pclog("RIVA 128 MMIO write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + + if((addr >= 0x000000) && (addr <= 0x000fff)) riva128_pmc_write(addr, val, riva128); + if((addr >= 0x001000) && (addr <= 0x001fff)) riva128_pbus_write(addr, val, riva128); + if((addr >= 0x002000) && (addr <= 0x002fff)) riva128_pfifo_write(addr, val, riva128); + if((addr >= 0x009000) && (addr <= 0x009fff)) riva128_ptimer_write(addr, val, riva128); + if((addr >= 0x100000) && (addr <= 0x100fff)) riva128_pfb_write(addr, val, riva128); + if((addr >= 0x400000) && (addr <= 0x400fff)) riva128_pgraph_write(addr, val, riva128); + if((addr >= 0x680000) && (addr <= 0x680fff)) riva128_pramdac_write(addr, val, riva128); + if((addr >= 0x800000) && (addr <= 0xffffff)) riva128_user_write(addr, val, riva128); + switch(addr) { - case 0x000000 ... 0x000fff: - riva128_pmc_write(addr, val, riva128); - break; - case 0x001000 ... 0x001fff: - riva128_pbus_write(addr, val, riva128); - break; - case 0x002000 ... 0x002fff: - riva128_pfifo_write(addr, val, riva128); - break; - case 0x009000 ... 0x009fff: - riva128_ptimer_write(addr, val, riva128); - break; - case 0x6013b4 ... 0x6013b5: - case 0x6013d4 ... 0x6013d5: + case 0x6013b4: case 0x6013b5: + case 0x6013d4: case 0x6013d5: case 0x6013da: - case 0x0c03c2 ... 0x0c03c5: - case 0x6813c6 ... 0x6813cc: + case 0x0c03c2: case 0x0c03c3: case 0x0c03c4: case 0x0c03c5: + case 0x6813c6: case 0x6813c7: case 0x6813c8: case 0x6813c9: case 0x6813ca: case 0x6813cb: case 0x6813cc: riva128_out(addr & 0xfff, val & 0xff, p); riva128_out((addr+1) & 0xfff, (val>>8) & 0xff, p); riva128_out((addr+2) & 0xfff, (val>>16) & 0xff, p); riva128_out((addr+3) & 0xfff, (val>>24) & 0xff, p); break; - case 0x100000 ... 0x100fff: - riva128_pfb_write(addr, val, riva128); - break; - case 0x400000 ... 0x401fff: - riva128_pgraph_write(addr, val, riva128); - break; - case 0x680000 ... 0x680fff: - riva128_pramdac_write(addr, val, riva128); - break; - case 0x800000 ... 0xffffff: - riva128_user_write(addr, val, riva128); - break; } } @@ -2126,9 +2097,8 @@ static uint8_t riva128_in(uint16_t addr, void *p) svga_t* svga = &riva128->svga; uint8_t ret = 0; - switch (addr) + if((addr >= 0x3d0) && (addr <= 0x3d3)) { - case 0x3D0 ... 0x3D3: //pclog("RIVA 128 RMA BAR Register read %04X %04X:%08X\n", addr, CS, cpu_state.pc); if(!(riva128->rma.mode & 1)) return ret; ret = riva128_rma_in(riva128->rma_addr + ((riva128->rma.mode & 0xe) << 1) + (addr & 3), riva128); @@ -2175,9 +2145,8 @@ static void riva128_out(uint16_t addr, uint8_t val, void *p) uint8_t old; - switch(addr) + if((addr >= 0x3d0) && (addr <= 0x3d3)) { - case 0x3D0 ... 0x3D3: //pclog("RIVA 128 RMA BAR Register write %04X %02x %04X:%08X\n", addr, val, CS, cpu_state.pc); riva128->rma.access_reg[addr & 3] = val; if(!(riva128->rma.mode & 1)) return; diff --git a/src/video.h b/src/video.h index c01bb812b..dc11dfd2b 100644 --- a/src/video.h +++ b/src/video.h @@ -11,7 +11,7 @@ typedef struct { int w, h; uint8_t *dat; - uint8_t *line[0]; + uint8_t *line[]; } BITMAP; extern BITMAP *screen; From 03952f200630b04a4b4e20443ab5c7d69fd19f49 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Sun, 30 Apr 2017 13:46:35 -0500 Subject: [PATCH 148/392] Mostly make the code C90-compliant --- src/vid_nv_riva128.c | 400 ++++++++++++++++++------------------------- 1 file changed, 170 insertions(+), 230 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index dd692e035..4ca2d0fd7 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -986,21 +986,24 @@ static void rivatnt_pgraph_ctx_switch(void *p) { riva128_t *riva128 = (riva128_t *)p; - if(!(riva128->pgraph.fifo_st2_addr & 1)) return; - unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; unsigned new_subc = (riva128->pgraph.fifo_st2_addr >> 12) & 7; unsigned mthd = (riva128->pgraph.fifo_st2_addr >> 1) & 0x7ff; - riva128->pgraph.fifo_st2_addr &= ~1; unsigned do_ctx_switch = mthd == 0; + if(!(riva128->pgraph.fifo_st2_addr & 1)) return; + riva128->pgraph.fifo_st2_addr &= ~1; + if(old_subc != new_subc || do_ctx_switch) { - if(do_ctx_switch) riva128->pgraph.ctx_cache[new_subc][3] = riva128->pgraph.fifo_st2_data & 0xffff; - uint32_t ctx_mask = 0x0303f0ff; unsigned reload = (riva128->pgraph.debug[1] >> 15) & 1; + + unsigned reset = (riva128->pgraph.debug[2] >> 28) & 1; + + if(do_ctx_switch) riva128->pgraph.ctx_cache[new_subc][3] = riva128->pgraph.fifo_st2_data & 0xffff; + if(reload || do_ctx_switch) { uint32_t instance = riva128_ramht_lookup(riva128->pgraph.fifo_st2_data, riva128); @@ -1010,7 +1013,6 @@ static void rivatnt_pgraph_ctx_switch(void *p) riva128->pgraph.ctx_cache[new_subc][4] = riva128->pramin[(instance >> 2) + 3]; } - unsigned reset = (riva128->pgraph.debug[2] >> 28) & 1; if(reset) { riva128->pgraph.debug[1] |= 1; @@ -1020,7 +1022,8 @@ static void rivatnt_pgraph_ctx_switch(void *p) if(riva128->pgraph.debug[1] & 0x100000) { - for(int i = 0; i < 5; i++) riva128->pgraph.ctx_switch[i] = riva128->pgraph.ctx_cache[new_subc][i]; + int i; + for(i = 0; i < 5; i++) riva128->pgraph.ctx_switch[i] = riva128->pgraph.ctx_cache[new_subc][i]; } } } @@ -1688,8 +1691,6 @@ static void riva128_pramdac_write(uint32_t addr, uint32_t val, void *p) static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) { riva128_t *riva128 = (riva128_t *)p; - pclog("RIVA 128 RAMHT lookup with handle %08X %04X:%08X\n", handle, CS, cpu_state.pc); - uint32_t ramht_base = riva128->pfifo.ramht_addr; uint32_t tmp = handle; @@ -1697,6 +1698,8 @@ static uint32_t riva128_ramht_lookup(uint32_t handle, void *p) int bits; + pclog("RIVA 128 RAMHT lookup with handle %08X %04X:%08X\n", handle, CS, cpu_state.pc); + switch(riva128->pfifo.ramht_size) { case 4096: @@ -1728,9 +1731,10 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui if(riva128->card_id == 0x03) { uint32_t tmp = riva128_ramht_lookup(val, riva128); - riva128->pgraph.instance = (tmp & 0xffff) << 2; + unsigned new_class = (tmp >> 16) & 0x1f; unsigned old_subc = (riva128->pgraph.ctx_user >> 13) & 7; unsigned new_subc = subchanid & 7; + riva128->pgraph.instance = (tmp & 0xffff) << 2; if((old_subc != new_subc) || !offset) { uint32_t tmp_ctx = riva128->pramin[riva128->pgraph.instance]; @@ -1758,7 +1762,6 @@ static void riva128_puller_exec_method(int chanid, int subchanid, int offset, ui riva128->pgraph.fifo_enable = 0; } - unsigned new_class = (tmp >> 16) & 0x1f; if((riva128->pgraph.debug[1] & 0x10000) && ((riva128->pgraph.instance >> 4) != riva128->pgraph.ctx_switch[3]) && (new_class == 0x0d || new_class == 0x0e || new_class == 0x14 || new_class == 0x17 || offset == 0x0104)) { riva128->pgraph.ctx_switch[3] = riva128->pgraph.instance >> 4; @@ -1791,7 +1794,8 @@ static void riva128_pusher_run(int chanid, void *p) uint32_t method = cmd & 0x1ffc; int subchannel = (cmd >> 13) & 7; int method_count = (cmd >> 18) & 0x7ff; - for(int i = 0; i> 16) & 0xf; //int subchanid = (addr >> 13) & 0x7; int offset = addr & 0x1fff; + pclog("RIVA 128 USER write %08X %08X %04X:%08X\n", addr, val, CS, cpu_state.pc); + + addr -= 0x800000; + if(riva128->pfifo.chan_mode & (1 << chanid)) { //DMA mode, at least this has docs. @@ -1907,9 +1911,10 @@ static void riva128_mmio_write(uint32_t addr, uint8_t val, void *p) static void riva128_mmio_write_w(uint32_t addr, uint16_t val, void *p) { + uint32_t tmp; addr &= 0xffffff; //pclog("RIVA 128 MMIO write %08X %04X %04X:%08X\n", addr, val, CS, cpu_state.pc); - uint32_t tmp = riva128_mmio_read_l(addr,p); + tmp = riva128_mmio_read_l(addr,p); tmp &= ~(0xffff << ((addr & 2) << 4)); tmp |= val << ((addr & 2) << 4); riva128_mmio_write_l(addr, tmp, p); @@ -1954,13 +1959,15 @@ static void riva128_ptimer_tick(void *p) riva128_t *riva128 = (riva128_t *)p; double time = (double)riva128->ptimer.clock_mul / (double)riva128->ptimer.clock_div; + uint64_t tmp; + int alarm_check; time *= 10000; - uint64_t tmp = riva128->ptimer.time; + tmp = riva128->ptimer.time; riva128->ptimer.time += (uint64_t)time << 5; - int alarm_check = ((uint32_t)tmp < riva128->ptimer.alarm) || ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm); + alarm_check = ((uint32_t)tmp < riva128->ptimer.alarm) || ((uint32_t)riva128->ptimer.time >= riva128->ptimer.alarm); if(alarm_check) { @@ -2446,8 +2453,9 @@ static void riva128_pci_write(int func, int addr, uint8_t val, void *p) case 0x13: { + uint32_t mmio_addr; riva128->pci_regs[addr] = val; - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + mmio_addr = riva128->pci_regs[0x13] << 24; mem_mapping_disable(&riva128->mmio_mapping); if (mmio_addr) { @@ -2458,8 +2466,9 @@ static void riva128_pci_write(int func, int addr, uint8_t val, void *p) case 0x17: { + uint32_t linear_addr; riva128->pci_regs[addr] = val; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + linear_addr = riva128->pci_regs[0x17] << 24; mem_mapping_disable(&riva128->linear_mapping); mem_mapping_disable(&riva128->ramin_mapping); if (linear_addr) @@ -2557,8 +2566,9 @@ static void rivatnt_pci_write(int func, int addr, uint8_t val, void *p) case 0x13: { + uint32_t mmio_addr; riva128->pci_regs[addr] = val; - uint32_t mmio_addr = riva128->pci_regs[0x13] << 24; + mmio_addr = riva128->pci_regs[0x13] << 24; mem_mapping_disable(&riva128->mmio_mapping); if (mmio_addr) { @@ -2569,8 +2579,9 @@ static void rivatnt_pci_write(int func, int addr, uint8_t val, void *p) case 0x17: { + uint32_t linear_addr; riva128->pci_regs[addr] = val; - uint32_t linear_addr = riva128->pci_regs[0x17] << 24; + linear_addr = riva128->pci_regs[0x17] << 24; mem_mapping_disable(&riva128->linear_mapping); if (linear_addr) { @@ -2828,83 +2839,62 @@ static void riva128_add_status_info(char *s, int max_len, void *p) static device_config_t riva128_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, 4, { { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "" + "" } }, - .default_int = 4 }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 9", - .value = 9 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 12", - .value = 12 - }, - { - .description = "IRQ 14", - .value = 14 - }, - { - .description = "IRQ 15", - .value = 15 - }, - { - .description = "" - } - }, - .default_int = 3 - }, + "irq", "IRQ", CONFIG_SELECTION, "", 3, + { + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, { - .type = -1 + -1 } }; @@ -3134,83 +3124,62 @@ static void rivatnt_add_status_info(char *s, int max_len, void *p) static device_config_t rivatnt_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, 16, { { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "8 MB", - .value = 8 + "8 MB", 8 }, { - .description = "16 MB", - .value = 16 + "16 MB", 16 }, { - .description = "" + "" } }, - .default_int = 16 }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 9", - .value = 9 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 12", - .value = 12 - }, - { - .description = "IRQ 14", - .value = 14 - }, - { - .description = "IRQ 15", - .value = 15 - }, - { - .description = "" - } - }, - .default_int = 3 - }, { - .type = -1 + "irq", "IRQ", CONFIG_SELECTION, "", 3, + { + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + -1 } }; @@ -3366,108 +3335,79 @@ static void rivatnt2_add_status_info(char *s, int max_len, void *p) static device_config_t rivatnt2_config[] = { { - .name = "model", - .description = "Card model", - .type = CONFIG_SELECTION, - .selection = + "model", "Card model", CONFIG_SELECTION, 0, { { - .description = "Vanilla TNT2", - .value = 0, + "Vanilla TNT2", 0, }, { - .description = "TNT2 Pro", - .value = 1, + "TNT2 Pro", 1, }, { - .description = "TNT2 Ultra", - .value = 2, + "TNT2 Ultra", 2, }, }, - .default_int = 0 }, { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, 32, { { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "8 MB", - .value = 8 + "8 MB", 8 }, { - .description = "16 MB", - .value = 16 + "16 MB", 16 }, { - .description = "32 MB", - .value = 32 + "32 MB", 32 }, { - .description = "" + "" } }, - .default_int = 32 }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 3", - .value = 3 - }, - { - .description = "IRQ 4", - .value = 4 - }, - { - .description = "IRQ 5", - .value = 5 - }, - { - .description = "IRQ 7", - .value = 7 - }, - { - .description = "IRQ 9", - .value = 9 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 12", - .value = 12 - }, - { - .description = "IRQ 14", - .value = 14 - }, - { - .description = "IRQ 15", - .value = 15 - }, - { - .description = "" - } - }, - .default_int = 3 - }, { - .type = -1 + "irq", "IRQ", CONFIG_SELECTION, "", 3, + { + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + -1 } }; From 385478ba482dae60ade0b3d28bf15c5600ed3a77 Mon Sep 17 00:00:00 2001 From: slipstream/RoL Date: Mon, 1 May 2017 01:20:44 +0100 Subject: [PATCH 149/392] Fix build server link and image in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e0a3c23ac..9696756bf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# 86Box [![Build Status](http://polar.rol.im/job/86Box/badge/icon)](http://polar.rol.im/job/86Box) +# 86Box [![Build Status](http://dome.rol.im/job/86Box/badge/icon)](http://dome.rol.im/job/86Box) 86Box (formerly PCem Unofficial, PCem Experimental, or PCem-X) is an unofficial branch of the PCem emulator, which aims to emulate IBM compatible machines from 1981-2000 period. This branch adds several emulated motherboards. --- From f6ef1f833c37e398de922f5d1f18bc27ccd84bc8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 01:49:42 +0200 Subject: [PATCH 150/392] Vastly overhauled the UI, there's now a completely new Settings dialog as well as a status bar with disk activity icons and removable drive menus; Thoroughly clean up the code to vastly reduce the number of compiler warnings and found and fixed several bugs in the process; Applied all mainline PCem commits; Added SCSI hard disk emulation; Commented out all unfinished machines and graphics cards; Added the AOpen AP53 and ASUS P/I-P55T2 machines as well as another Tyan 440FX machine, all three with AMI WinBIOS (patch from TheCollector1995); Added the Diamond Stealth 3D 3000 (S3 ViRGE/VX) graphics card (patch from TheCollector1995); Added the PS/2 XT IDE (AccuLogic) HDD Controller (patch from TheCollector1995); Added Microsoft/Logitech Bus Mouse emulation (patch from waltje); Overhauled the makefiles (patch from waltje); Added the Adaptec AHA-1542CF SCSI controller (patch from waltje); Added preliminary (but still unfinished) Adaptec AHA-154x SCSI controller BIOS support (patch from waltje); Added an ISABugger debugging device (patch from waltje); Added sanity checks to the Direct3D code. --- src/386.c | 49 +- src/386_common.h | 44 +- src/386_dynarec.c | 192 +- src/386_dynarec_ops.c | 9 +- src/386_ops.h | 60 +- src/808x.c | 451 +-- src/86Box.manifest | 4 +- src/86Box.rc | 833 +++++ src/86box.h | 2 +- src/CMakeLists.txt | 59 - src/{ => ICONS}/86Box-RB.ico | Bin src/{ => ICONS}/86Box.ico | Bin src/ICONS/cdrom_atapi.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_active.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_dma.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_dma_active.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_dma_empty.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_dma_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_empty.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_atapi_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_disabled.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_scsi.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_scsi_active.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_scsi_empty.ico | Bin 0 -> 1150 bytes src/ICONS/cdrom_scsi_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_1dd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_1dd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_1dd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_1dd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2dd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2dd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2dd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2dd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2ed.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2ed_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2ed_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2ed_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2hd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2hd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2hd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_35_2hd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_1dd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_1dd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_1dd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_1dd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2dd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2dd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2dd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2dd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2hd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2hd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2hd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2hd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2qd.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2qd_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2qd_empty.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_525_2qd_empty_active.ico | Bin 0 -> 1150 bytes src/ICONS/floppy_disabled.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_active.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_ide.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_ide_active.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_scsi.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_scsi_active.ico | Bin 0 -> 1150 bytes src/ICONS/input_devices.ico | Bin 0 -> 1150 bytes src/ICONS/machine.ico | Bin 0 -> 1150 bytes src/ICONS/other_peripherals.ico | Bin 0 -> 1150 bytes src/ICONS/removable_devices.ico | Bin 0 -> 1150 bytes src/ICONS/sound.ico | Bin 0 -> 1150 bytes src/ICONS/video.ico | Bin 0 -> 1150 bytes src/Makefile.am | 51 - src/Makefile.in | 2956 ----------------- src/Makefile.mingw | 227 +- src/Makefile.mingw64 | 227 +- src/ali1429.c | 3 - src/ali1429.h | 1 + src/amstrad.c | 10 +- src/bswap.h | 115 +- src/bugger.c | 325 ++ src/bugger.h | 37 + src/buslogic.c | 2643 --------------- src/buslogic.h | 28 +- src/cdrom-ioctl.c | 806 ++--- src/cdrom-iso.c | 70 +- src/cdrom-null.c | 5 - src/cdrom-null.h | 12 +- src/cdrom.c | 918 ++++- src/cdrom.h | 18 + src/codegen.h | 14 +- src/codegen_ops_arith.h | 8 +- src/codegen_ops_fpu.h | 66 +- src/codegen_ops_jump.h | 20 +- src/codegen_ops_misc.h | 12 +- src/codegen_ops_mmx.h | 36 +- src/codegen_ops_mov.h | 12 +- src/codegen_ops_stack.h | 16 +- src/codegen_ops_x86.h | 48 +- src/codegen_ops_xchg.h | 8 +- src/codegen_timing_486.c | 2 +- src/codegen_timing_686.c | 22 +- src/codegen_timing_pentium.c | 21 +- src/codegen_timing_winchip.c | 2 +- src/codegen_x86.c | 106 +- src/config.c | 7 +- src/cpu.c | 40 +- src/cpu.h | 2 +- src/dac.c | 3 +- src/dac.h | 2 + src/device.c | 2 + src/device.h | 5 +- src/disc.c | 18 +- src/disc.h | 3 +- src/disc_86f.c | 297 +- src/disc_fdi.c | 18 +- src/disc_imd.c | 73 +- src/disc_img.c | 191 +- src/disc_random.c | 12 +- src/disc_td0.c | 63 +- src/dma.c | 819 ++--- src/dma.h | 10 +- src/dosbox/vid_cga_comp.c | 98 +- src/fdc.c | 214 +- src/fdc.h | 4 + src/fdc37c665.c | 280 +- src/fdc37c669.c | 335 ++ src/fdc37c669.h | 1 + src/fdc37c932fr.c | 6 - src/fdd.c | 114 +- src/fdd.h | 7 +- src/fdi2raw.c | 28 +- src/fdi2raw.h | 1 - src/filters.h | 88 +- src/gameport.c | 27 +- src/hdd.c | 7 + src/hdd_esdi.c | 899 +++++ src/hdd_esdi.h | 1 + src/headland.c | 1 - src/i430hx.c | 3 - src/ibm.h | 184 +- src/ide.c | 325 +- src/ide.h | 17 +- src/intel.c | 22 +- src/intel_flash.c | 43 +- src/intel_flash.h | 1 + src/io.c | 18 +- src/jim.c | 4 - src/joystick_ch_flightstick_pro.c | 31 +- src/joystick_standard.c | 109 +- src/joystick_sw_pad.c | 28 +- src/joystick_tm_fcs.c | 31 +- src/keyboard.c | 1 - src/keyboard_amstrad.c | 9 +- src/keyboard_at.c | 137 +- src/keyboard_at.h | 2 + src/keyboard_olim24.c | 31 +- src/keyboard_pcjr.c | 21 +- src/keyboard_xt.c | 18 +- src/libwpcapdelay.a | Bin 0 -> 88406 bytes src/lpt.c | 11 +- src/mca.c | 64 + src/mca.h | 5 + src/mcr.c | 6 - src/mem.c | 309 +- src/mem.h | 26 +- src/memregs.h | 1 + src/mfm_at.c | 68 +- src/mfm_xebec.c | 950 ++++++ src/mfm_xebec.h | 2 + src/model.c | 373 ++- src/model.h | 21 +- src/mouse.c | 104 +- src/mouse.h | 54 +- src/mouse_bus.c | 444 +++ src/mouse_bus.h | 34 + src/mouse_ps2.c | 19 +- src/mouse_ps2.h | 2 + src/mouse_serial.c | 169 +- src/ne2000.c | 930 +++--- src/ne2000.h | 5 + src/nethandler.c | 76 +- src/nethandler.h | 2 +- src/nmi.c | 1 + src/nvr.c | 24 +- src/nvr.h | 4 + src/opti495.c | 4 - src/pc.c | 530 ++- src/pc.rc | 713 ---- src/pc87306.c | 44 +- src/pci.c | 25 +- src/pic.c | 32 +- src/pic.h | 1 + src/piix.c | 34 +- src/piix.h | 7 + src/pit.c | 575 ++-- src/pit.h | 11 +- src/plat-midi.h | 2 + src/ppi.c | 2 +- src/ps1.c | 2 + src/ps2.c | 2 + src/ps2_mca.c | 796 +++++ src/ps2_mca.h | 3 + src/ps2_nvr.c | 100 + src/ps2_nvr.h | 1 + src/resource.h | 425 +++ src/resources.h | 399 --- src/rom.c | 25 +- src/rtc.c | 5 +- src/rtc.h | 38 +- src/scat.c | 18 +- src/scsi.c | 102 +- src/scsi.h | 29 +- src/scsi_aha154x.c | 407 +++ src/scsi_buslogic.c | 2800 ++++++++++++++++ src/scsi_buslogic.h | 27 + src/scsi_hd.c | 1164 +++++++ src/serial.c | 15 +- src/serial.h | 3 + src/serial_bh.c | 606 ++++ src/serial_bh.h | 53 + src/sio.c | 75 +- src/sis496.c | 1 - src/sis85c471.c | 6 - src/slirp/debug.h | 1 - src/slirp/misc.c | 4 +- src/slirp/queue.h | 2 + src/slirp/slirp.h | 12 +- src/sound.c | 12 +- src/sound.h | 10 + src/sound_ad1848.c | 10 +- src/sound_ad1848.h | 2 + src/sound_adlib.c | 58 + src/sound_adlib.h | 1 + src/sound_adlibgold.c | 21 +- src/sound_emu8k.c | 31 +- src/sound_gus.c | 102 +- src/sound_mpu401_uart.c | 1 + src/sound_pas16.c | 24 +- src/sound_ps1.c | 11 +- src/sound_pssj.c | 8 +- src/sound_sb.c | 555 ++-- src/sound_sb.h | 2 + src/sound_sb_dsp.c | 46 - src/sound_sn76489.c | 3 +- src/sound_speaker.c | 1 - src/sound_ssi2001.c | 1 + src/sound_wss.c | 7 +- src/sound_ym7128.c | 10 - src/soundopenal.c | 134 +- src/tandy_eeprom.c | 6 +- src/tandy_rom.c | 8 +- src/timer.c | 5 +- src/um8669f.c | 25 +- src/usb.c | 4 +- src/vid_ati18800.c | 4 - src/vid_ati28800.c | 52 +- src/vid_ati68860_ramdac.c | 2 - src/vid_ati_eeprom.c | 11 - src/vid_ati_mach64.c | 1095 ++++-- src/vid_ati_mach64.h | 1 + src/vid_cga.c | 71 +- src/vid_cl_gd.c | 3 + src/vid_cl_gd_blit.c | 18 +- src/vid_cl_gd_blit.h | 2 - src/vid_cl_gd_vga_rop.h | 6 +- src/vid_colorplus.c | 47 +- src/vid_ega.c | 68 +- src/vid_ega.h | 3 + src/vid_et4000.c | 12 +- src/vid_et4000w32.c | 90 +- src/vid_genius.c | 629 ++++ src/vid_genius.h | 1 + src/vid_hercules.c | 32 +- src/vid_herculesplus.c | 28 +- src/vid_icd2061.c | 9 +- src/vid_ics2595.c | 4 - src/vid_incolor.c | 150 +- src/vid_mda.c | 37 +- src/vid_nv_riva128.c | 3 +- src/vid_olivetti_m24.c | 8 - src/vid_oti067.c | 58 +- src/vid_paradise.c | 15 +- src/vid_paradise.h | 1 - src/vid_pc1512.c | 17 +- src/vid_pcjr.c | 75 +- src/vid_ps1_svga.c | 6 - src/vid_s3.c | 676 +--- src/vid_s3.h | 4 +- src/vid_s3_virge.c | 383 ++- src/vid_s3_virge.h | 1 + src/vid_sdac_ramdac.c | 22 +- src/vid_stg_ramdac.c | 12 +- src/vid_svga.c | 90 +- src/vid_svga.h | 12 +- src/vid_svga_render.c | 4 - src/vid_tandy.c | 74 +- src/vid_tandysl.c | 44 +- src/vid_tgui9440.c | 91 +- src/vid_tkd8001_ramdac.c | 7 - src/vid_tvga.c | 34 +- src/vid_unk_ramdac.c | 3 - src/vid_vga.c | 15 +- src/vid_vga.h | 1 - src/vid_voodoo.c | 310 +- src/vid_voodoo_codegen_x86.h | 68 +- src/vid_wy700.c | 13 +- src/video.c | 39 +- src/video.h | 9 + src/w83877f.c | 22 - src/win-cgapal.h | 1 + src/win-config.c | 923 ------ src/win-d3d-fs.cc | 22 +- src/win-d3d.cc | 31 +- src/win-ddraw-fs.cc | 18 +- src/win-ddraw-screenshot.cc | 2 +- src/win-ddraw.cc | 26 +- src/win-deviceconfig.c | 51 +- src/win-hdconf.c | 664 ---- src/win-joystick.cc | 1 - src/win-joystickconfig.c | 78 +- src/win-language.c | 179 + src/win-language.h | 19 + src/win-midi.c | 7 +- src/win-settings.c | 3502 ++++++++++++++++++++ src/win-status.c | 26 +- src/win-video.c | 1 + src/win.c | 1588 +++++---- src/win.h | 20 +- src/x86_flags.h | 87 +- src/x86_ops_arith.h | 60 +- src/x86_ops_bitscan.h | 17 +- src/x86_ops_call.h | 4 - src/x86_ops_i686.h | 32 +- src/x86_ops_int.h | 46 +- src/x86_ops_io.h | 1 - src/x86_ops_jump.h | 20 +- src/x86_ops_misc.h | 45 +- src/x86_ops_mov.h | 32 +- src/x86_ops_pmode.h | 28 +- src/x86_ops_shift.h | 28 +- src/x86_ops_stack.h | 47 +- src/x86seg.c | 361 +- src/x87.c | 10 - src/x87.h | 3 - src/x87_ops.h | 676 ++-- src/xtide.c | 39 +- src/xtide.h | 1 + 346 files changed, 24292 insertions(+), 18058 deletions(-) create mode 100644 src/86Box.rc delete mode 100644 src/CMakeLists.txt rename src/{ => ICONS}/86Box-RB.ico (100%) rename src/{ => ICONS}/86Box.ico (100%) create mode 100644 src/ICONS/cdrom_atapi.ico create mode 100644 src/ICONS/cdrom_atapi_active.ico create mode 100644 src/ICONS/cdrom_atapi_dma.ico create mode 100644 src/ICONS/cdrom_atapi_dma_active.ico create mode 100644 src/ICONS/cdrom_atapi_dma_empty.ico create mode 100644 src/ICONS/cdrom_atapi_dma_empty_active.ico create mode 100644 src/ICONS/cdrom_atapi_empty.ico create mode 100644 src/ICONS/cdrom_atapi_empty_active.ico create mode 100644 src/ICONS/cdrom_disabled.ico create mode 100644 src/ICONS/cdrom_scsi.ico create mode 100644 src/ICONS/cdrom_scsi_active.ico create mode 100644 src/ICONS/cdrom_scsi_empty.ico create mode 100644 src/ICONS/cdrom_scsi_empty_active.ico create mode 100644 src/ICONS/floppy_35_1dd.ico create mode 100644 src/ICONS/floppy_35_1dd_active.ico create mode 100644 src/ICONS/floppy_35_1dd_empty.ico create mode 100644 src/ICONS/floppy_35_1dd_empty_active.ico create mode 100644 src/ICONS/floppy_35_2dd.ico create mode 100644 src/ICONS/floppy_35_2dd_active.ico create mode 100644 src/ICONS/floppy_35_2dd_empty.ico create mode 100644 src/ICONS/floppy_35_2dd_empty_active.ico create mode 100644 src/ICONS/floppy_35_2ed.ico create mode 100644 src/ICONS/floppy_35_2ed_active.ico create mode 100644 src/ICONS/floppy_35_2ed_empty.ico create mode 100644 src/ICONS/floppy_35_2ed_empty_active.ico create mode 100644 src/ICONS/floppy_35_2hd.ico create mode 100644 src/ICONS/floppy_35_2hd_active.ico create mode 100644 src/ICONS/floppy_35_2hd_empty.ico create mode 100644 src/ICONS/floppy_35_2hd_empty_active.ico create mode 100644 src/ICONS/floppy_525_1dd.ico create mode 100644 src/ICONS/floppy_525_1dd_active.ico create mode 100644 src/ICONS/floppy_525_1dd_empty.ico create mode 100644 src/ICONS/floppy_525_1dd_empty_active.ico create mode 100644 src/ICONS/floppy_525_2dd.ico create mode 100644 src/ICONS/floppy_525_2dd_active.ico create mode 100644 src/ICONS/floppy_525_2dd_empty.ico create mode 100644 src/ICONS/floppy_525_2dd_empty_active.ico create mode 100644 src/ICONS/floppy_525_2hd.ico create mode 100644 src/ICONS/floppy_525_2hd_active.ico create mode 100644 src/ICONS/floppy_525_2hd_empty.ico create mode 100644 src/ICONS/floppy_525_2hd_empty_active.ico create mode 100644 src/ICONS/floppy_525_2qd.ico create mode 100644 src/ICONS/floppy_525_2qd_active.ico create mode 100644 src/ICONS/floppy_525_2qd_empty.ico create mode 100644 src/ICONS/floppy_525_2qd_empty_active.ico create mode 100644 src/ICONS/floppy_disabled.ico create mode 100644 src/ICONS/hard_disk.ico create mode 100644 src/ICONS/hard_disk_active.ico create mode 100644 src/ICONS/hard_disk_ide.ico create mode 100644 src/ICONS/hard_disk_ide_active.ico create mode 100644 src/ICONS/hard_disk_scsi.ico create mode 100644 src/ICONS/hard_disk_scsi_active.ico create mode 100644 src/ICONS/input_devices.ico create mode 100644 src/ICONS/machine.ico create mode 100644 src/ICONS/other_peripherals.ico create mode 100644 src/ICONS/removable_devices.ico create mode 100644 src/ICONS/sound.ico create mode 100644 src/ICONS/video.ico delete mode 100644 src/Makefile.am delete mode 100644 src/Makefile.in create mode 100644 src/bugger.c create mode 100644 src/bugger.h delete mode 100644 src/buslogic.c create mode 100644 src/dac.h create mode 100644 src/fdc37c669.c create mode 100644 src/fdc37c669.h create mode 100644 src/hdd_esdi.c create mode 100644 src/hdd_esdi.h create mode 100644 src/libwpcapdelay.a create mode 100644 src/mca.c create mode 100644 src/mca.h create mode 100644 src/mfm_xebec.c create mode 100644 src/mfm_xebec.h create mode 100644 src/mouse_bus.c create mode 100644 src/mouse_bus.h delete mode 100644 src/pc.rc create mode 100644 src/ps2_mca.c create mode 100644 src/ps2_mca.h create mode 100644 src/ps2_nvr.c create mode 100644 src/ps2_nvr.h create mode 100644 src/resource.h delete mode 100644 src/resources.h create mode 100644 src/scsi_aha154x.c create mode 100644 src/scsi_buslogic.c create mode 100644 src/scsi_buslogic.h create mode 100644 src/scsi_hd.c create mode 100644 src/serial_bh.c create mode 100644 src/serial_bh.h create mode 100644 src/vid_genius.c create mode 100644 src/vid_genius.h delete mode 100644 src/win-config.c delete mode 100644 src/win-hdconf.c create mode 100644 src/win-language.c create mode 100644 src/win-language.h create mode 100644 src/win-settings.c diff --git a/src/386.c b/src/386.c index 2029c1afd..256a1ce88 100644 --- a/src/386.c +++ b/src/386.c @@ -1,3 +1,7 @@ +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif #include #include #include @@ -8,6 +12,7 @@ #include "cpu.h" #include "disc.h" #include "fdc.h" +#include "pic.h" #include "timer.h" #include "386_common.h" @@ -56,7 +61,7 @@ uint32_t *eal_r, *eal_w; uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; -static inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -74,7 +79,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) case 1: cpu_state.pc++; cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; -// pc++; + /* pc++; */ break; case 2: cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; @@ -129,7 +134,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) } } -static inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void fetch_ea_16_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -215,22 +220,23 @@ void exec386(int cycs) int tempi; int cycdiff; int oldcyc; + int cycle_period = cycs / 2000; /*Use a 5us timing granularity*/ cycles+=cycs; -// output=3; + /* output=3; */ while (cycles>0) { cycdiff=0; oldcyc=cycles; timer_start_period(cycles << TIMER_SHIFT); -// pclog("%i %02X\n", ins, ram[8]); - while (cycdiff<100) + /* pclog("%i %02X\n", ins, ram[8]); */ + while (cycdiff < cycle_period) { /* testr[0]=EAX; testr[1]=EBX; testr[2]=ECX; testr[3]=EDX; testr[4]=ESI; testr[5]=EDI; testr[6]=EBP; testr[7]=ESP;*/ /* testr[8]=flags;*/ -// oldcs2=oldcs; -// oldpc2=oldpc; + /* oldcs2=oldcs; */ + /* oldpc2=oldpc; */ oldcs=CS; cpu_state.oldpc = cpu_state.pc; oldcpl=CPL; @@ -262,8 +268,8 @@ dontprint=0; if (cpu_state.abrt) { flags_rebuild(); -// pclog("Abort\n"); -// if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,cpu_state.abrt); + /* pclog("Abort\n"); */ + /* if (CS == 0x228) pclog("Abort at %04X:%04X - %i %i %i\n",CS,pc,notpresent,nullseg,cpu_state.abrt); */ /* if (testr[0]!=EAX) pclog("EAX corrupted %08X\n",pc); if (testr[1]!=EBX) pclog("EBX corrupted %08X\n",pc); if (testr[2]!=ECX) pclog("ECX corrupted %08X\n",pc); @@ -297,8 +303,8 @@ dontprint=0; if (trap) { flags_rebuild(); -// oldpc=pc; -// oldcs=CS; + /* oldpc=pc; */ + /* oldcs=CS; */ if (msw&1) { pmodeint(1,0); @@ -320,19 +326,24 @@ dontprint=0; { cpu_state.oldpc = cpu_state.pc; oldcs = CS; -// pclog("NMI\n"); + /* pclog("NMI\n"); */ x86_int(2); nmi_enable = 0; + if (nmi_auto_clear) + { + nmi_auto_clear = 0; + nmi = 0; + } } else if ((flags&I_FLAG) && pic_intpending) { temp=picinterrupt(); if (temp!=0xFF) { -// if (temp == 0x54) pclog("Take int 54\n"); -// if (output) output=3; -// if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); -// if (temp==0x54) output=3; + /* if (temp == 0x54) pclog("Take int 54\n"); */ + /* if (output) output=3; */ + /* if (temp == 0xd) pclog("Hardware int %02X %i %04X(%08X):%08X\n",temp,ins, CS,cs,pc); */ + /* if (temp==0x54) output=3; */ flags_rebuild(); if (msw&1) { @@ -350,9 +361,9 @@ dontprint=0; oxpc=cpu_state.pc; cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); -// if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); + /* if (temp==0x76) pclog("INT to %04X:%04X\n",CS,pc); */ } -// pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); + /* pclog("Now at %04X(%08X):%08X\n", CS, cs, pc); */ } } diff --git a/src/386_common.h b/src/386_common.h index d1350f55d..a091a817d 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -64,7 +64,7 @@ extern uint16_t ea_rseg; } #define CHECK_READ(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high)) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || ((msw & 1) && !(eflags & VM_FLAG) && (((chseg)->access & 10) == 8))) \ { \ x86gpf("Limit check", 0); \ return 1; \ @@ -79,7 +79,7 @@ extern uint16_t ea_rseg; } #define CHECK_WRITE(chseg, low, high) \ - if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2)) \ + if ((low < (chseg)->limit_low) || (high > (chseg)->limit_high) || !((chseg)->access & 2) || ((msw & 1) && !(eflags & VM_FLAG) && ((chseg)->access & 8))) \ { \ x86gpf("Limit check", 0); \ return 1; \ @@ -118,7 +118,7 @@ extern uint16_t ea_rseg; -static inline uint8_t fastreadb(uint32_t a) +static __inline uint8_t fastreadb(uint32_t a) { uint8_t *t; @@ -126,13 +126,13 @@ static inline uint8_t fastreadb(uint32_t a) return *((uint8_t *)&pccache2[a]); t = getpccache(a); if (cpu_state.abrt) - return; + return 0xFF; pccache = a >> 12; pccache2 = t; return *((uint8_t *)&pccache2[a]); } -static inline uint16_t fastreadw(uint32_t a) +static __inline uint16_t fastreadw(uint32_t a) { uint8_t *t; uint16_t val; @@ -145,14 +145,14 @@ static inline uint16_t fastreadw(uint32_t a) if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); t = getpccache(a); if (cpu_state.abrt) - return; + return 0xff; pccache = a >> 12; pccache2 = t; return *((uint16_t *)&pccache2[a]); } -static inline uint32_t fastreadl(uint32_t a) +static __inline uint32_t fastreadl(uint32_t a) { uint8_t *t; uint32_t val; @@ -165,7 +165,7 @@ static inline uint32_t fastreadl(uint32_t a) return 0; pccache2 = t; pccache=a>>12; - //return *((uint32_t *)&pccache2[a]); + /* return *((uint32_t *)&pccache2[a]); */ } return *((uint32_t *)&pccache2[a]); } @@ -176,25 +176,25 @@ static inline uint32_t fastreadl(uint32_t a) return val; } -static inline uint8_t getbyte() +static __inline uint8_t getbyte() { cpu_state.pc++; return fastreadb(cs + (cpu_state.pc - 1)); } -static inline uint16_t getword() +static __inline uint16_t getword() { cpu_state.pc+=2; return fastreadw(cs+(cpu_state.pc-2)); } -static inline uint32_t getlong() +static __inline uint32_t getlong() { cpu_state.pc+=4; return fastreadl(cs+(cpu_state.pc-4)); } -static inline uint64_t getquad() +static __inline uint64_t getquad() { cpu_state.pc+=8; return fastreadl(cs+(cpu_state.pc-8)) | ((uint64_t)fastreadl(cs+(cpu_state.pc-4)) << 32); @@ -202,7 +202,7 @@ static inline uint64_t getquad() -static inline uint8_t geteab() +static __inline uint8_t geteab() { if (cpu_mod == 3) return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm&3].b.l; @@ -211,48 +211,48 @@ static inline uint8_t geteab() return readmemb(easeg, cpu_state.eaaddr); } -static inline uint16_t geteaw() +static __inline uint16_t geteaw() { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].w; -// cycles-=3; + /* cycles-=3; */ if (eal_r) return *(uint16_t *)eal_r; return readmemw(easeg, cpu_state.eaaddr); } -static inline uint32_t geteal() +static __inline uint32_t geteal() { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].l; -// cycles-=3; + /* cycles-=3; */ if (eal_r) return *eal_r; return readmeml(easeg, cpu_state.eaaddr); } -static inline uint64_t geteaq() +static __inline uint64_t geteaq() { return readmemq(easeg, cpu_state.eaaddr); } -static inline uint8_t geteab_mem() +static __inline uint8_t geteab_mem() { if (eal_r) return *(uint8_t *)eal_r; return readmemb(easeg,cpu_state.eaaddr); } -static inline uint16_t geteaw_mem() +static __inline uint16_t geteaw_mem() { if (eal_r) return *(uint16_t *)eal_r; return readmemw(easeg,cpu_state.eaaddr); } -static inline uint32_t geteal_mem() +static __inline uint32_t geteal_mem() { if (eal_r) return *eal_r; return readmeml(easeg,cpu_state.eaaddr); } -static inline void seteaq(uint64_t v) +static __inline void seteaq(uint64_t v) { writememql(easeg, cpu_state.eaaddr, v); } diff --git a/src/386_dynarec.c b/src/386_dynarec.c index 4fd3555f9..69a3df8a8 100644 --- a/src/386_dynarec.c +++ b/src/386_dynarec.c @@ -1,3 +1,7 @@ +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif #include #include #include @@ -10,6 +14,7 @@ #include "cpu.h" #include "disc.h" #include "fdc.h" +#include "pic.h" #include "timer.h" #include "386_common.h" @@ -62,7 +67,7 @@ uint32_t *eal_r, *eal_w; uint16_t *mod1add[2][8]; uint32_t *mod1seg[8]; -static inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -80,7 +85,6 @@ static inline void fetch_ea_32_long(uint32_t rmdat) case 1: cpu_state.pc++; cpu_state.eaaddr = ((uint32_t)(int8_t)getbyte()) + cpu_state.regs[sib & 7].l; -// cpu_state.pc++; break; case 2: cpu_state.eaaddr = (fastreadl(cs + cpu_state.pc + 1)) + cpu_state.regs[sib & 7].l; @@ -136,7 +140,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) cpu_state.last_ea = cpu_state.eaaddr; } -static inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void fetch_ea_16_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -187,7 +191,6 @@ static inline void fetch_ea_16_long(uint32_t rmdat) void x86_int(int num) { uint32_t addr; -// pclog("x86_int %02x %04x:%04x\n", num, CS,pc); flags_rebuild(); cpu_state.pc=cpu_state.oldpc; if (msw&1) @@ -225,8 +228,6 @@ void x86_int(int num) void x86_int_sw(int num) { uint32_t addr; -// pclog("x86_int_sw %02x %04x:%04x\n", num, CS,pc); -// pclog("x86_int\n"); flags_rebuild(); cycles -= timing_int; if (msw&1) @@ -264,14 +265,6 @@ void x86_int_sw(int num) void x86illegal() { - uint16_t addr; -// pclog("x86 illegal %04X %08X %04X:%08X %02X\n",msw,cr0,CS,pc,opcode); - -// if (output) -// { -// dumpregs(); -// exit(-1); -// } x86_int(6); } @@ -359,14 +352,28 @@ static void prefetch_flush() #define PREFETCH_FLUSH() prefetch_flush() +int checkio(int port) +{ + uint16_t t; + uint8_t d; + cpl_override = 1; + t = readmemw(tr.base, 0x66); + cpl_override = 0; + if (cpu_state.abrt) return 0; + if ((t+(port>>3))>tr.limit) return 1; + cpl_override = 1; + d = readmemb386l(0, tr.base + t + (port >> 3)); + cpl_override = 0; + return d&(1<<(port&7)); +} + int rep386(int fv) { uint8_t temp; - uint32_t c;//=CX; + uint32_t c; uint8_t temp2; uint16_t tempw,tempw2,of; - uint32_t ipc = cpu_state.oldpc;//pc-1; - uint32_t oldds; + uint32_t ipc = cpu_state.oldpc; uint32_t rep32 = cpu_state.op32; uint32_t templ,templ2; int tempz; @@ -384,16 +391,9 @@ int rep386(int fv) flags_rebuild(); of = flags; -// if (inrecomp) pclog("REP32 %04X %04X ",use32,rep32); startrep: temp=opcode2=readmemb(cs,cpu_state.pc); cpu_state.pc++; -// if (firstrepcycle && temp==0xA5) pclog("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); -// if (inrecomp) pclog("REP %02X %04X\n",temp,ipc); c=(rep32&0x200)?ECX:CX; -/* if (rep32 && (msw&1)) - { - if (temp!=0x67 && temp!=0x66 && (rep32|temp)!=0x1AB && (rep32|temp)!=0x3AB) pclog("32-bit REP %03X %08X %04X:%06X\n",temp|rep32,c,CS,pc); - }*/ switch (temp|rep32) { case 0xC3: case 0x1C3: case 0x2C3: case 0x3C3: @@ -436,7 +436,6 @@ int rep386(int fv) PREFETCH_PREFIX(); goto startrep; case 0x6C: case 0x16C: /*REP INSB*/ -// cpu_notreps++; if (c>0) { checkio_perm(DX); @@ -453,7 +452,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x26C: case 0x36C: /*REP INSB*/ -// cpu_notreps++; if (c>0) { checkio_perm(DX); @@ -470,10 +468,8 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x6D: /*REP INSW*/ -// cpu_notreps++; if (c>0) { -// pclog("REP INSW %04x %04x:%04x %04x\n", DX, ES, DI, CX); tempw=inw(DX); writememw(es,DI,tempw); if (cpu_state.abrt) break; @@ -487,7 +483,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x16D: /*REP INSL*/ -// cpu_notreps++; if (c>0) { templ=inl(DX); @@ -503,7 +498,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x26D: /*REP INSW*/ -// cpu_notreps++; if (c>0) { tempw=inw(DX); @@ -519,7 +513,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x36D: /*REP INSL*/ -// cpu_notreps++; if (c>0) { templ=inl(DX); @@ -535,7 +528,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x6E: case 0x16E: /*REP OUTSB*/ -// cpu_notreps++; if (c>0) { temp2 = readmemb(cpu_state.ea_seg->base, SI); @@ -552,7 +544,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x26E: case 0x36E: /*REP OUTSB*/ -// cpu_notreps++; if (c>0) { temp2 = readmemb(cpu_state.ea_seg->base, ESI); @@ -569,12 +560,10 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x6F: /*REP OUTSW*/ -// cpu_notreps++; if (c>0) { tempw = readmemw(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break; -// pclog("OUTSW %04X -> %04X\n",SI,tempw); outw(DX,tempw); if (flags&D_FLAG) SI-=2; else SI+=2; @@ -586,7 +575,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x16F: /*REP OUTSL*/ -// cpu_notreps++; if (c > 0) { templ = readmeml(cpu_state.ea_seg->base, SI); @@ -602,7 +590,6 @@ int rep386(int fv) else firstrepcycle = 1; break; case 0x26F: /*REP OUTSW*/ -// cpu_notreps++; if (c>0) { tempw = readmemw(cpu_state.ea_seg->base, ESI); @@ -618,7 +605,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x36F: /*REP OUTSL*/ -// cpu_notreps++; if (c > 0) { templ = readmeml(cpu_state.ea_seg->base, ESI); @@ -635,7 +621,6 @@ int rep386(int fv) break; case 0x90: case 0x190: /*REP NOP*/ case 0x290: case 0x390: -// cpu_notreps++; break; case 0xA4: case 0x1A4: /*REP MOVSB*/ while (c > 0) @@ -643,7 +628,6 @@ int rep386(int fv) CHECK_WRITE_REP(&_es, DI, DI); temp2 = readmemb(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break; writememb(es,DI,temp2); if (cpu_state.abrt) break; -// if (output==3) pclog("MOVSB %08X:%04X -> %08X:%04X %02X\n",ds,SI,es,DI,temp2); if (flags&D_FLAG) { DI--; SI--; } else { DI++; SI++; } c--; @@ -700,7 +684,6 @@ int rep386(int fv) { CHECK_WRITE_REP(&_es, DI, DI+3); templ = readmeml(cpu_state.ea_seg->base, SI); if (cpu_state.abrt) break; -// pclog("MOVSD %08X from %08X to %08X (%04X:%08X)\n", templ, ds+SI, es+DI, CS, pc); writememl(es,DI,templ); if (cpu_state.abrt) break; if (flags&D_FLAG) { DI-=4; SI-=4; } else { DI+=4; SI+=4; } @@ -721,7 +704,6 @@ int rep386(int fv) CHECK_WRITE_REP(&_es, EDI, EDI+1); tempw = readmemw(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break; writememw(es,EDI,tempw); if (cpu_state.abrt) break; -// if (output) pclog("Written %04X from %08X to %08X %i %08X %04X %08X %04X\n",tempw,ds+ESI,es+EDI,c,ds,ES,es,ES); if (flags&D_FLAG) { EDI-=2; ESI-=2; } else { EDI+=2; ESI+=2; } c--; @@ -740,9 +722,7 @@ int rep386(int fv) { CHECK_WRITE_REP(&_es, EDI, EDI+3); templ = readmeml(cpu_state.ea_seg->base, ESI); if (cpu_state.abrt) break; -// if ((EDI&0xFFFF0000)==0xA0000) cycles-=12; writememl(es,EDI,templ); if (cpu_state.abrt) break; -// if (output) pclog("Load %08X from %08X to %08X %04X %08X %04X %08X\n",templ,ESI,EDI,DS,ds,ES,es); if (flags&D_FLAG) { EDI-=4; ESI-=4; } else { EDI+=4; ESI+=4; } c--; @@ -757,7 +737,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0xA6: case 0x1A6: /*REP CMPSB*/ -// cpu_notreps++; tempz = (fv) ? 1 : 0; if ((c>0) && (fv==tempz)) { @@ -776,7 +755,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x2A6: case 0x3A6: /*REP CMPSB*/ -// cpu_notreps++; tempz = (fv) ? 1 : 0; if ((c>0) && (fv==tempz)) { @@ -795,14 +773,11 @@ int rep386(int fv) else firstrepcycle=1; break; case 0xA7: /*REP CMPSW*/ -// cpu_notreps++; tempz = (fv) ? 1 : 0; if ((c>0) && (fv==tempz)) { -// pclog("CMPSW (%04x:%04x)%05X (%04x:%04x)%05X ", DS,SI, ds+SI, ES,DI, es+DI); tempw = readmemw(cpu_state.ea_seg->base, SI); tempw2=readmemw(es,DI); -// pclog("%04X %04X %c%c %c%c\n", tempw, tempw2, tempw & 0xff, tempw >> 8, tempw2 & 0xff, tempw2 >> 8); if (cpu_state.abrt) { flags=of; break; } if (flags&D_FLAG) { DI-=2; SI-=2; } @@ -817,7 +792,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x1A7: /*REP CMPSL*/ -// cpu_notreps++; tempz = (fv) ? 1 : 0; if ((c>0) && (fv==tempz)) { @@ -836,7 +810,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x2A7: /*REP CMPSW*/ -// cpu_notreps++; tempz = (fv) ? 1 : 0; if ((c>0) && (fv==tempz)) { @@ -855,7 +828,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x3A7: /*REP CMPSL*/ -// cpu_notreps++; tempz = (fv) ? 1 : 0; if ((c>0) && (fv==tempz)) { @@ -989,8 +961,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0xAC: case 0x1AC: /*REP LODSB*/ -// cpu_notreps++; -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc); if (c>0) { AL = readmemb(cpu_state.ea_seg->base, SI); @@ -1005,8 +975,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x2AC: case 0x3AC: /*REP LODSB*/ -// cpu_notreps++; -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSB %04X(%06X):%06X\n",CS,cs,pc); if (c>0) { AL = readmemb(cpu_state.ea_seg->base, ESI); @@ -1021,8 +989,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0xAD: /*REP LODSW*/ -// cpu_notreps++; -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc); if (c>0) { AX = readmemw(cpu_state.ea_seg->base, SI); @@ -1037,8 +1003,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x1AD: /*REP LODSL*/ -// cpu_notreps++; -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc); if (c>0) { EAX = readmeml(cpu_state.ea_seg->base, SI); @@ -1053,8 +1017,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x2AD: /*REP LODSW*/ -// cpu_notreps++; -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSW %04X(%06X):%06X\n",CS,cs,pc); if (c>0) { AX = readmemw(cpu_state.ea_seg->base, ESI); @@ -1069,8 +1031,6 @@ int rep386(int fv) else firstrepcycle=1; break; case 0x3AD: /*REP LODSL*/ -// cpu_notreps++; -// if (ds==0xFFFFFFFF) pclog("Null selector REP LODSL %04X(%06X):%06X\n",CS,cs,pc); if (c>0) { EAX = readmeml(cpu_state.ea_seg->base, ESI); @@ -1086,8 +1046,6 @@ int rep386(int fv) break; case 0xAE: case 0x1AE: /*REP SCASB*/ cpu_notreps++; -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); -// tempz=(fv)?1:0; tempz = (fv) ? 1 : 0; while ((c > 0) && (fv == tempz)) { @@ -1110,14 +1068,11 @@ int rep386(int fv) break; case 0x2AE: case 0x3AE: /*REP SCASB*/ cpu_notreps++; -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASB %04X(%06X):%06X\n",CS,cs,pc); -// tempz=(fv)?1:0; tempz = (fv) ? 1 : 0; while ((c > 0) && (fv == tempz)) { temp2=readmemb(es,EDI); if (cpu_state.abrt) { flags=of; break; } -// if (output) pclog("Compare %02X,%02X\n",temp2,AL); setsub8(AL,temp2); tempz = (ZF_SET()) ? 1 : 0; if (flags&D_FLAG) EDI--; @@ -1135,7 +1090,6 @@ int rep386(int fv) break; case 0xAF: /*REP SCASW*/ cpu_notreps++; -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); tempz = (fv) ? 1 : 0; while ((c > 0) && (fv == tempz)) { @@ -1158,7 +1112,6 @@ int rep386(int fv) break; case 0x1AF: /*REP SCASL*/ cpu_notreps++; -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc); tempz = (fv) ? 1 : 0; while ((c > 0) && (fv == tempz)) { @@ -1181,7 +1134,6 @@ int rep386(int fv) break; case 0x2AF: /*REP SCASW*/ cpu_notreps++; -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASW %04X(%06X):%06X\n",CS,cs,pc); tempz = (fv) ? 1 : 0; while ((c > 0) && (fv == tempz)) { @@ -1204,7 +1156,6 @@ int rep386(int fv) break; case 0x3AF: /*REP SCASL*/ cpu_notreps++; -// if (es==0xFFFFFFFF) pclog("Null selector REP SCASL %04X(%06X):%06X\n",CS,cs,pc); tempz = (fv) ? 1 : 0; while ((c > 0) && (fv == tempz)) { @@ -1229,7 +1180,6 @@ int rep386(int fv) default: cpu_state.pc = ipc+1; - //pclog("Bad REP %02X %i\n", temp, rep32 >> 8); break; } if (rep32&0x200) ECX=c; @@ -1237,27 +1187,6 @@ int rep386(int fv) CPU_BLOCK_END(); PREFETCH_RUN(total_cycles, 1, -1, reads, reads_l, writes, writes_l, 0); return cpu_state.abrt; -//pclog("rep cpu_block_end=%d %p\n", cpu_block_end, (void *)&cpu_block_end); -// if (output) pclog("%03X %03X\n",rep32,use32); -} - -int checkio(int port) -{ - uint16_t t; - uint8_t d; - cpl_override = 1; - t = readmemw(tr.base, 0x66); - cpl_override = 0; -// pclog("CheckIO 1 %08X %04x %02x\n",tr.base, eflags, _cs.access); - if (cpu_state.abrt) return 0; -// pclog("CheckIO %04X %01X %01X %02X %04X %04X %08X ",CS,CPL,IOPL,port,t,t+(port>>3),tr.base+t+(port>>3)); - if ((t+(port>>3))>tr.limit) return 1; - cpl_override = 1; - d = readmemb386l(0, tr.base + t + (port >> 3)); -// d=readmemb(tr.base,t+(port>>3)); - cpl_override = 0; -// pclog("%02X %02X\n",d,d&(1<<(port&7))); - return d&(1<<(port&7)); } int xout=0; @@ -1276,15 +1205,20 @@ int xout=0; int divl(uint32_t val) { + uint64_t num, quo; + uint32_t rem, quo32; + if (val==0) { divexcp(); return 1; } - uint64_t num=(((uint64_t)EDX)<<32)|EAX; - uint64_t quo=num/val; - uint32_t rem=num%val; - uint32_t quo32=(uint32_t)(quo&0xFFFFFFFF); + + num=(((uint64_t)EDX)<<32)|EAX; + quo=num/val; + rem=num%val; + quo32=(uint32_t)(quo&0xFFFFFFFF); + if (quo!=(uint64_t)quo32) { divexcp(); @@ -1296,15 +1230,20 @@ int divl(uint32_t val) } int idivl(int32_t val) { + int64_t num, quo; + int32_t rem, quo32; + if (val==0) { divexcp(); return 1; } - int64_t num=(((uint64_t)EDX)<<32)|EAX; - int64_t quo=num/val; - int32_t rem=num%val; - int32_t quo32=(int32_t)(quo&0xFFFFFFFF); + + num=(((uint64_t)EDX)<<32)|EAX; + quo=num/val; + rem=num%val; + quo32=(int32_t)(quo&0xFFFFFFFF); + if (quo!=(int64_t)quo32) { divexcp(); @@ -1338,7 +1277,6 @@ int dontprint=0; #define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG)) -//#define CACHE_ON() 0 static int cycles_main = 0; void exec386_dynarec(int cycs) @@ -1348,8 +1286,8 @@ void exec386_dynarec(int cycs) int tempi; int cycdiff; int oldcyc; + uint32_t start_pc = 0; -//output = 3; cycles_main += cycs; while (cycles_main > 0) { @@ -1359,7 +1297,6 @@ void exec386_dynarec(int cycs) cycles_start = cycles; timer_start_period(cycles << TIMER_SHIFT); -// output=3; while (cycles>0) { oldcs = CS; @@ -1370,11 +1307,9 @@ void exec386_dynarec(int cycs) cycdiff=0; oldcyc=cycles; -// if (output && CACHE_ON()) pclog("Block %04x:%04x %04x:%08x\n", CS, pc, SS,ESP); if (!CACHE_ON()) /*Interpret block*/ { cpu_block_end = 0; -// if (output) pclog("Interpret block at %04x:%04x %04x %04x %04x %04x %04x %04x %04x\n", CS, pc, AX, BX, CX, DX, SI, DI, SP); while (!cpu_block_end) { oldcs=CS; @@ -1385,19 +1320,13 @@ void exec386_dynarec(int cycs) cpu_state.ea_seg = &_ds; cpu_state.ssegs = 0; - opcodestart: fetchdat = fastreadl(cs + cpu_state.pc); -// if (!fetchdat) -// fatal("Dead with cache off\n"); if (!cpu_state.abrt) { trap = flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; -// if (output == 3) -// pclog("int %04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %f %02X%02X %02X%02X\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, pit.c[0], ram[0x8f13f], ram[0x8f13e], ram[0x8f141], ram[0x8f140]); - cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); } @@ -1504,13 +1433,11 @@ void exec386_dynarec(int cycs) void (*code)() = (void *)&block->data[BLOCK_START]; codeblock_hash[hash] = block; -// if (output) pclog("Run block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%08x %04x %08x %08x %016llx %08x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, get_phys(cs+pc), block->phys, block->page_mask, block->endpc); inrecomp=1; code(); inrecomp=0; if (!use32) cpu_state.pc &= 0xffff; -// cpu_recomp_ins += block->ins; cpu_recomp_blocks++; /* ins += codeblock_ins[index]; insc += codeblock_ins[index];*/ @@ -1518,10 +1445,8 @@ inrecomp=0; } else if (valid_block && !cpu_state.abrt) { - uint32_t start_page = cpu_state.pc >> 12; - uint32_t start_pc = cpu_state.pc; + start_pc = cpu_state.pc; -// pclog("Hash %08x %i\n", codeblock_hash_pc[HASH(cs + pc)], codeblock_page_dirty[(cs + pc) >> 12]); cpu_block_end = 0; x86_was_reset = 0; @@ -1530,7 +1455,6 @@ inrecomp=0; codegen_block_start_recompile(block); codegen_in_recompile = 1; -// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); while (!cpu_block_end) { oldcs=CS; @@ -1541,21 +1465,13 @@ inrecomp=0; cpu_state.ea_seg = &_ds; cpu_state.ssegs = 0; - opcodestart_compile: fetchdat = fastreadl(cs + cpu_state.pc); -// if (fetchdat == 0xffffffff) -// fatal("Dead ffffffff\n"); -// if (!fetchdat) -// fatal("Dead\n"); if (!cpu_state.abrt) { trap = flags & T_FLAG; opcode = fetchdat & 0xFF; fetchdat >>= 8; -// if (output == 3) -// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache); - cpu_state.pc++; codegen_generate_call(opcode, x86_opcodes[(opcode | cpu_state.op32) & 0x3ff], fetchdat, cpu_state.pc, cpu_state.pc-1); @@ -1596,23 +1512,17 @@ inrecomp=0; codegen_reset(); codegen_in_recompile = 0; -// output &= ~2; } else if (!cpu_state.abrt) { /*Mark block but do not recompile*/ - uint32_t start_page = cpu_state.pc >> 12; - uint32_t start_pc = cpu_state.pc; + start_pc = cpu_state.pc; -// pclog("Hash %08x %i\n", codeblock_hash_pc[HASH(cs + pc)], codeblock_page_dirty[(cs + pc) >> 12]); cpu_block_end = 0; x86_was_reset = 0; -// cpu_new_blocks++; - codegen_block_init(phys_addr); -// if (output) pclog("Recompile block at %04x:%04x %04x %04x %04x %04x %04x %04x ESP=%04x %04x %02x%02x:%02x%02x %02x%02x:%02x%02x %02x%02x:%02x%02x\n", CS, pc, AX, BX, CX, DX, SI, DI, ESP, BP, ram[0x116330+0x6df4+0xa+3], ram[0x116330+0x6df4+0xa+2], ram[0x116330+0x6df4+0xa+1], ram[0x116330+0x6df4+0xa+0], ram[0x11d136+3],ram[0x11d136+2],ram[0x11d136+1],ram[0x11d136+0], ram[(0x119abe)+0x3],ram[(0x119abe)+0x2],ram[(0x119abe)+0x1],ram[(0x119abe)+0x0]); while (!cpu_block_end) { oldcs=CS; @@ -1632,9 +1542,6 @@ inrecomp=0; opcode = fetchdat & 0xFF; fetchdat >>= 8; -// if (output == 3) -// pclog("%04X(%06X):%04X : %08X %08X %08X %08X %04X %04X %04X(%08X) %04X %04X %04X(%08X) %08X %08X %08X SP=%04X:%08X %02X %04X %i %08X %08X %i %i %02X %02X %02X %02X %02X %08x %08x\n",CS,cs,pc,EAX,EBX,ECX,EDX,CS,DS,ES,es,FS,GS,SS,ss,EDI,ESI,EBP,SS,ESP,opcode,flags,ins,0, ldt.base, CPL, stack32, pic.pend, pic.mask, pic.mask2, pic2.pend, pic2.mask, cs+pc, pccache); - cpu_state.pc++; x86_opcodes[(opcode | cpu_state.op32) & 0x3ff](fetchdat); @@ -1671,18 +1578,12 @@ inrecomp=0; if (x86_was_reset) codegen_reset(); - -// output &= ~2; } -// if (output && (SP & 1)) -// fatal("odd SP\n"); } cycdiff=oldcyc-cycles; tsc += cycdiff; -// timer_end_period(cycles); - if (cpu_state.abrt) { flags_rebuild(); @@ -1710,8 +1611,6 @@ inrecomp=0; { flags_rebuild(); -// oldpc=pc; -// oldcs=CS; if (msw&1) { pmodeint(1,0); @@ -1734,7 +1633,6 @@ inrecomp=0; temp=picinterrupt(); if (temp!=0xFF) { -// pclog("IRQ %02X %04X:%04X %04X:%04X\n", temp, SS, SP, CS, pc); CPU_BLOCK_END(); flags_rebuild(); if (msw&1) diff --git a/src/386_dynarec_ops.c b/src/386_dynarec_ops.c index bf2fe7ad4..7b5a5c7f5 100644 --- a/src/386_dynarec_ops.c +++ b/src/386_dynarec_ops.c @@ -1,3 +1,7 @@ +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif #include "ibm.h" #include "cpu.h" #include "x86.h" @@ -6,6 +10,7 @@ #include "x86_flags.h" #include "mem.h" #include "codegen.h" +#include "pic.h" #define CPU_BLOCK_END() cpu_block_end = 1 @@ -15,7 +20,7 @@ extern uint16_t *mod1add[2][8]; extern uint32_t *mod1seg[8]; -static inline void fetch_ea_32_long(uint32_t rmdat) +static __inline void fetch_ea_32_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; @@ -31,7 +36,7 @@ static inline void fetch_ea_32_long(uint32_t rmdat) cpu_state.last_ea = cpu_state.eaaddr; } -static inline void fetch_ea_16_long(uint32_t rmdat) +static __inline void fetch_ea_16_long(uint32_t rmdat) { eal_r = eal_w = NULL; easeg = cpu_state.ea_seg->base; diff --git a/src/386_ops.h b/src/386_ops.h index 15ce9349a..4e5d78125 100644 --- a/src/386_ops.h +++ b/src/386_ops.h @@ -15,7 +15,7 @@ } \ } while (0) -static inline void PUSH_W(uint16_t val) +static __inline void PUSH_W(uint16_t val) { if (stack32) { @@ -31,7 +31,7 @@ static inline void PUSH_W(uint16_t val) } } -static inline void PUSH_L(uint32_t val) +static __inline void PUSH_L(uint32_t val) { if (stack32) { @@ -47,7 +47,7 @@ static inline void PUSH_L(uint32_t val) } } -static inline uint16_t POP_W() +static __inline uint16_t POP_W() { uint16_t ret; if (stack32) @@ -65,7 +65,7 @@ static inline uint16_t POP_W() return ret; } -static inline uint32_t POP_L() +static __inline uint32_t POP_L() { uint32_t ret; if (stack32) @@ -83,7 +83,7 @@ static inline uint32_t POP_L() return ret; } -static inline uint16_t POP_W_seg(uint32_t seg) +static __inline uint16_t POP_W_seg(uint32_t seg) { uint16_t ret; if (stack32) @@ -101,7 +101,7 @@ static inline uint16_t POP_W_seg(uint32_t seg) return ret; } -static inline uint32_t POP_L_seg(uint32_t seg) +static __inline uint32_t POP_L_seg(uint32_t seg) { uint32_t ret; if (stack32) @@ -119,6 +119,17 @@ static inline uint32_t POP_L_seg(uint32_t seg) return ret; } +static int fopcode; + +static int ILLEGAL(uint32_t fetchdat) +{ + cpu_state.pc = cpu_state.oldpc; + + pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode); + x86illegal(); + return 0; +} + #include "x86seg.h" #include "x86_ops_arith.h" #include "x86_ops_atomic.h" @@ -133,6 +144,8 @@ static inline uint32_t POP_L_seg(uint32_t seg) #include "x86_ops_io.h" #include "x86_ops_jump.h" #include "x86_ops_misc.h" +#include "x87_ops.h" +#include "x86_ops_i686.h" #include "x86_ops_mmx.h" #include "x86_ops_mmx_arith.h" #include "x86_ops_mmx_cmp.h" @@ -156,25 +169,12 @@ static inline uint32_t POP_L_seg(uint32_t seg) #include "x86_ops_string.h" #include "x86_ops_xchg.h" -static int fopcode; - -static int ILLEGAL(uint32_t fetchdat) -{ - cpu_state.pc = cpu_state.oldpc; - -// fatal("Illegal instruction %08X\n", fetchdat); - pclog("Illegal instruction %08X (%02X)\n", fetchdat, fopcode); - x86illegal(); - return 0; -} - static int op0F_w_a16(uint32_t fetchdat) { int opcode = fetchdat & 0xff; fopcode = opcode; cpu_state.pc++; - // pclog("A16W: 0F %02X\n", opcode); PREFETCH_PREFIX(); return x86_opcodes_0f[opcode](fetchdat >> 8); @@ -185,7 +185,6 @@ static int op0F_l_a16(uint32_t fetchdat) fopcode = opcode; cpu_state.pc++; - // pclog("A16L: 0F %02X\n", opcode); PREFETCH_PREFIX(); return x86_opcodes_0f[opcode | 0x100](fetchdat >> 8); @@ -196,7 +195,6 @@ static int op0F_w_a32(uint32_t fetchdat) fopcode = opcode; cpu_state.pc++; - // pclog("A32W: 0F %02X\n", opcode); PREFETCH_PREFIX(); return x86_opcodes_0f[opcode | 0x200](fetchdat >> 8); @@ -207,15 +205,11 @@ static int op0F_l_a32(uint32_t fetchdat) fopcode = opcode; cpu_state.pc++; - // pclog("A32L: 0F %02X\n", opcode); PREFETCH_PREFIX(); return x86_opcodes_0f[opcode | 0x300](fetchdat >> 8); } -#include "x87_ops.h" -#include "x86_ops_i686.h" - OpFn OP_TABLE(286_0f)[1024] = { /*16-bit data, 16-bit addr*/ @@ -1241,7 +1235,7 @@ OpFn OP_TABLE(286)[1024] = /*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -1263,7 +1257,7 @@ OpFn OP_TABLE(286)[1024] = /*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -1285,7 +1279,7 @@ OpFn OP_TABLE(286)[1024] = /*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -1307,7 +1301,7 @@ OpFn OP_TABLE(286)[1024] = /*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET_286, /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +/*f0*/ opLOCK, opLOCK, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, }; OpFn OP_TABLE(386)[1024] = @@ -1332,7 +1326,7 @@ OpFn OP_TABLE(386)[1024] = /*c0*/ opC0_a16, opC1_w_a16, opRET_w_imm, opRET_w, opLES_w_a16, opLDS_w_a16, opMOV_b_imm_a16,opMOV_w_imm_a16,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, /*d0*/ opD0_a16, opD1_w_a16, opD2_a16, opD3_w_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, +/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_w_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_w_a16, /*32-bit data, 16-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -1354,7 +1348,7 @@ OpFn OP_TABLE(386)[1024] = /*c0*/ opC0_a16, opC1_l_a16, opRET_l_imm, opRET_l, opLES_l_a16, opLDS_l_a16, opMOV_b_imm_a16,opMOV_l_imm_a16,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD, /*d0*/ opD0_a16, opD1_l_a16, opD2_a16, opD3_l_a16, opAAM, opAAD, opSETALC, opXLAT_a16, opESCAPE_d8_a16,opESCAPE_d9_a16,opESCAPE_da_a16,opESCAPE_db_a16,opESCAPE_dc_a16,opESCAPE_dd_a16,opESCAPE_de_a16,opESCAPE_df_a16, /*e0*/ opLOOPNE_w, opLOOPE_w, opLOOP_w, opJCXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_l_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_l_a16, +/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a16, opF7_l_a16, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a16, opFF_l_a16, /*16-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -1376,7 +1370,7 @@ OpFn OP_TABLE(386)[1024] = /*c0*/ opC0_a32, opC1_w_a32, opRET_w_imm, opRET_w, opLES_w_a32, opLDS_w_a32, opMOV_b_imm_a32,opMOV_w_imm_a32,opENTER_w, opLEAVE_w, opRETF_a16_imm, opRETF_a16, opINT3, opINT, opINTO, opIRET, /*d0*/ opD0_a32, opD1_w_a32, opD2_a32, opD3_w_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, /*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_AX_imm, opOUT_AL_imm, opOUT_AX_imm, opCALL_r16, opJMP_r16, opJMP_far_a16, opJMP_r8, opIN_AL_DX, opIN_AX_DX, opOUT_AL_DX, opOUT_AX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_w_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_w_a32, +/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_w_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_w_a32, /*32-bit data, 32-bit addr*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ @@ -1398,5 +1392,5 @@ OpFn OP_TABLE(386)[1024] = /*c0*/ opC0_a32, opC1_l_a32, opRET_l_imm, opRET_l, opLES_l_a32, opLDS_l_a32, opMOV_b_imm_a32,opMOV_l_imm_a32,opENTER_l, opLEAVE_l, opRETF_a32_imm, opRETF_a32, opINT3, opINT, opINTO, opIRETD, /*d0*/ opD0_a32, opD1_l_a32, opD2_a32, opD3_l_a32, opAAM, opAAD, opSETALC, opXLAT_a32, opESCAPE_d8_a32,opESCAPE_d9_a32,opESCAPE_da_a32,opESCAPE_db_a32,opESCAPE_dc_a32,opESCAPE_dd_a32,opESCAPE_de_a32,opESCAPE_df_a32, /*e0*/ opLOOPNE_l, opLOOPE_l, opLOOP_l, opJECXZ, opIN_AL_imm, opIN_EAX_imm, opOUT_AL_imm, opOUT_EAX_imm, opCALL_r32, opJMP_r32, opJMP_far_a32, opJMP_r8, opIN_AL_DX, opIN_EAX_DX, opOUT_AL_DX, opOUT_EAX_DX, -/*f0*/ opLOCK, ILLEGAL, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, +/*f0*/ opLOCK, opINT1, opREPNE, opREPE, opHLT, opCMC, opF6_a32, opF7_l_a32, opCLC, opSTC, opCLI, opSTI, opCLD, opSTD, opINCDEC_b_a32, opFF_l_a32, }; diff --git a/src/808x.c b/src/808x.c index 07f8ed95b..6f72fb613 100644 --- a/src/808x.c +++ b/src/808x.c @@ -1,8 +1,6 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -//1B64 - Vid_SetMode (Vid_Vesa.c) -//6689c - CONS_Printf /*SHR AX,1 4 clocks - fetch opcode @@ -13,6 +11,8 @@ 2 clocks - fetch opcode 1 2 clocks - execute 2 clocks - fetch opcode 2 etc*/ #include +#include + #include "ibm.h" #include "cpu.h" @@ -25,6 +25,7 @@ int xt_cpu_multi; int nmi = 0; +int nmi_auto_clear = 0; int nextcyc=0; int cycdiff; @@ -95,7 +96,7 @@ void writememl(uint32_t s, uint32_t a, uint32_t v) } -void dumpregs(); +void dumpregs(int); uint16_t oldcs; int oldcpl; @@ -109,14 +110,13 @@ int output=0; int shadowbios=0; int ins=0; -//#define readmemb(a) (((a)<0xA0000)?ram[a]:readmembl(a)) int fetchcycles=0,memcycs,fetchclocks; uint8_t prefetchqueue[6]; uint16_t prefetchpc; int prefetchw=0; -static inline uint8_t FETCH() +static __inline uint8_t FETCH() { uint8_t temp; /* temp=prefetchqueue[0]; @@ -134,20 +134,16 @@ static inline uint8_t FETCH() } }*/ -// uint8_t temp=readmemb(cs+pc); -// if (output) printf("FETCH %04X %i\n",pc,fetchcycles); - if (prefetchw==0) //(fetchcycles<4) + if (prefetchw==0) { cycles-=(4-(fetchcycles&3)); fetchclocks+=(4-(fetchcycles&3)); fetchcycles=4; temp=readmembf(cs+cpu_state.pc); prefetchpc = cpu_state.pc = cpu_state.pc + 1; -// if (output) printf(" FETCH %04X:%04X %02X %04X %04X %i\n",CS,pc-1,temp,pc,prefetchpc,prefetchw); if (is8086 && (cpu_state.pc&1)) { prefetchqueue[0]=readmembf(cs+cpu_state.pc); -// if (output) printf(" PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); prefetchpc++; prefetchw++; } @@ -161,19 +157,15 @@ static inline uint8_t FETCH() prefetchqueue[3]=prefetchqueue[4]; prefetchqueue[4]=prefetchqueue[5]; prefetchw--; -// if (output) printf("PREFETCH %04X:%04X %02X %04X %04X %i\n",CS,pc,temp,pc,prefetchpc,prefetchw); fetchcycles-=4; -// fetchclocks+=4; cpu_state.pc++; } -// if (output) printf("%i\n",fetchcycles); return temp; } -static inline void FETCHADD(int c) +static __inline void FETCHADD(int c) { int d; -// if (output) printf("FETCHADD %i\n",c); if (c<0) return; if (prefetchw>((is8086)?4:3)) return; d=c+(fetchcycles&3); @@ -183,26 +175,22 @@ static inline void FETCHADD(int c) if (is8086 && !(prefetchpc&1)) { prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); -// printf("PREFETCHED from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); prefetchpc++; prefetchw++; } if (prefetchw<6) { prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); -// printf("PREFETCHED from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); prefetchpc++; prefetchw++; } } fetchcycles+=c; if (fetchcycles>16) fetchcycles=16; -// if (fetchcycles>24) fetchcycles=24; } void FETCHCOMPLETE() { -// pclog("Fetchcomplete %i %i %i\n",fetchcycles&3,fetchcycles,prefetchw); if (!(fetchcycles&3)) return; if (prefetchw>((is8086)?4:3)) return; if (!prefetchw) nextcyc=(4-(fetchcycles&3)); @@ -211,47 +199,24 @@ void FETCHCOMPLETE() if (is8086 && !(prefetchpc&1)) { prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); -// printf("PREFETCHEDc from %04X:%04X %02X 8086\n",CS,prefetchpc,prefetchqueue[prefetchw]); prefetchpc++; prefetchw++; } if (prefetchw<6) { prefetchqueue[prefetchw]=readmembf(cs+prefetchpc); -// printf("PREFETCHEDc from %04X:%04X %02X\n",CS,prefetchpc,prefetchqueue[prefetchw]); prefetchpc++; prefetchw++; } fetchcycles+=(4-(fetchcycles&3)); } -static inline void FETCHCLEAR() +static __inline void FETCHCLEAR() { -/* int c; - fetchcycles=0; - prefetchpc=pc; - if (is8086 && (prefetchpc&1)) cycles-=4; - for (c=0;c<((is8086)?6:4);c++) - { - prefetchqueue[c]=readmembf(cs+prefetchpc); - if (!is8086 || !(prefetchpc&1)) cycles-=4; - prefetchpc++; - } - prefetchw=(is8086)?6:4;*/ -// fetchcycles=0; prefetchpc=cpu_state.pc; prefetchw=0; memcycs=cycdiff-cycles; fetchclocks=0; -// memcycs=cycles; -/* prefetchqueue[0]=readmembf(cs+prefetchpc); - prefetchpc++; - prefetchw=1; - if (is8086 && prefetchpc&1) - { - prefetchqueue[1]=readmembf(cs+prefetchpc); - prefetchpc++; - }*/ } static uint16_t getword() @@ -270,13 +235,13 @@ r16(/r) AX CX DX BX SP BP SI DI r32(/r) EAX ECX EDX EBX ESP EBP ESI EDI /digit (Opcode) 0 1 2 3 4 5 6 7 REG = 000 001 010 011 100 101 110 111 - ����Address + ÚÄÄÄAddress disp8 denotes an 8-bit displacement following the ModR/M byte, to be sign-extended and added to the index. disp16 denotes a 16-bit displacement following the ModR/M byte, to be added to the index. Default segment register is SS for the effective addresses containing a BP index, DS for other effective addresses. - �Ŀ �Mod R/M� ���������ModR/M Values in Hexadecimal�������Ŀ + ÄÄ¿ ÚMod R/M¿ ÚÄÄÄÄÄÄÄÄModR/M Values in HexadecimalÄÄÄÄÄÄÄÄ¿ [BX + SI] 000 00 08 10 18 20 28 30 38 [BX + DI] 001 01 09 11 19 21 29 31 39 @@ -391,30 +356,28 @@ static void fetcheal() cpu_state.last_ea = cpu_state.eaaddr; } -static inline uint8_t geteab() +static __inline uint8_t geteab() { if (cpu_mod == 3) return (cpu_rm & 4) ? cpu_state.regs[cpu_rm & 3].b.h : cpu_state.regs[cpu_rm & 3].b.l; return readmemb(easeg+cpu_state.eaaddr); } -static inline uint16_t geteaw() +static __inline uint16_t geteaw() { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].w; -// if (output==3) printf("GETEAW %04X:%08X\n",easeg,eaaddr); return readmemw(easeg,cpu_state.eaaddr); } -static inline uint16_t geteaw2() +static __inline uint16_t geteaw2() { if (cpu_mod == 3) return cpu_state.regs[cpu_rm].w; -// printf("Getting addr from %04X:%04X %05X\n",easeg,eaaddr+2,easeg+eaaddr+2); return readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); } -static inline void seteab(uint8_t val) +static __inline void seteab(uint8_t val) { if (cpu_mod == 3) { @@ -429,19 +392,20 @@ static inline void seteab(uint8_t val) } } -static inline void seteaw(uint16_t val) +static __inline void seteaw(uint16_t val) { if (cpu_mod == 3) cpu_state.regs[cpu_rm].w = val; else { writememw(easeg,cpu_state.eaaddr,val); -// writememb(easeg+eaaddr+1,val>>8); } } +#undef getr8 #define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) +#undef setr8 #define setr8(r,v) if (r & 4) cpu_state.regs[r & 3].b.h = v; \ else cpu_state.regs[r & 3].b.l = v; @@ -465,10 +429,14 @@ void makeznptable() if (c&64) d++; if (c&128) d++; if (d&1) + { znptable8[c]=0; + } else + { znptable8[c]=P_FLAG; - if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]); + } + if (c == 0xb1) pclog("znp8 b1 = %i %02X\n", d, znptable8[c]); if (!c) znptable8[c]|=Z_FLAG; if (c&0x80) znptable8[c]|=N_FLAG; } @@ -491,9 +459,7 @@ void makeznptable() if (c == 0x65b1) pclog("znp16 65b1 = %i %02X\n", d, znptable16[c]); if (!c) znptable16[c]|=Z_FLAG; if (c&0x8000) znptable16[c]|=N_FLAG; - } - -// makemod1table(); + } } int timetolive=0; @@ -502,46 +468,28 @@ extern uint32_t oldpc2; int indump = 0; -void dumpregs() +void dumpregs(int force) { int c,d=0,e=0; #ifndef RELEASE_BUILD FILE *f; - if (indump) return; +#endif + + /* Only dump when needed, and only once.. */ + if (indump || (!force && !dump_on_exit)) return; + +#ifndef RELEASE_BUILD indump = 1; -// return; output=0; -// return; -// savenvr(); -// return; -chdir(pcempath); + chdir(pcempath); nopageerrors=1; -/* f=fopen("rram3.dmp","wb"); - for (c=0;c<0x8000000;c++) putc(readmemb(c+0x10000000),f); - fclose(f);*/ f=fopen("ram.dmp","wb"); fwrite(ram,mem_size*1024,1,f); fclose(f); -/* pclog("Dumping rram5.dmp\n"); - f=fopen("rram5.dmp","wb"); - for (c=0;c<0x1000000;c++) putc(readmemb(c+0x10150000),f); - fclose(f);*/ pclog("Dumping rram.dmp\n"); f=fopen("rram.dmp","wb"); for (c=0;c<0x1000000;c++) putc(readmemb(c),f); fclose(f); -/* f=fopen("rram2.dmp","wb"); - for (c=0;c<0x100000;c++) putc(readmemb(c+0xbff00000),f); - fclose(f); - f = fopen("stack.dmp","wb"); - for (c = 0; c < 0x6000; c++) putc(readmemb(c+0xFFDFA000), f); - fclose(f); - f = fopen("tempx.dmp","wb"); - for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFC816000), f); - fclose(f); - f = fopen("tempx2.dmp","wb"); - for (c = 0; c < 0x10000; c++) putc(readmemb(c+0xFDEF5000), f); - fclose(f);*/ pclog("Dumping rram4.dmp\n"); f=fopen("rram4.dmp","wb"); for (c=0;c<0x0050000;c++) @@ -551,36 +499,6 @@ chdir(pcempath); } fclose(f); pclog("Dumping done\n"); -/* f=fopen("rram6.dmp","wb"); - for (c=0;c<0x1000000;c++) putc(readmemb(c+0xBF000000),f); - fclose(f);*/ -/* f=fopen("ram6.bin","wb"); - fwrite(ram+0x10100,0xA000,1,f); - fclose(f); - f=fopen("boot.bin","wb"); - fwrite(ram+0x7C00,0x200,1,f); - fclose(f); - f=fopen("ram7.bin","wb"); - fwrite(ram+0x11100,0x2000,1,f); - fclose(f); - f=fopen("ram8.bin","wb"); - fwrite(ram+0x3D210,0x200,1,f); - fclose(f); */ -/* f=fopen("bios.dmp","wb"); - fwrite(rom,0x20000,1,f); - fclose(f);*/ -/* f=fopen("kernel.dmp","wb"); - for (c=0;c<0x200000;c++) putc(readmemb(c+0xC0000000),f); - fclose(f);*/ -/* f=fopen("rram.dmp","wb"); - for (c=0;c<0x1500000;c++) putc(readmemb(c),f); - fclose(f); - if (!times) - { - f=fopen("thing.dmp","wb"); - fwrite(ram+0x11E50,0x1000,1,f); - fclose(f); - }*/ #endif if (is386) printf("EAX=%08X EBX=%08X ECX=%08X EDX=%08X\nEDI=%08X ESI=%08X EBP=%08X ESP=%08X\n",EAX,EBX,ECX,EDX,EDI,ESI,EBP,ESP); @@ -631,8 +549,6 @@ void resetx86() ins = 0; use32=0; stack32=0; -// i86_Reset(); -// cs=0xFFFF0; cpu_state.pc=0; msw=0; if (is486) @@ -655,6 +571,7 @@ void resetx86() FETCHCLEAR(); x87_reset(); cpu_set_edx(); + EAX = 0; ESP=0; mmu_perm=4; memset(inscounts, 0, sizeof(inscounts)); @@ -667,12 +584,8 @@ void resetx86() void softresetx86() { -// dumpregs(); -// exit(-1); use32=0; stack32=0; -// i86_Reset(); -// cs=0xFFFF0; cpu_state.pc=0; msw=0; cr0=0; @@ -680,7 +593,6 @@ void softresetx86() eflags=0; cgate32=0; loadcs(0xFFFF); - //rammask=0xFFFFFFFF; flags=2; idt.base = 0; x86seg_reset(); @@ -787,7 +699,6 @@ static void setsub16(uint16_t a, uint16_t b) flags|=znptable16[c&0xFFFF]; if (c&0x10000) flags|=C_FLAG; if ((a^b)&(a^c)&0x8000) flags|=V_FLAG; -// if (output) printf("%04X %04X %i\n",a^b,a^c,flags&V_FLAG); if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; } static void setsub16nc(uint16_t a, uint16_t b) @@ -827,18 +738,16 @@ int firstrepcycle=1; void rep(int fv) { - uint8_t temp; + uint8_t temp = 0; int c=CX; uint8_t temp2; uint16_t tempw,tempw2; - uint16_t ipc=cpu_state.oldpc;//pc-1; + uint16_t ipc=cpu_state.oldpc; int changeds=0; - uint32_t oldds; + uint32_t oldds = 0; startrep: temp=FETCH(); -// if (firstrepcycle && temp==0xA5) printf("REP MOVSW %06X:%04X %06X:%04X\n",ds,SI,es,DI); -// if (output) printf("REP %02X %04X\n",temp,ipc); switch (temp) { case 0x08: @@ -885,7 +794,6 @@ void rep(int fv) { temp2=readmemb(ds+SI); writememb(es+DI,temp2); -// if (output) printf("Moved %02X from %04X:%04X to %04X:%04X\n",temp2,ds>>4,SI,es>>4,DI); if (flags&D_FLAG) { DI--; SI--; } else { DI++; SI++; } c--; @@ -894,9 +802,6 @@ void rep(int fv) FETCHADD(17-memcycs); } if (IRQTEST && c>0) cpu_state.pc=ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; -// } break; case 0xA5: /*REP MOVSW*/ while (c>0 && !IRQTEST) @@ -912,9 +817,6 @@ void rep(int fv) FETCHADD(17 - memcycs); } if (IRQTEST && c>0) cpu_state.pc=ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; -// } break; case 0xA6: /*REP CMPSB*/ if (fv) flags|=Z_FLAG; @@ -924,7 +826,6 @@ void rep(int fv) memcycs=0; temp=readmemb(ds+SI); temp2=readmemb(es+DI); -// printf("CMPSB %c %c %i %05X %05X %04X:%04X\n",temp,temp2,c,ds+SI,es+DI,cs>>4,pc); if (flags&D_FLAG) { DI--; SI--; } else { DI++; SI++; } c--; @@ -934,8 +835,6 @@ void rep(int fv) FETCHADD(30 - memcycs); } if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) cpu_state.pc=ipc; -// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; break; case 0xA7: /*REP CMPSW*/ if (fv) flags|=Z_FLAG; @@ -954,9 +853,6 @@ void rep(int fv) FETCHADD(30 - memcycs); } if (IRQTEST && c>0 && (fv==((flags&Z_FLAG)?1:0))) cpu_state.pc=ipc; -// if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; -// if (firstrepcycle) printf("REP CMPSW %06X:%04X %06X:%04X %04X %04X\n",ds,SI,es,DI,tempw,tempw2); break; case 0xAA: /*REP STOSB*/ while (c>0 && !IRQTEST) @@ -971,8 +867,6 @@ void rep(int fv) FETCHADD(10 - memcycs); } if (IRQTEST && c>0) cpu_state.pc=ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; break; case 0xAB: /*REP STOSW*/ while (c>0 && !IRQTEST) @@ -987,8 +881,6 @@ void rep(int fv) FETCHADD(10 - memcycs); } if (IRQTEST && c>0) cpu_state.pc=ipc; -// if (c>0) { firstrepcycle=0; pc=ipc; if (ssegs) ssegs++; FETCHCLEAR(); } -// else firstrepcycle=1; break; case 0xAC: /*REP LODSB*/ if (c>0) @@ -1020,18 +912,14 @@ void rep(int fv) if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { temp2=readmemb(es+DI); -// if (output) printf("SCASB %02X %c %02X %05X ",temp2,temp2,AL,es+DI); setsub8(AL,temp2); -// if (output && flags&Z_FLAG) printf("Match %02X %02X\n",AL,temp2); if (flags&D_FLAG) DI--; else DI++; c--; cycles -= 15; } -//if (output) printf("%i %i %i %i\n",c,(c>0),(fv==((flags&Z_FLAG)?1:0)),((c>0) && (fv==((flags&Z_FLAG)?1:0)))); if ((c>0) && (fv==((flags&Z_FLAG)?1:0))) { cpu_state.pc=ipc; firstrepcycle=0; if (cpu_state.ssegs) cpu_state.ssegs++; FETCHCLEAR(); } else firstrepcycle=1; -// cycles-=120; break; case 0xAF: /*REP SCASW*/ if (fv) flags|=Z_FLAG; @@ -1052,15 +940,11 @@ void rep(int fv) cpu_state.pc = ipc+1; cycles-=20; FETCHCLEAR(); -// printf("Bad REP %02X\n",temp); -// dumpregs(); -// exit(-1); } CX=c; if (changeds) ds=oldds; if (IRQTEST) takeint = 1; -// if (pc==ipc) FETCHCLEAR(); } @@ -1070,10 +954,9 @@ int firstrepcycle; int skipnextprint=0; int instime=0; -//#if 0 void execx86(int cycs) { - uint8_t temp,temp2; + uint8_t temp = 0,temp2; uint16_t addr,tempw,tempw2,tempw3,tempw4; int8_t offset; int tempws; @@ -1082,24 +965,14 @@ void execx86(int cycs) int tempi; int trap; -// printf("Run x86! %i %i\n",cycles,cycs); cycles+=cycs; -// i86_Execute(cycs); -// return; while (cycles>0) { -// old83=old82; -// old82=old8; -// old8=oldpc|(oldcs<<16); -// if (pc==0x96B && cs==0x9E040) { printf("Hit it\n"); output=1; timetolive=150; } -// if (pc<0x8000) printf("%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i\n",pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags,disctime); cycdiff=cycles; timer_start_period(cycles*xt_cpu_multi); current_diff = 0; cycles-=nextcyc; -// if (instime) pclog("Cycles %i %i\n",cycles,cycdiff); nextcyc=0; -// if (output) printf("CLOCK %i %i\n",cycdiff,cycles); fetchclocks=0; oldcs=CS; cpu_state.oldpc=cpu_state.pc; @@ -1108,33 +981,17 @@ void execx86(int cycs) tempc=flags&C_FLAG; trap=flags&T_FLAG; cpu_state.pc--; -// output=1; -// if (output) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X\n",cs>>4,pc,AX,BX,CX,DX,cs>>4,ds>>4,es>>4,ss>>4,DI,SI,BP,SP,opcode,flags&~0x200,rmdat); -//#if 0 if (output) { -// if ((opcode!=0xF2 && opcode!=0xF3) || firstrepcycle) -// { if (!skipnextprint) printf("%04X:%04X : %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %04X %02X %04X %i %p %02X\n",cs,cpu_state.pc,AX,BX,CX,DX,CS,DS,ES,SS,DI,SI,BP,SP,opcode,flags, ins, ram, ram[0x1a925]); skipnextprint=0; -// ins++; -// } } -//#endif cpu_state.pc++; inhlt=0; -// if (ins==500000) { dumpregs(); exit(0); }*/ switch (opcode) { case 0x00: /*ADD 8,reg*/ fetchea(); -/* if (!rmdat) pc--; - if (!rmdat) - { - fatal("Crashed\n"); -// clear_keybuf(); -// readkey(); - }*/ temp=geteab(); setadd8(temp,getr8(cpu_reg)); temp+=getr8(cpu_reg); @@ -1317,7 +1174,6 @@ void execx86(int cycs) cpu_state.last_ea = SP; noint=1; cycles-=12; -// output=1; break; case 0x18: /*SBB 8,reg*/ @@ -1333,7 +1189,6 @@ void execx86(int cycs) fetchea(); tempw=geteaw(); tempw2=cpu_state.regs[cpu_reg].w; -// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); setsbc16(tempw,tempw2); tempw-=(tempw2+tempc); seteaw(tempw); @@ -1350,7 +1205,6 @@ void execx86(int cycs) fetchea(); tempw=geteaw(); tempw2=cpu_state.regs[cpu_reg].w; -// printf("%04X:%04X SBB %04X-%04X,%i\n",cs>>4,pc,tempw,tempw2,tempc); setsbc16(tempw2,tempw); tempw2-=(tempw+tempc); cpu_state.regs[cpu_reg].w=tempw2; @@ -1442,7 +1296,6 @@ void execx86(int cycs) cpu_state.ssegs=2; cycles-=4; goto opcodestart; -// break; case 0x27: /*DAA*/ if ((flags&A_FLAG) || ((AL&0xF)>9)) @@ -1452,15 +1305,11 @@ void execx86(int cycs) flags|=A_FLAG; if (tempi&0x100) flags|=C_FLAG; } -// else -// flags&=~A_FLAG; if ((flags&C_FLAG) || (AL>0x9F)) { AL+=0x60; flags|=C_FLAG; } -// else -// flags&=~C_FLAG; setznp8(AL); cycles-=4; break; @@ -1476,7 +1325,6 @@ void execx86(int cycs) case 0x29: /*SUB 16,reg*/ fetchea(); tempw=geteaw(); -// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,tempw,cpu_state.regs[cpu_reg].w); setsub16(tempw,cpu_state.regs[cpu_reg].w); tempw-=cpu_state.regs[cpu_reg].w; seteaw(tempw); @@ -1492,7 +1340,6 @@ void execx86(int cycs) case 0x2B: /*SUB cpu_reg,16*/ fetchea(); tempw=geteaw(); -// printf("%04X:%04X %04X-%04X\n",cs>>4,pc,cpu_state.regs[cpu_reg].w,tempw); setsub16(cpu_state.regs[cpu_reg].w,tempw); cpu_state.regs[cpu_reg].w-=tempw; cycles-=((cpu_mod==3)?3:13); @@ -1504,8 +1351,6 @@ void execx86(int cycs) cycles-=4; break; case 0x2D: /*SUB AX,#16*/ -// printf("INS %i\n",ins); -// output=1; tempw=getword(); setsub16(AX,tempw); AX-=tempw; @@ -1526,15 +1371,11 @@ void execx86(int cycs) flags|=A_FLAG; if (tempi&0x100) flags|=C_FLAG; } -// else -// flags&=~A_FLAG; if ((flags&C_FLAG)||(AL>0x9F)) { AL-=0x60; flags|=C_FLAG; } -// else -// flags&=~C_FLAG; setznp8(AL); cycles-=4; break; @@ -1594,7 +1435,6 @@ void execx86(int cycs) cpu_state.ssegs=2; cycles-=4; goto opcodestart; -// break; case 0x37: /*AAA*/ if ((flags&A_FLAG)||((AL&0xF)>9)) @@ -1612,28 +1452,24 @@ void execx86(int cycs) case 0x38: /*CMP 8,reg*/ fetchea(); temp=geteab(); -// if (output) printf("CMP %02X-%02X\n",temp,getr8(cpu_reg)); setsub8(temp,getr8(cpu_reg)); cycles-=((cpu_mod==3)?3:13); break; case 0x39: /*CMP 16,reg*/ fetchea(); tempw=geteaw(); -// if (output) printf("CMP %04X-%04X\n",tempw,cpu_state.regs[cpu_reg].w); setsub16(tempw,cpu_state.regs[cpu_reg].w); cycles-=((cpu_mod==3)?3:13); break; case 0x3A: /*CMP cpu_reg,8*/ fetchea(); temp=geteab(); -// if (output) printf("CMP %02X-%02X\n",getr8(cpu_reg),temp); setsub8(getr8(cpu_reg),temp); cycles-=((cpu_mod==3)?3:13); break; case 0x3B: /*CMP cpu_reg,16*/ fetchea(); tempw=geteaw(); -// printf("CMP %04X-%04X\n",cpu_state.regs[cpu_reg].w,tempw); setsub16(cpu_state.regs[cpu_reg].w,tempw); cycles-=((cpu_mod==3)?3:13); break; @@ -1655,7 +1491,6 @@ void execx86(int cycs) cpu_state.ssegs=2; cycles-=4; goto opcodestart; -// break; case 0x3F: /*AAS*/ if ((flags&A_FLAG)||((AL&0xF)>9)) @@ -1825,13 +1660,11 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?4:23); break; case 0x10: /*ADC b,#8*/ -// temp2+=(flags&C_FLAG); setadc8(temp,temp2); seteab(temp+temp2+tempc); cycles-=((cpu_mod==3)?4:23); break; case 0x18: /*SBB b,#8*/ -// temp2+=(flags&C_FLAG); setsbc8(temp,temp2); seteab(temp-(temp2+tempc)); cycles-=((cpu_mod==3)?4:23); @@ -1859,11 +1692,6 @@ void execx86(int cycs) setsub8(temp,temp2); cycles-=((cpu_mod==3)?4:14); break; - -// default: -// printf("Bad 80 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -1887,7 +1715,6 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?4:23); break; case 0x10: /*ADC w,#16*/ -// tempw2+=(flags&C_FLAG); setadc16(tempw,tempw2); tempw+=tempw2+tempc; seteaw(tempw); @@ -1901,7 +1728,6 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?4:23); break; case 0x18: /*SBB w,#16*/ -// tempw2+=(flags&C_FLAG); setsbc16(tempw,tempw2); seteaw(tempw-(tempw2+tempc)); cycles-=((cpu_mod==3)?4:23); @@ -1920,15 +1746,9 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?4:23); break; case 0x38: /*CMP w,#16*/ -// printf("CMP %04X %04X\n",tempw,tempw2); setsub16(tempw,tempw2); cycles-=((cpu_mod==3)?4:14); break; - -// default: -// printf("Bad 81 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -1953,14 +1773,12 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?4:23); break; case 0x10: /*ADC w,#8*/ -// tempw2+=(flags&C_FLAG); setadc16(tempw,tempw2); tempw+=tempw2+tempc; seteaw(tempw); cycles-=((cpu_mod==3)?4:23); break; case 0x18: /*SBB w,#8*/ -// tempw2+=(flags&C_FLAG); setsbc16(tempw,tempw2); tempw-=(tempw2+tempc); seteaw(tempw); @@ -1990,11 +1808,6 @@ void execx86(int cycs) setsub16(tempw,tempw2); cycles-=((cpu_mod==3)?4:14); break; - -// default: -// printf("Bad 83 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -2081,9 +1894,7 @@ void execx86(int cycs) break; case 0x8E: /*MOV sreg,w*/ -// if (output) printf("MOV %04X ",pc); fetchea(); -// if (output) printf("%04X %02X\n",pc,rmdat); switch (rmdat&0x38) { case 0x00: /*ES*/ @@ -2103,8 +1914,6 @@ void execx86(int cycs) tempw=geteaw(); loadseg(tempw,&_ss); if (cpu_state.ssegs) oldss=ss; -// printf("LOAD SS %04X %04X\n",tempw,SS); -// printf("SS loaded with %04X %04X:%04X %04X %04X %04X\n",ss>>4,cs>>4,pc,CX,DX,es>>4); break; } cycles-=((cpu_mod==3)?2:12); @@ -2149,7 +1958,6 @@ void execx86(int cycs) tempw4=cpu_state.pc; if (cpu_state.ssegs) ss=oldss; cpu_state.pc=tempw; -// printf("0x9a"); loadcs(tempw2); writememw(ss,(SP-2)&0xFFFF,tempw3); writememw(ss,(SP-4)&0xFFFF,tempw4); @@ -2191,7 +1999,6 @@ void execx86(int cycs) break; case 0xA1: /*MOV AX,(w)*/ addr=getword(); -// printf("Reading AX from %05X %04X:%04X\n",ds+addr,ds>>4,addr); AX=readmemw(ds,addr); cycles-=!4; break; @@ -2202,7 +2009,6 @@ void execx86(int cycs) break; case 0xA3: /*MOV (w),AX*/ addr=getword(); -// if (!addr) printf("Write !addr %04X:%04X\n",cs>>4,pc); writememw(ds,addr,AX); cycles-=14; break; @@ -2232,7 +2038,6 @@ void execx86(int cycs) case 0xA7: /*CMPSW*/ tempw =readmemw(ds,SI); tempw2=readmemw(es,DI); -// printf("CMPSW %04X %04X\n",tempw,tempw2); setsub16(tempw,tempw2); if (flags&D_FLAG) { DI-=2; SI-=2; } else { DI+=2; SI+=2; } @@ -2264,13 +2069,11 @@ void execx86(int cycs) break; case 0xAC: /*LODSB*/ AL=readmemb(ds+SI); -// printf("LODSB %04X:%04X %02X %04X:%04X\n",cs>>4,pc,AL,ds>>4,SI); if (flags&D_FLAG) SI--; else SI++; cycles-=16; break; case 0xAD: /*LODSW*/ -// if (times) printf("LODSW %04X:%04X\n",cs>>4,pc); AX=readmemw(ds,SI); if (flags&D_FLAG) SI-=2; else SI+=2; @@ -2334,8 +2137,6 @@ void execx86(int cycs) tempw=getword(); if (cpu_state.ssegs) ss=oldss; cpu_state.pc=readmemw(ss,SP); -// printf("C2\n"); -// printf("RET to %04X\n",pc); SP+=2+tempw; cycles-=24; FETCHCLEAR(); @@ -2344,16 +2145,14 @@ void execx86(int cycs) case 0xC3: /*RET*/ if (cpu_state.ssegs) ss=oldss; cpu_state.pc=readmemw(ss,SP); -// printf("C3\n"); -// if (output) printf("RET to %04X %05X\n",pc,ss+SP); SP+=2; cycles-=20; FETCHCLEAR(); break; case 0xC4: /*LES*/ fetchea(); - cpu_state.regs[cpu_reg].w=readmemw(easeg,cpu_state.eaaddr); //geteaw(); - tempw=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); //geteaw2(); + cpu_state.regs[cpu_reg].w=readmemw(easeg,cpu_state.eaaddr); + tempw=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); loadseg(tempw,&_es); cycles-=24; break; @@ -2383,7 +2182,6 @@ void execx86(int cycs) tempw=getword(); if (cpu_state.ssegs) ss=oldss; cpu_state.pc=readmemw(ss,SP); -// printf("CA\n"); loadcs(readmemw(ss,SP+2)); SP+=4; SP+=tempw; @@ -2394,7 +2192,6 @@ void execx86(int cycs) case 0xCB: /*RETF*/ if (cpu_state.ssegs) ss=oldss; cpu_state.pc=readmemw(ss,SP); -// printf("CB\n"); loadcs(readmemw(ss,SP+2)); SP+=4; cycles-=34; @@ -2409,11 +2206,9 @@ void execx86(int cycs) addr=3<<2; flags&=~I_FLAG; flags&=~T_FLAG; -// printf("CC %04X:%04X ",CS,pc); cpu_state.pc=readmemw(0,addr); loadcs(readmemw(0,addr+2)); FETCHCLEAR(); -// printf("%04X:%04X\n",CS,pc); cycles-=72; break; case 0xCD: /*INT*/ @@ -2440,7 +2235,6 @@ void execx86(int cycs) tempw=CS; tempw2=cpu_state.pc; cpu_state.pc=readmemw(ss,SP); -// printf("CF\n"); loadcs(readmemw(ss,((SP+2)&0xFFFF))); flags=readmemw(ss,((SP+4)&0xFFFF))&0xFFF; SP+=6; @@ -2459,7 +2253,6 @@ void execx86(int cycs) temp<<=1; if (flags&C_FLAG) temp|=1; seteab(temp); -// setznp8(temp); if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2470,7 +2263,6 @@ void execx86(int cycs) temp>>=1; if (flags&C_FLAG) temp|=0x80; seteab(temp); -// setznp8(temp); if ((temp^(temp>>1))&0x40) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2482,7 +2274,6 @@ void execx86(int cycs) temp<<=1; if (temp2) temp|=1; seteab(temp); -// setznp8(temp); if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2494,7 +2285,6 @@ void execx86(int cycs) temp>>=1; if (temp2) temp|=0x80; seteab(temp); -// setznp8(temp); if ((temp^(temp>>1))&0x40) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2532,11 +2322,6 @@ void execx86(int cycs) flags|=A_FLAG; flags&=~V_FLAG; break; - -// default: -// printf("Bad D0 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -2551,7 +2336,6 @@ void execx86(int cycs) tempw<<=1; if (flags&C_FLAG) tempw|=1; seteaw(tempw); -// setznp16(tempw); if ((flags&C_FLAG)^(tempw>>15)) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2562,7 +2346,6 @@ void execx86(int cycs) tempw>>=1; if (flags&C_FLAG) tempw|=0x8000; seteaw(tempw); -// setznp16(tempw); if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2585,7 +2368,6 @@ void execx86(int cycs) tempw>>=1; if (temp2) tempw|=0x8000; seteaw(tempw); -// setznp16(tempw); if ((tempw^(tempw>>1))&0x4000) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?2:23); @@ -2624,11 +2406,6 @@ void execx86(int cycs) flags|=A_FLAG; flags&=~V_FLAG; break; - -// default: -// printf("Bad D1 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -2636,9 +2413,7 @@ void execx86(int cycs) fetchea(); temp=geteab(); c=CL; -// cycles-=c; if (!c) break; -// if (c>7) printf("Shiftb %i %02X\n",rmdat&0x38,c); switch (rmdat&0x38) { case 0x00: /*ROL b,CL*/ @@ -2652,7 +2427,6 @@ void execx86(int cycs) if (temp2) flags|=C_FLAG; else flags&=~C_FLAG; seteab(temp); -// setznp8(temp); if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; else flags&=~V_FLAG; cycles-=((cpu_mod==3)?8:28); @@ -2674,7 +2448,6 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?8:28); break; case 0x10: /*RCL b,CL*/ -// printf("RCL %i %02X %02X\n",c,CL,temp); while (c>0) { templ=flags&C_FLAG; @@ -2686,7 +2459,6 @@ void execx86(int cycs) c--; cycles-=4; } -// printf("Now %02X\n",temp); seteab(temp); if ((flags&C_FLAG)^(temp>>7)) flags|=V_FLAG; else flags&=~V_FLAG; @@ -2704,8 +2476,6 @@ void execx86(int cycs) c--; cycles-=4; } -// if (temp2) flags|=C_FLAG; -// else flags&=~C_FLAG; seteab(temp); if ((temp^(temp>>1))&0x40) flags|=V_FLAG; else flags&=~V_FLAG; @@ -2746,11 +2516,6 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?8:28); flags|=A_FLAG; break; - -// default: -// printf("Bad D2 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -2758,9 +2523,7 @@ void execx86(int cycs) fetchea(); tempw=geteaw(); c=CL; -// cycles-=c; if (!c) break; -// if (c>15) printf("Shiftw %i %02X\n",rmdat&0x38,c); switch (rmdat&0x38) { case 0x00: /*ROL w,CL*/ @@ -2874,11 +2637,6 @@ void execx86(int cycs) cycles-=((cpu_mod==3)?8:28); flags|=A_FLAG; break; - -// default: -// printf("Bad D3 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -2925,12 +2683,10 @@ void execx86(int cycs) cycles-=6; break; case 0xE2: /*LOOP*/ -// printf("LOOP start\n"); offset=(int8_t)FETCH(); CX--; if (CX) { cpu_state.pc+=offset; cycles-=12; FETCHCLEAR(); } cycles-=5; -// printf("LOOP end!\n"); break; case 0xE3: /*JCXZ*/ offset=(int8_t)FETCH(); @@ -2964,7 +2720,6 @@ void execx86(int cycs) case 0xE8: /*CALL rel 16*/ tempw=getword(); if (cpu_state.ssegs) ss=oldss; -// writememb(ss+((SP-1)&0xFFFF),pc>>8); writememw(ss,((SP-2)&0xFFFF),cpu_state.pc); SP-=2; cpu_state.last_ea = SP; @@ -2973,10 +2728,8 @@ void execx86(int cycs) FETCHCLEAR(); break; case 0xE9: /*JMP rel 16*/ -// pclog("PC was %04X\n",cpu_state.pc); tempw = getword(); cpu_state.pc += tempw; -// pclog("PC now %04X\n",cpu_state.pc); cycles-=15; FETCHCLEAR(); break; @@ -2984,10 +2737,7 @@ void execx86(int cycs) addr=getword(); tempw=getword(); cpu_state.pc=addr; -// printf("EA\n"); loadcs(tempw); -// cs=loadcs(CS); -// cs=CS<<4; cycles-=15; FETCHCLEAR(); break; @@ -3029,13 +2779,6 @@ void execx86(int cycs) break; case 0xF4: /*HLT*/ -// printf("IN HLT!!!! %04X:%04X %08X %08X %08X\n",oldcs,oldpc,old8,old82,old83); -/* if (!(flags & I_FLAG)) - { - pclog("HLT\n"); - dumpregs(); - exit(-1); - }*/ inhlt=1; cpu_state.pc--; FETCHCLEAR(); @@ -3052,6 +2795,7 @@ void execx86(int cycs) switch (rmdat&0x38) { case 0x00: /*TEST b,#8*/ + case 0x08: temp2=FETCH(); temp&=temp2; setznp8(temp); @@ -3093,25 +2837,9 @@ void execx86(int cycs) if (temp) { tempw2=tempw%temp; -/* if (!tempw) - { - writememw((ss+SP)-2,flags|0xF000); - writememw((ss+SP)-4,cs>>4); - writememw((ss+SP)-6,pc); - SP-=6; - flags&=~I_FLAG; - pc=readmemw(0); - cs=readmemw(2)<<4; - printf("Div by zero %04X:%04X\n",cs>>4,pc); -// dumpregs(); -// exit(-1); - } - else - {*/ AH=tempw2; tempw/=temp; AL=tempw&0xFF; -// } } else { @@ -3123,14 +2851,8 @@ void execx86(int cycs) flags&=~I_FLAG; flags&=~T_FLAG; cpu_state.pc=readmemw(0,0); -// printf("F6 30\n"); loadcs(readmemw(0,2)); FETCHCLEAR(); -// cs=loadcs(CS); -// cs=CS<<4; -// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x30); -// dumpregs(); -// exit(-1); } cycles-=80; break; @@ -3139,23 +2861,9 @@ void execx86(int cycs) if (temp) { tempw2=tempws%(int)((int8_t)temp); -/* if (!tempw) - { - writememw((ss+SP)-2,flags|0xF000); - writememw((ss+SP)-4,cs>>4); - writememw((ss+SP)-6,pc); - SP-=6; - flags&=~I_FLAG; - pc=readmemw(0); - cs=readmemw(2)<<4; - printf("Div by zero %04X:%04X\n",cs>>4,pc); - } - else - {*/ AH=tempw2&0xFF; tempws/=(int)((int8_t)temp); AL=tempws&0xFF; -// } } else { @@ -3167,20 +2875,11 @@ void execx86(int cycs) flags&=~I_FLAG; flags&=~T_FLAG; cpu_state.pc=readmemw(0,0); -// printf("F6 38\n"); loadcs(readmemw(0,2)); FETCHCLEAR(); -// cs=loadcs(CS); -// cs=CS<<4; -// printf("Div by zero %04X:%04X %02X %02X\n",cs>>4,pc,0xf6,0x38); } cycles-=101; break; - -// default: -// printf("Bad F6 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -3190,6 +2889,7 @@ void execx86(int cycs) switch (rmdat&0x38) { case 0x00: /*TEST w*/ + case 0x08: tempw2=getword(); setznp16(tempw&tempw2); flags&=~(C_FLAG|V_FLAG|A_FLAG); @@ -3208,7 +2908,6 @@ void execx86(int cycs) case 0x20: /*MUL AX,w*/ setznp16(AX); templ=AX*tempw; -// if (output) printf("%04X*%04X=%08X\n",AX,tempw,templ); AX=templ&0xFFFF; DX=templ>>16; if (AX|DX) flags&=~Z_FLAG; @@ -3219,24 +2918,18 @@ void execx86(int cycs) break; case 0x28: /*IMUL AX,w*/ setznp16(AX); -// printf("IMUL %i %i ",(int)((int16_t)AX),(int)((int16_t)tempw)); tempws=(int)((int16_t)AX)*(int)((int16_t)tempw); if ((tempws>>15) && ((tempws>>15)!=-1)) flags|=(C_FLAG|V_FLAG); else flags&=~(C_FLAG|V_FLAG); -// printf("%i ",tempws); AX=tempws&0xFFFF; tempws=(uint16_t)(tempws>>16); DX=tempws&0xFFFF; -// printf("%04X %04X\n",AX,DX); -// dumpregs(); -// exit(-1); if (AX|DX) flags&=~Z_FLAG; else flags|=Z_FLAG; cycles-=128; break; case 0x30: /*DIV AX,w*/ templ=(DX<<16)|AX; -// printf("DIV %08X/%04X\n",templ,tempw); if (tempw) { tempw2=templ%tempw; @@ -3254,7 +2947,6 @@ void execx86(int cycs) flags&=~I_FLAG; flags&=~T_FLAG; cpu_state.pc=readmemw(0,0); -// printf("F7 30\n"); loadcs(readmemw(0,2)); FETCHCLEAR(); } @@ -3262,11 +2954,9 @@ void execx86(int cycs) break; case 0x38: /*IDIV AX,w*/ tempws=(int)((DX<<16)|AX); -// printf("IDIV %i %i ",tempws,tempw); if (tempw) { tempw2=tempws%(int)((int16_t)tempw); -// printf("%04X ",tempw2); DX=tempw2; tempws/=(int)((int16_t)tempw); AX=tempws&0xFFFF; @@ -3281,17 +2971,11 @@ void execx86(int cycs) flags&=~I_FLAG; flags&=~T_FLAG; cpu_state.pc=readmemw(0,0); -// printf("F7 38\n"); loadcs(readmemw(0,2)); FETCHCLEAR(); } cycles-=165; break; - -// default: -// printf("Bad F7 opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -3300,18 +2984,15 @@ void execx86(int cycs) cycles-=2; break; case 0xF9: /*STC*/ -// printf("STC %04X\n",pc); flags|=C_FLAG; cycles-=2; break; case 0xFA: /*CLI*/ flags&=~I_FLAG; -// printf("CLI at %04X:%04X\n",cs>>4,pc); cycles-=3; break; case 0xFB: /*STI*/ flags|=I_FLAG; -// printf("STI at %04X:%04X\n",cs>>4,pc); cycles-=2; break; case 0xFC: /*CLD*/ @@ -3339,7 +3020,6 @@ void execx86(int cycs) temp2=temp+1; if ((temp2&0x80) && !(temp&0x80)) flags|=V_FLAG; } -// setznp8(temp2); seteab(temp2); cycles-=((cpu_mod==3)?3:23); break; @@ -3351,17 +3031,13 @@ void execx86(int cycs) case 0x00: /*INC w*/ tempw=geteaw(); setadd16nc(tempw,1); -// setznp16(tempw+1); seteaw(tempw+1); cycles-=((cpu_mod==3)?3:23); break; case 0x08: /*DEC w*/ tempw=geteaw(); -// setsub16(tempw,1); setsub16nc(tempw,1); -// setznp16(tempw-1); seteaw(tempw-1); -// if (output) printf("DEC - %04X\n",tempw); cycles-=((cpu_mod==3)?3:23); break; case 0x10: /*CALL*/ @@ -3371,18 +3047,16 @@ void execx86(int cycs) SP-=2; cpu_state.last_ea = SP; cpu_state.pc=tempw; -// printf("FF 10\n"); cycles-=((cpu_mod==3)?20:29); FETCHCLEAR(); break; case 0x18: /*CALL far*/ tempw=readmemw(easeg,cpu_state.eaaddr); - tempw2=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); //geteaw2(); + tempw2=readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF); tempw3=CS; tempw4=cpu_state.pc; if (cpu_state.ssegs) ss=oldss; cpu_state.pc=tempw; -// printf("FF 18\n"); loadcs(tempw2); writememw(ss,(SP-2)&0xFFFF,tempw3); writememw(ss,((SP-4)&0xFFFF),tempw4); @@ -3393,34 +3067,24 @@ void execx86(int cycs) break; case 0x20: /*JMP*/ cpu_state.pc=geteaw(); -// printf("FF 20\n"); cycles-=((cpu_mod==3)?11:18); FETCHCLEAR(); break; case 0x28: /*JMP far*/ - cpu_state.pc=readmemw(easeg,cpu_state.eaaddr); //geteaw(); -// printf("FF 28\n"); - loadcs(readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF)); //geteaw2(); -// cs=loadcs(CS); -// cs=CS<<4; + cpu_state.pc=readmemw(easeg,cpu_state.eaaddr); + loadcs(readmemw(easeg,(cpu_state.eaaddr+2)&0xFFFF)); cycles-=24; FETCHCLEAR(); break; case 0x30: /*PUSH w*/ case 0x38: /*PUSH w alias, reported by reenigne*/ tempw=geteaw(); -// if (output) printf("PUSH %04X %i %02X %04X %04X %02X %02X\n",tempw,rm,rmdat,easeg,eaaddr,ram[0x22340+0x5638],ram[0x22340+0x5639]); if (cpu_state.ssegs) ss=oldss; writememw(ss,((SP-2)&0xFFFF),tempw); SP-=2; cpu_state.last_ea = SP; cycles-=((cpu_mod==3)?15:24); break; - -// default: -// printf("Bad FF opcode %02X\n",rmdat&0x38); -// dumpregs(); -// exit(-1); } break; @@ -3428,25 +3092,9 @@ void execx86(int cycs) FETCH(); cycles-=8; break; - -/* printf("Bad opcode %02X at %04X:%04X from %04X:%04X %08X\n",opcode,cs>>4,pc,old8>>16,old8&0xFFFF,old82); - dumpregs(); - exit(-1);*/ } cpu_state.pc&=0xFFFF; -/* if ((CS & 0xf000) == 0xa000) - { - dumpregs(); - exit(-1); - }*/ -// output = 3; -/* if (CS == 0xf000) - { - dumpregs(); - exit(-1); - } - output = 3;*/ if (cpu_state.ssegs) { ds=oldds; @@ -3454,8 +3102,6 @@ void execx86(int cycs) cpu_state.ssegs=0; } -// output = 3; - // if (instime) printf("%i %i %i %i\n",cycdiff,cycles,memcycs,fetchclocks); FETCHADD(((cycdiff-cycles)-memcycs)-fetchclocks); if ((cycdiff-cycles) -Your application description here. +Emulator for X86-based systems. + +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +STATUSBARMENU MENU DISCARDABLE +BEGIN + POPUP "FDD 1" + BEGIN + MENUITEM "&Change...", IDM_DISC_1 + MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP + MENUITEM "&Eject FDD 1", IDM_EJECT_1 + END + POPUP "FDD 2" + BEGIN + MENUITEM "&Change...", IDM_DISC_2 + MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP + MENUITEM "&Eject FDD 2", IDM_EJECT_2 + END + POPUP "FDD 3" + BEGIN + MENUITEM "&Change...", IDM_DISC_3 + MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP + MENUITEM "&Eject FDD 3", IDM_EJECT_3 + END + POPUP "FDD 4" + BEGIN + MENUITEM "&Change...", IDM_DISC_4 + MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP + MENUITEM "&Eject FDD 4", IDM_EJECT_4 + END + POPUP "CD-ROM 1" + BEGIN + MENUITEM "&Mute", IDM_CDROM_1_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_1_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD + MENUITEM SEPARATOR + MENUITEM "&ISO...", IDM_CDROM_1_ISO + END + POPUP "CD-ROM 2" + BEGIN + MENUITEM "&Mute", IDM_CDROM_2_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_2_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD + MENUITEM SEPARATOR + MENUITEM "&ISO...", IDM_CDROM_2_ISO + END + POPUP "CD-ROM 3" + BEGIN + MENUITEM "&Mute", IDM_CDROM_3_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_3_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD + MENUITEM SEPARATOR + MENUITEM "&ISO...", IDM_CDROM_3_ISO + END + POPUP "CD-ROM 4" + BEGIN + MENUITEM "&Mute", IDM_CDROM_4_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_4_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD + MENUITEM SEPARATOR + MENUITEM "&ISO...", IDM_CDROM_4_ISO + END +END + +MAINMENU MENU DISCARDABLE +BEGIN + POPUP "&Action" + BEGIN + MENUITEM "&Hard Reset", IDM_FILE_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_FILE_EXIT + END + POPUP "&Tools" + BEGIN + MENUITEM "&Settings...", IDM_CONFIG + MENUITEM SEPARATOR + MENUITEM "&Load configuration...", IDM_CONFIG_LOAD + MENUITEM "&Save configuration...", IDM_CONFIG_SAVE + MENUITEM SEPARATOR + POPUP "&Video" + BEGIN + MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "R&emember size && position", IDM_VID_REMEMBER + MENUITEM SEPARATOR + MENUITEM "&DirectDraw", IDM_VID_DDRAW + MENUITEM "Direct&3D 9", IDM_VID_D3D + MENUITEM SEPARATOR + POPUP "&Window scale factor" + BEGIN + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + END + MENUITEM SEPARATOR + MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN + POPUP "Fullscreen &stretch mode" + BEGIN + MENUITEM "&Full screen stretch", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Square pixels", IDM_VID_FS_SQ + MENUITEM "&Integer scale", IDM_VID_FS_INT + END + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT + MENUITEM SEPARATOR + MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 + MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + MENUITEM SEPARATOR + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT + END + MENUITEM "S&tatus", IDM_STATUS + END + POPUP "&Help" + BEGIN + MENUITEM "&About 86Box...", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +MAINACCEL ACCELERATORS MOVEABLE PURE +BEGIN + VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL + VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +CONFIGUREDLG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "86Box Settings" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,246,220,50,14 + PUSHBUTTON "Cancel",IDCANCEL,307,220,50,14 + CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,90,197 + CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 + LTEXT "Language:",2047,7,222,41,10 + COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP +END + +CONFIGUREDLG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Add Hard Disk" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,55,89,50,14 + PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14 + EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,188,12 + PUSHBUTTON "...",IDC_CFILE,195,16,16,12 + EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12 + EDITTEXT IDC_EDIT_HD_HPC,112,34,28,12 + EDITTEXT IDC_EDIT_HD_CYL,42,34,28,12 + EDITTEXT IDC_EDIT_HD_SIZE,42,52,28,12 + COMBOBOX IDC_COMBO_HD_TYPE,113,52,98,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Sectors:",IDC_STATIC,154,35,27,10 + LTEXT "Heads:",1793,81,35,29,8 + LTEXT "Cylinders:",1794,7,35,32,12 + LTEXT "Size (MB):",1795,7,54,33,8 + LTEXT "Type:",1797,86,54,24,8 + LTEXT "File name:",-1,7,7,204,9 + COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,72,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,99,72,34,8 + COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,117,72,15,8 + COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,168,72,15,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,99,72,34,8 +END + +STATUSDLG DIALOG DISCARDABLE 0, 0, 186, 386 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Status" +FONT 9, "Segoe UI" +BEGIN + LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 + LTEXT "1",IDC_STEXT1,16,186,180,1000 +END + +ABOUTDLG DIALOG DISCARDABLE 0, 0, 209, 114 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About 86Box" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,94,71,12 + ICON 100,IDC_ABOUT_ICON,7,7,20,20 + LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + IDC_ABOUT_ICON,54,7,146,73 + CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, + 86,208,1 +END + +CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Machine:",1794,7,8,60,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 + COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU type:",1796,7,26,59,10 + COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",1798,7,45,60,10 + COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU:",1797,124,26,18,10 + CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,147,81,113,10 + EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, + 12,12 + LTEXT "MB",IDC_TEXT_MB,123,64,10,10 + LTEXT "Memory:",1802,7,64,30,10 + CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 +END + +CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video:",1795,7,8,55,10 + COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video speed:",1800,7,26,58,10 + CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,215,44,45,12 + PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 +END + +CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Mouse :",IDC_STATIC,7,8,57,10 + COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Joystick :",1793,7,26,58,10 + COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 + PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 + PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 +END + +CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 60 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBOSND,71,7,141,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Sound card:",1800,7,8,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURESND,215,7,45,14 + CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,87,25,80,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,25,80,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,174,25,80,10 + CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 +END + +CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 132 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,215,24,45,14 + LTEXT "HD Controller:",1799,7,44,61,10 + COMBOBOX IDC_COMBO_HDC,71,43,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Network adapter:",1801,7,8,59,10 + COMBOBOX IDC_COMBONET,71,7,141,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURENET,215,6,45,14 + LTEXT "Tertiary IDE:",1802,7,62,61,10 + COMBOBOX IDC_COMBO_IDE_TER,71,61,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Quaternary IDE:",1803,7,81,61,10 + COMBOBOX IDC_COMBO_IDE_QUA,71,79,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "SCSI Controller:",1804,7,26,59,10 + COMBOBOX IDC_COMBO_SCSI,71,25,141,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,97,80,10 + CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,174,97,80,10 + CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,87,97,80,10 + CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,115,80,10 +END + +CONFIGUREDLG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,18,253,92 + LTEXT "Hard disks:",-1,7,7,34,8 + PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 + PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 + PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 + COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,118,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,131,118,38,8 + COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,118,38,8 + COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,118,38,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,131,118,38,8 +END + +CONFIGUREDLG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, + 7,18,253,60 + LTEXT "Floppy drives:",-1,7,7,43,8 + CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 + LTEXT "CD-ROM drives:",-1,7,106,50,8 + COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Type:",1803,7,86,24,8 + COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,184,24,8 + COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,184,38,8 + COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,184,38,8 + COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,131,184,38,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// 24 +// + +1 24 MOVEABLE PURE "86Box.manifest" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box.ico" +#endif +128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" +129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" +130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" +131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" +132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" +133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" +134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" +135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" +144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" +145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" +146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" +147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" +150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" +151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" +152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" +153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" +160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" +161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" +162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" +163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" +164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" +165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" +176 ICON DISCARDABLE "ICONS/hard_disk.ico" +177 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +178 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +179 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +180 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +181 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +256 ICON DISCARDABLE "ICONS/machine.ico" +257 ICON DISCARDABLE "ICONS/video.ico" +258 ICON DISCARDABLE "ICONS/input_devices.ico" +259 ICON DISCARDABLE "ICONS/sound.ico" +260 ICON DISCARDABLE "ICONS/other_peripherals.ico" +261 ICON DISCARDABLE "ICONS/hard_disk.ico" +262 ICON DISCARDABLE "ICONS/removable_devices.ico" +384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" +385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" +386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" +387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" +388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" +389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" +390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" +391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" +400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" +401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" +402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" +403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" +406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" +407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" +408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" +409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" +416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" +417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" +418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" +419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" +420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" +421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" +512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" +514 ICON DISCARDABLE "ICONS/cdrom_disabled.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resources.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + CONFIGUREDLG_MAIN, DIALOG + BEGIN + RIGHTMARGIN, 365 + END + + ABOUTDLG, DIALOG + BEGIN + RIGHTMARGIN, 208 + END + + CONFIGUREDLG_MACHINE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 105 + END + + CONFIGUREDLG_VIDEO, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + + CONFIGUREDLG_INPUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END + + CONFIGUREDLG_PERIPHERALS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 125 + END + + CONFIGUREDLG_HARD_DISKS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 137 + END + + CONFIGUREDLG_REMOVABLE_DEVICES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 195 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + 2048 "86Box" + IDS_STRING2049 "86Box Error" + IDS_STRING2050 "86Box Fatal Error" + IDS_STRING2051 "This will reset 86Box.\nDo you want to save the settings?" + IDS_STRING2052 "DirectDraw Screenshot Error" + IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" + IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" + IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" + IDS_STRING2056 "Please enter a valid file name" + IDS_STRING2057 "Unable to open the file for write" + IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" + IDS_STRING2059 "Remember to partition and format the new drive" + IDS_STRING2060 "Unable to open the file for read" + IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." + IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." + IDS_STRING2065 "Machine" + IDS_STRING2066 "Video" + IDS_STRING2067 "Input devices" + IDS_STRING2068 "Sound" + IDS_STRING2069 "Other peripherals" + IDS_STRING2070 "Hard disks" + IDS_STRING2071 "Removable devices" + IDS_STRING2072 "Disabled floppy drive" + IDS_STRING2073 "%i"" floppy drive: %s" + IDS_STRING2074 "Disabled CD-ROM drive" + IDS_STRING2075 "%s CD-ROM drive: %s" + IDS_STRING2076 "Host CD/DVD Drive (%c:)" + IDS_STRING2077 "Click to capture mouse" + IDS_STRING2078 "Press F12-F8 to release mouse" + IDS_STRING2079 "Press F12-F8 or middle button to release mouse" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2080 "Drive" + 2081 "Location" + 2082 "Bus" + 2083 "File" + 2084 "C" + 2085 "H" + 2086 "S" + 2087 "MB" + 2088 "%i" + 2089 "Enabled" + 2090 "Mute" + 2091 "Type" + 2092 "Bus" + 2093 "DMA" + 2094 "KB" + 2095 "Master" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2096 "Slave" + 2097 "SCSI (ID %s, LUN %s)" + 2098 "Adapter Type" + 2099 "Base Address" + 2100 "IRQ" + 2101 "8-bit DMA" + 2102 "16-bit DMA" + 2103 "BIOS" + 2104 "Network Type" + 2105 "Surround Module" + 2106 "MPU-401 Base Address" + 2107 "MIDI Out Device" + 2108 "On-board RAM" + 2109 "Memory Size" + 2110 "Display Type" + 2111 "RGB" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2112 "Composite" + 2113 "Composite Type" + 2114 "Old" + 2115 "New" + 2116 "RGB Type" + 2117 "Color" + 2118 "Monochrome (Green)" + 2119 "Monochrome (Amber)" + 2120 "Monochrome (Gray)" + 2121 "Color (no brown)" + 2122 "Monochrome (Default)" + 2123 "Snow Emulation" + 2124 "Bilinear Filtering" + 2125 "Dithering" + 2126 "Framebuffer Memory Size" + 2127 "Texture Memory Size" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2128 "Screen Filter" + 2129 "Render Threads" + 2130 "Recompiler" + 2131 "System Default" + 2132 "%i Wait state(s)" + 2133 "8-bit" + 2134 "Slow 16-bit" + 2135 "Fast 16-bit" + 2136 "Slow VLB/PCI" + 2137 "Mid VLB/PCI" + 2138 "Fast VLB/PCI" + 2139 "Microsoft 2-button mouse (serial)" + 2140 "2-button mouse (PS/2)" + 2141 "Microsoft Intellimouse (PS/2)" + 2142 "Amstrad mouse" + 2143 "Olivetti M24 mouse" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2144 "Standard 2-button joystick(s)" + 2145 "Standard 4-button joystick" + 2146 "Standard 6-button joystick" + 2147 "Standard 8-button joystick" + 2148 "CH Flightstick Pro" + 2149 "Microsoft SideWinder Pad" + 2150 "Thrustmaster Flight Control System" + 2151 "Disabled" + 2152 "None" + 2153 "AT Fixed Disk Adapter" + 2154 "Internal IDE" + 2155 "IRQ %i" + 2156 "MFM (%01i:%01i)" + 2157 "IDE (%01i:%01i)" + 2158 "SCSI (%02i:%02i)" + 2159 "IDE (PIO-only)" + 2160 "%" PRIu64 + 2161 "Microsoft Bus mouse" + 2162 "Mouse Systems mouse" + 2163 "Attempting to create a spuriously large hard disk image" + 2164 "Invalid number of sectors (valid values are between 1 and 99)" + 2165 "Invalid number of cylinders (valid values are between 1 and 1023)" + 2166 "MFM" + 2167 "IDE" + 2168 "SCSI" + 2169 "%01i:%01i" + 2170 "Custom..." + 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" + 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" + 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" + 2175 "CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0" + 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + 2177 "Microsoft InPort mouse" + 2178 "Genius Bus mouse" + 2179 "Floppy %i (%s): %s" + 2180 "CD-ROM %i: %s" + 2181 "Removable disk %i: %s" + 2182 "MFM hard disk" + 2183 "IDE hard disk" + 2184 "SCSI hard disk" + 2185 "(empty)" + 2186 "(host drive %c:)" + 2187 "Custom (large)..." + 2188 "Type" + 2189 "ATAPI (PIO-only)" + 2190 "ATAPI (PIO and DMA)" + 2191 "ATAPI (PIO-only) (%01i:%01i)" + 2192 "ATAPI (PIO and DMA) (%01i:%01i)" + 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + 2194 "" + 2195 "English (United States)" +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,20,0,0 + PRODUCTVERSION 1,20,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "IRC #SoftHistory\0" + VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" + VALUE "FileVersion", "1.20\0" + VALUE "InternalName", "pc_new\0" + VALUE "LegalCopyright", "Copyright © SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "86Box.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "86Box Emulator\0" + VALUE "ProductVersion", "1.20\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/86box.h b/src/86box.h index 0b4ca1f9c..09f0a8a15 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.10" +#define emulator_version "1.20" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index dc84277c5..000000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -cmake_minimum_required(VERSION 2.8.8) -project(86box) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/CMakeModules) - -ENABLE_LANGUAGE(RC) - -set(CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILER} -O coff -I${CMAKE_CURRENT_SOURCE_DIR} ") - -set(SRCS -386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c acerm3a.c ali1429.c amstrad.c buslogic.c cdrom.c cdrom-ioctl.c cdrom-iso.c -cdrom-null.c codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c dac.c -device.c disc.c disc_86f.c disc_fdi.c disc_imd.c disc_img.c disc_random.c disc_td0.c dma.c fdc.c fdc37c665.c fdc37c932fr.c fdd.c fdi2raw.c gameport.c hdd.c headland.c i430hx.c i430lx.c i430fx.c -i430nx.c i430vx.c i440fx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c joystick_tm_fcs.c keyboard.c keyboard_amstrad.c keyboard_at.c -keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c lpt.c mcr.c mem.c memregs.c mfm_at.c model.c mouse.c mouse_ps2.c -mouse_serial.c ne2000.c neat.c nethandler.c nmi.c nvr.c olivetti_m24.c opti495.c pc.c pc87306.c pci.c pic.c piix.c pit.c ppi.c ps1.c ps2.c rom.c rtc.c -scat.c scsi.c serial.c sis496.c sis85c471.c sio.c sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c -sound_dbopl.cc sound_emu8k.c sound_gus.c sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_resid.cc -sound_sb.c sound_sb_dsp.c sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c -soundopenal.c tandy_eeprom.c tandy_rom.c timer.c um8669f.c usb.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c -vid_ati28800.c vid_ati68860_ramdac.c vid_bt485_ramdac.c vid_cga.c vid_cl_gd.c vid_cl_gd_blit.c vid_cl_ramdac.c vid_colorplus.c vid_ega.c vid_et4000.c -vid_et4000w32.c vid_hercules.c vid_herculesplus.c vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_nv_riva128.c -vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc1512.c vid_pc1640.c vid_pc200.c -vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c -vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c -vid_vga.c vid_wy700.c vid_voodoo.c video.c w83877f.c wd76c10.c win.c win-config.c win-d3d.cc win-d3d-fs.cc win-ddraw.cc -win-ddraw-fs.cc win-ddraw-screenshot.cc win-deviceconfig.c win-hdconf.c win-joystick.cc win-joystickconfig.c win-keyboard.cc win-midi.c win-mouse.cc -win-status.c win-video.c x86seg.c x87.c xtide.c pc.rc -dosbox/dbopl.cpp dosbox/nukedopl.cpp dosbox/vid_cga_comp.c -lzf/lzf_c.c lzf/lzf_d.c -resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc resid-fp/voice.cc resid-fp/wave6581__ST.cc resid-fp/wave6581_P_T.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc resid-fp/wave8580__ST.cc resid-fp/wave8580_P_T.cc resid-fp/wave8580_PS_.cc resid-fp/wave8580_PST.cc resid-fp/wave.cc -slirp/bootp.c slirp/ip_icmp.c slirp/misc.c slirp/socket.c slirp/tcp_timer.c slirp/cksum.c slirp/ip_input.c slirp/queue.c slirp/tcp_input.c slirp/tftp.c slirp/debug.c slirp/ip_output.c slirp/sbuf.c slirp/tcp_output.c slirp/udp.c slirp/if.c slirp/mbuf.c slirp/slirp.c slirp/tcp_subr.c -) - -if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_ARCH_64 1) -else() - set(_ARCH_32 1) -endif() - -include(FindOpenAL REQUIRED) -include(FindDirectInput REQUIRED) -include(FindDirectDraw REQUIRED) - -if(_ARCH_32) -set(SRCS ${SRCS} -codegen_x86.c -) -else() -set(SRCS ${SRCS} -codegen_x86-64.c -) -endif() - -add_definitions(-msse2 -mstackrealign -mwindows -g) - -add_executable(86box ${SRCS}) - -target_link_libraries(86box winmm openal.dll openal ddraw dinput8 dxguid d3d9 d3dx9 wsock32 iphlpapi stdc++ psapi wpcapdelay comdlg32 gdi32) \ No newline at end of file diff --git a/src/86Box-RB.ico b/src/ICONS/86Box-RB.ico similarity index 100% rename from src/86Box-RB.ico rename to src/ICONS/86Box-RB.ico diff --git a/src/86Box.ico b/src/ICONS/86Box.ico similarity index 100% rename from src/86Box.ico rename to src/ICONS/86Box.ico diff --git a/src/ICONS/cdrom_atapi.ico b/src/ICONS/cdrom_atapi.ico new file mode 100644 index 0000000000000000000000000000000000000000..cef9124add04491f9f582de8843166cc3f652855 GIT binary patch literal 1150 zcmaKr%THQC6voH2i#A=`~aF22d=6B|tGv8&bk3aqWjK4oI(`&{) zGR8i0<1X%b^z#p6eC@-#M-%fGUMiL9>)6=Xiq&c@E-o%UEG#VC+wJxO_bm?%4Sjh5 z5iY*|R;SaseLkO5sZ=N)kJHi75tYkjDijKIaBx6ww_DO^G^>MygKv~^z?w{^aH&+H z+uK`eG#ZphBnWev&*gG-cz8&=ySvilX&)+*K9Ty zTrSto%gal_pPijiwOXZMFeo^K!I0#AO(9Mo5O~JV%*^!u#~Y2t6z9|b;%zot*WqxK zpPrB0l==Jpeu~9nqBdpz)6>&A-oLfe(^Cocqvyz<&xL+a$Ii|UrBW$EZO6yQqR;#L z`xFj`X>@dSd3bnuV10f47x?q@b79zvSTHc~BgcBZF2<;5c6L_ccQ5n|-9n$x-ObI7 z&;jm5z87%Nlx)x;*X)|CVd!^iYAOuP-QC>@Yq#4%OU-6e#Od{V)a`bKp7_1&DfNpu zh%qrS;qiLC63*>(I>HbSc|n^S8ygbObxp6=|MmaKdEm=?GQeYr|95_V{(f$5?!jWQ el(>IIu2;Fg^`5c4SB%;F9!}+Fv|=C5B;u8^${D?(Af^K47|= zjNNC9Jw%`hEwUXSjN!L?cVzJWKbD@Jp2te1a&ByFEIBhXb2>deePTA76B>hNS#Sv% zaY+QNR~r*-!qav-a&BuhnpaMzvz5(eVSRlaGMNmd(`i`xwglo=5k#pCxEJ2YK8UN+ z=>n-#3M!Qf9336O#>NKFp7^GZrmNg@KU$CW3+13zt6$SO;u6Z`G9;5pNF)-RFTTgP zx#xfTKzmYk&*uZ@C#PJ0`q?EP>sRa5%M%k5se^+9C>D#HOF6Huu7ca`hDapBLGO+a z4j5g=_}KrEcO&5b>;}DFpO~GUJ=@>k=lpy=54*d&;P?AEZ)j*JgngCBkJsyk&CN{+ zhrzs$+3+5hO_hs%>j)i}!hLZ4Cl}04NlS7rni`U3R z7$D8nYBi2(waT@0e0 zX>(y=p@q554-5=k;kNt1o^+uv{{K!*O`S|mPM#W##uVD;F6wPRU+!RR1r6qN;N#lM OjOPg}HyA75W$YK57`cl8 literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_atapi_dma.ico b/src/ICONS/cdrom_atapi_dma.ico new file mode 100644 index 0000000000000000000000000000000000000000..972e1001f88a7d3fafb242ab33a9606083fc076e GIT binary patch literal 1150 zcmaKrNla5w6owzsg~mi0V~B|)WmF_su?tzSkSMSaMWH||5s{&Ql9(vnNF)*h3z@~x zf=mGsFwQ`5pemyT2%{hcQ7KY1;y^{pppV~kODZ*>c{y)5?|%Oo?ztRiL6<*^J+7+=PdMU7aN1O3w=!ny}2Gh2Zq!dB22=A(12^ z*TyGk&l-r)WgQr}Q7n_^Cs)?;S6&;is~LzG29Cc1d|v{RE(1K2HN10xTqWEey1`tB zu^w_oW8Ls1TJ=EvSHPtO2p(MF5A*_VU4ZzJj^A-o@!VWPB#ka$Y#XtRZ<+=|`hlZl zruZh_r5&)ZnSiaoT*Y#5@;fCytg7YZ13>N63a@+*cy+JM+r9v-(;o1wAFe@iRraU> zL4Cl%PT=x8ppoKV?A2rQ^)XmgXd!;4hk1O)Td8MZb1W=3EGcWalHwM804@<5KsxSE z^>8fH;70eD(Hu%Oa8~P$^|SmLzm@vC{cP$`Y~Zk{0Sg!oc4`2!jwN_?J55wO?voK zZM)l-%<@kk6a_}+m5m#CR(}rlJd5}=s)1?PQ60icEzWf4QB2w?Zva`}5(Mf+SU#MA z9re$_H)L;YY0a+^;!7rhLh3;tt<5E^9MVdD3zU)X)<@tbSt-4HcKn1O=??GcbHX^! zBH8Kut9?2={sPpIRnvalBfCv~EhWt=;#z4>o4?U)k(KmMz(Ep~XPRL)ziyF=#=9CF zx_pX(_tDSY0R~RifX=f%76h{+cyhz zlGYPC51pS4NUf^o#j=<@Vd&rI$CL+qvVQE8L@K@G(>2nx;(1AG(ZW7O#;~1VxYE%t cY}NUlw&b{mbsU#yv25mAYrUJ+F@~|f0leCMbN~PV literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_atapi_dma_active.ico b/src/ICONS/cdrom_atapi_dma_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..17c857426c2299b508179828440500c9c4311558 GIT binary patch literal 1150 zcmaKrX-HI26vwaBha$)cLV|)RQ!*+uKP2Rb1eXtGi@A(hrfjNx#!&b7&D@uK)~p} zmj!NS%!Dy!L81^v^l=&(qyKhn(@XdMkDKt6mz9O9IK$yql9Ef#U+_vSn0JXv8nh1; zSNm3oM}qI3a7pC3z(H{)=RhI8@t%-NEsLL8%3crJwYC>Ld`S0)*u%9p@ko zRX7ENb(fHjphN|mSJc-IU|$=sllEsUj$B2~-2`VM=uf%T&15 zsYU^L$GrtSdzT=nUxab(EKJXH>1JoWj|CMy`&~$U;S`WZJ;ExA0Ua_MV^z6|23xb$Rt@-K8M|J1N^J@0}-bp#7MkEyRk{7CMXdH2*32jLZS_S)gus0=9nP4Z@Q? zTUK~}4oG1fqV=w;Ec;T28uc{OZeY{rrR&|M-T?Fxm<~sa1KXEIHa4g*<`g5DCz_Z zOA#CqNtu*W^9PoN9_R7f^PaPlzsj-ayquTk^L>82&kJKU^r@|7^t{AwoM!AIW9%{+ zZPAXtPYYx8+l6zwY47x?tE)R?rVj5_tKfG#`=cNH(J{pvNo>1cL<@Ey;4*c1t{n9@ z-kU_vS%)NhUZ!*E(2@dc5eO^*UEcs#84%|bJc?)4WPB zH}L)!U?bj3tiiW^0a`u-j$B2(>kADZ)UZpzF3x_cLgQyi!$&cB+@rj$1ei1HxZ{=u z9^2~bzW!u5r^*y7_hX+QSp}RF?_a!W7HEo0tGplgMOhf6dZl@wjr=3ufg2m^%F~e>hg0ptxh}K$ut$={%UJ!jfD>dVW5uE2Q|_B;4~8;tNT(sWdW^r-KeiQ&oxlhBGEO-( zeF9&V!m*Ek!R+$8ES^thw zTe1{=cb0b15S~;mkA2!a+oc{)yj($k6PO{((s^XaCds%z=lERC(z$X=mDgc$%c3#E ze12Q}q0uRt!SWU`M`p}of&8aQ=lc$@tk7&PRnRJjMh?!eaR+RkXVO4AtCoH$SRmi8 z+qxFN4|AJ4h)iTvhbJhSe24Fkkq2LSKdgf6Zm0Vz(cKjy38m$Ev`D>jTU_18?(fEV W#zsytcCSV^$=kT28{$1zX_j4Z@E2D3DIiu?pcK0k}ml`FR=`qi2^cnxkuii>sxSJ@OH~5qbC?nziO`&VEZH$Ip?6J_#sDoEP5Fx=WA# z_n>*1qUYv|v1ryranWBVyn6$X&ljz~PzPbYrqrYV&SZ<)q#B`owTr-0inp%;aoYbt zG7YhJ9S{7QsP~5Q`Oj9L@RYxpYHApC#zVBOXA2l4Rzp6Ir_+%7mJwXs$Vuv5My)4= zdPhBY{qOZxp(+qTt;HU*jQI9LsXRYQ9>eQ^B#`IiroPEevo-vIe5!pLXs7)(CFuDa zaG&a1WAp5qou}}|zOdY6jhw=#wS&&t(^Qw zGtFwFIplz8hs@B>9;&_fa<}Ctn|75TE2gJHLm0~W_EyS(iFXqFlmCs z<2lFsa*p0Bmp{1$snVn_^gr+4c7t_%l6o+?3w$RPdND@v5%O8v2UauG+bi4XFj?J_ zj+f^OJRiA7ljfCnAUKsx{LWyBVt?%Az4&?fzOxT|Xe!&PF{>r|QnuKK*F&Z vYU%8%?A}cKYe$@FrIadqa`_g=r^*;})Bix@k!U#e(@61L?lX*~E;9BHdr9}Z literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_atapi_empty.ico b/src/ICONS/cdrom_atapi_empty.ico new file mode 100644 index 0000000000000000000000000000000000000000..67c2c834705f6c5d4ee1a05a95e3585017bfc0a3 GIT binary patch literal 1150 zcmah}NsC%R5bhy!NXQ|ROU^mwmP~$>%+JW(n>y~Gs22qhmxH*F(TliykZ|JN$JiD9Zf+PoKeM}Q#y&B|z7WVnmb0A}#%S;3`!mEl zJv1843+QyZZx)Ni7zhMv@p$}5cn*a^k7T>o>-AqR{pCCDzq8xzmRv5UOs7-cZnybl zGU4O#n2$yy-tYH$DwR^KR;x*?)xMQHtl)Y)o)mod`#s-ox4hHo2(IK01_KeJR;wva zr}L*e2F0{VF8Ba)0+;-5x67;5DyN(#8~>Be>u%77LD?|KdYiB9Tzg z57dKthr^-JH=E5w3~-CZA}^QAyxDAuSm*)rgAbd@WV(+;B6Z|ltyUadXvQA6yS14L~UyQKA*2j{WFth1@)un&<`L6>Hxq&ZRijBjQ-T? zb`3SXKZvz%ef zugm31;p`5F!ymwRx7&$Wr_+fak4G_2bS@9-`IUFTX0utd*{p)x@C6W0YRc#H3TZVv z9F7zGj&UP#QlxMV$X!5-|w%JoytAetM*@hVC>-yV?VCWkl%&ZR_O;0xW563 CS0l~< literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_atapi_empty_active.ico b/src/ICONS/cdrom_atapi_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..a6d2044995626f20c09f62c423b07752da5e5655 GIT binary patch literal 1150 zcmah}+iQ|x9DYY#6kW7#y6&>OT7O6XgnpX@5p)y5AaLw*cVeDH(A`Yt#KYQ9Y|aAl zEKw|nh{q|4r+J!^y#1cneWgY9eLUaG_xpa&^E)bID|D}}GI~B>&u%hypE353Kqj)x z?Q}3k-|pR+L%h>NrBW?HqtQGz8jU)a%k?b~2uui99*^g2%eZy8ez2aCd=gh4D8DF7 zil>WQ;@q}aEXG(YHfuJUyih3cMx(*&^*TTKe8Qzq5|`2opm)W)xdynqySu0G9gRkO zFc|P+u_(B(ZGYHa=3eV4oyw2M!DKR-WiI$YtyU9&U3yP(t8f0)AiGYddlC+ZXYlLy z`+^I8r_Yssfo}qs99Qgy#Kpg-$s13bEpV6OeHp}&T{adY8 zyB3K=zJm`R8PEd2fo(BI5M?)U;hg)ArYd z*nKSo-BA+ExxcWm@GhNBw=OR)sZc0TsZ^41yT4L*_a_=3Pu|YW%}w|Aet06po?nRl zSKx!Yw6qkzxVWHty-u}Sjf%x0VGfPqVT*je91RUww6gN0wYa#r*3+Xu3W_92Q6A&J|w^2KdotdJ6^B%rC}H?#8<1;pZu$}T6HWwTkDn)*ymXO;}3Kqn_B ziYV+g?%fPisV8km&-{mVu5tprpd`e&cmj@K9l{h$>lm?FT&}qt*r*Q z!1eVtA@75O1IY`8Lfh=?4m2{EjLZ-J;VsT57K>H?!{1@P@i%@v9f&*!B_o%@Hw;S~GlX3tvCK<)rMga+z>f8d}ttSf(xkB@0~cJ}Se%*;S4m1?T` z5vP1mT9|j{2)&JsjTWE%bMz1T7H5aP18^P+il_PtZ^UxXy1~VR{tX6$vVR+m1}Pv` z={1{8y1BWL{mADMo0yom*JigzXmB6D$Njg|j#@g&9={Q-Xc^BL7RmJ#EdUwSCSchxonw*UYD literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_scsi.ico b/src/ICONS/cdrom_scsi.ico new file mode 100644 index 0000000000000000000000000000000000000000..50111bc5a5045a9dbb24c1db965d81bd5305c742 GIT binary patch literal 1150 zcmaJ=OH30{6n#V&8W$25u3ftGvm&q{6k5Q-!o);KS+J8BVlV~>iHk;2(48a{5EH;4 z$hV*Z8bhG8K*0X|w9^72v=nOjltDlkogD9*T5P16$({G+^`3Ljz3-H<1bPw^8NJW2 zqN9wRW{jPspd&hooYTS>{dVd^B$V$suh!(`^G3DWFkVvPu~t>?TkqZ3vy|QvdNVU? zpQogpivv-PI+K!)_i42ap5|s*n)L!xCScA6%uEBqB&7Fa5NaOE#;mNmrqtA9u{<0* zq|=$U+-_iV9as+m(_?`5-2omhGw^W~;@d8H@XFbE`v+S>usYee<)`W!D=jObRWYR4-oyjb-E!7sof@wlwO$S|a*?O3%tl=#uo zMrQ*`|4}@wgD_t!6l~R15<B?Uo75QTKwHs zegA)W$AC`f{3pJwcz3+KZ04YTfO_|lhRF#8ynTZS3VD8rrKb>dBbC? r)bCmE>h~?h*S*G!3`37bbLjuOd6KcwBaG=2A`#0KZy(L$7>@k~?+4Mi literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_scsi_active.ico b/src/ICONS/cdrom_scsi_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..d51e28c82c00e7c1d5b97ac33b4aefbf8b63fa36 GIT binary patch literal 1150 zcmaJwO)D@Kco?1rk!J;THMyZVwlwkHKwHP<`y zT(W){q}|f#yt=&fNP0(1%<&$Hq}JZt91hJofQb>nWdxj)u#C4urk6oxjsShkSpBlkUz!7^#`ojTl|kk%IiPVvnQKy~roITdY{0Y$FjKra z7vNu`cZ%Qo8c-@>8GI?$?=0HqQ~i(guV_Zg%NXDoDd7pLt2n~0kJ1OCL zXJX<7d%fZZyz{^^`FQB$cgM9BNy|<7c$TO?E5ORK_--15OL`^T9ewwWfnkz!kVnR=9N)6}oCCqQ;wUOWq&Cpjrut~l_@(t1) zY>=jp^mev@?JWdtRt#olYMbKXj)`n>=Ni4~m+Ndz4dD=vy&WV3NRPBAuaM6RTT64e zHzT9wPi~|R?}z$QvO-sU%WkZc?;0M+_wAK7A`uI^!KcmaCL0EmImeJ#eRMvm`y(NOhzA!-Z<^=oMWT+E-Dk= z$67dS8oPC%lmi+nuv-GOB8;7FXsho`#p{{c7<+iZ;YlmG>Dj<~PpbiX7wC2XH4oIu zJ>o;-`CATpHg2Zb-`sxQ0^&Ozo zKIZT5F<f-oG;CJY+vcLj!6RpvruEyLOBU&(SYHEDGc^ti`Th=9he znk>9r$f45&+6{7L9L_A4g%SCTj;dNP!V%u3to|K7Drw~Bo@LdQ<-=e6)^}i^vyaCt zUMk>Erk~6zGLBUX=Xa7{4n6Pvhp(h&1DpTg>xG5T_Hlmp-ee6W?)!B81@>R#K9Bmh z>wlWz?xu}q-L(2|at0D|hKzw&jCB(w@|v7cgZFaIg%pfj0tt_6GVXTW(mt&jXmejJ z`m|`}?wnW+*3;VOd|Ni;_ev4kV#rL4k6C)&q;B;JcPDk%r3O0mwLo7PvrVg0TV1Km zE_ziJiq}2uXxP&4jDNjXqlWtQ>mBK^NB;xH{K0sK17I+K)M+{}vvyLy&O5N_^ZK>$ zhG|Iufo?;_V_gQdsYSx3;+vR0&2{RKR?Z{ob^G$c`7QPBn|^ue^&me#ms33BzJ$kp a=KXD57Gmw35O;@cIR6WOvyPwSNbXOZJ~hq& literal 0 HcmV?d00001 diff --git a/src/ICONS/cdrom_scsi_empty_active.ico b/src/ICONS/cdrom_scsi_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..36ac042d0ec8d0d00ac8d0c71d770daf55e10428 GIT binary patch literal 1150 zcmah}-%nCu82(&c)Vj!Sy6&>Oe*7K%6LK1JYi-@MHk+H9H|0`cC>cU}W3v%dChFR9 zI31)2=L~X)pl~2LBohyTAnvfI_d7=eb2Hd;KE99ldEWPX-)D!h4*GU>GJ4)(-Ip1= z$r!s$pd&gl&S_zc{=0F_fWD`P*=#<8;K0kf5v#?Xa=+iqEchCk`PrkS*Bzf6?e&?x zLQ0qwVDg%NbUC^nv~xoPFRqFswl_*3(A4${Kso^wWneE2DY^h*MSvi-f%aW4LxXc; zF6UBR$pf`2P^|!R5-6l~e*a?sS?-CB$zxjPHBjDhgL`Q3xrUM>?C5-9j`HsIp4XuB zux03eVewlNg`YsB+~ObX1H0R;{F!GEcAlQm=ypGhh&JnMt*8L`ERdso`+J5)miB9_ zKxhrp>Wp#!ttTx$-G5^Axi9t6n?R)ml#9gWI@Gg799r-@DzdCY3j`qrKcVMq4|x9{ zeRvEh{29rq$+)~QfBcuP{sIoD_v;~@7j-%!v9~Uf>*%%Y(oAx3AiF_`A>(;h{|{e` zx}4Gl{94NE*=psdyO*ej^!B;>k)nC#X`XHQlT#BLG`lgaRA}n=FHsLTcn?Vfp%B$g zNE5F_Ju1>U?{g{&EfGf8IyAa&8M>z|`!$qlUMj_?wDQ@VY89y-^?>@T8sNXP+fZgb z&G7Kx9qu2Ad|S)X?6~i$Y!MzS*Eo{-l}qMR#DH%5N(#RQ~&G!9d|6%^W>o; zimRXauuk!Zr1_iljvGLu0q)b7bKJi&`0C0jpRZg)vfCU=V5Onjwh* literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_1dd.ico b/src/ICONS/floppy_35_1dd.ico new file mode 100644 index 0000000000000000000000000000000000000000..55842ba5d5c772b68ebd7b15d21d505b94d74a9c GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NJAW=YF}wU;ICR z)h(j%JfJ!i*Yp3`bk6<&nIW#-^uM(A^#6D7-Vu%MV{ZIs)w%c|q@Pjq^8bR?dqnF6 z*)yu2+TnMXqVN~By7u28_Bv76KIZy=4ufkb@z1Dr<39*1*dPDz9k&$)JB4rgZy&Pd zzh}&r|B4RB!0JG1k<$-MziZ^S|4ZjjLBYD72f=!pTW9_Eh}kym^s{K4{llVt@jnPV shp+!XXIc*m?(OdV-`>{uf5zmV|L&3N!RkP2*|bj|0_8top+OM_0PEwnAOHXW literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_1dd_active.ico b/src/ICONS/floppy_35_1dd_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..b6728029a9761eb6b6871c6bd3ba8ef3c1d3b09b GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NJAW=YF}wU;ICR z)h)cZcj>nOIqS;)CvQpqA2Fxozmo5oUm!EYwVVEzwx0g~?%g|__{jAm|C5g-|4%-T zgn|6TxrsiEnwS3arMqrYfv(f{NJ z<^PlKm7X(-LE%q~`_bdZ zKIX=MR-KDT`tRZme?t02t*-rdh`mk}wvV~~pTpo9iv5gQH~xdLg8lLT-f>$|uv7S! z|MnqU{(Hu3`LF1346F{M7TNtU{jQPQ{x6+B1qJJR9t7)YZk_etBWByM)6b%H_798p z#s47e9KQbloM}BMxVO9ae|uZs{~42e{<}x62de|AWz#-=2$X(+g$8y25+?!!09%f# AH~;_u literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_1dd_empty.ico b/src/ICONS/floppy_35_1dd_empty.ico new file mode 100644 index 0000000000000000000000000000000000000000..4299c47edd659c41418365a10238c5f7eeee34dc GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NIdJ4}bN~efeB?moHz4#yzv2|Ie&_^dF=@z52=jm0MmD ztruj^sD5gP-z$p3zqsw`|K2&ziNf8pp8wCTe~J?S={3*)gK%Zn-T#y4UP8frGcW${ znSSa2q&b)VS9RS1s{^S;PCqdH6J}lhfAZKq6x=xBCRopwt%v_l1eyU;J6!Z<);#=3{r}*;UH>NnvYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NIdJ4}bN~efsoU~@&6fNBzkK-I5*KJz52=jm0Mop)C)4Vd0#WCUZ^=qYm*KWqd$2Y(B7xDm}UUQiO~XVW t&;37qU>6GBwR6}1ZCiK$Ke%t#|A|0(nA)t``-ed32Uuue2Ox1GFaSz(2Au!^ literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2dd.ico b/src/ICONS/floppy_35_2dd.ico new file mode 100644 index 0000000000000000000000000000000000000000..7957e2e2f6ed49d7cae273c37c6ee950a8c40685 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NFw?Y<_KN%ldzA z_j=;+uJ!-dlm!1@l5Fz>WJZps$^V^md;Y(B_l{`1qdoKgvQ*puApOfztp6Wh(nqvj zkUgXNsT+RB7LyqMZ5b%>x30kJ|8`)U5{p-7I-=-boo4eNgqP)c|6f{{jDivYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NFw?Y<_KN%ldzA z_jc$)m*Ik)HkyLaz!;v?6O{7*iT{6G0T z5(e@U=O+3rPqF@gd`TZpy&!X&_cf#Hg_@JJHt8@i`jfW-?R{E{X$DZ782w=TAC&)3 zzE_H32C??T{ePNK1GAiONk`~T9qWE8xpBIf_X@~Hny zY7+l1&-VeV1FJ=HKTQ9U>iGXl=TAYw%Zh`*dKOHm|GyMy223ro|6yW7QUBs(>p#m< zfMEy3^U7oX&zaVPf@k(O{h!fO|9|$B&j0f(;=t-aY8NHj90H{uV4;B>fW(Qw0LQDs A&;S4c literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2dd_empty.ico b/src/ICONS/floppy_35_2dd_empty.ico new file mode 100644 index 0000000000000000000000000000000000000000..732514db2776f340ecbfa97c7568dbb1c363d3dc GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NK5@cKy1ved+&4 z*Ul4-&#s;R|M=prA0RW9O>X^v^~kROU%q@H8eiS9^#92v-Ty)QPcH8IfA8dOqV8QS_f#+VvlVPp+K&|Kz5HDEQd=x&M!? zoAdwV#s&XRt(*c@2Ud%ee&G5y&i{Y%*gjOeW;$5UvAvssX3QUU`j0Q_`UA>CAbe!q r-2aCU>_WkZ_H6loaMz~)hxhIHe{?-Ce4uKNE$TW1%74H@gCYz7BHu5% literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2dd_empty_active.ico b/src/ICONS/floppy_35_2dd_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..c3dd58afe91de52c0edf1015113c0b4bcb6ce0aa GIT binary patch literal 1150 zcmds%K}!Nb6vrp%*2ONJJN9Av5;~Vaf(}L@rNO# zWCsh0pl{$wg4dgMF(*^DYrFhsnYZuve=~1~C1eHfK!D)5Np@BV*&u{$p)iDzNgN-9 z;Jfv;iQG93os2YoY^d=5+*_)arNLo60<=aUqJ`li9UF6xynGCOONY^Dv{25A1Jt5G zdo#j$Fd5utSqX;hY9Y&g<3?O$J)h8J$n?Y0I@bL-n)krCAKtD1b^vs^FL?N^?+m>C z5B9$KKkT3PfO|yssN4T=X%~u040!+jtpDe?={HqixsxgX>MZa79N)+a{6kTOr$)}V zy7^Oq@2V1Tv4RY&nh|7|lVEG-z$$6DFPyn~Ztl$br+g&^%r-=o5-ww3SJ5N&@A!@) reeyHFWobz;Z*)QJRt;|TDwswS?#kF7FV|M2Ha|c3)A;@3aUc2ugDDo< literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2ed.ico b/src/ICONS/floppy_35_2ed.ico new file mode 100644 index 0000000000000000000000000000000000000000..449d68203e8235eb32da724977e329b196ba5629 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NGVH#=lCtQvPq= zvzAD_=6`&p&wsBB;~yY1Y)FUX#p z>csypQO0EJFX>MH@0~@y{liZGG7{sjI|(KHB1)b9gTjPZ?4NIeqTf5m_&*3o6}$W| zYK%j{d9~5N_>TNv*bw_ay2KT%4y+z2{$Tp^>Z1NHoj(NyxA*k@ukW1jf9ABl{{;;( z!%u&P(I4+DVE6%Xc2)TQIn#Pj@U)2?|EEl7|37O=*Z*8#IKtF=WttoUvYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NGVH#=lCtQvPq= zvlcI&y=mJ2f{pqAleZ-QPh1-JKd{{K7sw17AA|ps7j*uA_wF4|eB}C(|H(&^|0kbE z!a#oF+(aMGETjL^mUrRQ3o^HPUo)y+s5wb%lMWN3KY1I_-lw&gW&p*B(GRx&LHYmW zd!;C55NrRDYf%5+DnRHb!T+Ez0GUy>s|pK?uY5mtBd--bp8|++}_jozrJ(A|C!VJ{ueaF3_txDMt{7sfZ+$k*;V2H r=S=HC!P6#o{GT$R{r{{fUH@}|;RsXfm1%MalzxDP26g}vCjtWi%}=Kl literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2ed_empty.ico b/src/ICONS/floppy_35_2ed_empty.ico new file mode 100644 index 0000000000000000000000000000000000000000..5801518ac4739ad8b0eb56e92801b2e63565a86b GIT binary patch literal 1150 zcmeH{&q~8U5XML7%}c%X?9oT_IV6R8scoZ|nzqK8v?XFR9=ayv4+#_$a_~}LB!^N8 zpR*~2rl%NhBFk@j;C~9BWe)Q8N(^gZ1cPkaqZ-IOMd3ieQ2&N zagWchv>eM6qo-@IZYA%yR4))L1hOnEjU{xchtzir1<}XP^rn4>wpLwlz3J!~|N5%_ zANtpSY(wVCax-le{O_4fNHpsTv)569$@2iFeT$hhhp998bNcRB*{JM=#IXBFBDX-~&k-_7C~_Znz5M=TIe-2%e#JLdWgB_` literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2ed_empty_active.ico b/src/ICONS/floppy_35_2ed_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..1bf18502296a65d371a5bcde4574773be2618b7f GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NDyPwEkMXW6}SM z*U#d`8;-91U%IX2fAW^(|2gZj{x>bG`UNthb8^%FeaCkE|MKMvPJH6_iT}w*lK&^4 zN5VjU;@m`^2}@i4A2@|yfAhX(RJ~AhlGY|2CPshqHlV#vYcb6LiW8$BZ2yDu|H=1C zQOqFL{u8&L{=Zd#&`*N@L17CrqiR$R31h6`=dL;M5 z^e^8y=l{uL`%v)qUAzBp+OhZlp#!`Buh=wq*y*3RxaH4eU|4|g()F|cA3m@P1s~YE f{r`R-KD>ViI2>VWf$@I`lzxDP26g}vCjtWi3||Fj literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2hd.ico b/src/ICONS/floppy_35_2hd.ico new file mode 100644 index 0000000000000000000000000000000000000000..36bbc5a2f005c4bf8d248465121ea3f639030d8a GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NI#)PQPl)^8at& zvXLmfZS#iznTe7ALw%fnfXr~RwfH}Ma{vE#@7@uO3vx34d%4*D2k8&>cKknQ`Xr+D zg6yd&&HEqj>pZ~vT?W{G>iK{6w235!e=bV+Cq)K;;{+5h#Ng;acNG1gxCG(ksDS?! z1!*X_C@bNAK}OvFvb>c4Dbayobujg?^aJCU<|h4LI)4fZ&PojbALirqe^Phj|ML74 zvh;(@$JCFAe?s=tSpT0ep!-0$Ff-x*oM}BMcye#^{|Q|U|7T9_{9l}%2v!GD8|veH M2o!$6LW3d<0I_PTIsgCw literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2hd_active.ico b/src/ICONS/floppy_35_2hd_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..a5849237d505c43a675ee1e1f23a51e681a760ed GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NI#)PQPl)^8at& zvJo$yyJqJ9f(`lqleZ-QPhObtKQhJp7sw1JTZ{kGC-?t<_wF4|eB}C(|H(&y`pzR^ zAU|<#qED!|;NQA1O@8YX6pBuNUR!vL+u5k&9Wbv#d=3TwsZI@aP}s=nK9l;I$w|LPZ+e-tRbOQRfSe22$}8%)hTE<&}=zhhfd*+2ei G{D~znwHLPl literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_35_2hd_empty_active.ico b/src/ICONS/floppy_35_2hd_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..62527c89112ea9f3325fde31395aaf22255a5605 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NE+U_x;+iX666O zmoDJN8xOAkU%IvQfAW^(|G8^&{&!4k_ysbfx2ygCfqlFGfBEtSCq8le#Q)?Y$^Vnj zBViyvac-i|%*nm~4i=5>2>m4Z9~1^4Gpcq~fx|z0P454W>5czE;ZKbF(c@FTjJZIWO6#GGL0pW#nru|>Haxn^CwQT4%3OLHlW|{}0Um vl}i@@^U^L9yl?lG|9f_B`hRHO_W!GwEr9!f#^k<3pzs408rT6yoCpj6B`^WC literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_1dd.ico b/src/ICONS/floppy_525_1dd.ico new file mode 100644 index 0000000000000000000000000000000000000000..64963661bb9537801976e59861da25d95d90dd79 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NL!%Z~j|Hf55;t z(Qn_`2Os!vAGqbeQ`FOUwoz~Y+eN)XQ}^}{HoY)0N00LVcCM*tdNA#RsYj;=TE9ck z_Wut4E6H;|Fud%8b^ya~fB*jf$B!TX5AELl-`T7Ezb#N4J&dvO?ZYnrpFVBc|8L*Ef$`q$ z+x|NQtRhM;*u1Fs|J?(6|Ie5@_5YGNbN&Ygmjc7!1@Zc!>Cry)+<*I!WB;vzVTsM1 zATj6ISO434?~sMPQr?^mOuGO7_1!yU;n?CgHv*C#{(o`v23a^f|IPmZp#7H~J|YVT z7rg!Nop}3?&GZ}pZDs)R%$o>2>(+l;Fuo0@?dIJ1Z#x@^K{S-@ne*&FtQ;Vh1_0qG By?_7! literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_1dd_active.ico b/src/ICONS/floppy_525_1dd_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..71ba656cbf4b38690a30948bb66f726c15c97799 GIT binary patch literal 1150 zcmbW1%S!@L6vl7Ru1#%Px9opV8!IwlMraR= z=(Ve$Hdgj9D5BI_sf*z2G&)#mA;a*yXU;c#=iGZ3E@K7s6c;mE%UEwAW2KC-a)KmM zQaT03=vzrq3NfdJ>xe*Me$PT_j>b5{9yt95s!WeDt^EKU3q#;Hc$nvhp>Z6MC;E}g zD`}Nl0Tnep&^V94AM)VOzCpRB@2f_3Z%LEuWPSoi^EU zz|D_EbhjsqXUOU!6#cEobr+I8oQsPZ?&R0puX?fF3rIW1b2)#-|MdNP{(c#; z*Xqby7Dl6yN3Fcv9HQDg;>j%Xxg2f^1qg9Y{Riva{|02uhAdt&ou%LIKP%=CnQS{0 zi6iGuO?BXO+M!6DIW_gLi$Svy3M1`cdVjs!4TU&$v3Jm#@T&$qa!qg_l0~}J!c2#jVUEu0zcWzLM5ML|*4CZfQFj%iUwXqjOT zBEhH(d(9Lm!q;^sX~dXf7=HKMb1vt6_kN2Zq>X-^orJDEq_3TjZbC>eg_dZ=sMA0Q zJ?rW)&~v&70To>EvlUr;7Q_n({!@76muFT!K!4Z?W{aV51ng`I?toVNwfB3TXJP~V z_#)W36qqCfCT)V|Y%tZTYr0FL-xYN=_kPcDtd9MwpV_9mccZN{Xx;MuGg)|iN6__e zhr!$oHO;WncS{=e?u?QKEAJWaza0GOw|c*_J^LJK9y_{T2u4>`7+)f?rjlR tQBl_~mdmyfmo-e!J=VDBJ#=CZ;7sre&6P*gBd?TNm|A*8<3C_GegTKsC&vH) literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2dd.ico b/src/ICONS/floppy_525_2dd.ico new file mode 100644 index 0000000000000000000000000000000000000000..b08b379c4a17f36b2f3ccddf25b1e741fc5e158b GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NLV8P5!U5G{l09 z-c7MK{oie4{(qg7@w;`_#z5K#6FNHT3&dc$ulIj$Zx0ZIXb5|Gp!a`RIY2HA088j{XFwbccr{#e%4!mF>xKBxH*t&MQ4+aMeXaQSTztwv(hpM}{> zzJUe~W`iDLFAw2DfN-5B+KX1cK;2v~{onlPlI17+oo95>@-JRErn;|F@*LzB>wliB z#k8&t>H1F-5FW>V<18A5!)nHY#RzBq z{4IaaF2HFJ3I>r(CXq^|a2|_cM6ZRPeEE6RGB2c6LtI@&B9Tbz?Bp0TGzU2=y(>8{ z^*`2Rz}m_RHUk0JP3_n&_>B?I$@y%Z4eD3qY9P%r>-~-gd_68F#}(2B?EnA( literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2dd_empty.ico b/src/ICONS/floppy_525_2dd_empty.ico new file mode 100644 index 0000000000000000000000000000000000000000..00feded422aae4862f547091f48ce6fb987a2442 GIT binary patch literal 1150 zcmc(f(M!Tm6vl7RTQBy~bC3OL{UK9pS0pnkjb4JLL_Gw>rb5nUfueIJlR-TOMWGNq zZ3tiIP6o-Q#$ICl?%BS3zRNx5z!+PhCy`*ZZnEuF#x@vZTLej@Omzy3(cb#n6#tu+ z9#6vLQi!fBjqi908c)NNlVdZJM3?erkflkKH_*=bE(%-@ogM5ii~sGf$tm23`Xl)b*@WkLKF`A;F8B`aBW6u= z4%PQST0__2x~`8i7~pnJAENx?{+C&fM!k-fVc;jnTP*D20ea+r9gSk~R6Il{$0v%aLeVsoDwP?OY87R|kF^>~ P^!}UnaUQ{cAa48tU>FiL literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2dd_empty_active.ico b/src/ICONS/floppy_525_2dd_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..c0e50f4c0e9392daf753d40e8f430adfb5633337 GIT binary patch literal 1150 zcmbVMO-lk%6n#OvHnnNpvi~(3DS{S8V6-x|d|{xQiRieV?&CA#4wz>^UmCJ?%ewx!`KL2eMvXr@9Rr5PSmpGyDt^MCpw{R^#sYZJHSGV0YTvYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NID!&VRyvo&RIO z??OBs{|9+E{*U!_eis2$6N#oS($5u}KDd~dv%`N^CkHqmiye67K>A$|NHmv|9|}W@&C~7-T(bv9R7!R5$BFDpt|YPrv3l+?Hd^H-M;OAASvMhbZ3y4 z>;D;3r~Y3uXU_i!e_x{AjvP)Pe}n?lAU=P`2Dty9*4984PLA+Dn;GW&|MlHFWZ~lU z_!}8O{V#6bAPeWEME_3*>c8~x5m`7pHTHjUsLvnwNfZ8qu*c+y2s~xde~&4X;n;K9 Wl>eSnffz(X*$Ih}|6%0-xikQy3{hqP literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2hd_active.ico b/src/ICONS/floppy_525_2hd_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..d865b19bd8ec5b1e147e4e5feb4a7c08fe9cb98b GIT binary patch literal 1150 zcmbW1OG^S#6vuDSu8nP4x9ns1NPLZ2mXC1|t*dDS5k#~KTD2}8lMAs;U%&_h#Z9!0 zpp`{M1wjzFR2RX&Gul|`Fvc+a?wND${hxEs<<2lRL66DAXq;u4NycUvV{-(BDAJFU zVT|Ucr~34K8brbN8TQ(sL2KD%LBMH2%xh~&Ndbv+4E&t;Y?OS_XV=mVVs4umcB>iD zH39sJgWvpu{AfxTtktLwML$pacv1SR{mv7YrGM#pmFm9jjpm@ZR$Vo=M7=LKEdBb= zyWmede{$&77pze9i-ef+^!vZx`qAt4Puif*gR@Enjam(>Vi+R#jGVu^&tV&KTX0e? zqtof2+wJ1AUWb3)jAge~w_i0+h}Ip;GTQBSkH$q6i*yd^{8&r-54i0p7792ml@RfJ z5vJH!-OxQ$`Uuh;)YHZm9FPz84Z$P+>-CTqACC`)*iOfr8PdPsH4U+ul#nLL_O0GxaQL5 zCN#`X90SL;fsmVXK{>&XJi#rUZ>8C$fhM7;T}hLE(>SV>t9!?P{c`Odp{u<~ll!&u zyML=8y*_vGFd8A7Owc(M@To?rYtQO?kCb~m9HJ-+#p85}R?~ny&rN-+dCKdjDe^p5 zWaBYBtD={BS8I1I^pga4g8_uctM|VCjmdqZ{r_#ts8{sVR62Q?@A AY5)KL literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2hd_empty_active.ico b/src/ICONS/floppy_525_2hd_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..30c65587e791f8af4e387eade944ef7597df4738 GIT binary patch literal 1150 zcmbW1!ArtW9LHbKt&3ecckKV#rO2pD1VW&AS0XYzBGl=p4-{~n|}M(60Y+>(B2}zv)%wI3DVCw3|)j4m9d_5P|D}-T$)<_uj-8+!jRutHj9z+otM+&lm2w%k)haYawlvqAPG^wnP^tfR zKOD~}GKvJ_>f94~Epb=SWc+-6dZJj!woU){$Gay^4>LF-|7)k?iDUBTRe2zlO0du= aPEyiIw}}~L#B?229NuShX^j2@UgIwull2_{ literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2qd.ico b/src/ICONS/floppy_525_2qd.ico new file mode 100644 index 0000000000000000000000000000000000000000..e3f370d93ce21a6289f50d7aa5834cd903b9c745 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYHQxgi+L2NG6lGyj_@&%(gw z$}`{DXf^(~(W(A#r#j`Gh4PI5mMYWH)Xn&VO)pH$-Yn+7tz|Hp9!$Gn>e1l^1r#tR1(dY`QO_q_5Y@g8~^X!wd;ReNYZ}`)rtSjmC?f= zdstd)bo`$`Z{Gj!-@pI=@#Dw;L%VnXcQj7p~&4r7z^8HyT+TB@VKhP4zL6Kr8+QenaS7Db(Zu>DKUk99|h@}+= zxk@=9gi=a5?(RW7UNZ)3*S4nV_ka68)APK&Z__XqM^9oRqceqd$1|497|S9^B1P7z zFh=i^5@e)19oh^LC8-Nxl%|TWT+Rfzyb+Y8J710F8MFvi@Vh)(JXRRYv*Z!pB6$_9 zyrdO+O(P67v*1s8@aI3EyP@hMBfPhwDSrF0J=FV|(>&i7lb`oe->0$g4APZekt&xv z3VneMQvdrw@OQS5jOhIZaJggP@`qroo|fmo?*H~jonM5dvI{%g+c@(1(ALxeV~rid zzF}$q*3I6iyVGUOU}bq3fj|JkU=SyVho~s-gogA;bN<$}nRD>C-SGSU5=Z-9+QUFh zUO7vIQPTs#<-*$HA{xx?C{1(y!!LgmA9Luk9pn@K^p<6dnCjnBg{g4qtggs|m)jdv zG@CarE#!Z`x>QAD#Tsgh-MDyoR7HK|I;x7CZ`$!)NKEcQJ3&l(C3NJs(D^_JUt3%V z@aMdvYYcMQh=7e1u>~c23RP&2X_|owdT1Y;M0&z?XQw3sm%Dry7$UJuS-fc@PA9^;0`2-iQlZZva+Zl?p!^L(C$L#Vk1rutv^ zHCv;ZYcO4h>$*OUZO5zw!h7kDwvS Lg)V0QK+^FGum1t< literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_525_2qd_empty_active.ico b/src/ICONS/floppy_525_2qd_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..34a6a377785bef50498333f95a772c59c7b0f4cc GIT binary patch literal 1150 zcmbW1%}WAN6vbcAu1#%Px9tC#O(8)D5!IxbV@)$UW%NZvs5Q|-O42M^=)4rkMU+_~ z1<|4?iiBvT2&d;vmX=L148M1I_j1midl`n17WTBa6Lxlyo>oFS2_fAKmSPzr&jKN= z*3o95-`OFJQivmmO`t{D8HMcHhQcR`4q+X=8+LFp4n3+Jyr41-tu)sfe%{Fy$l@aS z2^CzL19wsfyYrr^N3-6IdUwLzsQvJ<1&98n=i;pI{pe2*mN)A!k3}GlhoSes9RznX z(BNU-pF-EWw%Gh@#{5_PUwYH|Ddv>-m* zqg*cQTwh*7@q|##o6TFRNsfI`O+%?v(kbNg`W|Zazaz!8sDdVw$fiJ@Hr{snzg#Io-Q3my%3FE5r@ jRI->A5|yb)4mvw$n5sjH=J84F9MU)Z-VAF00ju#HqYL^E literal 0 HcmV?d00001 diff --git a/src/ICONS/floppy_disabled.ico b/src/ICONS/floppy_disabled.ico new file mode 100644 index 0000000000000000000000000000000000000000..8203863cb49ec6b77a5a31cd049252d3c09d4c7c GIT binary patch literal 1150 zcmbtSO-lk%6n#N!Yt>4kAR}noujn_V3n}Oi1TAabB0rEUFan{E@f#6A+vxZ)nu^#$ z3>S(10Y%7&I^FwfVltwE7|xsb?wxb)x%Z6_GxW^Q3tE@N?yL|CLWng2g(&h7rxP`-^zzpAJ%VTHf3RE9^dlypU;NTRit19C0xYleo?|Qx7T`(9N z8@=m$tFs(bd#S;i+uN6N9uCJ1{^EB!9nyZ08tj8TbKg8WzL&rFG#{`= zKA)Gp=rhsZMt&?7Lm&_^4WG~VWaKB4NwnK-(?}!|4+PZfb#%L3L?RIkheOlIX0xMk zI1JWcA9Vj1jYg)C$z;HMzV~!GE$eHVhDxP^QmF)0RZ%XNQ7jhazECKD@--dgw`Sxw z8V$5sEeW1C&y)GA%{90`(1X%>s+KAlcer_-Tsw@ZyigDRB@l}aTl7K>83T#k@atJSDltx_V9kU1FHi!zyv zWZiDJtQU{R2@H7nalL_&DKbTCWJMa*4kPCr@A8IP02I63c!y$d-%V03P z>-YQL5m)svUkE<%J>^j!Jnzvry literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_active.ico b/src/ICONS/hard_disk_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..e888fb45cbb1b5a7e8a71a78c4f72d6380b90cac GIT binary patch literal 1150 zcmc(d%d1jR6vnsIETT(;#tr)$nl=?@;`n&L8eAkVgg6N9oeCm!5iu3fi|;3>=lGa( z;Sym%lLO-Wt@EOR)NQrDZM(Dv)hG|&Iqr4#?^|o_vluh+>*$E_`+fH0CS&&)V-L7^ zh(~sD{$Py1yL)RVvHpjf@=`I|%XUMpsbnwN4XpnbSK^9Uy;4bizbC#{qKet;^}dV8 z;<#L&d z#Ud371)*##DTI!~RG=)eE;C(rvodvQkfdj0c!KBw7icA(X2MVrk=Xt`Wc zv(qHE&THW3@7CO;ztK_WSDyd%WHO=Qa7g3vnAYpHU>1u7O{Y`g34iz@HW&=3+wD@n z-zR?FZ=Fu313ZL1*b9M$-)J=YA>=?DtYH}RnE$L+>z#JH{RwfI5A{Oufv@xckNn{I zIeoNPEVnU3{5xOlGdK&d(nHoFd3gAIzNnl(o6YtJJ%K?FvJdGa`#~MOUXMDR4sqt8 zn9pjpdhK$# c)L;4kwWdqP==9IoPfd&o-C*n$7tv1N0B)>V5C8xG literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_ide.ico b/src/ICONS/hard_disk_ide.ico new file mode 100644 index 0000000000000000000000000000000000000000..91ded91a72627cb7909aa736c04645ed16031624 GIT binary patch literal 1150 zcmd5*J5Lm06g@;cW5kBq(!yV0YehvU=rtz13JF_SP{1PU8YLBgd1LxtG|!XC1&8H z^c0JXlIK2>7e+{1@3$yvC>CE(j&cQYr6*4hc_=P!(XjE)#!667aSTuXtSj#QRIeZ% zU$?Ja{-Jkrc@_D^N5c`UA4=}#Xf4F`8on0!i!a#PC$i&P7&)V!#8D5v53l3JURg^|-)zJ8JR#Tn&!i0ggDlc%_X?O$dW*F9FYRoWbEhO?k~&^&4`dw&rh@b>T1zXhmDz?V92DLt_ z8;K|g6|@Ak8YT4++Vr6jyHI>p47MKcna@cRx=>dV&Lnd)zjN;Was$-ZtF{()U5)0Y zz$yT1OjfdrtJ@o3->qEc6x{#A#q0L!BiAE2|Ax=VwMb6)e~WwlUcGg z*!joPakdU;)#p#kAKp7g?s!S=$&)sAz#X3=4~#oc`O8nW*bCBoN=8RXJMV{R>TDD* z=@~sMiIv~3R|`^x>S8yI7{B>o6E<#Jfx+*ys)u>%SCWr>Ll5!F53*A;U$CKZd9Xtr znN%gCvk)74guR5kJh1O}vb=u{vGtlsjAjVu2z|nN)W_Bwxpv6-hS<6?ufItD+X+1v zN^F=bPMKmQoX+PeSog85x6SroKG+5AgZ5E-dFeAT@JYY3+s_N{=dtCazli@&1>Oai S_;Yxo1_-nS7&6%@1o{O*%q4LE literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_scsi.ico b/src/ICONS/hard_disk_scsi.ico new file mode 100644 index 0000000000000000000000000000000000000000..7a31cc1f12d4ff6d92cb99b566d2a5e64d6a7530 GIT binary patch literal 1150 zcmd6lJ5N+m6ot=3J7d6x+QddGds`bDD;pXU6QbDKX>jBbkPz_+0dZgk7-W!f2rsQ^ zfIi&eh=F2LTfuT-+|lB2h=wt z#!0wwE8+5$1^RL@ISo@Y@M0WBp2Khf@*@GcA$-ng5ej4QBolJ9);B=^K;SmE1izlA zAddLb8OVp6VhMyy7NphN2k9or4#M=ypeb*82(gaA;gBO8<;qtYT|MdtN)rccZNui) z@7Udg{m%hAyRg0it81{b`V+aK@1{BLzbU@94tx87v%LcwpMs|JrKi~P3cULOOUu}K zzvg1iRnM2ca+E8GD?NEe$U|{)7vIA93w4~Tu3+ZXS09gls#lOstUJ~&fAI@rU&<9# z$2EfXpYuLHar#(k_s{^ASirv5m-RG&HLdlE-I#6F@<>_;_xT!Og;jB_^fZB6lP zbn~!x<%=7A#gnJFLMHqE7p{M$w(h#kLD|oO=0WqQxty4S@k#yXFrURznVL(rfAas; V9_;)Lf4dq}&UqYhZq^WaKL7;`ZH@o{ literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_scsi_active.ico b/src/ICONS/hard_disk_scsi_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..e7579fd8edc78ce85a17f4a08a03469231a6e4ee GIT binary patch literal 1150 zcmc(dziU%b6vuDSO{8_{EV$Uo-POe*PA**>k_W9rC|Z!{5QrcYQR|ON#cG$Qyz>Licvd+(liKi_lCeaD!9T&=A}?)%Nj z-Nv*TV-AWWBoP~zhcWVP-ySP}{SUX$U?>=V6fS!Ok8nO**7e`wp>!zdz3}kf?U1ZP ziBOPpv9}D|uG2qI=lab$*ZMcFfPbAg3$=xJOPQz3I9_C^6 zJ`86eGisH*hgX!mwb<_-5+{+eZ2W@FcWV%Y@p<)0W$4NE;8mk|%V(NAA|nwPO2hPH zn^$vZ$E{o)>0wIAKK%YGr?z?NztnpcaueUEuEI*SS?e26`)swgPU-biqEDm-Isa%e zN@=F3b$*xpGb}E_d<7O3VWVc5)iqdJww~&*ej1ybhYufNb`Cl3HyrQi^m+BrJ-Sz= ztol_Jwxu~Vu59T&96i>>f%X;(#jk$c<&%0*sgL?P59Kw#^4ak(jh42(Iz#fGGyZpCrS(C}wL=RxOD=W=2S@{{_X?R-ASHRw3u{mTEZHP7YzT}YE*6n-tei}0pyB9*KtD!SNBU4%D5Kadl_Ebt;hhHVyYnmJRx^|KJ!b~k?@ zQ5?8Ar;Xusiz!=(^Jk`Rv%%a_(pqAhUTR9Gb6)#M6!wkhd%yGZyzg_)c^P9F_{+{_ z_|9XMnT(xej9oyW3q5;&To}WcFJ}+jPV*`$DY??v*!W)kvMGMK(6*C%*SRfws#{R0 zR0771rJ*vVQd!>K-u}C@vl9p}>df$1Zh@AT7BCu(pwVc8QmK^W9eRq3i_aiuySKL& z`uqFAVzEF^PY;+(CcalkM+daEwSii#))Tp*p`pTHFbF!Gjsy30IGs)y9v%jd#{;9I zqcAcu0&ce(91aIqtybvj>H@u9A0fWYX8S{V6dxKI;%9ihUKkr2gNca=n3|e`$;n9= zA0G$uQ%+xBAJy@d_+-z{&ce*h3FH^12ZKQfhr}*5 zA9a3vYYxGU*I&Tn4?`>#NOG`^nqi>haT3cI#m6a9V^F$)S zxvQ(IAP54lKN^j~+}s?^!$oI{5BBo|)lQ&ZkaoM>&b1St`s?@mArgrI&gNHbZS5_Q zORGd8$-+Bzf~p!?pw()t|K*;;{9OFLjVLsm&3TlITJDG(aV>wMzJIgs^de#+%?;$1^c z7qJgV#5`KDANl)j`hKJ_`*T!_kW(Fl^UBXq`CMCnFeja@c++ja^ePEwg%n&D7NGK3 zeMP$bgE5&*mak~C1&Y1`y*i{#ukN2GKJkR$$=Y7vPA0bin ziHRY!KSoNU2{}Rt;n1KEMYeD{5JI`w16vW9|A$>u^W14^{k!+Ro>#ZF(^J`>IV3d` zWB2b*o!G{9j@{i$2esFqH<)hDPHJDTqqybes?X=k2?PT5DNQfd%0`!Aa=z`mWC%KX zdqaD-^#Gy*ff;^j<3d;z_=OzJAk3jvoYFo*K|vvMb7kN<127DHhR8C!Djr&a!8JAL z_s^YV9+%wV!$jHc`d1pZ=6e2k}89W{j2?+@hiA2z9 zwU8*x5H<|JYWJ+Sx3{CCql4~KE)o+HArJ_Vot+J-REoU3Jcz~ONDT~6N=k}+Ba_LX z)9GL~n}2#d9u2MalUl7tdU|?fZKjt6*)9D1|M*Mz1`?Yp$^gcz~?e>b=+S+BW*9%%7Dl02LxZQ3!yKB1&cMxnH t>hYwis;V;-3dQcA|Jf8EgvHlpLWcHG+rMO3O}UwUgnT(f$hvS#_Z!yLjU500 literal 0 HcmV?d00001 diff --git a/src/ICONS/other_peripherals.ico b/src/ICONS/other_peripherals.ico new file mode 100644 index 0000000000000000000000000000000000000000..b078387d39de419d0da0d3fb2c782e5da19eb1a0 GIT binary patch literal 1150 zcmd6l-)mA~9LC?My9h=X(PfvxAZ%+nDycR`nof_KCx1+H&R?h0ETuWel5%OYcCm{_ zEgiGz%K1ClTp`TX59u}t0_h)!F8c$X-gAatv>PLWIDFoR^L(F&_vM_IkbU&&>LPSK zMz{ln93g}pr%;PJyFL{{=!X%dtajAquwm0KAUoBGBY1 zEsyt$(OfIf_hW^JKO|F3v)4AzR6L&e#>Aaq5*#D}6~wMf5WA)5_sDR@rx1K5;rvPG zO`e@MnR=`^3pQ?o>WLldXB0S|rI3=#E-hejcg*NTQhwc2AY%z%WW$Gtf(9y2p zg%9e88ET~ziwm=e-49}?mWAD-hs>>pA$1dDG&A+`FdqF3t{j4EGu(zzq1|A(=1P`_X{2`g-ied literal 0 HcmV?d00001 diff --git a/src/ICONS/removable_devices.ico b/src/ICONS/removable_devices.ico new file mode 100644 index 0000000000000000000000000000000000000000..45e15d3b4e94c1f5fadca81e19212b7062c8f6e5 GIT binary patch literal 1150 zcmbu8ZA?;O6vuC?txqkNTW@o&`Ngu;+OoEcRW568F(a2>tduF0r8P2Zr9^4qB&8R$ zutX|BF-=UdH%)@9Fv*u%TAP+Hg@y~1?*Ff+~7Xpi09D&K%Y;oLnwCi=S+wG8* zR^h_OaqM{uBva1H&o0Cntyq1x4{Pd%5Z3I3ho^5^YM4MkT7F#>e+RmZbsj!ft%ceO z$i4u_yMeFt!@y7`Zn;+ zN^pUEtfD-A#h>CA=4hRN@Fi7V-U8$iA8T@eqkRuK`QTC>n;%)Rz0Hl~CO16sv&sji z^GfY~6n?Owka!vK7yIe#$jAEHLBuxMA@6fR^wEvT*Dm<$Z0@B;^R7?lyLNO}VkwaOo?Wg=N%Ojx_XIw?Mg+k#aNv`x)d~zb< zQ<9)3`=xq^y9rKWY@G$FaxJ8?e2N=3o9*zt$8??Qr=112(uCXxhqO!)xRGIWcKcweG(%77Rjg7# zURH`?r2^ty33M+FkSP>lleJk_sD7+I^QyU;^?Y7iwnnO|IXlWyELty_SK2$DdfouQL0v=pri<5X*LAusc^q( z>7)Fw3q$-lnrV{Xq5kg2>-R>?eVE@WRS|7*5oq0LZK!W+a)@_xm%1(g=xKg*V%+Y3 z+e36h2(vN~my`f^Tg#T?wd3#kU0hr|wmRjH*gaq1yTj+ZIQ@S1yUpoLC`or7pQ*a!&@BRHrcC<!)_OR716Y E0O)_&JOBUy literal 0 HcmV?d00001 diff --git a/src/ICONS/video.ico b/src/ICONS/video.ico new file mode 100644 index 0000000000000000000000000000000000000000..664132269defbc0de32deda9de676e20593d6435 GIT binary patch literal 1150 zcmb7@-%nCu7{`yR%`UxYT~;@3{rm@7_j=Q~;x3o6oapASm6M?es7W|m(A15ds7yoJz8(t99YG=RGD9(^}{3^FHUiXW!?2ejSc0p}VY%qxC8$ zJ&9+27yq<$3;{&1M@M9UYZhES3jGqw!vM zclQ;gQh9+SB`0LUYk7J3t(uyejLBqz$K%1o#0192#|yaK?gNLz@!f8>C&tFcW(kYg zY`)LLB9Z70X|t`Zt)TNTJw1)d$w|So=d*CRT)adgx!uvxk?rd0LQhW*C}#M4KFrV0 zBM=B67!01t+}s@B+}v#M?CgX}r4n#DomgC4L_8kH`uaN3=`>QQ6q3m#5{X0+3;qSZ zsj0~$m&>76t3mk)@rT1cIjZ7x<)9dw0T3T8>R96fQ4WYNU z7do8|UzS7o8ec~KTMm1BdqwQ-?h3I*B9T|DcBCJnbAM3X511e76{21nLeC%KGvlQc zOC}kjRt@5A15)qbAQSLmYimo-^kT929M!*!>K{@l6hizfGrXW@K2BqKSjqAb^vp+X zZS9lx_I7AA8c<&mn{}P4JMzW!REvVXzP?`D*474^F<7luL}#7sWqtyC%n^%4UE16Y}|{#74-tt`}!(QpW<;76oC zO(E&CBlgye6}t{g7Bxb~#|Vu)#m2@)A^*C%x*OEPK4O(-_JGX@>-+xx{vRC81I?tC zoqhajXlN)k7!22FuI|QSF%g~dXl-pxMsxgPb8~Z;{CdbP5QBcd|02__mU7$-Srt)q PvA_H`Dzc}sO8dV6V%wa- literal 0 HcmV?d00001 diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index 233d3c6a0..000000000 --- a/src/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -# Makefile.am for PCem - -bin_PROGRAMS = pcem -noinst_SCRIPTS = ../pcem -CLEANFILES = $(noinst_SCRIPTS) - -../pcem: pcem - cp pcem .. - -amrefresh: - - -pcem_CFLAGS = $(allegro_CFLAGS) - -pcem_LDADD = $(allegro_LIBS) -lopenal -lalut - -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \ -allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c allegro-main.c \ -allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \ -codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ -dac.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ -headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c \ -keyboard.c keyboard_amstrad.c keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ -linux-time.c lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c mouse_serial.c neat.c nmi.c nvr.c \ -olivetti_m24.c opti.c pc.c pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c scat.c serial.c sis496.c sound.c \ -sound_ad1848.c sound_adlib.c sound_adlibgold.c sound_cms.c sound_emu8k.c sound_gus.c \ -sound_mpu401_uart.c sound_opl.c sound_pas16.c sound_ps1.c sound_pssj.c sound_sb.c sound_sb_dsp.c sound_sn76489.c \ -sound_speaker.c sound_ssi2001.c sound_wss.c sound_ym7128.c soundopenal.c tandy_eeprom.c tandy_rom.c thread-pthread.c \ -timer.c um8669f.c um8881f.c usb.c vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c vid_ati28800.c \ -vid_ati68860_ramdac.c vid_cga.c vid_cl_gd.c vid_cl_gd_blit.c vid_cl_ramdac.c vid_ega.c vid_et4000.c vid_et4000w32.c vid_hercules.c vid_herculesplus.c\ -vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_nv_riva128.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \ -vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c \ -vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ -vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c \ -x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ -resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \ -resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc \ -resid-fp/voice.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \ -resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc resid-fp/wave8580_PS_.cc \ -resid-fp/wave8580_PST.cc resid-fp/wave8580_P_T.cc resid-fp/wave8580__ST.cc \ -resid-fp/wave.cc - -if CPU_I386 -pcem_SOURCES += codegen_x86.c -pcem_CFLAGS += -msse2 -endif - -if CPU_X86_64 -pcem_SOURCES += codegen_x86-64.c -endif - diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index 1d3455bca..000000000 --- a/src/Makefile.in +++ /dev/null @@ -1,2956 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -# Makefile.am for PCem - - -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -bin_PROGRAMS = pcem$(EXEEXT) -@CPU_I386_TRUE@am__append_1 = codegen_x86.c -@CPU_X86_64_TRUE@am__append_2 = codegen_x86-64.c -subdir = src -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__installdirs = "$(DESTDIR)$(bindir)" -PROGRAMS = $(bin_PROGRAMS) -am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ - acer386sx.c ali1429.c allegro-gui.c allegro-gui-configure.c \ - allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c \ - allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ - amstrad.c cdrom-ioctl-linux.c cdrom-null.c codegen.c \ - codegen_ops.c codegen_timing_486.c codegen_timing_pentium.c \ - compaq.c config.c cpu.c dac.c device.c disc.c disc_fdi.c \ - disc_img.c dma.c fdc.c fdc37c665.c fdi2raw.c gameport.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ - intel_flash.c io.c jim.c keyboard.c keyboard_amstrad.c \ - keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ - linux-time.c lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c \ - mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c opti.c pc.c \ - pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c serial.c sis496.c \ - sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c \ - sound_cms.c sound_emu8k.c sound_gus.c sound_mpu401_uart.c \ - sound_opl.c sound_pas16.c sound_sb.c sound_sb_dsp.c \ - sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c \ - soundopenal.c thread-pthread.c timer.c um8669f.c um8881f.c \ - vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c \ - vid_ati28800.c vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c \ - vid_ega.c vid_et4000.c vid_et4000w32.c vid_hercules.c \ - vid_icd2061.c vid_ics2595.c vid_mda.c vid_olivetti_m24.c \ - vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ - vid_pc1640.c vid_pcjr.c vid_s3.c vid_s3_virge.c \ - vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c \ - vid_svga_render.c vid_tandy.c vid_tgui9440.c \ - vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c \ - vid_voodoo.c video.c wd76c10.c x86seg.c x87.c xtide.c \ - sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ - resid-fp/convolve.cc resid-fp/convolve-sse.cc \ - resid-fp/envelope.cc resid-fp/extfilt.cc resid-fp/filter.cc \ - resid-fp/pot.cc resid-fp/sid.cc resid-fp/voice.cc \ - resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \ - resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc \ - resid-fp/wave8580_PS_.cc resid-fp/wave8580_PST.cc \ - resid-fp/wave8580_P_T.cc resid-fp/wave8580__ST.cc \ - resid-fp/wave.cc codegen_x86.c codegen_x86-64.c -@CPU_I386_TRUE@am__objects_1 = pcem-codegen_x86.$(OBJEXT) -@CPU_X86_64_TRUE@am__objects_2 = pcem-codegen_x86-64.$(OBJEXT) -am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ - pcem-386_dynarec_ops.$(OBJEXT) pcem-808x.$(OBJEXT) \ - pcem-acer386sx.$(OBJEXT) pcem-ali1429.$(OBJEXT) \ - pcem-allegro-gui.$(OBJEXT) \ - pcem-allegro-gui-configure.$(OBJEXT) \ - pcem-allegro-gui-hdconf.$(OBJEXT) \ - pcem-allegro-joystick.$(OBJEXT) \ - pcem-allegro-keyboard.$(OBJEXT) pcem-allegro-main.$(OBJEXT) \ - pcem-allegro-midi.$(OBJEXT) pcem-allegro-mouse.$(OBJEXT) \ - pcem-allegro-video.$(OBJEXT) pcem-amstrad.$(OBJEXT) \ - pcem-cdrom-ioctl-linux.$(OBJEXT) pcem-cdrom-null.$(OBJEXT) \ - pcem-codegen.$(OBJEXT) pcem-codegen_ops.$(OBJEXT) \ - pcem-codegen_timing_486.$(OBJEXT) \ - pcem-codegen_timing_pentium.$(OBJEXT) pcem-compaq.$(OBJEXT) \ - pcem-config.$(OBJEXT) pcem-cpu.$(OBJEXT) pcem-dac.$(OBJEXT) \ - pcem-device.$(OBJEXT) pcem-disc.$(OBJEXT) \ - pcem-disc_fdi.$(OBJEXT) pcem-disc_img.$(OBJEXT) \ - pcem-dma.$(OBJEXT) pcem-fdc.$(OBJEXT) pcem-fdc37c665.$(OBJEXT) \ - pcem-fdi2raw.$(OBJEXT) pcem-gameport.$(OBJEXT) \ - pcem-headland.$(OBJEXT) pcem-i430lx.$(OBJEXT) \ - pcem-i430fx.$(OBJEXT) pcem-i430vx.$(OBJEXT) pcem-ide.$(OBJEXT) \ - pcem-intel.$(OBJEXT) pcem-intel_flash.$(OBJEXT) \ - pcem-io.$(OBJEXT) pcem-jim.$(OBJEXT) pcem-keyboard.$(OBJEXT) \ - pcem-keyboard_amstrad.$(OBJEXT) pcem-keyboard_at.$(OBJEXT) \ - pcem-keyboard_olim24.$(OBJEXT) pcem-keyboard_pcjr.$(OBJEXT) \ - pcem-keyboard_xt.$(OBJEXT) pcem-linux-time.$(OBJEXT) \ - pcem-lpt.$(OBJEXT) pcem-mcr.$(OBJEXT) pcem-mem.$(OBJEXT) \ - pcem-model.$(OBJEXT) pcem-mouse.$(OBJEXT) \ - pcem-mouse_ps2.$(OBJEXT) pcem-mouse_serial.$(OBJEXT) \ - pcem-neat.$(OBJEXT) pcem-nmi.$(OBJEXT) pcem-nvr.$(OBJEXT) \ - pcem-olivetti_m24.$(OBJEXT) pcem-opti.$(OBJEXT) \ - pcem-pc.$(OBJEXT) pcem-pci.$(OBJEXT) pcem-pic.$(OBJEXT) \ - pcem-piix.$(OBJEXT) pcem-pit.$(OBJEXT) pcem-ppi.$(OBJEXT) \ - pcem-ps1.$(OBJEXT) pcem-rom.$(OBJEXT) pcem-serial.$(OBJEXT) \ - pcem-sis496.$(OBJEXT) pcem-sound.$(OBJEXT) \ - pcem-sound_ad1848.$(OBJEXT) pcem-sound_adlib.$(OBJEXT) \ - pcem-sound_adlibgold.$(OBJEXT) pcem-sound_cms.$(OBJEXT) \ - pcem-sound_emu8k.$(OBJEXT) pcem-sound_gus.$(OBJEXT) \ - pcem-sound_mpu401_uart.$(OBJEXT) pcem-sound_opl.$(OBJEXT) \ - pcem-sound_pas16.$(OBJEXT) pcem-sound_sb.$(OBJEXT) \ - pcem-sound_sb_dsp.$(OBJEXT) pcem-sound_sn76489.$(OBJEXT) \ - pcem-sound_speaker.$(OBJEXT) pcem-sound_ssi2001.$(OBJEXT) \ - pcem-sound_wss.$(OBJEXT) pcem-soundopenal.$(OBJEXT) \ - pcem-thread-pthread.$(OBJEXT) pcem-timer.$(OBJEXT) \ - pcem-um8669f.$(OBJEXT) pcem-um8881f.$(OBJEXT) \ - pcem-vid_ati_eeprom.$(OBJEXT) pcem-vid_ati_mach64.$(OBJEXT) \ - pcem-vid_ati18800.$(OBJEXT) pcem-vid_ati28800.$(OBJEXT) \ - pcem-vid_ati68860_ramdac.$(OBJEXT) pcem-vid_cga.$(OBJEXT) \ - pcem-vid_cl5429.$(OBJEXT) pcem-vid_ega.$(OBJEXT) \ - pcem-vid_et4000.$(OBJEXT) pcem-vid_et4000w32.$(OBJEXT) \ - pcem-vid_hercules.$(OBJEXT) pcem-vid_icd2061.$(OBJEXT) \ - pcem-vid_ics2595.$(OBJEXT) pcem-vid_mda.$(OBJEXT) \ - pcem-vid_olivetti_m24.$(OBJEXT) pcem-vid_oti067.$(OBJEXT) \ - pcem-vid_paradise.$(OBJEXT) pcem-vid_pc200.$(OBJEXT) \ - pcem-vid_pc1512.$(OBJEXT) pcem-vid_pc1640.$(OBJEXT) \ - pcem-vid_pcjr.$(OBJEXT) pcem-vid_s3.$(OBJEXT) \ - pcem-vid_s3_virge.$(OBJEXT) pcem-vid_sdac_ramdac.$(OBJEXT) \ - pcem-vid_stg_ramdac.$(OBJEXT) pcem-vid_svga.$(OBJEXT) \ - pcem-vid_svga_render.$(OBJEXT) pcem-vid_tandy.$(OBJEXT) \ - pcem-vid_tgui9440.$(OBJEXT) pcem-vid_tkd8001_ramdac.$(OBJEXT) \ - pcem-vid_tvga.$(OBJEXT) pcem-vid_unk_ramdac.$(OBJEXT) \ - pcem-vid_vga.$(OBJEXT) pcem-vid_voodoo.$(OBJEXT) \ - pcem-video.$(OBJEXT) pcem-wd76c10.$(OBJEXT) \ - pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ - sound_dbopl.$(OBJEXT) sound_resid.$(OBJEXT) dbopl.$(OBJEXT) \ - convolve.$(OBJEXT) convolve-sse.$(OBJEXT) envelope.$(OBJEXT) \ - extfilt.$(OBJEXT) filter.$(OBJEXT) pot.$(OBJEXT) sid.$(OBJEXT) \ - voice.$(OBJEXT) wave6581_PS_.$(OBJEXT) wave6581_PST.$(OBJEXT) \ - wave6581_P_T.$(OBJEXT) wave6581__ST.$(OBJEXT) \ - wave8580_PS_.$(OBJEXT) wave8580_PST.$(OBJEXT) \ - wave8580_P_T.$(OBJEXT) wave8580__ST.$(OBJEXT) wave.$(OBJEXT) \ - $(am__objects_1) $(am__objects_2) -pcem_OBJECTS = $(am_pcem_OBJECTS) -am__DEPENDENCIES_1 = -pcem_DEPENDENCIES = $(am__DEPENDENCIES_1) -SCRIPTS = $(noinst_SCRIPTS) -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -CXXLD = $(CXX) -CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ - -o $@ -SOURCES = $(pcem_SOURCES) -DIST_SOURCES = $(am__pcem_SOURCES_DIST) -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALLEGRO_CONFIG = @ALLEGRO_CONFIG@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EXEEXT = @EXEEXT@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -VERSION = @VERSION@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -allegro_CFLAGS = @allegro_CFLAGS@ -allegro_LIBS = @allegro_LIBS@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_SCRIPTS = ../pcem -CLEANFILES = $(noinst_SCRIPTS) -pcem_CFLAGS = $(allegro_CFLAGS) -pcem_LDADD = $(allegro_LIBS) -lopenal -lalut -pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ - acer386sx.c ali1429.c allegro-gui.c allegro-gui-configure.c \ - allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c \ - allegro-main.c allegro-midi.c allegro-mouse.c allegro-video.c \ - amstrad.c cdrom-ioctl-linux.c cdrom-null.c codegen.c \ - codegen_ops.c codegen_timing_486.c codegen_timing_pentium.c \ - compaq.c config.c cpu.c dac.c device.c disc.c disc_fdi.c \ - disc_img.c dma.c fdc.c fdc37c665.c fdi2raw.c gameport.c \ - headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c \ - intel_flash.c io.c jim.c keyboard.c keyboard_amstrad.c \ - keyboard_at.c keyboard_olim24.c keyboard_pcjr.c keyboard_xt.c \ - linux-time.c lpt.c mcr.c mem.c model.c mouse.c mouse_ps2.c \ - mouse_serial.c neat.c nmi.c nvr.c olivetti_m24.c opti.c pc.c \ - pci.c pic.c piix.c pit.c ppi.c ps1.c rom.c serial.c sis496.c \ - sound.c sound_ad1848.c sound_adlib.c sound_adlibgold.c \ - sound_cms.c sound_emu8k.c sound_gus.c sound_mpu401_uart.c \ - sound_opl.c sound_pas16.c sound_sb.c sound_sb_dsp.c \ - sound_sn76489.c sound_speaker.c sound_ssi2001.c sound_wss.c \ - soundopenal.c thread-pthread.c timer.c um8669f.c um8881f.c \ - vid_ati_eeprom.c vid_ati_mach64.c vid_ati18800.c \ - vid_ati28800.c vid_ati68860_ramdac.c vid_cga.c vid_cl5429.c \ - vid_ega.c vid_et4000.c vid_et4000w32.c vid_hercules.c \ - vid_icd2061.c vid_ics2595.c vid_mda.c vid_olivetti_m24.c \ - vid_oti067.c vid_paradise.c vid_pc200.c vid_pc1512.c \ - vid_pc1640.c vid_pcjr.c vid_s3.c vid_s3_virge.c \ - vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c \ - vid_svga_render.c vid_tandy.c vid_tgui9440.c \ - vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c \ - vid_voodoo.c video.c wd76c10.c x86seg.c x87.c xtide.c \ - sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ - resid-fp/convolve.cc resid-fp/convolve-sse.cc \ - resid-fp/envelope.cc resid-fp/extfilt.cc resid-fp/filter.cc \ - resid-fp/pot.cc resid-fp/sid.cc resid-fp/voice.cc \ - resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \ - resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc \ - resid-fp/wave8580_PS_.cc resid-fp/wave8580_PST.cc \ - resid-fp/wave8580_P_T.cc resid-fp/wave8580__ST.cc \ - resid-fp/wave.cc $(am__append_1) $(am__append_2) -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .cc .cpp .o .obj -$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu src/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p; \ - then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) -pcem$(EXEEXT): $(pcem_OBJECTS) $(pcem_DEPENDENCIES) - @rm -f pcem$(EXEEXT) - $(CXXLINK) $(pcem_OBJECTS) $(pcem_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolve-sse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/convolve.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/envelope.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extfilt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-386_dynarec_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-808x.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-acer386sx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ali1429.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-gui-configure.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-gui-hdconf.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-gui.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-joystick.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-keyboard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-midi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-mouse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-allegro-video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-amstrad.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-ioctl-linux.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cdrom-null.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_ops.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_486.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_timing_pentium.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_x86-64.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-codegen_x86.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-compaq.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-config.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-cpu.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-device.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_fdi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-disc_img.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-dma.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdc37c665.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-fdi2raw.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-gameport.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-headland.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430fx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430lx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-i430vx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ide.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-intel_flash.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-io.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-jim.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_amstrad.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_at.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_olim24.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_pcjr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-keyboard_xt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-linux-time.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-lpt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mcr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mem.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-model.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_ps2.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-mouse_serial.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-neat.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nmi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-nvr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-olivetti_m24.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-opti.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pci.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pic.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-piix.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-pit.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ppi.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-ps1.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-rom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-serial.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sis496.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ad1848.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlib.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_adlibgold.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_cms.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_emu8k.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_gus.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_mpu401_uart.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_opl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_pas16.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sb_dsp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_sn76489.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_speaker.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_ssi2001.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-sound_wss.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-soundopenal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-thread-pthread.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-timer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8669f.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-um8881f.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati18800.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati28800.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati68860_ramdac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_eeprom.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ati_mach64.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cga.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_cl5429.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ega.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_et4000w32.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_hercules.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_icd2061.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ics2595.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_mda.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_olivetti_m24.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti067.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_paradise.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1512.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc1640.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pc200.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_pcjr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_s3_virge.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_sdac_ramdac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_stg_ramdac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_svga_render.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tandy.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tgui9440.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tkd8001_ramdac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_tvga.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_unk_ramdac.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_vga.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_voodoo.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-video.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-wd76c10.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x86seg.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-x87.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-xtide.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pot.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sound_dbopl.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sound_resid.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/voice.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave6581__ST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580_PST.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580_PS_.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580_P_T.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wave8580__ST.Po@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -pcem-386.o: 386.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386.o -MD -MP -MF $(DEPDIR)/pcem-386.Tpo -c -o pcem-386.o `test -f '386.c' || echo '$(srcdir)/'`386.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-386.Tpo $(DEPDIR)/pcem-386.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='386.c' object='pcem-386.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386.o `test -f '386.c' || echo '$(srcdir)/'`386.c - -pcem-386.obj: 386.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386.obj -MD -MP -MF $(DEPDIR)/pcem-386.Tpo -c -o pcem-386.obj `if test -f '386.c'; then $(CYGPATH_W) '386.c'; else $(CYGPATH_W) '$(srcdir)/386.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-386.Tpo $(DEPDIR)/pcem-386.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='386.c' object='pcem-386.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386.obj `if test -f '386.c'; then $(CYGPATH_W) '386.c'; else $(CYGPATH_W) '$(srcdir)/386.c'; fi` - -pcem-386_dynarec.o: 386_dynarec.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386_dynarec.o -MD -MP -MF $(DEPDIR)/pcem-386_dynarec.Tpo -c -o pcem-386_dynarec.o `test -f '386_dynarec.c' || echo '$(srcdir)/'`386_dynarec.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-386_dynarec.Tpo $(DEPDIR)/pcem-386_dynarec.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='386_dynarec.c' object='pcem-386_dynarec.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386_dynarec.o `test -f '386_dynarec.c' || echo '$(srcdir)/'`386_dynarec.c - -pcem-386_dynarec.obj: 386_dynarec.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386_dynarec.obj -MD -MP -MF $(DEPDIR)/pcem-386_dynarec.Tpo -c -o pcem-386_dynarec.obj `if test -f '386_dynarec.c'; then $(CYGPATH_W) '386_dynarec.c'; else $(CYGPATH_W) '$(srcdir)/386_dynarec.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-386_dynarec.Tpo $(DEPDIR)/pcem-386_dynarec.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='386_dynarec.c' object='pcem-386_dynarec.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386_dynarec.obj `if test -f '386_dynarec.c'; then $(CYGPATH_W) '386_dynarec.c'; else $(CYGPATH_W) '$(srcdir)/386_dynarec.c'; fi` - -pcem-386_dynarec_ops.o: 386_dynarec_ops.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386_dynarec_ops.o -MD -MP -MF $(DEPDIR)/pcem-386_dynarec_ops.Tpo -c -o pcem-386_dynarec_ops.o `test -f '386_dynarec_ops.c' || echo '$(srcdir)/'`386_dynarec_ops.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-386_dynarec_ops.Tpo $(DEPDIR)/pcem-386_dynarec_ops.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='386_dynarec_ops.c' object='pcem-386_dynarec_ops.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386_dynarec_ops.o `test -f '386_dynarec_ops.c' || echo '$(srcdir)/'`386_dynarec_ops.c - -pcem-386_dynarec_ops.obj: 386_dynarec_ops.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-386_dynarec_ops.obj -MD -MP -MF $(DEPDIR)/pcem-386_dynarec_ops.Tpo -c -o pcem-386_dynarec_ops.obj `if test -f '386_dynarec_ops.c'; then $(CYGPATH_W) '386_dynarec_ops.c'; else $(CYGPATH_W) '$(srcdir)/386_dynarec_ops.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-386_dynarec_ops.Tpo $(DEPDIR)/pcem-386_dynarec_ops.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='386_dynarec_ops.c' object='pcem-386_dynarec_ops.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-386_dynarec_ops.obj `if test -f '386_dynarec_ops.c'; then $(CYGPATH_W) '386_dynarec_ops.c'; else $(CYGPATH_W) '$(srcdir)/386_dynarec_ops.c'; fi` - -pcem-808x.o: 808x.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-808x.o -MD -MP -MF $(DEPDIR)/pcem-808x.Tpo -c -o pcem-808x.o `test -f '808x.c' || echo '$(srcdir)/'`808x.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-808x.Tpo $(DEPDIR)/pcem-808x.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='808x.c' object='pcem-808x.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-808x.o `test -f '808x.c' || echo '$(srcdir)/'`808x.c - -pcem-808x.obj: 808x.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-808x.obj -MD -MP -MF $(DEPDIR)/pcem-808x.Tpo -c -o pcem-808x.obj `if test -f '808x.c'; then $(CYGPATH_W) '808x.c'; else $(CYGPATH_W) '$(srcdir)/808x.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-808x.Tpo $(DEPDIR)/pcem-808x.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='808x.c' object='pcem-808x.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-808x.obj `if test -f '808x.c'; then $(CYGPATH_W) '808x.c'; else $(CYGPATH_W) '$(srcdir)/808x.c'; fi` - -pcem-acer386sx.o: acer386sx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acer386sx.o -MD -MP -MF $(DEPDIR)/pcem-acer386sx.Tpo -c -o pcem-acer386sx.o `test -f 'acer386sx.c' || echo '$(srcdir)/'`acer386sx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-acer386sx.Tpo $(DEPDIR)/pcem-acer386sx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='acer386sx.c' object='pcem-acer386sx.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acer386sx.o `test -f 'acer386sx.c' || echo '$(srcdir)/'`acer386sx.c - -pcem-acer386sx.obj: acer386sx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-acer386sx.obj -MD -MP -MF $(DEPDIR)/pcem-acer386sx.Tpo -c -o pcem-acer386sx.obj `if test -f 'acer386sx.c'; then $(CYGPATH_W) 'acer386sx.c'; else $(CYGPATH_W) '$(srcdir)/acer386sx.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-acer386sx.Tpo $(DEPDIR)/pcem-acer386sx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='acer386sx.c' object='pcem-acer386sx.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-acer386sx.obj `if test -f 'acer386sx.c'; then $(CYGPATH_W) 'acer386sx.c'; else $(CYGPATH_W) '$(srcdir)/acer386sx.c'; fi` - -pcem-ali1429.o: ali1429.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ali1429.o -MD -MP -MF $(DEPDIR)/pcem-ali1429.Tpo -c -o pcem-ali1429.o `test -f 'ali1429.c' || echo '$(srcdir)/'`ali1429.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ali1429.Tpo $(DEPDIR)/pcem-ali1429.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ali1429.c' object='pcem-ali1429.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ali1429.o `test -f 'ali1429.c' || echo '$(srcdir)/'`ali1429.c - -pcem-ali1429.obj: ali1429.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ali1429.obj -MD -MP -MF $(DEPDIR)/pcem-ali1429.Tpo -c -o pcem-ali1429.obj `if test -f 'ali1429.c'; then $(CYGPATH_W) 'ali1429.c'; else $(CYGPATH_W) '$(srcdir)/ali1429.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ali1429.Tpo $(DEPDIR)/pcem-ali1429.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ali1429.c' object='pcem-ali1429.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ali1429.obj `if test -f 'ali1429.c'; then $(CYGPATH_W) 'ali1429.c'; else $(CYGPATH_W) '$(srcdir)/ali1429.c'; fi` - -pcem-allegro-gui.o: allegro-gui.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui.Tpo -c -o pcem-allegro-gui.o `test -f 'allegro-gui.c' || echo '$(srcdir)/'`allegro-gui.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-gui.c' object='pcem-allegro-gui.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui.o `test -f 'allegro-gui.c' || echo '$(srcdir)/'`allegro-gui.c - -pcem-allegro-gui.obj: allegro-gui.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui.Tpo -c -o pcem-allegro-gui.obj `if test -f 'allegro-gui.c'; then $(CYGPATH_W) 'allegro-gui.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-gui.Tpo $(DEPDIR)/pcem-allegro-gui.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-gui.c' object='pcem-allegro-gui.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui.obj `if test -f 'allegro-gui.c'; then $(CYGPATH_W) 'allegro-gui.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui.c'; fi` - -pcem-allegro-gui-configure.o: allegro-gui-configure.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-configure.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-configure.Tpo -c -o pcem-allegro-gui-configure.o `test -f 'allegro-gui-configure.c' || echo '$(srcdir)/'`allegro-gui-configure.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-gui-configure.c' object='pcem-allegro-gui-configure.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-configure.o `test -f 'allegro-gui-configure.c' || echo '$(srcdir)/'`allegro-gui-configure.c - -pcem-allegro-gui-configure.obj: allegro-gui-configure.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-configure.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-configure.Tpo -c -o pcem-allegro-gui-configure.obj `if test -f 'allegro-gui-configure.c'; then $(CYGPATH_W) 'allegro-gui-configure.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-configure.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-gui-configure.Tpo $(DEPDIR)/pcem-allegro-gui-configure.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-gui-configure.c' object='pcem-allegro-gui-configure.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-configure.obj `if test -f 'allegro-gui-configure.c'; then $(CYGPATH_W) 'allegro-gui-configure.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-configure.c'; fi` - -pcem-allegro-gui-hdconf.o: allegro-gui-hdconf.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-hdconf.o -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo -c -o pcem-allegro-gui-hdconf.o `test -f 'allegro-gui-hdconf.c' || echo '$(srcdir)/'`allegro-gui-hdconf.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-gui-hdconf.c' object='pcem-allegro-gui-hdconf.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-hdconf.o `test -f 'allegro-gui-hdconf.c' || echo '$(srcdir)/'`allegro-gui-hdconf.c - -pcem-allegro-gui-hdconf.obj: allegro-gui-hdconf.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-gui-hdconf.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo -c -o pcem-allegro-gui-hdconf.obj `if test -f 'allegro-gui-hdconf.c'; then $(CYGPATH_W) 'allegro-gui-hdconf.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-hdconf.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-gui-hdconf.Tpo $(DEPDIR)/pcem-allegro-gui-hdconf.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-gui-hdconf.c' object='pcem-allegro-gui-hdconf.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-gui-hdconf.obj `if test -f 'allegro-gui-hdconf.c'; then $(CYGPATH_W) 'allegro-gui-hdconf.c'; else $(CYGPATH_W) '$(srcdir)/allegro-gui-hdconf.c'; fi` - -pcem-allegro-joystick.o: allegro-joystick.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-joystick.o -MD -MP -MF $(DEPDIR)/pcem-allegro-joystick.Tpo -c -o pcem-allegro-joystick.o `test -f 'allegro-joystick.c' || echo '$(srcdir)/'`allegro-joystick.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-joystick.c' object='pcem-allegro-joystick.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-joystick.o `test -f 'allegro-joystick.c' || echo '$(srcdir)/'`allegro-joystick.c - -pcem-allegro-joystick.obj: allegro-joystick.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-joystick.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-joystick.Tpo -c -o pcem-allegro-joystick.obj `if test -f 'allegro-joystick.c'; then $(CYGPATH_W) 'allegro-joystick.c'; else $(CYGPATH_W) '$(srcdir)/allegro-joystick.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-joystick.Tpo $(DEPDIR)/pcem-allegro-joystick.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-joystick.c' object='pcem-allegro-joystick.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-joystick.obj `if test -f 'allegro-joystick.c'; then $(CYGPATH_W) 'allegro-joystick.c'; else $(CYGPATH_W) '$(srcdir)/allegro-joystick.c'; fi` - -pcem-allegro-keyboard.o: allegro-keyboard.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-keyboard.o -MD -MP -MF $(DEPDIR)/pcem-allegro-keyboard.Tpo -c -o pcem-allegro-keyboard.o `test -f 'allegro-keyboard.c' || echo '$(srcdir)/'`allegro-keyboard.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-keyboard.c' object='pcem-allegro-keyboard.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-keyboard.o `test -f 'allegro-keyboard.c' || echo '$(srcdir)/'`allegro-keyboard.c - -pcem-allegro-keyboard.obj: allegro-keyboard.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-keyboard.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-keyboard.Tpo -c -o pcem-allegro-keyboard.obj `if test -f 'allegro-keyboard.c'; then $(CYGPATH_W) 'allegro-keyboard.c'; else $(CYGPATH_W) '$(srcdir)/allegro-keyboard.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-keyboard.Tpo $(DEPDIR)/pcem-allegro-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-keyboard.c' object='pcem-allegro-keyboard.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-keyboard.obj `if test -f 'allegro-keyboard.c'; then $(CYGPATH_W) 'allegro-keyboard.c'; else $(CYGPATH_W) '$(srcdir)/allegro-keyboard.c'; fi` - -pcem-allegro-main.o: allegro-main.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-main.o -MD -MP -MF $(DEPDIR)/pcem-allegro-main.Tpo -c -o pcem-allegro-main.o `test -f 'allegro-main.c' || echo '$(srcdir)/'`allegro-main.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-main.c' object='pcem-allegro-main.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-main.o `test -f 'allegro-main.c' || echo '$(srcdir)/'`allegro-main.c - -pcem-allegro-main.obj: allegro-main.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-main.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-main.Tpo -c -o pcem-allegro-main.obj `if test -f 'allegro-main.c'; then $(CYGPATH_W) 'allegro-main.c'; else $(CYGPATH_W) '$(srcdir)/allegro-main.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-main.Tpo $(DEPDIR)/pcem-allegro-main.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-main.c' object='pcem-allegro-main.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-main.obj `if test -f 'allegro-main.c'; then $(CYGPATH_W) 'allegro-main.c'; else $(CYGPATH_W) '$(srcdir)/allegro-main.c'; fi` - -pcem-allegro-midi.o: allegro-midi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-midi.o -MD -MP -MF $(DEPDIR)/pcem-allegro-midi.Tpo -c -o pcem-allegro-midi.o `test -f 'allegro-midi.c' || echo '$(srcdir)/'`allegro-midi.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-midi.c' object='pcem-allegro-midi.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-midi.o `test -f 'allegro-midi.c' || echo '$(srcdir)/'`allegro-midi.c - -pcem-allegro-midi.obj: allegro-midi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-midi.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-midi.Tpo -c -o pcem-allegro-midi.obj `if test -f 'allegro-midi.c'; then $(CYGPATH_W) 'allegro-midi.c'; else $(CYGPATH_W) '$(srcdir)/allegro-midi.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-midi.Tpo $(DEPDIR)/pcem-allegro-midi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-midi.c' object='pcem-allegro-midi.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-midi.obj `if test -f 'allegro-midi.c'; then $(CYGPATH_W) 'allegro-midi.c'; else $(CYGPATH_W) '$(srcdir)/allegro-midi.c'; fi` - -pcem-allegro-mouse.o: allegro-mouse.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-mouse.o -MD -MP -MF $(DEPDIR)/pcem-allegro-mouse.Tpo -c -o pcem-allegro-mouse.o `test -f 'allegro-mouse.c' || echo '$(srcdir)/'`allegro-mouse.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-mouse.c' object='pcem-allegro-mouse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-mouse.o `test -f 'allegro-mouse.c' || echo '$(srcdir)/'`allegro-mouse.c - -pcem-allegro-mouse.obj: allegro-mouse.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-mouse.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-mouse.Tpo -c -o pcem-allegro-mouse.obj `if test -f 'allegro-mouse.c'; then $(CYGPATH_W) 'allegro-mouse.c'; else $(CYGPATH_W) '$(srcdir)/allegro-mouse.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-mouse.Tpo $(DEPDIR)/pcem-allegro-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-mouse.c' object='pcem-allegro-mouse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-mouse.obj `if test -f 'allegro-mouse.c'; then $(CYGPATH_W) 'allegro-mouse.c'; else $(CYGPATH_W) '$(srcdir)/allegro-mouse.c'; fi` - -pcem-allegro-video.o: allegro-video.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-video.o -MD -MP -MF $(DEPDIR)/pcem-allegro-video.Tpo -c -o pcem-allegro-video.o `test -f 'allegro-video.c' || echo '$(srcdir)/'`allegro-video.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-video.c' object='pcem-allegro-video.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-video.o `test -f 'allegro-video.c' || echo '$(srcdir)/'`allegro-video.c - -pcem-allegro-video.obj: allegro-video.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-allegro-video.obj -MD -MP -MF $(DEPDIR)/pcem-allegro-video.Tpo -c -o pcem-allegro-video.obj `if test -f 'allegro-video.c'; then $(CYGPATH_W) 'allegro-video.c'; else $(CYGPATH_W) '$(srcdir)/allegro-video.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-allegro-video.Tpo $(DEPDIR)/pcem-allegro-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='allegro-video.c' object='pcem-allegro-video.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-allegro-video.obj `if test -f 'allegro-video.c'; then $(CYGPATH_W) 'allegro-video.c'; else $(CYGPATH_W) '$(srcdir)/allegro-video.c'; fi` - -pcem-amstrad.o: amstrad.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-amstrad.o -MD -MP -MF $(DEPDIR)/pcem-amstrad.Tpo -c -o pcem-amstrad.o `test -f 'amstrad.c' || echo '$(srcdir)/'`amstrad.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-amstrad.Tpo $(DEPDIR)/pcem-amstrad.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amstrad.c' object='pcem-amstrad.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-amstrad.o `test -f 'amstrad.c' || echo '$(srcdir)/'`amstrad.c - -pcem-amstrad.obj: amstrad.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-amstrad.obj -MD -MP -MF $(DEPDIR)/pcem-amstrad.Tpo -c -o pcem-amstrad.obj `if test -f 'amstrad.c'; then $(CYGPATH_W) 'amstrad.c'; else $(CYGPATH_W) '$(srcdir)/amstrad.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-amstrad.Tpo $(DEPDIR)/pcem-amstrad.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='amstrad.c' object='pcem-amstrad.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-amstrad.obj `if test -f 'amstrad.c'; then $(CYGPATH_W) 'amstrad.c'; else $(CYGPATH_W) '$(srcdir)/amstrad.c'; fi` - -pcem-cdrom-ioctl-linux.o: cdrom-ioctl-linux.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-linux.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo -c -o pcem-cdrom-ioctl-linux.o `test -f 'cdrom-ioctl-linux.c' || echo '$(srcdir)/'`cdrom-ioctl-linux.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cdrom-ioctl-linux.c' object='pcem-cdrom-ioctl-linux.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-linux.o `test -f 'cdrom-ioctl-linux.c' || echo '$(srcdir)/'`cdrom-ioctl-linux.c - -pcem-cdrom-ioctl-linux.obj: cdrom-ioctl-linux.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-ioctl-linux.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo -c -o pcem-cdrom-ioctl-linux.obj `if test -f 'cdrom-ioctl-linux.c'; then $(CYGPATH_W) 'cdrom-ioctl-linux.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-linux.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-cdrom-ioctl-linux.Tpo $(DEPDIR)/pcem-cdrom-ioctl-linux.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cdrom-ioctl-linux.c' object='pcem-cdrom-ioctl-linux.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-ioctl-linux.obj `if test -f 'cdrom-ioctl-linux.c'; then $(CYGPATH_W) 'cdrom-ioctl-linux.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-ioctl-linux.c'; fi` - -pcem-cdrom-null.o: cdrom-null.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-null.o -MD -MP -MF $(DEPDIR)/pcem-cdrom-null.Tpo -c -o pcem-cdrom-null.o `test -f 'cdrom-null.c' || echo '$(srcdir)/'`cdrom-null.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-cdrom-null.Tpo $(DEPDIR)/pcem-cdrom-null.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cdrom-null.c' object='pcem-cdrom-null.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-null.o `test -f 'cdrom-null.c' || echo '$(srcdir)/'`cdrom-null.c - -pcem-cdrom-null.obj: cdrom-null.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cdrom-null.obj -MD -MP -MF $(DEPDIR)/pcem-cdrom-null.Tpo -c -o pcem-cdrom-null.obj `if test -f 'cdrom-null.c'; then $(CYGPATH_W) 'cdrom-null.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-null.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-cdrom-null.Tpo $(DEPDIR)/pcem-cdrom-null.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cdrom-null.c' object='pcem-cdrom-null.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cdrom-null.obj `if test -f 'cdrom-null.c'; then $(CYGPATH_W) 'cdrom-null.c'; else $(CYGPATH_W) '$(srcdir)/cdrom-null.c'; fi` - -pcem-codegen.o: codegen.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen.o -MD -MP -MF $(DEPDIR)/pcem-codegen.Tpo -c -o pcem-codegen.o `test -f 'codegen.c' || echo '$(srcdir)/'`codegen.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen.Tpo $(DEPDIR)/pcem-codegen.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen.c' object='pcem-codegen.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen.o `test -f 'codegen.c' || echo '$(srcdir)/'`codegen.c - -pcem-codegen.obj: codegen.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen.obj -MD -MP -MF $(DEPDIR)/pcem-codegen.Tpo -c -o pcem-codegen.obj `if test -f 'codegen.c'; then $(CYGPATH_W) 'codegen.c'; else $(CYGPATH_W) '$(srcdir)/codegen.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen.Tpo $(DEPDIR)/pcem-codegen.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen.c' object='pcem-codegen.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen.obj `if test -f 'codegen.c'; then $(CYGPATH_W) 'codegen.c'; else $(CYGPATH_W) '$(srcdir)/codegen.c'; fi` - -pcem-codegen_ops.o: codegen_ops.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops.o -MD -MP -MF $(DEPDIR)/pcem-codegen_ops.Tpo -c -o pcem-codegen_ops.o `test -f 'codegen_ops.c' || echo '$(srcdir)/'`codegen_ops.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_ops.Tpo $(DEPDIR)/pcem-codegen_ops.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_ops.c' object='pcem-codegen_ops.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops.o `test -f 'codegen_ops.c' || echo '$(srcdir)/'`codegen_ops.c - -pcem-codegen_ops.obj: codegen_ops.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_ops.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_ops.Tpo -c -o pcem-codegen_ops.obj `if test -f 'codegen_ops.c'; then $(CYGPATH_W) 'codegen_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_ops.Tpo $(DEPDIR)/pcem-codegen_ops.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_ops.c' object='pcem-codegen_ops.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_ops.obj `if test -f 'codegen_ops.c'; then $(CYGPATH_W) 'codegen_ops.c'; else $(CYGPATH_W) '$(srcdir)/codegen_ops.c'; fi` - -pcem-codegen_timing_486.o: codegen_timing_486.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_486.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_486.Tpo -c -o pcem-codegen_timing_486.o `test -f 'codegen_timing_486.c' || echo '$(srcdir)/'`codegen_timing_486.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_timing_486.Tpo $(DEPDIR)/pcem-codegen_timing_486.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_timing_486.c' object='pcem-codegen_timing_486.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_486.o `test -f 'codegen_timing_486.c' || echo '$(srcdir)/'`codegen_timing_486.c - -pcem-codegen_timing_486.obj: codegen_timing_486.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_486.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_486.Tpo -c -o pcem-codegen_timing_486.obj `if test -f 'codegen_timing_486.c'; then $(CYGPATH_W) 'codegen_timing_486.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_486.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_timing_486.Tpo $(DEPDIR)/pcem-codegen_timing_486.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_timing_486.c' object='pcem-codegen_timing_486.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_486.obj `if test -f 'codegen_timing_486.c'; then $(CYGPATH_W) 'codegen_timing_486.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_486.c'; fi` - -pcem-codegen_timing_pentium.o: codegen_timing_pentium.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_pentium.o -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_pentium.Tpo -c -o pcem-codegen_timing_pentium.o `test -f 'codegen_timing_pentium.c' || echo '$(srcdir)/'`codegen_timing_pentium.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_timing_pentium.Tpo $(DEPDIR)/pcem-codegen_timing_pentium.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_timing_pentium.c' object='pcem-codegen_timing_pentium.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_pentium.o `test -f 'codegen_timing_pentium.c' || echo '$(srcdir)/'`codegen_timing_pentium.c - -pcem-codegen_timing_pentium.obj: codegen_timing_pentium.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_timing_pentium.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_timing_pentium.Tpo -c -o pcem-codegen_timing_pentium.obj `if test -f 'codegen_timing_pentium.c'; then $(CYGPATH_W) 'codegen_timing_pentium.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_pentium.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_timing_pentium.Tpo $(DEPDIR)/pcem-codegen_timing_pentium.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_timing_pentium.c' object='pcem-codegen_timing_pentium.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_timing_pentium.obj `if test -f 'codegen_timing_pentium.c'; then $(CYGPATH_W) 'codegen_timing_pentium.c'; else $(CYGPATH_W) '$(srcdir)/codegen_timing_pentium.c'; fi` - -pcem-compaq.o: compaq.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-compaq.o -MD -MP -MF $(DEPDIR)/pcem-compaq.Tpo -c -o pcem-compaq.o `test -f 'compaq.c' || echo '$(srcdir)/'`compaq.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-compaq.Tpo $(DEPDIR)/pcem-compaq.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='compaq.c' object='pcem-compaq.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-compaq.o `test -f 'compaq.c' || echo '$(srcdir)/'`compaq.c - -pcem-compaq.obj: compaq.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-compaq.obj -MD -MP -MF $(DEPDIR)/pcem-compaq.Tpo -c -o pcem-compaq.obj `if test -f 'compaq.c'; then $(CYGPATH_W) 'compaq.c'; else $(CYGPATH_W) '$(srcdir)/compaq.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-compaq.Tpo $(DEPDIR)/pcem-compaq.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='compaq.c' object='pcem-compaq.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-compaq.obj `if test -f 'compaq.c'; then $(CYGPATH_W) 'compaq.c'; else $(CYGPATH_W) '$(srcdir)/compaq.c'; fi` - -pcem-config.o: config.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-config.o -MD -MP -MF $(DEPDIR)/pcem-config.Tpo -c -o pcem-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-config.Tpo $(DEPDIR)/pcem-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config.c' object='pcem-config.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c - -pcem-config.obj: config.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-config.obj -MD -MP -MF $(DEPDIR)/pcem-config.Tpo -c -o pcem-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-config.Tpo $(DEPDIR)/pcem-config.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config.c' object='pcem-config.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi` - -pcem-cpu.o: cpu.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cpu.o -MD -MP -MF $(DEPDIR)/pcem-cpu.Tpo -c -o pcem-cpu.o `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-cpu.Tpo $(DEPDIR)/pcem-cpu.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpu.c' object='pcem-cpu.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cpu.o `test -f 'cpu.c' || echo '$(srcdir)/'`cpu.c - -pcem-cpu.obj: cpu.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-cpu.obj -MD -MP -MF $(DEPDIR)/pcem-cpu.Tpo -c -o pcem-cpu.obj `if test -f 'cpu.c'; then $(CYGPATH_W) 'cpu.c'; else $(CYGPATH_W) '$(srcdir)/cpu.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-cpu.Tpo $(DEPDIR)/pcem-cpu.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cpu.c' object='pcem-cpu.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-cpu.obj `if test -f 'cpu.c'; then $(CYGPATH_W) 'cpu.c'; else $(CYGPATH_W) '$(srcdir)/cpu.c'; fi` - -pcem-dac.o: dac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dac.o -MD -MP -MF $(DEPDIR)/pcem-dac.Tpo -c -o pcem-dac.o `test -f 'dac.c' || echo '$(srcdir)/'`dac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-dac.Tpo $(DEPDIR)/pcem-dac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dac.c' object='pcem-dac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dac.o `test -f 'dac.c' || echo '$(srcdir)/'`dac.c - -pcem-dac.obj: dac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dac.obj -MD -MP -MF $(DEPDIR)/pcem-dac.Tpo -c -o pcem-dac.obj `if test -f 'dac.c'; then $(CYGPATH_W) 'dac.c'; else $(CYGPATH_W) '$(srcdir)/dac.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-dac.Tpo $(DEPDIR)/pcem-dac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dac.c' object='pcem-dac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dac.obj `if test -f 'dac.c'; then $(CYGPATH_W) 'dac.c'; else $(CYGPATH_W) '$(srcdir)/dac.c'; fi` - -pcem-device.o: device.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-device.o -MD -MP -MF $(DEPDIR)/pcem-device.Tpo -c -o pcem-device.o `test -f 'device.c' || echo '$(srcdir)/'`device.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-device.Tpo $(DEPDIR)/pcem-device.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='device.c' object='pcem-device.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-device.o `test -f 'device.c' || echo '$(srcdir)/'`device.c - -pcem-device.obj: device.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-device.obj -MD -MP -MF $(DEPDIR)/pcem-device.Tpo -c -o pcem-device.obj `if test -f 'device.c'; then $(CYGPATH_W) 'device.c'; else $(CYGPATH_W) '$(srcdir)/device.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-device.Tpo $(DEPDIR)/pcem-device.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='device.c' object='pcem-device.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-device.obj `if test -f 'device.c'; then $(CYGPATH_W) 'device.c'; else $(CYGPATH_W) '$(srcdir)/device.c'; fi` - -pcem-disc.o: disc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-disc.o -MD -MP -MF $(DEPDIR)/pcem-disc.Tpo -c -o pcem-disc.o `test -f 'disc.c' || echo '$(srcdir)/'`disc.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-disc.Tpo $(DEPDIR)/pcem-disc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='disc.c' object='pcem-disc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-disc.o `test -f 'disc.c' || echo '$(srcdir)/'`disc.c - -pcem-disc.obj: disc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-disc.obj -MD -MP -MF $(DEPDIR)/pcem-disc.Tpo -c -o pcem-disc.obj `if test -f 'disc.c'; then $(CYGPATH_W) 'disc.c'; else $(CYGPATH_W) '$(srcdir)/disc.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-disc.Tpo $(DEPDIR)/pcem-disc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='disc.c' object='pcem-disc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-disc.obj `if test -f 'disc.c'; then $(CYGPATH_W) 'disc.c'; else $(CYGPATH_W) '$(srcdir)/disc.c'; fi` - -pcem-disc_fdi.o: disc_fdi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-disc_fdi.o -MD -MP -MF $(DEPDIR)/pcem-disc_fdi.Tpo -c -o pcem-disc_fdi.o `test -f 'disc_fdi.c' || echo '$(srcdir)/'`disc_fdi.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-disc_fdi.Tpo $(DEPDIR)/pcem-disc_fdi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='disc_fdi.c' object='pcem-disc_fdi.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-disc_fdi.o `test -f 'disc_fdi.c' || echo '$(srcdir)/'`disc_fdi.c - -pcem-disc_fdi.obj: disc_fdi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-disc_fdi.obj -MD -MP -MF $(DEPDIR)/pcem-disc_fdi.Tpo -c -o pcem-disc_fdi.obj `if test -f 'disc_fdi.c'; then $(CYGPATH_W) 'disc_fdi.c'; else $(CYGPATH_W) '$(srcdir)/disc_fdi.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-disc_fdi.Tpo $(DEPDIR)/pcem-disc_fdi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='disc_fdi.c' object='pcem-disc_fdi.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-disc_fdi.obj `if test -f 'disc_fdi.c'; then $(CYGPATH_W) 'disc_fdi.c'; else $(CYGPATH_W) '$(srcdir)/disc_fdi.c'; fi` - -pcem-disc_img.o: disc_img.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-disc_img.o -MD -MP -MF $(DEPDIR)/pcem-disc_img.Tpo -c -o pcem-disc_img.o `test -f 'disc_img.c' || echo '$(srcdir)/'`disc_img.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-disc_img.Tpo $(DEPDIR)/pcem-disc_img.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='disc_img.c' object='pcem-disc_img.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-disc_img.o `test -f 'disc_img.c' || echo '$(srcdir)/'`disc_img.c - -pcem-disc_img.obj: disc_img.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-disc_img.obj -MD -MP -MF $(DEPDIR)/pcem-disc_img.Tpo -c -o pcem-disc_img.obj `if test -f 'disc_img.c'; then $(CYGPATH_W) 'disc_img.c'; else $(CYGPATH_W) '$(srcdir)/disc_img.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-disc_img.Tpo $(DEPDIR)/pcem-disc_img.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='disc_img.c' object='pcem-disc_img.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-disc_img.obj `if test -f 'disc_img.c'; then $(CYGPATH_W) 'disc_img.c'; else $(CYGPATH_W) '$(srcdir)/disc_img.c'; fi` - -pcem-dma.o: dma.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dma.o -MD -MP -MF $(DEPDIR)/pcem-dma.Tpo -c -o pcem-dma.o `test -f 'dma.c' || echo '$(srcdir)/'`dma.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-dma.Tpo $(DEPDIR)/pcem-dma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dma.c' object='pcem-dma.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dma.o `test -f 'dma.c' || echo '$(srcdir)/'`dma.c - -pcem-dma.obj: dma.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-dma.obj -MD -MP -MF $(DEPDIR)/pcem-dma.Tpo -c -o pcem-dma.obj `if test -f 'dma.c'; then $(CYGPATH_W) 'dma.c'; else $(CYGPATH_W) '$(srcdir)/dma.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-dma.Tpo $(DEPDIR)/pcem-dma.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dma.c' object='pcem-dma.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-dma.obj `if test -f 'dma.c'; then $(CYGPATH_W) 'dma.c'; else $(CYGPATH_W) '$(srcdir)/dma.c'; fi` - -pcem-fdc.o: fdc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdc.o -MD -MP -MF $(DEPDIR)/pcem-fdc.Tpo -c -o pcem-fdc.o `test -f 'fdc.c' || echo '$(srcdir)/'`fdc.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-fdc.Tpo $(DEPDIR)/pcem-fdc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fdc.c' object='pcem-fdc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdc.o `test -f 'fdc.c' || echo '$(srcdir)/'`fdc.c - -pcem-fdc.obj: fdc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdc.obj -MD -MP -MF $(DEPDIR)/pcem-fdc.Tpo -c -o pcem-fdc.obj `if test -f 'fdc.c'; then $(CYGPATH_W) 'fdc.c'; else $(CYGPATH_W) '$(srcdir)/fdc.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-fdc.Tpo $(DEPDIR)/pcem-fdc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fdc.c' object='pcem-fdc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdc.obj `if test -f 'fdc.c'; then $(CYGPATH_W) 'fdc.c'; else $(CYGPATH_W) '$(srcdir)/fdc.c'; fi` - -pcem-fdc37c665.o: fdc37c665.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdc37c665.o -MD -MP -MF $(DEPDIR)/pcem-fdc37c665.Tpo -c -o pcem-fdc37c665.o `test -f 'fdc37c665.c' || echo '$(srcdir)/'`fdc37c665.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-fdc37c665.Tpo $(DEPDIR)/pcem-fdc37c665.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fdc37c665.c' object='pcem-fdc37c665.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdc37c665.o `test -f 'fdc37c665.c' || echo '$(srcdir)/'`fdc37c665.c - -pcem-fdc37c665.obj: fdc37c665.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdc37c665.obj -MD -MP -MF $(DEPDIR)/pcem-fdc37c665.Tpo -c -o pcem-fdc37c665.obj `if test -f 'fdc37c665.c'; then $(CYGPATH_W) 'fdc37c665.c'; else $(CYGPATH_W) '$(srcdir)/fdc37c665.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-fdc37c665.Tpo $(DEPDIR)/pcem-fdc37c665.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fdc37c665.c' object='pcem-fdc37c665.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdc37c665.obj `if test -f 'fdc37c665.c'; then $(CYGPATH_W) 'fdc37c665.c'; else $(CYGPATH_W) '$(srcdir)/fdc37c665.c'; fi` - -pcem-fdi2raw.o: fdi2raw.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdi2raw.o -MD -MP -MF $(DEPDIR)/pcem-fdi2raw.Tpo -c -o pcem-fdi2raw.o `test -f 'fdi2raw.c' || echo '$(srcdir)/'`fdi2raw.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-fdi2raw.Tpo $(DEPDIR)/pcem-fdi2raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fdi2raw.c' object='pcem-fdi2raw.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdi2raw.o `test -f 'fdi2raw.c' || echo '$(srcdir)/'`fdi2raw.c - -pcem-fdi2raw.obj: fdi2raw.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-fdi2raw.obj -MD -MP -MF $(DEPDIR)/pcem-fdi2raw.Tpo -c -o pcem-fdi2raw.obj `if test -f 'fdi2raw.c'; then $(CYGPATH_W) 'fdi2raw.c'; else $(CYGPATH_W) '$(srcdir)/fdi2raw.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-fdi2raw.Tpo $(DEPDIR)/pcem-fdi2raw.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fdi2raw.c' object='pcem-fdi2raw.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-fdi2raw.obj `if test -f 'fdi2raw.c'; then $(CYGPATH_W) 'fdi2raw.c'; else $(CYGPATH_W) '$(srcdir)/fdi2raw.c'; fi` - -pcem-gameport.o: gameport.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-gameport.o -MD -MP -MF $(DEPDIR)/pcem-gameport.Tpo -c -o pcem-gameport.o `test -f 'gameport.c' || echo '$(srcdir)/'`gameport.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-gameport.Tpo $(DEPDIR)/pcem-gameport.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gameport.c' object='pcem-gameport.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-gameport.o `test -f 'gameport.c' || echo '$(srcdir)/'`gameport.c - -pcem-gameport.obj: gameport.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-gameport.obj -MD -MP -MF $(DEPDIR)/pcem-gameport.Tpo -c -o pcem-gameport.obj `if test -f 'gameport.c'; then $(CYGPATH_W) 'gameport.c'; else $(CYGPATH_W) '$(srcdir)/gameport.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-gameport.Tpo $(DEPDIR)/pcem-gameport.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gameport.c' object='pcem-gameport.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-gameport.obj `if test -f 'gameport.c'; then $(CYGPATH_W) 'gameport.c'; else $(CYGPATH_W) '$(srcdir)/gameport.c'; fi` - -pcem-headland.o: headland.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-headland.o -MD -MP -MF $(DEPDIR)/pcem-headland.Tpo -c -o pcem-headland.o `test -f 'headland.c' || echo '$(srcdir)/'`headland.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-headland.Tpo $(DEPDIR)/pcem-headland.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='headland.c' object='pcem-headland.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-headland.o `test -f 'headland.c' || echo '$(srcdir)/'`headland.c - -pcem-headland.obj: headland.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-headland.obj -MD -MP -MF $(DEPDIR)/pcem-headland.Tpo -c -o pcem-headland.obj `if test -f 'headland.c'; then $(CYGPATH_W) 'headland.c'; else $(CYGPATH_W) '$(srcdir)/headland.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-headland.Tpo $(DEPDIR)/pcem-headland.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='headland.c' object='pcem-headland.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-headland.obj `if test -f 'headland.c'; then $(CYGPATH_W) 'headland.c'; else $(CYGPATH_W) '$(srcdir)/headland.c'; fi` - -pcem-i430lx.o: i430lx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430lx.o -MD -MP -MF $(DEPDIR)/pcem-i430lx.Tpo -c -o pcem-i430lx.o `test -f 'i430lx.c' || echo '$(srcdir)/'`i430lx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-i430lx.Tpo $(DEPDIR)/pcem-i430lx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i430lx.c' object='pcem-i430lx.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430lx.o `test -f 'i430lx.c' || echo '$(srcdir)/'`i430lx.c - -pcem-i430lx.obj: i430lx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430lx.obj -MD -MP -MF $(DEPDIR)/pcem-i430lx.Tpo -c -o pcem-i430lx.obj `if test -f 'i430lx.c'; then $(CYGPATH_W) 'i430lx.c'; else $(CYGPATH_W) '$(srcdir)/i430lx.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-i430lx.Tpo $(DEPDIR)/pcem-i430lx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i430lx.c' object='pcem-i430lx.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430lx.obj `if test -f 'i430lx.c'; then $(CYGPATH_W) 'i430lx.c'; else $(CYGPATH_W) '$(srcdir)/i430lx.c'; fi` - -pcem-i430fx.o: i430fx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430fx.o -MD -MP -MF $(DEPDIR)/pcem-i430fx.Tpo -c -o pcem-i430fx.o `test -f 'i430fx.c' || echo '$(srcdir)/'`i430fx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-i430fx.Tpo $(DEPDIR)/pcem-i430fx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i430fx.c' object='pcem-i430fx.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430fx.o `test -f 'i430fx.c' || echo '$(srcdir)/'`i430fx.c - -pcem-i430fx.obj: i430fx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430fx.obj -MD -MP -MF $(DEPDIR)/pcem-i430fx.Tpo -c -o pcem-i430fx.obj `if test -f 'i430fx.c'; then $(CYGPATH_W) 'i430fx.c'; else $(CYGPATH_W) '$(srcdir)/i430fx.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-i430fx.Tpo $(DEPDIR)/pcem-i430fx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i430fx.c' object='pcem-i430fx.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430fx.obj `if test -f 'i430fx.c'; then $(CYGPATH_W) 'i430fx.c'; else $(CYGPATH_W) '$(srcdir)/i430fx.c'; fi` - -pcem-i430vx.o: i430vx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430vx.o -MD -MP -MF $(DEPDIR)/pcem-i430vx.Tpo -c -o pcem-i430vx.o `test -f 'i430vx.c' || echo '$(srcdir)/'`i430vx.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-i430vx.Tpo $(DEPDIR)/pcem-i430vx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i430vx.c' object='pcem-i430vx.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430vx.o `test -f 'i430vx.c' || echo '$(srcdir)/'`i430vx.c - -pcem-i430vx.obj: i430vx.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-i430vx.obj -MD -MP -MF $(DEPDIR)/pcem-i430vx.Tpo -c -o pcem-i430vx.obj `if test -f 'i430vx.c'; then $(CYGPATH_W) 'i430vx.c'; else $(CYGPATH_W) '$(srcdir)/i430vx.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-i430vx.Tpo $(DEPDIR)/pcem-i430vx.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='i430vx.c' object='pcem-i430vx.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-i430vx.obj `if test -f 'i430vx.c'; then $(CYGPATH_W) 'i430vx.c'; else $(CYGPATH_W) '$(srcdir)/i430vx.c'; fi` - -pcem-ide.o: ide.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ide.o -MD -MP -MF $(DEPDIR)/pcem-ide.Tpo -c -o pcem-ide.o `test -f 'ide.c' || echo '$(srcdir)/'`ide.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ide.Tpo $(DEPDIR)/pcem-ide.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ide.c' object='pcem-ide.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide.o `test -f 'ide.c' || echo '$(srcdir)/'`ide.c - -pcem-ide.obj: ide.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ide.obj -MD -MP -MF $(DEPDIR)/pcem-ide.Tpo -c -o pcem-ide.obj `if test -f 'ide.c'; then $(CYGPATH_W) 'ide.c'; else $(CYGPATH_W) '$(srcdir)/ide.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ide.Tpo $(DEPDIR)/pcem-ide.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ide.c' object='pcem-ide.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ide.obj `if test -f 'ide.c'; then $(CYGPATH_W) 'ide.c'; else $(CYGPATH_W) '$(srcdir)/ide.c'; fi` - -pcem-intel.o: intel.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-intel.o -MD -MP -MF $(DEPDIR)/pcem-intel.Tpo -c -o pcem-intel.o `test -f 'intel.c' || echo '$(srcdir)/'`intel.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-intel.Tpo $(DEPDIR)/pcem-intel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intel.c' object='pcem-intel.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-intel.o `test -f 'intel.c' || echo '$(srcdir)/'`intel.c - -pcem-intel.obj: intel.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-intel.obj -MD -MP -MF $(DEPDIR)/pcem-intel.Tpo -c -o pcem-intel.obj `if test -f 'intel.c'; then $(CYGPATH_W) 'intel.c'; else $(CYGPATH_W) '$(srcdir)/intel.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-intel.Tpo $(DEPDIR)/pcem-intel.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intel.c' object='pcem-intel.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-intel.obj `if test -f 'intel.c'; then $(CYGPATH_W) 'intel.c'; else $(CYGPATH_W) '$(srcdir)/intel.c'; fi` - -pcem-intel_flash.o: intel_flash.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-intel_flash.o -MD -MP -MF $(DEPDIR)/pcem-intel_flash.Tpo -c -o pcem-intel_flash.o `test -f 'intel_flash.c' || echo '$(srcdir)/'`intel_flash.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-intel_flash.Tpo $(DEPDIR)/pcem-intel_flash.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intel_flash.c' object='pcem-intel_flash.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-intel_flash.o `test -f 'intel_flash.c' || echo '$(srcdir)/'`intel_flash.c - -pcem-intel_flash.obj: intel_flash.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-intel_flash.obj -MD -MP -MF $(DEPDIR)/pcem-intel_flash.Tpo -c -o pcem-intel_flash.obj `if test -f 'intel_flash.c'; then $(CYGPATH_W) 'intel_flash.c'; else $(CYGPATH_W) '$(srcdir)/intel_flash.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-intel_flash.Tpo $(DEPDIR)/pcem-intel_flash.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='intel_flash.c' object='pcem-intel_flash.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-intel_flash.obj `if test -f 'intel_flash.c'; then $(CYGPATH_W) 'intel_flash.c'; else $(CYGPATH_W) '$(srcdir)/intel_flash.c'; fi` - -pcem-io.o: io.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-io.o -MD -MP -MF $(DEPDIR)/pcem-io.Tpo -c -o pcem-io.o `test -f 'io.c' || echo '$(srcdir)/'`io.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-io.Tpo $(DEPDIR)/pcem-io.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io.c' object='pcem-io.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-io.o `test -f 'io.c' || echo '$(srcdir)/'`io.c - -pcem-io.obj: io.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-io.obj -MD -MP -MF $(DEPDIR)/pcem-io.Tpo -c -o pcem-io.obj `if test -f 'io.c'; then $(CYGPATH_W) 'io.c'; else $(CYGPATH_W) '$(srcdir)/io.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-io.Tpo $(DEPDIR)/pcem-io.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='io.c' object='pcem-io.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-io.obj `if test -f 'io.c'; then $(CYGPATH_W) 'io.c'; else $(CYGPATH_W) '$(srcdir)/io.c'; fi` - -pcem-jim.o: jim.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-jim.o -MD -MP -MF $(DEPDIR)/pcem-jim.Tpo -c -o pcem-jim.o `test -f 'jim.c' || echo '$(srcdir)/'`jim.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-jim.Tpo $(DEPDIR)/pcem-jim.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='jim.c' object='pcem-jim.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-jim.o `test -f 'jim.c' || echo '$(srcdir)/'`jim.c - -pcem-jim.obj: jim.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-jim.obj -MD -MP -MF $(DEPDIR)/pcem-jim.Tpo -c -o pcem-jim.obj `if test -f 'jim.c'; then $(CYGPATH_W) 'jim.c'; else $(CYGPATH_W) '$(srcdir)/jim.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-jim.Tpo $(DEPDIR)/pcem-jim.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='jim.c' object='pcem-jim.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-jim.obj `if test -f 'jim.c'; then $(CYGPATH_W) 'jim.c'; else $(CYGPATH_W) '$(srcdir)/jim.c'; fi` - -pcem-keyboard.o: keyboard.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard.o -MD -MP -MF $(DEPDIR)/pcem-keyboard.Tpo -c -o pcem-keyboard.o `test -f 'keyboard.c' || echo '$(srcdir)/'`keyboard.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard.Tpo $(DEPDIR)/pcem-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard.c' object='pcem-keyboard.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard.o `test -f 'keyboard.c' || echo '$(srcdir)/'`keyboard.c - -pcem-keyboard.obj: keyboard.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard.obj -MD -MP -MF $(DEPDIR)/pcem-keyboard.Tpo -c -o pcem-keyboard.obj `if test -f 'keyboard.c'; then $(CYGPATH_W) 'keyboard.c'; else $(CYGPATH_W) '$(srcdir)/keyboard.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard.Tpo $(DEPDIR)/pcem-keyboard.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard.c' object='pcem-keyboard.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard.obj `if test -f 'keyboard.c'; then $(CYGPATH_W) 'keyboard.c'; else $(CYGPATH_W) '$(srcdir)/keyboard.c'; fi` - -pcem-keyboard_amstrad.o: keyboard_amstrad.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_amstrad.o -MD -MP -MF $(DEPDIR)/pcem-keyboard_amstrad.Tpo -c -o pcem-keyboard_amstrad.o `test -f 'keyboard_amstrad.c' || echo '$(srcdir)/'`keyboard_amstrad.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_amstrad.Tpo $(DEPDIR)/pcem-keyboard_amstrad.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_amstrad.c' object='pcem-keyboard_amstrad.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_amstrad.o `test -f 'keyboard_amstrad.c' || echo '$(srcdir)/'`keyboard_amstrad.c - -pcem-keyboard_amstrad.obj: keyboard_amstrad.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_amstrad.obj -MD -MP -MF $(DEPDIR)/pcem-keyboard_amstrad.Tpo -c -o pcem-keyboard_amstrad.obj `if test -f 'keyboard_amstrad.c'; then $(CYGPATH_W) 'keyboard_amstrad.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_amstrad.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_amstrad.Tpo $(DEPDIR)/pcem-keyboard_amstrad.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_amstrad.c' object='pcem-keyboard_amstrad.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_amstrad.obj `if test -f 'keyboard_amstrad.c'; then $(CYGPATH_W) 'keyboard_amstrad.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_amstrad.c'; fi` - -pcem-keyboard_at.o: keyboard_at.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_at.o -MD -MP -MF $(DEPDIR)/pcem-keyboard_at.Tpo -c -o pcem-keyboard_at.o `test -f 'keyboard_at.c' || echo '$(srcdir)/'`keyboard_at.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_at.Tpo $(DEPDIR)/pcem-keyboard_at.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_at.c' object='pcem-keyboard_at.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_at.o `test -f 'keyboard_at.c' || echo '$(srcdir)/'`keyboard_at.c - -pcem-keyboard_at.obj: keyboard_at.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_at.obj -MD -MP -MF $(DEPDIR)/pcem-keyboard_at.Tpo -c -o pcem-keyboard_at.obj `if test -f 'keyboard_at.c'; then $(CYGPATH_W) 'keyboard_at.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_at.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_at.Tpo $(DEPDIR)/pcem-keyboard_at.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_at.c' object='pcem-keyboard_at.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_at.obj `if test -f 'keyboard_at.c'; then $(CYGPATH_W) 'keyboard_at.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_at.c'; fi` - -pcem-keyboard_olim24.o: keyboard_olim24.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_olim24.o -MD -MP -MF $(DEPDIR)/pcem-keyboard_olim24.Tpo -c -o pcem-keyboard_olim24.o `test -f 'keyboard_olim24.c' || echo '$(srcdir)/'`keyboard_olim24.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_olim24.Tpo $(DEPDIR)/pcem-keyboard_olim24.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_olim24.c' object='pcem-keyboard_olim24.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_olim24.o `test -f 'keyboard_olim24.c' || echo '$(srcdir)/'`keyboard_olim24.c - -pcem-keyboard_olim24.obj: keyboard_olim24.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_olim24.obj -MD -MP -MF $(DEPDIR)/pcem-keyboard_olim24.Tpo -c -o pcem-keyboard_olim24.obj `if test -f 'keyboard_olim24.c'; then $(CYGPATH_W) 'keyboard_olim24.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_olim24.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_olim24.Tpo $(DEPDIR)/pcem-keyboard_olim24.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_olim24.c' object='pcem-keyboard_olim24.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_olim24.obj `if test -f 'keyboard_olim24.c'; then $(CYGPATH_W) 'keyboard_olim24.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_olim24.c'; fi` - -pcem-keyboard_pcjr.o: keyboard_pcjr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_pcjr.o -MD -MP -MF $(DEPDIR)/pcem-keyboard_pcjr.Tpo -c -o pcem-keyboard_pcjr.o `test -f 'keyboard_pcjr.c' || echo '$(srcdir)/'`keyboard_pcjr.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_pcjr.Tpo $(DEPDIR)/pcem-keyboard_pcjr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_pcjr.c' object='pcem-keyboard_pcjr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_pcjr.o `test -f 'keyboard_pcjr.c' || echo '$(srcdir)/'`keyboard_pcjr.c - -pcem-keyboard_pcjr.obj: keyboard_pcjr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_pcjr.obj -MD -MP -MF $(DEPDIR)/pcem-keyboard_pcjr.Tpo -c -o pcem-keyboard_pcjr.obj `if test -f 'keyboard_pcjr.c'; then $(CYGPATH_W) 'keyboard_pcjr.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_pcjr.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_pcjr.Tpo $(DEPDIR)/pcem-keyboard_pcjr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_pcjr.c' object='pcem-keyboard_pcjr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_pcjr.obj `if test -f 'keyboard_pcjr.c'; then $(CYGPATH_W) 'keyboard_pcjr.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_pcjr.c'; fi` - -pcem-keyboard_xt.o: keyboard_xt.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_xt.o -MD -MP -MF $(DEPDIR)/pcem-keyboard_xt.Tpo -c -o pcem-keyboard_xt.o `test -f 'keyboard_xt.c' || echo '$(srcdir)/'`keyboard_xt.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_xt.Tpo $(DEPDIR)/pcem-keyboard_xt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_xt.c' object='pcem-keyboard_xt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_xt.o `test -f 'keyboard_xt.c' || echo '$(srcdir)/'`keyboard_xt.c - -pcem-keyboard_xt.obj: keyboard_xt.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-keyboard_xt.obj -MD -MP -MF $(DEPDIR)/pcem-keyboard_xt.Tpo -c -o pcem-keyboard_xt.obj `if test -f 'keyboard_xt.c'; then $(CYGPATH_W) 'keyboard_xt.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_xt.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-keyboard_xt.Tpo $(DEPDIR)/pcem-keyboard_xt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='keyboard_xt.c' object='pcem-keyboard_xt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-keyboard_xt.obj `if test -f 'keyboard_xt.c'; then $(CYGPATH_W) 'keyboard_xt.c'; else $(CYGPATH_W) '$(srcdir)/keyboard_xt.c'; fi` - -pcem-linux-time.o: linux-time.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-linux-time.o -MD -MP -MF $(DEPDIR)/pcem-linux-time.Tpo -c -o pcem-linux-time.o `test -f 'linux-time.c' || echo '$(srcdir)/'`linux-time.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-linux-time.Tpo $(DEPDIR)/pcem-linux-time.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='linux-time.c' object='pcem-linux-time.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-linux-time.o `test -f 'linux-time.c' || echo '$(srcdir)/'`linux-time.c - -pcem-linux-time.obj: linux-time.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-linux-time.obj -MD -MP -MF $(DEPDIR)/pcem-linux-time.Tpo -c -o pcem-linux-time.obj `if test -f 'linux-time.c'; then $(CYGPATH_W) 'linux-time.c'; else $(CYGPATH_W) '$(srcdir)/linux-time.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-linux-time.Tpo $(DEPDIR)/pcem-linux-time.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='linux-time.c' object='pcem-linux-time.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-linux-time.obj `if test -f 'linux-time.c'; then $(CYGPATH_W) 'linux-time.c'; else $(CYGPATH_W) '$(srcdir)/linux-time.c'; fi` - -pcem-lpt.o: lpt.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-lpt.o -MD -MP -MF $(DEPDIR)/pcem-lpt.Tpo -c -o pcem-lpt.o `test -f 'lpt.c' || echo '$(srcdir)/'`lpt.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-lpt.Tpo $(DEPDIR)/pcem-lpt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lpt.c' object='pcem-lpt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-lpt.o `test -f 'lpt.c' || echo '$(srcdir)/'`lpt.c - -pcem-lpt.obj: lpt.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-lpt.obj -MD -MP -MF $(DEPDIR)/pcem-lpt.Tpo -c -o pcem-lpt.obj `if test -f 'lpt.c'; then $(CYGPATH_W) 'lpt.c'; else $(CYGPATH_W) '$(srcdir)/lpt.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-lpt.Tpo $(DEPDIR)/pcem-lpt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='lpt.c' object='pcem-lpt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-lpt.obj `if test -f 'lpt.c'; then $(CYGPATH_W) 'lpt.c'; else $(CYGPATH_W) '$(srcdir)/lpt.c'; fi` - -pcem-mcr.o: mcr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mcr.o -MD -MP -MF $(DEPDIR)/pcem-mcr.Tpo -c -o pcem-mcr.o `test -f 'mcr.c' || echo '$(srcdir)/'`mcr.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mcr.Tpo $(DEPDIR)/pcem-mcr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mcr.c' object='pcem-mcr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mcr.o `test -f 'mcr.c' || echo '$(srcdir)/'`mcr.c - -pcem-mcr.obj: mcr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mcr.obj -MD -MP -MF $(DEPDIR)/pcem-mcr.Tpo -c -o pcem-mcr.obj `if test -f 'mcr.c'; then $(CYGPATH_W) 'mcr.c'; else $(CYGPATH_W) '$(srcdir)/mcr.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mcr.Tpo $(DEPDIR)/pcem-mcr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mcr.c' object='pcem-mcr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mcr.obj `if test -f 'mcr.c'; then $(CYGPATH_W) 'mcr.c'; else $(CYGPATH_W) '$(srcdir)/mcr.c'; fi` - -pcem-mem.o: mem.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mem.o -MD -MP -MF $(DEPDIR)/pcem-mem.Tpo -c -o pcem-mem.o `test -f 'mem.c' || echo '$(srcdir)/'`mem.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mem.Tpo $(DEPDIR)/pcem-mem.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mem.c' object='pcem-mem.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mem.o `test -f 'mem.c' || echo '$(srcdir)/'`mem.c - -pcem-mem.obj: mem.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mem.obj -MD -MP -MF $(DEPDIR)/pcem-mem.Tpo -c -o pcem-mem.obj `if test -f 'mem.c'; then $(CYGPATH_W) 'mem.c'; else $(CYGPATH_W) '$(srcdir)/mem.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mem.Tpo $(DEPDIR)/pcem-mem.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mem.c' object='pcem-mem.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mem.obj `if test -f 'mem.c'; then $(CYGPATH_W) 'mem.c'; else $(CYGPATH_W) '$(srcdir)/mem.c'; fi` - -pcem-model.o: model.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-model.o -MD -MP -MF $(DEPDIR)/pcem-model.Tpo -c -o pcem-model.o `test -f 'model.c' || echo '$(srcdir)/'`model.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-model.Tpo $(DEPDIR)/pcem-model.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='model.c' object='pcem-model.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-model.o `test -f 'model.c' || echo '$(srcdir)/'`model.c - -pcem-model.obj: model.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-model.obj -MD -MP -MF $(DEPDIR)/pcem-model.Tpo -c -o pcem-model.obj `if test -f 'model.c'; then $(CYGPATH_W) 'model.c'; else $(CYGPATH_W) '$(srcdir)/model.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-model.Tpo $(DEPDIR)/pcem-model.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='model.c' object='pcem-model.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-model.obj `if test -f 'model.c'; then $(CYGPATH_W) 'model.c'; else $(CYGPATH_W) '$(srcdir)/model.c'; fi` - -pcem-mouse.o: mouse.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse.o -MD -MP -MF $(DEPDIR)/pcem-mouse.Tpo -c -o pcem-mouse.o `test -f 'mouse.c' || echo '$(srcdir)/'`mouse.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mouse.Tpo $(DEPDIR)/pcem-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mouse.c' object='pcem-mouse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse.o `test -f 'mouse.c' || echo '$(srcdir)/'`mouse.c - -pcem-mouse.obj: mouse.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse.obj -MD -MP -MF $(DEPDIR)/pcem-mouse.Tpo -c -o pcem-mouse.obj `if test -f 'mouse.c'; then $(CYGPATH_W) 'mouse.c'; else $(CYGPATH_W) '$(srcdir)/mouse.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mouse.Tpo $(DEPDIR)/pcem-mouse.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mouse.c' object='pcem-mouse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse.obj `if test -f 'mouse.c'; then $(CYGPATH_W) 'mouse.c'; else $(CYGPATH_W) '$(srcdir)/mouse.c'; fi` - -pcem-mouse_ps2.o: mouse_ps2.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse_ps2.o -MD -MP -MF $(DEPDIR)/pcem-mouse_ps2.Tpo -c -o pcem-mouse_ps2.o `test -f 'mouse_ps2.c' || echo '$(srcdir)/'`mouse_ps2.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mouse_ps2.Tpo $(DEPDIR)/pcem-mouse_ps2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mouse_ps2.c' object='pcem-mouse_ps2.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse_ps2.o `test -f 'mouse_ps2.c' || echo '$(srcdir)/'`mouse_ps2.c - -pcem-mouse_ps2.obj: mouse_ps2.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse_ps2.obj -MD -MP -MF $(DEPDIR)/pcem-mouse_ps2.Tpo -c -o pcem-mouse_ps2.obj `if test -f 'mouse_ps2.c'; then $(CYGPATH_W) 'mouse_ps2.c'; else $(CYGPATH_W) '$(srcdir)/mouse_ps2.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mouse_ps2.Tpo $(DEPDIR)/pcem-mouse_ps2.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mouse_ps2.c' object='pcem-mouse_ps2.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse_ps2.obj `if test -f 'mouse_ps2.c'; then $(CYGPATH_W) 'mouse_ps2.c'; else $(CYGPATH_W) '$(srcdir)/mouse_ps2.c'; fi` - -pcem-mouse_serial.o: mouse_serial.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse_serial.o -MD -MP -MF $(DEPDIR)/pcem-mouse_serial.Tpo -c -o pcem-mouse_serial.o `test -f 'mouse_serial.c' || echo '$(srcdir)/'`mouse_serial.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mouse_serial.Tpo $(DEPDIR)/pcem-mouse_serial.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mouse_serial.c' object='pcem-mouse_serial.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse_serial.o `test -f 'mouse_serial.c' || echo '$(srcdir)/'`mouse_serial.c - -pcem-mouse_serial.obj: mouse_serial.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-mouse_serial.obj -MD -MP -MF $(DEPDIR)/pcem-mouse_serial.Tpo -c -o pcem-mouse_serial.obj `if test -f 'mouse_serial.c'; then $(CYGPATH_W) 'mouse_serial.c'; else $(CYGPATH_W) '$(srcdir)/mouse_serial.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-mouse_serial.Tpo $(DEPDIR)/pcem-mouse_serial.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='mouse_serial.c' object='pcem-mouse_serial.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-mouse_serial.obj `if test -f 'mouse_serial.c'; then $(CYGPATH_W) 'mouse_serial.c'; else $(CYGPATH_W) '$(srcdir)/mouse_serial.c'; fi` - -pcem-neat.o: neat.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-neat.o -MD -MP -MF $(DEPDIR)/pcem-neat.Tpo -c -o pcem-neat.o `test -f 'neat.c' || echo '$(srcdir)/'`neat.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-neat.Tpo $(DEPDIR)/pcem-neat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='neat.c' object='pcem-neat.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-neat.o `test -f 'neat.c' || echo '$(srcdir)/'`neat.c - -pcem-neat.obj: neat.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-neat.obj -MD -MP -MF $(DEPDIR)/pcem-neat.Tpo -c -o pcem-neat.obj `if test -f 'neat.c'; then $(CYGPATH_W) 'neat.c'; else $(CYGPATH_W) '$(srcdir)/neat.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-neat.Tpo $(DEPDIR)/pcem-neat.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='neat.c' object='pcem-neat.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-neat.obj `if test -f 'neat.c'; then $(CYGPATH_W) 'neat.c'; else $(CYGPATH_W) '$(srcdir)/neat.c'; fi` - -pcem-nmi.o: nmi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nmi.o -MD -MP -MF $(DEPDIR)/pcem-nmi.Tpo -c -o pcem-nmi.o `test -f 'nmi.c' || echo '$(srcdir)/'`nmi.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-nmi.Tpo $(DEPDIR)/pcem-nmi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nmi.c' object='pcem-nmi.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nmi.o `test -f 'nmi.c' || echo '$(srcdir)/'`nmi.c - -pcem-nmi.obj: nmi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nmi.obj -MD -MP -MF $(DEPDIR)/pcem-nmi.Tpo -c -o pcem-nmi.obj `if test -f 'nmi.c'; then $(CYGPATH_W) 'nmi.c'; else $(CYGPATH_W) '$(srcdir)/nmi.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-nmi.Tpo $(DEPDIR)/pcem-nmi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nmi.c' object='pcem-nmi.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nmi.obj `if test -f 'nmi.c'; then $(CYGPATH_W) 'nmi.c'; else $(CYGPATH_W) '$(srcdir)/nmi.c'; fi` - -pcem-nvr.o: nvr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nvr.o -MD -MP -MF $(DEPDIR)/pcem-nvr.Tpo -c -o pcem-nvr.o `test -f 'nvr.c' || echo '$(srcdir)/'`nvr.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-nvr.Tpo $(DEPDIR)/pcem-nvr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nvr.c' object='pcem-nvr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nvr.o `test -f 'nvr.c' || echo '$(srcdir)/'`nvr.c - -pcem-nvr.obj: nvr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-nvr.obj -MD -MP -MF $(DEPDIR)/pcem-nvr.Tpo -c -o pcem-nvr.obj `if test -f 'nvr.c'; then $(CYGPATH_W) 'nvr.c'; else $(CYGPATH_W) '$(srcdir)/nvr.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-nvr.Tpo $(DEPDIR)/pcem-nvr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='nvr.c' object='pcem-nvr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-nvr.obj `if test -f 'nvr.c'; then $(CYGPATH_W) 'nvr.c'; else $(CYGPATH_W) '$(srcdir)/nvr.c'; fi` - -pcem-olivetti_m24.o: olivetti_m24.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-olivetti_m24.o -MD -MP -MF $(DEPDIR)/pcem-olivetti_m24.Tpo -c -o pcem-olivetti_m24.o `test -f 'olivetti_m24.c' || echo '$(srcdir)/'`olivetti_m24.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-olivetti_m24.Tpo $(DEPDIR)/pcem-olivetti_m24.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='olivetti_m24.c' object='pcem-olivetti_m24.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-olivetti_m24.o `test -f 'olivetti_m24.c' || echo '$(srcdir)/'`olivetti_m24.c - -pcem-olivetti_m24.obj: olivetti_m24.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-olivetti_m24.obj -MD -MP -MF $(DEPDIR)/pcem-olivetti_m24.Tpo -c -o pcem-olivetti_m24.obj `if test -f 'olivetti_m24.c'; then $(CYGPATH_W) 'olivetti_m24.c'; else $(CYGPATH_W) '$(srcdir)/olivetti_m24.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-olivetti_m24.Tpo $(DEPDIR)/pcem-olivetti_m24.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='olivetti_m24.c' object='pcem-olivetti_m24.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-olivetti_m24.obj `if test -f 'olivetti_m24.c'; then $(CYGPATH_W) 'olivetti_m24.c'; else $(CYGPATH_W) '$(srcdir)/olivetti_m24.c'; fi` - -pcem-opti.o: opti.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-opti.o -MD -MP -MF $(DEPDIR)/pcem-opti.Tpo -c -o pcem-opti.o `test -f 'opti.c' || echo '$(srcdir)/'`opti.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-opti.Tpo $(DEPDIR)/pcem-opti.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='opti.c' object='pcem-opti.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-opti.o `test -f 'opti.c' || echo '$(srcdir)/'`opti.c - -pcem-opti.obj: opti.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-opti.obj -MD -MP -MF $(DEPDIR)/pcem-opti.Tpo -c -o pcem-opti.obj `if test -f 'opti.c'; then $(CYGPATH_W) 'opti.c'; else $(CYGPATH_W) '$(srcdir)/opti.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-opti.Tpo $(DEPDIR)/pcem-opti.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='opti.c' object='pcem-opti.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-opti.obj `if test -f 'opti.c'; then $(CYGPATH_W) 'opti.c'; else $(CYGPATH_W) '$(srcdir)/opti.c'; fi` - -pcem-pc.o: pc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pc.o -MD -MP -MF $(DEPDIR)/pcem-pc.Tpo -c -o pcem-pc.o `test -f 'pc.c' || echo '$(srcdir)/'`pc.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pc.Tpo $(DEPDIR)/pcem-pc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pc.c' object='pcem-pc.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc.o `test -f 'pc.c' || echo '$(srcdir)/'`pc.c - -pcem-pc.obj: pc.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pc.obj -MD -MP -MF $(DEPDIR)/pcem-pc.Tpo -c -o pcem-pc.obj `if test -f 'pc.c'; then $(CYGPATH_W) 'pc.c'; else $(CYGPATH_W) '$(srcdir)/pc.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pc.Tpo $(DEPDIR)/pcem-pc.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pc.c' object='pcem-pc.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pc.obj `if test -f 'pc.c'; then $(CYGPATH_W) 'pc.c'; else $(CYGPATH_W) '$(srcdir)/pc.c'; fi` - -pcem-pci.o: pci.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pci.o -MD -MP -MF $(DEPDIR)/pcem-pci.Tpo -c -o pcem-pci.o `test -f 'pci.c' || echo '$(srcdir)/'`pci.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pci.Tpo $(DEPDIR)/pcem-pci.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pci.c' object='pcem-pci.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pci.o `test -f 'pci.c' || echo '$(srcdir)/'`pci.c - -pcem-pci.obj: pci.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pci.obj -MD -MP -MF $(DEPDIR)/pcem-pci.Tpo -c -o pcem-pci.obj `if test -f 'pci.c'; then $(CYGPATH_W) 'pci.c'; else $(CYGPATH_W) '$(srcdir)/pci.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pci.Tpo $(DEPDIR)/pcem-pci.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pci.c' object='pcem-pci.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pci.obj `if test -f 'pci.c'; then $(CYGPATH_W) 'pci.c'; else $(CYGPATH_W) '$(srcdir)/pci.c'; fi` - -pcem-pic.o: pic.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pic.o -MD -MP -MF $(DEPDIR)/pcem-pic.Tpo -c -o pcem-pic.o `test -f 'pic.c' || echo '$(srcdir)/'`pic.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pic.Tpo $(DEPDIR)/pcem-pic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pic.c' object='pcem-pic.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pic.o `test -f 'pic.c' || echo '$(srcdir)/'`pic.c - -pcem-pic.obj: pic.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pic.obj -MD -MP -MF $(DEPDIR)/pcem-pic.Tpo -c -o pcem-pic.obj `if test -f 'pic.c'; then $(CYGPATH_W) 'pic.c'; else $(CYGPATH_W) '$(srcdir)/pic.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pic.Tpo $(DEPDIR)/pcem-pic.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pic.c' object='pcem-pic.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pic.obj `if test -f 'pic.c'; then $(CYGPATH_W) 'pic.c'; else $(CYGPATH_W) '$(srcdir)/pic.c'; fi` - -pcem-piix.o: piix.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-piix.o -MD -MP -MF $(DEPDIR)/pcem-piix.Tpo -c -o pcem-piix.o `test -f 'piix.c' || echo '$(srcdir)/'`piix.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-piix.Tpo $(DEPDIR)/pcem-piix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='piix.c' object='pcem-piix.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-piix.o `test -f 'piix.c' || echo '$(srcdir)/'`piix.c - -pcem-piix.obj: piix.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-piix.obj -MD -MP -MF $(DEPDIR)/pcem-piix.Tpo -c -o pcem-piix.obj `if test -f 'piix.c'; then $(CYGPATH_W) 'piix.c'; else $(CYGPATH_W) '$(srcdir)/piix.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-piix.Tpo $(DEPDIR)/pcem-piix.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='piix.c' object='pcem-piix.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-piix.obj `if test -f 'piix.c'; then $(CYGPATH_W) 'piix.c'; else $(CYGPATH_W) '$(srcdir)/piix.c'; fi` - -pcem-pit.o: pit.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pit.o -MD -MP -MF $(DEPDIR)/pcem-pit.Tpo -c -o pcem-pit.o `test -f 'pit.c' || echo '$(srcdir)/'`pit.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pit.Tpo $(DEPDIR)/pcem-pit.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pit.c' object='pcem-pit.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pit.o `test -f 'pit.c' || echo '$(srcdir)/'`pit.c - -pcem-pit.obj: pit.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-pit.obj -MD -MP -MF $(DEPDIR)/pcem-pit.Tpo -c -o pcem-pit.obj `if test -f 'pit.c'; then $(CYGPATH_W) 'pit.c'; else $(CYGPATH_W) '$(srcdir)/pit.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-pit.Tpo $(DEPDIR)/pcem-pit.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pit.c' object='pcem-pit.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-pit.obj `if test -f 'pit.c'; then $(CYGPATH_W) 'pit.c'; else $(CYGPATH_W) '$(srcdir)/pit.c'; fi` - -pcem-ppi.o: ppi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ppi.o -MD -MP -MF $(DEPDIR)/pcem-ppi.Tpo -c -o pcem-ppi.o `test -f 'ppi.c' || echo '$(srcdir)/'`ppi.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ppi.Tpo $(DEPDIR)/pcem-ppi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ppi.c' object='pcem-ppi.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ppi.o `test -f 'ppi.c' || echo '$(srcdir)/'`ppi.c - -pcem-ppi.obj: ppi.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ppi.obj -MD -MP -MF $(DEPDIR)/pcem-ppi.Tpo -c -o pcem-ppi.obj `if test -f 'ppi.c'; then $(CYGPATH_W) 'ppi.c'; else $(CYGPATH_W) '$(srcdir)/ppi.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ppi.Tpo $(DEPDIR)/pcem-ppi.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ppi.c' object='pcem-ppi.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ppi.obj `if test -f 'ppi.c'; then $(CYGPATH_W) 'ppi.c'; else $(CYGPATH_W) '$(srcdir)/ppi.c'; fi` - -pcem-ps1.o: ps1.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ps1.o -MD -MP -MF $(DEPDIR)/pcem-ps1.Tpo -c -o pcem-ps1.o `test -f 'ps1.c' || echo '$(srcdir)/'`ps1.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ps1.Tpo $(DEPDIR)/pcem-ps1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ps1.c' object='pcem-ps1.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ps1.o `test -f 'ps1.c' || echo '$(srcdir)/'`ps1.c - -pcem-ps1.obj: ps1.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-ps1.obj -MD -MP -MF $(DEPDIR)/pcem-ps1.Tpo -c -o pcem-ps1.obj `if test -f 'ps1.c'; then $(CYGPATH_W) 'ps1.c'; else $(CYGPATH_W) '$(srcdir)/ps1.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-ps1.Tpo $(DEPDIR)/pcem-ps1.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ps1.c' object='pcem-ps1.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-ps1.obj `if test -f 'ps1.c'; then $(CYGPATH_W) 'ps1.c'; else $(CYGPATH_W) '$(srcdir)/ps1.c'; fi` - -pcem-rom.o: rom.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-rom.o -MD -MP -MF $(DEPDIR)/pcem-rom.Tpo -c -o pcem-rom.o `test -f 'rom.c' || echo '$(srcdir)/'`rom.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-rom.Tpo $(DEPDIR)/pcem-rom.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rom.c' object='pcem-rom.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-rom.o `test -f 'rom.c' || echo '$(srcdir)/'`rom.c - -pcem-rom.obj: rom.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-rom.obj -MD -MP -MF $(DEPDIR)/pcem-rom.Tpo -c -o pcem-rom.obj `if test -f 'rom.c'; then $(CYGPATH_W) 'rom.c'; else $(CYGPATH_W) '$(srcdir)/rom.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-rom.Tpo $(DEPDIR)/pcem-rom.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='rom.c' object='pcem-rom.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-rom.obj `if test -f 'rom.c'; then $(CYGPATH_W) 'rom.c'; else $(CYGPATH_W) '$(srcdir)/rom.c'; fi` - -pcem-serial.o: serial.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-serial.o -MD -MP -MF $(DEPDIR)/pcem-serial.Tpo -c -o pcem-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-serial.Tpo $(DEPDIR)/pcem-serial.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='serial.c' object='pcem-serial.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c - -pcem-serial.obj: serial.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-serial.obj -MD -MP -MF $(DEPDIR)/pcem-serial.Tpo -c -o pcem-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-serial.Tpo $(DEPDIR)/pcem-serial.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='serial.c' object='pcem-serial.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi` - -pcem-sis496.o: sis496.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sis496.o -MD -MP -MF $(DEPDIR)/pcem-sis496.Tpo -c -o pcem-sis496.o `test -f 'sis496.c' || echo '$(srcdir)/'`sis496.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sis496.Tpo $(DEPDIR)/pcem-sis496.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sis496.c' object='pcem-sis496.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sis496.o `test -f 'sis496.c' || echo '$(srcdir)/'`sis496.c - -pcem-sis496.obj: sis496.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sis496.obj -MD -MP -MF $(DEPDIR)/pcem-sis496.Tpo -c -o pcem-sis496.obj `if test -f 'sis496.c'; then $(CYGPATH_W) 'sis496.c'; else $(CYGPATH_W) '$(srcdir)/sis496.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sis496.Tpo $(DEPDIR)/pcem-sis496.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sis496.c' object='pcem-sis496.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sis496.obj `if test -f 'sis496.c'; then $(CYGPATH_W) 'sis496.c'; else $(CYGPATH_W) '$(srcdir)/sis496.c'; fi` - -pcem-sound.o: sound.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound.o -MD -MP -MF $(DEPDIR)/pcem-sound.Tpo -c -o pcem-sound.o `test -f 'sound.c' || echo '$(srcdir)/'`sound.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound.Tpo $(DEPDIR)/pcem-sound.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound.c' object='pcem-sound.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound.o `test -f 'sound.c' || echo '$(srcdir)/'`sound.c - -pcem-sound.obj: sound.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound.obj -MD -MP -MF $(DEPDIR)/pcem-sound.Tpo -c -o pcem-sound.obj `if test -f 'sound.c'; then $(CYGPATH_W) 'sound.c'; else $(CYGPATH_W) '$(srcdir)/sound.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound.Tpo $(DEPDIR)/pcem-sound.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound.c' object='pcem-sound.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound.obj `if test -f 'sound.c'; then $(CYGPATH_W) 'sound.c'; else $(CYGPATH_W) '$(srcdir)/sound.c'; fi` - -pcem-sound_ad1848.o: sound_ad1848.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_ad1848.o -MD -MP -MF $(DEPDIR)/pcem-sound_ad1848.Tpo -c -o pcem-sound_ad1848.o `test -f 'sound_ad1848.c' || echo '$(srcdir)/'`sound_ad1848.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_ad1848.Tpo $(DEPDIR)/pcem-sound_ad1848.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_ad1848.c' object='pcem-sound_ad1848.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_ad1848.o `test -f 'sound_ad1848.c' || echo '$(srcdir)/'`sound_ad1848.c - -pcem-sound_ad1848.obj: sound_ad1848.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_ad1848.obj -MD -MP -MF $(DEPDIR)/pcem-sound_ad1848.Tpo -c -o pcem-sound_ad1848.obj `if test -f 'sound_ad1848.c'; then $(CYGPATH_W) 'sound_ad1848.c'; else $(CYGPATH_W) '$(srcdir)/sound_ad1848.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_ad1848.Tpo $(DEPDIR)/pcem-sound_ad1848.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_ad1848.c' object='pcem-sound_ad1848.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_ad1848.obj `if test -f 'sound_ad1848.c'; then $(CYGPATH_W) 'sound_ad1848.c'; else $(CYGPATH_W) '$(srcdir)/sound_ad1848.c'; fi` - -pcem-sound_adlib.o: sound_adlib.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_adlib.o -MD -MP -MF $(DEPDIR)/pcem-sound_adlib.Tpo -c -o pcem-sound_adlib.o `test -f 'sound_adlib.c' || echo '$(srcdir)/'`sound_adlib.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_adlib.Tpo $(DEPDIR)/pcem-sound_adlib.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_adlib.c' object='pcem-sound_adlib.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_adlib.o `test -f 'sound_adlib.c' || echo '$(srcdir)/'`sound_adlib.c - -pcem-sound_adlib.obj: sound_adlib.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_adlib.obj -MD -MP -MF $(DEPDIR)/pcem-sound_adlib.Tpo -c -o pcem-sound_adlib.obj `if test -f 'sound_adlib.c'; then $(CYGPATH_W) 'sound_adlib.c'; else $(CYGPATH_W) '$(srcdir)/sound_adlib.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_adlib.Tpo $(DEPDIR)/pcem-sound_adlib.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_adlib.c' object='pcem-sound_adlib.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_adlib.obj `if test -f 'sound_adlib.c'; then $(CYGPATH_W) 'sound_adlib.c'; else $(CYGPATH_W) '$(srcdir)/sound_adlib.c'; fi` - -pcem-sound_adlibgold.o: sound_adlibgold.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_adlibgold.o -MD -MP -MF $(DEPDIR)/pcem-sound_adlibgold.Tpo -c -o pcem-sound_adlibgold.o `test -f 'sound_adlibgold.c' || echo '$(srcdir)/'`sound_adlibgold.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_adlibgold.Tpo $(DEPDIR)/pcem-sound_adlibgold.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_adlibgold.c' object='pcem-sound_adlibgold.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_adlibgold.o `test -f 'sound_adlibgold.c' || echo '$(srcdir)/'`sound_adlibgold.c - -pcem-sound_adlibgold.obj: sound_adlibgold.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_adlibgold.obj -MD -MP -MF $(DEPDIR)/pcem-sound_adlibgold.Tpo -c -o pcem-sound_adlibgold.obj `if test -f 'sound_adlibgold.c'; then $(CYGPATH_W) 'sound_adlibgold.c'; else $(CYGPATH_W) '$(srcdir)/sound_adlibgold.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_adlibgold.Tpo $(DEPDIR)/pcem-sound_adlibgold.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_adlibgold.c' object='pcem-sound_adlibgold.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_adlibgold.obj `if test -f 'sound_adlibgold.c'; then $(CYGPATH_W) 'sound_adlibgold.c'; else $(CYGPATH_W) '$(srcdir)/sound_adlibgold.c'; fi` - -pcem-sound_cms.o: sound_cms.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_cms.o -MD -MP -MF $(DEPDIR)/pcem-sound_cms.Tpo -c -o pcem-sound_cms.o `test -f 'sound_cms.c' || echo '$(srcdir)/'`sound_cms.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_cms.Tpo $(DEPDIR)/pcem-sound_cms.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_cms.c' object='pcem-sound_cms.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_cms.o `test -f 'sound_cms.c' || echo '$(srcdir)/'`sound_cms.c - -pcem-sound_cms.obj: sound_cms.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_cms.obj -MD -MP -MF $(DEPDIR)/pcem-sound_cms.Tpo -c -o pcem-sound_cms.obj `if test -f 'sound_cms.c'; then $(CYGPATH_W) 'sound_cms.c'; else $(CYGPATH_W) '$(srcdir)/sound_cms.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_cms.Tpo $(DEPDIR)/pcem-sound_cms.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_cms.c' object='pcem-sound_cms.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_cms.obj `if test -f 'sound_cms.c'; then $(CYGPATH_W) 'sound_cms.c'; else $(CYGPATH_W) '$(srcdir)/sound_cms.c'; fi` - -pcem-sound_emu8k.o: sound_emu8k.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_emu8k.o -MD -MP -MF $(DEPDIR)/pcem-sound_emu8k.Tpo -c -o pcem-sound_emu8k.o `test -f 'sound_emu8k.c' || echo '$(srcdir)/'`sound_emu8k.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_emu8k.Tpo $(DEPDIR)/pcem-sound_emu8k.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_emu8k.c' object='pcem-sound_emu8k.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_emu8k.o `test -f 'sound_emu8k.c' || echo '$(srcdir)/'`sound_emu8k.c - -pcem-sound_emu8k.obj: sound_emu8k.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_emu8k.obj -MD -MP -MF $(DEPDIR)/pcem-sound_emu8k.Tpo -c -o pcem-sound_emu8k.obj `if test -f 'sound_emu8k.c'; then $(CYGPATH_W) 'sound_emu8k.c'; else $(CYGPATH_W) '$(srcdir)/sound_emu8k.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_emu8k.Tpo $(DEPDIR)/pcem-sound_emu8k.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_emu8k.c' object='pcem-sound_emu8k.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_emu8k.obj `if test -f 'sound_emu8k.c'; then $(CYGPATH_W) 'sound_emu8k.c'; else $(CYGPATH_W) '$(srcdir)/sound_emu8k.c'; fi` - -pcem-sound_gus.o: sound_gus.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_gus.o -MD -MP -MF $(DEPDIR)/pcem-sound_gus.Tpo -c -o pcem-sound_gus.o `test -f 'sound_gus.c' || echo '$(srcdir)/'`sound_gus.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_gus.Tpo $(DEPDIR)/pcem-sound_gus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_gus.c' object='pcem-sound_gus.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_gus.o `test -f 'sound_gus.c' || echo '$(srcdir)/'`sound_gus.c - -pcem-sound_gus.obj: sound_gus.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_gus.obj -MD -MP -MF $(DEPDIR)/pcem-sound_gus.Tpo -c -o pcem-sound_gus.obj `if test -f 'sound_gus.c'; then $(CYGPATH_W) 'sound_gus.c'; else $(CYGPATH_W) '$(srcdir)/sound_gus.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_gus.Tpo $(DEPDIR)/pcem-sound_gus.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_gus.c' object='pcem-sound_gus.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_gus.obj `if test -f 'sound_gus.c'; then $(CYGPATH_W) 'sound_gus.c'; else $(CYGPATH_W) '$(srcdir)/sound_gus.c'; fi` - -pcem-sound_mpu401_uart.o: sound_mpu401_uart.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_mpu401_uart.o -MD -MP -MF $(DEPDIR)/pcem-sound_mpu401_uart.Tpo -c -o pcem-sound_mpu401_uart.o `test -f 'sound_mpu401_uart.c' || echo '$(srcdir)/'`sound_mpu401_uart.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_mpu401_uart.Tpo $(DEPDIR)/pcem-sound_mpu401_uart.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_mpu401_uart.c' object='pcem-sound_mpu401_uart.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_mpu401_uart.o `test -f 'sound_mpu401_uart.c' || echo '$(srcdir)/'`sound_mpu401_uart.c - -pcem-sound_mpu401_uart.obj: sound_mpu401_uart.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_mpu401_uart.obj -MD -MP -MF $(DEPDIR)/pcem-sound_mpu401_uart.Tpo -c -o pcem-sound_mpu401_uart.obj `if test -f 'sound_mpu401_uart.c'; then $(CYGPATH_W) 'sound_mpu401_uart.c'; else $(CYGPATH_W) '$(srcdir)/sound_mpu401_uart.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_mpu401_uart.Tpo $(DEPDIR)/pcem-sound_mpu401_uart.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_mpu401_uart.c' object='pcem-sound_mpu401_uart.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_mpu401_uart.obj `if test -f 'sound_mpu401_uart.c'; then $(CYGPATH_W) 'sound_mpu401_uart.c'; else $(CYGPATH_W) '$(srcdir)/sound_mpu401_uart.c'; fi` - -pcem-sound_opl.o: sound_opl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_opl.o -MD -MP -MF $(DEPDIR)/pcem-sound_opl.Tpo -c -o pcem-sound_opl.o `test -f 'sound_opl.c' || echo '$(srcdir)/'`sound_opl.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_opl.Tpo $(DEPDIR)/pcem-sound_opl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_opl.c' object='pcem-sound_opl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_opl.o `test -f 'sound_opl.c' || echo '$(srcdir)/'`sound_opl.c - -pcem-sound_opl.obj: sound_opl.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_opl.obj -MD -MP -MF $(DEPDIR)/pcem-sound_opl.Tpo -c -o pcem-sound_opl.obj `if test -f 'sound_opl.c'; then $(CYGPATH_W) 'sound_opl.c'; else $(CYGPATH_W) '$(srcdir)/sound_opl.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_opl.Tpo $(DEPDIR)/pcem-sound_opl.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_opl.c' object='pcem-sound_opl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_opl.obj `if test -f 'sound_opl.c'; then $(CYGPATH_W) 'sound_opl.c'; else $(CYGPATH_W) '$(srcdir)/sound_opl.c'; fi` - -pcem-sound_pas16.o: sound_pas16.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_pas16.o -MD -MP -MF $(DEPDIR)/pcem-sound_pas16.Tpo -c -o pcem-sound_pas16.o `test -f 'sound_pas16.c' || echo '$(srcdir)/'`sound_pas16.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_pas16.Tpo $(DEPDIR)/pcem-sound_pas16.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_pas16.c' object='pcem-sound_pas16.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_pas16.o `test -f 'sound_pas16.c' || echo '$(srcdir)/'`sound_pas16.c - -pcem-sound_pas16.obj: sound_pas16.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_pas16.obj -MD -MP -MF $(DEPDIR)/pcem-sound_pas16.Tpo -c -o pcem-sound_pas16.obj `if test -f 'sound_pas16.c'; then $(CYGPATH_W) 'sound_pas16.c'; else $(CYGPATH_W) '$(srcdir)/sound_pas16.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_pas16.Tpo $(DEPDIR)/pcem-sound_pas16.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_pas16.c' object='pcem-sound_pas16.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_pas16.obj `if test -f 'sound_pas16.c'; then $(CYGPATH_W) 'sound_pas16.c'; else $(CYGPATH_W) '$(srcdir)/sound_pas16.c'; fi` - -pcem-sound_sb.o: sound_sb.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_sb.o -MD -MP -MF $(DEPDIR)/pcem-sound_sb.Tpo -c -o pcem-sound_sb.o `test -f 'sound_sb.c' || echo '$(srcdir)/'`sound_sb.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_sb.Tpo $(DEPDIR)/pcem-sound_sb.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_sb.c' object='pcem-sound_sb.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_sb.o `test -f 'sound_sb.c' || echo '$(srcdir)/'`sound_sb.c - -pcem-sound_sb.obj: sound_sb.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_sb.obj -MD -MP -MF $(DEPDIR)/pcem-sound_sb.Tpo -c -o pcem-sound_sb.obj `if test -f 'sound_sb.c'; then $(CYGPATH_W) 'sound_sb.c'; else $(CYGPATH_W) '$(srcdir)/sound_sb.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_sb.Tpo $(DEPDIR)/pcem-sound_sb.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_sb.c' object='pcem-sound_sb.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_sb.obj `if test -f 'sound_sb.c'; then $(CYGPATH_W) 'sound_sb.c'; else $(CYGPATH_W) '$(srcdir)/sound_sb.c'; fi` - -pcem-sound_sb_dsp.o: sound_sb_dsp.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_sb_dsp.o -MD -MP -MF $(DEPDIR)/pcem-sound_sb_dsp.Tpo -c -o pcem-sound_sb_dsp.o `test -f 'sound_sb_dsp.c' || echo '$(srcdir)/'`sound_sb_dsp.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_sb_dsp.Tpo $(DEPDIR)/pcem-sound_sb_dsp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_sb_dsp.c' object='pcem-sound_sb_dsp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_sb_dsp.o `test -f 'sound_sb_dsp.c' || echo '$(srcdir)/'`sound_sb_dsp.c - -pcem-sound_sb_dsp.obj: sound_sb_dsp.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_sb_dsp.obj -MD -MP -MF $(DEPDIR)/pcem-sound_sb_dsp.Tpo -c -o pcem-sound_sb_dsp.obj `if test -f 'sound_sb_dsp.c'; then $(CYGPATH_W) 'sound_sb_dsp.c'; else $(CYGPATH_W) '$(srcdir)/sound_sb_dsp.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_sb_dsp.Tpo $(DEPDIR)/pcem-sound_sb_dsp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_sb_dsp.c' object='pcem-sound_sb_dsp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_sb_dsp.obj `if test -f 'sound_sb_dsp.c'; then $(CYGPATH_W) 'sound_sb_dsp.c'; else $(CYGPATH_W) '$(srcdir)/sound_sb_dsp.c'; fi` - -pcem-sound_sn76489.o: sound_sn76489.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_sn76489.o -MD -MP -MF $(DEPDIR)/pcem-sound_sn76489.Tpo -c -o pcem-sound_sn76489.o `test -f 'sound_sn76489.c' || echo '$(srcdir)/'`sound_sn76489.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_sn76489.Tpo $(DEPDIR)/pcem-sound_sn76489.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_sn76489.c' object='pcem-sound_sn76489.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_sn76489.o `test -f 'sound_sn76489.c' || echo '$(srcdir)/'`sound_sn76489.c - -pcem-sound_sn76489.obj: sound_sn76489.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_sn76489.obj -MD -MP -MF $(DEPDIR)/pcem-sound_sn76489.Tpo -c -o pcem-sound_sn76489.obj `if test -f 'sound_sn76489.c'; then $(CYGPATH_W) 'sound_sn76489.c'; else $(CYGPATH_W) '$(srcdir)/sound_sn76489.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_sn76489.Tpo $(DEPDIR)/pcem-sound_sn76489.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_sn76489.c' object='pcem-sound_sn76489.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_sn76489.obj `if test -f 'sound_sn76489.c'; then $(CYGPATH_W) 'sound_sn76489.c'; else $(CYGPATH_W) '$(srcdir)/sound_sn76489.c'; fi` - -pcem-sound_speaker.o: sound_speaker.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_speaker.o -MD -MP -MF $(DEPDIR)/pcem-sound_speaker.Tpo -c -o pcem-sound_speaker.o `test -f 'sound_speaker.c' || echo '$(srcdir)/'`sound_speaker.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_speaker.Tpo $(DEPDIR)/pcem-sound_speaker.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_speaker.c' object='pcem-sound_speaker.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_speaker.o `test -f 'sound_speaker.c' || echo '$(srcdir)/'`sound_speaker.c - -pcem-sound_speaker.obj: sound_speaker.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_speaker.obj -MD -MP -MF $(DEPDIR)/pcem-sound_speaker.Tpo -c -o pcem-sound_speaker.obj `if test -f 'sound_speaker.c'; then $(CYGPATH_W) 'sound_speaker.c'; else $(CYGPATH_W) '$(srcdir)/sound_speaker.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_speaker.Tpo $(DEPDIR)/pcem-sound_speaker.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_speaker.c' object='pcem-sound_speaker.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_speaker.obj `if test -f 'sound_speaker.c'; then $(CYGPATH_W) 'sound_speaker.c'; else $(CYGPATH_W) '$(srcdir)/sound_speaker.c'; fi` - -pcem-sound_ssi2001.o: sound_ssi2001.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_ssi2001.o -MD -MP -MF $(DEPDIR)/pcem-sound_ssi2001.Tpo -c -o pcem-sound_ssi2001.o `test -f 'sound_ssi2001.c' || echo '$(srcdir)/'`sound_ssi2001.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_ssi2001.Tpo $(DEPDIR)/pcem-sound_ssi2001.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_ssi2001.c' object='pcem-sound_ssi2001.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_ssi2001.o `test -f 'sound_ssi2001.c' || echo '$(srcdir)/'`sound_ssi2001.c - -pcem-sound_ssi2001.obj: sound_ssi2001.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_ssi2001.obj -MD -MP -MF $(DEPDIR)/pcem-sound_ssi2001.Tpo -c -o pcem-sound_ssi2001.obj `if test -f 'sound_ssi2001.c'; then $(CYGPATH_W) 'sound_ssi2001.c'; else $(CYGPATH_W) '$(srcdir)/sound_ssi2001.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_ssi2001.Tpo $(DEPDIR)/pcem-sound_ssi2001.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_ssi2001.c' object='pcem-sound_ssi2001.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_ssi2001.obj `if test -f 'sound_ssi2001.c'; then $(CYGPATH_W) 'sound_ssi2001.c'; else $(CYGPATH_W) '$(srcdir)/sound_ssi2001.c'; fi` - -pcem-sound_wss.o: sound_wss.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_wss.o -MD -MP -MF $(DEPDIR)/pcem-sound_wss.Tpo -c -o pcem-sound_wss.o `test -f 'sound_wss.c' || echo '$(srcdir)/'`sound_wss.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_wss.Tpo $(DEPDIR)/pcem-sound_wss.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_wss.c' object='pcem-sound_wss.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_wss.o `test -f 'sound_wss.c' || echo '$(srcdir)/'`sound_wss.c - -pcem-sound_wss.obj: sound_wss.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-sound_wss.obj -MD -MP -MF $(DEPDIR)/pcem-sound_wss.Tpo -c -o pcem-sound_wss.obj `if test -f 'sound_wss.c'; then $(CYGPATH_W) 'sound_wss.c'; else $(CYGPATH_W) '$(srcdir)/sound_wss.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-sound_wss.Tpo $(DEPDIR)/pcem-sound_wss.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sound_wss.c' object='pcem-sound_wss.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-sound_wss.obj `if test -f 'sound_wss.c'; then $(CYGPATH_W) 'sound_wss.c'; else $(CYGPATH_W) '$(srcdir)/sound_wss.c'; fi` - -pcem-soundopenal.o: soundopenal.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-soundopenal.o -MD -MP -MF $(DEPDIR)/pcem-soundopenal.Tpo -c -o pcem-soundopenal.o `test -f 'soundopenal.c' || echo '$(srcdir)/'`soundopenal.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-soundopenal.Tpo $(DEPDIR)/pcem-soundopenal.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='soundopenal.c' object='pcem-soundopenal.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-soundopenal.o `test -f 'soundopenal.c' || echo '$(srcdir)/'`soundopenal.c - -pcem-soundopenal.obj: soundopenal.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-soundopenal.obj -MD -MP -MF $(DEPDIR)/pcem-soundopenal.Tpo -c -o pcem-soundopenal.obj `if test -f 'soundopenal.c'; then $(CYGPATH_W) 'soundopenal.c'; else $(CYGPATH_W) '$(srcdir)/soundopenal.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-soundopenal.Tpo $(DEPDIR)/pcem-soundopenal.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='soundopenal.c' object='pcem-soundopenal.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-soundopenal.obj `if test -f 'soundopenal.c'; then $(CYGPATH_W) 'soundopenal.c'; else $(CYGPATH_W) '$(srcdir)/soundopenal.c'; fi` - -pcem-thread-pthread.o: thread-pthread.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-thread-pthread.o -MD -MP -MF $(DEPDIR)/pcem-thread-pthread.Tpo -c -o pcem-thread-pthread.o `test -f 'thread-pthread.c' || echo '$(srcdir)/'`thread-pthread.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread-pthread.c' object='pcem-thread-pthread.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-thread-pthread.o `test -f 'thread-pthread.c' || echo '$(srcdir)/'`thread-pthread.c - -pcem-thread-pthread.obj: thread-pthread.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-thread-pthread.obj -MD -MP -MF $(DEPDIR)/pcem-thread-pthread.Tpo -c -o pcem-thread-pthread.obj `if test -f 'thread-pthread.c'; then $(CYGPATH_W) 'thread-pthread.c'; else $(CYGPATH_W) '$(srcdir)/thread-pthread.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-thread-pthread.Tpo $(DEPDIR)/pcem-thread-pthread.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='thread-pthread.c' object='pcem-thread-pthread.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-thread-pthread.obj `if test -f 'thread-pthread.c'; then $(CYGPATH_W) 'thread-pthread.c'; else $(CYGPATH_W) '$(srcdir)/thread-pthread.c'; fi` - -pcem-timer.o: timer.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-timer.o -MD -MP -MF $(DEPDIR)/pcem-timer.Tpo -c -o pcem-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-timer.Tpo $(DEPDIR)/pcem-timer.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timer.c' object='pcem-timer.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c - -pcem-timer.obj: timer.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-timer.obj -MD -MP -MF $(DEPDIR)/pcem-timer.Tpo -c -o pcem-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-timer.Tpo $(DEPDIR)/pcem-timer.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='timer.c' object='pcem-timer.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi` - -pcem-um8669f.o: um8669f.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-um8669f.o -MD -MP -MF $(DEPDIR)/pcem-um8669f.Tpo -c -o pcem-um8669f.o `test -f 'um8669f.c' || echo '$(srcdir)/'`um8669f.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-um8669f.Tpo $(DEPDIR)/pcem-um8669f.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='um8669f.c' object='pcem-um8669f.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-um8669f.o `test -f 'um8669f.c' || echo '$(srcdir)/'`um8669f.c - -pcem-um8669f.obj: um8669f.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-um8669f.obj -MD -MP -MF $(DEPDIR)/pcem-um8669f.Tpo -c -o pcem-um8669f.obj `if test -f 'um8669f.c'; then $(CYGPATH_W) 'um8669f.c'; else $(CYGPATH_W) '$(srcdir)/um8669f.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-um8669f.Tpo $(DEPDIR)/pcem-um8669f.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='um8669f.c' object='pcem-um8669f.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-um8669f.obj `if test -f 'um8669f.c'; then $(CYGPATH_W) 'um8669f.c'; else $(CYGPATH_W) '$(srcdir)/um8669f.c'; fi` - -pcem-um8881f.o: um8881f.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-um8881f.o -MD -MP -MF $(DEPDIR)/pcem-um8881f.Tpo -c -o pcem-um8881f.o `test -f 'um8881f.c' || echo '$(srcdir)/'`um8881f.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-um8881f.Tpo $(DEPDIR)/pcem-um8881f.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='um8881f.c' object='pcem-um8881f.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-um8881f.o `test -f 'um8881f.c' || echo '$(srcdir)/'`um8881f.c - -pcem-um8881f.obj: um8881f.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-um8881f.obj -MD -MP -MF $(DEPDIR)/pcem-um8881f.Tpo -c -o pcem-um8881f.obj `if test -f 'um8881f.c'; then $(CYGPATH_W) 'um8881f.c'; else $(CYGPATH_W) '$(srcdir)/um8881f.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-um8881f.Tpo $(DEPDIR)/pcem-um8881f.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='um8881f.c' object='pcem-um8881f.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-um8881f.obj `if test -f 'um8881f.c'; then $(CYGPATH_W) 'um8881f.c'; else $(CYGPATH_W) '$(srcdir)/um8881f.c'; fi` - -pcem-vid_ati_eeprom.o: vid_ati_eeprom.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati_eeprom.o -MD -MP -MF $(DEPDIR)/pcem-vid_ati_eeprom.Tpo -c -o pcem-vid_ati_eeprom.o `test -f 'vid_ati_eeprom.c' || echo '$(srcdir)/'`vid_ati_eeprom.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati_eeprom.Tpo $(DEPDIR)/pcem-vid_ati_eeprom.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati_eeprom.c' object='pcem-vid_ati_eeprom.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati_eeprom.o `test -f 'vid_ati_eeprom.c' || echo '$(srcdir)/'`vid_ati_eeprom.c - -pcem-vid_ati_eeprom.obj: vid_ati_eeprom.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati_eeprom.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ati_eeprom.Tpo -c -o pcem-vid_ati_eeprom.obj `if test -f 'vid_ati_eeprom.c'; then $(CYGPATH_W) 'vid_ati_eeprom.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati_eeprom.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati_eeprom.Tpo $(DEPDIR)/pcem-vid_ati_eeprom.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati_eeprom.c' object='pcem-vid_ati_eeprom.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati_eeprom.obj `if test -f 'vid_ati_eeprom.c'; then $(CYGPATH_W) 'vid_ati_eeprom.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati_eeprom.c'; fi` - -pcem-vid_ati_mach64.o: vid_ati_mach64.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati_mach64.o -MD -MP -MF $(DEPDIR)/pcem-vid_ati_mach64.Tpo -c -o pcem-vid_ati_mach64.o `test -f 'vid_ati_mach64.c' || echo '$(srcdir)/'`vid_ati_mach64.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati_mach64.Tpo $(DEPDIR)/pcem-vid_ati_mach64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati_mach64.c' object='pcem-vid_ati_mach64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati_mach64.o `test -f 'vid_ati_mach64.c' || echo '$(srcdir)/'`vid_ati_mach64.c - -pcem-vid_ati_mach64.obj: vid_ati_mach64.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati_mach64.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ati_mach64.Tpo -c -o pcem-vid_ati_mach64.obj `if test -f 'vid_ati_mach64.c'; then $(CYGPATH_W) 'vid_ati_mach64.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati_mach64.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati_mach64.Tpo $(DEPDIR)/pcem-vid_ati_mach64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati_mach64.c' object='pcem-vid_ati_mach64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati_mach64.obj `if test -f 'vid_ati_mach64.c'; then $(CYGPATH_W) 'vid_ati_mach64.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati_mach64.c'; fi` - -pcem-vid_ati18800.o: vid_ati18800.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati18800.o -MD -MP -MF $(DEPDIR)/pcem-vid_ati18800.Tpo -c -o pcem-vid_ati18800.o `test -f 'vid_ati18800.c' || echo '$(srcdir)/'`vid_ati18800.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati18800.Tpo $(DEPDIR)/pcem-vid_ati18800.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati18800.c' object='pcem-vid_ati18800.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati18800.o `test -f 'vid_ati18800.c' || echo '$(srcdir)/'`vid_ati18800.c - -pcem-vid_ati18800.obj: vid_ati18800.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati18800.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ati18800.Tpo -c -o pcem-vid_ati18800.obj `if test -f 'vid_ati18800.c'; then $(CYGPATH_W) 'vid_ati18800.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati18800.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati18800.Tpo $(DEPDIR)/pcem-vid_ati18800.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati18800.c' object='pcem-vid_ati18800.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati18800.obj `if test -f 'vid_ati18800.c'; then $(CYGPATH_W) 'vid_ati18800.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati18800.c'; fi` - -pcem-vid_ati28800.o: vid_ati28800.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati28800.o -MD -MP -MF $(DEPDIR)/pcem-vid_ati28800.Tpo -c -o pcem-vid_ati28800.o `test -f 'vid_ati28800.c' || echo '$(srcdir)/'`vid_ati28800.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati28800.Tpo $(DEPDIR)/pcem-vid_ati28800.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati28800.c' object='pcem-vid_ati28800.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati28800.o `test -f 'vid_ati28800.c' || echo '$(srcdir)/'`vid_ati28800.c - -pcem-vid_ati28800.obj: vid_ati28800.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati28800.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ati28800.Tpo -c -o pcem-vid_ati28800.obj `if test -f 'vid_ati28800.c'; then $(CYGPATH_W) 'vid_ati28800.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati28800.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati28800.Tpo $(DEPDIR)/pcem-vid_ati28800.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati28800.c' object='pcem-vid_ati28800.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati28800.obj `if test -f 'vid_ati28800.c'; then $(CYGPATH_W) 'vid_ati28800.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati28800.c'; fi` - -pcem-vid_ati68860_ramdac.o: vid_ati68860_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati68860_ramdac.o -MD -MP -MF $(DEPDIR)/pcem-vid_ati68860_ramdac.Tpo -c -o pcem-vid_ati68860_ramdac.o `test -f 'vid_ati68860_ramdac.c' || echo '$(srcdir)/'`vid_ati68860_ramdac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati68860_ramdac.Tpo $(DEPDIR)/pcem-vid_ati68860_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati68860_ramdac.c' object='pcem-vid_ati68860_ramdac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati68860_ramdac.o `test -f 'vid_ati68860_ramdac.c' || echo '$(srcdir)/'`vid_ati68860_ramdac.c - -pcem-vid_ati68860_ramdac.obj: vid_ati68860_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ati68860_ramdac.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ati68860_ramdac.Tpo -c -o pcem-vid_ati68860_ramdac.obj `if test -f 'vid_ati68860_ramdac.c'; then $(CYGPATH_W) 'vid_ati68860_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati68860_ramdac.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ati68860_ramdac.Tpo $(DEPDIR)/pcem-vid_ati68860_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ati68860_ramdac.c' object='pcem-vid_ati68860_ramdac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ati68860_ramdac.obj `if test -f 'vid_ati68860_ramdac.c'; then $(CYGPATH_W) 'vid_ati68860_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_ati68860_ramdac.c'; fi` - -pcem-vid_cga.o: vid_cga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_cga.o -MD -MP -MF $(DEPDIR)/pcem-vid_cga.Tpo -c -o pcem-vid_cga.o `test -f 'vid_cga.c' || echo '$(srcdir)/'`vid_cga.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_cga.Tpo $(DEPDIR)/pcem-vid_cga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_cga.c' object='pcem-vid_cga.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cga.o `test -f 'vid_cga.c' || echo '$(srcdir)/'`vid_cga.c - -pcem-vid_cga.obj: vid_cga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_cga.obj -MD -MP -MF $(DEPDIR)/pcem-vid_cga.Tpo -c -o pcem-vid_cga.obj `if test -f 'vid_cga.c'; then $(CYGPATH_W) 'vid_cga.c'; else $(CYGPATH_W) '$(srcdir)/vid_cga.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_cga.Tpo $(DEPDIR)/pcem-vid_cga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_cga.c' object='pcem-vid_cga.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cga.obj `if test -f 'vid_cga.c'; then $(CYGPATH_W) 'vid_cga.c'; else $(CYGPATH_W) '$(srcdir)/vid_cga.c'; fi` - -pcem-vid_cl5429.o: vid_cl5429.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_cl5429.o -MD -MP -MF $(DEPDIR)/pcem-vid_cl5429.Tpo -c -o pcem-vid_cl5429.o `test -f 'vid_cl5429.c' || echo '$(srcdir)/'`vid_cl5429.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_cl5429.Tpo $(DEPDIR)/pcem-vid_cl5429.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_cl5429.c' object='pcem-vid_cl5429.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cl5429.o `test -f 'vid_cl5429.c' || echo '$(srcdir)/'`vid_cl5429.c - -pcem-vid_cl5429.obj: vid_cl5429.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_cl5429.obj -MD -MP -MF $(DEPDIR)/pcem-vid_cl5429.Tpo -c -o pcem-vid_cl5429.obj `if test -f 'vid_cl5429.c'; then $(CYGPATH_W) 'vid_cl5429.c'; else $(CYGPATH_W) '$(srcdir)/vid_cl5429.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_cl5429.Tpo $(DEPDIR)/pcem-vid_cl5429.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_cl5429.c' object='pcem-vid_cl5429.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_cl5429.obj `if test -f 'vid_cl5429.c'; then $(CYGPATH_W) 'vid_cl5429.c'; else $(CYGPATH_W) '$(srcdir)/vid_cl5429.c'; fi` - -pcem-vid_ega.o: vid_ega.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ega.o -MD -MP -MF $(DEPDIR)/pcem-vid_ega.Tpo -c -o pcem-vid_ega.o `test -f 'vid_ega.c' || echo '$(srcdir)/'`vid_ega.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ega.Tpo $(DEPDIR)/pcem-vid_ega.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ega.c' object='pcem-vid_ega.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ega.o `test -f 'vid_ega.c' || echo '$(srcdir)/'`vid_ega.c - -pcem-vid_ega.obj: vid_ega.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ega.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ega.Tpo -c -o pcem-vid_ega.obj `if test -f 'vid_ega.c'; then $(CYGPATH_W) 'vid_ega.c'; else $(CYGPATH_W) '$(srcdir)/vid_ega.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ega.Tpo $(DEPDIR)/pcem-vid_ega.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ega.c' object='pcem-vid_ega.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ega.obj `if test -f 'vid_ega.c'; then $(CYGPATH_W) 'vid_ega.c'; else $(CYGPATH_W) '$(srcdir)/vid_ega.c'; fi` - -pcem-vid_et4000.o: vid_et4000.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_et4000.o -MD -MP -MF $(DEPDIR)/pcem-vid_et4000.Tpo -c -o pcem-vid_et4000.o `test -f 'vid_et4000.c' || echo '$(srcdir)/'`vid_et4000.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_et4000.Tpo $(DEPDIR)/pcem-vid_et4000.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_et4000.c' object='pcem-vid_et4000.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_et4000.o `test -f 'vid_et4000.c' || echo '$(srcdir)/'`vid_et4000.c - -pcem-vid_et4000.obj: vid_et4000.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_et4000.obj -MD -MP -MF $(DEPDIR)/pcem-vid_et4000.Tpo -c -o pcem-vid_et4000.obj `if test -f 'vid_et4000.c'; then $(CYGPATH_W) 'vid_et4000.c'; else $(CYGPATH_W) '$(srcdir)/vid_et4000.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_et4000.Tpo $(DEPDIR)/pcem-vid_et4000.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_et4000.c' object='pcem-vid_et4000.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_et4000.obj `if test -f 'vid_et4000.c'; then $(CYGPATH_W) 'vid_et4000.c'; else $(CYGPATH_W) '$(srcdir)/vid_et4000.c'; fi` - -pcem-vid_et4000w32.o: vid_et4000w32.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_et4000w32.o -MD -MP -MF $(DEPDIR)/pcem-vid_et4000w32.Tpo -c -o pcem-vid_et4000w32.o `test -f 'vid_et4000w32.c' || echo '$(srcdir)/'`vid_et4000w32.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_et4000w32.Tpo $(DEPDIR)/pcem-vid_et4000w32.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_et4000w32.c' object='pcem-vid_et4000w32.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_et4000w32.o `test -f 'vid_et4000w32.c' || echo '$(srcdir)/'`vid_et4000w32.c - -pcem-vid_et4000w32.obj: vid_et4000w32.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_et4000w32.obj -MD -MP -MF $(DEPDIR)/pcem-vid_et4000w32.Tpo -c -o pcem-vid_et4000w32.obj `if test -f 'vid_et4000w32.c'; then $(CYGPATH_W) 'vid_et4000w32.c'; else $(CYGPATH_W) '$(srcdir)/vid_et4000w32.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_et4000w32.Tpo $(DEPDIR)/pcem-vid_et4000w32.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_et4000w32.c' object='pcem-vid_et4000w32.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_et4000w32.obj `if test -f 'vid_et4000w32.c'; then $(CYGPATH_W) 'vid_et4000w32.c'; else $(CYGPATH_W) '$(srcdir)/vid_et4000w32.c'; fi` - -pcem-vid_hercules.o: vid_hercules.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_hercules.o -MD -MP -MF $(DEPDIR)/pcem-vid_hercules.Tpo -c -o pcem-vid_hercules.o `test -f 'vid_hercules.c' || echo '$(srcdir)/'`vid_hercules.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_hercules.Tpo $(DEPDIR)/pcem-vid_hercules.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_hercules.c' object='pcem-vid_hercules.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_hercules.o `test -f 'vid_hercules.c' || echo '$(srcdir)/'`vid_hercules.c - -pcem-vid_hercules.obj: vid_hercules.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_hercules.obj -MD -MP -MF $(DEPDIR)/pcem-vid_hercules.Tpo -c -o pcem-vid_hercules.obj `if test -f 'vid_hercules.c'; then $(CYGPATH_W) 'vid_hercules.c'; else $(CYGPATH_W) '$(srcdir)/vid_hercules.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_hercules.Tpo $(DEPDIR)/pcem-vid_hercules.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_hercules.c' object='pcem-vid_hercules.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_hercules.obj `if test -f 'vid_hercules.c'; then $(CYGPATH_W) 'vid_hercules.c'; else $(CYGPATH_W) '$(srcdir)/vid_hercules.c'; fi` - -pcem-vid_icd2061.o: vid_icd2061.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_icd2061.o -MD -MP -MF $(DEPDIR)/pcem-vid_icd2061.Tpo -c -o pcem-vid_icd2061.o `test -f 'vid_icd2061.c' || echo '$(srcdir)/'`vid_icd2061.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_icd2061.Tpo $(DEPDIR)/pcem-vid_icd2061.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_icd2061.c' object='pcem-vid_icd2061.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_icd2061.o `test -f 'vid_icd2061.c' || echo '$(srcdir)/'`vid_icd2061.c - -pcem-vid_icd2061.obj: vid_icd2061.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_icd2061.obj -MD -MP -MF $(DEPDIR)/pcem-vid_icd2061.Tpo -c -o pcem-vid_icd2061.obj `if test -f 'vid_icd2061.c'; then $(CYGPATH_W) 'vid_icd2061.c'; else $(CYGPATH_W) '$(srcdir)/vid_icd2061.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_icd2061.Tpo $(DEPDIR)/pcem-vid_icd2061.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_icd2061.c' object='pcem-vid_icd2061.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_icd2061.obj `if test -f 'vid_icd2061.c'; then $(CYGPATH_W) 'vid_icd2061.c'; else $(CYGPATH_W) '$(srcdir)/vid_icd2061.c'; fi` - -pcem-vid_ics2595.o: vid_ics2595.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ics2595.o -MD -MP -MF $(DEPDIR)/pcem-vid_ics2595.Tpo -c -o pcem-vid_ics2595.o `test -f 'vid_ics2595.c' || echo '$(srcdir)/'`vid_ics2595.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ics2595.Tpo $(DEPDIR)/pcem-vid_ics2595.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ics2595.c' object='pcem-vid_ics2595.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ics2595.o `test -f 'vid_ics2595.c' || echo '$(srcdir)/'`vid_ics2595.c - -pcem-vid_ics2595.obj: vid_ics2595.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_ics2595.obj -MD -MP -MF $(DEPDIR)/pcem-vid_ics2595.Tpo -c -o pcem-vid_ics2595.obj `if test -f 'vid_ics2595.c'; then $(CYGPATH_W) 'vid_ics2595.c'; else $(CYGPATH_W) '$(srcdir)/vid_ics2595.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_ics2595.Tpo $(DEPDIR)/pcem-vid_ics2595.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_ics2595.c' object='pcem-vid_ics2595.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ics2595.obj `if test -f 'vid_ics2595.c'; then $(CYGPATH_W) 'vid_ics2595.c'; else $(CYGPATH_W) '$(srcdir)/vid_ics2595.c'; fi` - -pcem-vid_mda.o: vid_mda.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_mda.o -MD -MP -MF $(DEPDIR)/pcem-vid_mda.Tpo -c -o pcem-vid_mda.o `test -f 'vid_mda.c' || echo '$(srcdir)/'`vid_mda.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_mda.Tpo $(DEPDIR)/pcem-vid_mda.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_mda.c' object='pcem-vid_mda.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_mda.o `test -f 'vid_mda.c' || echo '$(srcdir)/'`vid_mda.c - -pcem-vid_mda.obj: vid_mda.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_mda.obj -MD -MP -MF $(DEPDIR)/pcem-vid_mda.Tpo -c -o pcem-vid_mda.obj `if test -f 'vid_mda.c'; then $(CYGPATH_W) 'vid_mda.c'; else $(CYGPATH_W) '$(srcdir)/vid_mda.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_mda.Tpo $(DEPDIR)/pcem-vid_mda.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_mda.c' object='pcem-vid_mda.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_mda.obj `if test -f 'vid_mda.c'; then $(CYGPATH_W) 'vid_mda.c'; else $(CYGPATH_W) '$(srcdir)/vid_mda.c'; fi` - -pcem-vid_olivetti_m24.o: vid_olivetti_m24.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_olivetti_m24.o -MD -MP -MF $(DEPDIR)/pcem-vid_olivetti_m24.Tpo -c -o pcem-vid_olivetti_m24.o `test -f 'vid_olivetti_m24.c' || echo '$(srcdir)/'`vid_olivetti_m24.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_olivetti_m24.Tpo $(DEPDIR)/pcem-vid_olivetti_m24.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_olivetti_m24.c' object='pcem-vid_olivetti_m24.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_olivetti_m24.o `test -f 'vid_olivetti_m24.c' || echo '$(srcdir)/'`vid_olivetti_m24.c - -pcem-vid_olivetti_m24.obj: vid_olivetti_m24.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_olivetti_m24.obj -MD -MP -MF $(DEPDIR)/pcem-vid_olivetti_m24.Tpo -c -o pcem-vid_olivetti_m24.obj `if test -f 'vid_olivetti_m24.c'; then $(CYGPATH_W) 'vid_olivetti_m24.c'; else $(CYGPATH_W) '$(srcdir)/vid_olivetti_m24.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_olivetti_m24.Tpo $(DEPDIR)/pcem-vid_olivetti_m24.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_olivetti_m24.c' object='pcem-vid_olivetti_m24.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_olivetti_m24.obj `if test -f 'vid_olivetti_m24.c'; then $(CYGPATH_W) 'vid_olivetti_m24.c'; else $(CYGPATH_W) '$(srcdir)/vid_olivetti_m24.c'; fi` - -pcem-vid_oti067.o: vid_oti067.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_oti067.o -MD -MP -MF $(DEPDIR)/pcem-vid_oti067.Tpo -c -o pcem-vid_oti067.o `test -f 'vid_oti067.c' || echo '$(srcdir)/'`vid_oti067.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_oti067.Tpo $(DEPDIR)/pcem-vid_oti067.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_oti067.c' object='pcem-vid_oti067.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_oti067.o `test -f 'vid_oti067.c' || echo '$(srcdir)/'`vid_oti067.c - -pcem-vid_oti067.obj: vid_oti067.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_oti067.obj -MD -MP -MF $(DEPDIR)/pcem-vid_oti067.Tpo -c -o pcem-vid_oti067.obj `if test -f 'vid_oti067.c'; then $(CYGPATH_W) 'vid_oti067.c'; else $(CYGPATH_W) '$(srcdir)/vid_oti067.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_oti067.Tpo $(DEPDIR)/pcem-vid_oti067.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_oti067.c' object='pcem-vid_oti067.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_oti067.obj `if test -f 'vid_oti067.c'; then $(CYGPATH_W) 'vid_oti067.c'; else $(CYGPATH_W) '$(srcdir)/vid_oti067.c'; fi` - -pcem-vid_paradise.o: vid_paradise.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_paradise.o -MD -MP -MF $(DEPDIR)/pcem-vid_paradise.Tpo -c -o pcem-vid_paradise.o `test -f 'vid_paradise.c' || echo '$(srcdir)/'`vid_paradise.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_paradise.Tpo $(DEPDIR)/pcem-vid_paradise.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_paradise.c' object='pcem-vid_paradise.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_paradise.o `test -f 'vid_paradise.c' || echo '$(srcdir)/'`vid_paradise.c - -pcem-vid_paradise.obj: vid_paradise.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_paradise.obj -MD -MP -MF $(DEPDIR)/pcem-vid_paradise.Tpo -c -o pcem-vid_paradise.obj `if test -f 'vid_paradise.c'; then $(CYGPATH_W) 'vid_paradise.c'; else $(CYGPATH_W) '$(srcdir)/vid_paradise.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_paradise.Tpo $(DEPDIR)/pcem-vid_paradise.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_paradise.c' object='pcem-vid_paradise.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_paradise.obj `if test -f 'vid_paradise.c'; then $(CYGPATH_W) 'vid_paradise.c'; else $(CYGPATH_W) '$(srcdir)/vid_paradise.c'; fi` - -pcem-vid_pc200.o: vid_pc200.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pc200.o -MD -MP -MF $(DEPDIR)/pcem-vid_pc200.Tpo -c -o pcem-vid_pc200.o `test -f 'vid_pc200.c' || echo '$(srcdir)/'`vid_pc200.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pc200.Tpo $(DEPDIR)/pcem-vid_pc200.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pc200.c' object='pcem-vid_pc200.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pc200.o `test -f 'vid_pc200.c' || echo '$(srcdir)/'`vid_pc200.c - -pcem-vid_pc200.obj: vid_pc200.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pc200.obj -MD -MP -MF $(DEPDIR)/pcem-vid_pc200.Tpo -c -o pcem-vid_pc200.obj `if test -f 'vid_pc200.c'; then $(CYGPATH_W) 'vid_pc200.c'; else $(CYGPATH_W) '$(srcdir)/vid_pc200.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pc200.Tpo $(DEPDIR)/pcem-vid_pc200.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pc200.c' object='pcem-vid_pc200.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pc200.obj `if test -f 'vid_pc200.c'; then $(CYGPATH_W) 'vid_pc200.c'; else $(CYGPATH_W) '$(srcdir)/vid_pc200.c'; fi` - -pcem-vid_pc1512.o: vid_pc1512.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pc1512.o -MD -MP -MF $(DEPDIR)/pcem-vid_pc1512.Tpo -c -o pcem-vid_pc1512.o `test -f 'vid_pc1512.c' || echo '$(srcdir)/'`vid_pc1512.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pc1512.Tpo $(DEPDIR)/pcem-vid_pc1512.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pc1512.c' object='pcem-vid_pc1512.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pc1512.o `test -f 'vid_pc1512.c' || echo '$(srcdir)/'`vid_pc1512.c - -pcem-vid_pc1512.obj: vid_pc1512.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pc1512.obj -MD -MP -MF $(DEPDIR)/pcem-vid_pc1512.Tpo -c -o pcem-vid_pc1512.obj `if test -f 'vid_pc1512.c'; then $(CYGPATH_W) 'vid_pc1512.c'; else $(CYGPATH_W) '$(srcdir)/vid_pc1512.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pc1512.Tpo $(DEPDIR)/pcem-vid_pc1512.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pc1512.c' object='pcem-vid_pc1512.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pc1512.obj `if test -f 'vid_pc1512.c'; then $(CYGPATH_W) 'vid_pc1512.c'; else $(CYGPATH_W) '$(srcdir)/vid_pc1512.c'; fi` - -pcem-vid_pc1640.o: vid_pc1640.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pc1640.o -MD -MP -MF $(DEPDIR)/pcem-vid_pc1640.Tpo -c -o pcem-vid_pc1640.o `test -f 'vid_pc1640.c' || echo '$(srcdir)/'`vid_pc1640.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pc1640.Tpo $(DEPDIR)/pcem-vid_pc1640.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pc1640.c' object='pcem-vid_pc1640.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pc1640.o `test -f 'vid_pc1640.c' || echo '$(srcdir)/'`vid_pc1640.c - -pcem-vid_pc1640.obj: vid_pc1640.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pc1640.obj -MD -MP -MF $(DEPDIR)/pcem-vid_pc1640.Tpo -c -o pcem-vid_pc1640.obj `if test -f 'vid_pc1640.c'; then $(CYGPATH_W) 'vid_pc1640.c'; else $(CYGPATH_W) '$(srcdir)/vid_pc1640.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pc1640.Tpo $(DEPDIR)/pcem-vid_pc1640.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pc1640.c' object='pcem-vid_pc1640.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pc1640.obj `if test -f 'vid_pc1640.c'; then $(CYGPATH_W) 'vid_pc1640.c'; else $(CYGPATH_W) '$(srcdir)/vid_pc1640.c'; fi` - -pcem-vid_pcjr.o: vid_pcjr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pcjr.o -MD -MP -MF $(DEPDIR)/pcem-vid_pcjr.Tpo -c -o pcem-vid_pcjr.o `test -f 'vid_pcjr.c' || echo '$(srcdir)/'`vid_pcjr.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pcjr.Tpo $(DEPDIR)/pcem-vid_pcjr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pcjr.c' object='pcem-vid_pcjr.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pcjr.o `test -f 'vid_pcjr.c' || echo '$(srcdir)/'`vid_pcjr.c - -pcem-vid_pcjr.obj: vid_pcjr.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_pcjr.obj -MD -MP -MF $(DEPDIR)/pcem-vid_pcjr.Tpo -c -o pcem-vid_pcjr.obj `if test -f 'vid_pcjr.c'; then $(CYGPATH_W) 'vid_pcjr.c'; else $(CYGPATH_W) '$(srcdir)/vid_pcjr.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_pcjr.Tpo $(DEPDIR)/pcem-vid_pcjr.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_pcjr.c' object='pcem-vid_pcjr.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_pcjr.obj `if test -f 'vid_pcjr.c'; then $(CYGPATH_W) 'vid_pcjr.c'; else $(CYGPATH_W) '$(srcdir)/vid_pcjr.c'; fi` - -pcem-vid_s3.o: vid_s3.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_s3.o -MD -MP -MF $(DEPDIR)/pcem-vid_s3.Tpo -c -o pcem-vid_s3.o `test -f 'vid_s3.c' || echo '$(srcdir)/'`vid_s3.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_s3.Tpo $(DEPDIR)/pcem-vid_s3.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_s3.c' object='pcem-vid_s3.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_s3.o `test -f 'vid_s3.c' || echo '$(srcdir)/'`vid_s3.c - -pcem-vid_s3.obj: vid_s3.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_s3.obj -MD -MP -MF $(DEPDIR)/pcem-vid_s3.Tpo -c -o pcem-vid_s3.obj `if test -f 'vid_s3.c'; then $(CYGPATH_W) 'vid_s3.c'; else $(CYGPATH_W) '$(srcdir)/vid_s3.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_s3.Tpo $(DEPDIR)/pcem-vid_s3.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_s3.c' object='pcem-vid_s3.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_s3.obj `if test -f 'vid_s3.c'; then $(CYGPATH_W) 'vid_s3.c'; else $(CYGPATH_W) '$(srcdir)/vid_s3.c'; fi` - -pcem-vid_s3_virge.o: vid_s3_virge.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_s3_virge.o -MD -MP -MF $(DEPDIR)/pcem-vid_s3_virge.Tpo -c -o pcem-vid_s3_virge.o `test -f 'vid_s3_virge.c' || echo '$(srcdir)/'`vid_s3_virge.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_s3_virge.Tpo $(DEPDIR)/pcem-vid_s3_virge.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_s3_virge.c' object='pcem-vid_s3_virge.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_s3_virge.o `test -f 'vid_s3_virge.c' || echo '$(srcdir)/'`vid_s3_virge.c - -pcem-vid_s3_virge.obj: vid_s3_virge.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_s3_virge.obj -MD -MP -MF $(DEPDIR)/pcem-vid_s3_virge.Tpo -c -o pcem-vid_s3_virge.obj `if test -f 'vid_s3_virge.c'; then $(CYGPATH_W) 'vid_s3_virge.c'; else $(CYGPATH_W) '$(srcdir)/vid_s3_virge.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_s3_virge.Tpo $(DEPDIR)/pcem-vid_s3_virge.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_s3_virge.c' object='pcem-vid_s3_virge.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_s3_virge.obj `if test -f 'vid_s3_virge.c'; then $(CYGPATH_W) 'vid_s3_virge.c'; else $(CYGPATH_W) '$(srcdir)/vid_s3_virge.c'; fi` - -pcem-vid_sdac_ramdac.o: vid_sdac_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_sdac_ramdac.o -MD -MP -MF $(DEPDIR)/pcem-vid_sdac_ramdac.Tpo -c -o pcem-vid_sdac_ramdac.o `test -f 'vid_sdac_ramdac.c' || echo '$(srcdir)/'`vid_sdac_ramdac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_sdac_ramdac.Tpo $(DEPDIR)/pcem-vid_sdac_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_sdac_ramdac.c' object='pcem-vid_sdac_ramdac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_sdac_ramdac.o `test -f 'vid_sdac_ramdac.c' || echo '$(srcdir)/'`vid_sdac_ramdac.c - -pcem-vid_sdac_ramdac.obj: vid_sdac_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_sdac_ramdac.obj -MD -MP -MF $(DEPDIR)/pcem-vid_sdac_ramdac.Tpo -c -o pcem-vid_sdac_ramdac.obj `if test -f 'vid_sdac_ramdac.c'; then $(CYGPATH_W) 'vid_sdac_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_sdac_ramdac.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_sdac_ramdac.Tpo $(DEPDIR)/pcem-vid_sdac_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_sdac_ramdac.c' object='pcem-vid_sdac_ramdac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_sdac_ramdac.obj `if test -f 'vid_sdac_ramdac.c'; then $(CYGPATH_W) 'vid_sdac_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_sdac_ramdac.c'; fi` - -pcem-vid_stg_ramdac.o: vid_stg_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_stg_ramdac.o -MD -MP -MF $(DEPDIR)/pcem-vid_stg_ramdac.Tpo -c -o pcem-vid_stg_ramdac.o `test -f 'vid_stg_ramdac.c' || echo '$(srcdir)/'`vid_stg_ramdac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_stg_ramdac.Tpo $(DEPDIR)/pcem-vid_stg_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_stg_ramdac.c' object='pcem-vid_stg_ramdac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_stg_ramdac.o `test -f 'vid_stg_ramdac.c' || echo '$(srcdir)/'`vid_stg_ramdac.c - -pcem-vid_stg_ramdac.obj: vid_stg_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_stg_ramdac.obj -MD -MP -MF $(DEPDIR)/pcem-vid_stg_ramdac.Tpo -c -o pcem-vid_stg_ramdac.obj `if test -f 'vid_stg_ramdac.c'; then $(CYGPATH_W) 'vid_stg_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_stg_ramdac.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_stg_ramdac.Tpo $(DEPDIR)/pcem-vid_stg_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_stg_ramdac.c' object='pcem-vid_stg_ramdac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_stg_ramdac.obj `if test -f 'vid_stg_ramdac.c'; then $(CYGPATH_W) 'vid_stg_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_stg_ramdac.c'; fi` - -pcem-vid_svga.o: vid_svga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_svga.o -MD -MP -MF $(DEPDIR)/pcem-vid_svga.Tpo -c -o pcem-vid_svga.o `test -f 'vid_svga.c' || echo '$(srcdir)/'`vid_svga.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_svga.Tpo $(DEPDIR)/pcem-vid_svga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_svga.c' object='pcem-vid_svga.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_svga.o `test -f 'vid_svga.c' || echo '$(srcdir)/'`vid_svga.c - -pcem-vid_svga.obj: vid_svga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_svga.obj -MD -MP -MF $(DEPDIR)/pcem-vid_svga.Tpo -c -o pcem-vid_svga.obj `if test -f 'vid_svga.c'; then $(CYGPATH_W) 'vid_svga.c'; else $(CYGPATH_W) '$(srcdir)/vid_svga.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_svga.Tpo $(DEPDIR)/pcem-vid_svga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_svga.c' object='pcem-vid_svga.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_svga.obj `if test -f 'vid_svga.c'; then $(CYGPATH_W) 'vid_svga.c'; else $(CYGPATH_W) '$(srcdir)/vid_svga.c'; fi` - -pcem-vid_svga_render.o: vid_svga_render.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_svga_render.o -MD -MP -MF $(DEPDIR)/pcem-vid_svga_render.Tpo -c -o pcem-vid_svga_render.o `test -f 'vid_svga_render.c' || echo '$(srcdir)/'`vid_svga_render.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_svga_render.Tpo $(DEPDIR)/pcem-vid_svga_render.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_svga_render.c' object='pcem-vid_svga_render.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_svga_render.o `test -f 'vid_svga_render.c' || echo '$(srcdir)/'`vid_svga_render.c - -pcem-vid_svga_render.obj: vid_svga_render.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_svga_render.obj -MD -MP -MF $(DEPDIR)/pcem-vid_svga_render.Tpo -c -o pcem-vid_svga_render.obj `if test -f 'vid_svga_render.c'; then $(CYGPATH_W) 'vid_svga_render.c'; else $(CYGPATH_W) '$(srcdir)/vid_svga_render.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_svga_render.Tpo $(DEPDIR)/pcem-vid_svga_render.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_svga_render.c' object='pcem-vid_svga_render.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_svga_render.obj `if test -f 'vid_svga_render.c'; then $(CYGPATH_W) 'vid_svga_render.c'; else $(CYGPATH_W) '$(srcdir)/vid_svga_render.c'; fi` - -pcem-vid_tandy.o: vid_tandy.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tandy.o -MD -MP -MF $(DEPDIR)/pcem-vid_tandy.Tpo -c -o pcem-vid_tandy.o `test -f 'vid_tandy.c' || echo '$(srcdir)/'`vid_tandy.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tandy.Tpo $(DEPDIR)/pcem-vid_tandy.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tandy.c' object='pcem-vid_tandy.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tandy.o `test -f 'vid_tandy.c' || echo '$(srcdir)/'`vid_tandy.c - -pcem-vid_tandy.obj: vid_tandy.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tandy.obj -MD -MP -MF $(DEPDIR)/pcem-vid_tandy.Tpo -c -o pcem-vid_tandy.obj `if test -f 'vid_tandy.c'; then $(CYGPATH_W) 'vid_tandy.c'; else $(CYGPATH_W) '$(srcdir)/vid_tandy.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tandy.Tpo $(DEPDIR)/pcem-vid_tandy.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tandy.c' object='pcem-vid_tandy.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tandy.obj `if test -f 'vid_tandy.c'; then $(CYGPATH_W) 'vid_tandy.c'; else $(CYGPATH_W) '$(srcdir)/vid_tandy.c'; fi` - -pcem-vid_tgui9440.o: vid_tgui9440.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tgui9440.o -MD -MP -MF $(DEPDIR)/pcem-vid_tgui9440.Tpo -c -o pcem-vid_tgui9440.o `test -f 'vid_tgui9440.c' || echo '$(srcdir)/'`vid_tgui9440.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tgui9440.Tpo $(DEPDIR)/pcem-vid_tgui9440.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tgui9440.c' object='pcem-vid_tgui9440.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tgui9440.o `test -f 'vid_tgui9440.c' || echo '$(srcdir)/'`vid_tgui9440.c - -pcem-vid_tgui9440.obj: vid_tgui9440.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tgui9440.obj -MD -MP -MF $(DEPDIR)/pcem-vid_tgui9440.Tpo -c -o pcem-vid_tgui9440.obj `if test -f 'vid_tgui9440.c'; then $(CYGPATH_W) 'vid_tgui9440.c'; else $(CYGPATH_W) '$(srcdir)/vid_tgui9440.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tgui9440.Tpo $(DEPDIR)/pcem-vid_tgui9440.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tgui9440.c' object='pcem-vid_tgui9440.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tgui9440.obj `if test -f 'vid_tgui9440.c'; then $(CYGPATH_W) 'vid_tgui9440.c'; else $(CYGPATH_W) '$(srcdir)/vid_tgui9440.c'; fi` - -pcem-vid_tkd8001_ramdac.o: vid_tkd8001_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tkd8001_ramdac.o -MD -MP -MF $(DEPDIR)/pcem-vid_tkd8001_ramdac.Tpo -c -o pcem-vid_tkd8001_ramdac.o `test -f 'vid_tkd8001_ramdac.c' || echo '$(srcdir)/'`vid_tkd8001_ramdac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tkd8001_ramdac.Tpo $(DEPDIR)/pcem-vid_tkd8001_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tkd8001_ramdac.c' object='pcem-vid_tkd8001_ramdac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tkd8001_ramdac.o `test -f 'vid_tkd8001_ramdac.c' || echo '$(srcdir)/'`vid_tkd8001_ramdac.c - -pcem-vid_tkd8001_ramdac.obj: vid_tkd8001_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tkd8001_ramdac.obj -MD -MP -MF $(DEPDIR)/pcem-vid_tkd8001_ramdac.Tpo -c -o pcem-vid_tkd8001_ramdac.obj `if test -f 'vid_tkd8001_ramdac.c'; then $(CYGPATH_W) 'vid_tkd8001_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_tkd8001_ramdac.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tkd8001_ramdac.Tpo $(DEPDIR)/pcem-vid_tkd8001_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tkd8001_ramdac.c' object='pcem-vid_tkd8001_ramdac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tkd8001_ramdac.obj `if test -f 'vid_tkd8001_ramdac.c'; then $(CYGPATH_W) 'vid_tkd8001_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_tkd8001_ramdac.c'; fi` - -pcem-vid_tvga.o: vid_tvga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tvga.o -MD -MP -MF $(DEPDIR)/pcem-vid_tvga.Tpo -c -o pcem-vid_tvga.o `test -f 'vid_tvga.c' || echo '$(srcdir)/'`vid_tvga.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tvga.Tpo $(DEPDIR)/pcem-vid_tvga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tvga.c' object='pcem-vid_tvga.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tvga.o `test -f 'vid_tvga.c' || echo '$(srcdir)/'`vid_tvga.c - -pcem-vid_tvga.obj: vid_tvga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_tvga.obj -MD -MP -MF $(DEPDIR)/pcem-vid_tvga.Tpo -c -o pcem-vid_tvga.obj `if test -f 'vid_tvga.c'; then $(CYGPATH_W) 'vid_tvga.c'; else $(CYGPATH_W) '$(srcdir)/vid_tvga.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_tvga.Tpo $(DEPDIR)/pcem-vid_tvga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_tvga.c' object='pcem-vid_tvga.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_tvga.obj `if test -f 'vid_tvga.c'; then $(CYGPATH_W) 'vid_tvga.c'; else $(CYGPATH_W) '$(srcdir)/vid_tvga.c'; fi` - -pcem-vid_unk_ramdac.o: vid_unk_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_unk_ramdac.o -MD -MP -MF $(DEPDIR)/pcem-vid_unk_ramdac.Tpo -c -o pcem-vid_unk_ramdac.o `test -f 'vid_unk_ramdac.c' || echo '$(srcdir)/'`vid_unk_ramdac.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_unk_ramdac.Tpo $(DEPDIR)/pcem-vid_unk_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_unk_ramdac.c' object='pcem-vid_unk_ramdac.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_unk_ramdac.o `test -f 'vid_unk_ramdac.c' || echo '$(srcdir)/'`vid_unk_ramdac.c - -pcem-vid_unk_ramdac.obj: vid_unk_ramdac.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_unk_ramdac.obj -MD -MP -MF $(DEPDIR)/pcem-vid_unk_ramdac.Tpo -c -o pcem-vid_unk_ramdac.obj `if test -f 'vid_unk_ramdac.c'; then $(CYGPATH_W) 'vid_unk_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_unk_ramdac.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_unk_ramdac.Tpo $(DEPDIR)/pcem-vid_unk_ramdac.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_unk_ramdac.c' object='pcem-vid_unk_ramdac.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_unk_ramdac.obj `if test -f 'vid_unk_ramdac.c'; then $(CYGPATH_W) 'vid_unk_ramdac.c'; else $(CYGPATH_W) '$(srcdir)/vid_unk_ramdac.c'; fi` - -pcem-vid_vga.o: vid_vga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_vga.o -MD -MP -MF $(DEPDIR)/pcem-vid_vga.Tpo -c -o pcem-vid_vga.o `test -f 'vid_vga.c' || echo '$(srcdir)/'`vid_vga.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_vga.Tpo $(DEPDIR)/pcem-vid_vga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_vga.c' object='pcem-vid_vga.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_vga.o `test -f 'vid_vga.c' || echo '$(srcdir)/'`vid_vga.c - -pcem-vid_vga.obj: vid_vga.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_vga.obj -MD -MP -MF $(DEPDIR)/pcem-vid_vga.Tpo -c -o pcem-vid_vga.obj `if test -f 'vid_vga.c'; then $(CYGPATH_W) 'vid_vga.c'; else $(CYGPATH_W) '$(srcdir)/vid_vga.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_vga.Tpo $(DEPDIR)/pcem-vid_vga.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_vga.c' object='pcem-vid_vga.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_vga.obj `if test -f 'vid_vga.c'; then $(CYGPATH_W) 'vid_vga.c'; else $(CYGPATH_W) '$(srcdir)/vid_vga.c'; fi` - -pcem-vid_voodoo.o: vid_voodoo.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo.o -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo.Tpo -c -o pcem-vid_voodoo.o `test -f 'vid_voodoo.c' || echo '$(srcdir)/'`vid_voodoo.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_voodoo.Tpo $(DEPDIR)/pcem-vid_voodoo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_voodoo.c' object='pcem-vid_voodoo.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo.o `test -f 'vid_voodoo.c' || echo '$(srcdir)/'`vid_voodoo.c - -pcem-vid_voodoo.obj: vid_voodoo.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_voodoo.obj -MD -MP -MF $(DEPDIR)/pcem-vid_voodoo.Tpo -c -o pcem-vid_voodoo.obj `if test -f 'vid_voodoo.c'; then $(CYGPATH_W) 'vid_voodoo.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_voodoo.Tpo $(DEPDIR)/pcem-vid_voodoo.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_voodoo.c' object='pcem-vid_voodoo.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_voodoo.obj `if test -f 'vid_voodoo.c'; then $(CYGPATH_W) 'vid_voodoo.c'; else $(CYGPATH_W) '$(srcdir)/vid_voodoo.c'; fi` - -pcem-video.o: video.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-video.o -MD -MP -MF $(DEPDIR)/pcem-video.Tpo -c -o pcem-video.o `test -f 'video.c' || echo '$(srcdir)/'`video.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-video.Tpo $(DEPDIR)/pcem-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='video.c' object='pcem-video.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-video.o `test -f 'video.c' || echo '$(srcdir)/'`video.c - -pcem-video.obj: video.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-video.obj -MD -MP -MF $(DEPDIR)/pcem-video.Tpo -c -o pcem-video.obj `if test -f 'video.c'; then $(CYGPATH_W) 'video.c'; else $(CYGPATH_W) '$(srcdir)/video.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-video.Tpo $(DEPDIR)/pcem-video.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='video.c' object='pcem-video.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-video.obj `if test -f 'video.c'; then $(CYGPATH_W) 'video.c'; else $(CYGPATH_W) '$(srcdir)/video.c'; fi` - -pcem-wd76c10.o: wd76c10.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wd76c10.o -MD -MP -MF $(DEPDIR)/pcem-wd76c10.Tpo -c -o pcem-wd76c10.o `test -f 'wd76c10.c' || echo '$(srcdir)/'`wd76c10.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-wd76c10.Tpo $(DEPDIR)/pcem-wd76c10.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wd76c10.c' object='pcem-wd76c10.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wd76c10.o `test -f 'wd76c10.c' || echo '$(srcdir)/'`wd76c10.c - -pcem-wd76c10.obj: wd76c10.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-wd76c10.obj -MD -MP -MF $(DEPDIR)/pcem-wd76c10.Tpo -c -o pcem-wd76c10.obj `if test -f 'wd76c10.c'; then $(CYGPATH_W) 'wd76c10.c'; else $(CYGPATH_W) '$(srcdir)/wd76c10.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-wd76c10.Tpo $(DEPDIR)/pcem-wd76c10.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='wd76c10.c' object='pcem-wd76c10.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-wd76c10.obj `if test -f 'wd76c10.c'; then $(CYGPATH_W) 'wd76c10.c'; else $(CYGPATH_W) '$(srcdir)/wd76c10.c'; fi` - -pcem-x86seg.o: x86seg.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-x86seg.o -MD -MP -MF $(DEPDIR)/pcem-x86seg.Tpo -c -o pcem-x86seg.o `test -f 'x86seg.c' || echo '$(srcdir)/'`x86seg.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-x86seg.Tpo $(DEPDIR)/pcem-x86seg.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x86seg.c' object='pcem-x86seg.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-x86seg.o `test -f 'x86seg.c' || echo '$(srcdir)/'`x86seg.c - -pcem-x86seg.obj: x86seg.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-x86seg.obj -MD -MP -MF $(DEPDIR)/pcem-x86seg.Tpo -c -o pcem-x86seg.obj `if test -f 'x86seg.c'; then $(CYGPATH_W) 'x86seg.c'; else $(CYGPATH_W) '$(srcdir)/x86seg.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-x86seg.Tpo $(DEPDIR)/pcem-x86seg.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x86seg.c' object='pcem-x86seg.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-x86seg.obj `if test -f 'x86seg.c'; then $(CYGPATH_W) 'x86seg.c'; else $(CYGPATH_W) '$(srcdir)/x86seg.c'; fi` - -pcem-x87.o: x87.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-x87.o -MD -MP -MF $(DEPDIR)/pcem-x87.Tpo -c -o pcem-x87.o `test -f 'x87.c' || echo '$(srcdir)/'`x87.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-x87.Tpo $(DEPDIR)/pcem-x87.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x87.c' object='pcem-x87.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-x87.o `test -f 'x87.c' || echo '$(srcdir)/'`x87.c - -pcem-x87.obj: x87.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-x87.obj -MD -MP -MF $(DEPDIR)/pcem-x87.Tpo -c -o pcem-x87.obj `if test -f 'x87.c'; then $(CYGPATH_W) 'x87.c'; else $(CYGPATH_W) '$(srcdir)/x87.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-x87.Tpo $(DEPDIR)/pcem-x87.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='x87.c' object='pcem-x87.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-x87.obj `if test -f 'x87.c'; then $(CYGPATH_W) 'x87.c'; else $(CYGPATH_W) '$(srcdir)/x87.c'; fi` - -pcem-xtide.o: xtide.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-xtide.o -MD -MP -MF $(DEPDIR)/pcem-xtide.Tpo -c -o pcem-xtide.o `test -f 'xtide.c' || echo '$(srcdir)/'`xtide.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-xtide.Tpo $(DEPDIR)/pcem-xtide.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xtide.c' object='pcem-xtide.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-xtide.o `test -f 'xtide.c' || echo '$(srcdir)/'`xtide.c - -pcem-xtide.obj: xtide.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-xtide.obj -MD -MP -MF $(DEPDIR)/pcem-xtide.Tpo -c -o pcem-xtide.obj `if test -f 'xtide.c'; then $(CYGPATH_W) 'xtide.c'; else $(CYGPATH_W) '$(srcdir)/xtide.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-xtide.Tpo $(DEPDIR)/pcem-xtide.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xtide.c' object='pcem-xtide.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-xtide.obj `if test -f 'xtide.c'; then $(CYGPATH_W) 'xtide.c'; else $(CYGPATH_W) '$(srcdir)/xtide.c'; fi` - -pcem-codegen_x86.o: codegen_x86.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_x86.o -MD -MP -MF $(DEPDIR)/pcem-codegen_x86.Tpo -c -o pcem-codegen_x86.o `test -f 'codegen_x86.c' || echo '$(srcdir)/'`codegen_x86.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_x86.Tpo $(DEPDIR)/pcem-codegen_x86.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_x86.c' object='pcem-codegen_x86.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_x86.o `test -f 'codegen_x86.c' || echo '$(srcdir)/'`codegen_x86.c - -pcem-codegen_x86.obj: codegen_x86.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_x86.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_x86.Tpo -c -o pcem-codegen_x86.obj `if test -f 'codegen_x86.c'; then $(CYGPATH_W) 'codegen_x86.c'; else $(CYGPATH_W) '$(srcdir)/codegen_x86.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_x86.Tpo $(DEPDIR)/pcem-codegen_x86.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_x86.c' object='pcem-codegen_x86.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_x86.obj `if test -f 'codegen_x86.c'; then $(CYGPATH_W) 'codegen_x86.c'; else $(CYGPATH_W) '$(srcdir)/codegen_x86.c'; fi` - -pcem-codegen_x86-64.o: codegen_x86-64.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_x86-64.o -MD -MP -MF $(DEPDIR)/pcem-codegen_x86-64.Tpo -c -o pcem-codegen_x86-64.o `test -f 'codegen_x86-64.c' || echo '$(srcdir)/'`codegen_x86-64.c -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_x86-64.Tpo $(DEPDIR)/pcem-codegen_x86-64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_x86-64.c' object='pcem-codegen_x86-64.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_x86-64.o `test -f 'codegen_x86-64.c' || echo '$(srcdir)/'`codegen_x86-64.c - -pcem-codegen_x86-64.obj: codegen_x86-64.c -@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-codegen_x86-64.obj -MD -MP -MF $(DEPDIR)/pcem-codegen_x86-64.Tpo -c -o pcem-codegen_x86-64.obj `if test -f 'codegen_x86-64.c'; then $(CYGPATH_W) 'codegen_x86-64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_x86-64.c'; fi` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-codegen_x86-64.Tpo $(DEPDIR)/pcem-codegen_x86-64.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='codegen_x86-64.c' object='pcem-codegen_x86-64.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-codegen_x86-64.obj `if test -f 'codegen_x86-64.c'; then $(CYGPATH_W) 'codegen_x86-64.c'; else $(CYGPATH_W) '$(srcdir)/codegen_x86-64.c'; fi` - -.cc.o: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< - -.cc.obj: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -dbopl.o: dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dbopl.o -MD -MP -MF $(DEPDIR)/dbopl.Tpo -c -o dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/dbopl.Tpo $(DEPDIR)/dbopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dosbox/dbopl.cpp' object='dbopl.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dbopl.o `test -f 'dosbox/dbopl.cpp' || echo '$(srcdir)/'`dosbox/dbopl.cpp - -dbopl.obj: dosbox/dbopl.cpp -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT dbopl.obj -MD -MP -MF $(DEPDIR)/dbopl.Tpo -c -o dbopl.obj `if test -f 'dosbox/dbopl.cpp'; then $(CYGPATH_W) 'dosbox/dbopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/dbopl.cpp'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/dbopl.Tpo $(DEPDIR)/dbopl.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='dosbox/dbopl.cpp' object='dbopl.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o dbopl.obj `if test -f 'dosbox/dbopl.cpp'; then $(CYGPATH_W) 'dosbox/dbopl.cpp'; else $(CYGPATH_W) '$(srcdir)/dosbox/dbopl.cpp'; fi` - -convolve.o: resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT convolve.o -MD -MP -MF $(DEPDIR)/convolve.Tpo -c -o convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/convolve.Tpo $(DEPDIR)/convolve.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/convolve.cc' object='convolve.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o convolve.o `test -f 'resid-fp/convolve.cc' || echo '$(srcdir)/'`resid-fp/convolve.cc - -convolve.obj: resid-fp/convolve.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT convolve.obj -MD -MP -MF $(DEPDIR)/convolve.Tpo -c -o convolve.obj `if test -f 'resid-fp/convolve.cc'; then $(CYGPATH_W) 'resid-fp/convolve.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/convolve.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/convolve.Tpo $(DEPDIR)/convolve.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/convolve.cc' object='convolve.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o convolve.obj `if test -f 'resid-fp/convolve.cc'; then $(CYGPATH_W) 'resid-fp/convolve.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/convolve.cc'; fi` - -convolve-sse.o: resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT convolve-sse.o -MD -MP -MF $(DEPDIR)/convolve-sse.Tpo -c -o convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/convolve-sse.Tpo $(DEPDIR)/convolve-sse.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/convolve-sse.cc' object='convolve-sse.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o convolve-sse.o `test -f 'resid-fp/convolve-sse.cc' || echo '$(srcdir)/'`resid-fp/convolve-sse.cc - -convolve-sse.obj: resid-fp/convolve-sse.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT convolve-sse.obj -MD -MP -MF $(DEPDIR)/convolve-sse.Tpo -c -o convolve-sse.obj `if test -f 'resid-fp/convolve-sse.cc'; then $(CYGPATH_W) 'resid-fp/convolve-sse.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/convolve-sse.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/convolve-sse.Tpo $(DEPDIR)/convolve-sse.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/convolve-sse.cc' object='convolve-sse.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o convolve-sse.obj `if test -f 'resid-fp/convolve-sse.cc'; then $(CYGPATH_W) 'resid-fp/convolve-sse.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/convolve-sse.cc'; fi` - -envelope.o: resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT envelope.o -MD -MP -MF $(DEPDIR)/envelope.Tpo -c -o envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/envelope.Tpo $(DEPDIR)/envelope.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/envelope.cc' object='envelope.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o envelope.o `test -f 'resid-fp/envelope.cc' || echo '$(srcdir)/'`resid-fp/envelope.cc - -envelope.obj: resid-fp/envelope.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT envelope.obj -MD -MP -MF $(DEPDIR)/envelope.Tpo -c -o envelope.obj `if test -f 'resid-fp/envelope.cc'; then $(CYGPATH_W) 'resid-fp/envelope.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/envelope.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/envelope.Tpo $(DEPDIR)/envelope.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/envelope.cc' object='envelope.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o envelope.obj `if test -f 'resid-fp/envelope.cc'; then $(CYGPATH_W) 'resid-fp/envelope.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/envelope.cc'; fi` - -extfilt.o: resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extfilt.o -MD -MP -MF $(DEPDIR)/extfilt.Tpo -c -o extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extfilt.Tpo $(DEPDIR)/extfilt.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/extfilt.cc' object='extfilt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extfilt.o `test -f 'resid-fp/extfilt.cc' || echo '$(srcdir)/'`resid-fp/extfilt.cc - -extfilt.obj: resid-fp/extfilt.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT extfilt.obj -MD -MP -MF $(DEPDIR)/extfilt.Tpo -c -o extfilt.obj `if test -f 'resid-fp/extfilt.cc'; then $(CYGPATH_W) 'resid-fp/extfilt.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/extfilt.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/extfilt.Tpo $(DEPDIR)/extfilt.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/extfilt.cc' object='extfilt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o extfilt.obj `if test -f 'resid-fp/extfilt.cc'; then $(CYGPATH_W) 'resid-fp/extfilt.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/extfilt.cc'; fi` - -filter.o: resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT filter.o -MD -MP -MF $(DEPDIR)/filter.Tpo -c -o filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/filter.Tpo $(DEPDIR)/filter.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/filter.cc' object='filter.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o filter.o `test -f 'resid-fp/filter.cc' || echo '$(srcdir)/'`resid-fp/filter.cc - -filter.obj: resid-fp/filter.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT filter.obj -MD -MP -MF $(DEPDIR)/filter.Tpo -c -o filter.obj `if test -f 'resid-fp/filter.cc'; then $(CYGPATH_W) 'resid-fp/filter.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/filter.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/filter.Tpo $(DEPDIR)/filter.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/filter.cc' object='filter.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o filter.obj `if test -f 'resid-fp/filter.cc'; then $(CYGPATH_W) 'resid-fp/filter.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/filter.cc'; fi` - -pot.o: resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pot.o -MD -MP -MF $(DEPDIR)/pot.Tpo -c -o pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/pot.Tpo $(DEPDIR)/pot.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/pot.cc' object='pot.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pot.o `test -f 'resid-fp/pot.cc' || echo '$(srcdir)/'`resid-fp/pot.cc - -pot.obj: resid-fp/pot.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT pot.obj -MD -MP -MF $(DEPDIR)/pot.Tpo -c -o pot.obj `if test -f 'resid-fp/pot.cc'; then $(CYGPATH_W) 'resid-fp/pot.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/pot.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/pot.Tpo $(DEPDIR)/pot.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/pot.cc' object='pot.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o pot.obj `if test -f 'resid-fp/pot.cc'; then $(CYGPATH_W) 'resid-fp/pot.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/pot.cc'; fi` - -sid.o: resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sid.o -MD -MP -MF $(DEPDIR)/sid.Tpo -c -o sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/sid.Tpo $(DEPDIR)/sid.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/sid.cc' object='sid.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sid.o `test -f 'resid-fp/sid.cc' || echo '$(srcdir)/'`resid-fp/sid.cc - -sid.obj: resid-fp/sid.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sid.obj -MD -MP -MF $(DEPDIR)/sid.Tpo -c -o sid.obj `if test -f 'resid-fp/sid.cc'; then $(CYGPATH_W) 'resid-fp/sid.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/sid.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/sid.Tpo $(DEPDIR)/sid.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/sid.cc' object='sid.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sid.obj `if test -f 'resid-fp/sid.cc'; then $(CYGPATH_W) 'resid-fp/sid.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/sid.cc'; fi` - -voice.o: resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT voice.o -MD -MP -MF $(DEPDIR)/voice.Tpo -c -o voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/voice.Tpo $(DEPDIR)/voice.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/voice.cc' object='voice.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o voice.o `test -f 'resid-fp/voice.cc' || echo '$(srcdir)/'`resid-fp/voice.cc - -voice.obj: resid-fp/voice.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT voice.obj -MD -MP -MF $(DEPDIR)/voice.Tpo -c -o voice.obj `if test -f 'resid-fp/voice.cc'; then $(CYGPATH_W) 'resid-fp/voice.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/voice.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/voice.Tpo $(DEPDIR)/voice.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/voice.cc' object='voice.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o voice.obj `if test -f 'resid-fp/voice.cc'; then $(CYGPATH_W) 'resid-fp/voice.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/voice.cc'; fi` - -wave6581_PS_.o: resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581_PS_.o -MD -MP -MF $(DEPDIR)/wave6581_PS_.Tpo -c -o wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581_PS_.Tpo $(DEPDIR)/wave6581_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581_PS_.cc' object='wave6581_PS_.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581_PS_.o `test -f 'resid-fp/wave6581_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PS_.cc - -wave6581_PS_.obj: resid-fp/wave6581_PS_.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581_PS_.obj -MD -MP -MF $(DEPDIR)/wave6581_PS_.Tpo -c -o wave6581_PS_.obj `if test -f 'resid-fp/wave6581_PS_.cc'; then $(CYGPATH_W) 'resid-fp/wave6581_PS_.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581_PS_.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581_PS_.Tpo $(DEPDIR)/wave6581_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581_PS_.cc' object='wave6581_PS_.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581_PS_.obj `if test -f 'resid-fp/wave6581_PS_.cc'; then $(CYGPATH_W) 'resid-fp/wave6581_PS_.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581_PS_.cc'; fi` - -wave6581_PST.o: resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581_PST.o -MD -MP -MF $(DEPDIR)/wave6581_PST.Tpo -c -o wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581_PST.Tpo $(DEPDIR)/wave6581_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581_PST.cc' object='wave6581_PST.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581_PST.o `test -f 'resid-fp/wave6581_PST.cc' || echo '$(srcdir)/'`resid-fp/wave6581_PST.cc - -wave6581_PST.obj: resid-fp/wave6581_PST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581_PST.obj -MD -MP -MF $(DEPDIR)/wave6581_PST.Tpo -c -o wave6581_PST.obj `if test -f 'resid-fp/wave6581_PST.cc'; then $(CYGPATH_W) 'resid-fp/wave6581_PST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581_PST.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581_PST.Tpo $(DEPDIR)/wave6581_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581_PST.cc' object='wave6581_PST.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581_PST.obj `if test -f 'resid-fp/wave6581_PST.cc'; then $(CYGPATH_W) 'resid-fp/wave6581_PST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581_PST.cc'; fi` - -wave6581_P_T.o: resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581_P_T.o -MD -MP -MF $(DEPDIR)/wave6581_P_T.Tpo -c -o wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581_P_T.Tpo $(DEPDIR)/wave6581_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581_P_T.cc' object='wave6581_P_T.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581_P_T.o `test -f 'resid-fp/wave6581_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave6581_P_T.cc - -wave6581_P_T.obj: resid-fp/wave6581_P_T.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581_P_T.obj -MD -MP -MF $(DEPDIR)/wave6581_P_T.Tpo -c -o wave6581_P_T.obj `if test -f 'resid-fp/wave6581_P_T.cc'; then $(CYGPATH_W) 'resid-fp/wave6581_P_T.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581_P_T.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581_P_T.Tpo $(DEPDIR)/wave6581_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581_P_T.cc' object='wave6581_P_T.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581_P_T.obj `if test -f 'resid-fp/wave6581_P_T.cc'; then $(CYGPATH_W) 'resid-fp/wave6581_P_T.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581_P_T.cc'; fi` - -wave6581__ST.o: resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581__ST.o -MD -MP -MF $(DEPDIR)/wave6581__ST.Tpo -c -o wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581__ST.Tpo $(DEPDIR)/wave6581__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581__ST.cc' object='wave6581__ST.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581__ST.o `test -f 'resid-fp/wave6581__ST.cc' || echo '$(srcdir)/'`resid-fp/wave6581__ST.cc - -wave6581__ST.obj: resid-fp/wave6581__ST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave6581__ST.obj -MD -MP -MF $(DEPDIR)/wave6581__ST.Tpo -c -o wave6581__ST.obj `if test -f 'resid-fp/wave6581__ST.cc'; then $(CYGPATH_W) 'resid-fp/wave6581__ST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581__ST.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave6581__ST.Tpo $(DEPDIR)/wave6581__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave6581__ST.cc' object='wave6581__ST.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave6581__ST.obj `if test -f 'resid-fp/wave6581__ST.cc'; then $(CYGPATH_W) 'resid-fp/wave6581__ST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave6581__ST.cc'; fi` - -wave8580_PS_.o: resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580_PS_.o -MD -MP -MF $(DEPDIR)/wave8580_PS_.Tpo -c -o wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580_PS_.Tpo $(DEPDIR)/wave8580_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580_PS_.cc' object='wave8580_PS_.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580_PS_.o `test -f 'resid-fp/wave8580_PS_.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PS_.cc - -wave8580_PS_.obj: resid-fp/wave8580_PS_.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580_PS_.obj -MD -MP -MF $(DEPDIR)/wave8580_PS_.Tpo -c -o wave8580_PS_.obj `if test -f 'resid-fp/wave8580_PS_.cc'; then $(CYGPATH_W) 'resid-fp/wave8580_PS_.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580_PS_.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580_PS_.Tpo $(DEPDIR)/wave8580_PS_.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580_PS_.cc' object='wave8580_PS_.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580_PS_.obj `if test -f 'resid-fp/wave8580_PS_.cc'; then $(CYGPATH_W) 'resid-fp/wave8580_PS_.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580_PS_.cc'; fi` - -wave8580_PST.o: resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580_PST.o -MD -MP -MF $(DEPDIR)/wave8580_PST.Tpo -c -o wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580_PST.Tpo $(DEPDIR)/wave8580_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580_PST.cc' object='wave8580_PST.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580_PST.o `test -f 'resid-fp/wave8580_PST.cc' || echo '$(srcdir)/'`resid-fp/wave8580_PST.cc - -wave8580_PST.obj: resid-fp/wave8580_PST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580_PST.obj -MD -MP -MF $(DEPDIR)/wave8580_PST.Tpo -c -o wave8580_PST.obj `if test -f 'resid-fp/wave8580_PST.cc'; then $(CYGPATH_W) 'resid-fp/wave8580_PST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580_PST.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580_PST.Tpo $(DEPDIR)/wave8580_PST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580_PST.cc' object='wave8580_PST.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580_PST.obj `if test -f 'resid-fp/wave8580_PST.cc'; then $(CYGPATH_W) 'resid-fp/wave8580_PST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580_PST.cc'; fi` - -wave8580_P_T.o: resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580_P_T.o -MD -MP -MF $(DEPDIR)/wave8580_P_T.Tpo -c -o wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580_P_T.Tpo $(DEPDIR)/wave8580_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580_P_T.cc' object='wave8580_P_T.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580_P_T.o `test -f 'resid-fp/wave8580_P_T.cc' || echo '$(srcdir)/'`resid-fp/wave8580_P_T.cc - -wave8580_P_T.obj: resid-fp/wave8580_P_T.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580_P_T.obj -MD -MP -MF $(DEPDIR)/wave8580_P_T.Tpo -c -o wave8580_P_T.obj `if test -f 'resid-fp/wave8580_P_T.cc'; then $(CYGPATH_W) 'resid-fp/wave8580_P_T.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580_P_T.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580_P_T.Tpo $(DEPDIR)/wave8580_P_T.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580_P_T.cc' object='wave8580_P_T.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580_P_T.obj `if test -f 'resid-fp/wave8580_P_T.cc'; then $(CYGPATH_W) 'resid-fp/wave8580_P_T.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580_P_T.cc'; fi` - -wave8580__ST.o: resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580__ST.o -MD -MP -MF $(DEPDIR)/wave8580__ST.Tpo -c -o wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580__ST.Tpo $(DEPDIR)/wave8580__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580__ST.cc' object='wave8580__ST.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580__ST.o `test -f 'resid-fp/wave8580__ST.cc' || echo '$(srcdir)/'`resid-fp/wave8580__ST.cc - -wave8580__ST.obj: resid-fp/wave8580__ST.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave8580__ST.obj -MD -MP -MF $(DEPDIR)/wave8580__ST.Tpo -c -o wave8580__ST.obj `if test -f 'resid-fp/wave8580__ST.cc'; then $(CYGPATH_W) 'resid-fp/wave8580__ST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580__ST.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave8580__ST.Tpo $(DEPDIR)/wave8580__ST.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave8580__ST.cc' object='wave8580__ST.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave8580__ST.obj `if test -f 'resid-fp/wave8580__ST.cc'; then $(CYGPATH_W) 'resid-fp/wave8580__ST.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave8580__ST.cc'; fi` - -wave.o: resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave.o -MD -MP -MF $(DEPDIR)/wave.Tpo -c -o wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave.Tpo $(DEPDIR)/wave.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave.cc' object='wave.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave.o `test -f 'resid-fp/wave.cc' || echo '$(srcdir)/'`resid-fp/wave.cc - -wave.obj: resid-fp/wave.cc -@am__fastdepCXX_TRUE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT wave.obj -MD -MP -MF $(DEPDIR)/wave.Tpo -c -o wave.obj `if test -f 'resid-fp/wave.cc'; then $(CYGPATH_W) 'resid-fp/wave.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave.cc'; fi` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/wave.Tpo $(DEPDIR)/wave.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='resid-fp/wave.cc' object='wave.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o wave.obj `if test -f 'resid-fp/wave.cc'; then $(CYGPATH_W) 'resid-fp/wave.cc'; else $(CYGPATH_W) '$(srcdir)/resid-fp/wave.cc'; fi` - -.cpp.o: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< - -.cpp.obj: -@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: CTAGS -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(PROGRAMS) $(SCRIPTS) -installdirs: - for dir in "$(DESTDIR)$(bindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ - clean-generic ctags distclean distclean-compile \ - distclean-generic distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-binPROGRAMS \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-binPROGRAMS - - -../pcem: pcem - cp pcem .. - -amrefresh: - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e780126a3..c7850ce4a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -1,56 +1,189 @@ -VPATH = . dosbox lzf resid-fp slirp -CPP = g++.exe -CC = gcc.exe -WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ - cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o hdd.o headland.o i430hx.o i430lx.o i430fx.o \ - i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ - keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o mfm_at.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ - scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ - sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ - sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ - soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o usb.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_hercules.o vid_herculesplus.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ - vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ - vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ - vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-status.o win-video.o x86seg.o x87.o xtide.o pc.res -DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o -LZFOBJ = lzf_c.o lzf_d.o -SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o -SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# Modified Makefile for Win32 MinGW 32-bit environment. +# +# Version: @(#)Makefile.mingw 1.0.5 2017/05/05 +# +# Authors: Kotori, +# Fred N. van Kempen, +# Sarah Walker, +# Richard G., +# + +# Name of the executable. +PROG = 86Box + +# Various compile-time options. +# -DROM_TRACE=0xcd800 traces ROM access from segment C800 +# -DIO_TACE=0x66 traces I/O on port 0x66 +STUFF = + +# Add feature selections here. +# -DBUGGER adds the ISA BusBugger emulation. +EXTRAS = + +# Do we want a debugging build? +DEBUG = n -LIBS = -mwindows -lwinmm -lopenal.dll -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lwpcapdelay +######################################################################### +# Nothing should need changing from here on.. # +######################################################################### +VPATH = . dosbox lzf resid-fp slirp +CPP = g++.exe +CC = gcc.exe +WINDRES = windres.exe -86Box.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) - $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box.exe" $(LIBS) - sleep 10 - strip "86Box.exe" - sleep 10 +OPTS = -DWIN32 $(EXTRAS) $(STUFF) +ifeq ($(DEBUG), y) +DFLAGS = -march=i686 -Og -ggdb -DDEBUG +else +DFLAGS = -march=native -mtune=native -O6 +UFLAGS = -march=i686 -O3 +endif +AFLAGS = -msse -msse2 -mfpmath=sse +CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ + -fomit-frame-pointer -mstackrealign +RFLAGS = --input-format=rc -O coff -all : 86Box.exe -clean : - rm *.o - rm *.exe - rm *.res +MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ + mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ + memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o +CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ + codegen.o \ + codegen_ops.o codegen_timing_486.o \ + codegen_timing_686.o codegen_timing_pentium.o \ + codegen_timing_winchip.o codegen_x86.o \ + x86seg.o x87.o +SYSOBJ = model.o \ + headland.o \ + i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ + neat.o \ + ali1429.o \ + opti495.o \ + scat.o \ + sis496.o \ + wd76c10.o \ + acer386sx.o acerm3a.o amstrad.o \ + compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ + tandy_eeprom.o tandy_rom.o +DEVOBJ = bugger.o lpt.o serial.o \ + um8669f.o pc87306.o sis85c471.o w83877f.o \ + keyboard.o \ + keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ + keyboard_amstrad.o keyboard_olim24.o \ + gameport.o \ + joystick_standard.o joystick_ch_flightstick_pro.o \ + joystick_sw_pad.o joystick_tm_fcs.o \ + mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ + fdd.o fdc.o \ + fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ + hdd.o hdd_esdi.o mfm_at.o mfm_xebec.o ide.o xtide.o piix.o scsi_hd.o \ + disc.o \ + disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ + disc_random.o disc_td0.o \ + cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o +USBOBJ = usb.o +NETOBJ = ne2000.o nethandler.o +SCSIOBJ = scsi.o scsi_buslogic.o scsi_aha154x.o +SNDOBJ = sound.o sound_speaker.o dac.o sound_ps1.o sound_pssj.o \ + sound_adlib.o sound_adlibgold.o sound_ad1848.o sound_sb.o \ + sound_sb_dsp.o sound_cms.o sound_dbopl.o sound_emu8k.o \ + sound_gus.o sound_opl.o sound_mpu401_uart.o sound_pas16.o \ + sound_resid.o sound_sn76489.o sound_ssi2001.o sound_wss.o \ + sound_ym7128.o soundopenal.o +VIDOBJ = video.o \ + vid_mda.o vid_cga.o vid_ega.o \ + vid_vga.o vid_svga.o vid_svga_render.o \ + vid_hercules.o vid_herculesplus.o vid_incolor.o \ + vid_colorplus.o \ + vid_genius.o \ + vid_s3.o vid_s3_virge.o \ + vid_et4000.o vid_et4000w32.o vid_icd2061.o \ + vid_oti067.o \ + vid_paradise.o \ + vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ + vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ + vid_ati68860_ramdac.o vid_ati_mach64.o \ + vid_ics2595.o \ + vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o \ + vid_bt485_ramdac.o \ + vid_sdac_ramdac.o \ + vid_stg_ramdac.o \ + vid_unk_ramdac.o \ + vid_wy700.o \ + vid_nv_riva128.o \ + vid_voodoo.o \ + vid_pcjr.o vid_ps1_svga.o \ + vid_olivetti_m24.o \ + vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_tandy.o vid_tandysl.o +WINOBJ = win.o \ + win-d3d.o win-d3d-fs.o \ + win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ + win-language.o win-status.o win-video.o \ + win-keyboard.o win-mouse.o win-joystick.o win-midi.o \ + win-settings.o win-deviceconfig.o win-joystickconfig.o \ + 86Box.res +OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ + $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) -%.o : %.c - $(CC) $(CFLAGS) -c $< +DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o +LZFOBJ = lzf_c.o lzf_d.o +SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o \ + sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o \ + wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o +SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o \ + queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o \ + udp.o if.o mbuf.o slirp.o tcp_subr.o -%.o : %.cc - $(CPP) $(CFLAGS) -c $< +LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ + -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ + -lstdc++ -lpsapi -static-libstdc++ -static-libgcc \ + -static -L. -lwpcapdelay -%.o : %.cpp - $(CPP) $(CFLAGS) -c $< -pc.res: pc.rc - $(WINDRES) $(RFLAGS) -i pc.rc --input-format=rc -o pc.res -O coff +# Build rules. +%.o: %.c + @echo $< + $(CC) $(CFLAGS) -c $< + +%.o: %.cc + @echo $< + @$(CPP) $(CFLAGS) -c $< + +%.o: %.cpp + @echo $< + @$(CPP) $(CFLAGS) -c $< + +$(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) + @echo Linking $(PROG).exe .. + @$(CC) -o $(PROG).exe \ + $(OBJ) \ + $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ + $(LIBS) + +all: $(PROG).exe +ifeq ($(DEBUG), y) + strip $(PROG).exe +endif + +clean: + rm *.o + rm *.exe + rm *.res + +86Box.res: 86Box.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res + + +# End of Makefile.mingw. diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 2b285a556..c880ecaac 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -1,56 +1,189 @@ -VPATH = . dosbox lzf resid-fp slirp -CPP = g++.exe -CC = gcc.exe -WINDRES = windres.exe -CFLAGS = -O3 -march=native -mtune=native -fbranch-probabilities -fvpt -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse -mstackrealign -DFLAGS = -O3 -fomit-frame-pointer -msse2 -mstackrealign -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o acerm3a.o ali1429.o amstrad.o buslogic.o cdrom.o cdrom-ioctl.o cdrom-iso.o \ - cdrom-null.o codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ - device.o disc.o disc_86f.o disc_fdi.o disc_imd.o disc_img.o disc_random.o disc_td0.o dma.o fdc.o fdc37c665.o fdc37c932fr.o fdd.o fdi2raw.o gameport.o hdd.o headland.o i430hx.o i430lx.o i430fx.o \ - i430nx.o i430vx.o i440fx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ - keyboard_olim24.o keyboard_pcjr.o keyboard_xt.o lpt.o mcr.o mem.o memregs.o mfm_at.o model.o mouse.o mouse_ps2.o \ - mouse_serial.o ne2000.o neat.o nethandler.o nmi.o nvr.o olivetti_m24.o opti495.o pc.o pc87306.o pci.o pic.o piix.o pit.o ppi.o ps1.o ps2.o rom.o rtc.o \ - scat.o scsi.o serial.o sis496.o sis85c471.o sio.o sound.o sound_ad1848.o sound_adlib.o sound_adlibgold.o sound_cms.o \ - sound_dbopl.o sound_emu8k.o sound_gus.o sound_mpu401_uart.o sound_opl.o sound_pas16.o sound_ps1.o sound_pssj.o sound_resid.o \ - sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_ssi2001.o sound_wss.o sound_ym7128.o \ - soundopenal.o tandy_eeprom.o tandy_rom.o timer.o um8669f.o usb.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \ - vid_ati28800.o vid_ati68860_ramdac.o vid_bt485_ramdac.o vid_cga.o vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o vid_colorplus.o vid_ega.o vid_et4000.o \ - vid_et4000w32.o vid_hercules.o vid_herculesplus.o vid_icd2061.o vid_ics2595.o vid_incolor.o vid_mda.o vid_nv_riva128.o \ - vid_olivetti_m24.o vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o \ - vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o \ - vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o \ - vid_vga.o vid_wy700.o vid_voodoo.o video.o w83877f.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \ - win-ddraw-fs.o win-ddraw-screenshot.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ - win-status.o win-video.o x86seg.o x87.o xtide.o pc.res -DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o -LZFOBJ = lzf_c.o lzf_d.o -SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o -SLIRPOBJ = bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# Modified Makefile for Win32 MinGW 32-bit environment. +# +# Version: @(#)Makefile.mingw64 1.0.0 2017/05/05 +# +# Authors: Kotori, +# Fred N. van Kempen, +# Sarah Walker, +# Richard G., +# + +# Name of the executable. +PROG = 86Box64 + +# Various compile-time options. +# -DROM_TRACE=0xcd800 traces ROM access from segment C800 +# -DIO_TACE=0x66 traces I/O on port 0x66 +STUFF = + +# Add feature selections here. +# -DBUGGER adds the ISA BusBugger emulation. +EXTRAS = + +# Do we want a debugging build? +DEBUG = n -LIBS = -mwindows -lwinmm -lopenal -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi -lstdc++ -lpsapi -static-libstdc++ -static-libgcc -static -lopenal.dll -lgcov -lPacket -lwpcapdelay +######################################################################### +# Nothing should need changing from here on.. # +######################################################################### +VPATH = . dosbox lzf resid-fp slirp +CPP = g++.exe +CC = gcc.exe +WINDRES = windres.exe -86Box64.exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) - $(CC) $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) -o "86Box64.exe" $(LIBS) - sleep 10 - strip "86Box64.exe" - sleep 10 +OPTS = -DWIN32 $(EXTRAS) $(STUFF) +ifeq ($(DEBUG), y) +DFLAGS = -march=i686 -Og -ggdb -DDEBUG +else +DFLAGS = -march=native -mtune=native -O6 +UFLAGS = -O3 +endif +AFLAGS = -msse -msse2 -mfpmath=sse +CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ + -fomit-frame-pointer -mstackrealign +RFLAGS = --input-format=rc -O coff -all : 86Box64.exe -clean : - rm *.o - rm *.exe - rm *.res +MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ + mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ + memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o +CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ + codegen.o \ + codegen_ops.o codegen_timing_486.o \ + codegen_timing_686.o codegen_timing_pentium.o \ + codegen_timing_winchip.o codegen_x86-64.o \ + x86seg.o x87.o +SYSOBJ = model.o \ + headland.o \ + i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ + neat.o \ + ali1429.o \ + opti495.o \ + scat.o \ + sis496.o \ + wd76c10.o \ + acer386sx.o acerm3a.o amstrad.o \ + compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ + tandy_eeprom.o tandy_rom.o +DEVOBJ = bugger.o lpt.o serial.o \ + um8669f.o pc87306.o sis85c471.o w83877f.o \ + keyboard.o \ + keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ + keyboard_amstrad.o keyboard_olim24.o \ + gameport.o \ + joystick_standard.o joystick_ch_flightstick_pro.o \ + joystick_sw_pad.o joystick_tm_fcs.o \ + mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ + fdd.o fdc.o \ + fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ + hdd.o hdd_esdi.o mfm_at.o mfm_xebec.o ide.o xtide.o piix.o scsi_hd.o \ + disc.o \ + disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ + disc_random.o disc_td0.o \ + cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o +USBOBJ = usb.o +NETOBJ = ne2000.o nethandler.o +SCSIOBJ = scsi.o scsi_buslogic.o scsi_aha154x.o +SNDOBJ = sound.o sound_speaker.o dac.o sound_ps1.o sound_pssj.o \ + sound_adlib.o sound_adlibgold.o sound_ad1848.o sound_sb.o \ + sound_sb_dsp.o sound_cms.o sound_dbopl.o sound_emu8k.o \ + sound_gus.o sound_opl.o sound_mpu401_uart.o sound_pas16.o \ + sound_resid.o sound_sn76489.o sound_ssi2001.o sound_wss.o \ + sound_ym7128.o soundopenal.o +VIDOBJ = video.o \ + vid_mda.o vid_cga.o vid_ega.o \ + vid_vga.o vid_svga.o vid_svga_render.o \ + vid_hercules.o vid_herculesplus.o vid_incolor.o \ + vid_colorplus.o \ + vid_genius.o \ + vid_s3.o vid_s3_virge.o \ + vid_et4000.o vid_et4000w32.o vid_icd2061.o \ + vid_oti067.o \ + vid_paradise.o \ + vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ + vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ + vid_ati68860_ramdac.o vid_ati_mach64.o \ + vid_ics2595.o \ + vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o \ + vid_bt485_ramdac.o \ + vid_sdac_ramdac.o \ + vid_stg_ramdac.o \ + vid_unk_ramdac.o \ + vid_wy700.o \ + vid_nv_riva128.o \ + vid_voodoo.o \ + vid_pcjr.o vid_ps1_svga.o \ + vid_olivetti_m24.o \ + vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_tandy.o vid_tandysl.o +WINOBJ = win.o \ + win-d3d.o win-d3d-fs.o \ + win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ + win-language.o win-status.o win-video.o \ + win-keyboard.o win-mouse.o win-joystick.o win-midi.o \ + win-settings.o win-deviceconfig.o win-joystickconfig.o \ + 86Box.res +OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ + $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) -%.o : %.c - $(CC) $(CFLAGS) -c $< +DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o +LZFOBJ = lzf_c.o lzf_d.o +SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o \ + sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o \ + wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o +SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o \ + queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o \ + udp.o if.o mbuf.o slirp.o tcp_subr.o -%.o : %.cc - $(CPP) $(CFLAGS) -c $< +LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ + -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ + -lstdc++ -lpsapi -static-libstdc++ -static-libgcc \ + -static -L. -lwpcapdelay -%.o : %.cpp - $(CPP) $(CFLAGS) -c $< -pc.res: pc.rc - $(WINDRES) $(RFLAGS) -i pc.rc --input-format=rc -o pc.res -O coff +# Build rules. +%.o: %.c + @echo $< + $(CC) $(CFLAGS) -c $< + +%.o: %.cc + @echo $< + @$(CPP) $(CFLAGS) -c $< + +%.o: %.cpp + @echo $< + @$(CPP) $(CFLAGS) -c $< + +$(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) + @echo Linking $(PROG).exe .. + @$(CC) -o $(PROG).exe \ + $(OBJ) \ + $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ + $(LIBS) + +all: $(PROG).exe +ifeq ($(DEBUG), y) + strip $(PROG).exe +endif + +clean: + rm *.o + rm *.exe + rm *.res + +86Box.res: 86Box.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res + + +# End of Makefile.mingw. diff --git a/src/ali1429.c b/src/ali1429.c index d01eaf863..f1fa8fa3f 100644 --- a/src/ali1429.c +++ b/src/ali1429.c @@ -46,14 +46,11 @@ static void ali1429_recalc() void ali1429_write(uint16_t port, uint8_t val, void *priv) { - int c; - if (!(port & 1)) ali1429_index = val; else { ali1429_regs[ali1429_index] = val; -// pclog("ALI1429 write %02X %02X %04X:%04X %i\n",ali1429_index,val,CS,pc,ins); switch (ali1429_index) { case 0x13: diff --git a/src/ali1429.h b/src/ali1429.h index 83362e746..baea23a44 100644 --- a/src/ali1429.h +++ b/src/ali1429.h @@ -2,3 +2,4 @@ see COPYING for more details */ void ali1429_init(); +void ali1429_reset(); diff --git a/src/amstrad.c b/src/amstrad.c index 4c728ff0f..c1f0ef763 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -1,3 +1,4 @@ +#include #include "ibm.h" #include "io.h" #include "keyboard.h" @@ -58,7 +59,7 @@ typedef struct mouse_amstrad_t int oldb; } mouse_amstrad_t; -static void mouse_amstrad_poll(int x, int y, int z, int b, void *p) +static uint8_t mouse_amstrad_poll(int x, int y, int z, int b, void *p) { mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; @@ -75,6 +76,8 @@ static void mouse_amstrad_poll(int x, int y, int z, int b, void *p) keyboard_send(0xfd); mouse->oldb = b; + + return(0); } static void *mouse_amstrad_init() @@ -95,10 +98,11 @@ static void mouse_amstrad_close(void *p) mouse_t mouse_amstrad = { "Amstrad mouse", + "amstrad", + MOUSE_TYPE_AMSTRAD, mouse_amstrad_init, mouse_amstrad_close, - mouse_amstrad_poll, - MOUSE_TYPE_AMSTRAD + mouse_amstrad_poll }; void amstrad_init() diff --git a/src/bswap.h b/src/bswap.h index f3cfe6a37..a1f2f8052 100644 --- a/src/bswap.h +++ b/src/bswap.h @@ -4,117 +4,110 @@ #ifndef BSWAP_H #define BSWAP_H -//#include "config-host.h" - -#include +#include #ifdef HAVE_BYTESWAP_H #include #else +# define bswap_16(x) \ + ( \ + ((uint16_t)( \ + (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \ + (((uint16_t)(x) & (uint16_t)0xff00U) >> 8) )) \ + ) -#define bswap_16(x) \ -({ \ - uint16_t __x = (x); \ - ((uint16_t)( \ - (((uint16_t)(__x) & (uint16_t)0x00ffU) << 8) | \ - (((uint16_t)(__x) & (uint16_t)0xff00U) >> 8) )); \ -}) +# define bswap_32(x) \ + ( \ + ((uint32_t)( \ + (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \ + (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \ + (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \ + (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) )) \ + ) -#define bswap_32(x) \ -({ \ - uint32_t __x = (x); \ - ((uint32_t)( \ - (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \ - (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \ - (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \ - (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \ -}) +# define bswap_64(x) \ + ( \ + ((uint64_t)( \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ + (uint64_t)(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) )) \ + ) +#endif /*HAVE_BYTESWAP_H*/ -#define bswap_64(x) \ -({ \ - uint64_t __x = (x); \ - ((uint64_t)( \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000000000ffULL) << 56) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000000000ff00ULL) << 40) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00000000ff000000ULL) << 8) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \ - (uint64_t)(((uint64_t)(__x) & (uint64_t)0xff00000000000000ULL) >> 56) )); \ -}) - -#endif /* !HAVE_BYTESWAP_H */ - -static inline uint16_t bswap16(uint16_t x) +static __inline uint16_t bswap16(uint16_t x) { return bswap_16(x); } -static inline uint32_t bswap32(uint32_t x) +static __inline uint32_t bswap32(uint32_t x) { return bswap_32(x); } -static inline uint64_t bswap64(uint64_t x) +static __inline uint64_t bswap64(uint64_t x) { return bswap_64(x); } -static inline void bswap16s(uint16_t *s) +static __inline void bswap16s(uint16_t *s) { *s = bswap16(*s); } -static inline void bswap32s(uint32_t *s) +static __inline void bswap32s(uint32_t *s) { *s = bswap32(*s); } -static inline void bswap64s(uint64_t *s) +static __inline void bswap64s(uint64_t *s) { *s = bswap64(*s); } #if defined(WORDS_BIGENDIAN) -#define be_bswap(v, size) (v) -#define le_bswap(v, size) bswap ## size(v) -#define be_bswaps(v, size) -#define le_bswaps(p, size) *p = bswap ## size(*p); +# define be_bswap(v, size) (v) +# define le_bswap(v, size) bswap ## size(v) +# define be_bswaps(v, size) +# define le_bswaps(p, size) *p = bswap ## size(*p); #else -#define le_bswap(v, size) (v) -#define be_bswap(v, size) bswap ## size(v) -#define le_bswaps(v, size) -#define be_bswaps(p, size) *p = bswap ## size(*p); +# define le_bswap(v, size) (v) +# define be_bswap(v, size) bswap ## size(v) +# define le_bswaps(v, size) +# define be_bswaps(p, size) *p = bswap ## size(*p); #endif #define CPU_CONVERT(endian, size, type)\ -static inline type endian ## size ## _to_cpu(type v)\ +static __inline type endian ## size ## _to_cpu(type v)\ {\ return endian ## _bswap(v, size);\ }\ \ -static inline type cpu_to_ ## endian ## size(type v)\ +static __inline type cpu_to_ ## endian ## size(type v)\ {\ return endian ## _bswap(v, size);\ }\ \ -static inline void endian ## size ## _to_cpus(type *p)\ +static __inline void endian ## size ## _to_cpus(type *p)\ {\ endian ## _bswaps(p, size)\ }\ \ -static inline void cpu_to_ ## endian ## size ## s(type *p)\ +static __inline void cpu_to_ ## endian ## size ## s(type *p)\ {\ endian ## _bswaps(p, size)\ }\ \ -static inline type endian ## size ## _to_cpup(const type *p)\ +static __inline type endian ## size ## _to_cpup(const type *p)\ {\ return endian ## size ## _to_cpu(*p);\ }\ \ -static inline void cpu_to_ ## endian ## size ## w(type *p, type v)\ +static __inline void cpu_to_ ## endian ## size ## w(type *p, type v)\ {\ *p = cpu_to_ ## endian ## size(v);\ } @@ -141,7 +134,7 @@ CPU_CONVERT(le, 64, uint64_t) #else -static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) +static __inline void cpu_to_le16wu(uint16_t *p, uint16_t v) { uint8_t *p1 = (uint8_t *)p; @@ -149,7 +142,7 @@ static inline void cpu_to_le16wu(uint16_t *p, uint16_t v) p1[1] = v >> 8; } -static inline void cpu_to_le32wu(uint32_t *p, uint32_t v) +static __inline void cpu_to_le32wu(uint32_t *p, uint32_t v) { uint8_t *p1 = (uint8_t *)p; @@ -159,19 +152,19 @@ static inline void cpu_to_le32wu(uint32_t *p, uint32_t v) p1[3] = v >> 24; } -static inline uint16_t le16_to_cpupu(const uint16_t *p) +static __inline uint16_t le16_to_cpupu(const uint16_t *p) { const uint8_t *p1 = (const uint8_t *)p; return p1[0] | (p1[1] << 8); } -static inline uint32_t le32_to_cpupu(const uint32_t *p) +static __inline uint32_t le32_to_cpupu(const uint32_t *p) { const uint8_t *p1 = (const uint8_t *)p; return p1[0] | (p1[1] << 8) | (p1[2] << 16) | (p1[3] << 24); } -static inline void cpu_to_be16wu(uint16_t *p, uint16_t v) +static __inline void cpu_to_be16wu(uint16_t *p, uint16_t v) { uint8_t *p1 = (uint8_t *)p; @@ -179,7 +172,7 @@ static inline void cpu_to_be16wu(uint16_t *p, uint16_t v) p1[1] = v; } -static inline void cpu_to_be32wu(uint32_t *p, uint32_t v) +static __inline void cpu_to_be32wu(uint32_t *p, uint32_t v) { uint8_t *p1 = (uint8_t *)p; diff --git a/src/bugger.c b/src/bugger.c new file mode 100644 index 000000000..d9a79aafa --- /dev/null +++ b/src/bugger.c @@ -0,0 +1,325 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ISA Bus (de)Bugger expansion card + * sold as a DIY kit in the late 1980's in The Netherlands. + * This card was a assemble-yourself 8bit ISA addon card for + * PC and AT systems that had several tools to aid in low- + * level debugging (mostly for faulty BIOSes, bootloaders + * and system kernels...) + * + * The standard version had a total of 16 LEDs (8 RED, plus + * 8 GREEN), two 7-segment displays and one 8-position DIP + * switch block on board for use as debugging tools. + * + * The "Plus" version, added an extra 2 7-segment displays, + * as well as a very simple RS-232 serial interface that + * could be used as a mini-console terminal. + * + * Two I/O ports were used; one for control, at offset 0 in + * I/O space, and one for data, at offset 1 in I/O space. + * Both registers could be read from and written to. Although + * the author has a vague memory of a DIP switch to set the + * board's I/O address, comments in old software seems to + * indicate that it was actually fixed to 0x7A (and 0x7B.) + * + * A READ on the data register always returned the actual + * state of the DIP switch. Writing data to the LEDs was done + * in two steps.. first, the block number (RED or GREEN) was + * written to the CTRL register, and then the actual LED data + * was written to the DATA register. Likewise, data for the + * 7-segment displays was written. + * + * The serial port was a bit different, and its operation is + * not verified, but two extra bits in the control register + * were used to set up parameters, and also the actual data + * input and output. + * + * TODO: Still have to implement the RS232 Serial Port Parameters + * configuration register (CTRL_SPCFG bit set) but have to + * remember that stuff first... + * + * Version: @(#)bugger.c 1.0.3 2017/04/07 + * + * Author: Fred N. van Kempen, + * Copyright 1989-2017 Fred N. van Kempen. + */ +#include "ibm.h" +#include "io.h" +#include "bugger.h" + + +/* BugBugger registers. */ +#define BUG_CTRL 0 +# define CTRL_RLED 0x00 /* write to the RED LED block */ +# define CTRL_GLED 0x01 /* write to the GREEN LED block */ +# define CTRL_SEG1 0x02 /* write to the RIGHT 7SEG displays */ +# define CTRL_SEG2 0x04 /* write to the LEFT 7SEG displays */ +# define CTRL_SPORT 0x20 /* enable the serial port */ +# define CTRL_SPCFG 0x40 /* set up the serial port */ +# define CTRL_INIT 0x80 /* enable and reset the card */ +# define CTRL_RESET 0xff /* this resets the board */ +#define BUG_DATA 1 + + +static uint8_t bug_ctrl, /* control register */ + bug_data, /* data register */ + bug_ledr, bug_ledg, /* RED and GREEN LEDs */ + bug_seg1, bug_seg2, /* LEFT and RIGHT 7SEG displays */ + bug_spcfg; /* serial port configuration */ +# define FIFO_LEN 256 +static uint8_t bug_buff[FIFO_LEN], /* serial port data buffer */ + *bug_bptr; +# define UISTR_LEN 24 +static char bug_str[UISTR_LEN]; /* UI output string */ + + +extern void set_bugui(char *__str); + + +/* Update the system's UI with the actual Bugger status. */ +static void +bug_setui(void) +{ + /* Format all current info in a string. */ + sprintf(bug_str, "%02X:%02X %c%c%c%c%c%c%c%c-%c%c%c%c%c%c%c%c", + bug_seg2, bug_seg1, + (bug_ledg&0x80)?'G':'g', (bug_ledg&0x40)?'G':'g', + (bug_ledg&0x20)?'G':'g', (bug_ledg&0x10)?'G':'g', + (bug_ledg&0x08)?'G':'g', (bug_ledg&0x04)?'G':'g', + (bug_ledg&0x02)?'G':'g', (bug_ledg&0x01)?'G':'g', + (bug_ledr&0x80)?'R':'r', (bug_ledr&0x40)?'R':'r', + (bug_ledr&0x20)?'R':'r', (bug_ledr&0x10)?'R':'r', + (bug_ledr&0x08)?'R':'r', (bug_ledr&0x04)?'R':'r', + (bug_ledr&0x02)?'R':'r', (bug_ledr&0x01)?'R':'r'); + +#if 0 + /* Send formatted string to the UI. */ + set_bugui(bug_str); +#endif +} + + +/* Flush the serial port. */ +static void +bug_spflsh(void) +{ + *bug_bptr = '\0'; + pclog("BUGGER- serial port [%s]\n", bug_buff); + bug_bptr = bug_buff; +} + + +/* Handle a write to the Serial Port Data register. */ +static void +bug_wsport(uint8_t val) +{ + uint8_t old = bug_ctrl; + + /* Clear the SPORT bit to indicate we are busy. */ + bug_ctrl &= ~CTRL_SPORT; + + /* Delay while processing byte.. */ + if (bug_bptr == &bug_buff[FIFO_LEN-1]) { + /* Buffer full, gotta flush. */ + bug_spflsh(); + } + + /* Write (store) the byte. */ + *bug_bptr++ = val; + + /* Restore the SPORT bit. */ + bug_ctrl |= (old & CTRL_SPORT); + + pclog("BUGGER- sport %02x\n", val); +} + + +/* Handle a write to the Serial Port Configuration register. */ +static void +bug_wspcfg(uint8_t val) +{ + bug_spcfg = val; + + pclog("BUGGER- spcfg %02x\n", bug_spcfg); +} + + +/* Handle a write to the control register. */ +static void +bug_wctrl(uint8_t val) +{ + if (val == CTRL_RESET) { + /* User wants us to reset. */ + bug_ctrl = CTRL_INIT; + bug_spcfg = 0x00; + bug_bptr = NULL; + } else { + /* If turning off the serial port, flush it. */ + if ((bug_ctrl & CTRL_SPORT) && !(val & CTRL_SPORT)) + bug_spflsh(); + + /* FIXME: did they do this using an XOR of operation bits? --FvK */ + + if (val & CTRL_SPCFG) { + /* User wants to configure the serial port. */ + bug_ctrl &= ~(CTRL_SPORT|CTRL_SEG2|CTRL_SEG1|CTRL_GLED); + bug_ctrl |= CTRL_SPCFG; + } else if (val & CTRL_SPORT) { + /* User wants to talk to the serial port. */ + bug_ctrl &= ~(CTRL_SPCFG|CTRL_SEG2|CTRL_SEG1|CTRL_GLED); + bug_ctrl |= CTRL_SPORT; + if (bug_bptr == NULL) + bug_bptr = bug_buff; + } else if (val & CTRL_SEG2) { + /* User selected SEG2 (LEFT, Plus only) for output. */ + bug_ctrl &= ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG1|CTRL_GLED); + bug_ctrl |= CTRL_SEG2; + } else if (val & CTRL_SEG1) { + /* User selected SEG1 (RIGHT) for output. */ + bug_ctrl &= ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG2|CTRL_GLED); + bug_ctrl |= CTRL_SEG1; + } else if (val & CTRL_GLED) { + /* User selected the GREEN LEDs for output. */ + bug_ctrl &= ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG2|CTRL_SEG1); + bug_ctrl |= CTRL_GLED; + } else { + /* User selected the RED LEDs for output. */ + bug_ctrl &= + ~(CTRL_SPCFG|CTRL_SPORT|CTRL_SEG2|CTRL_SEG1|CTRL_GLED); + } + } + + /* Update the UI with active settings. */ + pclog("BUGGER- ctrl %02x\n", bug_ctrl); + bug_setui(); +} + + +/* Handle a write to the data register. */ +static void +bug_wdata(uint8_t val) +{ + bug_data = val; + + if (bug_ctrl & CTRL_SPCFG) + bug_wspcfg(val); + else if (bug_ctrl & CTRL_SPORT) + bug_wsport(val); + else { + if (bug_ctrl & CTRL_SEG2) + bug_seg2 = val; + else if (bug_ctrl & CTRL_SEG1) + bug_seg1 = val; + else if (bug_ctrl & CTRL_GLED) + bug_ledg = val; + else + bug_ledr = val; + + pclog("BUGGER- data %02x\n", bug_data); + } + + /* Update the UI with active settings. */ + bug_setui(); +} + + +/* Reset the ISA BusBugger controller. */ +static void +bug_reset(void) +{ + /* Clear the data register. */ + bug_data = 0x00; + + /* Clear the RED and GREEN LEDs. */ + bug_ledr = 0x00; bug_ledg = 0x00; + + /* Clear both 7SEG displays. */ + bug_seg1 = 0x00; bug_seg2 = 0x00; + + /* Reset the control register (updates UI.) */ + bug_wctrl(CTRL_RESET); +} + + +/* Handle a WRITE operation to one of our registers. */ +static void +bug_write(uint16_t port, uint8_t val, void *priv) +{ + switch (port-BUGGER_ADDR) { + case BUG_CTRL: /* control register */ + if (val == CTRL_RESET) { + /* Perform a full reset. */ + bug_reset(); + } else if (bug_ctrl & CTRL_INIT) { + /* Only allow writes if initialized. */ + bug_wctrl(val); + } + break; + + case BUG_DATA: /* data register */ + if (bug_ctrl & CTRL_INIT) { + bug_wdata(val); + } + break; + + } +} + + +/* Handle a READ operation from one of our registers. */ +static uint8_t +bug_read(uint16_t port, void *priv) +{ + uint8_t ret = 0xff; + + if (bug_ctrl & CTRL_INIT) switch (port-BUGGER_ADDR) { + case BUG_CTRL: /* control register */ + ret = bug_ctrl; + break; + + case BUG_DATA: /* data register */ + if (bug_ctrl & CTRL_SPCFG) { + ret = bug_spcfg; + } else if (bug_ctrl & CTRL_SPORT) { + ret = 0x00; /* input not supported */ + } else { + /* Just read the DIP switch. */ + ret = bug_data; + } + break; + + default: + break; + } + + return(ret); +} + + +/* Initialize the ISA BusBugger emulator. */ +void +bugger_init(void) +{ + pclog("ISA Bus (de)Bugger, I/O=%04x\n", BUGGER_ADDR); + + /* Initialize local registers. */ + bug_reset(); + + io_sethandler(BUGGER_ADDR, BUGGER_ADDRLEN, + bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); +} + + +/* Remove the ISA BusBugger emulator from the system. */ +void +bugger_remove(void) +{ + io_removehandler(BUGGER_ADDR, BUGGER_ADDRLEN, + bug_read, NULL, NULL, bug_write, NULL, NULL, NULL); +} diff --git a/src/bugger.h b/src/bugger.h new file mode 100644 index 000000000..1d4dfb841 --- /dev/null +++ b/src/bugger.h @@ -0,0 +1,37 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the ISA Bus (de)Bugger expansion card + * sold as a DIY kit in the late 1980's in The Netherlands. + * This card was a assemble-yourself 8bit ISA addon card for + * PC and AT systems that had several tools to aid in low- + * level debugging (mostly for faulty BIOSes, bootloaders + * and system kernels...) + * + * Definitions for the BUGGER card. + * + * Version: @(#)bugger.h 1.0.3 2017/04/07 + * + * Author: Fred N. van Kempen, + * Copyright 1989-2017 Fred N. van Kempen. + */ +#ifndef BUGGER_H +# define BUGGER_H + + +/* I/O port range used. */ +#define BUGGER_ADDR 0x007a +#define BUGGER_ADDRLEN 4 + + +/* Functions. */ +extern void bugger_init(void); +extern void bugger_remove(void); + + +#endif /*BUGGER_H*/ diff --git a/src/buslogic.c b/src/buslogic.c deleted file mode 100644 index b45ea65e3..000000000 --- a/src/buslogic.c +++ /dev/null @@ -1,2643 +0,0 @@ -/* Copyright holders: SA1988 - see COPYING for more details -*/ -/*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/ - -/* Emulated SCSI controllers: - 0 - Adaptec AHA-154xB ISA; - 1 - BusLogic BT-542B ISA; - 2 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ - -#include -#include -#include -#include -#include - -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "dma.h" -#include "pic.h" -#include "pci.h" -#include "timer.h" - -#include "scsi.h" -#include "cdrom.h" - -#include "buslogic.h" - -#define BUSLOGIC_RESET_DURATION_NS UINT64_C(50000000) - -typedef struct __attribute__((packed)) -{ - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; - -#define ADDR_TO_U32(x) (((x).hi << 16) | ((x).mid << 8) | (x).lo & 0xFF) -#define U32_TO_ADDR(a, x) do {(a).hi = (x) >> 16; (a).mid = (x) >> 8; (a).lo = (x) & 0xFF;} while(0) - -// I/O Port interface -// READ Port x+0: STATUS -// WRITE Port x+0: CONTROL -// -// READ Port x+1: DATA -// WRITE Port x+1: COMMAND -// -// READ Port x+2: INTERRUPT STATUS -// WRITE Port x+2: (undefined?) -// -// R/W Port x+3: (undefined) - -// READ STATUS flags -#define STAT_STST 0x80 // self-test in progress -#define STAT_DFAIL 0x40 // internal diagnostic failure -#define STAT_INIT 0x20 // mailbox initialization required -#define STAT_IDLE 0x10 // HBA is idle -#define STAT_CDFULL 0x08 // Command/Data output port is full -#define STAT_DFULL 0x04 // Data input port is full -#define STAT_INVCMD 0x01 // Invalid command - -// READ INTERRUPT STATUS flags -#define INTR_ANY 0x80 // any interrupt -#define INTR_SRCD 0x08 // SCSI reset detected -#define INTR_HACC 0x04 // HA command complete -#define INTR_MBOA 0x02 // MBO empty -#define INTR_MBIF 0x01 // MBI full - -// WRITE CONTROL commands -#define CTRL_HRST 0x80 // Hard reset -#define CTRL_SRST 0x40 // Soft reset -#define CTRL_IRST 0x20 // interrupt reset -#define CTRL_SCRST 0x10 // SCSI bus reset - -// READ/WRITE DATA commands -#define CMD_NOP 0x00 // No operation -#define CMD_MBINIT 0x01 // mailbox initialization -#define CMD_START_SCSI 0x02 // Start SCSI command -#define CMD_INQUIRY 0x04 // Adapter inquiry -#define CMD_EMBOI 0x05 // enable Mailbox Out Interrupt -#define CMD_SELTIMEOUT 0x06 // Set SEL timeout -#define CMD_BUSON_TIME 0x07 // set bus-On time -#define CMD_BUSOFF_TIME 0x08 // set bus-off time -#define CMD_DMASPEED 0x09 // set ISA DMA speed -#define CMD_RETDEVS 0x0A // return installed devices -#define CMD_RETCONF 0x0B // return configuration data -#define CMD_TARGET 0x0C // set HBA to target mode -#define CMD_RETSETUP 0x0D // return setup data -#define CMD_ECHO 0x1F // ECHO command data - -#pragma pack(1) -/** - * Auto SCSI structure which is located - * in host adapter RAM and contains several - * configuration parameters. - */ -typedef struct __attribute__((packed)) AutoSCSIRam -{ - uint8_t aInternalSignature[2]; - uint8_t cbInformation; - uint8_t aHostAdaptertype[6]; - uint8_t uReserved1; - uint8_t fFloppyEnabled : 1; - uint8_t fFloppySecondary : 1; - uint8_t fLevelSensitiveInterrupt : 1; - unsigned char uReserved2 : 2; - unsigned char uSystemRAMAreForBIOS : 3; - unsigned char uDMAChannel : 7; - uint8_t fDMAAutoConfiguration : 1; - unsigned char uIrqChannel : 7; - uint8_t fIrqAutoConfiguration : 1; - uint8_t uDMATransferRate; - uint8_t uSCSIId; - uint8_t fLowByteTerminated : 1; - uint8_t fParityCheckingEnabled : 1; - uint8_t fHighByteTerminated : 1; - uint8_t fNoisyCablingEnvironment : 1; - uint8_t fFastSynchronousNeogtiation : 1; - uint8_t fBusResetEnabled : 1; - uint8_t fReserved3 : 1; - uint8_t fActiveNegotiationEnabled : 1; - uint8_t uBusOnDelay; - uint8_t uBusOffDelay; - uint8_t fHostAdapterBIOSEnabled : 1; - uint8_t fBIOSRedirectionOfInt19 : 1; - uint8_t fExtendedTranslation : 1; - uint8_t fMapRemovableAsFixed : 1; - uint8_t fReserved4 : 1; - uint8_t fBIOSSupportsMoreThan2Drives : 1; - uint8_t fBIOSInterruptMode : 1; - uint8_t fFlopticalSupport : 1; - uint16_t u16DeviceEnabledMask; - uint16_t u16WidePermittedMask; - uint16_t u16FastPermittedMask; - uint16_t u16SynchronousPermittedMask; - uint16_t u16DisconnectPermittedMask; - uint16_t u16SendStartUnitCommandMask; - uint16_t u16IgnoreInBIOSScanMask; - unsigned char uPCIInterruptPin : 2; - unsigned char uHostAdapterIoPortAddress : 2; - uint8_t fStrictRoundRobinMode : 1; - uint8_t fVesaBusSpeedGreaterThan33MHz : 1; - uint8_t fVesaBurstWrite : 1; - uint8_t fVesaBurstRead : 1; - uint16_t u16UltraPermittedMask; - uint32_t uReserved5; - uint8_t uReserved6; - uint8_t uAutoSCSIMaximumLUN; - uint8_t fReserved7 : 1; - uint8_t fSCAMDominant : 1; - uint8_t fSCAMenabled : 1; - uint8_t fSCAMLevel2 : 1; - unsigned char uReserved8 : 4; - uint8_t fInt13Extension : 1; - uint8_t fReserved9 : 1; - uint8_t fCDROMBoot : 1; - unsigned char uReserved10 : 5; - unsigned char uBootTargetId : 4; - unsigned char uBootChannel : 4; - uint8_t fForceBusDeviceScanningOrder : 1; - unsigned char uReserved11 : 7; - uint16_t u16NonTaggedToAlternateLunPermittedMask; - uint16_t u16RenegotiateSyncAfterCheckConditionMask; - uint8_t aReserved12[10]; - uint8_t aManufacturingDiagnostic[2]; - uint16_t u16Checksum; -} AutoSCSIRam; -#pragma pack() - -/** - * The local Ram. - */ -typedef union HostAdapterLocalRam -{ - /** Byte view. */ - uint8_t u8View[256]; - /** Structured view. */ - struct __attribute__((packed)) - { - /** Offset 0 - 63 is for BIOS. */ - uint8_t u8Bios[64]; - /** Auto SCSI structure. */ - AutoSCSIRam autoSCSIData; - } structured; -} HostAdapterLocalRam; - -/** Structure for the INQUIRE_SETUP_INFORMATION reply. */ -typedef struct __attribute__((packed)) ReplyInquireSetupInformationSynchronousValue -{ - uint8_t uOffset : 4; - uint8_t uTransferPeriod : 3; - uint8_t fSynchronous : 1; -}ReplyInquireSetupInformationSynchronousValue; - -typedef struct __attribute__((packed)) ReplyInquireSetupInformation -{ - uint8_t fSynchronousInitiationEnabled : 1; - uint8_t fParityCheckingEnabled : 1; - uint8_t uReserved1 : 6; - uint8_t uBusTransferRate; - uint8_t uPreemptTimeOnBus; - uint8_t uTimeOffBus; - uint8_t cMailbox; - addr24 MailboxAddress; - ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; - uint8_t uDisconnectPermittedId0To7; - uint8_t uSignature; - uint8_t uCharacterD; - uint8_t uHostBusType; - uint8_t uWideTransferPermittedId0To7; - uint8_t uWideTransfersActiveId0To7; - ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15[8]; - uint8_t uDisconnectPermittedId8To15; - uint8_t uReserved2; - uint8_t uWideTransferPermittedId8To15; - uint8_t uWideTransfersActiveId8To15; -} ReplyInquireSetupInformation; - -/** Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ -#pragma pack(1) -typedef struct __attribute__((packed)) ReplyInquireExtendedSetupInformation -{ - uint8_t uBusType; - uint8_t uBiosAddress; - uint16_t u16ScatterGatherLimit; - uint8_t cMailbox; - uint32_t uMailboxAddressBase; - uint8_t uReserved1 : 2; - uint8_t fFastEISA : 1; - uint8_t uReserved2 : 3; - uint8_t fLevelSensitiveInterrupt : 1; - uint8_t uReserved3 : 1; - uint8_t aFirmwareRevision[3]; - uint8_t fHostWideSCSI : 1; - uint8_t fHostDifferentialSCSI : 1; - uint8_t fHostSupportsSCAM : 1; - uint8_t fHostUltraSCSI : 1; - uint8_t fHostSmartTermination : 1; - uint8_t uReserved4 : 3; -} ReplyInquireExtendedSetupInformation; -#pragma pack() - -typedef struct __attribute__((packed)) MailboxInit_t -{ - uint8_t Count; - addr24 Address; -} MailboxInit_t; - -#pragma pack(1) -typedef struct __attribute__((packed)) MailboxInitExtended_t -{ - uint8_t Count; - uint32_t Address; -} MailboxInitExtended_t; -#pragma pack() - -/////////////////////////////////////////////////////////////////////////////// -// -// Mailbox Definitions -// -// -/////////////////////////////////////////////////////////////////////////////// - -// -// Mailbox Out -// -// -// MBO Command Values -// - -#define MBO_FREE 0x00 -#define MBO_START 0x01 -#define MBO_ABORT 0x02 - -// -// Mailbox In -// -// -// MBI Status Values -// - -#define MBI_FREE 0x00 -#define MBI_SUCCESS 0x01 -#define MBI_ABORT 0x02 -#define MBI_NOT_FOUND 0x03 -#define MBI_ERROR 0x04 - -typedef struct __attribute__((packed)) Mailbox_t -{ - uint8_t CmdStatus; - addr24 CCBPointer; -} Mailbox_t; - -typedef struct __attribute__((packed)) Mailbox32_t -{ - uint32_t CCBPointer; - union - { - struct - { - uint8_t Reserved[3]; - uint8_t ActionCode; - } out; - struct - { - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Reserved; - uint8_t CompletionCode; - } in; - } u; -} Mailbox32_t; - -/////////////////////////////////////////////////////////////////////////////// -// -// CCB - Buslogic SCSI Command Control Block -// -// The CCB is a superset of the CDB (Command Descriptor Block) -// and specifies detailed information about a SCSI command. -// -/////////////////////////////////////////////////////////////////////////////// - -// -// Byte 0 Command Control Block Operation Code -// - -#define SCSI_INITIATOR_COMMAND 0x00 -#define TARGET_MODE_COMMAND 0x01 -#define SCATTER_GATHER_COMMAND 0x02 -#define SCSI_INITIATOR_COMMAND_RES 0x03 -#define SCATTER_GATHER_COMMAND_RES 0x04 -#define BUS_RESET 0x81 - -// -// Byte 1 Address and Direction Control -// - -#define CCB_TARGET_ID_SHIFT 0x06 // CCB Op Code = 00, 02 -#define CCB_INITIATOR_ID_SHIFT 0x06 // CCB Op Code = 01 -#define CCB_DATA_XFER_IN 0x01 -#define CCB_DATA_XFER_OUT 0x02 -#define CCB_LUN_MASK 0x07 // Logical Unit Number - -// -// Byte 2 SCSI_Command_Length - Length of SCSI CDB -// -// Byte 3 Request Sense Allocation Length -// - -#define FOURTEEN_BYTES 0x00 // Request Sense Buffer size -#define NO_AUTO_REQUEST_SENSE 0x01 // No Request Sense Buffer - -// -// Bytes 4, 5 and 6 Data Length // Data transfer byte count -// -// Bytes 7, 8 and 9 Data Pointer // SGD List or Data Buffer -// -// Bytes 10, 11 and 12 Link Pointer // Next CCB in Linked List -// -// Byte 13 Command Link ID // TBD (I don't know yet) -// -// Byte 14 Host Status // Host Adapter status -// - -#define CCB_COMPLETE 0x00 // CCB completed without error -#define CCB_LINKED_COMPLETE 0x0A // Linked command completed -#define CCB_LINKED_COMPLETE_INT 0x0B // Linked complete with interrupt -#define CCB_SELECTION_TIMEOUT 0x11 // Set SCSI selection timed out -#define CCB_DATA_OVER_UNDER_RUN 0x12 -#define CCB_UNEXPECTED_BUS_FREE 0x13 // Target dropped SCSI BSY -#define CCB_PHASE_SEQUENCE_FAIL 0x14 // Target bus phase sequence failure -#define CCB_BAD_MBO_COMMAND 0x15 // MBO command not 0, 1 or 2 -#define CCB_INVALID_OP_CODE 0x16 // CCB invalid operation code -#define CCB_BAD_LINKED_LUN 0x17 // Linked CCB LUN different from first -#define CCB_INVALID_DIRECTION 0x18 // Invalid target direction -#define CCB_DUPLICATE_CCB 0x19 // Duplicate CCB -#define CCB_INVALID_CCB 0x1A // Invalid CCB - bad parameter - -// -// Byte 15 Target Status -// -// See scsi.h files for these statuses. -// - -// -// Bytes 16 and 17 Reserved (must be 0) -// - -// -// Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block -// - -typedef struct __attribute__((packed)) CCB32 -{ - uint8_t Opcode; - uint8_t Reserved1:3; - uint8_t ControlByte:2; - uint8_t TagQueued:1; - uint8_t QueueTag:2; - uint8_t CdbLength; - uint8_t RequestSenseLength; - uint32_t DataLength; - uint32_t DataPointer; - uint8_t Reserved2[2]; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Id; - uint8_t Lun:5; - uint8_t LegacyTagEnable:1; - uint8_t LegacyQueueTag:2; - uint8_t Cdb[12]; - uint8_t Reserved3[6]; - uint32_t SensePointer; -} CCB32; - -typedef struct __attribute__((packed)) CCB -{ - uint8_t Opcode; - uint8_t Lun:3; - uint8_t ControlByte:2; - uint8_t Id:3; - uint8_t CdbLength; - uint8_t RequestSenseLength; - addr24 DataLength; - addr24 DataPointer; - addr24 LinkPointer; - uint8_t LinkId; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Reserved[2]; - uint8_t Cdb[12]; -} CCB; - -typedef struct __attribute__((packed)) CCBC -{ - uint8_t Opcode; - uint8_t Pad1:3; - uint8_t ControlByte:2; - uint8_t Pad2:3; - uint8_t CdbLength; - uint8_t RequestSenseLength; - uint8_t Pad3[10]; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t Pad4[2]; - uint8_t Cdb[12]; -} CCBC; - -typedef union __attribute__((packed)) CCBU -{ - CCB32 new; - CCB old; - CCBC common; -} CCBU; - -/////////////////////////////////////////////////////////////////////////////// -// -// Scatter/Gather Segment List Definitions -// -/////////////////////////////////////////////////////////////////////////////// - -// -// Adapter limits -// - -#define MAX_SG_DESCRIPTORS (scsi_model ? 32 : 17) - -typedef struct __attribute__((packed)) SGE32 -{ - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; - -typedef struct __attribute__((packed)) SGE -{ - addr24 Segment; - addr24 SegmentPointer; -} SGE; - -typedef struct __attribute__((packed)) BuslogicRequests_t -{ - CCBU CmdBlock; - uint8_t *RequestSenseBuffer; - uint32_t CCBPointer; - int Is24bit; - uint8_t TargetID; - uint8_t LUN; - uint8_t HostStatus; - uint8_t TargetStatus; - uint8_t MailboxCompletionCode; -} BuslogicRequests_t; - -typedef struct __attribute__((packed)) Buslogic_t -{ - rom_t bios; - int UseLocalRam; - int StrictRoundRobinMode; - int ExtendedLUNCCBFormat; - HostAdapterLocalRam LocalRam; - BuslogicRequests_t BuslogicRequests; - uint8_t Status; - uint8_t Interrupt; - uint8_t Geometry; - uint8_t Control; - uint8_t Command; - uint8_t CmdBuf[53]; - uint8_t CmdParam; - uint8_t CmdParamLeft; - uint8_t DataBuf[64]; - uint8_t DataReply; - uint8_t DataReplyLeft; - uint32_t MailboxCount; - uint32_t MailboxOutAddr; - uint32_t MailboxOutPosCur; - uint32_t MailboxInAddr; - uint32_t MailboxInPosCur; - int Base; - int PCIBase; - int MMIOBase; - int Irq; - int DmaChannel; - int IrqEnabled; - int Mbx24bit; - int MailboxOutInterrupts; - int MbiActive[256]; - int PendingInterrupt; - int Lock; - mem_mapping_t mmio_mapping; -} Buslogic_t; - -int scsi_model = 1; - -int BuslogicResetCallback = 0; -int BuslogicCallback = 0; - -int BuslogicInOperation = 0; - -/** Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ -typedef struct __attribute__((packed)) BuslogicPCIInformation_t -{ - uint8_t IsaIOPort; - uint8_t IRQ; - unsigned char LowByteTerminated:1; - unsigned char HighByteTerminated:1; - unsigned char uReserved:2; /* Reserved. */ - unsigned char JP1:1; /* Whatever that means. */ - unsigned char JP2:1; /* Whatever that means. */ - unsigned char JP3:1; /* Whatever that means. */ - /** Whether the provided info is valid. */ - unsigned char InformationIsValid:1; - uint8_t uReserved2; /* Reserved. */ -} BuslogicPCIInformation_t; - -static void BuslogicStartMailbox(Buslogic_t *Buslogic); - -int buslogic_do_log = 0; - -void BuslogicLog(const char *format, ...) -{ -#ifdef ENABLE_BUSLOGIC_LOG - if (buslogic_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -static int BuslogicIsPCI() -{ - if (PCI && (scsi_model == 2)) - { - return 1; - } - else - { - return 0; - } -} - -static void BuslogicClearInterrupt(Buslogic_t *Buslogic) -{ - BuslogicLog("Buslogic: Lowering Interrupt 0x%02X\n", Buslogic->Interrupt); - Buslogic->Interrupt = 0; - BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); - picintc(1 << Buslogic->Irq); - if (Buslogic->PendingInterrupt) - { - Buslogic->Interrupt = Buslogic->PendingInterrupt; - BuslogicLog("Buslogic: Raising Interrupt 0x%02X (Pending)\n", Buslogic->Interrupt); - if (Buslogic->MailboxOutInterrupts || !(Buslogic->Interrupt & INTR_MBOA)) - { - if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); - } - Buslogic->PendingInterrupt = 0; - } -} - -static void BuslogicLocalRam(Buslogic_t *Buslogic) -{ - /* - * These values are mostly from what I think is right - * looking at the dmesg output from a Linux guest inside - * a VMware server VM. - * - * So they don't have to be right :) - */ - memset(Buslogic->LocalRam.u8View, 0, sizeof(HostAdapterLocalRam)); - Buslogic->LocalRam.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; - Buslogic->LocalRam.structured.autoSCSIData.fParityCheckingEnabled = 1; - Buslogic->LocalRam.structured.autoSCSIData.fExtendedTranslation = 1; /* Same as in geometry register. */ - Buslogic->LocalRam.structured.autoSCSIData.u16DeviceEnabledMask = UINT16_MAX; /* All enabled. Maybe mask out non present devices? */ - Buslogic->LocalRam.structured.autoSCSIData.u16WidePermittedMask = UINT16_MAX; - Buslogic->LocalRam.structured.autoSCSIData.u16FastPermittedMask = UINT16_MAX; - Buslogic->LocalRam.structured.autoSCSIData.u16SynchronousPermittedMask = UINT16_MAX; - Buslogic->LocalRam.structured.autoSCSIData.u16DisconnectPermittedMask = UINT16_MAX; - Buslogic->LocalRam.structured.autoSCSIData.fStrictRoundRobinMode = Buslogic->StrictRoundRobinMode; - Buslogic->LocalRam.structured.autoSCSIData.u16UltraPermittedMask = UINT16_MAX; - /** @todo calculate checksum? */ -} - -static Buslogic_t *BuslogicResetDevice; - -static void BuslogicReset(Buslogic_t *Buslogic) -{ - BuslogicCallback = 0; - BuslogicResetCallback = 0; - Buslogic->Status = STAT_IDLE | STAT_INIT; - Buslogic->Geometry = 0x80; - Buslogic->Command = 0xFF; - Buslogic->CmdParam = 0; - Buslogic->CmdParamLeft = 0; - Buslogic->IrqEnabled = 1; - Buslogic->StrictRoundRobinMode = 0; - Buslogic->ExtendedLUNCCBFormat = 0; - Buslogic->MailboxOutPosCur = 0; - Buslogic->MailboxInPosCur = 0; - Buslogic->MailboxOutInterrupts = 0; - Buslogic->PendingInterrupt = 0; - Buslogic->Lock = 0; - BuslogicInOperation = 0; - - BuslogicClearInterrupt(Buslogic); - - BuslogicLocalRam(Buslogic); -} - -void BuslogicSoftReset() -{ - if (BuslogicResetDevice != NULL) - { - BuslogicReset(BuslogicResetDevice); - } -} - -static void BuslogicResetControl(Buslogic_t *Buslogic, uint8_t Reset) -{ - BuslogicReset(Buslogic); - if (Reset) - { - Buslogic->Status |= STAT_STST; - Buslogic->Status &= ~STAT_IDLE; - } - BuslogicResetCallback = BUSLOGIC_RESET_DURATION_NS * TIMER_USEC; -} - -static void BuslogicCommandComplete(Buslogic_t *Buslogic) -{ - Buslogic->DataReply = 0; - Buslogic->Status |= STAT_IDLE; - - if (Buslogic->Command != 0x02) - { - Buslogic->Status &= ~STAT_DFULL; - Buslogic->Interrupt = (INTR_ANY | INTR_HACC); - BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); - if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); - } - - Buslogic->Command = 0xFF; - Buslogic->CmdParam = 0; -} - -static void BuslogicRaiseInterrupt(Buslogic_t *Buslogic, uint8_t Interrupt) -{ - if (Buslogic->Interrupt & INTR_HACC) - { - BuslogicLog("Pending IRQ\n"); - Buslogic->PendingInterrupt = Interrupt; - } - else - { - Buslogic->Interrupt = Interrupt; - BuslogicLog("Raising IRQ %i\n", Buslogic->Irq); - if (Buslogic->IrqEnabled) picint(1 << Buslogic->Irq); - } -} - -static void BuslogicMailboxInSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, CCBU *CmdBlock, - uint8_t HostStatus, uint8_t TargetStatus, uint8_t MailboxCompletionCode) -{ - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - - BuslogicRequests->CCBPointer = CCBPointer; - memcpy(&(BuslogicRequests->CmdBlock), CmdBlock, sizeof(CCB32)); - BuslogicRequests->Is24bit = Buslogic->Mbx24bit; - BuslogicRequests->HostStatus = HostStatus; - BuslogicRequests->TargetStatus = TargetStatus; - BuslogicRequests->MailboxCompletionCode = MailboxCompletionCode; - - BuslogicLog("Mailbox in setup\n"); - - BuslogicInOperation = 2; -} - -static uint32_t BuslogicMailboxInRead(Buslogic_t *Buslogic, uint8_t *CompletionCode) -{ - Mailbox32_t TempMailbox32; - Mailbox_t TempMailboxIn; - - uint32_t Incoming = 0; - - Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); - - if (Buslogic->Mbx24bit) - { - DMAPageRead(Incoming, &TempMailboxIn, sizeof(Mailbox_t)); - *CompletionCode = TempMailboxIn.CmdStatus; - } - else - { - DMAPageRead(Incoming, &TempMailbox32, sizeof(Mailbox32_t)); - *CompletionCode = TempMailbox32.u.in.CompletionCode; - } - - return Incoming; -} - -static void BuslogicMailboxInAdvance(Buslogic_t *Buslogic) -{ - Buslogic->MailboxInPosCur = (Buslogic->MailboxInPosCur + 1) % Buslogic->MailboxCount; -} - -static void BuslogicMailboxIn(Buslogic_t *Buslogic) -{ - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - - uint32_t CCBPointer = BuslogicRequests->CCBPointer; - CCBU *CmdBlock = &(BuslogicRequests->CmdBlock); - uint8_t HostStatus = BuslogicRequests->HostStatus; - uint8_t TargetStatus = BuslogicRequests->TargetStatus; - uint8_t MailboxCompletionCode = BuslogicRequests->MailboxCompletionCode; - - Mailbox32_t Mailbox32; - Mailbox_t MailboxIn; - - Mailbox32_t TempMailbox32; - Mailbox_t TempMailboxIn; - - Mailbox32.CCBPointer = CCBPointer; - Mailbox32.u.in.HostStatus = HostStatus; - Mailbox32.u.in.TargetStatus = TargetStatus; - Mailbox32.u.in.CompletionCode = MailboxCompletionCode; - - uint32_t Incoming = Buslogic->MailboxInAddr + (Buslogic->MailboxInPosCur * (Buslogic->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); - - if (MailboxCompletionCode != MBI_NOT_FOUND) - { - CmdBlock->common.HostStatus = HostStatus; - CmdBlock->common.TargetStatus = TargetStatus; - - //Rewrite the CCB up to the CDB. - BuslogicLog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); - DMAPageWrite(CCBPointer, CmdBlock, offsetof(CCBC, Cdb)); - } - else - { - BuslogicLog("Mailbox not found!\n"); - } - - BuslogicLog("Host Status 0x%02X, Target Status 0x%02X\n", HostStatus, TargetStatus); - - if (Buslogic->Mbx24bit) - { - MailboxIn.CmdStatus = Mailbox32.u.in.CompletionCode; - U32_TO_ADDR(MailboxIn.CCBPointer, Mailbox32.CCBPointer); - BuslogicLog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); - - DMAPageWrite(Incoming, &MailboxIn, sizeof(Mailbox_t)); - BuslogicLog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); - } - else - { - BuslogicLog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); - - DMAPageWrite(Incoming, &Mailbox32, sizeof(Mailbox32_t)); - BuslogicLog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); - } - - Buslogic->MailboxInPosCur++; - if (Buslogic->MailboxInPosCur >= Buslogic->MailboxCount) - Buslogic->MailboxInPosCur = 0; - - BuslogicRaiseInterrupt(Buslogic, INTR_MBIF | INTR_ANY); - - BuslogicInOperation = 0; -} - -static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) -{ - if (Is24bit) - { - uint32_t i; - SGE SGE24[MAX_SG_DESCRIPTORS]; - - DMAPageRead(SGList, &SGE24, Entries * sizeof(SGE)); - - for (i=0;iCmdBlock.old.DataPointer); - DataLength = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength); - } - else - { - DataPointer = BuslogicRequests->CmdBlock.new.DataPointer; - DataLength = BuslogicRequests->CmdBlock.new.DataLength; - } - - BuslogicLog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); - - if ((BuslogicRequests->CmdBlock.common.ControlByte != 0x03) && DataLength) - { - if (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || - BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) - { - uint32_t ScatterGatherRead; - uint32_t ScatterEntry; - SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherLeft = DataLength / ScatterGatherEntryLength; - uint32_t ScatterGatherAddrCurrent = DataPointer; - uint32_t DataToTransfer = 0; - - do - { - ScatterGatherRead = (ScatterGatherLeft < ELEMENTS(ScatterGatherBuffer)) - ? ScatterGatherLeft : ELEMENTS(ScatterGatherBuffer); - - ScatterGatherLeft -= ScatterGatherRead; - - BuslogicReadSGEntries(Is24bit, ScatterGatherAddrCurrent, ScatterGatherRead, ScatterGatherBuffer); - - for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) - { - uint32_t Address; - - BuslogicLog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); - - Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; - DataToTransfer += ScatterGatherBuffer[ScatterEntry].Segment; - - BuslogicLog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); - } - - ScatterGatherAddrCurrent += ScatterGatherRead * ScatterGatherEntryLength; - } while (ScatterGatherLeft > 0); - - BuslogicLog("Data to transfer (S/G) %d\n", DataToTransfer); - - SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = DataToTransfer; - - //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without - //checking its length, so do this procedure for both no read/write commands. - if ((BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || (BuslogicRequests->CmdBlock.common.ControlByte == 0x00)) - { - ScatterGatherLeft = DataLength / ScatterGatherEntryLength; - ScatterGatherAddrCurrent = DataPointer; - - do - { - ScatterGatherRead = (ScatterGatherLeft < ELEMENTS(ScatterGatherBuffer)) - ? ScatterGatherLeft : ELEMENTS(ScatterGatherBuffer); - - ScatterGatherLeft -= ScatterGatherRead; - - BuslogicReadSGEntries(Is24bit, ScatterGatherAddrCurrent, ScatterGatherRead, ScatterGatherBuffer); - - for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) - { - uint32_t Address; - - BuslogicLog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); - - Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; - DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - - BuslogicLog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); - - DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); - sg_buffer_pos += DataToTransfer; - } - - ScatterGatherAddrCurrent += ScatterGatherRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); - } while (ScatterGatherLeft > 0); - } - } - else if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || - BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) - { - uint32_t Address = DataPointer; - SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength = DataLength; - - if (DataLength > 0) - { - DMAPageRead(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); - } - } - } -} - -void BuslogicDataBufferFree(BuslogicRequests_t *BuslogicRequests) -{ - uint32_t DataPointer = 0; - uint32_t DataLength = 0; - - uint32_t sg_buffer_pos = 0; - - uint32_t transfer_length = 0; - - if (BuslogicRequests->Is24bit) - { - DataPointer = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataPointer); - DataLength = ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength); - } - else - { - DataPointer = BuslogicRequests->CmdBlock.new.DataPointer; - DataLength = BuslogicRequests->CmdBlock.new.DataLength; - } - - /* if (DataLength > SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) - { - DataLength = SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; - } */ - - if ((DataLength != 0) && (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) - { - BuslogicLog("Data length not 0 with TEST UNIT READY: %i (%i)\n", DataLength, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength); - } - - if (BuslogicRequests->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) - { - DataLength = 0; - } - - BuslogicLog("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); - - //If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without - //checking its length, so do this procedure for both read/write commands. - if ((DataLength > 0) && - ((BuslogicRequests->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || - (BuslogicRequests->CmdBlock.common.ControlByte == 0x00))) - { - if ((BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || - (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) - { - uint32_t ScatterGatherRead; - uint32_t ScatterEntry; - SGE32 ScatterGatherBuffer[MAX_SG_DESCRIPTORS]; - uint32_t ScatterGatherEntrySize = (BuslogicRequests->Is24bit ? sizeof(SGE) : sizeof(SGE32)); - uint32_t ScatterGatherLeft = DataLength / ScatterGatherEntrySize; - // uint32_t ScatterGatherLength = (ScatterGatherLeft * ScatterGatherEntrySize); - uint32_t ScatterGatherAddrCurrent = DataPointer; - - do - { - ScatterGatherRead = (ScatterGatherLeft < ELEMENTS(ScatterGatherBuffer)) - ? ScatterGatherLeft : ELEMENTS(ScatterGatherBuffer); - - ScatterGatherLeft -= ScatterGatherRead; - - BuslogicReadSGEntries(BuslogicRequests->Is24bit, ScatterGatherAddrCurrent, ScatterGatherRead, ScatterGatherBuffer); - - for (ScatterEntry = 0; ScatterEntry < ScatterGatherRead; ScatterEntry++) - { - uint32_t Address; - uint32_t DataToTransfer; - - BuslogicLog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); - - Address = ScatterGatherBuffer[ScatterEntry].SegmentPointer; - DataToTransfer = ScatterGatherBuffer[ScatterEntry].Segment; - - BuslogicLog("BusLogic S/G: Writing %i bytes at %08X\n", DataToTransfer, Address); - - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); - sg_buffer_pos += DataToTransfer; - } - - ScatterGatherAddrCurrent += (ScatterGatherRead * ScatterGatherEntrySize); - } while (ScatterGatherLeft > 0); - } - else if (BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || - BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) - { - uint32_t Address = DataPointer; - - BuslogicLog("BusLogic DMA: Writing %i bytes at %08X\n", DataLength, Address); - DMAPageWrite(Address, SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].CmdBuffer, DataLength); - } - } - - if ((BuslogicRequests->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || (BuslogicRequests->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) - { - uint32_t Residual; - - /* Should be 0 when scatter/gather? */ - if (DataLength >= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength) - { - Residual = DataLength; - Residual -= SCSIDevices[BuslogicRequests->TargetID][BuslogicRequests->LUN].InitLength; - } - else - { - Residual = 0; - } - - if (BuslogicRequests->Is24bit) - { - U32_TO_ADDR(BuslogicRequests->CmdBlock.old.DataLength, Residual); - BuslogicLog("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(BuslogicRequests->CmdBlock.old.DataLength)); - } - else - { - BuslogicRequests->CmdBlock.new.DataLength = Residual; - BuslogicLog("32-bit Residual data length for reading: %d\n", BuslogicRequests->CmdBlock.new.DataLength); - } - } -} - -uint8_t BuslogicRead(uint16_t Port, void *p) -{ - Buslogic_t *Buslogic = (Buslogic_t *)p; - uint8_t Temp; - - switch (Port & 3) - { - case 0: - Temp = Buslogic->Status; -#if 0 - if (Buslogic->Status & STAT_STST) - { - Buslogic->Status &= ~STAT_STST; - Buslogic->Status |= STAT_IDLE; - - if (BuslogicResetCallback <= 0) - { - Temp = Buslogic->Status; - BuslogicResetCallback; - } - } -#endif - break; - - case 1: - if (Buslogic->UseLocalRam) - Temp = Buslogic->LocalRam.u8View[Buslogic->DataReply]; - else - Temp = Buslogic->DataBuf[Buslogic->DataReply]; - if (Buslogic->DataReplyLeft) - { - Buslogic->DataReply++; - Buslogic->DataReplyLeft--; - if (!Buslogic->DataReplyLeft) - { - BuslogicCommandComplete(Buslogic); - } - } - break; - - case 2: - Temp = Buslogic->Interrupt; - break; - - case 3: - Temp = Buslogic->Geometry; - break; - } - - if (Port < 0x1000) - { - BuslogicLog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", Port, Temp); - } - return Temp; -} - -uint16_t BuslogicReadW(uint16_t Port, void *p) -{ - return BuslogicRead(Port, p); -} - -uint32_t BuslogicReadL(uint16_t Port, void *p) -{ - return BuslogicRead(Port, p); -} - -int buslogic_scsi_drive_is_cdrom(uint8_t id, uint8_t lun) -{ - if (lun > 7) - { - return 0; - } - - if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) - { - return 0; - } - else - { - if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) - { - return 1; - } - else - { - return 0; - } - } -} - -void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); -void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); - -void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) -{ - int i = 0; - - uint8_t j = 0; - - uint8_t max_id = scsi_model ? 16 : 8; - - Buslogic_t *Buslogic = (Buslogic_t *)p; - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - BuslogicLog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); - - switch (Port & 3) - { - case 0: - if ((Val & CTRL_HRST) || (Val & CTRL_SRST)) - { - uint8_t Reset = !!(Val & CTRL_HRST); - BuslogicResetControl(Buslogic, Reset); - break; - } - - if (Val & CTRL_IRST) - { - BuslogicClearInterrupt(Buslogic); - } - break; - - case 1: - /* Fast path for the mailbox execution command. */ - if ((Val == 0x02) && (Buslogic->Command == 0xFF)) - { - /* If there are no mailboxes configured, don't even try to do anything. */ - if (Buslogic->MailboxCount) - { - if (!BuslogicCallback) - { - BuslogicCallback = 50 * SCSI_TIME; - } - } - return; - } - - if (Buslogic->Command == 0xFF) - { - Buslogic->Command = Val; - Buslogic->CmdParam = 0; - - Buslogic->Status &= ~(STAT_INVCMD | STAT_IDLE); - BuslogicLog("Buslogic: Operation Code 0x%02X\n", Val); - switch (Buslogic->Command) - { - case 0x00: - case 0x04: - case 0x0A: - case 0x0B: - case 0x20: - case 0x23: - case 0x84: - case 0x85: - Buslogic->CmdParamLeft = 0; - break; - - case 0x05: - case 0x07: - case 0x08: - case 0x09: - case 0x0D: - case 0x1F: - case 0x21: - case 0x24: - case 0x25: - Buslogic->CmdParamLeft = 1; - break; - - case 0x8B: - case 0x8D: - case 0x8F: - case 0x96: - Buslogic->CmdParamLeft = scsi_model ? 1 : 0; - break; - - case 0x91: - Buslogic->CmdParamLeft = 2; - break; - - case 0x1C: - case 0x1D: - Buslogic->CmdParamLeft = 3; - break; - - case 0x06: - Buslogic->CmdParamLeft = 4; - break; - - case 0x01: - Buslogic->CmdParamLeft = sizeof(MailboxInit_t); - break; - - case 0x81: - BuslogicLog("Command 0x81 on %s\n", scsi_model ? "BusLogic" : "Adaptec"); - Buslogic->CmdParamLeft = scsi_model ? sizeof(MailboxInitExtended_t) : 0; - break; - - case 0x29: - Buslogic->CmdParamLeft = scsi_model ? 0 : 2; - break; - - case 0x86: //Valid only for PCI - Buslogic->CmdParamLeft = 0; - break; - - case 0x8C: - Buslogic->CmdParamLeft = scsi_model ? 1 : 0; - break; - - case 0x95: //Valid only for PCI - Buslogic->CmdParamLeft = BuslogicIsPCI() ? 1 : 0; - break; - - case 0x28: - Buslogic->CmdParamLeft = 0; - break; - } - } - else - { - Buslogic->CmdBuf[Buslogic->CmdParam] = Val; - Buslogic->CmdParam++; - Buslogic->CmdParamLeft--; - } - - if (!Buslogic->CmdParamLeft) - { - BuslogicLog("Running Operation Code 0x%02X\n", Buslogic->Command); - switch (Buslogic->Command) - { - case 0x00: - Buslogic->DataReplyLeft = 0; - break; - - case 0x01: - { - Buslogic->Mbx24bit = 1; - - MailboxInit_t *MailboxInit = (MailboxInit_t *)Buslogic->CmdBuf; - - Buslogic->MailboxCount = MailboxInit->Count; - Buslogic->MailboxOutAddr = ADDR_TO_U32(MailboxInit->Address); - Buslogic->MailboxInAddr = Buslogic->MailboxOutAddr + (Buslogic->MailboxCount * sizeof(Mailbox_t)); - - BuslogicLog("Buslogic Initialize Mailbox Command\n"); - BuslogicLog("Mailbox Out Address=0x%08X\n", Buslogic->MailboxOutAddr); - BuslogicLog("Mailbox In Address=0x%08X\n", Buslogic->MailboxInAddr); - BuslogicLog("Initialized Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, ADDR_TO_U32(MailboxInit->Address)); - - Buslogic->Status &= ~STAT_INIT; - Buslogic->DataReplyLeft = 0; - } - break; - - case 0x04: - Buslogic->DataBuf[0] = 0x41; - Buslogic->DataBuf[1] = scsi_model ? 0x41 : 0x30; - Buslogic->DataBuf[2] = '5'; - Buslogic->DataBuf[3] = '0'; - Buslogic->DataReplyLeft = 4; - break; - - case 0x05: - if (Buslogic->CmdBuf[0] <= 1) - { - Buslogic->MailboxOutInterrupts = Buslogic->CmdBuf[0]; - BuslogicLog("Mailbox out interrupts: %s\n", Buslogic->MailboxOutInterrupts ? "ON" : "OFF"); - } - else - { - Buslogic->Status |= STAT_INVCMD; - } - Buslogic->DataReplyLeft = 0; - break; - - case 0x06: - Buslogic->DataReplyLeft = 0; - break; - - case 0x07: - Buslogic->DataReplyLeft = 0; - Buslogic->LocalRam.structured.autoSCSIData.uBusOnDelay = Buslogic->CmdBuf[0]; - BuslogicLog("Bus-on time: %d\n", Buslogic->CmdBuf[0]); - break; - - case 0x08: - Buslogic->DataReplyLeft = 0; - Buslogic->LocalRam.structured.autoSCSIData.uBusOffDelay = Buslogic->CmdBuf[0]; - BuslogicLog("Bus-off time: %d\n", Buslogic->CmdBuf[0]); - break; - - case 0x09: - Buslogic->DataReplyLeft = 0; - Buslogic->LocalRam.structured.autoSCSIData.uDMATransferRate = Buslogic->CmdBuf[0]; - BuslogicLog("DMA transfer rate: %02X\n", Buslogic->CmdBuf[0]); - break; - - case 0x0A: - memset(Buslogic->DataBuf, 0, 8); - for (i = 0; i < 7; i++) - { - for (j = 0; j < 8; j++) - { - if (buslogic_scsi_drive_is_cdrom(i, j)) - Buslogic->DataBuf[i] = 1; - } - } - Buslogic->DataBuf[7] = 0; - Buslogic->DataReplyLeft = 8; - break; - - case 0x0B: - Buslogic->DataBuf[0] = (1 << Buslogic->DmaChannel); - Buslogic->DataBuf[1] = (1 << (Buslogic->Irq - 9)); - Buslogic->DataBuf[2] = 7; - Buslogic->DataReplyLeft = 3; - break; - - case 0x0D: - { - Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; - - ReplyInquireSetupInformation *Reply = (ReplyInquireSetupInformation *)Buslogic->DataBuf; - memset(Reply, 0, sizeof(ReplyInquireSetupInformation)); - - Reply->fSynchronousInitiationEnabled = 1; - Reply->fParityCheckingEnabled = 1; - Reply->cMailbox = Buslogic->MailboxCount; - U32_TO_ADDR(Reply->MailboxAddress, Buslogic->MailboxOutAddr); - - if (scsi_model) - { - Reply->uSignature = 'B'; - /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too - * friendly with Adaptec hardware and upsetting the HBA state. - */ - Reply->uCharacterD = 'D'; /* BusLogic model. */ - Reply->uHostBusType = BuslogicIsPCI() ? 'F' : 'A'; /* ISA bus. */ - } - - BuslogicLog("Return Setup Information: %d\n", Buslogic->CmdBuf[0]); - } - break; - - case 0x23: - if (scsi_model) - { - memset(Buslogic->DataBuf, 0, 8); - for (i = 8; i < max_id; i++) - { - for (i = 0; j < 8; j++) - { - if (buslogic_scsi_drive_is_cdrom(i, j)) - Buslogic->DataBuf[i] = 1; - } - } - Buslogic->DataReplyLeft = 8; - } - else - { - Buslogic->Status |= STAT_INVCMD; - Buslogic->DataReplyLeft = 0; - } - break; - - case 0x1C: - { - uint32_t FIFOBuf; - addr24 Address; - - Buslogic->DataReplyLeft = 0; - Address.hi = Buslogic->CmdBuf[0]; - Address.mid = Buslogic->CmdBuf[1]; - Address.lo = Buslogic->CmdBuf[2]; - FIFOBuf = ADDR_TO_U32(Address); - DMAPageRead(FIFOBuf, &Buslogic->LocalRam.u8View[64], 64); - } - break; - - case 0x1D: - { - uint32_t FIFOBuf; - addr24 Address; - - Buslogic->DataReplyLeft = 0; - Address.hi = Buslogic->CmdBuf[0]; - Address.mid = Buslogic->CmdBuf[1]; - Address.lo = Buslogic->CmdBuf[2]; - FIFOBuf = ADDR_TO_U32(Address); - BuslogicLog("Buslogic FIFO: Writing 64 bytes at %08X\n", FIFOBuf); - DMAPageWrite(FIFOBuf, &Buslogic->LocalRam.u8View[64], 64); - } - break; - - case 0x1F: - Buslogic->DataBuf[0] = Buslogic->CmdBuf[0]; - Buslogic->DataReplyLeft = 1; - break; - - case 0x20: - Buslogic->DataReplyLeft = 0; - if (scsi_model) - { - BuslogicResetControl(Buslogic, 1); - } - else - { - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x21: - if (Buslogic->CmdParam == 1) - Buslogic->CmdParamLeft = Buslogic->CmdBuf[0]; - - Buslogic->DataReplyLeft = 0; - break; - - case 0x24: - { - uint16_t TargetsPresentMask = 0; - - for (i = 0; i < max_id; i++) - { - for (j = 0; j < 8; j++) - { - if (SCSIDevices[i][j].LunType == SCSI_CDROM) - TargetsPresentMask |= (1 << i); - } - } - Buslogic->DataBuf[0] = TargetsPresentMask&0x0F; - Buslogic->DataBuf[1] = TargetsPresentMask>>8; - Buslogic->DataReplyLeft = 2; - } - break; - - case 0x25: - if (Buslogic->CmdBuf[0] == 0) - Buslogic->IrqEnabled = 0; - else - Buslogic->IrqEnabled = 1; - BuslogicLog("Lowering IRQ %i\n", Buslogic->Irq); - picintc(1 << Buslogic->Irq); - break; - - case 0x28: - if (!scsi_model) - { - Buslogic->DataBuf[0] = 0x08; - Buslogic->DataBuf[1] = Buslogic->Lock; - Buslogic->DataReplyLeft = 2; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x29: - if (!scsi_model) - { - if (Buslogic->CmdBuf[1] = Buslogic->Lock) - { - if (Buslogic->CmdBuf[0] & 1) - { - Buslogic->Lock = 1; - } - else - { - Buslogic->Lock = 0; - } - } - Buslogic->DataReplyLeft = 0; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x81: - { - if (scsi_model) - { - Buslogic->Mbx24bit = 0; - - MailboxInitExtended_t *MailboxInit = (MailboxInitExtended_t *)Buslogic->CmdBuf; - - Buslogic->MailboxCount = MailboxInit->Count; - Buslogic->MailboxOutAddr = MailboxInit->Address; - Buslogic->MailboxInAddr = MailboxInit->Address + (Buslogic->MailboxCount * sizeof(Mailbox32_t)); - - BuslogicLog("Buslogic Extended Initialize Mailbox Command\n"); - BuslogicLog("Mailbox Out Address=0x%08X\n", Buslogic->MailboxOutAddr); - BuslogicLog("Mailbox In Address=0x%08X\n", Buslogic->MailboxInAddr); - BuslogicLog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, MailboxInit->Address); - - Buslogic->Status &= ~STAT_INIT; - Buslogic->DataReplyLeft = 0; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - } - break; - - case 0x84: - if (scsi_model) - { - Buslogic->DataBuf[0] = '7'; - Buslogic->DataReplyLeft = 1; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x85: - if (scsi_model) - { - Buslogic->DataBuf[0] = 'B'; - Buslogic->DataReplyLeft = 1; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x86: - if (BuslogicIsPCI()) - { - BuslogicPCIInformation_t *Reply = (BuslogicPCIInformation_t *) Buslogic->DataBuf; - memset(Reply, 0, sizeof(BuslogicPCIInformation_t)); - Reply->InformationIsValid = 0; - switch(Buslogic->Base) - { - case 0x330: - Reply->IsaIOPort = 0; - break; - case 0x334: - Reply->IsaIOPort = 1; - break; - case 0x230: - Reply->IsaIOPort = 2; - break; - case 0x234: - Reply->IsaIOPort = 3; - break; - case 0x130: - Reply->IsaIOPort = 4; - break; - case 0x134: - Reply->IsaIOPort = 5; - break; - default: - Reply->IsaIOPort = 0xFF; - break; - } - Reply->IRQ = Buslogic->Irq; - Buslogic->DataReplyLeft = sizeof(BuslogicPCIInformation_t); - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x8B: - { - if (scsi_model) - { - int i; - - /* The reply length is set by the guest and is found in the first byte of the command buffer. */ - Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; - memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft); - char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */ - if (BuslogicIsPCI()) - { - aModelName[0] = '9'; - aModelName[1] = '5'; - aModelName[2] = '8'; - aModelName[3] = 'D'; - } - int cCharsToTransfer = Buslogic->DataReplyLeft <= sizeof(aModelName) - ? Buslogic->DataReplyLeft - : sizeof(aModelName); - - for (i = 0; i < cCharsToTransfer; i++) - Buslogic->DataBuf[i] = aModelName[i]; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - } - break; - - case 0x8C: - // if (BuslogicIsPCI()) - if (scsi_model) - { - int i = 0; - Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; - memset(Buslogic->DataBuf, 0, Buslogic->DataReplyLeft); - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x8D: - { - if (scsi_model) - { - Buslogic->DataReplyLeft = Buslogic->CmdBuf[0]; - ReplyInquireExtendedSetupInformation *Reply = (ReplyInquireExtendedSetupInformation *)Buslogic->DataBuf; - memset(Reply, 0, sizeof(ReplyInquireExtendedSetupInformation)); - - Reply->uBusType = (BuslogicIsPCI()) ? 'E' : 'A'; /* ISA style */ - Reply->uBiosAddress = 0; - Reply->u16ScatterGatherLimit = 8192; - Reply->cMailbox = Buslogic->MailboxCount; - Reply->uMailboxAddressBase = Buslogic->MailboxOutAddr; - if (BuslogicIsPCI()) - { - Reply->fLevelSensitiveInterrupt = 1; - Reply->fHostWideSCSI = 1; - Reply->fHostUltraSCSI = 1; - } - memcpy(Reply->aFirmwareRevision, "07B", sizeof(Reply->aFirmwareRevision)); - BuslogicLog("Return Extended Setup Information: %d\n", Buslogic->CmdBuf[0]); - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - } - break; - - /* VirtualBox has these two modes implemented in reverse. - According to the BusLogic datasheet: - 0 is the strict round robin mode, which is also the one used by the AHA-154x according to the - Adaptec specification; - 1 is the aggressive round robin mode, which "hunts" for an active outgoing mailbox and then - processes it. */ - case 0x8F: - if (scsi_model) - { - if (Buslogic->CmdBuf[0] == 0) - Buslogic->StrictRoundRobinMode = 1; - else if (Buslogic->CmdBuf[0] == 1) - Buslogic->StrictRoundRobinMode = 0; - - Buslogic->DataReplyLeft = 0; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x91: - { - uint8_t Offset = Buslogic->CmdBuf[0]; - Buslogic->DataReplyLeft = Buslogic->CmdBuf[1]; - - Buslogic->UseLocalRam = 1; - Buslogic->DataReply = Offset; - } - break; - - case 0x95: - if (BuslogicIsPCI()) - { - if (Buslogic->Base != 0) - { - io_removehandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - } - switch(Buslogic->CmdBuf[0]) - { - case 0: - Buslogic->Base = 0x330; - break; - case 1: - Buslogic->Base = 0x334; - break; - case 2: - Buslogic->Base = 0x230; - break; - case 3: - Buslogic->Base = 0x234; - break; - case 4: - Buslogic->Base = 0x130; - break; - case 5: - Buslogic->Base = 0x134; - break; - default: - Buslogic->Base = 0; - break; - } - if (Buslogic->Base != 0) - { - io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - } - Buslogic->DataReplyLeft = 0; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - case 0x96: - if (scsi_model) - { - if (Buslogic->CmdBuf[0] == 0) - Buslogic->ExtendedLUNCCBFormat = 0; - else if (Buslogic->CmdBuf[0] == 1) - Buslogic->ExtendedLUNCCBFormat = 1; - - Buslogic->DataReplyLeft = 0; - } - else - { - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - } - break; - - default: - case 0x22: //undocumented - Buslogic->DataReplyLeft = 0; - Buslogic->Status |= STAT_INVCMD; - break; - } - } - - if (Buslogic->DataReplyLeft) - Buslogic->Status |= STAT_DFULL; - else if (!Buslogic->CmdParamLeft) - BuslogicCommandComplete(Buslogic); - break; - - case 2: - if (scsi_model) - Buslogic->Interrupt = Val; //For Buslogic - break; - - case 3: - if (scsi_model) - Buslogic->Geometry = Val; //For Buslogic - break; - } -} - -void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) -{ - BuslogicWrite(Port, Val & 0xFF, p); -} - -void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) -{ - BuslogicWrite(Port, Val & 0xFF, p); -} - -static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) -{ - BuslogicLog("Unconverted Request Sense length %i\n", RequestSenseLength); - - if (RequestSenseLength == 0) - RequestSenseLength = 14; - else if (RequestSenseLength == 1) - RequestSenseLength = 0; - /* else if ((RequestSenseLength > 1) && (RequestSenseLength < 8)) - { - if (!scsi_model) RequestSenseLength = 0; - } */ - - BuslogicLog("Request Sense length %i\n", RequestSenseLength); - - return RequestSenseLength; -} - -static void BuslogicSenseBufferFree(BuslogicRequests_t *BuslogicRequests, int Copy) -{ - uint8_t SenseLength = BuslogicConvertSenseLength(BuslogicRequests->CmdBlock.common.RequestSenseLength); - uint8_t cdrom_id = scsi_cdrom_drives[BuslogicRequests->TargetID][BuslogicRequests->LUN]; - - uint8_t temp_sense[256]; - - if (SenseLength && Copy) - { - uint32_t SenseBufferAddress; - - cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); - - /*The sense address, in 32-bit mode, is located in the Sense Pointer of the CCB, but in - 24-bit mode, it is located at the end of the Command Descriptor Block. */ - - if (BuslogicRequests->Is24bit) - { - SenseBufferAddress = BuslogicRequests->CCBPointer; - SenseBufferAddress += BuslogicRequests->CmdBlock.common.CdbLength + offsetof(CCB, Cdb); - } - else - { - SenseBufferAddress = BuslogicRequests->CmdBlock.new.SensePointer; - } - - BuslogicLog("Request Sense address: %02X\n", SenseBufferAddress); - - BuslogicLog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", SenseLength, SenseBufferAddress); - DMAPageWrite(SenseBufferAddress, temp_sense, SenseLength); - BuslogicLog("Sense data written to buffer: %02X %02X %02X\n", temp_sense[2], temp_sense[12], temp_sense[13]); - } -} - -static void BuslogicCDROMCommand(Buslogic_t *Buslogic) -{ - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - uint8_t Id, Lun; - - uint8_t cdrom_id; - uint8_t cdrom_phase; - - uint32_t temp = 0; - - uint8_t temp_cdb[12]; - uint32_t i; - - Id = BuslogicRequests->TargetID; - Lun = BuslogicRequests->LUN; - - cdrom_id = scsi_cdrom_drives[Id][Lun]; - - BuslogicLog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); - - BuslogicLog("SCSI Cdb[0]=0x%02X\n", BuslogicRequests->CmdBlock.common.Cdb[0]); - for (i = 1; i < BuslogicRequests->CmdBlock.common.CdbLength; i++) - { - BuslogicLog("SCSI Cdb[%i]=%i\n", i, BuslogicRequests->CmdBlock.common.Cdb[i]); - } - - memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); - if (BuslogicRequests->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) - { - memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, BuslogicRequests->CmdBlock.common.CdbLength); - } - else - { - memcpy(temp_cdb, BuslogicRequests->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); - } - - cdrom[cdrom_id].request_length = temp_cdb[1]; /* Since that field in the cdrom struct is never used when the bus type is SCSI, let's use it for this scope. */ - - if (BuslogicRequests->CmdBlock.common.CdbLength != 12) - { - temp_cdb[1] &= 0x1f; /* Make sure the LUN field of the temporary CDB is always 0, otherwise Daemon Tools drives will misehave when a command is passed through to them. */ - } - - //Finally, execute the SCSI command immediately and get the transfer length. - - SCSIPhase = SCSI_PHASE_COMMAND; - cdrom_command(cdrom_id, temp_cdb); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); - if (SCSIStatus == SCSI_STATUS_OK) - { - cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); - if (cdrom_phase == 2) - { - /* Command completed - call the phase callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - else - { - /* Command first phase complete - call the callback to execute the second phase. */ - cdrom_phase_callback(cdrom_id); - SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); - /* Command second phase complete - call the callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - } - else - { - /* Error (Check Condition) - call the phase callback to complete the command. */ - cdrom_phase_callback(cdrom_id); - } - - BuslogicLog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); - - BuslogicDataBufferFree(BuslogicRequests); - - BuslogicSenseBufferFree(BuslogicRequests, (SCSIStatus != SCSI_STATUS_OK)); - - BuslogicLog("Request complete\n"); - - if (SCSIStatus == SCSI_STATUS_OK) - { - BuslogicMailboxInSetup(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - } - else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) - { - BuslogicMailboxInSetup(Buslogic, BuslogicRequests->CCBPointer, &BuslogicRequests->CmdBlock, CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - } -} - -static int BuslogicSCSIRequestSetup(Buslogic_t *Buslogic, uint32_t CCBPointer, Mailbox32_t *Mailbox32) -{ - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - uint8_t Id, Lun; - - uint8_t cdrom_id; - uint8_t cdrom_phase; - - uint8_t last_id = scsi_model ? 15 : 7; - - //Fetch data from the Command Control Block. - DMAPageRead(CCBPointer, &BuslogicRequests->CmdBlock, sizeof(CCB32)); - - BuslogicRequests->Is24bit = Buslogic->Mbx24bit; - BuslogicRequests->CCBPointer = CCBPointer; - - BuslogicRequests->TargetID = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Id : BuslogicRequests->CmdBlock.new.Id; - BuslogicRequests->LUN = Buslogic->Mbx24bit ? BuslogicRequests->CmdBlock.old.Lun : BuslogicRequests->CmdBlock.new.Lun; - - Id = BuslogicRequests->TargetID; - Lun = BuslogicRequests->LUN; - - if ((Id > last_id) || (Lun > 7)) - { - BuslogicMailboxInSetup(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); - return 1; - } - - BuslogicLog("Scanning SCSI Target ID %i\n", Id); - - cdrom_id = scsi_cdrom_drives[Id][Lun]; - - SCSIStatus = SCSI_STATUS_OK; - - SCSIDevices[Id][Lun].InitLength = 0; - - /* Do this here, so MODE SELECT data will does not get lost in transit. */ - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - - BuslogicDataBufferAllocate(BuslogicRequests, BuslogicRequests->Is24bit); - - if (!buslogic_scsi_drive_is_cdrom(Id, Lun)) - { - BuslogicLog("SCSI Target ID %i and LUN %i have no device attached\n", Id, Lun); - - BuslogicDataBufferFree(BuslogicRequests); - - BuslogicSenseBufferFree(BuslogicRequests, 0); - - BuslogicMailboxInSetup(Buslogic, CCBPointer, &BuslogicRequests->CmdBlock, CCB_SELECTION_TIMEOUT, SCSI_STATUS_OK, MBI_ERROR); - } - else - { - BuslogicLog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); - - BuslogicLog("Transfer Control %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); - BuslogicLog("CDB Length %i\n", BuslogicRequests->CmdBlock.common.CdbLength); - BuslogicLog("CCB Opcode %x\n", BuslogicRequests->CmdBlock.common.Opcode); - - if (BuslogicRequests->CmdBlock.common.ControlByte > 0x03) - { - BuslogicLog("Invalid control byte: %02X\n", BuslogicRequests->CmdBlock.common.ControlByte); - } - - BuslogicInOperation = 1; - } - - return 1; -} - -static int BuslogicSCSIRequestAbort(Buslogic_t *Buslogic, uint32_t CCBPointer) -{ - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - CCBU CmdBlock; - - //Fetch data from the Command Control Block. - DMAPageRead(CCBPointer, &CmdBlock, sizeof(CCB32)); - - //Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. - BuslogicMailboxInSetup(Buslogic, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); - - return 1; -} - -static uint32_t BuslogicMailboxOut(Buslogic_t *Buslogic, Mailbox32_t *Mailbox32) -{ - Mailbox_t MailboxOut; - uint32_t Outgoing; - - if (Buslogic->Mbx24bit) - { - Outgoing = Buslogic->MailboxOutAddr + (Buslogic->MailboxOutPosCur * sizeof(Mailbox_t)); - - DMAPageRead(Outgoing, &MailboxOut, sizeof(Mailbox_t)); - - Mailbox32->CCBPointer = ADDR_TO_U32(MailboxOut.CCBPointer); - Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; - } - else - { - Outgoing = Buslogic->MailboxOutAddr + (Buslogic->MailboxOutPosCur * sizeof(Mailbox32_t)); - - DMAPageRead(Outgoing, Mailbox32, sizeof(Mailbox32_t)); - } - - return Outgoing; -} - -static void BuslogicMailboxOutAdvance(Buslogic_t *Buslogic) -{ - Buslogic->MailboxOutPosCur = (Buslogic->MailboxOutPosCur + 1) % Buslogic->MailboxCount; -} - -static int BuslogicProcessMailbox(Buslogic_t *Buslogic) -{ - Mailbox32_t Mailbox32; - Mailbox_t MailboxOut; - uint32_t Outgoing; - - uint8_t CmdStatus = MBO_FREE; - uint32_t CodeOffset = 0; - - int old_irq_enabled = Buslogic->IrqEnabled; - - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - - int ret = 0; - - CodeOffset = Buslogic->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); - - if (!Buslogic->StrictRoundRobinMode) - { - uint8_t MailboxCur = Buslogic->MailboxOutPosCur; - - /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ - do - { - /* Fetch mailbox from guest memory. */ - Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); - - /* Check the next mailbox. */ - BuslogicMailboxOutAdvance(Buslogic); - } while ((Mailbox32.u.out.ActionCode == MBO_FREE) && (MailboxCur != Buslogic->MailboxOutPosCur)); - } - else - { - Outgoing = BuslogicMailboxOut(Buslogic, &Mailbox32); - } - - if (Mailbox32.u.out.ActionCode != MBO_FREE) - { - /* We got the mailbox, mark it as free in the guest. */ - BuslogicLog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); - DMAPageWrite(Outgoing + CodeOffset, &CmdStatus, sizeof(CmdStatus)); - } - - if (Buslogic->MailboxOutInterrupts) - { - BuslogicRaiseInterrupt(Buslogic, INTR_MBOA | INTR_ANY); - } - - /* Check if the mailbox is actually loaded. */ - if (Mailbox32.u.out.ActionCode == MBO_FREE) - { - // BuslogicLog("No loaded mailbox left\n"); - return 0; - } - - if (Mailbox32.u.out.ActionCode == MBO_START) - { - BuslogicLog("Start Mailbox Command\n"); - ret = BuslogicSCSIRequestSetup(Buslogic, Mailbox32.CCBPointer, &Mailbox32); - } - else if (Mailbox32.u.out.ActionCode == MBO_ABORT) - { - BuslogicLog("Abort Mailbox Command\n"); - ret = BuslogicSCSIRequestAbort(Buslogic, Mailbox32.CCBPointer); - } - else - { - BuslogicLog("Invalid action code: %02X\n", Mailbox32.u.out.ActionCode); - ret = 0; - } - - /* Advance to the next mailbox. */ - if (Buslogic->StrictRoundRobinMode) - { - BuslogicMailboxOutAdvance(Buslogic); - } - - return ret; -} - -void BuslogicResetPoll(void *p) -{ - Buslogic_t *Buslogic = (Buslogic_t *)p; - - Buslogic->Status &= ~STAT_STST; - Buslogic->Status |= STAT_IDLE; - - BuslogicResetCallback = 0; -} - -void BuslogicCommandCallback(void *p) -{ - Buslogic_t *Buslogic = (Buslogic_t *)p; - - BuslogicRequests_t *BuslogicRequests = &Buslogic->BuslogicRequests; - - int ret = 0; - int i = 0; - - // BuslogicLog("BusLogic Callback (%08X)!\n", BuslogicCallback); - - if (BuslogicInOperation == 0) - { - // BuslogicLog("BusLogic Callback: Start outgoing mailbox\n"); - if (Buslogic->MailboxCount) - { - ret = BuslogicProcessMailbox(Buslogic); - } - else - { - // fatal("Callback active with mailbox count 0!\n"); - BuslogicCallback += 50 * SCSI_TIME; - return; - } - } - else if (BuslogicInOperation == 1) - { - BuslogicLog("BusLogic Callback: Process request\n"); - BuslogicCDROMCommand(Buslogic); - } - else if (BuslogicInOperation == 2) - { - BuslogicLog("BusLogic Callback: Send incoming mailbox\n"); - BuslogicMailboxIn(Buslogic); - } - else - { - fatal("Invalid BusLogic callback phase: %i\n", BuslogicInOperation); - } - - BuslogicCallback += 50 * SCSI_TIME; -} - -uint8_t mem_read_null(uint32_t addr, void *priv) -{ - return 0; -} - -uint16_t mem_read_nullw(uint32_t addr, void *priv) -{ - return 0; -} - -uint32_t mem_read_nulll(uint32_t addr, void *priv) -{ - return 0; -} - -typedef union -{ - uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; - -uint8_t buslogic_pci_regs[256]; - -bar_t buslogic_pci_bar[3]; - -uint8_t BuslogicPCIRead(int func, int addr, void *p) -{ - Buslogic_t *Buslogic = (Buslogic_t *)p; - - // BuslogicLog("BusLogic PCI read %08X\n", addr); - switch (addr) - { - case 0x00: - return 0x4b; - case 0x01: - return 0x10; - - case 0x02: - return 0x40; - case 0x03: - return 0x10; - - case 0x2C: - return 0x4b; - case 0x2D: - return 0x10; - case 0x2E: - return 0x40; - case 0x2F: - return 0x10; - - case 0x04: - return buslogic_pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return buslogic_pci_regs[0x05]; - - case 0x07: - return 2; - - case 0x08: - return 1; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - case 0x0A: - return 0; /*Subclass*/ - case 0x0B: - return 1; /* Class code*/ - - case 0x10: - return (buslogic_pci_bar[0].addr_regs[0] & 0xe0) | 1; /*I/O space*/ - case 0x11: - return buslogic_pci_bar[0].addr_regs[1]; - case 0x12: - return buslogic_pci_bar[0].addr_regs[2]; - case 0x13: - return buslogic_pci_bar[0].addr_regs[3]; - - case 0x14: - return (buslogic_pci_bar[1].addr_regs[0] & 0xe0); /*Memory space*/ - case 0x15: - return buslogic_pci_bar[1].addr_regs[1]; - case 0x16: - return buslogic_pci_bar[1].addr_regs[2]; - case 0x17: - return buslogic_pci_bar[1].addr_regs[3]; - - case 0x30: - return buslogic_pci_bar[2].addr_regs[0] & 0x01; /*BIOS ROM address*/ - case 0x31: - return buslogic_pci_bar[2].addr_regs[1] | 0x18; - case 0x32: - return buslogic_pci_bar[2].addr_regs[2]; - case 0x33: - return buslogic_pci_bar[2].addr_regs[3]; - - case 0x3C: - return Buslogic->Irq; - case 0x3D: - return 1; - } - return 0; -} - -void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) -{ - Buslogic_t *Buslogic = (Buslogic_t *)p; - - switch (addr) - { - case 0x04: - io_removehandler(Buslogic->PCIBase, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - mem_mapping_disable(&Buslogic->mmio_mapping); - if (val & PCI_COMMAND_IO) - { - if (Buslogic->PCIBase != 0) - { - io_sethandler(Buslogic->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - } - } - if (val & PCI_COMMAND_MEM) - { - if (Buslogic->PCIBase != 0) - { - mem_mapping_set_addr(&Buslogic->mmio_mapping, Buslogic->MMIOBase, 0x20); - } - } - buslogic_pci_regs[addr] = val; - break; - - case 0x10: - val &= 0xe0; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O. */ - io_removehandler(Buslogic->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - /* Then let's set the PCI regs. */ - buslogic_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - Buslogic->PCIBase = buslogic_pci_bar[0].addr & 0xffe0; - /* Log the new base. */ - BuslogicLog("BusLogic PCI: New I/O base is %04X\n" , Buslogic->PCIBase); - /* We're done, so get out of the here. */ - if (buslogic_pci_regs[4] & PCI_COMMAND_IO) - { - if (Buslogic->PCIBase != 0) - { - io_sethandler(Buslogic->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - } - } - return; - - case 0x14: - val &= 0xe0; - case 0x15: case 0x16: case 0x17: - /* I/O Base set. */ - /* First, remove the old I/O. */ - mem_mapping_disable(&Buslogic->mmio_mapping); - /* Then let's set the PCI regs. */ - buslogic_pci_bar[1].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - Buslogic->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; - /* Log the new base. */ - BuslogicLog("BusLogic PCI: New MMIO base is %04X\n" , Buslogic->MMIOBase); - /* We're done, so get out of the here. */ - if (buslogic_pci_regs[4] & PCI_COMMAND_MEM) - { - if (Buslogic->PCIBase != 0) - { - mem_mapping_set_addr(&Buslogic->mmio_mapping, Buslogic->MMIOBase, 0x20); - } - } - return; - - /* Commented out until an APIC controller is emulated for the PIIX3, - otherwise the BT-958 will not get an IRQ on boards using the PIIX3. */ -#if 0 - case 0x3C: - buslogic_pci_regs[addr] = val; - if (val != 0xFF) - { - buslogic_log("BusLogic IRQ now: %i\n", val); - Buslogic->Irq = val; - } - return; -#endif - } -} - -void *BuslogicInit() -{ - int i = 0; - - Buslogic_t *Buslogic = malloc(sizeof(Buslogic_t)); - memset(Buslogic, 0, sizeof(Buslogic_t)); - - BuslogicResetDevice = Buslogic; - - scsi_model = device_get_config_int("model"); - Buslogic->Base = device_get_config_int("addr"); - Buslogic->PCIBase = 0; - Buslogic->MMIOBase = 0; - Buslogic->Irq = device_get_config_int("irq"); - Buslogic->DmaChannel = device_get_config_int("dma"); - - if (Buslogic->Base != 0) - { - if (BuslogicIsPCI()) - { - io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, Buslogic); - } - else - { - io_sethandler(Buslogic->Base, 0x0004, BuslogicRead, BuslogicReadW, NULL, BuslogicWrite, BuslogicWriteW, NULL, Buslogic); - } - } - - BuslogicLog("Building CD-ROM map...\n"); - build_scsi_cdrom_map(); - - for (i = 0; i < CDROM_NUM; i++) - { - if (buslogic_scsi_drive_is_cdrom(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun)) - { - SCSIDevices[cdrom_drives[i].scsi_device_id][cdrom_drives[i].scsi_device_lun].LunType == SCSI_CDROM; - } - } - - timer_add(BuslogicResetPoll, &BuslogicResetCallback, &BuslogicResetCallback, Buslogic); - timer_add(BuslogicCommandCallback, &BuslogicCallback, &BuslogicCallback, Buslogic); - - if (BuslogicIsPCI()) - { - pci_add(BuslogicPCIRead, BuslogicPCIWrite, Buslogic); - - buslogic_pci_bar[0].addr_regs[0] = 1; - buslogic_pci_bar[1].addr_regs[0] = 0; - - buslogic_pci_regs[0x04] = 1; - buslogic_pci_regs[0x05] = 0; - - buslogic_pci_regs[0x07] = 2; - - buslogic_pci_bar[2].addr = 0; - - mem_mapping_add(&Buslogic->mmio_mapping, 0xfffd0000, 0x20, mem_read_null, mem_read_nullw, mem_read_nulll, mem_write_null, mem_write_nullw, mem_write_nulll, NULL, MEM_MAPPING_EXTERNAL, Buslogic); - mem_mapping_disable(&Buslogic->mmio_mapping); - } - - BuslogicLog("Buslogic on port 0x%04X\n", Buslogic->Base); - - BuslogicResetControl(Buslogic, CTRL_HRST); - - return Buslogic; -} - -void BuslogicClose(void *p) -{ - Buslogic_t *Buslogic = (Buslogic_t *)p; - free(Buslogic); - BuslogicResetDevice = NULL; -} - -static device_config_t BuslogicConfig[] = -{ - { - .name = "model", - .description = "Model", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Adaptec AHA-154XB ISA", - .value = 0 - }, - { - .description = "BusLogic BT-542B ISA", - .value = 1 - }, - { - .description = "BusLogic BT-958 PCI", - .value = 2 - }, - { - .description = "" - } - }, - .default_int = 0 - }, - { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "None", - .value = 0 - }, - { - .description = "0x330", - .value = 0x330 - }, - { - .description = "0x334", - .value = 0x334 - }, - { - .description = "0x230", - .value = 0x230 - }, - { - .description = "0x234", - .value = 0x234 - }, - { - .description = "0x130", - .value = 0x130 - }, - { - .description = "0x134", - .value = 0x134 - }, - { - .description = "" - } - }, - .default_int = 0x334 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "IRQ 9", - .value = 9 - }, - { - .description = "IRQ 10", - .value = 10 - }, - { - .description = "IRQ 11", - .value = 11 - }, - { - .description = "IRQ 12", - .value = 12 - }, - { - .description = "IRQ 14", - .value = 14 - }, - { - .description = "IRQ 15", - .value = 15 - }, - { - .description = "" - } - }, - .default_int = 9 - }, - { - .name = "dma", - .description = "DMA channel", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "DMA 5", - .value = 5 - }, - { - .description = "DMA 6", - .value = 6 - }, - { - .description = "DMA 7", - .value = 7 - }, - { - .description = "" - } - }, - .default_int = 6 - }, - { - .type = -1 - } -}; - -device_t BuslogicDevice = -{ - "Adaptec/Buslogic", - 0, - BuslogicInit, - BuslogicClose, - NULL, - NULL, - NULL, - NULL, - BuslogicConfig -}; diff --git a/src/buslogic.h b/src/buslogic.h index ffb5b4a05..c4b6805f0 100644 --- a/src/buslogic.h +++ b/src/buslogic.h @@ -1 +1,27 @@ -extern device_t BuslogicDevice; \ No newline at end of file +#ifndef BUSLOGIC_H +# define BUSLOGIC_H + + +typedef struct { + uint8_t flags; /* local flags */ + uint8_t bid; /* board ID */ + char fwl, fwh; /* firmware info */ +} aha_info; +#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ + + +extern device_t aha1540b_device; +extern device_t aha1542cf_device; +extern device_t buslogic_device; +extern device_t buslogic_pci_device; + + +extern int buslogic_dev_present(uint8_t id, uint8_t lun); + +extern void aha154x_init(uint16_t, uint32_t, aha_info *); +extern uint8_t aha154x_shram(uint8_t); +extern uint8_t aha154x_eeprom(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t *); +extern uint8_t aha154x_memory(uint8_t); + + +#endif /*BUSLOGIC_H*/ diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index ba8d1f9c3..5ab4d09a3 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -25,16 +25,11 @@ typedef struct cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; -// #define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)-150) -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ - enum { - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED }; int cdrom_ioctl_do_log = 0; @@ -58,281 +53,302 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) RAW_READ_INFO in; DWORD count; -// return; -// cdrom_ioctl_log("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (cdrom_ioctl[id].cd_state != CD_PLAYING) - { - memset(output, 0, len * 2); - return; - } - while (cdrom_ioctl[id].cd_buflen < len) - { - if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) - { - in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - ioctl_open(id, 0); -// cdrom_ioctl_log("Read to %i\n", cd_buflen); - if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) - { -// cdrom_ioctl_log("DeviceIoControl returned false\n"); - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; - } - else - { -// cdrom_ioctl_log("DeviceIoControl returned true\n"); - cdrom[id].seek_pos++; - cdrom_ioctl[id].cd_buflen += (2352 / 2); - } - ioctl_close(id); - } - else - { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; - } - } - memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); -// for (c = 0; c < BUF_SIZE - len; c++) -// cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); - cdrom_ioctl[id].cd_buflen -= len; -// cdrom_ioctl_log("Done %i\n", GetTickCount()); + if (cdrom_ioctl[id].cd_state != CD_PLAYING) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_ioctl[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) + { + in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + ioctl_open(id, 0); + if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) + { + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_ioctl[id].cd_buflen += (2352 / 2); + } + ioctl_close(id); + } + else + { + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; + } + } + memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); + memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); + cdrom_ioctl[id].cd_buflen -= len; } void ioctl_audio_stop(uint8_t id) { - cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_state = CD_STOPPED; } static int get_track_nr(uint8_t id, uint32_t pos) { - int c; - int track = 0; - - if (!cdrom_ioctl[id].tocvalid) - return 0; + int c; + int track = 0; - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } - if (track_address <= pos) - track = c; - } - return track; + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); + + if (track_address <= pos) + { + track = c; + } + } + return track; } static uint32_t get_track_msf(uint8_t id, uint32_t track_no) { - int c; - int track = 0; - - if (!cdrom_ioctl[id].tocvalid) - return 0; + int c; - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - if (c == track_no) - { - return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); - } - } - return 0xffffffff; + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + if (c == track_no) + { + return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); + } + } + return 0xffffffff; } static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) { - if (!cdrom_drives[id].host_drive) return; - // cdrom_ioctl_log("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf == 2) + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + if (!cdrom_drives[id].host_drive) + { + return; + } + if (ismsf == 2) + { + start_msf = get_track_msf(id, pos); + end_msf = get_track_msf(id, len); + if (start_msf == 0xffffffff) { - uint32_t start_msf = get_track_msf(id, pos); - uint32_t end_msf = get_track_msf(id, len); - if (start_msf == 0xffffffff) - { - return; - } - if (end_msf == 0xffffffff) - { - return; - } - int m = (start_msf >> 16) & 0xff; - int s = (start_msf >> 8) & 0xff; - int f = start_msf & 0xff; - pos = MSFtoLBA(m, s, f); - m = (end_msf >> 16) & 0xff; - s = (end_msf >> 8) & 0xff; - f = end_msf & 0xff; - len = MSFtoLBA(m, s, f); + return; } + if (end_msf == 0xffffffff) + { + return; + } + m = (start_msf >> 16) & 0xff; + s = (start_msf >> 8) & 0xff; + f = start_msf & 0xff; + pos = MSFtoLBA(m, s, f); + m = (end_msf >> 16) & 0xff; + s = (end_msf >> 8) & 0xff; + f = end_msf & 0xff; + len = MSFtoLBA(m, s, f); + } else if (ismsf == 1) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; - if (pos == 0xffffff) - { - cdrom_ioctl_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; - } - else - { - pos = MSFtoLBA(m, s, f); - } + if (pos == 0xffffff) + { + cdrom_ioctl_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); - // cdrom_ioctl_log("MSF - pos = %08X len = %08X\n", pos, len); - } - else if (ismsf == 0) + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) { - if (pos == 0xffffffff) - { - cdrom_ioctl_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; - } - len += pos; + cdrom_ioctl_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; } - cdrom[id].seek_pos = pos;// + 150; - cdrom_ioctl[id].cd_end = len;// + 150; - if (cdrom[id].seek_pos < 150) - { - /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - cdrom[id].seek_pos = 150; - } - cdrom_ioctl[id].cd_state = CD_PLAYING; - // cdrom_ioctl_log("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len); + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_ioctl[id].cd_end = len; + if (cdrom[id].seek_pos < 150) + { + /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ + cdrom[id].seek_pos = 150; + } + cdrom_ioctl[id].cd_state = CD_PLAYING; } static void ioctl_pause(uint8_t id) { - if (!cdrom_drives[id].host_drive) return; - if (cdrom_ioctl[id].cd_state == CD_PLAYING) - cdrom_ioctl[id].cd_state = CD_PAUSED; + if (!cdrom_drives[id].host_drive) + { + return; + } + if (cdrom_ioctl[id].cd_state == CD_PLAYING) + { + cdrom_ioctl[id].cd_state = CD_PAUSED; + } } static void ioctl_resume(uint8_t id) { - if (!cdrom_drives[id].host_drive) return; - if (cdrom_ioctl[id].cd_state == CD_PAUSED) - cdrom_ioctl[id].cd_state = CD_PLAYING; + if (!cdrom_drives[id].host_drive) + { + return; + } + if (cdrom_ioctl[id].cd_state == CD_PAUSED) + { + cdrom_ioctl[id].cd_state = CD_PLAYING; + } } static void ioctl_stop(uint8_t id) { - if (!cdrom_drives[id].host_drive) return; - cdrom_ioctl[id].cd_state = CD_STOPPED; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; } static int ioctl_ready(uint8_t id) { - long size; - int temp; - CDROM_TOC ltoc; - // cdrom_ioctl_log("Ready? %i\n",cdrom_drives[id].host_drive); - if (!cdrom_drives[id].host_drive) return 0; - ioctl_open(id, 0); - temp=DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,<oc,sizeof(ltoc),&size,NULL); - ioctl_close(id); - if (!temp) - return 0; - // cdrom_ioctl_log("ioctl_ready(): Drive opened successfully\n"); - // if ((cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) cdrom_ioctl_log("Drive has changed\n"); - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || - !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - // cdrom_ioctl_log("ioctl_ready(): Disc or drive changed\n"); - // cdrom_ioctl_log("ioctl_ready(): Stopped\n"); - cdrom_ioctl[id].cd_state = CD_STOPPED; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - return 1; - } - // cdrom_ioctl_log("ioctl_ready(): All is good\n"); - return 1; + unsigned long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + if (!temp) + { + return 0; + } + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || + !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + } + return 1; + } + return 1; } static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) { - int len=4; - long size; - int c,d; - uint32_t temp; - CDROM_TOC lbtoc; - int lb=0; - if (!cdrom_drives[id].host_drive) return 0; - cdrom_ioctl[id].cd_state = CD_STOPPED; - // cdrom_ioctl_log("ioctl_readtoc(): IOCtl state now CD_STOPPED\n"); - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&lbtoc,sizeof(lbtoc),&size,NULL); - ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; - for (c=d;c<=lbtoc.LastTrack;c++) - { - uint32_t address; - address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - if (address > lb) - lb = address; + unsigned long size; + int c, d = 0; + CDROM_TOC lbtoc; + int lb = 0; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; + for (c=d; c <= lbtoc.LastTrack; c++) + { + uint32_t address; + address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + if (address > lb) + { + lb = address; } - return lb; + } + return lb; } static int ioctl_medium_changed(uint8_t id) { - long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drives[id].host_drive) return 0; /* This will be handled by the not ready handler instead. */ - ioctl_open(id, 0); - temp=DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,<oc,sizeof(ltoc),&size,NULL); - ioctl_close(id); - if (!temp) - return 0; /* Drive empty, a not ready handler matter, not disc change. */ - if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl_log("Setting TOC...\n"); - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; - } - else + unsigned long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) + { + return 0; /* This will be handled by the not ready handler instead. */ + } + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); + ioctl_close(id); + if (!temp) + { + return 0; /* Drive empty, a not ready handler matter, not disc change. */ + } + if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) { - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl_log("Setting TOC...\n"); - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; /* TOC mismatches. */ - } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; } - return 0; /* None of the above, return 0. */ + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; + } + else + { + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_log("Setting TOC...\n"); + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; /* TOC mismatches. */ + } + } + return 0; /* None of the above, return 0. */ } static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; - long size; + unsigned long size; int pos=0; if (!cdrom_drives[id].host_drive) return 0; @@ -422,62 +438,72 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) static void ioctl_eject(uint8_t id) { - long size; - if (!cdrom_drives[id].host_drive) return; - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); } static void ioctl_load(uint8_t id) { - long size; - if (!cdrom_drives[id].host_drive) return; - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); } static int is_track_audio(uint8_t id, uint32_t pos) { - int c; - int control = 0; - - if (!cdrom_ioctl[id].tocvalid) - return 0; + int c; + int control = 0; - for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - uint32_t track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - - if (track_address <= pos) - control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; - } - // cdrom_ioctl_log("Control: %i\n", control); - if ((control & 0xd) == 0) + uint32_t track_address = 0; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + + if (track_address <= pos) { - return 1; - } - else if ((control & 0xd) == 1) - { - return 1; - } - else - { - return 0; + control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; } + } + + if ((control & 0xd) <= 1) + { + return 1; + } + else + { + return 0; + } } static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) { + int m = 0, s = 0, f = 0; + if (ismsf) { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; pos = MSFtoLBA(m, s, f); } else @@ -630,28 +656,24 @@ common_handler: static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) { - HANDLE fh; - DWORD ioctl_bytes; - DWORD out_size; - int ioctl_rv = 0; - int sector_type = 0; - int temp_len = 0; + DWORD ioctl_bytes; + int ioctl_rv = 0; SCSISense.SenseKey = 0; SCSISense.Asc = 0; SCSISense.Ascq = 0; - *len = 0; - memset(&sptd, 0, sizeof(sptd)); - sptd.s.Length = sizeof(SCSI_PASS_THROUGH); - sptd.s.CdbLength = 12; - sptd.s.DataIn = SCSI_IOCTL_DATA_IN; - sptd.s.TimeOutValue = 80 * 60; - sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); - sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; - sptd.s.SenseInfoLength = 32; - sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; - + *len = 0; + memset(&sptd, 0, sizeof(sptd)); + sptd.s.Length = sizeof(SCSI_PASS_THROUGH); + sptd.s.CdbLength = 12; + sptd.s.DataIn = SCSI_IOCTL_DATA_IN; + sptd.s.TimeOutValue = 80 * 60; + sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); + sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; + sptd.s.SenseInfoLength = 32; + sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; + memcpy(sptd.s.Cdb, cdb, 12); ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); @@ -664,25 +686,25 @@ static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); - cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); - cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); - cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); + cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); + cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); + cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); *len = sptd.s.DataTransferLength; if (sptd.s.DataTransferLength != 0) { memcpy(buf, sptd.data, sptd.s.DataTransferLength); } - return ioctl_rv; + return ioctl_rv; } static void ioctl_read_capacity(uint8_t id, uint8_t *b) { - int len = 0; + uint32_t len = 0; const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; UCHAR buf[16]; @@ -701,7 +723,7 @@ static int ioctl_media_type_id(uint8_t id) uint8_t old_sense[3] = { 0, 0, 0 }; UCHAR msbuf[28]; - int len = 0; + uint32_t len = 0; int sense = 0; const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; @@ -714,8 +736,6 @@ static int ioctl_media_type_id(uint8_t id) SCSICommand(id, cdb, msbuf, &len, 1); - // pclog("Returned length: %i, media type: %i\n", len, msbuf[2]); - ioctl_close(id); sense = cdrom_sense_key; @@ -743,66 +763,75 @@ static uint32_t msf_to_lba32(int lba) static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) { - int i = 0; - int ioctl_rv = 0; + int i = 0; + int ioctl_rv = 0; - int len = 0; - - for (i = 2; i <= 5; i++) - { - cdb[1] = i << 2; - ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ - if (ioctl_rv) - { - return i; - } - } - return 0; + uint32_t len = 0; + + for (i = 2; i <= 5; i++) + { + cdb[1] = i << 2; + ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ + if (ioctl_rv) + { + return i; + } + } + return 0; } static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) { - int ioctl_rv = 0; - const UCHAR cdb_lba[] = { 0xBE, 0, (sector >> 24), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0, 0, 1, 0x10, 0, 0 }; - const UCHAR cdb_msf[] = { 0xB9, 0, 0, ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), ((sector >> 16) & 0xff), ((sector >> 8) & 0xff), (sector & 0xff), 0x10, 0, 0 }; - UCHAR buf[2352]; + int ioctl_rv = 0; + UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; + UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; + UCHAR buf[2352]; - ioctl_open(id, 0); + cdb_lba[2] = (sector >> 24); + cdb_lba[3] = ((sector >> 16) & 0xff); + cdb_lba[4] = ((sector >> 8) & 0xff); + cdb_lba[5] = (sector & 0xff); - if (ioctl_is_track_audio(id, sector, ismsf)) - { - return 1; - } - - if (ismsf) - { - ioctl_rv = ioctl_get_type(id, cdb_msf, buf); - } - else - { - ioctl_rv = ioctl_get_type(id, cdb_lba, buf); - } + cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); + cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); + cdb_msf[5] = cdb_msf[8] = (sector & 0xff); - if (ioctl_rv) - { - ioctl_close(id); - return ioctl_rv; - } - - if (ismsf) - { - sector = msf_to_lba32(sector); - if (sector < 150) - { - ioctl_close(id); - return 0; - } - sector -= 150; - ioctl_rv = ioctl_get_type(id, cdb_lba, buf); - } - - ioctl_close(id); - return ioctl_rv; + ioctl_open(id, 0); + + if (ioctl_is_track_audio(id, sector, ismsf)) + { + return 1; + } + + if (ismsf) + { + ioctl_rv = ioctl_get_type(id, cdb_msf, buf); + } + else + { + ioctl_rv = ioctl_get_type(id, cdb_lba, buf); + } + + if (ioctl_rv) + { + ioctl_close(id); + return ioctl_rv; + } + + if (ismsf) + { + sector = msf_to_lba32(sector); + if (sector < 150) + { + ioctl_close(id); + return 0; + } + sector -= 150; + ioctl_rv = ioctl_get_type(id, (UCHAR *) cdb_lba, buf); + } + + ioctl_close(id); + return ioctl_rv; } static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) @@ -816,7 +845,7 @@ static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_ static void ioctl_validate_toc(uint8_t id) { - long size; + unsigned long size; if (!cdrom_drives[id].host_drive) { return; @@ -835,7 +864,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t { const UCHAR cdb[12]; - int ret; + int ret = 0; int block_length = 0; @@ -845,10 +874,9 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t int blocks_at_once = 0; int buffer_pos = 0; - int temp_requested_blocks = 0; int transferred_blocks = 0; - int temp_len = 0; + uint32_t temp_len = 0; int chunk = 0; if (in_cdb[0] == 0x43) @@ -859,7 +887,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t ioctl_open(id, 0); - memcpy(cdb, in_cdb, 12); + memcpy((void *) cdb, in_cdb, 12); temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); *len = 0; @@ -873,7 +901,6 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t buffer_pos = 0; temp_pos = cdrom[id].sector_pos; - temp_requested_blocks = cdrom[id].requested_blocks; transferred_blocks = 0; temp_len = 0; @@ -890,7 +917,7 @@ split_block_read_iterate: cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; } cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); - cdrom_update_cdb(cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); + cdrom_update_cdb((uint8_t *) cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); *len += temp_len; transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; @@ -928,21 +955,22 @@ split_block_read_iterate: static uint32_t ioctl_size(uint8_t id) { - uint8_t capacity_buffer[8]; - uint32_t capacity = 0; - ioctl_read_capacity(id, capacity_buffer); - capacity = ((uint32_t) capacity_buffer[0]) << 24; - capacity |= ((uint32_t) capacity_buffer[1]) << 16; - capacity |= ((uint32_t) capacity_buffer[2]) << 8; - capacity |= (uint32_t) capacity_buffer[3]; - return capacity + 1; - // return cdrom_capacity; + uint8_t capacity_buffer[8]; + uint32_t capacity = 0; + ioctl_read_capacity(id, capacity_buffer); + capacity = ((uint32_t) capacity_buffer[0]) << 24; + capacity |= ((uint32_t) capacity_buffer[1]) << 16; + capacity |= ((uint32_t) capacity_buffer[2]) << 8; + capacity |= (uint32_t) capacity_buffer[3]; + return capacity + 1; } static int ioctl_status(uint8_t id) { if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) - return CD_STATUS_EMPTY; + { + return CD_STATUS_EMPTY; + } switch(cdrom_ioctl[id].cd_state) { @@ -952,14 +980,15 @@ static int ioctl_status(uint8_t id) return CD_STATUS_PAUSED; case CD_STOPPED: return CD_STATUS_STOPPED; + default: + return CD_STATUS_EMPTY; } } void ioctl_reset(uint8_t id) { CDROM_TOC ltoc; - int temp; - long size; + unsigned long size; if (!cdrom_drives[id].host_drive) { @@ -968,7 +997,7 @@ void ioctl_reset(uint8_t id) } ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); ioctl_close(id); cdrom_ioctl_windows[id].toc = ltoc; @@ -977,19 +1006,12 @@ void ioctl_reset(uint8_t id) int ioctl_open(uint8_t id, char d) { - // char s[8]; if (!cdrom_ioctl[id].ioctl_inited) { sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - // cdrom_ioctl_log("Path is %s\n",ioctl_path); cdrom_ioctl[id].tocvalid=0; } - // cdrom_ioctl_log("Opening %s\n",ioctl_path); cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - if (!cdrom_ioctl_windows[id].hIOCTL) - { - // fatal("IOCTL"); - } cdrom_drives[id].handler = &ioctl_cdrom; if (!cdrom_ioctl[id].ioctl_inited) { @@ -1018,26 +1040,26 @@ static void ioctl_exit(uint8_t id) static CDROM ioctl_cdrom= { - ioctl_ready, - ioctl_medium_changed, - ioctl_media_type_id, - ioctl_audio_callback, - ioctl_audio_stop, - NULL, - NULL, - NULL, - ioctl_getcurrentsubchannel, - ioctl_pass_through, - ioctl_sector_data_type, - NULL, - ioctl_playaudio, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit + ioctl_ready, + ioctl_medium_changed, + ioctl_media_type_id, + ioctl_audio_callback, + ioctl_audio_stop, + NULL, + NULL, + NULL, + ioctl_getcurrentsubchannel, + ioctl_pass_through, + ioctl_sector_data_type, + NULL, + ioctl_playaudio, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit }; diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index dc10fbf64..7fc01b246 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -8,6 +8,11 @@ #include "ibm.h" #include "cdrom.h" #include "cdrom-iso.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + #include static CDROM iso_cdrom; @@ -38,7 +43,7 @@ void iso_audio_callback(uint8_t id, int16_t *output, int len) void iso_audio_stop(uint8_t id) { - // cdrom_iso_log("iso_audio_stop stub\n"); + return; } static int iso_ready(uint8_t id) @@ -93,8 +98,8 @@ static void lba_to_msf(uint8_t *buf, int lba) static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { - long size; int pos=0; + int32_t temp; if (strlen(cdrom_iso[id].iso_path) == 0) { return 0; @@ -104,7 +109,7 @@ static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) b[pos++]=0; b[pos++]=0; - int32_t temp = cdrom[id].seek_pos; + temp = cdrom[id].seek_pos; if (msf) { memset(&(b[pos]), 0, 8); @@ -130,12 +135,12 @@ static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) static void iso_eject(uint8_t id) { - // cdrom_iso_log("iso_eject stub\n"); + return; } static void iso_load(uint8_t id) { - // cdrom_iso_log("iso_load stub\n"); + return; } static int iso_sector_data_type(uint8_t id, int sector, int ismsf) @@ -145,50 +150,52 @@ static int iso_sector_data_type(uint8_t id, int sector, int ismsf) static void iso_readsector(uint8_t id, uint8_t *b, int sector) { - uint32_t temp; uint64_t file_pos = sector; - if (!cdrom_drives[id].host_drive) return; + if (!cdrom_drives[id].host_drive) + { + return; + } file_pos <<= 11; memset(b, 0, 2856); - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); - fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); - fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); - fclose(cdrom_iso[id].iso_image); + cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); + fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); + fclose(cdrom_iso[id].iso_image); - /* sync bytes */ - b[0] = 0; - memset(b + 1, 0xff, 10); - b[11] = 0; - b += 12; - lba_to_msf(b, sector); - b[3] = 1; /* mode 1 data */ - b += 4; - b += 2048; - memset(b, 0, 288); + /* sync bytes */ + b[0] = 0; + memset(b + 1, 0xff, 10); + b[11] = 0; + b += 12; + lba_to_msf(b, sector); + b[3] = 1; /* mode 1 data */ + b += 4; + b += 2048; + memset(b, 0, 288); b += 288; - memset(b, 0, 392); + memset(b, 0, 392); } -typedef struct __attribute__((packed)) +typedef struct __attribute__((__packed__)) { uint8_t user_data[2048]; uint8_t ecc[288]; } m1_data_t; -typedef struct __attribute__((packed)) +typedef struct __attribute__((__packed__)) { uint8_t sub_header[8]; uint8_t user_data[2328]; } m2_data_t; -typedef union __attribute__((packed)) +typedef union __attribute__((__packed__)) { m1_data_t m1_data; m2_data_t m2_data; uint8_t raw_data[2352]; } sector_data_t; -typedef struct __attribute__((packed)) +typedef struct __attribute__((__packed__)) { uint8_t sync[12]; uint8_t header[4]; @@ -199,7 +206,7 @@ typedef struct __attribute__((packed)) uint8_t subchannel_rw[96]; } cdrom_sector_t; -typedef union __attribute__((packed)) +typedef union __attribute__((__packed__)) { cdrom_sector_t cdrom_sector; uint8_t buffer[2856]; @@ -211,10 +218,8 @@ int cdrom_sector_size; static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) { - int real_sector_type; uint8_t *b; uint8_t *temp_b; - int is_audio; int real_pos; b = temp_b = buffer; @@ -314,8 +319,6 @@ static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf temp_b += 288; } - cdrom_iso_log("CD-ROM sector size: %i (%i, %i) [%04X]\n", cdrom_sector_size, cdrom_sector_type, real_sector_type, cdrom_sector_flags); - if ((cdrom_sector_flags & 0x06) == 0x02) { /* Add error flags. */ @@ -546,7 +549,7 @@ void iso_reset(uint8_t id) int iso_open(uint8_t id, char *fn) { - struct stat st; + struct stat64 st; if (strcmp(fn, cdrom_iso[id].iso_path) != 0) { @@ -557,7 +560,6 @@ int iso_open(uint8_t id, char *fn) if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) { sprintf(cdrom_iso[id].iso_path, "%s", fn); - // cdrom_iso_log("Path is %s\n", cdrom_iso[id].iso_path); } cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); cdrom_drives[id].handler = &iso_cdrom; @@ -567,7 +569,7 @@ int iso_open(uint8_t id, char *fn) fclose(cdrom_iso[id].iso_image); } - stat(cdrom_iso[id].iso_path, &st); + stat64(cdrom_iso[id].iso_path, &st); cdrom_iso[id].image_size = st.st_size; return 0; diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 2409df412..9c52cc848 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -42,11 +42,6 @@ static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int isms return 0; } -static int null_read_track_information(uint8_t id, uint8_t *in_cdb, uint8_t *b) -{ - return 0; -} - static int null_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { return 0; diff --git a/src/cdrom-null.h b/src/cdrom-null.h index 7cc595089..7217760ca 100644 --- a/src/cdrom-null.h +++ b/src/cdrom-null.h @@ -1,14 +1,14 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#ifndef CDROM_IOCTL_H -#define CDROM_IOCTL_H +#ifndef CDROM_NULL_H +#define CDROM_NULL_H /* this header file lists the functions provided by various platform specific cdrom-ioctl files */ -extern int cdrom_null_open(uint8_t id, char d); -extern void cdrom_null_reset(uint8_t id); -extern void null_close(uint8_t id); +int cdrom_null_open(uint8_t id, char d); +void cdrom_null_reset(uint8_t id); +void null_close(uint8_t id); -#endif /* ! CDROM_IOCTL_H */ +#endif /* ! CDROM_NULL_H */ diff --git a/src/cdrom.c b/src/cdrom.c index 24a00cbeb..8cf6e3174 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -10,6 +10,7 @@ #include "cdrom.h" #include "ibm.h" #include "ide.h" +#include "piix.h" #include "scsi.h" #include "timer.h" @@ -51,7 +52,12 @@ uint8_t scsi_cdrom_drives[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; +#ifdef __MSC__ +# pragma pack(push,1) +static struct +#else static struct __attribute__((__packed__)) +#endif { uint8_t opcode; uint8_t polled; @@ -61,150 +67,660 @@ static struct __attribute__((__packed__)) uint16_t len; uint8_t control; } *gesn_cdb; +#ifdef __MSC__ +# pragma pack(pop) +#endif +#ifdef __MSC__ +# pragma pack(push,1) +static struct +#else static struct __attribute__((__packed__)) +#endif { uint16_t len; uint8_t notification_class; uint8_t supported_events; } *gesn_event_header; +#ifdef __MSC__ +# pragma pack(pop) +#endif /* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ uint8_t cdrom_command_flags[0x100] = { - [GPCMD_TEST_UNIT_READY] = IMPLEMENTED | CHECK_READY | NONDATA, - [GPCMD_REZERO_UNIT] = IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, - [GPCMD_REQUEST_SENSE] = IMPLEMENTED | ALLOW_UA, - [GPCMD_READ_6] = IMPLEMENTED | CHECK_READY, - [GPCMD_SEEK_6] = IMPLEMENTED | CHECK_READY | NONDATA, - [GPCMD_INQUIRY] = IMPLEMENTED | ALLOW_UA, - [GPCMD_VERIFY_6] = IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, - [GPCMD_MODE_SELECT_6] = IMPLEMENTED, - [GPCMD_MODE_SENSE_6] = IMPLEMENTED, - [GPCMD_START_STOP_UNIT] = IMPLEMENTED | CHECK_READY, - [GPCMD_PREVENT_REMOVAL] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_CDROM_CAPACITY] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_10] = IMPLEMENTED | CHECK_READY, - [GPCMD_SEEK_10] = IMPLEMENTED | CHECK_READY | NONDATA, - [GPCMD_VERIFY_10] = IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, - [GPCMD_READ_SUBCHANNEL] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_TOC_PMA_ATIP] = IMPLEMENTED | CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS - NOTE: The ATAPI reference says otherwise, but I think this is a question of - interpreting things right - the UNIT ATTENTION condition we have here - is a tradition from not ready to ready, by definition the drive - eventually becomes ready, make the condition go away. */ - [GPCMD_READ_HEADER] = IMPLEMENTED | CHECK_READY, - [GPCMD_PLAY_AUDIO_10] = IMPLEMENTED | CHECK_READY, - [GPCMD_GET_CONFIGURATION] = IMPLEMENTED | ALLOW_UA, - [GPCMD_PLAY_AUDIO_MSF] = IMPLEMENTED | CHECK_READY, - [GPCMD_PLAY_AUDIO_TRACK_INDEX] = IMPLEMENTED | CHECK_READY, - [GPCMD_GET_EVENT_STATUS_NOTIFICATION] = IMPLEMENTED | ALLOW_UA, - [GPCMD_PAUSE_RESUME] = IMPLEMENTED | CHECK_READY, - [GPCMD_STOP_PLAY_SCAN] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_DISC_INFORMATION] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_TRACK_INFORMATION] = IMPLEMENTED | CHECK_READY, - [GPCMD_MODE_SELECT_10] = IMPLEMENTED, - [GPCMD_MODE_SENSE_10] = IMPLEMENTED, - [GPCMD_PLAY_AUDIO_12] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_12] = IMPLEMENTED | CHECK_READY, - [GPCMD_READ_DVD_STRUCTURE] = IMPLEMENTED | CHECK_READY, - [GPCMD_VERIFY_12] = IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, - [GPCMD_PLAY_CD_OLD] = IMPLEMENTED | CHECK_READY | ATAPI_ONLY, - [GPCMD_READ_CD_OLD] = IMPLEMENTED | CHECK_READY | ATAPI_ONLY, - [GPCMD_READ_CD_MSF] = IMPLEMENTED | CHECK_READY, - [GPCMD_SCAN] = IMPLEMENTED | CHECK_READY, - [GPCMD_SET_SPEED] = IMPLEMENTED, - [GPCMD_PLAY_CD] = IMPLEMENTED | CHECK_READY, - [GPCMD_MECHANISM_STATUS] = IMPLEMENTED, - [GPCMD_READ_CD] = IMPLEMENTED | CHECK_READY, - [GPCMD_SEND_DVD_STRUCTURE] = IMPLEMENTED | CHECK_READY, - [GPCMD_PAUSE_RESUME_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, - [GPCMD_SCAN_ALT] = IMPLEMENTED | CHECK_READY | SCSI_ONLY, - [GPCMD_SET_SPEED_ALT] = IMPLEMENTED | SCSI_ONLY + IMPLEMENTED | CHECK_READY | NONDATA, + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, + 0, + IMPLEMENTED | ALLOW_UA, + 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA, + 0, 0, 0, 0, 0, 0, + IMPLEMENTED | ALLOW_UA, + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, + 0, + IMPLEMENTED, + 0, 0, 0, 0, + IMPLEMENTED, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA, + 0, 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | CHECK_READY, /* Read TOC - can get through UNIT_ATTENTION, per VIDE-CDD.SYS + NOTE: The ATAPI reference says otherwise, but I think this is a question of + interpreting things right - the UNIT ATTENTION condition we have here + is a tradition from not ready to ready, by definition the drive + eventually becomes ready, make the condition go away. */ + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | ALLOW_UA, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | CHECK_READY, + 0, + IMPLEMENTED | ALLOW_UA, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED, + 0, 0, 0, 0, + IMPLEMENTED, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY, + 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, + 0, + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, + 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, + 0, 0, 0, + IMPLEMENTED | CHECK_READY | ATAPI_ONLY, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED, + IMPLEMENTED | CHECK_READY, + IMPLEMENTED | CHECK_READY, + 0, 0, + IMPLEMENTED | CHECK_READY | SCSI_ONLY, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | SCSI_ONLY, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | SCSI_ONLY, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t cdrom_mode_sense_page_flags[CDROM_NUM][0x40] = { - { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, - [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, - [GPMODE_ALL_PAGES] = IMPLEMENTED }, - { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, - [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, - [GPMODE_ALL_PAGES] = IMPLEMENTED }, - { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, - [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, - [GPMODE_ALL_PAGES] = IMPLEMENTED }, - { [GPMODE_R_W_ERROR_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_PAGE] = IMPLEMENTED, - [GPMODE_CDROM_AUDIO_PAGE] = IMPLEMENTED, - [GPMODE_CAPABILITIES_PAGE] = IMPLEMENTED, - [GPMODE_ALL_PAGES] = IMPLEMENTED } + { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED }, + { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED }, + { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED }, + { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED } }; const uint8_t cdrom_mode_sense_pages_default[CDROM_NUM][0x40][0x40] = { - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; uint8_t cdrom_mode_sense_pages_changeable[CDROM_NUM][0x40][0x40] = { - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 0, 0, 0, 0, 0 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0xFF, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } } + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; uint8_t cdrom_mode_sense_pages_saved[CDROM_NUM][0x40][0x40] = { - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, - { [GPMODE_R_W_ERROR_PAGE] = { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, - [GPMODE_CDROM_PAGE] = { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, - [GPMODE_CDROM_AUDIO_PAGE] = { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, - [GPMODE_CAPABILITIES_PAGE] = { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } }, + { { 0, 0 }, + { GPMODE_R_W_ERROR_PAGE, 6, 0, 5, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CDROM_PAGE, 6, 0, 1, 0, 60, 0, 75 }, + { 0x8E, 0xE, 4, 0, 0, 0, 0, 75, 1, 0xFF, 2, 0xFF, 0, 0, 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { GPMODE_CAPABILITIES_PAGE, 0x12, 0, 0, 1, 0, 0, 0, 0x02, 0xC2, 0, 2, 0, 0, 0x02, 0xC2, 0, 0, 0, 0 } } }; int cdrom_do_log = 0; @@ -379,6 +895,8 @@ int cdrom_current_mode(int id) { return (cdrom[id].features & 1) ? 2 : 1; } + + return 0; } /* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ @@ -423,6 +941,8 @@ int cdrom_atapi_phase_to_scsi(uint8_t id) return 4; } } + + return 0; } int cdrom_lba_to_msf_accurate(int lba) @@ -469,6 +989,8 @@ void cdrom_mode_sense_load(uint8_t id) case 3: f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "rb"); break; + default: + return; } if (!f) { @@ -495,6 +1017,8 @@ void cdrom_mode_sense_save(uint8_t id) case 3: f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "wb"); break; + default: + return; } if (!f) { @@ -738,9 +1262,9 @@ int cdrom_mode_select_write(uint8_t id, uint8_t val) uint8_t cdrom_read_capacity_cdb[12] = {0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static int cdrom_pass_through(uint8_t id, int *len, uint8_t *cdb, uint8_t *buffer); +static int cdrom_pass_through(uint8_t id, uint32_t *len, uint8_t *cdb, uint8_t *buffer); -int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, int *len) +int cdrom_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { int ret = 0; int size = 0; @@ -787,6 +1311,8 @@ uint8_t cdrom_mode_sense_read(uint8_t id, uint8_t page_control, uint8_t page, ui return cdrom_mode_sense_pages_default[id][page][pos]; break; } + + return 0; } uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, uint8_t block_descriptor_len) @@ -800,8 +1326,6 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, type &= 0x3f; - int len = 0; - if (block_descriptor_len) { buf[pos++] = 1; /* Density code. */ @@ -1129,14 +1653,27 @@ static void cdrom_data_phase_error(uint8_t id) cdrom_cmd_error(id); } -static int cdrom_pass_through(uint8_t id, int *len, uint8_t *cdb, uint8_t *buffer) +static int cdrom_pass_through(uint8_t id, uint32_t *len, uint8_t *cdb, uint8_t *buffer) { int ret = 0; - // uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; + uint8_t temp_cdb[16]; - // ret = cdrom_drives[id].handler->pass_through(id, cdrom[id].current_cdb, cdbufferb + cdrom[id].data_pos, len); - ret = cdrom_drives[id].handler->pass_through(id, cdb, buffer, len); - // cdrom_log("CD-ROM %i: Data from pass through: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, cdbufferb[cdrom[id].data_pos + 0], cdbufferb[cdrom[id].data_pos + 1], cdbufferb[cdrom[id].data_pos + 2], cdbufferb[cdrom[id].data_pos + 3], cdbufferb[cdrom[id].data_pos + 4], cdbufferb[cdrom[id].data_pos + 5], cdbufferb[cdrom[id].data_pos + 6], cdbufferb[cdrom[id].data_pos + 7]); + memset(temp_cdb, 0, 16); + + if (cdb[0] == 8) + { + temp_cdb[0] = 0x28; + temp_cdb[8] = cdb[4]; + temp_cdb[3] = cdb[1]; + temp_cdb[4] = cdb[2]; + temp_cdb[5] = cdb[3]; + } + else + { + memcpy(temp_cdb, cdb, 16); + } + + ret = cdrom_drives[id].handler->pass_through(id, temp_cdb, buffer, len); cdrom_log("CD-ROM %i: Data from pass through: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); cdrom_log("CD-ROM %i: Returned value: %i\n", id, ret); @@ -1165,7 +1702,7 @@ static int cdrom_pass_through(uint8_t id, int *len, uint8_t *cdb, uint8_t *buffe } } -int cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) +void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) { int temp = 0; @@ -1221,7 +1758,7 @@ int cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) } } -int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) +int cdrom_read_data(uint8_t id, int msf, int type, int flags, uint32_t *len) { uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; @@ -1247,7 +1784,7 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) if (cdrom[id].sector_pos > (cdsize - 1)) { - // cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); + /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ cdrom_lba_out_of_range(id); return 0; } @@ -1258,7 +1795,7 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) { if (cdrom[id].sector_pos > (cdrom_drives[id].handler->size(id) - 1)) { - // cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); + /* cdrom_log("CD-ROM %i: Trying to read beyond the end of disc\n", id); */ cdrom_lba_out_of_range(id); return 0; } @@ -1290,9 +1827,8 @@ int cdrom_read_data(uint8_t id, int msf, int type, int flags, int *len) return 1; } -int cdrom_read_blocks(uint8_t id, int *len, int first_batch) +int cdrom_read_blocks(uint8_t id, uint32_t *len, int first_batch) { - int i = 0; int ret = 0; int msf = 0; @@ -1385,7 +1921,7 @@ static int cdrom_read_dvd_structure(uint8_t id, int format, const uint8_t *packe total_sectors >>= 2; if (total_sectors == 0) { - // return -ASC_MEDIUM_NOT_PRESENT; + /* return -ASC_MEDIUM_NOT_PRESENT; */ cdrom_not_ready(id); return 0; } @@ -1567,7 +2103,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) if (cdrom_drives[id].handler->medium_changed(id)) { - // cdrom_log("CD-ROM %i: Medium has changed...\n", id); + /* cdrom_log("CD-ROM %i: Medium has changed...\n", id); */ cdrom_insert(id); } @@ -1588,7 +2124,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) /* Only increment the unit attention phase if the command can not pass through it. */ if (!(cdrom_command_flags[cdb[0]] & ALLOW_UA)) { - // cdrom_log("CD-ROM %i: Unit attention now 2\n", id); + /* cdrom_log("CD-ROM %i: Unit attention now 2\n", id); */ cdrom[id].unit_attention = 2; cdrom_log("CD-ROM %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); cdrom_unit_attention(id); @@ -1599,7 +2135,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { if (cdb[0] != GPCMD_REQUEST_SENSE) { - // cdrom_log("CD-ROM %i: Unit attention now 0\n", id); + /* cdrom_log("CD-ROM %i: Unit attention now 0\n", id); */ cdrom[id].unit_attention = 0; } } @@ -1636,7 +2172,7 @@ void cdrom_clear_callback(uint8_t channel) static void cdrom_seek(uint8_t id, uint32_t pos) { - // cdrom_log("CD-ROM %i: Seek %08X\n", id, pos); + /* cdrom_log("CD-ROM %i: Seek %08X\n", id, pos); */ cdrom[id].seek_pos = pos; if (cdrom_drives[id].handler->stop) { @@ -1710,7 +2246,7 @@ void cdrom_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) } } - // cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]); + /* cdrom_log("CD-ROM %i: Reporting sense: %02X %02X %02X\n", id, cdbufferb[2], cdbufferb[12], cdbufferb[13]); */ if (buffer[2] == SENSE_UNIT_ATTENTION) { @@ -1729,7 +2265,7 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len if (cdrom_drives[id].handler->medium_changed(id)) { - // cdrom_log("CD-ROM %i: Medium has changed...\n", id); + /* cdrom_log("CD-ROM %i: Medium has changed...\n", id); */ cdrom_insert(id); } @@ -1751,34 +2287,28 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len void cdrom_command(uint8_t id, uint8_t *cdb) { uint8_t *cdbufferb = (uint8_t *) cdrom[id].buffer; - uint8_t rcdmode = 0; - int c; - int len; + uint32_t len; int msf; int pos=0; - unsigned char temp; - uint32_t size; - uint8_t page_code; int max_len; int used_len; unsigned idx = 0; unsigned size_idx; unsigned preamble_len; int toc_format; - int temp_command; - int alloc_length; - int completed; + uint32_t alloc_length; uint8_t index = 0; int block_desc = 0; - int media; - int format; + int format = 0; int ret; int real_pos; int track = 0; - int ready = 0; - uint8_t device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; - uint8_t device_identify_ex[14] = { '8', '6', 'B', '_', 'C', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + char device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; + char device_identify_ex[14] = { '8', '6', 'B', '_', 'C', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; +#if 0 + int CdbLength; +#endif if (cdrom_drives[id].bus_type) { cdrom[id].status &= ~ERR_STAT; @@ -1802,18 +2332,19 @@ void cdrom_command(uint8_t id, uint8_t *cdb) memcpy(cdrom[id].current_cdb, cdb, cdrom[id].cdb_len); + cdrom[id].cd_status = cdrom_drives[id].handler->status(id); + if (cdb[0] != 0) { cdrom_log("CD-ROM %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i, Unit attention: %i\n", id, cdb[0], cdrom_sense_key, cdrom_asc, cdrom_ascq, ins, cdrom[id].unit_attention); cdrom_log("CD-ROM %i: Request length: %04X\n", id, cdrom[id].request_length); -// #if 0 - int CdbLength; +#if 0 for (CdbLength = 1; CdbLength < cdrom[id].cdb_len; CdbLength++) { cdrom_log("CD-ROM %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); } -// #endif +#endif } msf = cdb[1] & 2; @@ -1825,11 +2356,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb) return; } - if (cdb[0] != GPCMD_REQUEST_SENSE) - { - completed = cdrom_playing_completed(id); - } - switch (cdb[0]) { case GPCMD_TEST_UNIT_READY: @@ -1919,7 +2445,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } cdrom_data_command_finish(id, len, len, len, 0); - // cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); + /* cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); */ return; case GPCMD_READ_CD_OLD: @@ -1948,7 +2474,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) msf = 0; break; case GPCMD_READ_CD_MSF: - // cdrom_log("CD-ROM %i: Read CD MSF: Start MSF %02X%02X%02X End MSF %02X%02X%02X Flags %02X\n", id, cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); + /* cdrom_log("CD-ROM %i: Read CD MSF: Start MSF %02X%02X%02X End MSF %02X%02X%02X Flags %02X\n", id, cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); */ cdrom[id].sector_len = MSFtoLBA(cdb[6], cdb[7], cdb[8]); cdrom[id].sector_pos = MSFtoLBA(cdb[3], cdb[4], cdb[5]); @@ -1958,7 +2484,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_READ_CD_OLD: case GPCMD_READ_CD: - // cdrom_log("CD-ROM %i: Read CD: Start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n", id, cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); + /* cdrom_log("CD-ROM %i: Read CD: Start LBA %02X%02X%02X%02X Length %02X%02X%02X Flags %02X\n", id, cdb[2], cdb[3], cdb[4], cdb[5], cdb[6], cdb[7], cdb[8], cdb[9]); */ cdrom[id].sector_len = (cdb[6] << 16) | (cdb[7] << 8) | cdb[8]; cdrom[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; @@ -1968,14 +2494,14 @@ void cdrom_command(uint8_t id, uint8_t *cdb) if (!cdrom[id].sector_len) { - // cdrom_log("CD-ROM %i: All done - callback set\n", id); + /* cdrom_log("CD-ROM %i: All done - callback set\n", id); */ cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].callback = 20 * CDROM_TIME; break; } max_len = cdrom[id].sector_len; - // if (cdrom_drives[id].bus_type) + /* if (cdrom_drives[id].bus_type) */ if (cdrom_current_mode(id) == 2) { cdrom[id].requested_blocks = max_len; @@ -2003,7 +2529,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].all_blocks_total = cdrom[id].block_total; if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) { - readflash=1; + update_status_bar_icon(0x10 | id, 1); + } + else + { + update_status_bar_icon(0x10 | id, 0); } return; @@ -2132,7 +2662,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb) return; case GPCMD_GET_CONFIGURATION: - temp_command = cdb[0]; /* XXX: could result in alignment problems in some architectures */ len = (cdb[7] << 8) | cdb[8]; alloc_length = len; @@ -2398,7 +2927,6 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { return; } - cdrom_log("CD-ROM %i: Audio status: %i\n", id, temp); switch(cdrom[id].cd_status) { case CD_STATUS_PLAYING: @@ -2435,7 +2963,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { if (cdb[3] > 3) { - // cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", id, cdb[3]); + /* cdrom_log("CD-ROM %i: Read subchannel check condition %02X\n", id, cdb[3]); */ cdrom_invalid_field(id); return; } @@ -2453,7 +2981,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; } - memset(cdbufferb, 24, 0); + memset(cdbufferb, 0, 24); pos = 0; cdbufferb[pos++] = 0; cdbufferb[pos++] = 0; /*Audio status*/ @@ -2523,7 +3051,22 @@ void cdrom_command(uint8_t id, uint8_t *cdb) switch (cdb[7]) { - case 0x00 ... 0x7f: + case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: + case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: + case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: + case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: + case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: + case 0x38: case 0x39: case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f: + case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: + case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f: + case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67: + case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f: + case 0x70: case 0x71: case 0x72: case 0x73: case 0x74: case 0x75: case 0x76: case 0x77: + case 0x78: case 0x79: case 0x7a: case 0x7b: case 0x7c: case 0x7d: case 0x7e: case 0x7f: case 0xff: if (cdb[1] == 0) { @@ -2649,7 +3192,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) memset(cdbufferb, 0, 8); cdbufferb[0] = 5; /*CD-ROM*/ cdbufferb[1] = 0x80; /*Removable*/ - cdbufferb[3] = 0x21; + cdbufferb[2] = cdrom_drives[id].bus_type ? 0x02 : 0x00; /*SCSI-2 compliant*/ + cdbufferb[3] = cdrom_drives[id].bus_type ? 0x02 : 0x21; cdbufferb[4] = 31; ide_padstr8(cdbufferb + 8, 8, "86Box"); /* Vendor */ @@ -2740,13 +3284,13 @@ atapi_out: break; } - // cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", cdrom[id].phase, cdrom[id].request_length); + /* cdrom_log("CD-ROM %i: Phase: %02X, request length: %i\n", cdrom[id].phase, cdrom[id].request_length); */ } /* This is for block reads. */ int cdrom_block_check(uint8_t id) { - int alloc_length = 0; + uint32_t alloc_length = 0; int ret = 0; /* If this is a media access command, and we hit the end of the block but not the entire length, @@ -2801,7 +3345,6 @@ int cdrom_block_check(uint8_t id) /* This is the general ATAPI callback. */ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ { - int ret = 0; int old_pos = 0; if (!cdrom_drives[id].bus_type) @@ -2840,6 +3383,8 @@ int cdrom_mode_select_return(uint8_t id, int ret) { case 0: /* Invalid field in parameter list. */ + case -6: + /* Attempted to write to a non-existent CD-ROM drive (should never occur, but you never know). */ cdrom_invalid_field_pl(id); return -2; case 1: @@ -2860,10 +3405,12 @@ int cdrom_mode_select_return(uint8_t id, int ret) /* Unknown phase. */ cdrom_illegal_opcode(id); return -2; - case -6: + case -5: /* Command terminated successfully. */ - cdrom_command_complete(id); + /* cdrom_command_complete(id); */ return -1; + default: + return -15; } } @@ -2895,6 +3442,8 @@ int cdrom_read_from_ide_dma(uint8_t channel) return 1; } } + + return 0; } int cdrom_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) @@ -2963,6 +3512,8 @@ int cdrom_read_from_dma(uint8_t id) return 0; } } + + return 0; } int cdrom_write_to_ide_dma(uint8_t channel) @@ -2990,7 +3541,7 @@ int cdrom_write_to_ide_dma(uint8_t channel) { while(transfer_length > 0) { - // pclog("CD-ROM %i: ATAPI DMA on position: %08X...\n", id, cdbufferb + cdbufferb_pos); + /* pclog("CD-ROM %i: ATAPI DMA on position: %08X...\n", id, cdbufferb + cdbufferb_pos); */ bus_master_len = piix_bus_master_get_count(channel >> 1); ret = piix_bus_master_dma_read_ex(channel >> 1, cdbufferb + cdbufferb_pos); if (ret != 0) @@ -3003,17 +3554,19 @@ int cdrom_write_to_ide_dma(uint8_t channel) if (ret > 0) { - // pclog("CD-ROM %i: ATAPI DMA error\n", id); + /* pclog("CD-ROM %i: ATAPI DMA error\n", id); */ cdrom_data_phase_error(id); cdrom_phase_callback(id); return 0; } else { - // pclog("CD-ROM %i: ATAPI DMA successful\n", id); + /* pclog("CD-ROM %i: ATAPI DMA successful\n", id); */ return 1; } } + + return 0; } int cdrom_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) @@ -3087,6 +3640,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].status = READY_STAT; cdrom[id].phase = 3; cdrom[id].packet_status = 0xFF; + update_status_bar_icon(0x10 | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT: @@ -3101,6 +3655,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; + update_status_bar_icon(0x10 | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_IN: @@ -3115,6 +3670,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; + update_status_bar_icon(0x10 | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_ERROR: diff --git a/src/cdrom.h b/src/cdrom.h index 2902fd39d..eb5e4066e 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -46,7 +46,12 @@ typedef struct CDROM void (*exit)(uint8_t id); } CDROM; +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else typedef struct __attribute__((__packed__)) +#endif { uint8_t previous_command; int toctimes; @@ -115,10 +120,18 @@ typedef struct __attribute__((__packed__)) int init_length; } cdrom_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif extern cdrom_t cdrom[CDROM_NUM]; +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else typedef struct __attribute__((__packed__)) +#endif { int enabled; @@ -141,6 +154,9 @@ typedef struct __attribute__((__packed__)) uint8_t sound_on; uint8_t atapi_dma; } cdrom_drive_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif extern cdrom_drive_t cdrom_drives[CDROM_NUM]; @@ -199,6 +215,8 @@ int cdrom_lba_to_msf_accurate(int lba); void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); +void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); +void cdrom_insert(uint8_t id); #define cdrom_sense_error cdrom[id].sense[0] #define cdrom_sense_key cdrom[id].sense[2] diff --git a/src/codegen.h b/src/codegen.h index ed5ce3a5f..ad0b3f63a 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -69,7 +69,7 @@ typedef struct codeblock_t /*Code block is always entered with the same FPU top-of-stack*/ #define CODEBLOCK_STATIC_TOP 2 -static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) +static __inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) { codeblock_t *block = pages[phys >> 12].head; uint64_t a = _cs | ((uint64_t)phys << 32); @@ -87,7 +87,7 @@ static inline codeblock_t *codeblock_tree_find(uint32_t phys, uint32_t _cs) return block; } -static inline void codeblock_tree_add(codeblock_t *new_block) +static __inline void codeblock_tree_add(codeblock_t *new_block) { codeblock_t *block = pages[new_block->phys >> 12].head; uint64_t a = new_block->_cs | ((uint64_t)new_block->phys << 32); @@ -121,7 +121,7 @@ static inline void codeblock_tree_add(codeblock_t *new_block) } } -static inline void codeblock_tree_delete(codeblock_t *block) +static __inline void codeblock_tree_delete(codeblock_t *block) { codeblock_t *parent = block->parent; @@ -297,7 +297,7 @@ extern int block_pos; #define CPU_BLOCK_END() cpu_block_end = 1 -static inline void addbyte(uint8_t val) +static __inline void addbyte(uint8_t val) { codeblock[block_current].data[block_pos++] = val; if (block_pos >= BLOCK_MAX) @@ -306,7 +306,7 @@ static inline void addbyte(uint8_t val) } } -static inline void addword(uint16_t val) +static __inline void addword(uint16_t val) { *(uint16_t *)&codeblock[block_current].data[block_pos] = val; block_pos += 2; @@ -316,7 +316,7 @@ static inline void addword(uint16_t val) } } -static inline void addlong(uint32_t val) +static __inline void addlong(uint32_t val) { *(uint32_t *)&codeblock[block_current].data[block_pos] = val; block_pos += 4; @@ -326,7 +326,7 @@ static inline void addlong(uint32_t val) } } -static inline void addquad(uint64_t val) +static __inline void addquad(uint64_t val) { *(uint64_t *)&codeblock[block_current].data[block_pos] = val; block_pos += 8; diff --git a/src/codegen_ops_arith.h b/src/codegen_ops_arith.h index b732f9f9f..fc67be9f1 100644 --- a/src/codegen_ops_arith.h +++ b/src/codegen_ops_arith.h @@ -2,7 +2,7 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); host_reg = LOAD_REG_W(opcode & 7); @@ -21,7 +21,7 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); host_reg = LOAD_REG_L(opcode & 7); @@ -40,7 +40,7 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); host_reg = LOAD_REG_W(opcode & 7); @@ -59,7 +59,7 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); host_reg = LOAD_REG_L(opcode & 7); diff --git a/src/codegen_ops_fpu.h b/src/codegen_ops_fpu.h index 4fafa33ce..7c414c3b5 100644 --- a/src/codegen_ops_fpu.h +++ b/src/codegen_ops_fpu.h @@ -200,30 +200,30 @@ static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t return op_pc + 1; \ } -ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); -ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); -ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); -ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); -ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) +ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) +ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) +ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) +ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) +ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) +ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) +ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) +ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) +ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) +ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) +ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) +ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) +ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) +ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) +ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) +ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) +ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) +ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) +ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) +ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) +ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) +ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) +ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) #define ropFcompare(name, size, load, op) \ static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ @@ -252,10 +252,10 @@ static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uin return new_pc; \ } -ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); -ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); -ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW); -ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL); +ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S) +ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D) +ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW) +ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL) /*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { @@ -491,7 +491,7 @@ static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u int host_reg; FP_ENTER(); - host_reg = LOAD_VAR_W(&cpu_state.npxs); + host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxs); STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); return op_pc; @@ -631,8 +631,8 @@ static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 opFLDimm(1, 1.0) opFLDimm(L2T, 3.3219280948873623) -opFLDimm(L2E, 1.4426950408889634); -opFLDimm(PI, 3.141592653589793); -opFLDimm(EG2, 0.3010299956639812); -opFLDimm(LN2, 0.693147180559945); +opFLDimm(L2E, 1.4426950408889634) +opFLDimm(PI, 3.141592653589793) +opFLDimm(EG2, 0.3010299956639812) +opFLDimm(LN2, 0.693147180559945) opFLDimm(Z, 0.0) diff --git a/src/codegen_ops_jump.h b/src/codegen_ops_jump.h index 8dba96c7c..440f867ef 100644 --- a/src/codegen_ops_jump.h +++ b/src/codegen_ops_jump.h @@ -75,16 +75,16 @@ static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 return op_pc+1; } -static int BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC(CF_SET); + CALL_FUNC((void *) CF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); } -static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { int host_reg; @@ -122,7 +122,7 @@ static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not break; case FLAGS_UNKNOWN: - CALL_FUNC(ZF_SET); + CALL_FUNC((void *) ZF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else @@ -131,25 +131,25 @@ static int BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int not } } -static int BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC(VF_SET); + CALL_FUNC((void *) VF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); } -static int BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC(PF_SET); + CALL_FUNC((void *) PF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else TEST_NONZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); } -static int BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { int host_reg; @@ -204,7 +204,7 @@ static int BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int not break; case FLAGS_UNKNOWN: - CALL_FUNC(NF_SET); + CALL_FUNC((void *) NF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else diff --git a/src/codegen_ops_misc.h b/src/codegen_ops_misc.h index 9d9ee7507..63ee0d6bd 100644 --- a/src/codegen_ops_misc.h +++ b/src/codegen_ops_misc.h @@ -33,7 +33,7 @@ static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ if ((fetchdat & 0x30) != 0x00) return 0; - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); if ((fetchdat & 0xc0) == 0xc0) host_reg = LOAD_REG_B(fetchdat & 7); @@ -86,7 +86,7 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return 0; if ((fetchdat & 0x30) == 0x00) - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); if ((fetchdat & 0xc0) == 0xc0) host_reg = LOAD_REG_W(fetchdat & 7); @@ -167,6 +167,9 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint MEM_STORE_ADDR_EA_W(&_ss, host_reg); SP_MODIFY(-2); return op_pc + 1; + + default: + return -1; } } static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) @@ -178,7 +181,7 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return 0; if ((fetchdat & 0x30) == 0x00) - CALL_FUNC(flags_rebuild_c); + CALL_FUNC((void *) flags_rebuild_c); if ((fetchdat & 0xc0) == 0xc0) host_reg = LOAD_REG_L(fetchdat & 7); @@ -259,5 +262,8 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint MEM_STORE_ADDR_EA_L(&_ss, host_reg); SP_MODIFY(-4); return op_pc + 1; + + default: + return -1; } } diff --git a/src/codegen_ops_mmx.h b/src/codegen_ops_mmx.h index 14730cb93..1c425daa2 100644 --- a/src/codegen_ops_mmx.h +++ b/src/codegen_ops_mmx.h @@ -154,22 +154,22 @@ MMX_OP(ropPSUBSW, MMX_SUBSW) MMX_OP(ropPSUBUSB, MMX_SUBUSB) MMX_OP(ropPSUBUSW, MMX_SUBUSW) -MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW); -MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD); -MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ); -MMX_OP(ropPACKSSWB, MMX_PACKSSWB); -MMX_OP(ropPCMPGTB, MMX_PCMPGTB); -MMX_OP(ropPCMPGTW, MMX_PCMPGTW); -MMX_OP(ropPCMPGTD, MMX_PCMPGTD); -MMX_OP(ropPACKUSWB, MMX_PACKUSWB); -MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW); -MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD); -MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ); -MMX_OP(ropPACKSSDW, MMX_PACKSSDW); +MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW) +MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD) +MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ) +MMX_OP(ropPACKSSWB, MMX_PACKSSWB) +MMX_OP(ropPCMPGTB, MMX_PCMPGTB) +MMX_OP(ropPCMPGTW, MMX_PCMPGTW) +MMX_OP(ropPCMPGTD, MMX_PCMPGTD) +MMX_OP(ropPACKUSWB, MMX_PACKUSWB) +MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW) +MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD) +MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ) +MMX_OP(ropPACKSSDW, MMX_PACKSSDW) -MMX_OP(ropPCMPEQB, MMX_PCMPEQB); -MMX_OP(ropPCMPEQW, MMX_PCMPEQW); -MMX_OP(ropPCMPEQD, MMX_PCMPEQD); +MMX_OP(ropPCMPEQB, MMX_PCMPEQB) +MMX_OP(ropPCMPEQW, MMX_PCMPEQW) +MMX_OP(ropPCMPEQD, MMX_PCMPEQD) MMX_OP(ropPSRLW, MMX_PSRLW) MMX_OP(ropPSRLD, MMX_PSRLD) @@ -180,9 +180,9 @@ MMX_OP(ropPSLLW, MMX_PSLLW) MMX_OP(ropPSLLD, MMX_PSLLD) MMX_OP(ropPSLLQ, MMX_PSLLQ) -MMX_OP(ropPMULLW, MMX_PMULLW); -MMX_OP(ropPMULHW, MMX_PMULHW); -MMX_OP(ropPMADDWD, MMX_PMADDWD); +MMX_OP(ropPMULLW, MMX_PMULLW) +MMX_OP(ropPMULHW, MMX_PMULHW) +MMX_OP(ropPMADDWD, MMX_PMADDWD) static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { diff --git a/src/codegen_ops_mov.h b/src/codegen_ops_mov.h index bfee56a29..4679c03f4 100644 --- a/src/codegen_ops_mov.h +++ b/src/codegen_ops_mov.h @@ -512,22 +512,22 @@ static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, switch (fetchdat & 0x38) { case 0x00: /*ES*/ - host_reg = LOAD_VAR_WL(&ES); + host_reg = LOAD_VAR_WL((uintptr_t) &ES); break; case 0x08: /*CS*/ - host_reg = LOAD_VAR_WL(&CS); + host_reg = LOAD_VAR_WL((uintptr_t) &CS); break; case 0x18: /*DS*/ - host_reg = LOAD_VAR_WL(&DS); + host_reg = LOAD_VAR_WL((uintptr_t) &DS); break; case 0x10: /*SS*/ - host_reg = LOAD_VAR_WL(&SS); + host_reg = LOAD_VAR_WL((uintptr_t) &SS); break; case 0x20: /*FS*/ - host_reg = LOAD_VAR_WL(&FS); + host_reg = LOAD_VAR_WL((uintptr_t) &FS); break; case 0x28: /*GS*/ - host_reg = LOAD_VAR_WL(&GS); + host_reg = LOAD_VAR_WL((uintptr_t) &GS); break; default: return 0; diff --git a/src/codegen_ops_stack.h b/src/codegen_ops_stack.h index 082d8a4e3..9aadbaa4e 100644 --- a/src/codegen_ops_stack.h +++ b/src/codegen_ops_stack.h @@ -85,7 +85,7 @@ static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_3 static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -97,7 +97,7 @@ static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -110,7 +110,7 @@ static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -122,7 +122,7 @@ static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - int host_reg; + /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -136,7 +136,7 @@ static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { uint16_t offset = fetchdat & 0xffff; - int host_reg; + /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -149,7 +149,7 @@ static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { uint16_t offset = fetchdat & 0xffff; - int host_reg; + /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -254,8 +254,6 @@ ROP_PUSH_SEG(SS) #define ROP_POP_SEG(seg, rseg) \ static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ { \ - int host_reg; \ - \ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ LOAD_STACK_TO_EA(0); \ MEM_LOAD_ADDR_EA_W(&_ss); \ @@ -266,8 +264,6 @@ static uint32_t ropPOP_ ## seg ## _16(uint8_t opcode, uint32_t fetchdat, uint32_ } \ static uint32_t ropPOP_ ## seg ## _32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ { \ - int host_reg; \ - \ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); \ LOAD_STACK_TO_EA(0); \ MEM_LOAD_ADDR_EA_W(&_ss); \ diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 30c013856..c8c18a28c 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -8,7 +8,7 @@ #define HOST_REG_END 4 #define HOST_REG_XMM_START 0 #define HOST_REG_XMM_END 7 -static inline int find_host_reg() +static __inline int find_host_reg() { int c; for (c = HOST_REG_START; c < HOST_REG_END; c++) @@ -21,7 +21,7 @@ static inline int find_host_reg() fatal("Out of host regs!\n"); return c; } -static inline int find_host_xmm_reg() +static __inline int find_host_xmm_reg() { int c; for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) @@ -942,7 +942,7 @@ static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u break; case 2: addbyte(0xb8); /*MOVL EAX, imm16*/ - addlong((fetchdat >> 8) & 0xffff);// pc++; + addlong((fetchdat >> 8) & 0xffff); addbyte(0x03); /*ADDL EAX, *mod1add[0][rm]*/ addbyte(0x05); addlong((uint32_t)mod1add[0][rm]); @@ -983,7 +983,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u { new_eaaddr = fastreadl(cs + (*op_pc) + 1); addbyte(0xb8); /*MOVL EAX, imm32*/ - addlong(new_eaaddr);// pc++; + addlong(new_eaaddr); (*op_pc) += 4; } else @@ -3600,29 +3600,29 @@ MMX_x86_OP(SUBSW, 0xe9) MMX_x86_OP(SUBUSB, 0xd8) MMX_x86_OP(SUBUSW, 0xd9) -MMX_x86_OP(PUNPCKLBW, 0x60); -MMX_x86_OP(PUNPCKLWD, 0x61); -MMX_x86_OP(PUNPCKLDQ, 0x62); -MMX_x86_OP(PCMPGTB, 0x64); -MMX_x86_OP(PCMPGTW, 0x65); -MMX_x86_OP(PCMPGTD, 0x66); +MMX_x86_OP(PUNPCKLBW, 0x60) +MMX_x86_OP(PUNPCKLWD, 0x61) +MMX_x86_OP(PUNPCKLDQ, 0x62) +MMX_x86_OP(PCMPGTB, 0x64) +MMX_x86_OP(PCMPGTW, 0x65) +MMX_x86_OP(PCMPGTD, 0x66) -MMX_x86_OP(PCMPEQB, 0x74); -MMX_x86_OP(PCMPEQW, 0x75); -MMX_x86_OP(PCMPEQD, 0x76); +MMX_x86_OP(PCMPEQB, 0x74) +MMX_x86_OP(PCMPEQW, 0x75) +MMX_x86_OP(PCMPEQD, 0x76) -MMX_x86_OP(PSRLW, 0xd1); -MMX_x86_OP(PSRLD, 0xd2); -MMX_x86_OP(PSRLQ, 0xd3); -MMX_x86_OP(PSRAW, 0xe1); -MMX_x86_OP(PSRAD, 0xe2); -MMX_x86_OP(PSLLW, 0xf1); -MMX_x86_OP(PSLLD, 0xf2); -MMX_x86_OP(PSLLQ, 0xf3); +MMX_x86_OP(PSRLW, 0xd1) +MMX_x86_OP(PSRLD, 0xd2) +MMX_x86_OP(PSRLQ, 0xd3) +MMX_x86_OP(PSRAW, 0xe1) +MMX_x86_OP(PSRAD, 0xe2) +MMX_x86_OP(PSLLW, 0xf1) +MMX_x86_OP(PSLLD, 0xf2) +MMX_x86_OP(PSLLQ, 0xf3) -MMX_x86_OP(PMULLW, 0xd5); -MMX_x86_OP(PMULHW, 0xe5); -MMX_x86_OP(PMADDWD, 0xf5); +MMX_x86_OP(PMULLW, 0xd5) +MMX_x86_OP(PMULHW, 0xe5) +MMX_x86_OP(PMADDWD, 0xf5) static void MMX_PACKSSWB(int dst_reg, int src_reg) { diff --git a/src/codegen_ops_xchg.h b/src/codegen_ops_xchg.h index 9a72c9a5a..597d26e1b 100644 --- a/src/codegen_ops_xchg.h +++ b/src/codegen_ops_xchg.h @@ -44,9 +44,9 @@ OP_XCHG_EAX_(EBP) static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { -// #ifdef __amd64__ - // return 0; -// #else +/* #ifdef __amd64__ + return 0; +#else */ int src_reg, dst_reg, temp_reg; if ((fetchdat & 0xc0) != 0xc0) @@ -59,7 +59,7 @@ static uint32_t ropXCHG_b(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin STORE_REG_TARGET_B_RELEASE(temp_reg, fetchdat & 7); return op_pc + 1; -// #endif +/* #endif */ } static uint32_t ropXCHG_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { diff --git a/src/codegen_timing_486.c b/src/codegen_timing_486.c index 0cd8c25b7..19b958931 100644 --- a/src/codegen_timing_486.c +++ b/src/codegen_timing_486.c @@ -251,7 +251,7 @@ static int *opcode_timings_8x[8] = static int timing_count; static uint8_t last_prefix; -static inline int COUNT(int *c, int op_32) +static __inline int COUNT(int *c, int op_32) { if ((uintptr_t)c <= 10000) return (int)c; diff --git a/src/codegen_timing_686.c b/src/codegen_timing_686.c index 5b2b5eda5..c4b4cc456 100644 --- a/src/codegen_timing_686.c +++ b/src/codegen_timing_686.c @@ -819,7 +819,7 @@ static uint32_t opcode_timings_8x[8] = static int decode_delay; static uint8_t last_prefix; -static inline int COUNT(uint32_t c, int op_32) +static __inline int COUNT(uint32_t c, int op_32) { if (c & CYCLES_HAS_MULTI) { @@ -863,48 +863,39 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { case 0x0f: timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; -// pclog("timings 0f\n"); break; case 0xd8: timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; opcode = (opcode >> 3) & 7; -// pclog("timings d8\n"); break; case 0xd9: timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings d9\n"); break; case 0xda: timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; opcode = (opcode >> 3) & 7; -// pclog("timings da\n"); break; case 0xdb: timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings db\n"); break; case 0xdc: timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; opcode = (opcode >> 3) & 7; -// pclog("timings dc\n"); break; case 0xdd: timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; opcode = (opcode >> 3) & 7; -// pclog("timings dd\n"); break; case 0xde: timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; opcode = (opcode >> 3) & 7; -// pclog("timings de\n"); break; case 0xdf: timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; opcode = (opcode >> 3) & 7; -// pclog("timings df\n"); break; default: @@ -914,7 +905,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; if (!mod3) opcode = (fetchdat >> 3) & 7; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); break; case 0xc0: case 0xc1: @@ -935,22 +925,18 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) case 0xf6: timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; opcode = (fetchdat >> 3) & 7; -// pclog("timings f6\n"); break; case 0xf7: timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; opcode = (fetchdat >> 3) & 7; -// pclog("timings f7\n"); break; case 0xff: timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; opcode = (fetchdat >> 3) & 7; -// pclog("timings ff\n"); break; default: timings = mod3 ? opcode_timings_mod3 : opcode_timings; -// pclog("timings normal\n"); break; } } @@ -970,7 +956,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1; prev_full = 0; -// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } else if (((timings[opcode] & PAIR_MASK) == PAIR_X || (timings[opcode] & PAIR_MASK) == PAIR_X_BRANCH) && (prev_timings[opcode] & PAIR_MASK) == PAIR_X) @@ -980,7 +965,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1; prev_full = 0; -// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } else if (prev_regmask & regmask) { @@ -989,7 +973,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) codegen_block_cycles += COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay; decode_delay = (-COUNT(prev_timings[prev_opcode], prev_op_32)) + 1; prev_full = 0; -// pclog("Not pairable %i\n", COUNT(prev_timings[prev_opcode], prev_op_32) + decode_delay); } else { @@ -1003,7 +986,6 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) decode_delay = (-t_pair) + 1; prev_full = 0; -// pclog("Pairable %i %i %i %02x %02x\n", t_pair, t1, t2, opcode, prev_opcode); return; } } @@ -1016,12 +998,10 @@ void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) /*Instruction not pairable*/ codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay; decode_delay = (-COUNT(timings[opcode], op_32)) + 1; -// pclog("Not pairable %i\n", COUNT(timings[opcode], op_32) + decode_delay); } else { /*Instruction might pair with next*/ -// pclog("Might pair - %02x %02x %08x %08x %08x %p %p %p\n", last_prefix, opcode, timings[opcode], timings[opcode] & PAIR_MASK, PAIR_X_BRANCH, timings, opcode_timings_0f, opcode_timings_0f_mod3); prev_full = 1; prev_opcode = opcode; prev_timings = timings; diff --git a/src/codegen_timing_pentium.c b/src/codegen_timing_pentium.c index 31d4cafe7..6d678915e 100644 --- a/src/codegen_timing_pentium.c +++ b/src/codegen_timing_pentium.c @@ -819,7 +819,7 @@ static uint32_t opcode_timings_8x[8] = static int decode_delay; static uint8_t last_prefix; -static inline int COUNT(uint32_t c, int op_32) +static __inline int COUNT(uint32_t c, int op_32) { if (c & CYCLES_HAS_MULTI) { @@ -855,7 +855,6 @@ void codegen_timing_pentium_block_start() void codegen_timing_pentium_start() { -// decode_delay = 0; last_prefix = 0; } @@ -896,48 +895,39 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { case 0x0f: timings = mod3 ? opcode_timings_0f_mod3 : opcode_timings_0f; -// pclog("timings 0f\n"); break; case 0xd8: timings = mod3 ? opcode_timings_d8_mod3 : opcode_timings_d8; opcode = (opcode >> 3) & 7; -// pclog("timings d8\n"); break; case 0xd9: timings = mod3 ? opcode_timings_d9_mod3 : opcode_timings_d9; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings d9\n"); break; case 0xda: timings = mod3 ? opcode_timings_da_mod3 : opcode_timings_da; opcode = (opcode >> 3) & 7; -// pclog("timings da\n"); break; case 0xdb: timings = mod3 ? opcode_timings_db_mod3 : opcode_timings_db; opcode = mod3 ? opcode & 0x3f : (opcode >> 3) & 7; -// pclog("timings db\n"); break; case 0xdc: timings = mod3 ? opcode_timings_dc_mod3 : opcode_timings_dc; opcode = (opcode >> 3) & 7; -// pclog("timings dc\n"); break; case 0xdd: timings = mod3 ? opcode_timings_dd_mod3 : opcode_timings_dd; opcode = (opcode >> 3) & 7; -// pclog("timings dd\n"); break; case 0xde: timings = mod3 ? opcode_timings_de_mod3 : opcode_timings_de; opcode = (opcode >> 3) & 7; -// pclog("timings de\n"); break; case 0xdf: timings = mod3 ? opcode_timings_df_mod3 : opcode_timings_df; opcode = (opcode >> 3) & 7; -// pclog("timings df\n"); break; default: @@ -947,34 +937,28 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; if (!mod3) opcode = (fetchdat >> 3) & 7; -// pclog("timings 80 %p %p %p\n", (void *)timings, (void *)opcode_timings_mod3, (void *)opcode_timings_8x); break; case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; opcode = (fetchdat >> 3) & 7; -// pclog("timings c0\n"); break; case 0xf6: timings = mod3 ? opcode_timings_f6_mod3 : opcode_timings_f6; opcode = (fetchdat >> 3) & 7; -// pclog("timings f6\n"); break; case 0xf7: timings = mod3 ? opcode_timings_f7_mod3 : opcode_timings_f7; opcode = (fetchdat >> 3) & 7; -// pclog("timings f7\n"); break; case 0xff: timings = mod3 ? opcode_timings_ff_mod3 : opcode_timings_ff; opcode = (fetchdat >> 3) & 7; -// pclog("timings ff\n"); break; default: timings = mod3 ? opcode_timings_mod3 : opcode_timings; -// pclog("timings normal\n"); break; } } @@ -1007,7 +991,6 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if (t_pair < 1) fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); -// pclog("Paired timings : t_pair=%i t1=%i t2=%i u_opcode=%02x v_opcode=%02x %08x:%08x\n", t_pair, t1, t2, u_pipe_opcode, opcode, cs, pc); codegen_block_cycles += t_pair; decode_delay = (-t_pair) + 1; @@ -1021,7 +1004,6 @@ nopair: codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32) + decode_delay; decode_delay = (-COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32)) + 1; u_pipe_full = 0; -// pclog("Evicited U-pipe timings : t1=%i u_opcode=%02x decode_delay=%i %08x:%08x\n", COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32), u_pipe_opcode, decode_delay, cs, pc); } if ((timings[opcode] & PAIR_U) && !decode_delay) @@ -1038,7 +1020,6 @@ nopair: codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay; decode_delay = (-COUNT(timings[opcode], op_32)) + 1; -// pclog("Non-pairable timings : %08x t1=%i opcode=%02x mod3=%i decode_delay=%i %08x:%08x %08x %p %p\n", timings[opcode], COUNT(timings[opcode], op_32), opcode, mod3, decode_delay, cs, pc, opcode_timings[0x04], (void *)timings, (void *)opcode_timings); } void codegen_timing_pentium_block_end() diff --git a/src/codegen_timing_winchip.c b/src/codegen_timing_winchip.c index 342fbb0b6..5d1a26bf3 100644 --- a/src/codegen_timing_winchip.c +++ b/src/codegen_timing_winchip.c @@ -251,7 +251,7 @@ static int *opcode_timings_8x[8] = static int timing_count; static uint8_t last_prefix; -static inline int COUNT(int *c, int op_32) +static __inline int COUNT(int *c, int op_32) { if ((uintptr_t)c <= 10000) return (int)c; diff --git a/src/codegen_x86.c b/src/codegen_x86.c index 65eddfabd..e7971c383 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -80,7 +80,7 @@ uint32_t mem_check_write_l; static uint32_t gen_MEM_LOAD_ADDR_EA_B() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -130,7 +130,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B() static uint32_t gen_MEM_LOAD_ADDR_EA_W() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -187,7 +187,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W() static uint32_t gen_MEM_LOAD_ADDR_EA_L() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -240,7 +240,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L() static uint32_t gen_MEM_LOAD_ADDR_EA_Q() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -297,7 +297,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_Q() static uint32_t gen_MEM_STORE_ADDR_EA_B() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EBX, ESI*/ @@ -345,7 +345,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B() static uint32_t gen_MEM_STORE_ADDR_EA_W() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EBX, ESI*/ @@ -401,7 +401,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W() static uint32_t gen_MEM_STORE_ADDR_EA_L() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EBX, ESI*/ @@ -456,7 +456,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L() static uint32_t gen_MEM_STORE_ADDR_EA_Q() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = EBX/ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EDX, ESI*/ @@ -517,7 +517,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q() static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -568,7 +568,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong(gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err); + addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -579,7 +579,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -637,7 +637,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong(gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err); + addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -648,7 +648,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x89); /*MOV ESI, EDX*/ addbyte(0xd6); @@ -705,7 +705,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() addbyte(0xc7); /*MOV [ESP], gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong(gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err); + addlong((uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -716,7 +716,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EBX, ESI*/ @@ -763,7 +763,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong(gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err); + addlong((uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -774,7 +774,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EBX, ESI*/ @@ -829,7 +829,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong(gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); + addlong((uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -840,7 +840,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*dat = ECX, seg = ESI, addr = EAX*/ addbyte(0x89); /*MOV EBX, ESI*/ @@ -894,7 +894,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong(gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); + addlong((uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -904,7 +904,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() static uint32_t gen_MEM_CHECK_WRITE() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*seg = ESI, addr = EAX*/ @@ -966,7 +966,7 @@ static uint32_t gen_MEM_CHECK_WRITE() static uint32_t gen_MEM_CHECK_WRITE_W() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*seg = ESI, addr = EAX*/ @@ -1048,7 +1048,7 @@ static uint32_t gen_MEM_CHECK_WRITE_W() static uint32_t gen_MEM_CHECK_WRITE_L() { - uint32_t addr = &codeblock[block_current].data[block_pos]; + uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; /*seg = ESI, addr = EAX*/ @@ -1157,11 +1157,11 @@ void codegen_init() exit(-1); } #endif -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); + /* pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); */ block_current = BLOCK_SIZE; block_pos = 0; - mem_abrt_rout = &codeblock[block_current].data[block_pos]; + mem_abrt_rout = (uint32_t)&codeblock[block_current].data[block_pos]; addbyte(0x83); /*ADDL $16+4,%esp*/ addbyte(0xC4); addbyte(0x10+4); @@ -1205,10 +1205,16 @@ void codegen_init() block_pos = (block_pos + 15) & ~15; mem_check_write_l = gen_MEM_CHECK_WRITE_L(); - asm( +#ifdef __MSC__ + __asm { + fstcw cpu_state.old_npxc + } +#else + __asm( "fstcw %0\n" : "=m" (cpu_state.old_npxc) ); +#endif } void codegen_reset() @@ -1313,7 +1319,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } else { -// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); + /* pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); */ pages[block->phys_2 >> 12].block_2 = block->next_2; if (block->next_2) block->next_2->prev_2 = NULL; @@ -1380,11 +1386,11 @@ void codegen_block_init(uint32_t phys_addr) block_current = (block_current + 1) & BLOCK_MASK; block = &codeblock[block_current]; -// if (block->pc == 0xb00b4ff5) -// pclog("Init target block\n"); + /* if (block->pc == 0xb00b4ff5) + pclog("Init target block\n"); */ if (block->pc != 0) { -// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); + /* pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); */ delete_block(block); cpu_recomp_reuse++; } @@ -1457,7 +1463,7 @@ void codegen_block_start_recompile(codeblock_t *block) addbyte(0xBD); /*MOVL EBP, &cpu_state*/ addlong(((uintptr_t)&cpu_state) + 128); -// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); + /* pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); */ last_op32 = -1; last_ea_seg = NULL; @@ -1511,11 +1517,11 @@ void codegen_block_generate_end_mask() start_pc >>= PAGE_MASK_SHIFT; end_pc >>= PAGE_MASK_SHIFT; -// pclog("block_end: %08x %08x\n", start_pc, end_pc); + /* pclog("block_end: %08x %08x\n", start_pc, end_pc); */ for (; start_pc <= end_pc; start_pc++) { block->page_mask |= ((uint64_t)1 << start_pc); -// pclog(" %08x %llx\n", start_pc, block->page_mask); + /* pclog(" %08x %llx\n", start_pc, block->page_mask); */ } pages[block->phys >> 12].code_present_mask |= block->page_mask; @@ -1528,7 +1534,7 @@ void codegen_block_generate_end_mask() block->phys_2 = get_phys_noabrt(block->endpc); if (block->phys_2 != -1) { -// pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2); + /* pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2); */ start_pc = 0; end_pc = (block->endpc & 0xfff) >> PAGE_MASK_SHIFT; @@ -1537,19 +1543,19 @@ void codegen_block_generate_end_mask() if (!pages[block->phys_2 >> 12].block_2) mem_flush_write_page(block->phys_2, block->endpc); -// pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2); + /* pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2); */ if (!block->page_mask2) fatal("!page_mask2\n"); if (block->next_2) { -// pclog(" next_2->pc=%08x\n", block->next_2->pc); + /* pclog(" next_2->pc=%08x\n", block->next_2->pc); */ if (!block->next_2->pc) fatal("block->next_2->pc=0 %p\n", (void *)block->next_2); } } } -// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask); + /* pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask); */ recomp_page = -1; } @@ -1605,7 +1611,7 @@ void codegen_block_end_recompile(codeblock_t *block) block->next_2 = block->prev_2 = NULL; codegen_block_generate_end_mask(); add_to_block_list(block); -// pclog("End block %i\n", block_num); + /* pclog("End block %i\n", block_num); */ if (!(block->flags & CODEBLOCK_HAS_FPU)) block->flags &= ~CODEBLOCK_STATIC_TOP; @@ -1715,7 +1721,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, break; case 1: addbyte(0xb8); /*MOVL ,%eax*/ - addlong((uint32_t)(int8_t)(rmdat >> 8));// pc++; + addlong((uint32_t)(int8_t)(rmdat >> 8)); /* pc++; */ addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ addbyte(0x05); addlong((uint32_t)mod1add[0][cpu_rm]); @@ -1726,7 +1732,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, break; case 2: addbyte(0xb8); /*MOVL ,%eax*/ - addlong((fetchdat >> 8) & 0xffff);// pc++; + addlong((fetchdat >> 8) & 0xffff); /* pc++; */ addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ addbyte(0x05); addlong((uint32_t)mod1add[0][cpu_rm]); @@ -1763,7 +1769,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, { new_eaaddr = fastreadl(cs + (*op_pc) + 1); addbyte(0xb8); /*MOVL ,%eax*/ - addlong(new_eaaddr);// pc++; + addlong(new_eaaddr); /* pc++; */ (*op_pc) += 4; } else @@ -1843,8 +1849,10 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ addbyte(0x45); addbyte(cpu_state_offset(regs[cpu_rm].l)); -// addbyte(0xa1); /*MOVL regs[cpu_rm].l, %eax*/ -// addlong((uint32_t)&cpu_state.regs[cpu_rm].l); +#if 0 + addbyte(0xa1); /*MOVL regs[cpu_rm].l, %eax*/ + addlong((uint32_t)&cpu_state.regs[cpu_rm].l); +#endif cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; if (cpu_mod) { @@ -2086,8 +2094,10 @@ generate_call: } op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; -// if (output) -// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); +#if 0 + if (output) + pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); +#endif if (op_ssegs != last_ssegs) { last_ssegs = op_ssegs; @@ -2169,8 +2179,10 @@ generate_call: addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); -// addbyte(0xE8); /*CALL*/ -// addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4]))); +#if 0 + addbyte(0xE8); /*CALL*/ + addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4]))); +#endif codegen_endpc = (cs + cpu_state.pc) + 8; } diff --git a/src/config.c b/src/config.c index 234254fe5..1e22f6415 100644 --- a/src/config.c +++ b/src/config.c @@ -5,6 +5,7 @@ #include #include #include "config.h" +#include "ibm.h" char config_file_default[256]; @@ -148,9 +149,7 @@ void config_load(char *fn) strncpy(new_section->name, name, 256); list_add(&new_section->list, &config_head); - current_section = new_section; - -// pclog("New section : %s %p\n", name, (void *)current_section); + current_section = new_section; } else { @@ -182,8 +181,6 @@ void config_load(char *fn) strncpy(new_entry->name, name, 256); strncpy(new_entry->data, &buffer[data_pos], 256); list_add(&new_entry->list, ¤t_section->entry_head); - -// pclog("New data under section [%s] : %s = %s\n", current_section->name, new_entry->name, new_entry->data); } } diff --git a/src/cpu.c b/src/cpu.c index 085f4e1b7..d2e1b26f7 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -166,11 +166,13 @@ CPU cpus_8088[] = { /*8088 standard*/ {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0}, - {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, {"8088/8", CPU_8088, 1, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, +#if 0 + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, {"8088/10", CPU_8088, 2, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, {"8088/12", CPU_8088, 3, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, {"8088/16", CPU_8088, 4, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0}, +#endif {"", -1, 0, 0, 0, 0, 0,0,0,0} }; @@ -325,6 +327,7 @@ CPU cpus_i486[] = {"i486SX/25", CPU_i486SX, 2, 25000000, 1, 25000000, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3}, {"i486SX/33", CPU_i486SX, 3, 33333333, 1, 33333333, 0x42a, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3}, {"i486SX2/50", CPU_i486SX, 5, 50000000, 2, 25000000, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, + {"i486SX2/66 (Q0569)", CPU_i486SX, 6, 66666666, 2, 33333333, 0x45b, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,6,6}, {"i486DX/25", CPU_i486DX, 2, 25000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 4,4,3,3}, {"i486DX/33", CPU_i486DX, 3, 33333333, 1, 33333333, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 6,6,3,3}, {"i486DX/50", CPU_i486DX, 5, 50000000, 1, 25000000, 0x404, 0, 0, CPU_SUPPORTS_DYNAREC, 8,8,4,4}, @@ -1862,8 +1865,6 @@ void cpu_CPUID() EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_CMOV; - // EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_CMOV; - // EDX = 0x0183FBFF; } else if (EAX == 2) { @@ -1888,8 +1889,6 @@ void cpu_CPUID() EAX = CPUID; EBX = ECX = 0; EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_SEP | CPUID_FXSR | CPUID_CMOV; - // EDX = CPUID_FPU | CPUID_TSC | CPUID_MSR | CPUID_CMPXCHG8B | CPUID_MMX | CPUID_FXSR | CPUID_CMOV; - // EDX = 0x0183FBFF; } else if (EAX == 2) { @@ -1997,10 +1996,8 @@ void cpu_RDMSR() break; case CPU_PENTIUMPRO: - // case CPU_PENTIUM2: case CPU_PENTIUM2D: EAX = EDX = 0; - // pclog("RDMSR, ECX=%08X\n", ECX); switch (ECX) { case 0x10: @@ -2024,11 +2021,11 @@ void cpu_RDMSR() EAX = ecx79_msr & 0xffffffff; EDX = ecx79_msr >> 32; break; - case 0x88 ... 0x8B: + case 0x88: case 0x89: case 0x8A: case 0x8B: EAX = ecx8x_msr[ECX - 0x88] & 0xffffffff; EDX = ecx8x_msr[ECX - 0x88] >> 32; break; - case 0xC1 ... 0xC8: + case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: EAX = msr_ia32_pmc[ECX - 0xC1] & 0xffffffff; EDX = msr_ia32_pmc[ECX - 0xC1] >> 32; break; @@ -2040,7 +2037,7 @@ void cpu_RDMSR() EAX = ecx116_msr & 0xffffffff; EDX = ecx116_msr >> 32; break; - case 0x118 ... 0x11B: + case 0x118: case 0x119: case 0x11A: case 0x11B: EAX = ecx11x_msr[ECX - 0x118] & 0xffffffff; EDX = ecx11x_msr[ECX - 0x118] >> 32; break; @@ -2073,7 +2070,8 @@ void cpu_RDMSR() EAX = ecx1e0_msr & 0xffffffff; EDX = ecx1e0_msr >> 32; break; - case 0x200 ... 0x20F: + case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: if (ECX & 1) { EAX = mtrr_physmask_msr[(ECX - 0x200) >> 1] & 0xffffffff; @@ -2097,8 +2095,7 @@ void cpu_RDMSR() EAX = mtrr_fix16k_a000_msr & 0xffffffff; EDX = mtrr_fix16k_a000_msr >> 32; break; - case 0x268 ... 0x26F: - // ((ECX - 0x268) * 0x8000) + case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: EAX = mtrr_fix4k_msr[ECX - 0x268] & 0xffffffff; EDX = mtrr_fix4k_msr[ECX - 0x268] >> 32; break; @@ -2206,9 +2203,7 @@ void cpu_WRMSR() break; case CPU_PENTIUMPRO: - // case CPU_PENTIUM2: case CPU_PENTIUM2D: - // pclog("WRMSR, ECX=%08X\n", ECX); switch (ECX) { case 0x10: @@ -2224,10 +2219,10 @@ void cpu_WRMSR() case 0x79: ecx79_msr = EAX | ((uint64_t)EDX << 32); break; - case 0x88 ... 0x8B: + case 0x88: case 0x89: case 0x8A: case 0x8B: ecx8x_msr[ECX - 0x88] = EAX | ((uint64_t)EDX << 32); break; - case 0xC1 ... 0xC8: + case 0xC1: case 0xC2: case 0xC3: case 0xC4: case 0xC5: case 0xC6: case 0xC7: case 0xC8: msr_ia32_pmc[ECX - 0xC1] = EAX | ((uint64_t)EDX << 32); break; case 0xFE: @@ -2236,7 +2231,7 @@ void cpu_WRMSR() case 0x116: ecx116_msr = EAX | ((uint64_t)EDX << 32); break; - case 0x118 ... 0x011B: + case 0x118: case 0x119: case 0x11A: case 0x11B: ecx11x_msr[ECX - 0x118] = EAX | ((uint64_t)EDX << 32); break; case 0x11E: @@ -2244,17 +2239,14 @@ void cpu_WRMSR() break; case 0x174: if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - // pclog("WRMSR SYSENTER_CS: old=%04X, new=%04X\n", cs_msr, (uint16_t) (EAX & 0xFFFF)); cs_msr = EAX & 0xFFFF; break; case 0x175: if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - // pclog("WRMSR SYSENTER_ESP: old=%08X, new=%08X\n", esp_msr, EAX); esp_msr = EAX; break; case 0x176: if (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type == CPU_PENTIUMPRO) goto i686_invalid_wrmsr; - // pclog("WRMSR SYSENTER_EIP: old=%08X, new=%08X\n", eip_msr, EAX); eip_msr = EAX; break; case 0x186: @@ -2266,7 +2258,8 @@ void cpu_WRMSR() case 0x1E0: ecx1e0_msr = EAX | ((uint64_t)EDX << 32); break; - case 0x200 ... 0x20F: + case 0x200: case 0x201: case 0x202: case 0x203: case 0x204: case 0x205: case 0x206: case 0x207: + case 0x208: case 0x209: case 0x20A: case 0x20B: case 0x20C: case 0x20D: case 0x20E: case 0x20F: if (ECX & 1) mtrr_physmask_msr[(ECX - 0x200) >> 1] = EAX | ((uint64_t)EDX << 32); else @@ -2281,8 +2274,7 @@ void cpu_WRMSR() case 0x259: mtrr_fix16k_a000_msr = EAX | ((uint64_t)EDX << 32); break; - case 0x268 ... 0x26F: - // ((ECX - 0x268) * 0x8000) + case 0x268: case 0x269: case 0x26A: case 0x26B: case 0x26C: case 0x26D: case 0x26E: case 0x26F: mtrr_fix4k_msr[ECX - 0x268] = EAX | ((uint64_t)EDX << 32); break; case 0x277: diff --git a/src/cpu.h b/src/cpu.h index 1159caefc..cbf7b7516 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -133,7 +133,6 @@ extern uint64_t cpu_CR4_mask; #define CPU_SUPPORTS_DYNAREC 1 #define CPU_REQUIRES_DYNAREC 2 -// #define CPU_REQUIRES_DYNAREC 0 extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; extern int cpu_prefetch_cycles, cpu_prefetch_width; @@ -161,5 +160,6 @@ extern int isa_cycles; #define ISA_CYCLES(x) ((x * isa_cycles) >> ISA_CYCLES_SHIFT) void cpu_update_waitstates(); +void cpu_set(); #endif diff --git a/src/dac.c b/src/dac.c index 5a784d04c..7aecf02f5 100644 --- a/src/dac.c +++ b/src/dac.c @@ -2,6 +2,7 @@ see COPYING for more details */ #include "ibm.h" +#include "dac.h" uint8_t dac,dac2; uint8_t dacctrl; @@ -18,10 +19,8 @@ void writedac(uint16_t addr, uint8_t val) void writedacctrl(uint16_t addr, uint8_t val) { -// printf("Write DAC ctrl %02X %i\n",val,lptfifo); if (dacctrl&8 && !(val&8) && (lptfifo!=16)) { -// dac=dac2; dssbuffer[dssend++]=dac2; dssend&=15; lptfifo++; diff --git a/src/dac.h b/src/dac.h new file mode 100644 index 000000000..4a10e6c2f --- /dev/null +++ b/src/dac.h @@ -0,0 +1,2 @@ +void writedac(uint16_t addr, uint8_t val); +void writedacctrl(uint16_t addr, uint8_t val); diff --git a/src/device.c b/src/device.c index 44f6cb5e9..39a4c0c32 100644 --- a/src/device.c +++ b/src/device.c @@ -112,6 +112,8 @@ char *device_add_status_info(char *s, int max_len) devices[c]->add_status_info(s, max_len, device_priv[c]); } } + + return NULL; } int device_get_config_int(char *s) diff --git a/src/device.h b/src/device.h index 6ac7628d7..fb509ce7f 100644 --- a/src/device.h +++ b/src/device.h @@ -47,7 +47,10 @@ char *device_get_config_string(char *name); enum { DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ - DEVICE_AT = 2 /*Device requires an AT-compatible system*/ + DEVICE_AT = 2, /*Device requires an AT-compatible system*/ + DEVICE_PS2 = 4, /*Device requires a PS/1 or PS/2 system*/ + DEVICE_MCA = 0x20, /*Device requires the MCA bus*/ + DEVICE_PCI = 0x40 /*Device requires the PCI bus*/ }; int model_get_config_int(char *s); diff --git a/src/disc.c b/src/disc.c index e5d202775..70141de15 100644 --- a/src/disc.c +++ b/src/disc.c @@ -102,13 +102,9 @@ void disc_load(int drive, char *fn) int c = 0, size; char *p; FILE *f; -// pclog("disc_load %i %s\n", drive, fn); -// setejecttext(drive, ""); if (!fn) return; p = get_extension(fn); if (!p) return; -// setejecttext(drive, fn); - // pclog("Loading :%i %s %s\n", drive, fn,p); f = fopen(fn, "rb"); if (!f) return; fseek(f, -1, SEEK_END); @@ -118,12 +114,10 @@ void disc_load(int drive, char *fn) { if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { - // pclog("Loading as %s (UI write protected = %s)\n", p, ui_writeprot[drive] ? "yes" : "no"); driveloaders[drive] = c; loaders[c].load(drive, fn); drive_empty[drive] = 0; strcpy(discfns[drive], fn); - // fdd_set_head(real_drive(drive), 0); fdd_forced_seek(real_drive(drive), 0); disc_changed[drive] = 1; return; @@ -138,7 +132,6 @@ void disc_load(int drive, char *fn) void disc_close(int drive) { -// pclog("disc_close %i\n", drive); if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); @@ -210,8 +203,7 @@ void disc_poll(int drive) { if (drive >= FDD_NUM) { - disc_poll_time[drive] += (int) (((romset == ROM_MRTHOR) ? 8.0 : 32.0) * TIMER_USEC); - return; + fatal("Attempting to poll floppy drive %i that is not supposed to be there\n", drive); } disc_poll_time[drive] += (int) disc_real_period(drive); @@ -249,7 +241,7 @@ void disc_poll_3() int disc_get_bitcell_period(int rate) { - int bit_rate; + int bit_rate = 250; switch (rate) { @@ -312,7 +304,6 @@ void disc_reset() void disc_init() { -// pclog("disc_init %p\n", drives); drives[0].poll = drives[1].poll = drives[2].poll = drives[3].poll = 0; drives[0].seek = drives[1].seek = drives[2].seek = drives[3].seek = 0; drives[0].readsector = drives[1].readsector = drives[2].readsector = drives[3].readsector = 0; @@ -322,13 +313,8 @@ void disc_init() int oldtrack[FDD_NUM] = {0, 0, 0, 0}; void disc_seek(int drive, int track) { -// pclog("disc_seek: drive=%i track=%i\n", drive, track); if (drives[drive].seek) drives[drive].seek(drive, track); -// if (track != oldtrack[drive]) -// fdc_discchange_clear(drive); -// ddnoise_seek(track - oldtrack[drive]); -// oldtrack[drive] = track; } void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size) diff --git a/src/disc.h b/src/disc.h index bb6491ea4..32bb601a0 100644 --- a/src/disc.h +++ b/src/disc.h @@ -64,7 +64,6 @@ extern int swwp; extern int disable_write; extern int defaultwriteprot; -//extern char discfns[4][260]; extern int writeprot[FDD_NUM], fwriteprot[FDD_NUM]; extern int disc_track[FDD_NUM]; @@ -147,7 +146,7 @@ void d86f_reset_index_hole_pos(int drive, int side); uint16_t d86f_prepare_pretrack(int drive, int side, int iso); uint16_t d86f_prepare_sector(int drive, int side, int prev_pos, uint8_t *id_buf, uint8_t *data_buf, int data_len, int gap2, int gap3, int deleted, int bad_crc); -int gap3_sizes[5][8][256]; +int gap3_sizes[5][8][48]; void null_writeback(int drive); void null_write_data(int drive, int side, uint16_t pos, uint8_t data); diff --git a/src/disc_86f.c b/src/disc_86f.c index af9d5d58c..c1567a1d5 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -5,8 +5,6 @@ #include #include -// #include "crcspeed/crc64speed.h" -// #include "zlib.h" #include "lzf/lzf.h" #include "config.h" @@ -22,7 +20,7 @@ #define CHUNK 16384 -uint64_t poly = 0x42F0E1EBA9EA3693; /* ECMA normal */ +uint64_t poly = 0x42F0E1EBA9EA3693ll; /* ECMA normal */ uint64_t table[256]; @@ -86,25 +84,45 @@ enum /* 1 11 01 ??? */ STATE_0D_SPIN_TO_INDEX = 0xE8, /* FORMAT TRACK */ - STATE_0D_FORMAT_TRACK + STATE_0D_FORMAT_TRACK, + + /* 1 11 11 ??? */ + STATE_0D_NOP_SPIN_TO_INDEX = 0xF8, /* FORMAT TRACK */ + STATE_0D_NOP_FORMAT_TRACK }; static uint16_t CRCTable[256]; -typedef struct __attribute__((packed)) +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else +typedef struct __attribute__((__packed__)) +#endif { uint8_t buffer[10]; uint32_t pos; uint32_t len; } sliding_buffer_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif -typedef struct __attribute__((packed)) +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else +typedef struct __attribute__((__packed__)) +#endif { uint32_t sync_marks; uint32_t bits_obtained; uint32_t bytes_obtained; uint32_t sync_pos; } find_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif uint8_t encoded_fm[64] = { 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF, 0xAA, 0xAB, 0xAE, 0xAF, 0xBA, 0xBB, 0xBE, 0xBF, 0xEA, 0xEB, 0xEE, 0xEF, 0xFA, 0xFB, 0xFE, 0xFF, @@ -135,14 +153,22 @@ enum FMT_SECTOR_GAP3, FMT_POSTTRK_CHECK, - FMT_POSTTRK_GAP4, + FMT_POSTTRK_GAP4 }; -typedef struct __attribute__((packed)) +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else +typedef struct __attribute__((__packed__)) +#endif { unsigned nibble0 :4; unsigned nibble1 :4; } split_byte_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif typedef union { uint8_t byte; @@ -160,7 +186,12 @@ typedef union { Bits 10, 9 Zone type (3 = Commodore 64 zoned, 2 = Apple zoned, 1 = Pre-Apple zoned #2, 0 = Pre-Apple zoned #1) Bit 11 Data and surface bits are stored in reverse byte endianness */ -static struct __attribute__((packed)) +#ifdef __MSC__ +# pragma pack(push,1) +struct +#else +struct __attribute__((__packed__)) +#endif { FILE *f; uint16_t version; @@ -198,11 +229,14 @@ static struct __attribute__((packed)) uint32_t error_condition; int is_compressed; int id_found; - uint8_t original_file_name[2048]; + char original_file_name[2048]; uint8_t *filebuf; uint8_t *outbuf; uint32_t dma_over; } d86f[FDD_NUM]; +#ifdef __MSC__ +# pragma pack(pop) +#endif int d86f_do_log = 0; @@ -475,7 +509,6 @@ int d86f_get_array_size(int drive, int side) int array_size = 0; int rm = 0; int hole = 0; - int extra_bytes = 0; rm = d86f_get_rpm_mode(drive); hole = (d86f_handler[drive].disk_flags(drive) & 6) >> 1; switch (hole) @@ -833,7 +866,7 @@ void d86f_get_bit(int drive, int side) uint32_t track_word; uint32_t track_bit; uint16_t encoded_data; - uint16_t surface_data; + uint16_t surface_data = 0; uint16_t current_bit; uint16_t surface_bit; @@ -905,7 +938,7 @@ void d86f_put_bit(int drive, int side, int bit) uint32_t track_word; uint32_t track_bit; uint16_t encoded_data; - uint16_t surface_data; + uint16_t surface_data = 0; uint16_t current_bit; uint16_t surface_bit; @@ -1124,7 +1157,6 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_ { find->sync_marks++; find->sync_pos = d86f[drive].track_pos; - // d86f_log("Sync marks: %i\n", find->sync_marks); return; } @@ -1137,7 +1169,6 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_ disc_calccrc(decodefm(drive, d86f[drive].last_word[side]), &(d86f[drive].calc_crc)); find->sync_marks = find->bits_obtained = find->bytes_obtained = 0; find->sync_pos = 0xFFFFFFFF; - // d86f_log("AM found (%04X) (%02X)\n", req_am, d86f[drive].state); d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; d86f[drive].state++; return; @@ -1160,7 +1191,6 @@ void d86f_find_address_mark_mfm(int drive, int side, find_t *find, uint16_t req_ else { /* Not skip mode, process the sector anyway. */ - // d86f_log("Wrong AM found (%04X) (%02X)\n", other_am, d86f[drive].state); fdc_set_wrong_am(); d86f[drive].preceding_bit[side] = d86f[drive].last_word[side] & 1; d86f[drive].state++; @@ -1212,8 +1242,6 @@ void d86f_write_find_address_mark_mfm(int drive, int side, find_t *find) /* State 2: Read sector ID and CRC*/ void d86f_read_sector_id(int drive, int side, int match) { - uint16_t temp; - if (d86f[drive].id_find.bits_obtained) { if (!(d86f[drive].id_find.bits_obtained & 15)) @@ -1264,12 +1292,10 @@ void d86f_read_sector_id(int drive, int side, int match) else { /* CRC is valid. */ - // d86f_log("Sector ID found: %08X; Requested: %08X\n", d86f[drive].last_sector.dword, d86f[drive].req_sector.dword); d86f[drive].id_find.sync_marks = d86f[drive].id_find.bits_obtained = d86f[drive].id_find.bytes_obtained = 0; d86f[drive].id_found++; if ((d86f[drive].last_sector.dword == d86f[drive].req_sector.dword) || !match) { - // d86f_log("ID read (%02X)\n", d86f[drive].state); d86f_handler[drive].set_sector(drive, side, d86f[drive].last_sector.id.c, d86f[drive].last_sector.id.h, d86f[drive].last_sector.id.r, d86f[drive].last_sector.id.n); if (d86f[drive].state == STATE_02_READ_ID) { @@ -1291,12 +1317,10 @@ void d86f_read_sector_id(int drive, int side, int match) { if (d86f[drive].last_sector.id.c == 0xFF) { - // d86f_log("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].error_condition |= 8; } else { - // d86f_log("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].error_condition |= 0x10; } } @@ -1372,7 +1396,6 @@ void d86f_read_sector_data(int drive, int side) int data = 0; int recv_data = 0; int read_status = 0; - uint16_t temp; uint32_t sector_len = d86f[drive].last_sector.id.n; uint32_t crc_pos = 0; sector_len = 1 << (7 + sector_len); @@ -1402,7 +1425,6 @@ void d86f_read_sector_data(int drive, int side) if (read_status == -1) { d86f[drive].dma_over++; - // d86f_log("DMA over now: %i\n", d86f[drive].dma_over); } } } @@ -1420,7 +1442,6 @@ void d86f_read_sector_data(int drive, int side) /* We've got the data. */ if (d86f[drive].dma_over > 1) { - // d86f_log("DMA overrun while reading data!\n"); d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; d86f[drive].error_condition = 0; d86f[drive].state = STATE_IDLE; @@ -1432,10 +1453,6 @@ void d86f_read_sector_data(int drive, int side) d86f[drive].data_find.bits_obtained++; return; } - else - { - // d86f_log("Bytes over DMA: %i\n", d86f[drive].dma_over); - } if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state != STATE_02_READ_DATA)) { @@ -1448,7 +1465,6 @@ void d86f_read_sector_data(int drive, int side) } else if ((d86f[drive].calc_crc.word != d86f[drive].track_crc.word) && (d86f[drive].state == STATE_02_READ_DATA)) { - // printf("%04X != %04X (%08X)\n", d86f[drive].track_crc.word, d86f[drive].calc_crc.word, d86f[drive].last_sector.dword); d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; d86f[drive].error_condition |= 2; /* Mark that there was a data error. */ d86f[drive].state = STATE_IDLE; @@ -1507,7 +1523,6 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) { /* We're in the data field of the sector, use a CRC byte. */ d86f[drive].current_byte[side] = d86f[drive].calc_crc.bytes[(d86f[drive].data_find.bytes_obtained & 1)]; - // d86f_log("BO: %04X (%02X)\n", d86f[drive].data_find.bytes_obtained, d86f[drive].current_byte[side]); } d86f[drive].current_bit[side] = (15 - (d86f[drive].data_find.bits_obtained & 15)) >> 1; @@ -1591,7 +1606,6 @@ void d86f_write_sector_data(int drive, int side, int mfm, uint16_t am) { if (d86f[drive].dma_over > 1) { - // d86f_log("DMA overrun while writing data!\n"); d86f[drive].data_find.sync_marks = d86f[drive].data_find.bits_obtained = d86f[drive].data_find.bytes_obtained = 0; d86f[drive].error_condition = 0; d86f[drive].state = STATE_IDLE; @@ -1628,7 +1642,6 @@ void d86f_advance_bit(int drive, int side) if (d86f[drive].state != STATE_IDLE) { d86f[drive].index_count++; - // d86f_log("Index count now: %i\n", d86f[drive].index_count); } } } @@ -1650,7 +1663,7 @@ void d86f_spin_to_index(int drive, int side) if (d86f[drive].track_pos == d86f_handler[drive].index_hole_pos(drive, side)) { - if (d86f[drive].state == STATE_0D_SPIN_TO_INDEX) + if ((d86f[drive].state == STATE_0D_SPIN_TO_INDEX) || (d86f[drive].state == STATE_0D_NOP_SPIN_TO_INDEX)) { /* When starting format, reset format state to the beginning. */ d86f[drive].preceding_bit[side] = 1; @@ -1664,12 +1677,11 @@ void d86f_spin_to_index(int drive, int side) void d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, uint32_t pos) { - uint16_t encoded_byte, mask_data, mask_surface, mask_hole, mask_fuzzy; + uint16_t encoded_byte = 0, mask_data, mask_surface, mask_hole, mask_fuzzy; decoded_t dbyte, dpbyte; dbyte.byte = byte; dpbyte.byte = d86f[drive].preceding_bit[side]; - d86f[drive].preceding_bit[side] = encoded_byte & 1; if (type == 0) { @@ -1696,6 +1708,8 @@ void d86f_write_direct_common(int drive, int side, uint16_t byte, uint8_t type, } } + d86f[drive].preceding_bit[side] = encoded_byte & 1; + if (d86f_has_surface_desc(drive)) { mask_data = d86f[drive].track_encoded_data[side][pos] ^= 0xFFFF; @@ -1737,21 +1751,23 @@ void d86f_format_finish(int drive, int side, int mfm, uint16_t sc, uint16_t gap_ } d86f[drive].state = STATE_IDLE; - d86f_handler[drive].writeback(drive); - // d86f_log("Format finished (%i) (%i)!\n", d86f[drive].track_pos, sc); + + if (do_write) + { + d86f_handler[drive].writeback(drive); + } + d86f[drive].error_condition = 0; d86f[drive].datac = 0; fdc_sector_finishread(); } -void d86f_format_track(int drive, int side) +void d86f_format_track(int drive, int side, int do_write) { int data; - uint16_t max_len, temp, temp2; + uint16_t max_len; int mfm; - uint16_t i = 0; - uint16_t j = 0; uint16_t sc = 0; uint16_t dtl = 0; int gap_sizes[4] = { 0, 0, 0, 0 }; @@ -1764,7 +1780,6 @@ void d86f_format_track(int drive, int side) uint16_t idam_fm = 0x7EF5; uint16_t dataam_fm = 0x6FF5; uint16_t gap_fill = 0x4E; - int do_write = 0; mfm = d86f_is_mfm(drive); am_len = mfm ? 4 : 1; @@ -1776,7 +1791,6 @@ void d86f_format_track(int drive, int side) sc = fdc_get_format_sectors(); dtl = 128 << fdc_get_format_n(); gap_fill = mfm ? 0x4E : 0xFF; - do_write = (d86f[drive].version == D86FVER); switch(d86f[drive].format_state) { @@ -1789,6 +1803,7 @@ void d86f_format_track(int drive, int side) if (do_write) d86f_write_direct(drive, side, gap_fill, 0); break; case FMT_SECTOR_ID_SYNC: + max_len = sync_len; if (d86f[drive].datac <= 3) { data = fdc_getdata(0); @@ -1801,11 +1816,9 @@ void d86f_format_track(int drive, int side) data = 0; } d86f[drive].format_sector_id.byte_array[d86f[drive].datac] = data & 0xff; - // d86f_log("format_sector_id[%i] = %i\n", d86f[drive].datac, d86f[drive].format_sector_id.byte_array[d86f[drive].datac]); if (d86f[drive].datac == 3) { fdc_stop_id_request(); - // d86f_log("Formatting sector: %08X (%i) (%i)...\n", d86f[drive].format_sector_id.dword, d86f[drive].track_pos, sc); } } case FMT_PRETRK_SYNC: @@ -1890,15 +1903,17 @@ void d86f_format_track(int drive, int side) max_len = gap_sizes[3]; if (do_write) d86f_write_direct(drive, side, gap_fill, 0); break; + default: + max_len = 0; + break; } d86f[drive].datac++; d86f_advance_word(drive, side); - if ((d86f[drive].index_count) && (d86f[drive].format_state < FMT_SECTOR_ID_SYNC) || (d86f[drive].format_state > FMT_SECTOR_GAP3)) + if ((d86f[drive].index_count) && ((d86f[drive].format_state < FMT_SECTOR_ID_SYNC) || (d86f[drive].format_state > FMT_SECTOR_GAP3))) { - // d86f_log("Format finished regularly\n"); d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); return; } @@ -1920,7 +1935,6 @@ void d86f_format_track(int drive, int side) case FMT_POSTTRK_CHECK: if (d86f[drive].index_count) { - // d86f_log("Format finished with delay\n"); d86f_format_finish(drive, side, mfm, sc, gap_fill, do_write); return; } @@ -1942,6 +1956,16 @@ void d86f_format_track(int drive, int side) } } +void d86f_format_track_normal(int drive, int side) +{ + d86f_format_track(drive, side, (d86f[drive].version == D86FVER)); +} + +void d86f_format_track_nop(int drive, int side) +{ + d86f_format_track(drive, side, 0); +} + void d86f_poll(int drive) { int side = 0; @@ -1980,6 +2004,7 @@ void d86f_poll(int drive) { case STATE_02_SPIN_TO_INDEX: case STATE_0D_SPIN_TO_INDEX: + case STATE_0D_NOP_SPIN_TO_INDEX: d86f_spin_to_index(drive, side); return; case STATE_02_FIND_ID: @@ -2084,7 +2109,13 @@ void d86f_poll(int drive) case STATE_0D_FORMAT_TRACK: if (!(d86f[drive].track_pos & 15)) { - d86f_format_track(drive, side); + d86f_format_track_normal(drive, side); + } + return; + case STATE_0D_NOP_FORMAT_TRACK: + if (!(d86f[drive].track_pos & 15)) + { + d86f_format_track_nop(drive, side); } return; case STATE_IDLE: @@ -2098,7 +2129,6 @@ void d86f_poll(int drive) if (d86f_wrong_densel(drive) && (d86f[drive].state != STATE_IDLE)) { - // d86f_log("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].state = STATE_IDLE; fdc_noidam(); return; @@ -2110,7 +2140,6 @@ void d86f_poll(int drive) { case STATE_0A_FIND_ID: case STATE_SECTOR_NOT_FOUND: - // d86f_log("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].state = STATE_IDLE; fdc_noidam(); break; @@ -2121,7 +2150,6 @@ void d86f_poll(int drive) case STATE_05_FIND_DATA: case STATE_09_FIND_DATA: case STATE_0C_FIND_DATA: - // d86f_log("[State: %02X] [Side %i] No data address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); d86f[drive].state = STATE_IDLE; fdc_nodataam(); break; @@ -2145,24 +2173,20 @@ void d86f_poll(int drive) { if ((d86f[drive].error_condition & 0x18) == 0x08) { - // d86f_log("[State: %02X] [Side %i] Bad cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_badcylinder(); } if ((d86f[drive].error_condition & 0x10) == 0x10) { - // d86f_log("[State: %02X] [Side %i] Wrong cylinder (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_wrongcylinder(); } } else { - // d86f_log("[State: %02X] [Side %i] Sector not found (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_nosector(); } } else { - // d86f_log("[State: %02X] [Side %i] No ID address mark (%i != %i?) (%02X) (%08X) (%i)\n", d86f[drive].state, side, fdc_get_bitcell_period(), d86f_get_bitcell_period(drive), d86f_handler[drive].side_flags(drive), d86f[drive].req_sector.dword, d86f_handler[drive].get_raw_size(drive, side)); fdc_noidam(); } break; @@ -2245,7 +2269,7 @@ uint16_t d86f_prepare_pretrack(int drive, int side, int iso) d86f_write_direct_common(drive, side, mfm ? iam_mfm : iam_fm, 1, pos); pos = (pos + 1) % raw_size; } - for (i = 0; i < real_gap0_len; i++) + for (i = 0; i < real_gap1_len; i++) { d86f_write_direct_common(drive, side, gap_fill, 0, pos); pos = (pos + 1) % raw_size; @@ -2427,7 +2451,6 @@ void d86f_decompose_encoded_buffer(int drive, int side) uint16_t temp, temp2; uint32_t len; uint16_t *dst = d86f[drive].track_encoded_data[side]; - uint16_t *dst_s = d86f[drive].track_surface_data[side]; uint16_t *src1 = d86f[drive].thin_track_encoded_data[0][side]; uint16_t *src1_s = d86f[drive].thin_track_surface_data[0][side]; uint16_t *src2 = d86f[drive].thin_track_encoded_data[1][side]; @@ -2538,7 +2561,6 @@ void d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *d void d86f_seek(int drive, int track) { - uint8_t track_id = track; int sides; int side, thin_track; sides = d86f_get_sides(drive); @@ -2597,8 +2619,6 @@ void d86f_seek(int drive, int track) void d86f_write_track(int drive, int side, uint16_t *da0, uint16_t *sa0) { - // d86f_log("Pos: %08X\n", ftell(d86f[drive].f)); - fwrite(&(d86f[drive].side_flags[side]), 1, 2, d86f[drive].f); if (d86f_has_extra_bit_cells(drive)) @@ -2614,8 +2634,6 @@ void d86f_write_track(int drive, int side, uint16_t *da0, uint16_t *sa0) } fwrite(da0, 1, d86f_get_array_size(drive, side) << 1, d86f[drive].f); - - // d86f_log("Pos: %08X\n", ftell(d86f[drive].f)); } int d86f_get_track_table_size(int drive) @@ -2632,16 +2650,12 @@ int d86f_get_track_table_size(int drive) void d86f_writeback(int drive) { - uint8_t track_id = d86f[drive].cur_track; uint8_t header[32]; int sides, header_size; int side, thin_track; - // uint64_t crc64; uint32_t len; - int i = 0; int ret = 0; int logical_track = 0; - uint8_t tempb; FILE *cf; sides = d86f_get_sides(drive); header_size = d86f_header_size(drive); @@ -2656,9 +2670,7 @@ void d86f_writeback(int drive) fread(header, 1, header_size, d86f[drive].f); fseek(d86f[drive].f, 8, SEEK_SET); - // d86f_log("PosEx: %08X\n", ftell(d86f[drive].f)); fwrite(d86f[drive].track_offset, 1, d86f_get_track_table_size(drive), d86f[drive].f); - // d86f_log("PosEx: %08X\n", ftell(d86f[drive].f)); if (!fdd_doublestep_40(drive)) { @@ -2698,15 +2710,12 @@ void d86f_writeback(int drive) } if (d86f[drive].track_offset[logical_track]) { - // d86f_log("Writing track...\n"); fseek(d86f[drive].f, d86f[drive].track_offset[logical_track], SEEK_SET); d86f_write_track(drive, side, d86f[drive].track_encoded_data[side], d86f[drive].track_surface_data[side]); } } } - // d86f_log("Position: %08X\n", ftell(d86f[drive].f)); - if (d86f[drive].is_compressed) { /* The image is compressed. */ @@ -2729,7 +2738,6 @@ void d86f_writeback(int drive) fread(d86f[drive].filebuf, 1, len, d86f[drive].f); ret = lzf_compress(d86f[drive].filebuf, len, d86f[drive].outbuf, len - 1); - // ret = d86f_zlib(cf, d86f[drive].f, 0); if (!ret) { d86f_log("86F: Error compressing file\n"); @@ -2738,58 +2746,7 @@ void d86f_writeback(int drive) fwrite(d86f[drive].outbuf, 1, ret, cf); free(d86f[drive].outbuf); free(d86f[drive].filebuf); - -#ifdef DO_CRC64 - len = ftell(cf); - - fclose(cf); - cf = fopen(d86f[drive].original_file_name, "rb+"); - - crc64 = 0xffffffffffffffff; - fseek(cf, 8, SEEK_SET); - fwrite(&crc64, 1, 8, cf); - - fseek(cf, 0, SEEK_SET); - d86f[drive].filebuf = (uint8_t *) malloc(len); - fread(d86f[drive].filebuf, 1, len, cf); - *(uint64_t *) &(d86f[drive].filebuf[8]) = 0xffffffffffffffff; - - crc64 = (uint64_t) crc64speed(0, d86f[drive].filebuf, len); - free(d86f[drive].filebuf); - - fseek(cf, 8, SEEK_SET); - fwrite(&crc64, 1, 8, cf); - - /* Close the original file. */ - fclose(cf); -#endif } -#ifdef DO_CRC64 - else - { - fseek(d86f[drive].f, 0, SEEK_END); - len = ftell(d86f[drive].f); - - fseek(d86f[drive].f, 0, SEEK_SET); - - crc64 = 0xffffffffffffffff; - fseek(d86f[drive].f, 8, SEEK_SET); - fwrite(&crc64, 1, 8, d86f[drive].f); - - fseek(d86f[drive].f, 0, SEEK_SET); - d86f[drive].filebuf = (uint8_t *) malloc(len); - fread(d86f[drive].filebuf, 1, len, d86f[drive].f); - *(uint64_t *) &(d86f[drive].filebuf[8]) = 0xffffffffffffffff; - - crc64 = (uint64_t) crc64speed(0, d86f[drive].filebuf, len); - free(d86f[drive].filebuf); - - fseek(d86f[drive].f, 8, SEEK_SET); - fwrite(&crc64, 1, 8, d86f[drive].f); - } -#endif - - // d86f_log("d86f_writeback(): %08X\n", d86f[drive].track_offset[track]); } void d86f_stop(int drive) @@ -2819,7 +2776,6 @@ int d86f_common_command(int drive, int sector, int track, int side, int rate, in if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { - // d86f_log("Wrong side!\n"); fdc_noidam(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -2880,11 +2836,8 @@ void d86f_comparesector(int drive, int sector, int track, int side, int rate, in void d86f_readaddress(int drive, int side, int rate) { - // d86f_log("Reading sector ID on drive %i...\n", drive); - if (fdd_get_head(drive) && (d86f_get_sides(drive) == 1)) { - // d86f_log("Trying to access the second side of a single-sided disk\n"); fdc_noidam(); d86f[drive].state = STATE_IDLE; d86f[drive].index_count = 0; @@ -2952,7 +2905,7 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) return; } - if ((side && (d86f_get_sides(drive) == 1)) || !(d86f_can_format(drive))) + if (!(d86f_can_format(drive))) { fdc_cannotformat(); d86f[drive].state = STATE_IDLE; @@ -2960,49 +2913,48 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) return; } - if (!proxy) + if (!side || (d86f_get_sides(drive) == 2)) { - d86f_reset_index_hole_pos(drive, side); - - if (d86f[drive].cur_track > 256) + if (!proxy) { - // d86f_log("Track above 256\n"); - fdc_writeprotect(); - d86f[drive].state = STATE_IDLE; - d86f[drive].index_count = 0; - return; - } + d86f_reset_index_hole_pos(drive, side); - array_size = d86f_get_array_size(drive, side); - - if (d86f_has_surface_desc(drive)) - { - /* Preserve the physical holes but get rid of the fuzzy bytes. */ - for (i = 0; i < array_size; i++) + if (d86f[drive].cur_track > 256) { - temp = d86f[drive].track_encoded_data[side][i] ^ 0xffff; - temp2 = d86f[drive].track_surface_data[side][i]; - temp &= temp2; - d86f[drive].track_surface_data[side][i] = temp; + fdc_writeprotect(); + d86f[drive].state = STATE_IDLE; + d86f[drive].index_count = 0; + return; + } + + array_size = d86f_get_array_size(drive, side); + + if (d86f_has_surface_desc(drive)) + { + /* Preserve the physical holes but get rid of the fuzzy bytes. */ + for (i = 0; i < array_size; i++) + { + temp = d86f[drive].track_encoded_data[side][i] ^ 0xffff; + temp2 = d86f[drive].track_surface_data[side][i]; + temp &= temp2; + d86f[drive].track_surface_data[side][i] = temp; + } + } + /* Zero the data buffer. */ + memset(d86f[drive].track_encoded_data[side], 0, array_size << 1); + + d86f_add_track(drive, d86f[drive].cur_track, side); + if (!fdd_doublestep_40(drive)) + { + d86f_add_track(drive, d86f[drive].cur_track + 1, side); } } - /* Zero the data buffer. */ - memset(d86f[drive].track_encoded_data[side], 0, array_size << 1); - - d86f_add_track(drive, d86f[drive].cur_track, side); - if (!fdd_doublestep_40(drive)) - { - d86f_add_track(drive, d86f[drive].cur_track + 1, side); - } } - // d86f_log("Formatting track %i side %i\n", track, side); - d86f[drive].fill = fill; if (!proxy) { - // d86f[drive].side_flags[side] &= 0xc0; d86f[drive].side_flags[side] = 0; d86f[drive].side_flags[side] |= (fdd_getrpm(real_drive(drive)) == 360) ? 0x20 : 0; d86f[drive].side_flags[side] |= fdc_get_bit_rate(); @@ -3016,7 +2968,14 @@ void d86f_common_format(int drive, int side, int rate, uint8_t fill, int proxy) d86f[drive].index_count = d86f[drive].error_condition = d86f[drive].satisfying_bytes = d86f[drive].sector_count = 0; d86f[drive].dma_over = 0; - d86f[drive].state = STATE_0D_SPIN_TO_INDEX; + if (!side || (d86f_get_sides(drive) == 2)) + { + d86f[drive].state = STATE_0D_SPIN_TO_INDEX; + } + else + { + d86f[drive].state = STATE_0D_NOP_SPIN_TO_INDEX; + } } void d86f_proxy_format(int drive, int side, int rate, uint8_t fill) @@ -3046,12 +3005,8 @@ void d86f_load(int drive, char *fn) { uint32_t magic = 0; uint32_t len = 0; - uint32_t len2 = 0; - uint8_t temp_file_name[2048]; + char temp_file_name[2048]; uint16_t temp = 0; - uint8_t tempb = 0; - // uint64_t crc64 = 0; - // uint64_t read_crc64 = 0; int i = 0; FILE *tf; @@ -3173,8 +3128,6 @@ void d86f_load(int drive, char *fn) fread(&temp, 1, 2, tf); fwrite(&temp, 1, 2, d86f[drive].f); } - - // temp = d86f_zlib(d86f[drive].f, tf, 1); d86f[drive].filebuf = (uint8_t *) malloc(len); d86f[drive].outbuf = (uint8_t *) malloc(67108864); @@ -3328,19 +3281,15 @@ void d86f_load(int drive, char *fn) void d86f_init() { - disc_random_init(); - memset(d86f, 0, sizeof(d86f)); d86f_setupcrc(0x1021); - // crc64speed_init(); - d86f[0].state = d86f[1].state = STATE_IDLE; } void d86f_close(int drive) { - uint8_t temp_file_name[2048]; + char temp_file_name[2048]; append_filename(temp_file_name, pcempath, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 511); memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 13); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index a016d4462..091524b20 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -172,7 +172,6 @@ void fdi_read_revolution(int drive) memset(fdi[drive].track_data[1][density], 0, 106096); fdi[drive].tracklen[0][density] = fdi[drive].tracklen[1][density] = 100000; } - // pclog("Track is bigger than last track\n"); return; } @@ -185,16 +184,15 @@ void fdi_read_revolution(int drive) (track * fdi[drive].sides) + side, &fdi[drive].tracklen[side][density], &fdi[drive].trackindex[side][density], NULL, density); - // pclog("Side 0 [%i]: len %i, index %i\n", density, fdi[drive].tracklen[side][density], fdi[drive].trackindex[side][density]); if (!c) memset(fdi[drive].track_data[side][density], 0, fdi[drive].tracklen[side][density]); } - } - if (fdi[drive].sides == 1) - { - memset(fdi[drive].track_data[1][density], 0, 106096); - fdi[drive].tracklen[1][density] = 100000; + if (fdi[drive].sides == 1) + { + memset(fdi[drive].track_data[1][density], 0, 106096); + fdi[drive].tracklen[1][density] = 100000; + } } } @@ -264,10 +262,8 @@ void fdi_load(int drive, char *fn) } fdi[drive].h = fdi2raw_header(fdi[drive].f); -// if (!fdih[drive]) printf("Failed to load!\n"); fdi[drive].lasttrack = fdi2raw_get_last_track(fdi[drive].h); fdi[drive].sides = fdi2raw_get_last_head(fdi[drive].h) + 1; -// printf("Last track %i\n",fdilasttrack[drive]); d86f_register_fdi(drive); @@ -297,11 +293,9 @@ void fdi_seek(int drive, int track) track /= 2; } } - // pclog("fdi_seek(): %i %i (%i)\n", fdi[drive].lasttrack, track); if (!fdi[drive].f) return; -// printf("Track start %i\n",track); if (track < 0) track = 0; if (track > fdi[drive].lasttrack) @@ -314,5 +308,5 @@ void fdi_seek(int drive, int track) void fdi_init() { -// printf("FDI reset\n"); + return; } diff --git a/src/disc_imd.c b/src/disc_imd.c index f5db814f6..c69a0b674 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -28,7 +28,7 @@ typedef struct static struct { FILE *f; - uint8_t *buffer; + char *buffer; uint32_t start_offs; int track_count, sides; int track; @@ -38,7 +38,7 @@ static struct uint16_t current_side_flags[2]; uint8_t xdf_ordered_pos[256][2]; uint8_t interleave_ordered_pos[256][2]; - uint8_t *current_data[2]; + char *current_data[2]; uint8_t track_buffer[2][25000]; } imd[FDD_NUM]; @@ -53,18 +53,14 @@ void imd_load(int drive, char *fn) { uint32_t magic = 0; uint32_t fsize = 0; - uint8_t *buffer; - uint8_t *buffer2; + char *buffer; + char *buffer2; int i = 0; - int has_cyl_map = 0; - int has_head_map = 0; - int has_size_map = 0; int track_spt = 0; int sector_size = 0; int track = 0; int side = 0; int extra = 0; - int fm = 0; uint32_t last_offset = 0; uint32_t data_size = 512; uint32_t mfm = 0; @@ -72,7 +68,6 @@ void imd_load(int drive, char *fn) uint32_t track_total = 0; uint32_t raw_tsize = 0; uint32_t minimum_gap3 = 0; - // uint32_t minimum_gap4 = 12; uint32_t minimum_gap4 = 0; d86f_unregister(drive); @@ -149,7 +144,6 @@ void imd_load(int drive, char *fn) if (side & 1) imd[drive].sides = 2; extra = side & 0xC0; side &= 0x3F; - // pclog("IMD: Loading track %i, side %i\n", track, side); imd[drive].tracks[track][side].side_flags = (buffer2[0] % 3); if (!imd[drive].tracks[track][side].side_flags) imd[drive].disk_flags |= (0x02); @@ -295,10 +289,10 @@ int imd_track_is_xdf(int drive, int side, int track) int i, effective_sectors, xdf_sectors; int high_sectors, low_sectors; int max_high_id, expected_high_count, expected_low_count; - uint8_t *r_map; - uint8_t *n_map; - uint8_t *data_base; - uint8_t *cur_data; + char *r_map; + char *n_map; + char *data_base; + char *cur_data; effective_sectors = xdf_sectors = high_sectors = low_sectors = 0; @@ -341,12 +335,12 @@ int imd_track_is_xdf(int drive, int side, int track) if ((r_map[i] >= 0x81) && (r_map[i] <= max_high_id)) { high_sectors++; - imd[drive].xdf_ordered_pos[r_map[i]][side] = i; + imd[drive].xdf_ordered_pos[(int) r_map[i]][side] = i; } if ((r_map[i] >= 0x01) && (r_map[i] <= 0x08)) { low_sectors++; - imd[drive].xdf_ordered_pos[r_map[i]][side] = i; + imd[drive].xdf_ordered_pos[(int) r_map[i]][side] = i; } if ((high_sectors == expected_high_count) && (low_sectors == expected_low_count)) { @@ -376,7 +370,7 @@ int imd_track_is_xdf(int drive, int side, int track) if ((r_map[i] == (n_map[i] | 0x80))) { xdf_sectors++; - imd[drive].xdf_ordered_pos[r_map[i]][side] = i; + imd[drive].xdf_ordered_pos[(int) r_map[i]][side] = i; } cur_data += (128 << ((uint32_t) n_map[i])); } @@ -392,12 +386,14 @@ int imd_track_is_xdf(int drive, int side, int track) } return 0; } + + return 0; } int imd_track_is_interleave(int drive, int side, int track) { int i, effective_sectors; - uint8_t *r_map; + char *r_map; int track_spt; effective_sectors = 0; @@ -429,7 +425,7 @@ int imd_track_is_interleave(int drive, int side, int track) if ((r_map[i] >= 1) && (r_map[i] <= track_spt)) { effective_sectors++; - imd[drive].interleave_ordered_pos[r_map[i]][side] = i; + imd[drive].interleave_ordered_pos[(int) r_map[i]][side] = i; } } @@ -492,18 +488,16 @@ void imd_seek(int drive, int track) int real_sector = 0; int actual_sector = 0; - uint8_t *c_map; - uint8_t *h_map; - uint8_t *r_map; - uint8_t *n_map; + char *c_map; + char *h_map; + char *r_map; + char *n_map; uint8_t *data; uint32_t track_buf_pos[2] = { 0, 0 }; if (!imd[drive].f) return; - // pclog("IMD: Seeking...\n"); - if (!imd[drive].track_width && fdd_doublestep_40(drive)) track /= 2; @@ -514,8 +508,6 @@ void imd_seek(int drive, int track) imd[drive].current_side_flags[0] = imd[drive].tracks[track][0].side_flags; imd[drive].current_side_flags[1] = imd[drive].tracks[track][1].side_flags; - // pclog("IMD Seek: %02X %02X (%02X)\n", imd[drive].current_side_flags[0], imd[drive].current_side_flags[1], imd[drive].disk_flags); - d86f_reset_index_hole_pos(drive, 0); d86f_reset_index_hole_pos(drive, 1); @@ -543,7 +535,7 @@ void imd_seek(int drive, int track) if (n == 0xFF) { n_map = imd[drive].buffer + imd[drive].tracks[track][side].n_map_offs; - track_gap3 = gap3_sizes[track_rate][n_map[0]][imd[drive].tracks[track][side].params[3]]; + track_gap3 = gap3_sizes[track_rate][(int) n_map[0]][imd[drive].tracks[track][side].params[3]]; } else { @@ -586,7 +578,6 @@ void imd_seek(int drive, int track) if ((type == 2) || (type == 4)) deleted = 1; if ((type == 3) || (type == 4)) bad_crc = 1; - // pclog("IMD: (%i %i) %i %i %i %i (%i %i) (GPL=%i)\n", track, side, id[0], id[1], id[2], id[3], deleted, bad_crc, track_gap3); imd_sector_to_buffer(drive, track, side, data, actual_sector, ssize); current_pos = d86f_prepare_sector(drive, side, current_pos, id, data, ssize, 22, track_gap3, deleted, bad_crc); track_buf_pos[side] += ssize; @@ -627,8 +618,6 @@ void imd_seek(int drive, int track) } } } - - // pclog("Seeked to track: %i (%02X, %02X)\n", imd[drive].track, imd[drive].current_side_flags[0], imd[drive].current_side_flags[1]); } uint16_t imd_disk_flags(int drive) @@ -652,7 +641,7 @@ void imd_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_ int sc = 0; int sh = 0; int sn = 0; - uint8_t *c_map, *h_map, *r_map, *n_map; + char *c_map, *h_map, *r_map, *n_map; uint8_t id[4] = { 0, 0, 0, 0 }; sc = imd[drive].tracks[track][side].params[1]; sh = imd[drive].tracks[track][side].params[2]; @@ -673,10 +662,10 @@ void imd_set_sector(int drive, int side, uint8_t c, uint8_t h, uint8_t r, uint8_ if (c != imd[drive].track) return; for (i = 0; i < imd[drive].tracks[track][side].params[3]; i++) { - id[0] = (h & 0x80) ? c_map[i] : sc; - id[1] = (h & 0x40) ? h_map[i] : (sh & 1); + id[0] = (sh & 0x80) ? c_map[i] : sc; + id[1] = (sh & 0x40) ? h_map[i] : (sh & 1); id[2] = r_map[i]; - id[3] = (n == 0xFF) ? n_map[i] : sn; + id[3] = (sn == 0xFF) ? n_map[i] : sn; if ((id[0] == c) && (id[1] == h) && (id[2] == r) && @@ -693,18 +682,18 @@ void imd_writeback(int drive) int side; int track = imd[drive].track; + int i = 0; + + char *n_map; + + uint8_t h, n, spt; + uint32_t ssize; + if (writeprot[drive]) { return; } - int i = 0; - - uint8_t *n_map; - - uint8_t h, n, spt; - uint32_t ssize; - for (side = 0; side < imd[drive].sides; side++) { if (imd[drive].tracks[track][side].is_present) diff --git a/src/disc_img.c b/src/disc_img.c index 7f8417196..a9e60c880 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -37,7 +37,6 @@ static struct } img[FDD_NUM]; uint8_t dmf_r[21] = { 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10, 21, 11, 1 }; -static uint8_t xdf_spt[2] = { 6, 8 }; static uint8_t xdf_logical_sectors[2][2] = { { 38, 6 }, { 46, 8 } }; uint8_t xdf_physical_sectors[2][2] = { { 16, 3 }, { 19, 4 } }; uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } }; @@ -115,53 +114,126 @@ static uint8_t rates[6] = { 2, 2, 1, 4, 0, 3 }; static uint8_t holes[6] = { 0, 0, 0, 1, 1, 2 }; -int gap3_sizes[5][8][256] = { [0][1][16] = 0x54, - [0][2][18] = 0x6C, - [0][2][19] = 0x48, - [0][2][20] = 0x2A, - [0][2][21] = 0x08, /* Microsoft DMFWRITE.EXE uses this, 0x0C is used by FDFORMAT. */ - [0][2][22] = 0x02, - [0][2][23] = 0x01, - [0][3][10] = 0x83, - [0][3][11] = 0x26, - [1][2][11] = 0x54, - [1][2][12] = 0x1C, - [1][2][13] = 0x0E, - [1][3][6] = 0x79, - [1][3][7] = 0x06, - [2][1][10] = 0x32, - [2][1][11] = 0x0C, - [2][1][15] = 0x36, - [2][1][16] = 0x32, - [2][2][8] = 0x58, - [2][2][9] = 0x50, - [2][2][10] = 0x2E, - [2][2][21] = 0x1C, - [2][2][22] = 0x1C, - [2][3][4] = 0xF0, - [2][3][5] = 0x74, - [3][2][36] = 0x53, - [3][2][37] = 0x4E, - [3][2][38] = 0x3D, - [3][2][39] = 0x2C, - [3][2][40] = 0x1C, - [3][2][41] = 0x0D, - [3][2][42] = 0x02, - [3][2][46] = 0x01, - [3][3][18] = 0xF7, - [3][3][19] = 0xAF, - [3][3][20] = 0x6F, - [3][3][21] = 0x55, - [3][3][22] = 0x1F, - [4][1][32] = 0x36, - [4][2][14] = 0x92, - [4][2][15] = 0x54, - [4][2][16] = 0x38, - [4][2][17] = 0x23, - [4][2][19] = 0x01, - [4][3][8] = 0x74, - [4][3][9] = 0x24 -}; +int gap3_sizes[5][8][48] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][0] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][1] */ + 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][2] */ + 0x00, 0x00, 0x6C, 0x48, 0x2A, 0x08, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x26, 0x00, 0x00, 0x00, 0x00, /* [0][3] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][4] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][5] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][6] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [0][7] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][0] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][1] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x1C, 0x0E, 0x00, 0x00, /* [1][2] */ + 0x00, 0x00, 0x6C, 0x48, 0x2A, 0x08, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][3] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][4] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][5] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][6] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [1][7] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][0] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x0C, 0x00, 0x00, 0x00, 0x36, /* [2][1] */ + 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x50, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][2] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0xF0, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][3] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][4] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][5] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][6] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [2][7] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][0] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][1] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][2] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x4E, 0x3D, 0x2C, 0x1C, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][3] */ + 0x00, 0x00, 0xF7, 0xAF, 0x6F, 0x55, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][4] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][5] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][6] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [3][7] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][0] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][1] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x54, /* [4][2] */ + 0x38, 0x23, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][3] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][4] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][5] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][6] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* [4][7] */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }; void img_writeback(int drive); @@ -189,15 +261,9 @@ static int sector_size_code(int sector_size) } } -static int img_sector_size_code(int drive) -{ - return sector_size_code(img[drive].sector_size); -} - void img_init() { memset(img, 0, sizeof(img)); -// adl[0] = adl[1] = 0; } void d86f_register_img(int drive); @@ -245,8 +311,6 @@ void img_load(int drive, char *fn) uint8_t bpb_mid; /* Media type ID. */ uint8_t bpb_sectors; uint8_t bpb_sides; - uint32_t bpt; - uint8_t max_spt; /* Used for XDF detection. */ int temp_rate; uint8_t fdi, cqm, fdf; int i; @@ -635,6 +699,8 @@ jump_if_fdf: if (size <= (160*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; img[drive].sides = 1; } else if (size <= (180*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; img[drive].sides = 1; } + else if (size <= (315*1024)) { img[drive].sectors = 9; img[drive].tracks = 70; img[drive].sides = 1; } + else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; } else if (size <= (320*1024)) { img[drive].sectors = 8; img[drive].tracks = 40; } else if (size <= (360*1024)) { img[drive].sectors = 9; img[drive].tracks = 40; } /*Double density*/ else if (size <= (400*1024)) { img[drive].sectors = 10; img[drive].tracks = 80; img[drive].sides = 1; } /*DEC RX50*/ @@ -653,7 +719,6 @@ jump_if_fdf: else if (size <= 1720320) { img[drive].sectors = 21; img[drive].tracks = 80; } /*DMF format - used by Windows 95 */ else if (size <= 1741824) { img[drive].sectors = 21; img[drive].tracks = 81; } else if (size <= 1763328) { img[drive].sectors = 21; img[drive].tracks = 82; } - // else if (size <= 1802240) { img[drive].sectors = 11; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ else if (size <= 1802240) { img[drive].sectors = 22; img[drive].tracks = 80; img[drive].sector_size = 3; } /*High density (not supported by Tandy 1000)*/ else if (size == 1884160) { img[drive].sectors = 23; img[drive].tracks = 80; } /*XDF format - used by OS/2 Warp*/ else if (size <= 2949120) { img[drive].sectors = 36; img[drive].tracks = 80; } /*E density*/ @@ -839,9 +904,7 @@ void img_seek(int drive, int track) if (img[drive].disk_at_once) { cur_pos = (track * img[drive].sectors * ssize * img[drive].sides) + (side * img[drive].sectors * ssize); - // pclog("Current position: %i... ", cur_pos); memcpy(img[drive].track_data[side], img[drive].disk_data + cur_pos, img[drive].sectors * ssize); - // pclog("done!\n"); } else { @@ -864,7 +927,6 @@ void img_seek(int drive, int track) for (sector = 0; sector < img[drive].sectors; sector++) { - // sr = img[drive].dmf ? (dmf_r[sector]) : (sector + 1); if (img[drive].is_cqm) { if (img[drive].interleave) @@ -898,7 +960,6 @@ void img_seek(int drive, int track) id[3] = img[drive].sector_size; img[drive].sector_pos_side[side][sr] = side; img[drive].sector_pos[side][sr] = (sr - 1) * ssize; - // pclog("Seek: %i %i %i %i | %i %04X\n", id[0], id[1], id[2], id[3], side, (sr - 1) * ssize); current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[side][(sr - 1) * ssize], ssize, img[drive].gap2_size, img[drive].gap3_size, 0, 0); } } @@ -922,7 +983,6 @@ void img_seek(int drive, int track) { img[drive].sector_pos_side[xdf_img_sector.id.h][xdf_img_sector.id.r] = sside; img[drive].sector_pos[xdf_img_sector.id.h][xdf_img_sector.id.r] = img_pos; - // pclog("Side: %i, Position: %04X\n", sside, img_pos); } if (!is_t0) @@ -941,13 +1001,10 @@ void img_seek(int drive, int track) for (sector = 0; sector < xdf_physical_sectors[current_xdft][!is_t0]; sector++) { array_sector = (side * xdf_physical_sectors[current_xdft][!is_t0]) + sector; - // pclog("Sector %i, array sector %i\n", sector, array_sector); buf_side = img[drive].sector_pos_side[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; buf_pos = img[drive].sector_pos[xdf_disk_sector.id.h][xdf_disk_sector.id.r]; - // pclog("Side: %i, Position: %04X\n", buf_side, buf_pos); - id[0] = track; id[1] = xdf_disk_sector.id.h; id[2] = xdf_disk_sector.id.r; @@ -955,21 +1012,17 @@ void img_seek(int drive, int track) if (is_t0) { id[3] = 2; - // pclog("XDF Track 0: Registering sector: %i %i %i %i\n", id[0], id[1], id[2], id[3]); current_pos = d86f_prepare_sector(drive, side, current_pos, id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); } else { id[3] = id[2] & 7; - // pclog("XDF Track X: Registering sector: %i %i %i %i\n", id[0], id[1], id[2], id[3]); ssize = (128 << id[3]); current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[current_xdft][array_sector], id, &img[drive].track_data[buf_side][buf_pos], ssize, img[drive].gap2_size, xdf_gap3_sizes[current_xdft][!is_t0], 0, 0); } } } } - - // pclog("Seeked to track: %i\n", img[drive].track); } void img_writeback(int drive) diff --git a/src/disc_random.c b/src/disc_random.c index da4b09673..1712193e4 100644 --- a/src/disc_random.c +++ b/src/disc_random.c @@ -5,7 +5,7 @@ #include -#include +#include #include #include #include @@ -33,7 +33,15 @@ static __inline__ uint32_t rotr32c (uint32_t x, uint32_t n) static __inline__ unsigned long long rdtsc(void) { unsigned hi, lo; - __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); +#ifdef __MSC__ + __asm { + rdtsc + mov hi, edx ; EDX:EAX is already standard return!! + mov lo, eax + } +#else + __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); +#endif return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 ); } diff --git a/src/disc_td0.c b/src/disc_td0.c index 9e21a9b11..5905527b9 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -1,5 +1,5 @@ -// license:BSD-3-Clause -// copyright-holders:Miodrag Milanovic,Kiririn (translation to C and port to 86Box) +/* license:BSD-3-Clause + copyright-holders:Miodrag Milanovic,Kiririn (translation to C and port to 86Box) */ /********************************************************************* formats/td0_dsk.c @@ -22,7 +22,7 @@ #include -#define BUFSZ 512 // new input buffer +#define BUFSZ 512 /* new input buffer */ /* LZSS Parameters */ @@ -44,10 +44,10 @@ typedef struct { uint16_t r, - bufcnt,bufndx,bufpos, // string buffer - // the following to allow block reads from input in next_word() - ibufcnt,ibufndx; // input buffer counters - uint8_t inbuf[BUFSZ]; // input buffer + bufcnt,bufndx,bufpos, /* string buffer */ + /* the following to allow block reads from input in next_word() */ + ibufcnt,ibufndx; /* input buffer counters */ + uint8_t inbuf[BUFSZ]; /* input buffer */ } tdlzhuf; typedef struct @@ -72,8 +72,6 @@ typedef struct uint8_t getlen; } td0dsk_t; -//static td0dsk_t td0dsk; - typedef struct { uint8_t track; @@ -118,7 +116,7 @@ void floppy_image_read(int drive, char *buffer, uint32_t offset, uint32_t len) int td0_dsk_identify(int drive) { - uint8_t header[2]; + char header[2]; floppy_image_read(drive, header, 0, 2); if (header[0]=='T' && header[1]=='D') { @@ -230,7 +228,7 @@ int td0_state_next_word(td0dsk_t *state) if(state->tdctl.ibufcnt == 0) return(-1); } - while (state->getlen <= 8) { // typically reads a word at a time + while (state->getlen <= 8) { /* typically reads a word at a time */ state->getbuf |= state->tdctl.inbuf[state->tdctl.ibufndx++] << (8 - state->getlen); state->getlen += 8; } @@ -427,7 +425,7 @@ void td0_state_init_Decode(td0dsk_t *state) int i; state->getbuf = 0; state->getlen = 0; - state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; // input buffer is empty + state->tdctl.ibufcnt= state->tdctl.ibufndx = 0; /* input buffer is empty */ state->tdctl.bufcnt = 0; td0_state_StartHuff(state); for (i = 0; i < N - F; i++) @@ -439,11 +437,11 @@ void td0_state_init_Decode(td0dsk_t *state) int td0_state_Decode(td0dsk_t *state, uint8_t *buf, int len) /* Decoding/Uncompressing */ { int16_t c,pos; - int count; // was an unsigned long, seems unnecessary + int count; /* was an unsigned long, seems unnecessary */ for (count = 0; count < len; ) { if(state->tdctl.bufcnt == 0) { if((c = td0_state_DecodeChar(state)) < 0) - return(count); // fatal error + return(count); /* fatal error */ if (c < 256) { *(buf++) = c; state->text_buf[state->tdctl.r++] = c; @@ -452,13 +450,13 @@ int td0_state_Decode(td0dsk_t *state, uint8_t *buf, int len) /* Decoding/Uncomp } else { if((pos = td0_state_DecodePosition(state)) < 0) - return(count); // fatal error + return(count); /* fatal error */ state->tdctl.bufpos = (state->tdctl.r - pos - 1) & (N - 1); state->tdctl.bufcnt = c - 255 + THRESHOLD; state->tdctl.bufndx = 0; } } - else { // still chars from last string + else { /* still chars from last string */ while( state->tdctl.bufndx < state->tdctl.bufcnt && count < len ) { c = state->text_buf[(state->tdctl.bufpos + state->tdctl.bufndx) & (N - 1)]; *(buf++) = c; @@ -467,12 +465,12 @@ int td0_state_Decode(td0dsk_t *state, uint8_t *buf, int len) /* Decoding/Uncomp state->tdctl.r &= (N - 1); count++; } - // reset bufcnt after copy string from text_buf[] + /* reset bufcnt after copy string from text_buf[] */ if(state->tdctl.bufndx >= state->tdctl.bufcnt) state->tdctl.bufndx = state->tdctl.bufcnt = 0; } } - return(count); // count == len, success + return(count); /* count == len, success */ } @@ -495,8 +493,7 @@ void td0_init() void d86f_register_td0(int drive); -// static const int rates[3] = { 2, 1, 0, 2, 3 }; /* 0 = 250 kbps, 1 = 300 kbps, 2 = 500 kbps, 3 = unknown, 4 = 1000 kbps */ -const int max_size = 4*1024*1024; // 4MB ought to be large enough for any floppy +const int max_size = 4*1024*1024; /* 4MB ought to be large enough for any floppy */ const int max_processed_size = 5*1024*1024; uint8_t imagebuf[4*1024*1024]; uint8_t processed_buf[5*1024*1024]; @@ -632,12 +629,10 @@ int td0_initialize(int drive) int head_count = 0; int track_spt; int offset = 0; - int ret = 0; - int gap3_len = 0; - // int rate = 0; int density = 0; int i = 0; int j = 0; + int k = 0; int temp_rate = 0; uint32_t file_size; uint16_t len; @@ -651,7 +646,6 @@ int td0_initialize(int drive) uint32_t track_size = 0; uint32_t raw_tsize = 0; uint32_t minimum_gap3 = 0; - // uint32_t minimum_gap4 = 12; uint32_t minimum_gap4 = 0; if (!td0[drive].f) @@ -698,7 +692,7 @@ int td0_initialize(int drive) offset = 10 + imagebuf[2] + (imagebuf[3] << 8); track_spt = imagebuf[offset]; - if(track_spt == 255) // Empty file? + if(track_spt == 255) /* Empty file? */ { pclog("TD0: File has no tracks\n"); return 0; @@ -738,9 +732,6 @@ int td0_initialize(int drive) td0[drive].track_width = (header[7] & 1) ^ 1; - // rate = (header[5] & 0x7f) >= 3 ? 0 : rates[header[5] & 0x7f]; - // td0[drive].default_track_flags |= rate; - for (i = 0; i < 256; i++) { memset(td0[drive].side_flags[i], 0, 4); @@ -756,7 +747,7 @@ int td0_initialize(int drive) { track = imagebuf[offset + 1]; head = imagebuf[offset + 2] & 1; - fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); // ? + fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); /* ? */ td0[drive].side_flags[track][head] = td0[drive].default_track_flags | (fm ? 0 : 8); td0[drive].track_in_file[track][head] = 1; offset += 4; @@ -766,7 +757,6 @@ int td0_initialize(int drive) for(i = 0; i < track_spt; i++) { hs = &imagebuf[offset]; - size; offset += 6; td0[drive].sects[track][head][i].track = hs[0]; @@ -792,7 +782,6 @@ int td0_initialize(int drive) else { offset += 3; - int j, k; switch(hs[8]) { default: @@ -890,7 +879,6 @@ int td0_initialize(int drive) temp_rate = td0[drive].default_track_flags & 7; if ((td0[drive].default_track_flags & 0x27) == 0x20) temp_rate = 4; td0[drive].gap3_len = gap3_sizes[temp_rate][td0[drive].sects[0][0][0].size][td0[drive].track_spt[0][0]]; - // pclog("GAP3 length for %i %i %i is %i\n", temp_rate, td0[drive].sects[0][0][0].size, td0[drive].track_spt[0][0], td0[drive].gap3_len); if (!td0[drive].gap3_len) { td0[drive].gap3_len = td0[drive].calculated_gap3_lengths[0][0]; /* If we can't determine the GAP3 length, assume the smallest one we possibly know of. */ @@ -968,12 +956,10 @@ int td0_track_is_xdf(int drive, int side, int track) td0[drive].current_side_flags[side] = (td0[drive].track_spt[track][side] == 19) ? 0x08 : 0x28; return (td0[drive].track_spt[track][side] == 19) ? 2 : 1; } - // pclog("XDF: %i %i %i %i\n", high_sectors, expected_high_count, low_sectors, expected_low_count); return 0; } else { - // pclog("XDF: %i sectors per track (%i %i)\n", td0[drive].track_spt[track][side], track, side); return 0; } } @@ -996,7 +982,6 @@ int td0_track_is_xdf(int drive, int side, int track) td0[drive].xdf_ordered_pos[id[2]][side] = i; } } - // pclog("XDF: %i %i\n", effective_sectors, xdf_sectors); if ((effective_sectors == 3) && (xdf_sectors == 3)) { td0[drive].current_side_flags[side] = 0x28; @@ -1087,8 +1072,6 @@ void td0_seek(int drive, int track) td0[drive].current_side_flags[0] = td0[drive].side_flags[track][0]; td0[drive].current_side_flags[1] = td0[drive].side_flags[track][1]; - // pclog("TD0 Seek: %02X %02X (%02X)\n", td0[drive].current_side_flags[0], td0[drive].current_side_flags[1], td0[drive].disk_flags); - d86f_reset_index_hole_pos(drive, 0); d86f_reset_index_hole_pos(drive, 1); @@ -1128,7 +1111,6 @@ void td0_seek(int drive, int track) id[1] = td0[drive].sects[track][side][actual_sector].head; id[2] = real_sector; id[3] = td0[drive].sects[track][side][actual_sector].size; - // pclog("TD0: %i %i %i %i (%i %i) (GPL=%i)\n", id[0], id[1], id[2], id[3], td0[drive].sects[track][side][actual_sector].deleted, td0[drive].sects[track][side][actual_sector].bad_crc, track_gap3); ssize = 128 << ((uint32_t) td0[drive].sects[track][side][actual_sector].size); current_pos = d86f_prepare_sector(drive, side, current_pos, id, td0[drive].sects[track][side][actual_sector].data, ssize, track_gap2, track_gap3, td0[drive].sects[track][side][actual_sector].deleted, td0[drive].sects[track][side][actual_sector].bad_crc); } @@ -1146,7 +1128,6 @@ void td0_seek(int drive, int track) id[3] = is_trackx ? (id[2] & 7) : 2; ssize = 128 << ((uint32_t) id[3]); ordered_pos = td0[drive].xdf_ordered_pos[id[2]][side]; - // pclog("TD0: XDF: (%i %i) %i %i %i %i (%i %i) (GPL=%i)\n", track, side, id[0], id[1], id[2], id[3], td0[drive].sects[track][side][ordered_pos].deleted, td0[drive].sects[track][side][ordered_pos].bad_crc, track_gap3); if (is_trackx) { current_pos = d86f_prepare_sector(drive, side, xdf_trackx_spos[xdf_type][xdf_sector], id, td0[drive].sects[track][side][ordered_pos].data, ssize, track_gap2, xdf_gap3_sizes[xdf_type][is_trackx], td0[drive].sects[track][side][ordered_pos].deleted, td0[drive].sects[track][side][ordered_pos].bad_crc); @@ -1158,8 +1139,6 @@ void td0_seek(int drive, int track) } } } - - // pclog("Seeked to track: %i (%02X, %02X)\n", td0[drive].track, td0[drive].current_side_flags[0], td0[drive].current_side_flags[1]); } uint16_t td0_disk_flags(int drive) @@ -1208,4 +1187,4 @@ void d86f_register_td0(int drive) d86f_handler[drive].index_hole_pos = null_index_hole_pos; d86f_handler[drive].get_raw_size = common_get_raw_size; d86f_handler[drive].check_crc = 1; -} \ No newline at end of file +} diff --git a/src/dma.c b/src/dma.c index 391121c18..c1c039ffa 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,19 +1,13 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ #include "ibm.h" -#include "disc.h" #include "dma.h" -#include "fdc.h" #include "io.h" #include "mem.h" #include "video.h" +#include "x86.h" static uint8_t dmaregs[16]; -static int dmaon[4]; static uint8_t dma16regs[16]; -static int dma16on[4]; static uint8_t dmapages[16]; void dma_reset() @@ -49,14 +43,13 @@ void dma_reset() uint8_t dma_read(uint16_t addr, void *priv) { uint8_t temp; -// printf("Read DMA %04X %04X:%04X %i %02X\n",addr,CS,pc, pic_intpending, pic.pend); switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ dma.wp ^= 1; if (dma.wp) return dma.ac[(addr >> 1) & 3] & 0xff; - return dma.ac[(addr >> 1) & 3] >> 8; + return (dma.ac[(addr >> 1) & 3] >> 8) & 0xff; case 1: case 3: case 5: case 7: /*Count registers*/ dma.wp ^= 1; @@ -66,72 +59,55 @@ uint8_t dma_read(uint16_t addr, void *priv) case 8: /*Status register*/ temp = dma.stat; - dma.stat &= 0xf0; + dma.stat = 0; return temp; - - case 0xd: /*Temporary register*/ - // return dmaregs[addr & 0xd]; - return 0; - - case 0xf: /*Mask register*/ - return dma16.m; - - default: - return 0; + + case 0xd: + return 0; } + return dmaregs[addr & 0xf]; } void dma_write(uint16_t addr, uint8_t val, void *priv) { - int channel = val & 3; -// printf("Write DMA %04X %02X %04X:%04X\n",addr,val,CS,pc); dmaregs[addr & 0xf] = val; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ dma.wp ^= 1; - // if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00) | val; - // else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8); - if (dma.wp) dma.ab[(addr >> 1) & 3] = val; - else dma.ab[(addr >> 1) & 3] |= (((uint16_t) val) << 8); - dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3] & 0xffff; - dmaon[(addr >> 1) & 3] = 1; + if (dma.wp) dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xffff00) | val; + else dma.ab[(addr >> 1) & 3] = (dma.ab[(addr >> 1) & 3] & 0xff00ff) | (val << 8); + dma.ac[(addr >> 1) & 3] = dma.ab[(addr >> 1) & 3]; return; case 1: case 3: case 5: case 7: /*Count registers*/ dma.wp ^= 1; - // if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val; - // else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); - if (dma.wp) dma.cb[(addr >> 1) & 3] = val; - else dma.cb[(addr >> 1) & 3] |= (((uint16_t) val) << 8); - dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3] & 0xffff; - // pclog("DMA count for channel %i now: %02X\n", (addr >> 1) & 3, dma.cc[(addr >> 1) & 3]); - dmaon[(addr >> 1) & 3] = 1; + if (dma.wp) dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0xff00) | val; + else dma.cb[(addr >> 1) & 3] = (dma.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); + dma.cc[(addr >> 1) & 3] = dma.cb[(addr >> 1) & 3]; return; case 8: /*Control register*/ dma.command = val; return; - - case 9: /*Request register*/ - if (val & 4) - { - dma.stat |= (1 << (channel + 4)); - } - else - { - dma.stat &= ~(1 << (channel + 4)); - } - return; case 0xa: /*Mask*/ if (val & 4) dma.m |= (1 << (val & 3)); else dma.m &= ~(1 << (val & 3)); return; - + case 0xb: /*Mode*/ - dma.mode[val & 3] = val & 0xfc; - dma.stat &= ~(1 << (val & 3)); + dma.mode[val & 3] = val; + if (dma.is_ps2) + { + dma.ps2_mode[val & 3] &= ~0x1c; + if (val & 0x20) + dma.ps2_mode[val & 3] |= 0x10; + if ((val & 0xc) == 8) + dma.ps2_mode[val & 3] |= 4; + else if ((val & 0xc) == 4) + dma.ps2_mode[val & 3] |= 0xc; + } return; case 0xc: /*Clear FF*/ @@ -139,14 +115,8 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) return; case 0xd: /*Master clear*/ - dma.m = 0xf; - dma.command = 0; - dma.stat = 0; dma.wp = 0; - return; - - case 0xe: /*Mask reset*/ - dma.m = 0; + dma.m = 0xf; return; case 0xf: /*Mask write*/ @@ -155,18 +125,194 @@ void dma_write(uint16_t addr, uint8_t val, void *priv) } } +static uint8_t dma_ps2_read(uint16_t addr, void *priv) +{ + uint8_t temp = 0xff; + + switch (addr) + { + case 0x1a: + switch (dma.xfr_command) + { + case 2: /*Address*/ + case 3: + switch (dma.byte_ptr) + { + case 0: + temp = (dma.xfr_channel & 4) ? (dma16.ac[dma.xfr_channel & 3] & 0xff) : (dma.ac[dma.xfr_channel] & 0xff); + dma.byte_ptr = 1; + break; + case 1: + temp = (dma.xfr_channel & 4) ? (dma16.ac[dma.xfr_channel & 3] >> 8) : (dma.ac[dma.xfr_channel] >> 8); + dma.byte_ptr = 2; + break; + case 2: + temp = (dma.xfr_channel & 4) ? (dma16.ac[dma.xfr_channel & 3] >> 16) : (dma.ac[dma.xfr_channel] >> 16); + dma.byte_ptr = 0; + break; + } + break; + case 4: /*Count*/ + case 5: + if (dma.byte_ptr) + temp = (dma.xfr_channel & 4) ? (dma16.cc[dma.xfr_channel & 3] >> 8) : (dma.cc[dma.xfr_channel] >> 8); + else + temp = (dma.xfr_channel & 4) ? (dma16.cc[dma.xfr_channel & 3] & 0xff) : (dma.cc[dma.xfr_channel] & 0xff); + dma.byte_ptr = (dma.byte_ptr + 1) & 1; + break; + case 7: /*Mode*/ + temp = (dma.xfr_channel & 4) ? dma16.ps2_mode[dma.xfr_channel & 3] : dma.ps2_mode[dma.xfr_channel]; + break; + case 8: /*Arbitration Level*/ + temp = (dma.xfr_channel & 4) ? dma16.arb_level[dma.xfr_channel & 3] : dma.arb_level[dma.xfr_channel]; + break; + + default: + fatal("Bad XFR Read command %i channel %i\n", dma.xfr_command, dma.xfr_channel); + } + break; + } + + return temp; +} + +static void dma_ps2_write(uint16_t addr, uint8_t val, void *priv) +{ + uint8_t mode; + + switch (addr) + { + case 0x18: + dma.xfr_channel = val & 0x7; + dma.xfr_command = val >> 4; + dma.byte_ptr = 0; + switch (dma.xfr_command) + { + case 9: /*Set DMA mask*/ + if (dma.xfr_channel & 4) + dma16.m |= (1 << (dma.xfr_channel & 3)); + else + dma.m |= (1 << dma.xfr_channel); + break; + case 0xa: /*Reset DMA mask*/ + if (dma.xfr_channel & 4) + dma16.m &= ~(1 << (dma.xfr_channel & 3)); + else + dma.m &= ~(1 << dma.xfr_channel); + break; + } + break; + case 0x1a: + switch (dma.xfr_command) + { + case 2: /*Address*/ + switch (dma.byte_ptr) + { + case 0: + if (dma.xfr_channel & 4) + dma16.ac[dma.xfr_channel & 3] = (dma16.ac[dma.xfr_channel & 3] & 0xffff00) | val; + else + dma.ac[dma.xfr_channel] = (dma.ac[dma.xfr_channel] & 0xffff00) | val; + dma.byte_ptr = 1; + break; + case 1: + if (dma.xfr_channel & 4) + dma16.ac[dma.xfr_channel & 3] = (dma16.ac[dma.xfr_channel & 3] & 0xff00ff) | (val << 8); + else + dma.ac[dma.xfr_channel] = (dma.ac[dma.xfr_channel] & 0xff00ff) | (val << 8); + dma.byte_ptr = 2; + break; + case 2: + if (dma.xfr_channel & 4) + dma16.ac[dma.xfr_channel & 3] = (dma16.ac[dma.xfr_channel & 3] & 0x00ffff) | (val << 16); + else + dma.ac[dma.xfr_channel] = (dma.ac[dma.xfr_channel] & 0x00ffff) | (val << 16); + dma.byte_ptr = 0; + break; + } + if (dma.xfr_channel & 4) + dma16.ab[dma.xfr_channel & 3] = dma16.ac[dma.xfr_channel & 3]; + else + dma.ab[dma.xfr_channel] = dma.ac[dma.xfr_channel]; + break; + + case 4: /*Count*/ + if (dma.byte_ptr) + { + if (dma.xfr_channel & 4) + dma16.cc[dma.xfr_channel & 3] = (dma16.cc[dma.xfr_channel & 3] & 0xff) | (val << 8); + else + dma.cc[dma.xfr_channel] = (dma.cc[dma.xfr_channel] & 0xff) | (val << 8); + } + else + { + if (dma.xfr_channel & 4) + dma16.cc[dma.xfr_channel & 3] = (dma16.cc[dma.xfr_channel & 3] & 0xff00) | val; + else + dma.cc[dma.xfr_channel] = (dma.cc[dma.xfr_channel] & 0xff00) | val; + } + dma.byte_ptr = (dma.byte_ptr + 1) & 1; + if (dma.xfr_channel & 4) + dma16.cb[dma.xfr_channel & 3] = dma16.cc[dma.xfr_channel & 3]; + else + dma.cb[dma.xfr_channel] = dma.cc[dma.xfr_channel]; + break; + + case 7: /*Mode register*/ + mode = 0; + if (val & 0x10) + mode |= 0x20; + if ((val & 0xc) == 4) + mode |= 8; + else if ((val & 0xc) == 0xc) + mode |= 4; + if ((val & 0x40) && !(dma.xfr_channel & 4)) + fatal("16-bit DMA on 8-bit channel\n"); + if (!(val & 0x40) && (dma.xfr_channel & 4)) + fatal("8-bit DMA on 16-bit channel\n"); + if (dma.xfr_channel & 4) + { + dma16.mode[dma.xfr_channel & 3] = (dma16.mode[dma.xfr_channel & 3] & ~0x2c) | mode; + dma16.ps2_mode[dma.xfr_channel & 3] = val; + } + else + { + dma.mode[dma.xfr_channel] = (dma.mode[dma.xfr_channel] & ~0x2c) | mode; + dma.ps2_mode[dma.xfr_channel] = val; + } + break; + + case 8: /*Arbitration Level*/ + if (dma.xfr_channel & 4) + dma16.arb_level[dma.xfr_channel & 3] = val; + else + dma.arb_level[dma.xfr_channel] = val; + break; + + default: + fatal("Bad XFR command %i channel %i val %02x\n", dma.xfr_command, dma.xfr_channel, val); + } + break; + } +} + uint8_t dma16_read(uint16_t addr, void *priv) { uint8_t temp; - // printf("Read DMA %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); addr >>= 1; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ dma16.wp ^= 1; + if (dma.is_ps2) + { + if (dma16.wp) + return dma16.ac[(addr >> 1) & 3] & 0xff; + return (dma16.ac[(addr >> 1) & 3] >> 8) & 0xff; + } if (dma16.wp) - return dma16.ac[(addr >> 1) & 3] & 0xff; - return dma16.ac[(addr >> 1) & 3] >> 8; + return (dma16.ac[(addr >> 1) & 3] >> 1) & 0xff; + return (dma16.ac[(addr >> 1) & 3] >> 9) & 0xff; case 1: case 3: case 5: case 7: /*Count registers*/ dma16.wp ^= 1; @@ -176,63 +322,42 @@ uint8_t dma16_read(uint16_t addr, void *priv) case 8: /*Status register*/ temp = dma16.stat; - dma16.stat &= 0xf0; + dma16.stat = 0; return temp; - - case 0xd: /*Temporary register*/ - // return dma16regs[addr & 0xd]; - return 0; - - case 0xf: /*Mask register*/ - return dma16.m; - - default: - return 0; } + return dma16regs[addr & 0xf]; } void dma16_write(uint16_t addr, uint8_t val, void *priv) { - int channel = val & 3; - // printf("Write dma16 %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); addr >>= 1; dma16regs[addr & 0xf] = val; switch (addr & 0xf) { case 0: case 2: case 4: case 6: /*Address registers*/ dma16.wp ^= 1; - // if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00) | val; - // else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0x00ff) | (val << 8); - if (dma16.wp) dma16.ab[(addr >> 1) & 3] = val; - else dma16.ab[(addr >> 1) & 3] |= (((uint16_t) val) << 8); - dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3] & 0xffff; - dma16on[(addr >> 1) & 3] = 1; + if (dma.is_ps2) + { + if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xffff00) | val; + else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xff00ff) | (val << 8); + } + else + { + if (dma16.wp) dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xfffe00) | (val << 1); + else dma16.ab[(addr >> 1) & 3] = (dma16.ab[(addr >> 1) & 3] & 0xfe01ff) | (val << 9); + } + dma16.ac[(addr >> 1) & 3] = dma16.ab[(addr >> 1) & 3]; return; case 1: case 3: case 5: case 7: /*Count registers*/ dma16.wp ^= 1; - // if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val; - // else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); - if (dma16.wp) dma16.cb[(addr >> 1) & 3] = val; - else dma16.cb[(addr >> 1) & 3] |= (((uint16_t) val) << 8); - dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3] & 0xffff; - dma16on[(addr >> 1) & 3] = 1; + if (dma16.wp) dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0xff00) | val; + else dma16.cb[(addr >> 1) & 3] = (dma16.cb[(addr >> 1) & 3] & 0x00ff) | (val << 8); + dma16.cc[(addr >> 1) & 3] = dma16.cb[(addr >> 1) & 3]; return; case 8: /*Control register*/ - dma16.command = val; return; - - case 9: /*Request register*/ - if (val & 4) - { - dma16.stat |= (1 << (channel + 4)); - } - else - { - dma16.stat &= ~(1 << (channel + 4)); - } - return; case 0xa: /*Mask*/ if (val & 4) dma16.m |= (1 << (val & 3)); @@ -240,8 +365,17 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xb: /*Mode*/ - dma16.mode[val & 3] = val & 0xfc; - dma16.stat &= ~(1 << (val & 3)); + dma16.mode[val & 3] = val; + if (dma.is_ps2) + { + dma16.ps2_mode[val & 3] &= ~0x1c; + if (val & 0x20) + dma16.ps2_mode[val & 3] |= 0x10; + if ((val & 0xc) == 8) + dma16.ps2_mode[val & 3] |= 4; + else if ((val & 0xc) == 4) + dma16.ps2_mode[val & 3] |= 0xc; + } return; case 0xc: /*Clear FF*/ @@ -249,18 +383,12 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) return; case 0xd: /*Master clear*/ - dma16.m = 0xf; - dma16.command = 0; - dma16.stat = 0; dma16.wp = 0; - return; - - case 0xe: /*Mask reset*/ - dma16.m = 0; + dma16.m = 0xf; return; case 0xf: /*Mask write*/ - dma16.m = val & 0xf; + dma16.m = val&0xf; return; } } @@ -268,43 +396,54 @@ void dma16_write(uint16_t addr, uint8_t val, void *priv) void dma_page_write(uint16_t addr, uint8_t val, void *priv) { - // printf("Write dma16 Page %04X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); dmapages[addr & 0xf] = val; switch (addr & 0xf) { case 1: dma.page[2] = (AT) ? val : val & 0xf; + dma.ab[2] = (dma.ab[2] & 0xffff) | (dma.page[2] << 16); + dma.ac[2] = (dma.ac[2] & 0xffff) | (dma.page[2] << 16); break; case 2: dma.page[3] = (AT) ? val : val & 0xf; + dma.ab[3] = (dma.ab[3] & 0xffff) | (dma.page[3] << 16); + dma.ac[3] = (dma.ac[3] & 0xffff) | (dma.page[3] << 16); break; case 3: dma.page[1] = (AT) ? val : val & 0xf; + dma.ab[1] = (dma.ab[1] & 0xffff) | (dma.page[1] << 16); + dma.ac[1] = (dma.ac[1] & 0xffff) | (dma.page[1] << 16); + break; + case 7: + dma.page[0] = (AT) ? val : val & 0xf; + dma.ab[0] = (dma.ab[0] & 0xffff) | (dma.page[0] << 16); + dma.ac[0] = (dma.ac[0] & 0xffff) | (dma.page[0] << 16); break; - case 0x7: - dma.page[0] = (AT) ? val : val & 0xf; - break; case 0x9: - dma16.page[2] = val; + dma16.page[2] = val & 0xfe; + dma16.ab[2] = (dma16.ab[2] & 0x1ffff) | (dma16.page[2] << 16); + dma16.ac[2] = (dma16.ac[2] & 0x1ffff) | (dma16.page[2] << 16); break; case 0xa: - dma16.page[3] = val; + dma16.page[3] = val & 0xfe; + dma16.ab[3] = (dma16.ab[3] & 0x1ffff) | (dma16.page[3] << 16); + dma16.ac[3] = (dma16.ac[3] & 0x1ffff) | (dma16.page[3] << 16); break; case 0xb: - dma16.page[1] = val; + dma16.page[1] = val & 0xfe; + dma16.ab[1] = (dma16.ab[1] & 0x1ffff) | (dma16.page[1] << 16); + dma16.ac[1] = (dma16.ac[1] & 0x1ffff) | (dma16.page[1] << 16); break; case 0xf: - dma16.page[0] = val; + dma16.page[0] = val & 0xfe; + dma16.ab[0] = (dma16.ab[0] & 0x1ffff) | (dma16.page[0] << 16); + dma16.ac[0] = (dma16.ac[0] & 0x1ffff) | (dma16.page[0] << 16); break; - default: - // pclog("DMA write to extra page register: %02X\n", addr & 0xf); - break; } } uint8_t dma_page_read(uint16_t addr, void *priv) { - // printf("Read DMA Page %04X %04X:%04X\n",addr,cs>>4,cpu_state.pc); return dmapages[addr & 0xf]; } @@ -312,6 +451,7 @@ void dma_init() { io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); + dma.is_ps2 = 0; } void dma16_init() @@ -338,15 +478,18 @@ void dma_alias_remove_piix() io_removehandler(0x009C, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } +void ps2_dma_init() +{ + io_sethandler(0x0018, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); + io_sethandler(0x001a, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); + dma.is_ps2 = 1; +} + uint8_t _dma_read(uint32_t addr) { - return mem_readb_phys(addr); -} - -uint16_t _dma_readw(uint32_t addr) -{ - return mem_readw_phys(addr); + uint8_t temp = mem_readb_phys(addr); + return temp; } void _dma_write(uint32_t addr, uint8_t val) @@ -355,291 +498,194 @@ void _dma_write(uint32_t addr, uint8_t val) mem_invalidate_range(addr, addr); } -void _dma_writew(uint32_t addr, uint16_t val) -{ - mem_writew_phys(addr, val); - mem_invalidate_range(addr, addr + 1); -} - -int dma_is_masked(int channel) -{ - if (channel < 4) - { - if (dma.m & (1 << channel)) - { - return 1; - } - if (AT) - { - if (dma16.m & 1) - { - return 1; - } - } - } - else - { - channel &= 3; - if (dma16.m & (1 << channel)) - { - return 1; - } - } - return 0; -} - -int dma_channel_mode(int channel) -{ - if (channel < 4) - { - return (dma.mode[channel] & 0xC) >> 2; - } - else - { - channel &= 3; - return (dma16.mode[channel] & 0xC) >> 2; - } -} - -DMA * get_dma_controller(int channel) -{ - if (channel < 4) - { - return &dma; - } - else - { - return &dma16; - } -} - -int dma_tc(DMA *dma_controller, int channel) -{ - if (dma_controller->command & 1) - { - /* Memory to memory command */ - dma_controller->stat |= (1 << 0); - dma_controller->stat |= (1 << 1); - dma_controller->request &= ~(1 << 0); - dma_controller->request &= ~(1 << 1); - } - else - { - dma_controller->stat |= (1 << channel); - dma_controller->request &= ~(1 << channel); - } - - if (dma_controller->mode[channel] & 0x10) /*Auto-init*/ - { - // pclog("DMA read auto-init\n"); - dma_controller->cc[channel] = dma_controller->cb[channel] & 0xffff; - dma_controller->ac[channel] = dma_controller->ab[channel] & 0xffff; - } - else - { - dma_controller->cc[channel] &= 0xffff; - dma_controller->m |= (1 << channel); - } -} - int dma_channel_read(int channel) { uint16_t temp; int tc = 0; - - int cmode = 0; - int real_channel = channel & 3; - - int mem_over = 0; - - DMA *dma_controller; - - cmode = dma_channel_mode(channel); - - channel &= 7; - - if ((channel >= 4) && !AT) - { - // pclog ("DMA read - channel is 4 or higher on a non-AT machine\n"); + + if (dma.command & 0x04) return DMA_NODATA; - } - - dma_controller = get_dma_controller(channel); - - if (dma_controller->command & 0x04) - { - // pclog ("DMA read - channel bit 2 of control bit is set\n"); - return DMA_NODATA; - } - + if (!AT) refreshread(); - - if ((channel == 4) || dma_is_masked(channel)) - { - // pclog ("DMA read - channel is 4 or masked\n"); - return DMA_NODATA; - } - - if (cmode) - { - if (cmode != 2) - { - // pclog ("DMA read - transfer mode (%i) is 1 or 3\n", cmode); + + if (channel < 4) + { + if (dma.m & (1 << channel)) + return DMA_NODATA; + if ((dma.mode[channel] & 0xC) != 8) return DMA_NODATA; - } - else - { - if (channel < 4) - { - temp = _dma_read(dma_controller->ac[real_channel] + (dma_controller->page[real_channel] << 16)); - } - else - { - temp = _dma_readw((dma_controller->ac[real_channel] << 1) + ((dma_controller->page[real_channel] & ~1) << 16)); - } - } - } - if (dma_controller->mode[real_channel] & 0x20) - { - if (dma_controller->ac[real_channel] == 0) - { - mem_over = 1; - } - dma_controller->ac[real_channel]--; - } - else - { - if (dma_controller->ac[real_channel] == 0xFFFF) - { - mem_over = 1; - } - dma_controller->ac[real_channel]++; - } - dma_controller->ac[real_channel] &= 0xffff; + temp = _dma_read(dma.ac[channel]); - dma_controller->cc[real_channel]--; - if ((dma_controller->cc[real_channel] < 0) || mem_over) - { - tc = 1; - dma_tc(dma_controller, real_channel); - } + if (dma.mode[channel] & 0x20) + { + if (dma.is_ps2) + dma.ac[channel]--; + else + dma.ac[channel] = (dma.ac[channel] & 0xff0000) | ((dma.ac[channel] - 1) & 0xffff); + } + else + { + if (dma.is_ps2) + dma.ac[channel]++; + else + dma.ac[channel] = (dma.ac[channel] & 0xff0000) | ((dma.ac[channel] + 1) & 0xffff); + } + dma.cc[channel]--; + if (dma.cc[channel] < 0) + { + tc = 1; + if (dma.mode[channel] & 0x10) /*Auto-init*/ + { + dma.cc[channel] = dma.cb[channel]; + dma.ac[channel] = dma.ab[channel]; + } + else + dma.m |= (1 << channel); + dma.stat |= (1 << channel); + } - if (tc) - { - // pclog("DMA read over in transfer mode %i (value %04X)!\n", cmode, temp); - return temp | DMA_OVER; - } + if (tc) + return temp | DMA_OVER; + return temp; + } + else + { + channel &= 3; + if (dma16.m & (1 << channel)) + return DMA_NODATA; + if ((dma16.mode[channel] & 0xC) != 8) + return DMA_NODATA; - // pclog("DMA read success (value %04X)\n", temp); - return temp; + temp = _dma_read(dma16.ac[channel]) | + (_dma_read(dma16.ac[channel] + 1) << 8); + + if (dma16.mode[channel] & 0x20) + { + if (dma.is_ps2) + dma16.ac[channel] -= 2; + else + dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] - 2) & 0x1ffff); + } + else + { + if (dma.is_ps2) + dma16.ac[channel] += 2; + else + dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] + 2) & 0x1ffff); + } + + dma16.cc[channel]--; + if (dma16.cc[channel] < 0) + { + tc = 1; + if (dma16.mode[channel] & 0x10) /*Auto-init*/ + { + dma16.cc[channel] = dma16.cb[channel]; + dma16.ac[channel] = dma16.ab[channel]; + } + else + dma16.m |= (1 << channel); + dma16.stat |= (1 << channel); + } + + if (tc) + return temp | DMA_OVER; + return temp; + } } int dma_channel_write(int channel, uint16_t val) { - int tc = 0; - - int cmode = 0; - int real_channel = channel & 3; - - int mem_over = 0; - - DMA *dma_controller; - - cmode = dma_channel_mode(channel); - - channel &= 7; - - if ((channel >= 4) && !AT) - { - // pclog ("DMA write - channel is 4 or higher on a non-AT machine\n"); + if (dma.command & 0x04) return DMA_NODATA; - } - - dma_controller = get_dma_controller(channel); - - if (dma_controller->command & 0x04) - { - // pclog ("DMA write - channel bit 2 of control bit is set\n"); - return DMA_NODATA; - } if (!AT) refreshread(); - if ((channel == 4) || dma_is_masked(channel)) - { - // pclog ("DMA write - channel is 4 or masked\n"); - return DMA_NODATA; - } - - if (cmode) - { - if (cmode != 1) - { - // pclog ("DMA write - transfer mode (%i) is 2 or 3\n", cmode); + if (channel < 4) + { + if (dma.m & (1 << channel)) + return DMA_NODATA; + if ((dma.mode[channel] & 0xC) != 4) return DMA_NODATA; - } - if (channel < 4) - { - _dma_write(dma_controller->ac[real_channel] + (dma_controller->page[real_channel] << 16), val); - } - else - { - _dma_writew((dma_controller->ac[real_channel] << 1) + ((dma_controller->page[real_channel] & ~1) << 16), val); - } - } + _dma_write(dma.ac[channel], val); - if (dma_controller->mode[real_channel] & 0x20) - { - if (dma_controller->ac[real_channel] == 0) - { - mem_over = 1; - } - dma_controller->ac[real_channel]--; - } - else - { - if (dma_controller->ac[real_channel] == 0xFFFF) - { - mem_over = 1; - } - dma_controller->ac[real_channel]++; - } - dma_controller->ac[real_channel] &= 0xffff; + if (dma.mode[channel] & 0x20) + { + if (dma.is_ps2) + dma.ac[channel]--; + else + dma.ac[channel] = (dma.ac[channel] & 0xff0000) | ((dma.ac[channel] - 1) & 0xffff); + } + else + { + if (dma.is_ps2) + dma.ac[channel]++; + else + dma.ac[channel] = (dma.ac[channel] & 0xff0000) | ((dma.ac[channel] + 1) & 0xffff); + } - dma_controller->cc[real_channel]--; - if ((dma_controller->cc[real_channel] < 0) || mem_over) - { - tc = 1; - dma_tc(dma_controller, real_channel); - } + dma.cc[channel]--; + if (dma.cc[channel] < 0) + { + if (dma.mode[channel] & 0x10) /*Auto-init*/ + { + dma.cc[channel] = dma.cb[channel]; + dma.ac[channel] = dma.ab[channel]; + } + else + dma.m |= (1 << channel); + dma.stat |= (1 << channel); + } - // if (dma_is_masked(channel)) - if (tc) - { - // pclog("DMA write over in transfer mode %i (value %04X)\n", cmode, val); - return DMA_OVER; - } + if (dma.m & (1 << channel)) + return DMA_OVER; + } + else + { + channel &= 3; + if (dma16.m & (1 << channel)) + return DMA_NODATA; + if ((dma16.mode[channel] & 0xC) != 4) + return DMA_NODATA; - // pclog("DMA write success (value %04X)\n", val); - return 0; -} + _dma_write(dma16.ac[channel], val); + _dma_write(dma16.ac[channel] + 1, val >> 8); -//DMA Bus Master Page Read/Write -void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize) -{ - memcpy(DataRead, &ram[PhysAddress], TotalSize); - DataRead -= TotalSize; -} + if (dma16.mode[channel] & 0x20) + { + if (dma.is_ps2) + dma16.ac[channel] -= 2; + else + dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] - 2) & 0x1ffff); + } + else + { + if (dma.is_ps2) + dma16.ac[channel] += 2; + else + dma16.ac[channel] = (dma16.ac[channel] & 0xfe0000) | ((dma16.ac[channel] + 2) & 0x1ffff); + } -void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize) -{ - mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); - memcpy(&ram[PhysAddress], DataWrite, TotalSize); - DataWrite -= TotalSize; + dma16.cc[channel]--; + if (dma16.cc[channel] < 0) + { + if (dma16.mode[channel] & 0x10) /*Auto-init*/ + { + dma16.cc[channel] = dma16.cb[channel] + 1; + dma16.ac[channel] = dma16.ab[channel]; + } + dma16.m |= (1 << channel); + dma16.stat |= (1 << channel); + } + + if (dma.m & (1 << channel)) + return DMA_OVER; + } + return 0; } int dma_mode(int channel) @@ -654,7 +700,14 @@ int dma_mode(int channel) } } -/* void dma_c2_mode() +/* DMA Bus Master Page Read/Write */ +void DMAPageRead(uint32_t PhysAddress, char *DataRead, uint32_t TotalSize) { - printf("DMA Channel 2 mode: %02X\n", dma.mode[2]); -} */ + memcpy(DataRead, &ram[PhysAddress], TotalSize); +} + +void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize) +{ + mem_invalidate_range(PhysAddress, PhysAddress + TotalSize - 1); + memcpy(&ram[PhysAddress], DataWrite, TotalSize); +} diff --git a/src/dma.h b/src/dma.h index e8eb7fbc4..3cf611ea2 100644 --- a/src/dma.h +++ b/src/dma.h @@ -3,7 +3,9 @@ */ void dma_init(); void dma16_init(); +void ps2_dma_init(); void dma_reset(); +int dma_mode(int channel); #define DMA_NODATA -1 #define DMA_OVER 0x10000 @@ -19,5 +21,9 @@ void writedma2(uint8_t temp); int dma_channel_read(int channel); int dma_channel_write(int channel, uint16_t val); -void DMAPageRead(uint32_t PhysAddress, void *DataRead, uint32_t TotalSize); -void DMAPageWrite(uint32_t PhysAddress, const void *DataWrite, uint32_t TotalSize); \ No newline at end of file +void dma_alias_set(); +void dma_alias_remove(); +void dma_alias_remove_piix(); + +void DMAPageRead(uint32_t PhysAddress, char *DataRead, uint32_t TotalSize); +void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); \ No newline at end of file diff --git a/src/dosbox/vid_cga_comp.c b/src/dosbox/vid_cga_comp.c index 7752f5ba6..63e54cdad 100644 --- a/src/dosbox/vid_cga_comp.c +++ b/src/dosbox/vid_cga_comp.c @@ -19,10 +19,10 @@ static double saturation = 100; static double sharpness = 0; static double hue_offset = 0; -// New algorithm by reenigne -// Works in all CGA modes/color settings and can simulate older and newer CGA revisions +/* New algorithm by reenigne + Works in all CGA modes/color settings and can simulate older and newer CGA revisions */ -static const double tau = 6.28318531; // == 2*pi +static const double tau = 6.28318531; /* == 2*pi */ static unsigned char chroma_multiplexer[256] = { 2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4, @@ -58,26 +58,28 @@ int video_sharpness; int tandy_mode_control = 0; static bool new_cga = 0; -static bool is_bw = 0; -static bool is_bpp1 = 0; - -static uint8_t comp_pal[256][3]; - -static Bit8u byte_clamp_other(int v) { return v < 0 ? 0 : (v > 255 ? 255 : v); } - -FILE *df; void update_cga16_color(uint8_t cgamode) { int x; - Bit32u x2; + double c, i, v; + double q, a, s, r; + double iq_adjust_i, iq_adjust_q; + double i0, i3, mode_saturation; + + static const double ri = 0.9563; + static const double rq = 0.6210; + static const double gi = -0.2721; + static const double gq = -0.6474; + static const double bi = -1.1069; + static const double bq = 1.7046; if (!new_cga) { min_v = chroma_multiplexer[0] + intensity[0]; max_v = chroma_multiplexer[255] + intensity[3]; } else { - double i0 = intensity[0]; - double i3 = intensity[3]; + i0 = intensity[0]; + i3 = intensity[3]; min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0); max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3); } @@ -88,9 +90,9 @@ void update_cga16_color(uint8_t cgamode) { else mode_hue = 4; - mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; // new CGA: 120% - mode_brightness += (new_cga ? brightness-10 : brightness)*5; // new CGA: -10 - double mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; // new CGA: 150% + mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; /* new CGA: 120% */ + mode_brightness += (new_cga ? brightness-10 : brightness)*5; /* new CGA: -10 */ + mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; /* new CGA: 150% */ for (x = 0; x < 1024; ++x) { int phase = x & 3; @@ -102,10 +104,8 @@ void update_cga16_color(uint8_t cgamode) { rc = (right & 8) | ((right & 7) != 0 ? 7 : 0); lc = (left & 8) | ((left & 7) != 0 ? 7 : 0); } - double c = - chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; - double i = intensity[(left >> 3) | ((right >> 2) & 2)]; - double v; + c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase]; + i = intensity[(left >> 3) | ((right >> 2) & 2)]; if (!new_cga) v = c + i; else { @@ -117,23 +117,16 @@ void update_cga16_color(uint8_t cgamode) { CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness); } - double i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2]; - double q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3]; + i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2]; + q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3]; - double a = tau*(33 + 90 + hue_offset + mode_hue)/360.0; - double c = cos(a); - double s = sin(a); - double r = 256*mode_saturation/sqrt(i*i+q*q); + a = tau*(33 + 90 + hue_offset + mode_hue)/360.0; + c = cos(a); + s = sin(a); + r = 256*mode_saturation/sqrt(i*i+q*q); - double iq_adjust_i = -(i*c + q*s)*r; - double iq_adjust_q = (q*c - i*s)*r; - - static const double ri = 0.9563; - static const double rq = 0.6210; - static const double gi = -0.2721; - static const double gq = -0.6474; - static const double bi = -1.1069; - static const double bq = 1.7046; + iq_adjust_i = -(i*c + q*s)*r; + iq_adjust_q = (q*c - i*s)*r; video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q); video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i); @@ -163,6 +156,13 @@ Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool d int w = blocks*4; + int *o; + Bit8u *rgbi; + int *b; + int *i; + Bit32u* srgb; + int *ap, *bp; + #define COMPOSITE_CONVERT(I, Q) do { \ i[1] = (i[1]<<3) - ap[1]; \ a = ap[0]; \ @@ -182,10 +182,10 @@ Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool d #define OUT(v) do { *o = (v); ++o; } while (0) - // Simulate CGA composite output - int* o = temp; - Bit8u* rgbi = TempLine; - int* b = &CGA_Composite_Table[border*68]; + /* Simulate CGA composite output */ + o = temp; + rgbi = TempLine; + b = &CGA_Composite_Table[border*68]; for (x = 0; x < 4; ++x) OUT(b[(x+3)&3]); OUT(CGA_Composite_Table[(border<<6) | ((*rgbi)<<2) | 3]); @@ -198,9 +198,9 @@ Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool d OUT(b[x&3]); if ((cgamode & 4) != 0) { - // Decode - int* i = temp + 5; - Bit32u* srgb = (Bit32u *)TempLine; + /* Decode */ + i = temp + 5; + srgb = (Bit32u *)TempLine; for (x2 = 0; x2 < blocks*4; ++x2) { int c = (i[0]+i[0])<<3; int d = (i[-1]+i[1])<<3; @@ -211,21 +211,21 @@ Bit8u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool d } } else { - // Store chroma - int* i = temp + 4; - int* ap = atemp + 1; - int* bp = btemp + 1; + /* Store chroma */ + i = temp + 4; + ap = atemp + 1; + bp = btemp + 1; for (x = -1; x < w + 1; ++x) { ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4]; bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1; ++i; } - // Decode + /* Decode */ i = temp + 5; i[-1] = (i[-1]<<3) - ap[-1]; i[0] = (i[0]<<3) - ap[0]; - Bit32u* srgb = (Bit32u *)TempLine; + srgb = (Bit32u *)TempLine; for (x2 = 0; x2 < blocks; ++x2) { int y,a,b,c,d,rr,gg,bb; COMPOSITE_CONVERT(a, b); diff --git a/src/fdc.c b/src/fdc.c index 42ea7ff49..0174778f5 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -18,20 +18,44 @@ extern int motoron[FDD_NUM]; int ui_writeprot[FDD_NUM] = {0, 0, 0, 0}; -int command_has_drivesel[256] = { [0x02] = 1, /* READ TRACK */ - [0x04] = 1, /* SENSE DRIVE STATUS */ - [0x05] = 1, /* WRITE DATA */ - [0x06] = 1, /* READ DATA */ - [0x07] = 1, /* RECALIBRATE */ - [0x09] = 1, /* WRITE DELETED DATA */ - [0x0A] = 1, /* READ ID */ - [0x0C] = 1, /* READ DELETED DATA */ - [0x0D] = 1, /* FORMAT TRACK */ - [0x0F] = 1, /* SEEK, RELATIVE SEEK */ - [0x11] = 1, /* SCAN EQUAL */ - [0x16] = 1, /* VERIFY */ - [0x19] = 1, /* SCAN LOW OR EQUAL */ - [0x1D] = 1 }; /* SCAN HIGH OR EQUAL */ +int command_has_drivesel[256] = { 0, 0, + 1, /* READ TRACK */ + 0, + 1, /* SENSE DRIVE STATUS */ + 1, /* WRITE DATA */ + 1, /* READ DATA */ + 1, /* RECALIBRATE */ + 0, + 1, /* WRITE DELETED DATA */ + 1, /* READ ID */ + 0, + 1, /* READ DELETED DATA */ + 1, /* FORMAT TRACK */ + 0, + 1, /* SEEK, RELATIVE SEEK */ + 0, + 1, /* SCAN EQUAL */ + 0, 0, 0, 0, + 1, /* VERIFY */ + 0, 0, 0, + 1, /* SCAN LOW OR EQUAL */ + 0, 0, 0, + 1, /* SCAN HIGH OR EQUAL */ + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; static int fdc_reset_stat = 0; /*FDC*/ @@ -110,7 +134,6 @@ static FDC fdc; void fdc_callback(); int timetolive; -//#define SECTORS 9 int lastbyte=0; uint8_t disc_3f7; @@ -146,9 +169,7 @@ void fdc_reset() if (!AT) { fdc.rate = 2; - // fdc_update_rate(); } -// fdc_log("Reset FDC\n"); } sector_id_t fdc_get_read_track_sector() @@ -314,7 +335,6 @@ void fdc_fifo_buf_advance() { fdc.fifobufpos++; } - // fdc_log("FIFO buffer position = %02X\n", fdc.fifobufpos); } void fdc_fifo_buf_write(int val) @@ -337,7 +357,6 @@ static void fdc_int() { if (fdc.dor & 8) { - // fdc_log("FDC interrupt!\n"); picint(1 << 6); fdc.fintr = 1; } @@ -352,9 +371,7 @@ static void fdc_watchdog_poll(void *p) if (fdc->watchdog_count) fdc->watchdog_timer += 1000 * TIMER_USEC; else - { -// fdc_log("Watchdog timed out\n"); - + { fdc->watchdog_timer = 0; if (fdc->dor & 0x20) picint(1 << 6); @@ -492,7 +509,6 @@ void fdc_update_rate(int drive) } fdc.bitcell_period = 1000000 / bit_rate*2; /*Bitcell period in ns*/ - // fdc_log("fdc_update_rate: rate=%i bit_rate=%i bitcell_period=%i\n", fdc.rate, bit_rate, fdc.bitcell_period); } int fdc_get_bit_rate() @@ -564,6 +580,8 @@ static int fdc_get_densel(int drive) case 2: return fdc.densel_polarity ? 0 : 1; } + + return 0; } static void fdc_rate(int drive) @@ -605,18 +623,16 @@ void fdc_implied_seek() void fdc_write(uint16_t addr, uint8_t val, void *priv) { - fdc_log("Write FDC %04X %02X\n",addr,val); - // fdc_log("Write FDC %04X %02X %04X:%04X %i %02X %i rate=%i %i\n",addr,val,cs>>4,pc,ins,fdc.st0,ins,fdc.rate, fdc.data_ready); int drive, i, drive_num; int seek_time, seek_time_base; + fdc_log("Write FDC %04X %02X\n",addr,val); + switch (addr&7) { case 0: return; case 1: return; case 2: /*DOR*/ -// if (val == 0xD && (cs >> 4) == 0xFC81600 && ins > 769619936) output = 3; -// printf("DOR was %02X\n",fdc.dor); if (fdc.pcjr) { if ((fdc.dor & 0x40) && !(val & 0x40)) @@ -624,7 +640,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.watchdog_timer = 1000 * TIMER_USEC; fdc.watchdog_count = 1000; picintc(1 << 6); -// fdc_log("watchdog set %i %i\n", fdc.watchdog_timer, TIMER_USEC); } if ((val & 0x80) && !(fdc.dor & 0x80)) { @@ -639,15 +654,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) val &= 0xfe; } motoron[0 ^ fdd_swap] = val & 0x01; - /* if (!motoron[0 ^ fdd_swap]) - { - disc_changed[0 ^ fdd_swap] = 0; - } */ - // fdc.drive = 0; -/* if (motoron) - output = 3; - else - output = 0;*/ } else { @@ -678,7 +684,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) } timer_process(); timer_update_outstanding(); - // val &= 0x3f; /* Drives 2 and 3 are not emulated, so their motors are always forced off. */ /* We can now simplify this since each motor now spins separately. */ for (i = 0; i < FDD_NUM; i++) { @@ -693,13 +698,8 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) } } drive_num = real_drive(val & 3); - /* if (!motoron[drive_num]) - { - disc_changed[drive_num] = 0; - } */ } fdc.dor=val; - // printf("DOR now %02X (%04X:%04X)\n",val, CS, cpu_state.pc); return; case 3: /* TDR */ @@ -719,10 +719,8 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.perp &= 0xfc; fdc_reset(); } - // fdc_log("DSR now: %02X\n", val); return; case 5: /*Command register*/ - // fdc_log("CMD now: %02X\n", val); if ((fdc.stat & 0xf0) == 0xb0) { if (fdc.pcjr || !fdc.fifo) @@ -737,12 +735,8 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) } break; } -// if (fdc.inread) -// rfdc_log("c82c711_fdc_write : writing while inread! %02X\n", val); -// rfdc_log("Write command reg %i %i\n",fdc.pnum, fdc.ptot); if (fdc.pnum==fdc.ptot) { - // if ((fdc.stat & 0x10) || !fdc.stat) if ((fdc.stat & 0xf0) != 0x80) { /* If bit 4 of the MSR is set, or the MSR is 0x00, the FDC is NOT in the command phase, therefore do NOT accept commands. */ @@ -794,13 +788,11 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.sc=0; fdc.wrong_am=0; fdc.deleted = ((fdc.command&0x1F) == 9) ? 1 : 0; -// printf("Write data!\n"); fdc.pnum=0; fdc.ptot=8; fdc.stat |= 0x90; fdc.pos=0; fdc.mfm=(fdc.command&0x40)?1:0; -// readflash=1; break; case 6: /*Read data*/ case 0xC: /*Read deleted data*/ @@ -826,12 +818,8 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.stat |= 0x90; break; case 8: /*Sense interrupt status*/ - // if (!fdc.fintr && !fdc_reset_stat) fdc_log("Attempted SENSE INTERRUPT STATUS without FINTR\n"); if (!fdc.fintr && !fdc_reset_stat) goto bad_command; -// printf("Sense interrupt status %i\n",curdrive); fdc.lastdrive = fdc.drive; -// fdc.stat = 0x10 | (fdc.stat & 0xf); -// fdc_time=1024; discint = 8; fdc.pos = 0; fdc_callback(); @@ -902,9 +890,6 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) default: bad_command: - // fatal("Bad FDC command %02X\n",val); -// dumpregs(); -// exit(-1); fdc.stat |= 0x10; discint=0xfc; timer_process(); @@ -954,7 +939,6 @@ bad_command: fdc.read_track_sector.id.n = fdc.params[4]; fdc_implied_seek(); fdc.rw_track = fdc.params[1]; -// fdc_log("Read a track track=%i head=%i sector=%i eot=%i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc.sector, fdc.eot[fdc.drive]); disc_readsector(fdc.drive, SECTOR_FIRST, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); if (fdc.pcjr || !fdc.dma) { @@ -965,6 +949,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; + update_status_bar_icon(fdc.drive, 1); readflash = 1; fdc.inread = 1; break; @@ -988,7 +973,6 @@ bad_command: fdc.perp &= 0xfc; fdc.perp |= (fdc.params[0] & 0x03); } - // fdc_log("PERPENDICULAR: Set to: %02X\n", fdc.perp); disctime = 0; return; @@ -1011,7 +995,7 @@ bad_command: disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - readflash = 1; + update_status_bar_icon(fdc.drive, 1); fdc.pos = 0; if (fdc.pcjr) fdc.stat = 0xb0; @@ -1026,7 +1010,6 @@ bad_command: fdc.stat = 0xb0; } } - // ioc_fiq(IOC_FIQ_DISC_DATA); break; case 0x11: /*Scan equal*/ @@ -1045,7 +1028,7 @@ bad_command: disc_comparesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - readflash = 1; + update_status_bar_icon(fdc.drive, 1); fdc.pos = 0; if (fdc.pcjr || !fdc.dma) { @@ -1055,7 +1038,6 @@ bad_command: { fdc.stat = 0x90; } - // ioc_fiq(IOC_FIQ_DISC_DATA); break; case 0x16: /*Verify*/ @@ -1080,7 +1062,6 @@ bad_command: fdc.tc = 1; fdc.deleted |= 2; } - // dma_c2_mode(); disc_readsector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); if (fdc.pcjr || !fdc.dma) { @@ -1091,7 +1072,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; - readflash = 1; + update_status_bar_icon(fdc.drive, 1); fdc.inread = 1; break; @@ -1136,12 +1117,10 @@ bad_command: fdc.gap = fdc.params[3]; fdc.dtl = 4000000; fdc.format_sectors = fdc.params[2]; - // fdc_log("Formatting with %i sectors per track\n", fdc.format_sectors); fdc.format_n = fdc.params[1]; fdc.format_state = 1; fdc.pos = 0; fdc.stat = 0x10; - // fdc_log("FDC FORMAT: %02X %02X %02X %02X %02X\n", fdc.params[0], fdc.params[1], fdc.params[2], fdc.params[3], fdc.params[4]); break; case 0xf: /*Seek*/ @@ -1197,7 +1176,7 @@ bad_command: fdc_seek(fdc.drive, -fdc.params[1]); fdc.pcn[fdc.params[0] & 3] -= fdc.params[1]; } - disctime = ((int) fdc.params[1]) * seek_time * TIMER_USEC; + disctime = ((int) fdc.params[1]) * seek_time_base * TIMER_USEC; } else { @@ -1266,13 +1245,10 @@ bad_command: case 7: if (!AT) return; fdc.rate=val&3; - // fdc_log("Rate now: %i\n", val & 3); disc_3f7=val; return; } -// dumpregs(); -// exit(-1); } int paramstogo=0; @@ -1281,7 +1257,6 @@ uint8_t fdc_read(uint16_t addr, void *priv) uint8_t temp; int drive; fdc_log("Read FDC %04X\n",addr); - // /*if (addr!=0x3f4) */printf("Read FDC %04X %04X:%04X %04X %i %02X %02x %i ",addr,cs>>4,pc,BX,fdc.pos,fdc.st0,fdc.stat,ins); switch (addr&7) { case 0: /* STA */ @@ -1295,16 +1270,19 @@ uint8_t fdc_read(uint16_t addr, void *priv) drive = real_drive(fdc.dor & 3); if (!fdc.enable_3f1) return 0xff; -// temp=0x50; temp = 0x70; if (drive) temp &= ~0x40; else temp &= ~0x20; + + if (fdc.dor & 0x10) + temp |= 1; + if (fdc.dor & 0x20) + temp |= 2; break; case 2: temp = fdc.dor; - // fdc_log("Read DOR: %02X\n", fdc.dor); break; case 3: drive = real_drive(fdc.dor & 3); @@ -1334,7 +1312,6 @@ uint8_t fdc_read(uint16_t addr, void *priv) return 0; } temp=fdc.stat; - // fdc_log("Read MSR: %02X\n", fdc.stat); break; case 5: /*Data*/ fdc.stat&=~0x80; @@ -1346,24 +1323,19 @@ uint8_t fdc_read(uint16_t addr, void *priv) { temp = fdc_fifo_buf_read(); } - // fdc_log("Read DAT: %02X\n", temp); break; } if (paramstogo) { paramstogo--; temp=fdc.res[10 - paramstogo]; - // fdc_log("Read result: %02X\n", temp); -// fdc_log("Read param %i %02X\n",10-paramstogo,temp); if (!paramstogo) { fdc.stat=0x80; -// fdc.st0=0; } else { fdc.stat|=0xC0; -// fdc_poll(); } } else @@ -1372,7 +1344,6 @@ uint8_t fdc_read(uint16_t addr, void *priv) fdc.stat = 0x80; lastbyte=0; temp=fdc.dat; - // fdc_log("Read DAT: %02X\n", temp); fdc.data_ready = 0; } /* What the heck is this even doing?! */ @@ -1392,21 +1363,11 @@ uint8_t fdc_read(uint16_t addr, void *priv) temp = 0; if (fdc.dskchg_activelow) /*PC2086/3086 seem to reverse this bit*/ temp ^= 0x80; - if (AT) - { - temp |= 0x7F; - } - // fdc_log("Read CCR: %02X\n", temp); -// printf("- DC %i %02X %02X %i %i - ",fdc.dor & 3, fdc.dor, 0x10 << (fdc.dor & 3), discchanged[fdc.dor & 1], driveempty[fdc.dor & 1]); -// discchanged[fdc.dor&1]=0; + temp |= 0x01; break; default: temp=0xFF; -// printf("Bad read FDC %04X\n",addr); -// dumpregs(); -// exit(-1); } -// /*if (addr!=0x3f4) */printf("%02X rate=%i %i\n",temp,fdc.rate, fdc.data_ready); return temp; } @@ -1464,6 +1425,7 @@ void fdc_poll_common_finish(int compare, int st5) fdc.res[8]=fdc.head; fdc.res[9]=fdc.sector; fdc.res[10]=fdc.params[4]; + update_status_bar_icon(fdc.drive, 0); paramstogo=7; } @@ -1484,20 +1446,13 @@ void fdc_no_dma_end(int compare) void fdc_callback() { - int temp; int compare = 0; int drive_num = 0; int old_sector = 0; - int bad_end = 0; disctime = 0; -// fdc_log("fdc_callback %i %i\n", discint, disctime); -// if (fdc.inread) -// rfdc_log("c82c711_fdc_callback : while inread! %08X %i %02X %i\n", discint, fdc.drive, fdc.st0, ins); switch (discint) { case -3: /*End of command with interrupt*/ -// if (output) printf("EOC - interrupt!\n"); -//rfdc_log("EOC\n"); fdc_int(); fdc.stat = (fdc.stat & 0xf) | 0x80; return; @@ -1505,7 +1460,6 @@ void fdc_callback() fdc.stat = (fdc.stat & 0xf) | 0x80; return; case -1: /*Reset*/ -//rfdc_log("Reset\n"); fdc_int(); fdc.fintr = 0; memset(fdc.pcn, 0, 4); @@ -1517,10 +1471,9 @@ void fdc_callback() return; case 2: /*Read track*/ - readflash = 1; + update_status_bar_icon(fdc.drive, 1); fdc.eot[fdc.drive]--; fdc.read_track_sector.id.r++; -// fdc_log("Read a track callback, eot=%i\n", fdc.eot[fdc.drive]); if (!fdc.eot[fdc.drive] || fdc.tc) { fdc_poll_readwrite_finish(2); @@ -1564,7 +1517,6 @@ void fdc_callback() case 0x19: /*Scan low or equal*/ case 0x1C: /*Verify*/ case 0x1D: /*Scan high or equal*/ -// rfdc_log("Read data %i\n", fdc.tc); if ((discint == 0x11) || (discint == 0x19) || (discint == 0x1D)) { compare = 1; @@ -1573,14 +1525,12 @@ void fdc_callback() { compare = 0; } - bad_end = 1; if ((discint == 6) || (discint == 0xC)) { if (fdc.wrong_am && !(fdc.deleted & 0x20)) { /* Mismatching data address mark and no skip, set TC. */ fdc.tc = 1; - bad_end = 0; } } old_sector = fdc.sector; @@ -1657,7 +1607,7 @@ void fdc_callback() { fdc.sector++; } - readflash = 1; + update_status_bar_icon(fdc.drive, 1); switch (discint) { case 5: @@ -1703,7 +1653,6 @@ void fdc_callback() return; case 7: /*Recalibrate*/ - // if (!driveempty[fdc.dor & 3]) discchanged[fdc.dor & 3] = 0; fdc.pcn[fdc.params[0] & 3] = 0; drive_num = real_drive(fdc.rw_drive); fdc.st0 = 0x20 | (fdc.params[0] & 3); @@ -1715,12 +1664,10 @@ void fdc_callback() timer_process(); disctime = 2048 * (1 << TIMER_SHIFT); timer_update_outstanding(); -// printf("Recalibrate complete!\n"); fdc.stat = 0x80 | (1 << fdc.drive); return; case 8: /*Sense interrupt status*/ -// fdc_log("Sense interrupt status %i\n", fdc_reset_stat); fdc.stat = (fdc.stat & 0xf) | 0xd0; @@ -1751,18 +1698,14 @@ void fdc_callback() fdc.res[10] = fdc.pcn[fdc.res[9] & 3]; - // fdc_log("SENSE INTERRUPT STATUS: Results %02X %02X, ST0 %02X\n", fdc.res[9], fdc.res[10], fdc.st0); - paramstogo = 2; discint = 0; disctime = 0; return; case 0x0d: /*Format track*/ -// rfdc_log("Format\n"); if (fdc.format_state == 1) { -// ioc_fiq(IOC_FIQ_DISC_DATA); fdc.format_state = 2; timer_process(); disctime = 128 * (1 << TIMER_SHIFT); @@ -1770,7 +1713,6 @@ void fdc_callback() } else if (fdc.format_state == 2) { - // fdc_log("Format next stage track %i head %i n %i is_mfm %i gap %i sc %i\n", fdc.pcn[fdc.params[0] & 3], fdc.head, fdc_get_format_n(), fdc_is_mfm(), fdc_get_gap(), fdc_get_format_sectors()); disc_format(fdc.drive, fdc.head, fdc.rate, fdc.params[4]); fdc.format_state = 3; } @@ -1793,7 +1735,6 @@ void fdc_callback() return; case 15: /*Seek*/ -// printf("Seeked to track %i %i\n",fdc.pcn[fdc.params[0] & 3], fdc.drive); drive_num = real_drive(fdc.rw_drive); fdc.st0 = 0x20 | (fdc.params[0] & 7); discint=-3; @@ -1801,7 +1742,6 @@ void fdc_callback() disctime = 2048 * (1 << TIMER_SHIFT); timer_update_outstanding(); fdc.stat = 0x80 | (1 << fdc.drive); -// fdc_log("Stat %02X ST0 %02X\n", fdc.stat, fdc.st0); return; case 0x0e: /*Dump registers*/ fdc.stat = (fdc.stat & 0xf) | 0xd0; @@ -1833,11 +1773,8 @@ void fdc_callback() fdc.pretrk = fdc.params[2]; fdc.fifo = (fdc.params[1] & 0x20) ? 0 : 1; fdc.tfifo = (fdc.params[1] & 0xF) + 1; - // fdc_log("CONFIGURE (%02X, %02X, %02X)\n", fdc.params[0], fdc.params[1], fdc.params[2]); - // fdc_log("FIFO is now %02X, threshold is %02X\n", fdc.fifo, fdc.tfifo); fdc.stat = 0x80; disctime = 0; -// picint(0x40); return; case 0x14: /*Unlock*/ fdc.lock = 0; @@ -1866,19 +1803,13 @@ void fdc_callback() case 0xfc: /*Invalid*/ fdc.dat = fdc.st0 = 0x80; -// fdc_log("Inv!\n"); - //picint(0x40); fdc.stat = (fdc.stat & 0xf) | 0xd0; -// fdc.stat|=0xC0; fdc.res[10] = fdc.st0; paramstogo=1; discint=0; disctime = 0; return; } -// printf("Bad FDC disc int %i\n",discint); -// dumpregs(); -// exit(-1); } void fdc_error(int st5, int st6) @@ -1914,6 +1845,7 @@ void fdc_error(int st5, int st6) fdc.res[10]=0; break; } + update_status_bar_icon(fdc.drive, 0); paramstogo=7; } @@ -1948,7 +1880,6 @@ int fdc_data(uint8_t data) if (fdc.data_ready) { fdc_overrun(); -// fdc_log("Overrun\n"); return -1; } @@ -1960,11 +1891,11 @@ int fdc_data(uint8_t data) } else { - // FIFO enabled + /* FIFO enabled */ fdc_fifo_buf_write(data); if (fdc.fifobufpos == 0) { - // We have wrapped around, means FIFO is over + /* We have wrapped around, means FIFO is over */ fdc.data_ready = 1; fdc.stat = 0xf0; } @@ -1995,7 +1926,7 @@ int fdc_data(uint8_t data) fdc_fifo_buf_advance(); if (fdc.fifobufpos == 0) { - // We have wrapped around, means FIFO is over + /* We have wrapped around, means FIFO is over */ fdc.data_ready = 1; fdc.stat = 0xd0; } @@ -2008,8 +1939,6 @@ int fdc_data(uint8_t data) void fdc_finishread() { fdc.inread = 0; - // disctime = 200 * TIMER_USEC; -// rfdc_log("fdc_finishread\n"); } void fdc_track_finishread(int condition) @@ -2018,7 +1947,6 @@ void fdc_track_finishread(int condition) fdc.satisfying_sectors |= condition; fdc.inread = 0; fdc_callback(); -// rfdc_log("fdc_finishread\n"); } void fdc_sector_finishcompare(int satisfying) @@ -2027,7 +1955,6 @@ void fdc_sector_finishcompare(int satisfying) fdc.satisfying_sectors++; fdc.inread = 0; fdc_callback(); -// rfdc_log("fdc_finishread\n"); } void fdc_sector_finishread() @@ -2035,18 +1962,8 @@ void fdc_sector_finishread() fdc.stat = 0x10; fdc.inread = 0; fdc_callback(); -// rfdc_log("fdc_finishread\n"); } -#if 0 -void fdc_notfound() -{ - fdc_error(5, 0); - -// rfdc_log("c82c711_fdc_notfound\n"); -} -#endif - /* There is no sector ID. */ void fdc_noidam() { @@ -2075,15 +1992,11 @@ void fdc_cannotformat() void fdc_datacrcerror() { fdc_error(0x20, 0x20); - -// rfdc_log("c82c711_fdc_datacrcerror\n"); } void fdc_headercrcerror() { fdc_error(0x20, 0); - -// rfdc_log("c82c711_fdc_headercrcerror\n"); } void fdc_wrongcylinder() @@ -2110,7 +2023,6 @@ int fdc_getdata(int last) if (fdc.written) { fdc_overrun(); -// fdc_log("Overrun\n"); return -1; } if (fdc.pcjr || !fdc.fifo) @@ -2155,7 +2067,6 @@ int fdc_getdata(int last) void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2) { - // fdc_log("SectorID %i %i %i %i\n", track, side, sector, size); fdc_int(); fdc.stat=0xD0; fdc.res[4]=(fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.drive; @@ -2170,8 +2081,7 @@ void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uin void fdc_indexpulse() { -// ioc_irqa(IOC_IRQA_DISC_INDEX); -// rfdc_log("c82c711_fdc_indexpulse\n"); + return; } void fdc_hard_reset() diff --git a/src/fdc.h b/src/fdc.h index 9b1f840aa..5bdb7d00e 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -64,3 +64,7 @@ void fdc_track_finishread(int condition); int fdc_is_verify(); int real_drive(int drive); +void fdc_overrun(); +void fdc_set_base(int base, int super_io); +int fdc_ps1_525(); +void fdc_hard_reset(); diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 59e0bcb78..53b4f6b24 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -6,6 +6,7 @@ #include "disc.h" #include "fdc.h" #include "fdd.h" +#include "ide.h" #include "io.h" #include "lpt.h" #include "serial.h" @@ -14,6 +15,7 @@ static uint8_t fdc37c665_lock[2]; static int fdc37c665_curreg; static uint8_t fdc37c665_regs[16]; +static int com3_addr, com4_addr; static void write_lock(uint8_t val) { @@ -26,9 +28,127 @@ static void write_lock(uint8_t val) fdc37c665_lock[1] = val; } +static void ide_handler() +{ + uint16_t or_value = 0; + if (romset == ROM_440FX) + { + return; + } + ide_pri_disable(); + if (fdc37c665_regs[0] & 1) + { + if (fdc37c665_regs[5] & 2) + { + or_value = 0; + } + else + { + or_value = 0x800; + } + ide_set_base(0, 0x170 | or_value); + ide_set_side(0, 0x376 | or_value); + ide_pri_enable_ex(); + } + else + { + pclog("Disabling IDE...\n"); + } +} + +static void set_com34_addr() +{ + switch (fdc37c665_regs[1] & 0x60) + { + case 0x00: + com3_addr = 0x338; + com4_addr = 0x238; + break; + case 0x20: + com3_addr = 0x3e8; + com4_addr = 0x2e8; + break; + case 0x40: + com3_addr = 0x3e8; + com4_addr = 0x2e0; + break; + case 0x60: + com3_addr = 0x220; + com4_addr = 0x228; + break; + } +} + +void set_serial1_addr() +{ + if (fdc37c665_regs[2] & 4) + { + switch (fdc37c665_regs[2] & 3) + { + case 0: + serial1_set(0x3f8, 4); + break; + + case 1: + serial1_set(0x2f8, 3); + break; + + case 2: + serial1_set(com3_addr, 4); + break; + + case 3: + serial1_set(com4_addr, 3); + break; + } + } +} + +void set_serial2_addr() +{ + if (fdc37c665_regs[2] & 0x40) + { + switch (fdc37c665_regs[2] & 0x30) + { + case 0: + serial2_set(0x3f8, 4); + break; + + case 1: + serial2_set(0x2f8, 3); + break; + + case 2: + serial2_set(com3_addr, 4); + break; + + case 3: + serial2_set(com4_addr, 3); + break; + } + } +} + +static void lpt1_handler() +{ + lpt1_remove(); + switch (fdc37c665_regs[1] & 3) + { + case 1: + lpt1_init(0x3bc); + break; + case 2: + lpt1_init(0x378); + break; + case 3: + lpt1_init(0x278); + break; + } +} + void fdc37c665_write(uint16_t port, uint8_t val, void *priv) { - // pclog("Write SuperIO %04x %02x\n", port, val); + uint8_t valxor = 0; if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) { if (port == 0x3f0) @@ -36,89 +156,75 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv) if (val == 0xaa) write_lock(val); else - fdc37c665_curreg = val & 0xf; + if (fdc37c665_curreg != 0) + { + fdc37c665_curreg = val & 0xf; + } + else + { + /* Hardcode the IDE to AT type. */ + fdc37c665_curreg = (val & 0xf) | 2; + } } else { - uint16_t com3_addr, com4_addr; + valxor = val ^ fdc37c665_regs[fdc37c665_curreg]; fdc37c665_regs[fdc37c665_curreg] = val; -// pclog("Write superIO %02x %02x %04x(%08x):%08x\n", fdc37c665_curreg, val, CS, cs, pc); - switch (fdc37c665_regs[1] & 0x60) - { - case 0x00: - com3_addr = 0x338; - com4_addr = 0x238; - break; - case 0x20: - com3_addr = 0x3e8; - com4_addr = 0x2e8; - break; - case 0x40: - com3_addr = 0x3e8; - com4_addr = 0x2e0; - break; - case 0x60: - com3_addr = 0x220; - com4_addr = 0x228; - break; + switch(fdc37c665_curreg) + { + case 0: + if (valxor & 1) + { + ide_handler(); + } + break; + case 1: + if (valxor & 3) + { + lpt1_handler(); + } + if (valxor & 0x60) + { + serial1_remove(); + set_com34_addr(); + set_serial1_addr(); + set_serial2_addr(); + } + break; + case 2: + if (valxor & 7) + { + serial1_remove(); + set_serial1_addr(); + } + if (valxor & 0x70) + { + serial2_remove(); + set_serial2_addr(); + } + break; + case 3: + if (valxor & 2) + { + fdc_update_enh_mode((fdc37c665_regs[3] & 2) ? 1 : 0); + } + break; + case 5: + if (valxor & 2) + { + ide_handler(); + } + if (valxor & 0x18) + { + fdc_update_densel_force((fdc37c665_regs[5] & 0x18) >> 3); + } + if (valxor & 0x20) + { + fdd_swap = ((fdc37c665_regs[5] & 0x20) >> 5); + } + break; } - - if (!(fdc37c665_regs[2] & 4)) - serial1_remove(); - else switch (fdc37c665_regs[2] & 3) - { - case 0: - serial1_set(0x3f8, 4); - break; - case 1: - serial1_set(0x2f8, 4); - break; - case 2: - serial1_set(com3_addr, 4); - break; - case 3: - serial1_set(com4_addr, 4); - break; - } - - if (!(fdc37c665_regs[2] & 0x40)) - serial2_remove(); - else switch (fdc37c665_regs[2] & 0x30) - { - case 0x00: - serial2_set(0x3f8, 3); - break; - case 0x10: - serial2_set(0x2f8, 3); - break; - case 0x20: - serial2_set(com3_addr, 3); - break; - case 0x30: - serial2_set(com4_addr, 3); - break; - } - - lpt1_remove(); - lpt2_remove(); - switch (fdc37c665_regs[1] & 3) - { - case 1: - lpt1_init(0x3bc); - break; - case 2: - lpt1_init(0x378); - break; - case 3: - lpt1_init(0x278); - break; - } - - fdc_update_enh_mode((fdc37c665_regs[3] & 2) ? 1 : 0); - - fdc_update_densel_force((fdc37c665_regs[5] & 0x18) >> 3); - fdd_swap = ((fdc37c665_regs[5] & 0x20) >> 5); } } else @@ -130,7 +236,6 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv) uint8_t fdc37c665_read(uint16_t port, void *priv) { - // pclog("Read SuperIO %04x %02x\n", port, fdc37c665_curreg); if (fdc37c665_lock[0] == 0x55 && fdc37c665_lock[1] == 0x55) { if (port == 0x3f1) @@ -141,8 +246,25 @@ uint8_t fdc37c665_read(uint16_t port, void *priv) void fdc37c665_reset(void) { + com3_addr = 0x338; + com4_addr = 0x238; + + fdc_remove(); + fdc_add_for_superio(); + fdc_update_is_nsc(0); + serial1_remove(); + serial1_set(0x3f8, 4); + + serial2_remove(); + serial2_set(0x2f8, 3); + + lpt2_remove(); + + lpt1_remove(); + lpt1_init(0x378); + memset(fdc37c665_lock, 0, 2); memset(fdc37c665_regs, 0, 16); fdc37c665_regs[0x0] = 0x3b; diff --git a/src/fdc37c669.c b/src/fdc37c669.c new file mode 100644 index 000000000..337b8cec1 --- /dev/null +++ b/src/fdc37c669.c @@ -0,0 +1,335 @@ +/* + SMSC SMC FDC37C669 Super I/O Chip + Used by the 430TX +*/ + +#include "ibm.h" + +#include "disc.h" +#include "fdc.h" +#include "fdd.h" +#include "io.h" +#include "ide.h" +#include "lpt.h" +#include "serial.h" +#include "fdc37c669.h" + +static int fdc37c669_locked; +static int fdc37c669_rw_locked = 0; +static int fdc37c669_curreg = 0; +static uint8_t fdc37c669_regs[42]; +static uint8_t tries; + +static uint16_t fdc_valid_ports[2] = {0x3F0, 0x370}; +static uint16_t ide_valid_ports[2] = {0x1F0, 0x170}; +static uint16_t ide_as_valid_ports[2] = {0x3F6, 0x376}; +static uint16_t lpt1_valid_ports[3] = {0x3BC, 0x378, 0x278}; +static uint16_t com1_valid_ports[9] = {0x3F8, 0x2F8, 0x338, 0x3E8, 0x2E8, 0x220, 0x238, 0x2E0, 0x228}; +static uint16_t com2_valid_ports[9] = {0x3F8, 0x2F8, 0x338, 0x3E8, 0x2E8, 0x220, 0x238, 0x2E0, 0x228}; + +static uint8_t is_in_array(uint16_t *port_array, uint8_t max, uint16_t port) +{ + uint8_t i = 0; + + for (i = 0; i < max; i++) + { + if (port_array[i] == port) return 1; + } + return 0; +} + +static uint16_t make_port(uint8_t reg) +{ + uint16_t p = 0; + + switch(reg) + { + case 0x20: + p = ((uint16_t) (fdc37c669_regs[reg] & 0xfc)) << 2; + p &= 0xFF0; + if ((p < 0x100) || (p > 0x3F0)) p = 0x3F0; + if (!(is_in_array(fdc_valid_ports, 2, p))) p = 0x3F0; + fdc37c669_regs[reg] = ((p >> 2) & 0xfc) | (fdc37c669_regs[reg] & 3); + break; + case 0x21: + p = ((uint16_t) (fdc37c669_regs[reg] & 0xfc)) << 2; + p &= 0xFF0; + if ((p < 0x100) || (p > 0x3F0)) p = 0x1F0; + if (!(is_in_array(ide_valid_ports, 2, p))) p = 0x1F0; + fdc37c669_regs[reg] = ((p >> 2) & 0xfc) | (fdc37c669_regs[reg] & 3); + break; + case 0x22: + p = ((uint16_t) (fdc37c669_regs[reg] & 0xfc)) << 2; + p &= 0xFF0; + if ((p < 0x106) || (p > 0x3F6)) p = 0x3F6; + if (!(is_in_array(ide_as_valid_ports, 2, p))) p = 0x3F6; + fdc37c669_regs[reg] = ((p >> 2) & 0xfc) | (fdc37c669_regs[reg] & 3); + break; + case 0x23: + p = ((uint16_t) (fdc37c669_regs[reg] & 0xff)) << 2; + p &= 0xFFC; + if ((p < 0x100) || (p > 0x3F8)) p = 0x378; + if (!(is_in_array(lpt1_valid_ports, 3, p))) p = 0x378; + fdc37c669_regs[reg] = (p >> 2); + break; + case 0x24: + p = ((uint16_t) (fdc37c669_regs[reg] & 0xfe)) << 2; + p &= 0xFF8; + if ((p < 0x100) || (p > 0x3F8)) p = 0x3F8; + if (!(is_in_array(com1_valid_ports, 9, p))) p = 0x3F8; + fdc37c669_regs[reg] = ((p >> 2) & 0xfe) | (fdc37c669_regs[reg] & 1); + break; + case 0x25: + p = ((uint16_t) (fdc37c669_regs[reg] & 0xfe)) << 2; + p &= 0xFF8; + if ((p < 0x100) || (p > 0x3F8)) p = 0x2F8; + if (!(is_in_array(com2_valid_ports, 9, p))) p = 0x2F8; + fdc37c669_regs[reg] = ((p >> 2) & 0xfe) | (fdc37c669_regs[reg] & 1); + break; + } + + return p; +} + +void fdc37c669_write(uint16_t port, uint8_t val, void *priv) +{ + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0; + uint8_t max = 42; + pclog("fdc37c669_write : port=%04x reg %02X = %02X locked=%i\n", port, fdc37c669_curreg, val, fdc37c669_locked); + + if (index) + { + if ((val == 0x55) && !fdc37c669_locked) + { + if (tries) + { + fdc37c669_locked = 1; + tries = 0; + } + else + { + tries++; + } + } + else + { + if (fdc37c669_locked) + { + if (val < max) fdc37c669_curreg = val; + if (val == 0xaa) fdc37c669_locked = 0; + } + else + { + if (tries) + tries = 0; + } + } + } + else + { + if (fdc37c669_locked) + { + if ((fdc37c669_curreg < 0x18) && (fdc37c669_rw_locked)) return; + if ((fdc37c669_curreg >= 0x26) && (fdc37c669_curreg <= 0x27)) return; + if (fdc37c669_curreg == 0x29) return; + valxor = val ^ fdc37c669_regs[fdc37c669_curreg]; + fdc37c669_regs[fdc37c669_curreg] = val; + goto process_value; + } + } + return; + +process_value: + switch(fdc37c669_curreg) + { + case 0: + if (valxor & 3) + { + ide_pri_disable(); + if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable_ex(); + break; + } + if (valxor & 8) + { + fdc_remove(); + if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(make_port(0x20), 1); + } + break; + case 1: + if (valxor & 4) + { + lpt1_remove(); + if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] & 0xc0)) lpt1_init(make_port(0x23)); + } + if (valxor & 7) + { + fdc37c669_rw_locked = (val & 8) ? 0 : 1; + } + break; + case 2: + if (valxor & 8) + { + serial1_remove(); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + } + if (valxor & 0x80) + { + serial2_remove(); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + } + break; + case 3: + if (valxor & 2) fdc_update_enh_mode((val & 2) ? 1 : 0); + break; + case 5: + if (valxor & 0x18) fdc_update_densel_force((val & 0x18) >> 3); + if (valxor & 0x20) fdd_swap = ((val & 0x20) >> 5); + break; + case 0xB: + if (valxor & 3) fdc_update_rwc(0, val & 3); + if (valxor & 0xC) fdc_update_rwc(1, (val & 0xC) >> 2); + break; + case 0x20: + if (valxor & 0xfc) + { + fdc_remove(); + if ((fdc37c669_regs[0] & 8) && (fdc37c669_regs[0x20] & 0xc0)) fdc_set_base(make_port(0x20), 1); + } + break; + case 0x21: + case 0x22: + if (valxor & 0xfc) + { + ide_pri_disable(); + switch (fdc37c669_curreg) + { + case 0x21: + ide_set_base(0, make_port(0x21)); + break; + case 0x22: + ide_set_side(0, make_port(0x22)); + break; + } + if ((fdc37c669_regs[0] & 3) == 2) ide_pri_enable_ex(); + } + break; + case 0x23: + if (valxor) + { + lpt1_remove(); + if ((fdc37c669_regs[1] & 4) && (fdc37c669_regs[0x23] & 0xc0)) lpt1_init(make_port(0x23)); + } + break; + case 0x24: + if (valxor & 0xfe) + { + serial1_remove(); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + } + break; + case 0x25: + if (valxor & 0xfe) + { + serial2_remove(); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + } + break; + case 0x28: + if (valxor & 0xf) + { + serial2_remove(); + if ((fdc37c669_regs[0x28] & 0xf) == 0) fdc37c669_regs[0x28] |= 0x3; + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + } + if (valxor & 0xf0) + { + serial1_remove(); + if ((fdc37c669_regs[0x28] & 0xf0) == 0) fdc37c669_regs[0x28] |= 0x40; + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + } + break; + } +} + +uint8_t fdc37c669_read(uint16_t port, void *priv) +{ + uint8_t index = (port & 1) ? 0 : 1; + + pclog("fdc37c669_read : port=%04x reg %02X locked=%i\n", port, fdc37c669_curreg, fdc37c669_locked); + + if (!fdc37c669_locked) + { + return 0xFF; + } + + if (index) + return fdc37c669_curreg; + else + { + pclog("0x03F1: %02X\n", fdc37c669_regs[fdc37c669_curreg]); + if ((fdc37c669_curreg < 0x18) && (fdc37c669_rw_locked)) return 0xff; + return fdc37c669_regs[fdc37c669_curreg]; + } +} + +void fdc37c669_reset(void) +{ + fdc_remove(); + fdc_add_for_superio(); + + fdc_update_is_nsc(0); + + serial1_remove(); + serial1_set(0x3f8, 4); + + serial2_remove(); + serial2_set(0x2f8, 3); + + lpt2_remove(); + + lpt1_remove(); + lpt1_init(0x378); + + memset(fdc37c669_regs, 0, 42); + fdc37c669_regs[0] = 0x28; + fdc37c669_regs[1] = 0x9C; + fdc37c669_regs[2] = 0x88; + fdc37c669_regs[3] = 0x78; + fdc37c669_regs[4] = 0; + fdc37c669_regs[5] = 0; + fdc37c669_regs[6] = 0xFF; + fdc37c669_regs[7] = 0; + fdc37c669_regs[8] = 0; + fdc37c669_regs[9] = 0; + fdc37c669_regs[0xA] = 0; + fdc37c669_regs[0xB] = 0; + fdc37c669_regs[0xC] = 0; + fdc37c669_regs[0xD] = 3; + fdc37c669_regs[0xE] = 2; + fdc37c669_regs[0x1E] = 0x80; /* Gameport controller. */ + fdc37c669_regs[0x20] = (0x3f0 >> 2) & 0xfc; + fdc37c669_regs[0x21] = (0x1f0 >> 2) & 0xfc; + fdc37c669_regs[0x22] = ((0x3f6 >> 2) & 0xfc) | 1; + fdc37c669_regs[0x23] = (0x378 >> 2); + fdc37c669_regs[0x24] = (0x3f8 >> 2) & 0xfe; + fdc37c669_regs[0x25] = (0x2f8 >> 2) & 0xfe; + fdc37c669_regs[0x26] = (2 << 4) | 3; + fdc37c669_regs[0x27] = (6 << 4) | 7; + fdc37c669_regs[0x28] = (4 << 4) | 3; + + fdc_update_densel_polarity(1); + fdc_update_densel_force(0); + fdd_swap = 0; + fdc37c669_locked = 0; + fdc37c669_rw_locked = 0; +} + +void fdc37c669_init() +{ + io_sethandler(0x3f0, 0x0002, fdc37c669_read, NULL, NULL, fdc37c669_write, NULL, NULL, NULL); + + fdc37c669_reset(); + + pci_reset_handler.super_io_reset = fdc37c669_reset; +} diff --git a/src/fdc37c669.h b/src/fdc37c669.h new file mode 100644 index 000000000..f3fa420d7 --- /dev/null +++ b/src/fdc37c669.h @@ -0,0 +1 @@ +extern void fdc37c669_init(); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 27385712a..13b8371bd 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -144,9 +144,6 @@ void fdc37c932fr_write(uint16_t port, uint8_t val, void *priv) uint8_t index = (port & 1) ? 0 : 1; uint8_t valxor = 0; uint16_t ld_port = 0; - uint16_t ld_port2 = 0; - int temp; - // pclog("fdc37c932fr_write : port=%04x reg %02X = %02X locked=%i\n", port, fdc37c932fr_curreg, val, fdc37c932fr_locked); if (index) { @@ -367,7 +364,6 @@ uint8_t fdc37c932fr_gpio_read(uint16_t port, void *priv) uint8_t fdc37c932fr_read(uint16_t port, void *priv) { - // pclog("fdc37c932fr_read : port=%04x reg %02X locked=%i\n", port, fdc37c932fr_curreg, fdc37c932fr_locked); uint8_t index = (port & 1) ? 0 : 1; if (!fdc37c932fr_locked) @@ -381,12 +377,10 @@ uint8_t fdc37c932fr_read(uint16_t port, void *priv) { if (fdc37c932fr_curreg < 0x30) { - // pclog("0x03F1: %02X\n", fdc37c932fr_regs[fdc37c932fr_curreg]); return fdc37c932fr_regs[fdc37c932fr_curreg]; } else { - // pclog("0x03F1 (CD=%02X): %02X\n", fdc37c932fr_regs[7], fdc37c932fr_ld_regs[fdc37c932fr_regs[7]][fdc37c932fr_curreg]); if ((fdc37c932fr_regs[7] == 0) && (fdc37c932fr_curreg == 0xF2)) return (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2)); return fdc37c932fr_ld_regs[fdc37c932fr_regs[7]][fdc37c932fr_curreg]; } diff --git a/src/fdd.c b/src/fdd.c index b6c49143a..1ecc6eebd 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -18,85 +18,116 @@ static struct } fdd[FDD_NUM]; /* Flags: - Bit 0: 300 rpm supported; - Bit 1: 360 rpm supported; - Bit 2: size (0 = 3.5", 1 = 5.25"); - Bit 3: double density supported; - Bit 4: high density supported; - Bit 5: extended density supported; - Bit 6: double step for 40-track media; - Bit 7: invert DENSEL polarity; - Bit 8: ignore DENSEL; - Bit 9: drive is a PS/2 drive; + Bit 0: 300 rpm supported; + Bit 1: 360 rpm supported; + Bit 2: size (0 = 3.5", 1 = 5.25"); + Bit 3: sides (0 = 1, 1 = 2); + Bit 4: double density supported; + Bit 5: high density supported; + Bit 6: extended density supported; + Bit 7: double step for 40-track media; + Bit 8: invert DENSEL polarity; + Bit 9: ignore DENSEL; + Bit 10: drive is a PS/2 drive; */ #define FLAG_RPM_300 1 #define FLAG_RPM_360 2 -#define FLAG_525 4 -#define FLAG_HOLE0 8 -#define FLAG_HOLE1 16 -#define FLAG_HOLE2 32 -#define FLAG_DOUBLE_STEP 64 -#define FLAG_INVERT_DENSEL 128 -#define FLAG_IGNORE_DENSEL 256 -#define FLAG_PS2 512 +#define FLAG_525 4 +#define FLAG_DS 8 +#define FLAG_HOLE0 16 +#define FLAG_HOLE1 32 +#define FLAG_HOLE2 64 +#define FLAG_DOUBLE_STEP 128 +#define FLAG_INVERT_DENSEL 256 +#define FLAG_IGNORE_DENSEL 512 +#define FLAG_PS2 1024 static struct { int max_track; int flags; + char name[64]; + char internal_name[24]; } drive_types[] = { { /*None*/ - .max_track = 0, - .flags = 0 + 0, 0, "None", "none" + }, + { /*5.25" 1DD*/ + 43, FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0, "5.25\" 180k", "525_1dd" }, { /*5.25" DD*/ - .max_track = 43, - .flags = FLAG_RPM_300 | FLAG_525 | FLAG_HOLE0 + 43, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0, "5.25\" 360k", "525_2dd" + }, + { /*5.25" QD*/ + 86, FLAG_RPM_300 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "5.25\" 720k", "525_2qd" + }, + { /*5.25" HD PS/2*/ + 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "5.25\" 1.2M PS/2", "525_2hd_ps2" }, { /*5.25" HD*/ - .max_track = 86, - .flags = FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP + 86, FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M", "525_2hd" }, { /*5.25" HD Dual RPM*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP + 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_525 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "5.25\" 1.2M 300/360 RPM", "525_2hd_dualrpm" + }, + { /*3.5" 1DD*/ + 86, FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 360k", "35_1dd" }, { /*3.5" DD*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_DOUBLE_STEP + 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_DOUBLE_STEP, "3.5\" 720k", "35_2dd" }, { /*3.5" HD PS/2*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2 + 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL | FLAG_PS2, "3.5\" 1.44M PS/2", "35_2hd_ps2" }, { /*3.5" HD*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP + 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M", "35_2hd" }, { /*3.5" HD PC-98*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL + 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP | FLAG_INVERT_DENSEL, "3.5\" 1.25M PC-98", "35_2hd_nec" }, { /*3.5" HD 3-Mode*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_RPM_360 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP + 86, FLAG_RPM_300 | FLAG_RPM_360 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_DOUBLE_STEP, "3.5\" 1.44M 300/360 RPM", "35_2hd_3mode" }, { /*3.5" ED*/ - .max_track = 86, - .flags = FLAG_RPM_300 | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP + 86, FLAG_RPM_300 | FLAG_DS | FLAG_HOLE0 | FLAG_HOLE1 | FLAG_HOLE2 | FLAG_DOUBLE_STEP, "3.5\" 2.88M", "35_2ed" + }, + { /*End of list*/ + -1, -1, "", "" } }; int fdd_swap = 0; +char *fdd_getname(int type) +{ + return drive_types[type].name; +} + +char *fdd_get_internal_name(int type) +{ + return drive_types[type].internal_name; +} + +int fdd_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(drive_types[c].internal_name)) + { + if (!strcmp(drive_types[c].internal_name, s)) + return c; + c++; + } + + return 0; +} + void fdd_forced_seek(int drive, int track_diff) { drive = real_drive(drive); fdd[drive].track += track_diff; - - // pclog("Seeking %i tracks...\n", track_diff); if (fdd[drive].track < 0) fdd[drive].track = 0; @@ -120,8 +151,6 @@ void fdd_seek(int drive, int track_diff) fdd[drive].track += track_diff; - // pclog("Seeking %i tracks...\n", track_diff); - if (fdd[drive].track < 0) fdd[drive].track = 0; @@ -209,7 +238,6 @@ int fdd_can_read_medium(int drive) hole = 1 << (hole + 3); -// pclog("Drive %02X, type %02X, hole flag %02X, flags %02X, result %02X\n", drive, fdd[drive].type, hole, drive_types[fdd[drive].type].flags, drive_types[fdd[drive].type].flags & hole); return (drive_types[fdd[drive].type].flags & hole) ? 1 : 0; } diff --git a/src/fdd.h b/src/fdd.h index 131e94bcf..f9481148f 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -21,4 +21,9 @@ int fdd_get_flags(int drive); extern int fdd_swap; -void fdd_init(); \ No newline at end of file +void fdd_init(); +int fdd_get_densel(int drive); + +void fdd_setswap(int swap); + +char *fdd_getname(int type); diff --git a/src/fdi2raw.c b/src/fdi2raw.c index a82af5230..68edb5e26 100644 --- a/src/fdi2raw.c +++ b/src/fdi2raw.c @@ -28,7 +28,6 @@ #include "sysdeps.h" #include "zfile.h"*/ /* ELSE */ -//#include "types.h" #define xmalloc malloc #include "fdi2raw.h" @@ -243,26 +242,26 @@ static void fdi_decode (uae_u8 *stream, int size, uae_u8 *out) sub_stream_shift = 1; while (sub_stream_shift) { - //sub-stream header decode + /* sub-stream header decode */ sign_extend = *stream++; sub_stream_shift = sign_extend & 0x7f; sign_extend &= 0x80; sixteen_bit = (*stream++) & 0x80; - //huffman tree architecture decode + /* huffman tree architecture decode */ temp = *stream++; temp2 = 0x80; stream = expand_tree (stream, &root); if (temp2 == 0x80) stream--; - //huffman output values decode + /* huffman output values decode */ if (sixteen_bit) stream = values_tree16 (stream, &root); else stream = values_tree8 (stream, &root); - //sub-stream data decode + /* sub-stream data decode */ temp2 = 0; for (i = 0; i < size; i++) { uae_u32 v; @@ -312,20 +311,18 @@ static int decode_raw_track (FDI *fdi) static void zxx (FDI *fdi) { outlog ("track %d: unknown track type 0x%02.2X\n", fdi->current_track, fdi->track_type); -// return -1; } /* unsupported track */ #if 0 static void zyy (FDI *fdi) { outlog ("track %d: unsupported track type 0x%02.2X\n", fdi->current_track, fdi->track_type); -// return -1; } #endif /* empty track */ static void track_empty (FDI *fdi) { -// return 0; + return; } /* unknown sector described type */ @@ -575,7 +572,6 @@ static void s0d(FDI *fdi) } }*/ -//static int check_offset; /*static uae_u16 getmfmword (uae_u8 *mbuf) { uae_u32 v; @@ -633,7 +629,6 @@ static int amiga_check_track (FDI *fdi) mbuf = bigmfmbuf; memset (sectable, 0, sizeof (sectable)); - //memcpy (mbuf + fwlen, mbuf, fwlen * sizeof (uae_u16)); mend = bigmfmbuf + length; mend -= (4 + 16 + 8 + 512); @@ -648,7 +643,6 @@ static int amiga_check_track (FDI *fdi) mbuf[0] = 0x44; mbuf[1] = 0x89; } -// check_offset++; if (check_offset > 7) { check_offset = 0; mbuf++; @@ -1399,7 +1393,7 @@ static void init_array(uint32_t standard_MFM_2_bit_cell_size, int nb_of_bits) int i; for (i = 0; i < FDI_MAX_ARRAY; i++) { - psarray[i].size = standard_MFM_2_bit_cell_size; // That is (total track length / 50000) for Amiga double density + psarray[i].size = standard_MFM_2_bit_cell_size; /* That is (total track length / 50000) for Amiga double density */ total += psarray[i].size; psarray[i].number_of_bits = nb_of_bits; totaldiv += psarray[i].number_of_bits; @@ -1448,7 +1442,6 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */ if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) || (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) { - //init_array(standard_MFM_2_bit_cell_size, 2); avg_size = standard_MFM_8_bit_cell_size; } /* this is to prevent the average value from going too far @@ -1578,7 +1571,6 @@ static void fdi2_decode (FDI *fdi, uint32_t totalavg, uae_u32 *avgp, uae_u32 *mi /* you can try tighter ranges than 25%, or wider ranges. I would probably go for tighter... */ if ((avg_size < (standard_MFM_8_bit_cell_size - (pulse_limitval * standard_MFM_8_bit_cell_size / 100))) || (avg_size > (standard_MFM_8_bit_cell_size + (pulse_limitval * standard_MFM_8_bit_cell_size / 100)))) { - //init_array(standard_MFM_2_bit_cell_size, mfm + 1); avg_size = standard_MFM_8_bit_cell_size; } /* this is to prevent the average value from going too far @@ -1801,16 +1793,15 @@ static void fdi2_celltiming (FDI *fdi, uint32_t totalavg, int bitoffset, uae_u16 static int decode_lowlevel_track (FDI *fdi, int track, struct fdi_cache *cache) { - uae_u8 *p1, *d; + uae_u8 *p1; uae_u32 *p2; uae_u32 *avgp, *minp = 0, *maxp = 0; uae_u8 *idxp = 0; uae_u32 maxidx, totalavg, weakbits; int i, j, len, pulses, indexoffset; int avg_free, min_free = 0, max_free = 0, idx_free; - int idx_off1, idx_off2, idx_off3; + int idx_off1 = 0, idx_off2 = 0, idx_off3 = 0; - d = fdi->track_dst; p1 = fdi->track_src; pulses = get_u32 (p1); if (!pulses) @@ -2077,7 +2068,6 @@ int fdi2raw_loadrevolution_2 (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, i fdi2_decode (fdi, cache->totalavg, cache->avgp, cache->minp, cache->maxp, cache->idxp, cache->maxidx, &idx, cache->pulses, mfm); - //fdi2_gcr_decode (fdi, totalavg, avgp, minp, maxp, idxp, idx_off1, idx_off2, idx_off3, maxidx, pulses); /* outlog("track %d: nbits=%d avg len=%.2f weakbits=%d idx=%d\n", track, bitoffset, (double)cache->totalavg / bitoffset, cache->weakbits, cache->indexoffset); */ len = fdi->out; @@ -2164,8 +2154,6 @@ int fdi2raw_loadtrack (FDI *fdi, uae_u16 *mfmbuf, uae_u16 *tracktiming, int trac } -// amiga_check_track (fdi); - if (fdi->err) return 0; diff --git a/src/fdi2raw.h b/src/fdi2raw.h index 207dabd7e..b8c3201e5 100644 --- a/src/fdi2raw.h +++ b/src/fdi2raw.h @@ -8,7 +8,6 @@ #define uae_u16 uint16_t #define uae_u32 uint32_t -//#include "types.h" #include typedef struct fdi FDI; diff --git a/src/filters.h b/src/filters.h index acc022ba0..6269b55e3 100644 --- a/src/filters.h +++ b/src/filters.h @@ -3,8 +3,7 @@ */ #define NCoef 2 -//fc=350Hz -static inline float low_iir(int i, float NewSample) { +static __inline float low_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.00049713569693400649, 0.00099427139386801299, @@ -17,17 +16,17 @@ static inline float low_iir(int i, float NewSample) { 0.93726236021404663000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -36,8 +35,7 @@ static inline float low_iir(int i, float NewSample) { return y[i][0]; } -//fc=350Hz -static inline float low_cut_iir(int i, float NewSample) { +static __inline float low_cut_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.96839970114733542000, -1.93679940229467080000, @@ -50,17 +48,17 @@ static inline float low_cut_iir(int i, float NewSample) { 0.93726236021916731000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -69,8 +67,7 @@ static inline float low_cut_iir(int i, float NewSample) { return y[i][0]; } -//fc=3.5kHz -static inline float high_iir(int i, float NewSample) { +static __inline float high_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.72248704753064896000, -1.44497409506129790000, @@ -82,17 +79,17 @@ static inline float high_iir(int i, float NewSample) { -1.36640781670578510000, 0.52352474706139873000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -101,8 +98,7 @@ static inline float high_iir(int i, float NewSample) { return y[i][0]; } -//fc=3.5kHz -static inline float high_cut_iir(int i, float NewSample) { +static __inline float high_cut_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.03927726802250377400, 0.07855453604500754700, @@ -114,17 +110,17 @@ static inline float high_cut_iir(int i, float NewSample) { -1.36640781666419950000, 0.52352474703279628000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -137,8 +133,7 @@ static inline float high_cut_iir(int i, float NewSample) { #undef NCoef #define NCoef 1 -//fc=3.2kHz -static inline float sb_iir(int i, float NewSample) { +static __inline float sb_iir(int i, float NewSample) { /* float ACoef[NCoef+1] = { 0.03356837051492005100, 0.06713674102984010200, @@ -160,17 +155,17 @@ static inline float sb_iir(int i, float NewSample) { 1.00000000000000000000, -0.64940759319751051000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -184,8 +179,7 @@ static inline float sb_iir(int i, float NewSample) { #undef NCoef #define NCoef 2 -//fc=150Hz -static inline float adgold_highpass_iir(int i, float NewSample) { +static __inline float adgold_highpass_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.98657437157334349000, -1.97314874314668700000, @@ -198,17 +192,17 @@ static inline float adgold_highpass_iir(int i, float NewSample) { 0.97261396931534050000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -217,8 +211,7 @@ static inline float adgold_highpass_iir(int i, float NewSample) { return y[i][0]; } -//fc=150Hz -static inline float adgold_lowpass_iir(int i, float NewSample) { +static __inline float adgold_lowpass_iir(int i, float NewSample) { float ACoef[NCoef+1] = { 0.00009159473951071446, 0.00018318947902142891, @@ -231,17 +224,17 @@ static inline float adgold_lowpass_iir(int i, float NewSample) { 0.97261396931306277000 }; - static float y[2][NCoef+1]; //output samples - static float x[2][NCoef+1]; //input samples + static float y[2][NCoef+1]; /* output samples */ + static float x[2][NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[i][n] = x[i][n-1]; y[i][n] = y[i][n-1]; } - //Calculate the new output + /* Calculate the new output */ x[i][0] = NewSample; y[i][0] = ACoef[0] * x[i][0]; for(n=1; n<=NCoef; n++) @@ -250,8 +243,7 @@ static inline float adgold_lowpass_iir(int i, float NewSample) { return y[i][0]; } -//fc=56Hz -static inline float adgold_pseudo_stereo_iir(float NewSample) { +static __inline float adgold_pseudo_stereo_iir(float NewSample) { float ACoef[NCoef+1] = { 0.00001409030866231767, 0.00002818061732463533, @@ -264,17 +256,17 @@ static inline float adgold_pseudo_stereo_iir(float NewSample) { 0.98738361004063568000 }; - static float y[NCoef+1]; //output samples - static float x[NCoef+1]; //input samples + static float y[NCoef+1]; /* output samples */ + static float x[NCoef+1]; /* input samples */ int n; - //shift the old samples + /* shift the old samples */ for(n=NCoef; n>0; n--) { x[n] = x[n-1]; y[n] = y[n-1]; } - //Calculate the new output + /* Calculate the new output */ x[0] = NewSample; y[0] = ACoef[0] * x[0]; for(n=1; n<=NCoef; n++) diff --git a/src/gameport.c b/src/gameport.c index 7b135dc39..45e2cb8d8 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -19,16 +19,16 @@ int joystick_type; joystick_if_t joystick_none = { - .name = "No joystick", - .init = NULL, - .close = NULL, - .read = NULL, - .write = NULL, - .read_axis = NULL, - .a0_over = NULL, - .max_joysticks = 0, - .axis_count = 0, - .button_count = 0 + "No joystick", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0 }; static joystick_if_t *joystick_list[] = @@ -140,12 +140,7 @@ uint8_t gameport_read(uint16_t addr, void *p) uint8_t ret; timer_clock(); -// if (joysticks_present) - ret = gameport->state | gameport->joystick->read(gameport->joystick_dat);//0xf0; -// else -// ret = 0xff; - - // pclog("gameport_read: ret=%02x %08x:%08x isa_cycles=%i %i\n", ret, cs, cpu_state.pc, isa_cycles, gameport->axis[0].count); + ret = gameport->state | gameport->joystick->read(gameport->joystick_dat); cycles -= ISA_CYCLES(8); diff --git a/src/hdd.c b/src/hdd.c index eed719db5..f9491ec7a 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -2,7 +2,9 @@ #include "device.h" #include "hdd.h" +#include "hdd_esdi.h" #include "mfm_at.h" +#include "mfm_xebec.h" #include "xtide.h" char hdd_controller_name[16]; @@ -21,8 +23,13 @@ static struct { {"None", "none", &null_hdd_device, 0}, {"AT Fixed Disk Adapter", "mfm_at", &mfm_at_device, 1}, + {"DTC 5150X", "dtc5150x", &dtc_5150x_device, 1}, + {"Fixed Disk Adapter (Xebec)", "mfm_xebec", &mfm_xebec_device, 1}, + {"IBM ESDI Fixed Disk Adapter (MCA)", "esdi_mca", &hdd_esdi_device, 1}, {"XTIDE", "xtide", &xtide_device, 0}, {"XTIDE (AT)", "xtide_at", &xtide_at_device, 0}, + {"XTIDE (PS/2)", "xtide_ps2",&xtide_ps2_device,0}, + {"XTIDE (AT) (PS/2)", "xtide_at_ps2",&xtide_at_ps2_device,0}, {"", "", NULL, 0} }; diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c new file mode 100644 index 000000000..4dfc0b4b6 --- /dev/null +++ b/src/hdd_esdi.c @@ -0,0 +1,899 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include +#include "ibm.h" + +#include "device.h" +#include "dma.h" +#include "io.h" +#include "mca.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "timer.h" + +#include "hdd_esdi.h" + +#define ESDI_TIME (2000 * TIMER_USEC) + +#define CMD_ADAPTER 0 + +typedef struct esdi_drive_t +{ + int spt, hpc; + int tracks; + int sectors; + FILE *hdfile; +} esdi_drive_t; + +typedef struct esdi_t +{ + rom_t bios_rom; + + uint8_t basic_ctrl; + uint8_t status; + uint8_t irq_status; + + int irq_in_progress; + int cmd_req_in_progress; + + int cmd_pos; + uint16_t cmd_data[4]; + int cmd_dev; + + int status_pos, status_len; + uint16_t status_data[256]; + + int data_pos; + uint16_t data[256]; + + uint16_t sector_buffer[16][256]; + + int sector_pos; + int sector_count; + + int command; + int cmd_state; + + int in_reset; + int callback; + + uint32_t rba; + + struct + { + int req_in_progress; + } cmds[3]; + + esdi_drive_t drives[2]; + + uint8_t pos_regs[8]; +} esdi_t; + +#define STATUS_DMA_ENA (1 << 7) +#define STATUS_IRQ_PENDING (1 << 6) +#define STATUS_CMD_IN_PROGRESS (1 << 5) +#define STATUS_BUSY (1 << 4) +#define STATUS_STATUS_OUT_FULL (1 << 3) +#define STATUS_CMD_IR_FULL (1 << 2) +#define STATUS_TRANSFER_REQ (1 << 1) +#define STATUS_IRQ (1 << 0) + +#define CTRL_RESET (1 << 7) +#define CTRL_DMA_ENA (1 << 1) +#define CTRL_IRQ_ENA (1 << 0) + +#define IRQ_HOST_ADAPTER (7 << 5) +#define IRQ_DEVICE_0 (0 << 5) +#define IRQ_CMD_COMPLETE_SUCCESS 0x1 +#define IRQ_RESET_COMPLETE 0xa +#define IRQ_DATA_TRANSFER_READY 0xb +#define IRQ_CMD_COMPLETE_FAILURE 0xc + +#define ATTN_DEVICE_SEL (7 << 5) +#define ATTN_HOST_ADAPTER (7 << 5) +#define ATTN_DEVICE_0 (0 << 5) +#define ATTN_DEVICE_1 (1 << 5) +#define ATTN_REQ_MASK 0xf +#define ATTN_CMD_REQ 1 +#define ATTN_EOI 2 +#define ATTN_RESET 4 + +#define CMD_SIZE_4 (1 << 14) + +#define CMD_DEVICE_SEL (7 << 5) +#define CMD_MASK 0x1f +#define CMD_READ 0x01 +#define CMD_WRITE 0x02 +#define CMD_READ_VERIFY 0x03 +#define CMD_WRITE_VERIFY 0x04 +#define CMD_SEEK 0x05 +#define CMD_GET_DEV_CONFIG 0x09 +#define CMD_GET_POS_INFO 0x0a + +#define STATUS_LEN(x) ((x) << 8) +#define STATUS_DEVICE_HOST_ADAPTER (7 << 5) + +static __inline void esdi_set_irq(esdi_t *esdi) +{ + if (esdi->basic_ctrl & CTRL_IRQ_ENA) + picint(1 << 14); +} +static __inline void esdi_clear_irq() +{ + picintc(1 << 14); +} + +static uint8_t esdi_read(uint16_t port, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + uint8_t temp = 0xff; + + switch (port) + { + case 0x3512: /*Basic status register*/ + temp = esdi->status; + break; + case 0x3513: /*IRQ status*/ + esdi->status &= ~STATUS_IRQ; + temp = esdi->irq_status; + break; + + default: + fatal("esdi_read port=%04x\n", port); + } + + return temp; +} + +static void esdi_write(uint16_t port, uint8_t val, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + + switch (port) + { + case 0x3512: /*Basic control register*/ + if ((esdi->basic_ctrl & CTRL_RESET) && !(val & CTRL_RESET)) + { + esdi->in_reset = 1; + esdi->callback = ESDI_TIME * 50; + esdi->status = STATUS_BUSY; + } + esdi->basic_ctrl = val; + if (!(esdi->basic_ctrl & CTRL_IRQ_ENA)) + picintc(1 << 14); + break; + case 0x3513: /*Attention register*/ + switch (val & ATTN_DEVICE_SEL) + { + case ATTN_HOST_ADAPTER: + switch (val & ATTN_REQ_MASK) + { + case ATTN_CMD_REQ: + if (esdi->cmd_req_in_progress) + fatal("Try to start command on in_progress adapter\n"); + esdi->cmd_req_in_progress = 1; + esdi->cmd_dev = ATTN_HOST_ADAPTER; + esdi->status |= STATUS_BUSY; + esdi->cmd_pos = 0; + break; + + case ATTN_EOI: + esdi->irq_in_progress = 0; + esdi->status &= ~STATUS_IRQ; + esdi_clear_irq(); + break; + + case ATTN_RESET: + esdi->in_reset = 1; + esdi->callback = ESDI_TIME * 50; + esdi->status = STATUS_BUSY; + break; + + default: + fatal("Bad attention request %02x\n", val); + } + break; + + case ATTN_DEVICE_0: + switch (val & ATTN_REQ_MASK) + { + case ATTN_CMD_REQ: + if (esdi->cmd_req_in_progress) + fatal("Try to start command on in_progress device0\n"); + esdi->cmd_req_in_progress = 1; + esdi->cmd_dev = ATTN_DEVICE_0; + esdi->status |= STATUS_BUSY; + esdi->cmd_pos = 0; + break; + + case ATTN_EOI: + esdi->irq_in_progress = 0; + esdi->status &= ~STATUS_IRQ; + esdi_clear_irq(); + break; + + default: + fatal("Bad attention request %02x\n", val); + } + break; + + case ATTN_DEVICE_1: + switch (val & ATTN_REQ_MASK) + { + case ATTN_CMD_REQ: + if (esdi->cmd_req_in_progress) + fatal("Try to start command on in_progress device0\n"); + esdi->cmd_req_in_progress = 1; + esdi->cmd_dev = ATTN_DEVICE_1; + esdi->status |= STATUS_BUSY; + esdi->cmd_pos = 0; + break; + + case ATTN_EOI: + esdi->irq_in_progress = 0; + esdi->status &= ~STATUS_IRQ; + esdi_clear_irq(); + break; + + default: + fatal("Bad attention request %02x\n", val); + } + break; + + default: + fatal("Attention to unknown device %02x\n", val); + } + break; + + default: + fatal("esdi_write port=%04x val=%02x\n", port, val); + } +} + +static uint16_t esdi_readw(uint16_t port, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + uint16_t temp = 0xffff; + + switch (port) + { + case 0x3510: /*Status Interface Register*/ + if (esdi->status_pos >= esdi->status_len) + return 0; + temp = esdi->status_data[esdi->status_pos++]; + if (esdi->status_pos >= esdi->status_len) + { + esdi->status &= ~STATUS_STATUS_OUT_FULL; + esdi->status_pos = esdi->status_len = 0; + } + break; + + default: + fatal("esdi_readw port=%04x\n", port); + } + + return temp; +} + +static void esdi_writew(uint16_t port, uint16_t val, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + + switch (port) + { + case 0x3510: /*Command Interface Register*/ + if (esdi->cmd_pos >= 4) + fatal("CIR pos 4\n"); + esdi->cmd_data[esdi->cmd_pos++] = val; + if ( ((esdi->cmd_data[0] & CMD_SIZE_4) && esdi->cmd_pos == 4) || + (!(esdi->cmd_data[0] & CMD_SIZE_4) && esdi->cmd_pos == 2)) + { + + esdi->cmd_pos = 0; + esdi->cmd_req_in_progress = 0; + esdi->cmd_state = 0; + + if ((esdi->cmd_data[0] & CMD_DEVICE_SEL) != esdi->cmd_dev) + fatal("Command device mismatch with attn\n"); + esdi->command = esdi->cmd_data[0] & CMD_MASK; + esdi->callback = ESDI_TIME; + esdi->status = STATUS_BUSY; + esdi->data_pos = 0; + } + break; + + default: + fatal("esdi_writew port=%04x val=%04x\n", port, val); + } +} + +static void cmd_unsupported(esdi_t *esdi) +{ + esdi->status_len = 9; + esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; + esdi->status_data[1] = 0x0f03; /*Attention error, command not supported*/ + esdi->status_data[2] = 0x0002; /*Interface fault*/ + esdi->status_data[3] = 0; + esdi->status_data[4] = 0; + esdi->status_data[5] = 0; + esdi->status_data[6] = 0; + esdi->status_data[7] = 0; + esdi->status_data[8] = 0; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); +} + +static void device_not_present(esdi_t *esdi) +{ + esdi->status_len = 9; + esdi->status_data[0] = esdi->command | STATUS_LEN(9) | esdi->cmd_dev; + esdi->status_data[1] = 0x0c11; /*Command failed, internal hardware error*/ + esdi->status_data[2] = 0x000b; /*Selection error*/ + esdi->status_data[3] = 0; + esdi->status_data[4] = 0; + esdi->status_data[5] = 0; + esdi->status_data[6] = 0; + esdi->status_data[7] = 0; + esdi->status_data[8] = 0; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_FAILURE; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); +} + +#define ESDI_ADAPTER_ONLY() do \ + { \ + if (esdi->cmd_dev != ATTN_HOST_ADAPTER) \ + { \ + cmd_unsupported(esdi); \ + return; \ + } \ + } while (0) + +#define ESDI_DRIVE_ONLY() do \ + { \ + if (esdi->cmd_dev != ATTN_DEVICE_0 && esdi->cmd_dev != ATTN_DEVICE_1) \ + { \ + cmd_unsupported(esdi); \ + return; \ + } \ + if (esdi->cmd_dev == ATTN_DEVICE_0) \ + drive = &esdi->drives[0]; \ + else \ + drive = &esdi->drives[1]; \ + } while (0) + +static void esdi_callback(void *p) +{ + esdi_t *esdi = (esdi_t *)p; + esdi_drive_t *drive; + + esdi->callback = 0; + + if (esdi->in_reset) + { + esdi->in_reset = 0; + esdi->status = STATUS_IRQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_RESET_COMPLETE; + + return; + } + switch (esdi->command) + { + case CMD_READ: + ESDI_DRIVE_ONLY(); + + if (!drive->hdfile) + { + device_not_present(esdi); + return; + } + + switch (esdi->cmd_state) + { + case 0: + esdi->rba = (esdi->cmd_data[2] | (esdi->cmd_data[3] << 16)) & 0x0fffffff; + + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + esdi->callback = ESDI_TIME; + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) + { + esdi->callback = ESDI_TIME; + return; + } + while (esdi->sector_pos < esdi->sector_count) + { + if (!esdi->data_pos) + { + if (esdi->rba >= drive->sectors) + fatal("Read past end of drive\n"); + fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); + fread(esdi->data, 512, 1, drive->hdfile); + update_status_bar_icon(0x20, 1); + } + while (esdi->data_pos < 256) + { + int val = dma_channel_write(5, esdi->data[esdi->data_pos]); + + if (val == DMA_NODATA) + { + esdi->callback = ESDI_TIME; + return; + } + + esdi->data_pos++; + } + + esdi->data_pos = 0; + esdi->sector_pos++; + esdi->rba++; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + esdi->callback = ESDI_TIME; + break; + + case 2: + esdi->status = STATUS_IRQ; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case CMD_WRITE: + case CMD_WRITE_VERIFY: + ESDI_DRIVE_ONLY(); + + if (!drive->hdfile) + { + device_not_present(esdi); + return; + } + + switch (esdi->cmd_state) + { + case 0: + esdi->rba = (esdi->cmd_data[2] | (esdi->cmd_data[3] << 16)) & 0x0fffffff; + + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = esdi->cmd_dev | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + esdi->callback = ESDI_TIME; + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) + { + esdi->callback = ESDI_TIME; + return; + } + while (esdi->sector_pos < esdi->sector_count) + { + while (esdi->data_pos < 256) + { + int val = dma_channel_read(5); + + if (val == DMA_NODATA) + { + esdi->callback = ESDI_TIME; + return; + } + + esdi->data[esdi->data_pos++] = val & 0xffff; + } + + if (esdi->rba >= drive->sectors) + fatal("Write past end of drive\n"); + fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); + fwrite(esdi->data, 512, 1, drive->hdfile); + esdi->rba++; + esdi->sector_pos++; + update_status_bar_icon(0x20, 1); + + esdi->data_pos = 0; + } + update_status_bar_icon(0x20, 0); + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + esdi->callback = ESDI_TIME; + break; + + case 2: + esdi->status = STATUS_IRQ; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case CMD_READ_VERIFY: + ESDI_DRIVE_ONLY(); + + if (!drive->hdfile) + { + device_not_present(esdi); + return; + } + + esdi->status = STATUS_IRQ; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_SEEK: + ESDI_DRIVE_ONLY(); + + if (!drive->hdfile) + { + device_not_present(esdi); + return; + } + + esdi->status = STATUS_IRQ; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_GET_DEV_CONFIG: + ESDI_DRIVE_ONLY(); + + if (!drive->hdfile) + { + device_not_present(esdi); + return; + } + + if (esdi->status_pos) + fatal("Status send in progress\n"); + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 6; + esdi->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(6) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0x10; /*Zero defect*/ + esdi->status_data[2] = drive->sectors & 0xffff; + esdi->status_data[3] = drive->sectors >> 16; + esdi->status_data[4] = drive->tracks; + esdi->status_data[5] = drive->hpc | (drive->spt << 16); + +/* pclog("CMD_GET_DEV_CONFIG %i %04x %04x %04x %04x %04x %04x\n", drive->sectors, + esdi->status_data[0], esdi->status_data[1], + esdi->status_data[2], esdi->status_data[3], + esdi->status_data[4], esdi->status_data[5]);*/ + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = esdi->cmd_dev | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case CMD_GET_POS_INFO: + ESDI_ADAPTER_ONLY(); + if (esdi->status_pos) + fatal("Status send in progress\n"); + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 5; + esdi->status_data[0] = CMD_GET_POS_INFO | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0xffdd; /*MCA ID*/ + esdi->status_data[2] = esdi->pos_regs[3] | (esdi->pos_regs[2] << 8); + esdi->status_data[3] = 0xff; + esdi->status_data[4] = 0xff; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + case 0x11: + ESDI_ADAPTER_ONLY(); + switch (esdi->cmd_state) + { + case 0: + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + if (esdi->sector_count > 16) + fatal("Read sector buffer count %04x\n", esdi->cmd_data[1]); + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + esdi->callback = ESDI_TIME; + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) + { + esdi->callback = ESDI_TIME; + return; + } + while (esdi->sector_pos < esdi->sector_count) + { + if (!esdi->data_pos) + memcpy(esdi->data, esdi->sector_buffer[esdi->sector_pos++], 512); + while (esdi->data_pos < 256) + { + int val = dma_channel_write(5, esdi->data[esdi->data_pos]); + + if (val == DMA_NODATA) + { + esdi->callback = ESDI_TIME; + return; + } + + esdi->data_pos++; + } + + esdi->data_pos = 0; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + esdi->callback = ESDI_TIME; + break; + + case 2: + esdi->status = STATUS_IRQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case 0x10: + ESDI_ADAPTER_ONLY(); + switch (esdi->cmd_state) + { + case 0: + esdi->sector_pos = 0; + esdi->sector_count = esdi->cmd_data[1]; + if (esdi->sector_count > 16) + fatal("Write sector buffer count %04x\n", esdi->cmd_data[1]); + + esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_DATA_TRANSFER_READY; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + + esdi->cmd_state = 1; + esdi->callback = ESDI_TIME; + esdi->data_pos = 0; + break; + + case 1: + if (!(esdi->basic_ctrl & CTRL_DMA_ENA)) + { + esdi->callback = ESDI_TIME; + return; + } + while (esdi->sector_pos < esdi->sector_count) + { + while (esdi->data_pos < 256) + { + int val = dma_channel_read(5); + + if (val == DMA_NODATA) + { + esdi->callback = ESDI_TIME; + return; + } + + esdi->data[esdi->data_pos++] = val & 0xffff;; + } + + memcpy(esdi->sector_buffer[esdi->sector_pos++], esdi->data, 512); + esdi->data_pos = 0; + } + + esdi->status = STATUS_CMD_IN_PROGRESS; + esdi->cmd_state = 2; + esdi->callback = ESDI_TIME; + break; + + case 2: + esdi->status = STATUS_IRQ; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + } + break; + + case 0x12: + ESDI_ADAPTER_ONLY(); + if (esdi->status_pos) + fatal("Status send in progress\n"); + if ((esdi->status & STATUS_IRQ) || esdi->irq_in_progress) + fatal("IRQ in progress %02x %i\n", esdi->status, esdi->irq_in_progress); + + esdi->status_len = 2; + esdi->status_data[0] = 0x12 | STATUS_LEN(5) | STATUS_DEVICE_HOST_ADAPTER; + esdi->status_data[1] = 0; + + esdi->status = STATUS_IRQ | STATUS_STATUS_OUT_FULL; + esdi->irq_status = IRQ_HOST_ADAPTER | IRQ_CMD_COMPLETE_SUCCESS; + esdi->irq_in_progress = 1; + esdi_set_irq(esdi); + break; + + default: + fatal("Bad command %02x %i\n", esdi->command, esdi->cmd_dev); + + } +} + +static uint8_t esdi_mca_read(int port, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + + return esdi->pos_regs[port & 7]; +} + +static void esdi_mca_write(int port, uint8_t val, void *p) +{ + esdi_t *esdi = (esdi_t *)p; + + if (port < 0x102) + return; + + esdi->pos_regs[port & 7] = val; + + io_removehandler(0x3510, 0x0008, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); + mem_mapping_disable(&esdi->bios_rom.mapping); + if (esdi->pos_regs[2] & 1) + { + io_sethandler(0x3510, 0x0008, esdi_read, esdi_readw, NULL, esdi_write, esdi_writew, NULL, esdi); + if (!(esdi->pos_regs[3] & 8)) + { + mem_mapping_enable(&esdi->bios_rom.mapping); + mem_mapping_set_addr(&esdi->bios_rom.mapping, ((esdi->pos_regs[3] & 7) * 0x4000) + 0xc0000, 0x4000); + } + } +} + +static void loadhd(esdi_t *esdi, int d, const char *fn) +{ + esdi_drive_t *drive = &esdi->drives[d]; + + if (drive->hdfile == NULL) + { + /* Try to open existing hard disk image */ + drive->hdfile = fopen64(fn, "rb+"); + if (drive->hdfile == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + drive->hdfile = fopen64(fn, "wb+"); + if (drive->hdfile == NULL) + { + pclog("Cannot create file '%s': %s", + fn, strerror(errno)); + return; + } + } + else + { + /* Failed for another reason */ + pclog("Cannot open file '%s': %s", + fn, strerror(errno)); + return; + } + } + } + + drive->spt = hdc[d].spt; + drive->hpc = hdc[d].hpc; + drive->tracks = hdc[d].tracks; + drive->sectors = hdc[d].spt * hdc[d].hpc * hdc[d].tracks; +} + +static void *esdi_init() +{ + int i = 0; + + esdi_t *esdi = malloc(sizeof(esdi_t)); + memset(esdi, 0, sizeof(esdi_t)); + + rom_init_interleaved(&esdi->bios_rom, "roms/90x8970.bin", "roms/90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + mem_mapping_disable(&esdi->bios_rom.mapping); + + for (i = 0; i < HDC_NUM; i++) + { + loadhd(esdi, hdc[i].mfm_channel, hdd_fn[i]); + } + + timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); + + mca_add(esdi_mca_read, esdi_mca_write, esdi); + + esdi->pos_regs[0] = 0xff; + esdi->pos_regs[1] = 0xdd; + + esdi->in_reset = 1; + esdi->callback = ESDI_TIME * 50; + esdi->status = STATUS_BUSY; + + return esdi; +} + +static void esdi_close(void *p) +{ + esdi_t *esdi = (esdi_t *)p; + int d; + + for (d = 0; d < 2; d++) + { + esdi_drive_t *drive = &esdi->drives[d]; + + if (drive->hdfile != NULL) + fclose(drive->hdfile); + } + + free(esdi); +} + +static int esdi_available() +{ + return rom_present("roms/90x8969.bin") && rom_present("roms/90x8970.bin"); +} + +device_t hdd_esdi_device = +{ + "IBM ESDI Fixed Disk Adapter (MCA)", + DEVICE_MCA, + esdi_init, + esdi_close, + esdi_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/hdd_esdi.h b/src/hdd_esdi.h new file mode 100644 index 000000000..4fea361bd --- /dev/null +++ b/src/hdd_esdi.h @@ -0,0 +1 @@ +extern device_t hdd_esdi_device; diff --git a/src/headland.c b/src/headland.c index cba96b7ef..b100b85c8 100644 --- a/src/headland.c +++ b/src/headland.c @@ -17,7 +17,6 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) { if (headland_index == 0xc1 && !is486) val = 0; headland_regs[headland_index] = val; - // pclog("Headland write %02X %02X\n",headland_index,val); if (headland_index == 0x82) { shadowbios = val & 0x10; diff --git a/src/i430hx.c b/src/i430hx.c index 8d20e98e4..e13da7606 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -50,7 +50,6 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) i430hx_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } - // pclog("i430hx_write : PAM0 write %02X\n", val); break; case 0x5a: /*PAM1*/ if ((card_i430hx[0x5a] ^ val) & 0x0f) @@ -81,14 +80,12 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) i430hx_map(0xe0000, 0x04000, val & 0xf); if ((card_i430hx[0x5e] ^ val) & 0xf0) i430hx_map(0xe4000, 0x04000, val >> 4); - // pclog("i430hx_write : PAM5 write %02X\n", val); break; case 0x5f: /*PAM6*/ if ((card_i430hx[0x5f] ^ val) & 0x0f) i430hx_map(0xe8000, 0x04000, val & 0xf); if ((card_i430hx[0x5f] ^ val) & 0xf0) i430hx_map(0xec000, 0x04000, val >> 4); - // pclog("i430hx_write : PAM6 write %02X\n", val); break; } diff --git a/src/ibm.h b/src/ibm.h index f2fd339cb..ffbc18593 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -24,13 +24,6 @@ extern int mmu_perm; #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE)?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC)?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -//#define writememb(a,v) if (writelookup2[(a)>>12]==0xFFFFFFFF) writemembl(a,v); else ram[writelookup2[(a)>>12]+((a)&0xFFF)]=v -//#define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememwl(s,a,v); else *((uint16_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v -//#define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==0xFFFFFFFF || (s)==0xFFFFFFFF) writememll(s,a,v); else *((uint32_t *)(&ram[writelookup2[((s)+(a))>>12]+(((s)+(a))&0xFFF)]))=v -//#define readmemb(a) ((isram[((a)>>16)&255] && !(cr0>>31))?ram[a&0xFFFFFF]:readmembl(a)) -//#define writememb(a,v) if (isram[((a)>>16)&255] && !(cr0>>31)) ram[a&0xFFFFFF]=v; else writemembl(a,v) - -//void writememb(uint32_t addr, uint8_t val); uint8_t readmembl(uint32_t addr); void writemembl(uint32_t addr, uint8_t val); uint8_t readmemb386l(uint32_t seg, uint32_t addr); @@ -138,7 +131,6 @@ struct uint32_t pc; uint32_t oldpc; uint32_t op32; - uint32_t last_ea; int TOP; @@ -167,15 +159,20 @@ struct MMX_REG MM[8]; uint16_t old_npxc, new_npxc; + uint32_t last_ea; } cpu_state; #define cycles cpu_state._cycles -#define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; +#ifdef __MSC__ +# define COMPILE_TIME_ASSERT(expr) /*nada*/ +#else +# define COMPILE_TIME_ASSERT(expr) typedef char COMP_TIME_ASSERT[(expr) ? 1 : 0]; +#endif -COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128); +COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) -#define cpu_state_offset(MEMBER) ((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128) +#define cpu_state_offset(MEMBER) ((uint8_t)((uintptr_t)&cpu_state.MEMBER - (uintptr_t)&cpu_state - 128)) /*x86reg regs[8];*/ @@ -242,9 +239,7 @@ uint32_t dr[8]; #define IOPL ((flags>>12)&3) #define IOPLp ((!(msw&1)) || (CPL<=IOPL)) -//#define IOPLp 1 -//#define IOPLV86 ((!(msw&1)) || (CPL<=IOPL)) extern int cycles_lost; extern int israpidcad; extern int is486; @@ -260,6 +255,12 @@ extern int CPUID; extern int cpl_override; /*Timer*/ +typedef struct PIT_nr +{ + int nr; + struct PIT *pit; +} PIT_nr; + typedef struct PIT { uint32_t l[3]; @@ -284,9 +285,13 @@ typedef struct PIT uint8_t read_status[3]; int do_read_status[3]; + + PIT_nr pit_nr[3]; + + void (*set_out_funcs[3])(int new_out, int old_out); } PIT; -PIT pit; +PIT pit, pit2; void setpitclock(float clock); float pit_timer0_freq(); @@ -300,7 +305,7 @@ float pit_timer0_freq(); /*DMA*/ typedef struct DMA { - uint16_t ab[4],ac[4]; + uint32_t ab[4],ac[4]; uint16_t cb[4]; int cc[4]; int wp; @@ -309,6 +314,13 @@ typedef struct DMA uint8_t stat; uint8_t command; uint8_t request; + + int xfr_command, xfr_channel; + int byte_ptr; + + int is_ps2; + uint8_t arb_level[4]; + uint8_t ps2_mode[4]; } DMA; DMA dma,dma16; @@ -341,8 +353,8 @@ int disctime; char discfns[4][256]; int driveempty[4]; -#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR) && (romset=ROM_IBMAT)) -#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && gfxcard!=GFX_HERCULESPLUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) +#define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset=ROM_IBMAT)) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && gfxcard!=GFX_HERCULESPLUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -395,13 +407,16 @@ enum ROM_PORTABLE, ROM_PORTABLEII, ROM_PORTABLEIII, - ROM_PORTABLEIII386, //The original Compaq Portable III shipped with an Intel 80286 CPU, but later switched to a 386DX. + ROM_PORTABLEIII386, /* The original Compaq Portable III shipped with an Intel 80286 CPU, but later switched to a 386DX. */ ROM_IBMPS1_2121, ROM_AMI386DX_OPTI495, ROM_MR386DX_OPTI495, ROM_IBMPS2_M30_286, + ROM_IBMPS2_M50, + ROM_IBMPS2_M55SX, + ROM_IBMPS2_M80, ROM_DTK486, /*DTK PKM-0038S E-2 / SiS 471 / Award BIOS / SiS 85C471*/ ROM_VLI486SV2G, /*ASUS VL/I-486SV2G / SiS 471 / Award BIOS / SiS 85C471*/ @@ -410,13 +425,15 @@ enum ROM_PLATO, /*Intel Premiere/PCI II / 430NX / AMI BIOS / SMC FDC37C665*/ ROM_MB500N, /*PC Partner MB500N / 430FX / Award BIOS / SMC FDC37C665*/ ROM_P54TP4XE, /*ASUS P/I-P55TP4XE / 430FX / Award BIOS / SMC FDC37C665*/ + ROM_AP53, /*AOpen AP53 / 430HX / AMI BIOS / SMC FDC37C665/669*/ + ROM_P55T2S, /*ASUS P/I-P55T2S / 430HX / AMI BIOS / National Semiconductors PC87306*/ ROM_ACERM3A, /*Acer M3A / 430HX / Acer BIOS / SMC FDC37C932FR*/ ROM_ACERV35N, /*Acer V35N / 430HX / Acer BIOS / SMC FDC37C932FR*/ ROM_P55T2P4, /*ASUS P/I-P55T2P4 / 430HX / Award BIOS / Winbond W8387F*/ ROM_P55TVP4, /*ASUS P/I-P55TVP4 / 430HX / Award BIOS / Winbond W8387F*/ ROM_P55VA, /*Epox P55-VA / 430VX / Award BIOS / SMC FDC37C932FR*/ - ROM_440FX, /*Unknown / 440FX / Award BIOS / SMC FDC37C665*/ + ROM_440FX, /*Tyan Titan-Pro AT / 440FX / Award BIOS / SMC FDC37C665*/ ROM_MARL, /*Intel Advanced/ML / 430HX / AMI BIOS / National Semiconductors PC87306*/ ROM_THOR, /*Intel Advanced/ATX / 430FX / AMI BIOS / National Semiconductors PC87306*/ @@ -433,6 +450,8 @@ enum ROM_CMDPC60, + ROM_S1668, /*Tyan Titan-Pro ATX / 440FX / AMI BIOS / SMC FDC37C669*/ + ROM_MAX }; @@ -466,6 +485,9 @@ enum GFX_INCOLOR, /* Hercules InColor */ GFX_COLORPLUS, /* Plantronics ColorPlus */ GFX_WY700, /* Wyse 700 */ + GFX_GENIUS, /* MDSI Genius */ + GFX_MACH64VT2, /*ATI Mach64 VT2*/ + GFX_COMPAQ_EGA, /*Compaq EGA*/ GFX_SUPER_EGA, /*Using Chips & Technologies SuperEGA BIOS*/ GFX_COMPAQ_VGA, /*Compaq/Paradise VGA*/ @@ -485,6 +507,8 @@ enum GFX_TRIGEM_UNK, GFX_OTI037, /*Oak OTI-037*/ + GFX_VIRGEVX, /*S3 Virge/VX*/ + GFX_MAX }; @@ -532,7 +556,12 @@ char pcempath[512]; /*Hard disc*/ -typedef struct __attribute__((__packed__)) +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else +typedef struct __attribute((__packed__)) +#endif { FILE *f; uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ @@ -540,15 +569,78 @@ typedef struct __attribute__((__packed__)) int is_hdi; uint32_t base; uint64_t at_spt,at_hpc; /*[Translation] Sectors per track, heads per cylinder*/ + int bus; /* 0 = none, 1 = MFM/RLL, 2 = IDE, 3 = SCSI */ + uint8_t mfm_channel; + uint8_t ide_channel; + uint8_t scsi_id; + uint8_t scsi_lun; } hard_disk_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct +#else +typedef struct __attribute((__packed__)) +#endif +{ + /* Stuff for SCSI hard disks. */ + uint8_t cdb[16]; + uint8_t current_cdb[16]; + uint8_t max_cdb_len; + int requested_blocks; + int max_blocks_at_once; + uint16_t request_length; + int block_total; + int all_blocks_total; + uint32_t packet_len; + int packet_status; + uint8_t status; + uint8_t phase; + uint32_t pos; + int callback; + int total_read; + int unit_attention; + uint8_t sense[256]; + uint8_t previous_command; + uint8_t error; + uint16_t buffer[390144]; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t last_sector; + uint32_t seek_pos; + int data_pos; + int old_len; + int cdb_len_setting; + int cdb_len; + int request_pos; + uint64_t base; + uint8_t hd_cdb[16]; +} scsi_hard_disk_t; +#ifdef __MSC__ +# pragma pack(pop) +#endif + +#define HDC_NUM 16 #define IDE_NUM 8 +#define MFM_NUM 2 +#define SCSI_NUM 16 /* Theoretically the controller can have at least 64 devices, or even 128 in case of a wide bus, but + let's not exaggerate with them - 16 ought to be enough for everyone. */ -hard_disk_t hdc[IDE_NUM]; +hard_disk_t hdc[HDC_NUM]; +scsi_hard_disk_t shdc[HDC_NUM]; + +FILE *shdf[HDC_NUM]; uint64_t hdt[128][3]; +uint64_t hdt_mfm[128][3]; + +extern char hdd_fn[HDC_NUM][512]; int image_is_hdi(const char *s); +int image_is_hdx(const char *s, int check_signature); /*Keyboard*/ int keybsenddelay; @@ -573,6 +665,7 @@ extern int ui_writeprot[4]; void pclog(const char *format, ...); extern int nmi; +extern int nmi_auto_clear; extern float isa_timing, bus_timing; @@ -590,6 +683,7 @@ void onesec(); void resetpc_cad(); +extern int dump_on_exit; extern int start_in_fullscreen; extern int window_w, window_h, window_x, window_y, window_remember; @@ -647,3 +741,51 @@ extern int invert_display; uint32_t svga_color_transform(uint32_t color); extern int scale; + +/* Function prototypes. */ +void BuslogicSoftReset(); +int checkio(int port); +void closepc(); +void codegen_block_end(); +void codegen_reset(); +void cpu_set_edx(); +int divl(uint32_t val); +void dumpregs(); +void exec386(int cycs); +void exec386_dynarec(int cycs); +void execx86(int cycs); +void flushmmucache(); +void flushmmucache_cr3(); +int idivl(int32_t val); +void initpc(int argc, char *argv[]); +void loadcscall(uint16_t seg); +void loadcsjmp(uint16_t seg, uint32_t oxpc); +void mmu_invalidate(uint32_t addr); +void pclog(const char *format, ...); +void pmodeint(int num, int soft); +void pmoderetf(int is32, uint16_t off); +void pmodeiret(int is32); +void port_92_clear_reset(); +uint8_t readdacfifo(); +void refreshread(); +int rep386(int fv); +void resetmcr(); +void resetpchard(); +void resetreadlookup(); +void resetx86(); +void runpc(); +void saveconfig(); +void softresetx86(); +void speedchanged(); +void trc_reset(uint8_t val); +void update_status_bar_icon(int tag, int active); +void x86_int_sw(int num); +void x86gpf(char *s, uint16_t error); +void x86np(char *s, uint16_t error); +void x86ss(char *s, uint16_t error); +void x86ts(char *s, uint16_t error); +void x87_dumpregs(); +void x87_reset(); + +extern int serial_enabled[2]; +extern int lpt_enabled, bugger_enabled; diff --git a/src/ide.c b/src/ide.c index 2750802b8..525534189 100644 --- a/src/ide.c +++ b/src/ide.c @@ -46,7 +46,7 @@ #define WIN_WRITE 0x30 /* 28-Bit Write */ #define WIN_WRITE_NORETRY 0x31 /* 28-Bit Write */ #define WIN_VERIFY 0x40 /* 28-Bit Verify */ -#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */ +#define WIN_VERIFY_ONCE 0x41 /* Added by OBattler - deprected older ATA command, according to the specification I found, it is identical to 0x40 */ #define WIN_FORMAT 0x50 #define WIN_SEEK 0x70 #define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ @@ -62,21 +62,11 @@ #define WIN_IDLENOW1 0xE1 #define WIN_SETIDLE1 0xE3 #define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 +#define WIN_SLEEP1 0xE6 #define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ #define WIN_SET_FEATURES 0xEF #define WIN_READ_NATIVE_MAX 0xF8 -/** Evaluate to non-zero if the currently selected drive is an ATAPI device */ -// #define IDE_DRIVE_IS_CDROM(ide) (ide->type == IDE_CDROM) - -#define ATAPI_STATUS_IDLE 0 -#define ATAPI_STATUS_COMMAND 1 -#define ATAPI_STATUS_COMPLETE 2 -#define ATAPI_STATUS_DATA_IN 3 -#define ATAPI_STATUS_DATA_OUT 4 -#define ATAPI_STATUS_ERROR 0x80 - enum { IDE_NONE = 0, @@ -84,26 +74,6 @@ enum IDE_CDROM }; -static struct -{ - uint8_t opcode; - uint8_t polled; - uint8_t reserved2[2]; - uint8_t class; - uint8_t reserved3[2]; - uint16_t len; - uint8_t control; -} *gesn_cdb; - -static struct -{ - uint16_t len; - uint8_t notification_class; - uint8_t supported_events; -} *gesn_event_header; - -static unsigned int used_len; - uint64_t hdt[128][3] = { { 306, 4, 17 }, { 615, 2, 17 }, { 306, 4, 26 }, { 1024, 2, 17 }, { 697, 3, 17 }, { 306, 8, 17 }, { 614, 4, 17 }, { 615, 4, 17 }, /* 000-007 */ { 670, 4, 17 }, { 697, 4, 17 }, { 987, 3, 17 }, { 820, 4, 17 }, { 670, 5, 17 }, { 697, 5, 17 }, { 733, 5, 17 }, { 615, 6, 17 }, /* 008-015 */ { 462, 8, 17 }, { 306, 8, 26 }, { 615, 4, 26 }, { 1024, 4, 17 }, { 855, 5, 17 }, { 925, 5, 17 }, { 932, 5, 17 }, { 1024, 2, 40 }, /* 016-023 */ @@ -125,15 +95,12 @@ IDE ide_drives[IDE_NUM]; IDE *ext_ide; -char ide_fn[IDE_NUM][512]; +char hdd_fn[HDC_NUM][512]; int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); void (*ide_bus_master_set_irq)(int channel); -static void atapi_callback(IDE *ide); -static void atapicommand(int ide_board); - int idecallback[4] = {0, 0, 0, 0}; int cur_ide[4]; @@ -234,7 +201,7 @@ int image_is_hdx(const char *s, int check_signature) } fread(&signature, 1, 8, f); fclose(f); - if (signature == 0xD778A82044445459) + if (signature == 0xD778A82044445459ll) { return 1; } @@ -261,7 +228,6 @@ void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { - // ide_log("Not raising IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); return; } @@ -270,7 +236,6 @@ void ide_irq_raise(IDE *ide) if (!(ide->fdisk&2)) { picint(1 << ide_irq[ide->board]); - // if (ide->board && !ide->irqstat) ide_log("IDE_IRQ_RAISE\n"); if (ide->board < 2) { @@ -283,14 +248,12 @@ void ide_irq_raise(IDE *ide) ide->irqstat=1; ide->service=1; - // ide_log("raising interrupt %i\n", 14 + ide->board); } void ide_irq_lower(IDE *ide) { if ((ide->board > 3) || !(ide->irqstat)) { - // ide_log("Not lowering IRQ %i (board %i)\n", ide_irq[ide->board], ide->board); return; } @@ -298,7 +261,6 @@ void ide_irq_lower(IDE *ide) picintc(1 << ide_irq[ide->board]); ide->irqstat=0; - // ide->service=0; } void ide_irq_update(IDE *ide) @@ -314,8 +276,6 @@ void ide_irq_update(IDE *ide) mask = ide_irq[ide->board]; mask &= 7; - // ide_log("Updating IRQ %i (%i) (board %i)\n", ide_irq[ide->board], mask, ide->board); - pending = (pic2.pend | pic2.ins); pending &= (1 << mask); @@ -387,22 +347,19 @@ void ide_padstr8(uint8_t *buf, int buf_size, const char *src) */ static void ide_identify(IDE *ide) { - int c, h, s; - uint8_t device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; + uint32_t c, h, s; + char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; uint64_t full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); device_identify[6] = ide->channel + 0x30; ide_log("IDE Identify: %s\n", device_identify); memset(ide->buffer, 0, 512); - - //ide->buffer[1] = 101; /* Cylinders */ c = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ h = hdc[cur_ide[ide->board]].hpc; /* Heads */ s = hdc[cur_ide[ide->board]].spt; /* Sectors */ - // ide->buffer[0] = 0x40; /* Fixed disk */ if (hdc[cur_ide[ide->board]].tracks <= 16383) { ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ @@ -420,7 +377,7 @@ static void ide_identify(IDE *ide) ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ ide->buffer[48] = 1; /*Dword transfers supported*/ - if (ide->board < 2) + if (PCI && (ide->board < 2)) { ide->buffer[49] = (1 << 8); /* LBA and DMA supported */ } @@ -435,7 +392,7 @@ static void ide_identify(IDE *ide) ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[52] = 2 << 8; /*DMA timing mode*/ - ide->buffer[53] = ide->specify_success ? 1 : 0; + ide->buffer[53] = 1; ide->buffer[55] = ide->hpc; ide->buffer[56] = ide->spt; if (((full_size / ide->hpc) / ide->spt) <= 16383) @@ -448,24 +405,18 @@ static void ide_identify(IDE *ide) } full_size = ((uint64_t) ide->hpc) * ((uint64_t) ide->spt) * ((uint64_t) ide->buffer[54]); ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = full_size >> 16; + ide->buffer[58] = (full_size >> 16) & 0x0FFF; ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if (ide->buffer[49] & (1 << 9)) { ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[61] = ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16) & 0x0FFF; } - ide->buffer[80] = 0x1e; /*ATA-1 to ATA-4 supported*/ - // ide->buffer[63] = 7; /*Multiword DMA*/ - if (ide->board < 2) + if (PCI && (ide->board < 2)) { - ide->buffer[53] = 2; - ide->buffer[63] = ide->dma_identify_data[0]; - ide->buffer[65] = 150; - ide->buffer[66] = 150; - // ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ - // ide->buffer[88] = ide->dma_identify_data[2]; + ide->buffer[63] = 7; } + ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ } /** @@ -473,10 +424,12 @@ static void ide_identify(IDE *ide) */ static void ide_atapi_identify(IDE *ide) { - memset(ide->buffer, 0, 512); - uint8_t device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; - uint8_t cdrom_id = atapi_cdrom_drives[ide->channel]; + char device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; + uint8_t cdrom_id; + memset(ide->buffer, 0, 512); + cdrom_id = atapi_cdrom_drives[ide->channel]; + device_identify[6] = cdrom_id + 0x30; ide_log("ATAPI Identify: %s\n", device_identify); @@ -486,20 +439,14 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[73] = 6; ide->buffer[74] = 9; ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ - if ((ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) + if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) { ide->buffer[49] |= 0x100; /* DMA supported */ - ide->buffer[52] = 2 << 8; /*DMA timing mode*/ - ide->buffer[53] = 2; - ide->buffer[63] = ide->dma_identify_data[0]; - ide->buffer[65] = 150; - ide->buffer[66] = 150; - // ide->buffer[88] = ide->dma_identify_data[2]; + ide->buffer[63] = 7; } } @@ -514,8 +461,8 @@ static off64_t ide_get_sector(IDE *ide) } else { - int heads = ide->hpc; - int sectors = ide->spt; + uint32_t heads = ide->hpc; + uint32_t sectors = ide->spt; return ((((off64_t) ide->cylinder * heads) + ide->head) * sectors) + (ide->sector - 1) + ide->skip512; @@ -551,7 +498,7 @@ static void loadhd(IDE *ide, int d, const char *fn) { uint32_t sector_size = 512; uint32_t zero = 0; - uint64_t signature = 0xD778A82044445459; + uint64_t signature = 0xD778A82044445459ll; uint64_t full_size = 0; int c; ide->base = 0; @@ -707,6 +654,7 @@ int ide_cdrom_is_pio_only(IDE *ide) return 1; } +#if 0 int ide_set_features(IDE *ide) { uint8_t cdrom_id = cur_ide[ide->board]; @@ -777,6 +725,7 @@ int ide_set_features(IDE *ide) } return 1; } +#endif void ide_set_sector(IDE *ide, int64_t sector_num) { @@ -797,9 +746,12 @@ void ide_set_sector(IDE *ide, int64_t sector_num) } } +void ide_ter_disable_cond(); +void ide_qua_disable_cond(); + void resetide(void) { - int d; + int c, d; build_atapi_cdrom_map(); @@ -825,23 +777,33 @@ void resetide(void) idecallback[0]=idecallback[1]=0; idecallback[2]=idecallback[3]=0; + c = 0; + for (d = 0; d < HDC_NUM; d++) + { + if ((hdc[d].bus == 2) && (hdc[d].ide_channel < IDE_NUM)) + { + pclog("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); + loadhd(&ide_drives[hdc[d].ide_channel], d, hdd_fn[d]); + c++; + if (c >= IDE_NUM) break; + } + } + for (d = 0; d < IDE_NUM; d++) { - if (ide_drive_is_cdrom(&ide_drives[d])) + if (ide_drive_is_cdrom(&ide_drives[d]) && (ide_drives[d].type != IDE_HDD)) { ide_drives[d].type = IDE_CDROM; } - else - { - loadhd(&ide_drives[d], d, ide_fn[d]); - } ide_set_signature(&ide_drives[d]); +#if 0 if (ide_drives[d].type != IDE_NONE) { ide_drives[d].dma_identify_data[0] = 7; } +#endif ide_drives[d].error = 1; } @@ -859,7 +821,6 @@ int idetimes = 0; void ide_write_data(int ide_board, uint32_t val, int length) { - int ret = 0; IDE *ide = &ide_drives[cur_ide[ide_board]]; uint8_t *idebufferb = (uint8_t *) ide->buffer; @@ -873,7 +834,6 @@ void ide_write_data(int ide_board, uint32_t val, int length) } #endif - // ide_log("Write IDEw %04X\n",val); if (ide->command == WIN_PACKETCMD) { ide->pos = 0; @@ -931,14 +891,11 @@ void ide_write_data(int ide_board, uint32_t val, int length) void writeidew(int ide_board, uint16_t val) { - // ide_log("WriteIDEw %04X\n", val); ide_write_data(ide_board, val, 2); } void writeidel(int ide_board, uint32_t val) { - // ide_log("WriteIDEl %08X\n", val); - // ide_write_data(ide_board, val, 4); writeidew(ide_board, val); writeidew(ide_board, val >> 16); } @@ -957,7 +914,6 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) switch (addr) { case 0x1F0: /* Data */ - // writeidew(ide_board, val | (val << 8)); writeidew(ide_board, val | (val << 8)); return; @@ -1094,39 +1050,9 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) return; } -#if 0 - if (ide_drive_is_cdrom(ide)) - { -#if 0 - ide_log("Write CD-ROM ATA command: %02X\n", val); -#endif - switch(val) - { - case WIN_SRST: - case WIN_CHECKPOWERMODE1: - case WIN_DRIVE_DIAGNOSTICS: - case WIN_IDLENOW1: - case WIN_PACKETCMD: - case WIN_PIDENTIFY: - case WIN_IDENTIFY: - case WIN_SET_FEATURES: - case WIN_SLEEP1: - case WIN_STANDBYNOW1: - break; - default: - ide_irq_lower(ide); - ide->command=val; - val = 0xFF; - goto skip_to_command_processing; - break; - } - } -#endif ide_irq_lower(ide); ide->command=val; -skip_to_command_processing: - // ide_log("New IDE command - %02X %i %i\n",ide->command,cur_ide[ide_board],ide_board); ide->error=0; if (ide_drive_is_cdrom(ide)) { @@ -1260,8 +1186,6 @@ skip_to_command_processing: case WIN_FORMAT: if (ide_drive_is_cdrom(ide)) { - // cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT; - // cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; goto ide_bad_command; } else @@ -1315,8 +1239,7 @@ skip_to_command_processing: timer_update_outstanding(); return; - case WIN_IDENTIFY: /* Identify Device */ - case WIN_SET_FEATURES: + case WIN_IDENTIFY: /* Identify Device */ case WIN_READ_NATIVE_MAX: if (ide_drive_is_cdrom(ide)) { @@ -1346,10 +1269,9 @@ skip_to_command_processing: } else { - ide->packetstatus = ATAPI_STATUS_IDLE; ide->atastat = BUSY_STAT; timer_process(); - idecallback[ide_board]=1;//30*IDE_TIME; + idecallback[ide_board]=1; timer_update_outstanding(); ide->pos=0; } @@ -1397,7 +1319,6 @@ ide_bad_command: cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; } ide->atastat = ide_other->atastat = BUSY_STAT; - // ide_log("IDE Reset %i\n", ide_board); } if (val & 4) { @@ -1411,7 +1332,6 @@ ide_bad_command: ide_irq_update(ide); return; } - // fatal("Bad IDE write %04X %02X\n", addr, val); } uint32_t ide_read_data(int ide_board, int length) @@ -1463,11 +1383,9 @@ uint32_t ide_read_data(int ide_board, int length) ide->atastat = READY_STAT | DSC_STAT; if (ide_drive_is_cdrom(ide)) { - // cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].pos = 0; cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status = READY_STAT | DSC_STAT; cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].packet_status = CDROM_PHASE_IDLE; } - ide->packetstatus = ATAPI_STATUS_IDLE; if (ide->command == WIN_READ || ide->command == WIN_READ_NORETRY || ide->command == WIN_READ_MULTIPLE) { ide->secount = (ide->secount - 1) & 0xff; @@ -1486,10 +1404,13 @@ uint32_t ide_read_data(int ide_board, int length) } timer_update_outstanding(); } + else + { + update_status_bar_icon(0x21, 0); + } } } - // ide_log("Read IDEw %04X\n",temp); return temp; } @@ -1499,17 +1420,13 @@ uint8_t readide(int ide_board, uint16_t addr) uint8_t temp; uint16_t tempw; - uint8_t temp2; - - addr|=0x90; - addr&=0xFFF7; + addr |= 0x90; + addr &= 0xFFF7; switch (addr) { case 0x1F0: /* Data */ - // temp = ide_read_data(ide_board, 1); tempw = readidew(ide_board); - // ide_log("Read IDEW %04X\n", tempw); temp = tempw & 0xff; break; @@ -1613,7 +1530,6 @@ uint8_t readide(int ide_board, uint16_t addr) if (ide_drive_is_cdrom(ide)) { temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - // ide_log("Read CD-ROM status: %02X\n", temp); } else { @@ -1629,17 +1545,18 @@ uint8_t readide(int ide_board, uint16_t addr) if (ide_drive_is_cdrom(ide)) { temp = (cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].status & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0); - // ide_log("Read CD-ROM alternate status: %02X\n", temp); } else { temp = ide->atastat; } break; + + default: + return 0xff; } /* if (ide_board) */ ide_log("Read IDEb %04X %02X %02X %02X %i %04X:%04X %i\n", addr, temp, ide->atastat,(ide->atastat & ~DSC_STAT) | (ide->service ? SERVICE_STAT : 0),cur_ide[ide_board],CS,cpu_state.pc,ide_board); return temp; - // fatal("Bad IDE read %04X\n", addr); } uint8_t cdb[16]; @@ -1656,16 +1573,9 @@ uint16_t readidew(int ide_board) return ide_read_data(ide_board, 2); } -/* uint32_t readidel(int ide_board) -{ - // ide_log("Read IDEl %i\n", ide_board); - return ide_read_data(ide_board, 4); -} */ - uint32_t readidel(int ide_board) { uint16_t temp; - // ide_log("Read IDEl %i\n", ide_board); temp = readidew(ide_board); return temp | (readidew(ide_board) << 16); } @@ -1673,15 +1583,17 @@ uint32_t readidel(int ide_board) int times30=0; void callbackide(int ide_board) { - IDE *ide = &ide_drives[cur_ide[ide_board]]; - IDE *ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; + IDE *ide, *ide_other; off64_t addr; - uint64_t faddr; int c; - ext_ide = ide; int64_t snum; int cdrom_id; - uint64_t full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); + uint64_t full_size; + + ide = &ide_drives[cur_ide[ide_board]]; + ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; + full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); + ext_ide = ide; if (ide_drive_is_cdrom(ide)) { @@ -1735,7 +1647,6 @@ void callbackide(int ide_board) { ide_other->cylinder=0xFFFF; } - // ide_log("Reset callback\n"); return; } @@ -1818,7 +1729,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - readflash=1; + update_status_bar_icon(0x21, 1); return; case WIN_READ_DMA: @@ -1852,15 +1763,16 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; + update_status_bar_icon(0x21, 1); } else { ide_irq_raise(ide); + update_status_bar_icon(0x21, 0); } } } - readflash=1; return; case WIN_READ_MULTIPLE: @@ -1886,7 +1798,6 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; if (!ide->blockcount) { - // ide_log("Read multiple int\n"); ide_irq_raise(ide); } ide->blockcount++; @@ -1895,7 +1806,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - readflash=1; + update_status_bar_icon(0x21, 1); return; case WIN_WRITE: @@ -1918,13 +1829,14 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); + update_status_bar_icon(0x21, 1); } else { ide->atastat = READY_STAT | DSC_STAT; + update_status_bar_icon(0x21, 0); } - readflash=1; return; case WIN_WRITE_DMA: @@ -1958,15 +1870,16 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; + update_status_bar_icon(0x21, 1); } else { ide_irq_raise(ide); + update_status_bar_icon(0x21, 0); } } } - readflash=1; return; case WIN_WRITE_MULTIPLE: @@ -1993,13 +1906,13 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); + update_status_bar_icon(0x21, 1); } else { ide->atastat = READY_STAT | DSC_STAT; + update_status_bar_icon(0x21, 0); } - - readflash=1; return; case WIN_VERIFY: @@ -2015,7 +1928,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - readflash=1; + update_status_bar_icon(0x21, 1); return; case WIN_FORMAT: @@ -2028,7 +1941,6 @@ void callbackide(int ide_board) goto id_not_found; } addr = ide_get_sector(ide) * 512; - // ide_log("Format cyl %i head %i offset %08X %08X %08X secount %i\n",ide.cylinder,ide.head,addr,addr>>32,addr,ide.secount); fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); memset(ide->buffer, 0, 512); for (c=0;csecount;c++) @@ -2038,7 +1950,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - readflash=1; + /* update_status_bar_icon(0x21, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: @@ -2064,32 +1976,17 @@ void callbackide(int ide_board) { goto abort_cmd; } - /* if (((hdc[cur_ide[ide->board]].at_hpc == 0) && (hdc[cur_ide[ide->board]].at_spt == 0)) || (ide->hdi != 2)) - { */ - full_size /= (ide->head+1); - full_size /= ide->secount; - ide->specify_success = 1; - if (ide->hdi == 2) - { - hdc[cur_ide[ide->board]].at_hpc = ide->head+1; - hdc[cur_ide[ide->board]].at_spt = ide->secount; - fseeko64(ide->hdfile, 0x20, SEEK_SET); - fwrite(&(hdc[cur_ide[ide->board]].at_spt), 1, 4, ide->hdfile); - fwrite(&(hdc[cur_ide[ide->board]].at_hpc), 1, 4, ide->hdfile); - } - /* } - else + full_size /= (ide->head+1); + full_size /= ide->secount; + ide->specify_success = 1; + if (ide->hdi == 2) { - if ((hdc[cur_ide[ide->board]].at_hpc == (ide->head + 1)) && (hdc[cur_ide[ide->board]].at_spt == ide->secount)) - { - ide->specify_success = 1; - } - else - { - ide_log("WIN_SPECIFY error (%04X, %04X)\n", ide->head + 1, ide->secount); - ide->specify_success = 0; - } - } */ + hdc[cur_ide[ide->board]].at_hpc = ide->head+1; + hdc[cur_ide[ide->board]].at_spt = ide->secount; + fseeko64(ide->hdfile, 0x20, SEEK_SET); + fwrite(&(hdc[cur_ide[ide->board]].at_spt), 1, 4, ide->hdfile); + fwrite(&(hdc[cur_ide[ide->board]].at_hpc), 1, 4, ide->hdfile); + } ide->spt=ide->secount; ide->hpc=ide->head+1; ide->atastat = READY_STAT | DSC_STAT; @@ -2116,10 +2013,10 @@ void callbackide(int ide_board) } ide->blocksize = ide->secount; ide->atastat = READY_STAT | DSC_STAT; - // ide_log("Set multiple mode - %i\n", ide->blocksize); ide_irq_raise(ide); return; +#if 0 case WIN_SET_FEATURES: if (!(ide_set_features(ide))) { @@ -2135,7 +2032,8 @@ void callbackide(int ide_board) } ide_irq_raise(ide); return; - +#endif + case WIN_READ_NATIVE_MAX: if ((ide->type != IDE_HDD) || ide_drive_is_cdrom(ide)) { @@ -2335,28 +2233,71 @@ uint32_t ide_read_qua_l(uint16_t addr, void *priv) } /* *** REMOVE FROM CODE SUBMITTED TO MAINLINE - END *** */ +static uint16_t ide_base_main[2] = { 0x1f0, 0x170 }; +static uint16_t ide_side_main[2] = { 0x3f6, 0x376 }; + void ide_pri_enable() { io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); + ide_base_main[0] = 0x1f0; + ide_side_main[0] = 0x3f6; +} + +void ide_pri_enable_ex() +{ + if (ide_base_main[0] & 0x300) + { + pclog("Enabling primary base (%04X)...\n", ide_base_main[0]); + io_sethandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); + } + if (ide_side_main[0] & 0x300) + { + pclog("Enabling primary side (%04X)...\n", ide_side_main[0]); + io_sethandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); + } } void ide_pri_disable() { - io_removehandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); - io_removehandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); + io_removehandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); + io_removehandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); } void ide_sec_enable() { io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); + ide_base_main[1] = 0x170; + ide_side_main[1] = 0x376; +} + +void ide_sec_enable_ex() +{ + if (ide_base_main[1] & 0x300) + { + io_sethandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); + } + if (ide_side_main[1] & 0x300) + { + io_sethandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); + } } void ide_sec_disable() { - io_removehandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); - io_removehandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); + io_removehandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); + io_removehandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); +} + +void ide_set_base(int controller, uint16_t port) +{ + ide_base_main[controller] = port; +} + +void ide_set_side(int controller, uint16_t port) +{ + ide_side_main[controller] = port; } /* *** REMOVE FROM CODE SUBMITTED TO MAINLINE - START *** */ diff --git a/src/ide.h b/src/ide.h index 970bc557b..dedb41793 100644 --- a/src/ide.h +++ b/src/ide.h @@ -4,7 +4,12 @@ #ifndef __IDE__ #define __IDE__ +#ifdef __MSC__ +# pragma pack(push,1) +typedef struct IDE +#else typedef struct __attribute__((__packed__)) IDE +#endif { int type; int board; @@ -34,6 +39,9 @@ typedef struct __attribute__((__packed__)) IDE int hdc_num; uint8_t specify_success; } IDE; +#ifdef __MSC__ +# pragma pack(pop) +#endif extern void writeide(int ide_board, uint16_t addr, uint8_t val); extern void writeidew(int ide_board, uint16_t val); @@ -61,8 +69,6 @@ extern int ide_irq[4]; extern int idecallback[4]; -extern char ide_fn[IDE_NUM][512]; - void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); @@ -73,4 +79,9 @@ void ide_padstr8(uint8_t *buf, int buf_size, const char *src); void win_cdrom_eject(uint8_t id); void win_cdrom_reload(uint8_t id); -#endif //__IDE__ +#endif + +void ide_pri_disable(); +void ide_pri_enable_ex(); +void ide_set_base(int controller, uint16_t port); +void ide_set_side(int controller, uint16_t port); diff --git a/src/intel.c b/src/intel.c index 9d305df2b..2eb47939b 100644 --- a/src/intel.c +++ b/src/intel.c @@ -12,7 +12,6 @@ uint8_t batman_brdconfig(uint16_t port, void *p) { -// pclog("batman_brdconfig read port=%04x\n", port); switch (port) { case 0x73: @@ -24,7 +23,7 @@ uint8_t batman_brdconfig(uint16_t port, void *p) } static uint16_t batman_timer_latch; -static int64_t batman_timer = 0; +static int batman_timer = 0; static void batman_timer_over(void *p) { batman_timer = 0; @@ -65,22 +64,3 @@ void intel_batman_init() io_sethandler(0x0078, 0x0002, batman_timer_read, NULL, NULL, batman_timer_write, NULL, NULL, NULL); timer_add(batman_timer_over, &batman_timer, &batman_timer, NULL); } - - -#if 0 -uint8_t endeavor_brdconfig(uint16_t port, void *p) -{ -// pclog("endeavor_brdconfig read port=%04x\n", port); - switch (port) - { - case 0x79: - return 0xff; - } - return 0; -} - -void intel_endeavor_init() -{ - io_sethandler(0x0079, 0x0001, endeavor_brdconfig, NULL, NULL, NULL, NULL, NULL, NULL); -} -#endif diff --git a/src/intel_flash.c b/src/intel_flash.c index de8fe15a5..39d40ec7d 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -20,7 +20,8 @@ enum CMD_ERASE_SETUP = 0x20, CMD_ERASE_CONFIRM = 0xd0, CMD_ERASE_SUSPEND = 0xb0, - CMD_PROGRAM_SETUP = 0x40 + CMD_PROGRAM_SETUP = 0x40, + CMD_PROGRAM_SETUP_ALT = 0x10 }; typedef struct flash_t @@ -40,11 +41,9 @@ static uint8_t flash_read(uint32_t addr, void *p) flash_t *flash = (flash_t *)p; if (flash->invert_high_pin) { - // pclog("flash_read : addr=%08x/%08x val=%02x command=%02x %04x:%08x\n", addr, addr ^ 0x10000, flash->array[(addr ^ 0x10000) & 0x1ffff], flash->command, CS, cpu_state.pc); addr ^= 0x10000; if (addr & 0xfff00000) return flash->array[addr & 0x1ffff]; } - // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); addr &= 0x1ffff; switch (flash->command) { @@ -82,7 +81,6 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) { flash_t *flash = (flash_t *)p; int i; - // pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc); if (flash->invert_high_pin) { @@ -96,8 +94,6 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) case CMD_ERASE_SETUP: if (val == CMD_ERASE_CONFIRM) { - // pclog("flash_write: erase %05x\n", addr); - for (i = 0; i < 3; i++) { if ((addr >= flash->block_start[i]) && (addr <= flash->block_end[i])) @@ -110,7 +106,7 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) break; case CMD_PROGRAM_SETUP: - // pclog("flash_write: program %05x %02x\n", addr, val); + case CMD_PROGRAM_SETUP_ALT: if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000)) flash->array[addr] = val; flash->command = CMD_READ_STATUS; @@ -154,10 +150,11 @@ static void intel_flash_add_mappings_inverted(flash_t *flash) void *intel_flash_init(uint8_t type) { FILE *f; - flash_t *flash = malloc(sizeof(flash_t)); - memset(flash, 0, sizeof(flash_t)); char fpath[1024]; int i; + flash_t *flash; + flash = malloc(sizeof(flash_t)); + memset(flash, 0, sizeof(flash_t)); switch(romset) { @@ -184,6 +181,12 @@ void *intel_flash_init(uint8_t type) case ROM_P54TP4XE: strcpy(flash_path, "roms/p54tp4xe/"); break; + case ROM_AP53: + strcpy(flash_path, "roms/ap53/"); + break; + case ROM_P55T2S: + strcpy(flash_path, "roms/p55t2s/"); + break; case ROM_ACERM3A: strcpy(flash_path, "roms/acerm3a/"); break; @@ -219,10 +222,12 @@ void *intel_flash_init(uint8_t type) case ROM_ZAPPA: strcpy(flash_path, "roms/zappa/"); break; + case ROM_S1668: + strcpy(flash_path, "roms/tpatx/"); + break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); } - // pclog("Flash init: Path is: %s\n", flash_path); flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; flash->invert_high_pin = (type & FLASH_INVERT); @@ -298,6 +303,11 @@ void *intel_flash_init(uint8_t type) return flash; } +void *intel_flash_bxb_ami_init() +{ + return intel_flash_init(FLASH_IS_BXB | FLASH_INVERT); +} + /* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ void *intel_flash_bxt_ami_init() { @@ -347,6 +357,19 @@ device_t intel_flash_bxt_ami_device = NULL }; +device_t intel_flash_bxb_ami_device = +{ + "Intel 28F001BXB Flash BIOS", + 0, + intel_flash_bxb_ami_init, + intel_flash_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + device_t intel_flash_bxt_device = { "Intel 28F001BXT Flash BIOS", diff --git a/src/intel_flash.h b/src/intel_flash.h index e8e0c1bc7..242480961 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -1,3 +1,4 @@ extern device_t intel_flash_bxt_ami_device; +extern device_t intel_flash_bxb_ami_device; extern device_t intel_flash_bxt_device; extern device_t intel_flash_bxb_device; diff --git a/src/io.c b/src/io.c index 9431268fd..da9e3318a 100644 --- a/src/io.c +++ b/src/io.c @@ -23,10 +23,12 @@ void io_init() pclog("io_init\n"); for (c = 0; c < 0x10000; c++) { - port_inb[c][0] = port_inw[c][0] = port_inl[c][0] = NULL; - port_outb[c][0] = port_outw[c][0] = port_outl[c][0] = NULL; - port_inb[c][1] = port_inw[c][1] = port_inl[c][1] = NULL; - port_outb[c][1] = port_outw[c][1] = port_outl[c][1] = NULL; + port_inb[c][0] = port_inb[c][1] = NULL; + port_outb[c][0] = port_outb[c][1] = NULL; + port_inw[c][0] = port_inw[c][1] = NULL; + port_outw[c][0] = port_outw[c][1] = NULL; + port_inl[c][0] = port_inl[c][1] = NULL; + port_outl[c][0] = port_outl[c][1] = NULL; port_priv[c][0] = port_priv[c][1] = NULL; } } @@ -94,6 +96,7 @@ void io_removehandler(uint16_t base, int size, port_outw[ base + c][0] = NULL; if (port_outl[ base + c][0] == outl) port_outl[ base + c][0] = NULL; + port_priv[base + c][0] = NULL; } if (port_priv[base + c][1] == priv) { @@ -109,6 +112,7 @@ void io_removehandler(uint16_t base, int size, port_outw[ base + c][1] = NULL; if (port_outl[ base + c][1] == outl) port_outl[ base + c][1] = NULL; + port_priv[base + c][1] = NULL; } } } @@ -133,6 +137,9 @@ uint8_t inb(uint16_t port) /* if (port_inb[port][0] || port_inb[port][1]) pclog("Good INB %04X %04X:%04X\n", port, CS, cpu_state.pc); */ +#ifdef IO_TRACE +if (CS == IO_TRACE) pclog("IOTRACE(%04X): inb(%04x)=%02x\n", IO_TRACE, port, temp); +#endif return temp; } @@ -145,6 +152,9 @@ void outb(uint16_t port, uint8_t val) if (port_outb[port][1]) port_outb[port][1](port, val, port_priv[port][1]); +#ifdef IO_TRACE +if (CS == IO_TRACE) pclog("IOTRACE(%04X): outb(%04x,%02x)\n", IO_TRACE, port, val); +#endif /* if (!port_outb[port][0] && !port_outb[port][1]) pclog("Bad OUTB %04X %02X %04X:%08X\n", port, val, CS, cpu_state.pc); */ diff --git a/src/jim.c b/src/jim.c index d1adcd5c3..ea7c5d64d 100644 --- a/src/jim.c +++ b/src/jim.c @@ -20,13 +20,11 @@ void writejim(uint16_t addr, uint8_t val, void *p) switch (addr) { case 0x25A: -// printf("Write RTC stat %i val %02X\n",europc_rtc.stat,val); switch (europc_rtc.stat) { case 0: europc_rtc.addr=val&0xF; europc_rtc.stat++; -// printf("RTC addr now %02X - contents %02X\n",val&0xF,europc_rtc.dat[europc_rtc.addr]); break; case 1: europc_rtc.dat[europc_rtc.addr]=(europc_rtc.dat[europc_rtc.addr]&0xF)|(val<<4); @@ -39,12 +37,10 @@ void writejim(uint16_t addr, uint8_t val, void *p) } break; } -// printf("Write JIM %04X %02X\n",addr,val); } uint8_t readjim(uint16_t addr, void *p) { -// printf("Read JIM %04X\n",addr); switch (addr) { case 0x250: case 0x251: case 0x252: case 0x253: return 0; diff --git a/src/joystick_ch_flightstick_pro.c b/src/joystick_ch_flightstick_pro.c index 3ced21653..9f0e97250 100644 --- a/src/joystick_ch_flightstick_pro.c +++ b/src/joystick_ch_flightstick_pro.c @@ -8,6 +8,7 @@ static void *ch_flightstick_pro_init() { + return NULL; } static void ch_flightstick_pro_close(void *p) @@ -63,6 +64,8 @@ static int ch_flightstick_pro_read_axis(void *p, int axis) return 0; case 3: return joystick_state[0].axis[2]; + default: + return 0; } } @@ -72,18 +75,18 @@ static void ch_flightstick_pro_a0_over(void *p) joystick_if_t joystick_ch_flightstick_pro = { - .name = "CH Flightstick Pro", - .init = ch_flightstick_pro_init, - .close = ch_flightstick_pro_close, - .read = ch_flightstick_pro_read, - .write = ch_flightstick_pro_write, - .read_axis = ch_flightstick_pro_read_axis, - .a0_over = ch_flightstick_pro_a0_over, - .max_joysticks = 1, - .axis_count = 3, - .button_count = 4, - .pov_count = 1, - .axis_names = {"X axis", "Y axis", "Throttle"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, - .pov_names = {"POV"} + "CH Flightstick Pro", + ch_flightstick_pro_init, + ch_flightstick_pro_close, + ch_flightstick_pro_read, + ch_flightstick_pro_write, + ch_flightstick_pro_read_axis, + ch_flightstick_pro_a0_over, + 1, + 3, + 4, + 1, + {"X axis", "Y axis", "Throttle"}, + {"Button 1", "Button 2", "Button 3", "Button 4"}, + {"POV"} }; diff --git a/src/joystick_standard.c b/src/joystick_standard.c index 6f961a896..7c8098ba7 100644 --- a/src/joystick_standard.c +++ b/src/joystick_standard.c @@ -8,6 +8,7 @@ static void *joystick_standard_init() { + return NULL; } static void joystick_standard_close(void *p) @@ -79,6 +80,8 @@ static int joystick_standard_read_axis(void *p, int axis) if (!JOYSTICK_PRESENT(1)) return AXIS_NOT_PRESENT; return joystick_state[1].axis[1]; + default: + return 0; } } @@ -97,6 +100,8 @@ static int joystick_standard_read_axis_4button(void *p, int axis) return 0; case 3: return 0; + default: + return 0; } } static int joystick_standard_read_axis_6button(void *p, int axis) @@ -114,6 +119,8 @@ static int joystick_standard_read_axis_6button(void *p, int axis) return joystick_state[0].button[4] ? -32767 : 32768; case 3: return joystick_state[0].button[5] ? -32767 : 32768; + default: + return 0; } } static int joystick_standard_read_axis_8button(void *p, int axis) @@ -139,6 +146,8 @@ static int joystick_standard_read_axis_8button(void *p, int axis) if (joystick_state[0].button[7]) return 32768; return 0; + default: + return 0; } } @@ -148,61 +157,65 @@ static void joystick_standard_a0_over(void *p) joystick_if_t joystick_standard = { - .name = "Standard 2-button joystick(s)", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 2, - .axis_count = 2, - .button_count = 2, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2"} + "Standard 2-button joystick(s)", + joystick_standard_init, + joystick_standard_close, + joystick_standard_read, + joystick_standard_write, + joystick_standard_read_axis, + joystick_standard_a0_over, + 2, + 2, + 2, + 0, + {"X axis", "Y axis"}, + {"Button 1", "Button 2"} }; joystick_if_t joystick_standard_4button = { - .name = "Standard 4-button joystick", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read_4button, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_4button, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 4, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"} + "Standard 4-button joystick", + joystick_standard_init, + joystick_standard_close, + joystick_standard_read_4button, + joystick_standard_write, + joystick_standard_read_axis_4button, + joystick_standard_a0_over, + 1, + 2, + 4, + 0, + {"X axis", "Y axis"}, + {"Button 1", "Button 2", "Button 3", "Button 4"} }; joystick_if_t joystick_standard_6button = { - .name = "Standard 6-button joystick", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read_4button, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_6button, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 6, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"} + "Standard 6-button joystick", + joystick_standard_init, + joystick_standard_close, + joystick_standard_read_4button, + joystick_standard_write, + joystick_standard_read_axis_6button, + joystick_standard_a0_over, + 1, + 2, + 6, + 0, + {"X axis", "Y axis"}, + {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6"} }; joystick_if_t joystick_standard_8button = { - .name = "Standard 8-button joystick", - .init = joystick_standard_init, - .close = joystick_standard_close, - .read = joystick_standard_read_4button, - .write = joystick_standard_write, - .read_axis = joystick_standard_read_axis_8button, - .a0_over = joystick_standard_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 8, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8"} + "Standard 8-button joystick", + joystick_standard_init, + joystick_standard_close, + joystick_standard_read_4button, + joystick_standard_write, + joystick_standard_read_axis_8button, + joystick_standard_a0_over, + 1, + 2, + 8, + 0, + {"X axis", "Y axis"}, + {"Button 1", "Button 2", "Button 3", "Button 4", "Button 5", "Button 6", "Button 7", "Button 8"} }; diff --git a/src/joystick_sw_pad.c b/src/joystick_sw_pad.c index 007dd5492..5fce2447a 100644 --- a/src/joystick_sw_pad.c +++ b/src/joystick_sw_pad.c @@ -149,7 +149,6 @@ static void sw_write(void *p) if (time_since_last > 9900 && time_since_last < 9940) { -// pclog("sw sends ID packet\n"); sw->poll_mode = 0; sw->poll_left = 49; sw->poll_data = 0x2400ull | (0x1830ull << 15) | (0x19b0ull << 30); @@ -157,8 +156,6 @@ static void sw_write(void *p) else { int c; - -// pclog("sw sends data packet %08x %i\n", cpu_state.pc, data_packets++); sw->poll_mode = sw->data_mode; sw->data_mode = !sw->data_mode; @@ -236,16 +233,17 @@ static void sw_a0_over(void *p) joystick_if_t joystick_sw_pad = { - .name = "Microsoft SideWinder Pad", - .init = sw_init, - .close = sw_close, - .read = sw_read, - .write = sw_write, - .read_axis = sw_read_axis, - .a0_over = sw_a0_over, - .max_joysticks = 4, - .axis_count = 2, - .button_count = 10, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M"} + "Microsoft SideWinder Pad", + sw_init, + sw_close, + sw_read, + sw_write, + sw_read_axis, + sw_a0_over, + 4, + 2, + 10, + 0, + {"X axis", "Y axis"}, + {"A", "B", "C", "X", "Y", "Z", "L", "R", "Start", "M"} }; diff --git a/src/joystick_tm_fcs.c b/src/joystick_tm_fcs.c index 02c153e49..a60e0ca5d 100644 --- a/src/joystick_tm_fcs.c +++ b/src/joystick_tm_fcs.c @@ -8,6 +8,7 @@ static void *tm_fcs_init() { + return NULL; } static void tm_fcs_close(void *p) @@ -62,6 +63,8 @@ static int tm_fcs_read_axis(void *p, int axis) if (joystick_state[0].pov[0] >= 225 && joystick_state[0].pov[0] < 315) return 16384; return 0; + default: + return 0; } } @@ -71,18 +74,18 @@ static void tm_fcs_a0_over(void *p) joystick_if_t joystick_tm_fcs = { - .name = "Thrustmaster Flight Control System", - .init = tm_fcs_init, - .close = tm_fcs_close, - .read = tm_fcs_read, - .write = tm_fcs_write, - .read_axis = tm_fcs_read_axis, - .a0_over = tm_fcs_a0_over, - .max_joysticks = 1, - .axis_count = 2, - .button_count = 4, - .pov_count = 1, - .axis_names = {"X axis", "Y axis"}, - .button_names = {"Button 1", "Button 2", "Button 3", "Button 4"}, - .pov_names = {"POV"} + "Thrustmaster Flight Control System", + tm_fcs_init, + tm_fcs_close, + tm_fcs_read, + tm_fcs_write, + tm_fcs_read_axis, + tm_fcs_a0_over, + 1, + 2, + 4, + 1, + {"X axis", "Y axis"}, + {"Button 1", "Button 2", "Button 3", "Button 4"}, + {"POV"} }; diff --git a/src/keyboard.c b/src/keyboard.c index 8090f9196..22924f504 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -467,7 +467,6 @@ void keyboard_process() if (!set3_all_break && !recv_key[scorder[c]] && !(set3_flags[scancodes[scorder[c]].scancodes_make[0]] & 2)) continue; } -// pclog("Key %02X start\n", scorder[c]); d = 0; if (recv_key[scorder[c]]) { diff --git a/src/keyboard_amstrad.c b/src/keyboard_amstrad.c index 7f1a99c9e..6ec66001f 100644 --- a/src/keyboard_amstrad.c +++ b/src/keyboard_amstrad.c @@ -88,7 +88,7 @@ void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_set_gate(2, val & 1); + pit_set_gate(&pit, 2, val & 1); if (val & 0x80) keyboard_amstrad.pa = 0; @@ -107,15 +107,12 @@ void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv) default: pclog("\nBad XT keyboard write %04X %02X\n", port, val); -// dumpregs(); -// exit(-1); } } uint8_t keyboard_amstrad_read(uint16_t port, void *priv) { uint8_t temp; -// pclog("keyboard_amstrad : read %04X ", port); switch (port) { case 0x60: @@ -155,10 +152,7 @@ uint8_t keyboard_amstrad_read(uint16_t port, void *priv) default: pclog("\nBad XT keyboard read %04X\n", port); -// dumpregs(); -// exit(-1); } -// pclog("%02X %04X:%04X\n", temp, CS, pc); return temp; } @@ -171,7 +165,6 @@ void keyboard_amstrad_reset() void keyboard_amstrad_init() { - //return; pclog("keyboard_amstrad_init\n"); io_sethandler(0x0060, 0x0006, keyboard_amstrad_read, NULL, NULL, keyboard_amstrad_write, NULL, NULL, NULL); keyboard_amstrad_reset(); diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 9d9857945..4cf084829 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -4,6 +4,8 @@ #include #include "ibm.h" +#include "disc.h" +#include "fdc.h" #include "io.h" #include "mem.h" #include "pic.h" @@ -25,6 +27,8 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 +#define PS2_REFRESH_TIME (16 * TIMER_USEC) + #define CCB_UNUSED 0x80 #define CCB_TRANSLATE 0x40 #define CCB_PCMODE 0x20 @@ -63,6 +67,11 @@ struct void (*mouse_write)(uint8_t val, void *p); void *mouse_p; + + int refresh_time; + int refresh; + + int is_ps2; } keyboard_at; static uint8_t key_ctrl_queue[16]; @@ -136,7 +145,6 @@ void keyboard_at_poll() keyboard_at.status |= STAT_OFULL; keyboard_at.status &= ~STAT_IFULL; keyboard_at.status |= STAT_MFULL; -// pclog("keyboard_at : take IRQ12\n"); keyboard_at.last_irq = 0x1000; } else @@ -148,12 +156,17 @@ void keyboard_at_poll() keyboard_at.status |= STAT_OFULL; keyboard_at.status &= ~STAT_IFULL; keyboard_at.status &= ~STAT_MFULL; -// pclog("keyboard_at : take IRQ1\n"); keyboard_at.last_irq = 2; } } - if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && /*!(keyboard_at.mem[0] & 0x20) &&*/ + if (keyboard_at.out_new == -1 && !(keyboard_at.status & STAT_OFULL) && + key_ctrl_queue_start != key_ctrl_queue_end) + { + keyboard_at.out_new = key_ctrl_queue[key_ctrl_queue_start]; + key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; + } + else if (!(keyboard_at.status & STAT_OFULL) && keyboard_at.out_new == -1 && /*!(keyboard_at.mem[0] & 0x20) &&*/ mouse_queue_start != mouse_queue_end) { keyboard_at.out_new = mouse_queue[mouse_queue_start] | 0x100; @@ -165,29 +178,12 @@ void keyboard_at_poll() keyboard_at.out_new = key_queue[key_queue_start]; key_queue_start = (key_queue_start + 1) & 0xf; } - else if (keyboard_at.out_new == -1 && !(keyboard_at.status & STAT_OFULL) && - key_ctrl_queue_start != key_ctrl_queue_end) - { - keyboard_at.out_new = key_ctrl_queue[key_ctrl_queue_start]; - key_ctrl_queue_start = (key_ctrl_queue_start + 1) & 0xf; - } } void keyboard_at_adddata(uint8_t val) { -// if (keyboard_at.status & STAT_OFULL) -// { key_ctrl_queue[key_ctrl_queue_end] = val; key_ctrl_queue_end = (key_ctrl_queue_end + 1) & 0xf; -// pclog("keyboard_at : %02X added to queue\n", val); -/* return; - } - keyboard_at.out = val; - keyboard_at.status |= STAT_OFULL; - keyboard_at.status &= ~STAT_IFULL; - if (keyboard_at.mem[0] & 0x01) - keyboard_at.wantirq = 1; - pclog("keyboard_at : output %02X (IRQ %i)\n", val, keyboard_at.wantirq);*/ } uint8_t sc_or = 0; @@ -223,18 +219,12 @@ void keyboard_at_adddata_mouse(uint8_t val) { mouse_queue[mouse_queue_end] = val; mouse_queue_end = (mouse_queue_end + 1) & 0xf; -// pclog("keyboard_at : %02X added to mouse queue\n", val); return; } void keyboard_at_write(uint16_t port, uint8_t val, void *priv) { int i = 0; -// pclog("keyboard_at : write %04X %02X %i %02X\n", port, val, keyboard_at.key_wantdata, ram[8]); -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ switch (port) { case 0x60: @@ -244,7 +234,15 @@ void keyboard_at_write(uint16_t port, uint8_t val, void *priv) keyboard_at.want60 = 0; switch (keyboard_at.command) { - case 0x40 ... 0x5f: /* 0x40 - 0x5F are aliases for 0x60-0x7F */ + /* 0x40 - 0x5F are aliases for 0x60-0x7F */ + case 0x40: case 0x41: case 0x42: case 0x43: + case 0x44: case 0x45: case 0x46: case 0x47: + case 0x48: case 0x49: case 0x4a: case 0x4b: + case 0x4c: case 0x4d: case 0x4e: case 0x4f: + case 0x50: case 0x51: case 0x52: case 0x53: + case 0x54: case 0x55: case 0x56: case 0x57: + case 0x58: case 0x59: case 0x5a: case 0x5b: + case 0x5c: case 0x5d: case 0x5e: case 0x5f: keyboard_at.command |= 0x20; goto write_register; @@ -268,7 +266,6 @@ write_register: mouse_scan = !(val & 0x20); /* Addition by OBattler: Scan code translate ON/OFF. */ - // pclog("KEYBOARD_AT: Writing %02X to system register\n", val); mode &= 0x93; mode |= (val & MODE_MASK); if (first_write) @@ -285,7 +282,6 @@ write_register: } keyboard_at.default_mode = (mode & 3); first_write = 0; - // pclog("Keyboard set to scan code set %i, mode & 0x60 = 0x%02X\n", mode & 3, mode & 0x60); /* No else because in all other cases, translation is off, so we need to keep it set to set 0 which the mode &= 0xFC above will set it. */ } @@ -295,23 +291,18 @@ write_register: case 0xaf: /*AMI - set extended controller RAM*/ if (keyboard_at.secr_phase == 0) { - // pclog("Set extended controller RAM - phase 0 (bad)\n"); goto bad_command; } else if (keyboard_at.secr_phase == 1) { - // pclog("Set extended controller RAM - phase 1\n"); keyboard_at.mem_addr = val; keyboard_at.want60 = 1; keyboard_at.secr_phase = 2; - // pclog("Set extended controller RAM - starting phase 2\n"); } else if (keyboard_at.secr_phase == 2) { - // pclog("Set extended controller RAM - phase 2\n"); keyboard_at.mem[keyboard_at.mem_addr] = val; keyboard_at.secr_phase = 0; - // pclog("Set extended controller RAM - starting phase 0\n"); } break; @@ -325,12 +316,10 @@ write_register: break; case 0xd1: /*Write output port*/ -// pclog("Write output port - %02X %02X %04X:%04X\n", keyboard_at.output_port, val, CS, pc); if ((keyboard_at.output_port ^ val) & 0x02) /*A20 enable change*/ { mem_a20_key = val & 0x02; mem_a20_recalc(); -// pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); flushmmucache(); } keyboard_at.output_port = val; @@ -352,8 +341,6 @@ write_register: default: bad_command: pclog("Bad AT keyboard controller 0060 write %02X command %02X\n", val, keyboard_at.command); -// dumpregs(); -// exit(-1); } } else @@ -370,7 +357,6 @@ bad_command: break; case 0xf0: /*Get/set scancode set*/ - // pclog("KEYBOARD_AT: Get/set scan code set: %i\n", val); if (val == 0) { keyboard_at_adddata_keyboard(mode & 3); @@ -392,8 +378,6 @@ bad_command: default: pclog("Bad AT keyboard 0060 write %02X command %02X\n", val, keyboard_at.key_command); -// dumpregs(); -// exit(-1); } } else @@ -452,11 +436,9 @@ bad_command: break; case 0xf6: /*Set defaults*/ - // pclog("KEYBOARD_AT: Set defaults\n"); set3_all_break = 0; set3_all_repeat = 0; memset(set3_flags, 0, 272); - // mode = (mode & 0xFC) | 2; mode = (mode & 0xFC) | keyboard_at.default_mode; keyboard_at_adddata_keyboard(0xfa); break; @@ -487,7 +469,6 @@ bad_command: break; case 0xff: /*Reset*/ - // pclog("KEYBOARD_AT: Set defaults\n"); key_queue_start = key_queue_end = 0; /*Clear key queue*/ keyboard_at_adddata_keyboard(0xfa); keyboard_at_adddata_keyboard(0xaa); @@ -499,8 +480,6 @@ bad_command: default: pclog("Bad AT keyboard command %02X\n", val); keyboard_at_adddata_keyboard(0xfe); -// dumpregs(); -// exit(-1); } } } @@ -517,7 +496,7 @@ bad_command: speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_set_gate(2, val & 1); + pit_set_gate(&pit, 2, val & 1); break; case 0x64: @@ -526,7 +505,14 @@ bad_command: /*New controller command*/ switch (val) { - case 0x00 ... 0x1f: + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x04: case 0x05: case 0x06: case 0x07: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x1c: case 0x1d: case 0x1e: case 0x1f: val |= 0x20; /* 0x00-0x1f are aliases for 0x20-0x3f */ keyboard_at_adddata(keyboard_at.mem[val & 0x1f]); break; @@ -583,7 +569,6 @@ bad_command: { mem_a20_key = 2; mem_a20_recalc(); -// pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); flushmmucache(); } keyboard_at.output_port = 0xcf; @@ -625,10 +610,12 @@ bad_command: case ROM_ENDEAVOR: case ROM_THOR: case ROM_MRTHOR: + case ROM_AP53: + case ROM_P55T2S: + case ROM_S1668: /*Set extended controlled RAM*/ keyboard_at.want60 = 1; keyboard_at.secr_phase = 1; - // pclog("Set extended controller RAM - starting phase 1\n"); break; default: /*Read keyboard version*/ @@ -637,7 +624,9 @@ bad_command: } break; - case 0xb0 ... 0xbf: /*Set keyboard lines low (B0-B7) or high (B8-BF)*/ + case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7: + case 0xb8: case 0xb9: case 0xba: case 0xbb: case 0xbc: case 0xbd: case 0xbe: case 0xbf: + /*Set keyboard lines low (B0-B7) or high (B8-BF)*/ keyboard_at_adddata(0x00); break; @@ -694,7 +683,6 @@ bad_command: keyboard_at.output_port &= ~0x02; mem_a20_key = 0; mem_a20_recalc(); - // pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); flushmmucache(); break; @@ -702,7 +690,6 @@ bad_command: keyboard_at.output_port |= 0x02; mem_a20_key = 2; mem_a20_recalc(); - // pclog("Rammask change to %08X %02X\n", rammask, val & 0x02); flushmmucache(); break; @@ -713,19 +700,19 @@ bad_command: case 0xef: /*??? - sent by AMI486*/ break; - case 0xf0 ... 0xff: + case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7: + case 0xf8: case 0xf9: case 0xfa: case 0xfb: case 0xfc: case 0xfd: case 0xfe: case 0xff: if (!(val & 1)) { /* Pin 0 selected. */ - softresetx86(); /*Pulse reset!*/ - cpu_set_edx(); + /* trc_reset(2); */ + softresetx86(); /*Pulse reset!*/ + cpu_set_edx(); } break; default: pclog("Bad AT keyboard controller command %02X\n", val); -// dumpregs(); -// exit(-1); } } } @@ -733,8 +720,6 @@ bad_command: uint8_t keyboard_at_read(uint16_t port, void *priv) { uint8_t temp = 0xff; - cycles -= 4; -// if (port != 0x61) pclog("keyboard_at : read %04X ", port); switch (port) { case 0x60: @@ -753,9 +738,18 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) keyboard_at.last_irq = 0; break; - case 0x61: - if (ppispeakon) return (ppi.pb&~0xC0)|0x20; - return ppi.pb&~0xe0; + case 0x61: + temp = ppi.pb & ~0xe0; + if (ppispeakon) + temp |= 0x20; + if (keyboard_at.is_ps2) + { + if (keyboard_at.refresh) + temp |= 0x10; + else + temp &= ~0x10; + } + break; case 0x64: temp = (keyboard_at.status & 0xFB) | (mode & CCB_SYSTEM); @@ -763,7 +757,6 @@ uint8_t keyboard_at_read(uint16_t port, void *priv) keyboard_at.status &= ~(STAT_RTIMEOUT/* | STAT_TTIMEOUT*/); break; } -// if (port != 0x61) pclog("%02X %08X\n", temp, rammask); return temp; } @@ -777,7 +770,7 @@ void keyboard_at_reset() first_write = 1; keyboard_at.wantirq = 0; keyboard_at.output_port = 0xcf; - keyboard_at.input_port = 0xb0; + keyboard_at.input_port = (MDA) ? 0xf0 : 0xb0; keyboard_at.out_new = -1; keyboard_at.last_irq = 0; keyboard_at.secr_phase = 0; @@ -791,15 +784,21 @@ void keyboard_at_reset() memset(set3_flags, 0, 272); } +static void at_refresh(void *p) +{ + keyboard_at.refresh = !keyboard_at.refresh; + keyboard_at.refresh_time += PS2_REFRESH_TIME; +} + void keyboard_at_init() { - //return; io_sethandler(0x0060, 0x0005, keyboard_at_read, NULL, NULL, keyboard_at_write, NULL, NULL, NULL); keyboard_at_reset(); keyboard_send = keyboard_at_adddata_keyboard; keyboard_poll = keyboard_at_poll; keyboard_at.mouse_write = NULL; keyboard_at.mouse_p = NULL; + keyboard_at.is_ps2 = 0; dtrans = 0; timer_add(keyboard_at_poll, &keybsenddelay, TIMER_ALWAYS_ENABLED, NULL); @@ -810,3 +809,9 @@ void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p) keyboard_at.mouse_write = mouse_write; keyboard_at.mouse_p = p; } + +void keyboard_at_init_ps2() +{ + timer_add(at_refresh, &keyboard_at.refresh_time, TIMER_ALWAYS_ENABLED, NULL); + keyboard_at.is_ps2 = 1; +} diff --git a/src/keyboard_at.h b/src/keyboard_at.h index 5f0d758ee..2fdfb5ee8 100644 --- a/src/keyboard_at.h +++ b/src/keyboard_at.h @@ -2,9 +2,11 @@ see COPYING for more details */ void keyboard_at_init(); +void keyboard_at_init_ps2(); void keyboard_at_reset(); void keyboard_at_poll(); void keyboard_at_adddata_keyboard_raw(uint8_t val); +void keyboard_at_adddata_mouse(uint8_t val); void keyboard_at_set_mouse(void (*mouse_write)(uint8_t val, void *p), void *p); extern int mouse_queue_start, mouse_queue_end; diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index 79eff4217..498640777 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -1,8 +1,10 @@ +#include #include "ibm.h" #include "io.h" #include "mem.h" #include "mouse.h" #include "pic.h" +#include "pit.h" #include "sound.h" #include "sound_speaker.h" #include "timer.h" @@ -152,7 +154,7 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_set_gate(2, val & 1); + pit_set_gate(&pit, 2, val & 1); break; } } @@ -221,7 +223,7 @@ typedef struct mouse_olim24_t int x, y, b; } mouse_olim24_t; -void mouse_olim24_poll(int x, int y, int z, int b, void *p) +uint8_t mouse_olim24_poll(int x, int y, int z, int b, void *p) { mouse_olim24_t *mouse = (mouse_olim24_t *)p; @@ -231,7 +233,7 @@ void mouse_olim24_poll(int x, int y, int z, int b, void *p) // pclog("mouse_poll - %i, %i %i, %i\n", x, y, mouse->x, mouse->y); if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); if ((b & 1) && !(mouse->b & 1)) keyboard_olim24_adddata(mouse_scancodes[0]); if (!(b & 1) && (mouse->b & 1)) @@ -239,7 +241,7 @@ void mouse_olim24_poll(int x, int y, int z, int b, void *p) mouse->b = (mouse->b & ~1) | (b & 1); if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); if ((b & 2) && !(mouse->b & 2)) keyboard_olim24_adddata(mouse_scancodes[2]); if (!(b & 2) && (mouse->b & 2)) @@ -247,7 +249,7 @@ void mouse_olim24_poll(int x, int y, int z, int b, void *p) mouse->b = (mouse->b & ~2) | (b & 2); if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); if ((b & 4) && !(mouse->b & 4)) keyboard_olim24_adddata(mouse_scancodes[1]); if (!(b & 4) && (mouse->b & 4)) @@ -257,9 +259,9 @@ void mouse_olim24_poll(int x, int y, int z, int b, void *p) if (keyboard_olim24.mouse_mode) { if (((key_queue_end - key_queue_start) & 0xf) > 12) - return; + return(0xff); if (!mouse->x && !mouse->y) - return; + return(0xff); mouse->y = -mouse->y; @@ -282,32 +284,34 @@ void mouse_olim24_poll(int x, int y, int z, int b, void *p) while (mouse->x < -4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); mouse->x += 4; keyboard_olim24_adddata(mouse_scancodes[3]); } while (mouse->x > 4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); mouse->x -= 4; keyboard_olim24_adddata(mouse_scancodes[4]); } while (mouse->y < -4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); mouse->y += 4; keyboard_olim24_adddata(mouse_scancodes[5]); } while (mouse->y > 4) { if (((key_queue_end - key_queue_start) & 0xf) > 14) - return; + return(0xff); mouse->y -= 4; keyboard_olim24_adddata(mouse_scancodes[6]); } } + + return(0); } static void *mouse_olim24_init() @@ -328,10 +332,11 @@ static void mouse_olim24_close(void *p) mouse_t mouse_olim24 = { "Olivetti M24 mouse", + "olim24", + MOUSE_TYPE_OLIM24, mouse_olim24_init, mouse_olim24_close, - mouse_olim24_poll, - MOUSE_TYPE_OLIM24 + mouse_olim24_poll }; void keyboard_olim24_init() diff --git a/src/keyboard_pcjr.c b/src/keyboard_pcjr.c index 64fa693cd..38142dd14 100644 --- a/src/keyboard_pcjr.c +++ b/src/keyboard_pcjr.c @@ -9,6 +9,7 @@ #include "mem.h" #include "nmi.h" #include "pic.h" +#include "pit.h" #include "sound.h" #include "sound_sn76489.h" #include "sound_speaker.h" @@ -52,7 +53,6 @@ void keyboard_pcjr_poll() int p = 0; uint8_t key = key_queue[key_queue_start]; -// pclog("Reading %02X from the key queue at %i\n", key, key_queue_start); key_queue_start = (key_queue_start + 1) & 0xf; keyboard_pcjr.latched = 1; @@ -102,25 +102,18 @@ void keyboard_pcjr_poll() keyboard_pcjr.serial_pos++; if (keyboard_pcjr.serial_pos == 42+1) keyboard_pcjr.serial_pos = 0; -// pclog("Keyboard poll %i %i\n", keyboard_pcjr.data, keyboard_pcjr.serial_pos); } } void keyboard_pcjr_adddata(uint8_t val) { key_queue[key_queue_end] = val; -// pclog("keyboard_pcjr : %02X added to key queue at %i\n", val, key_queue_end); key_queue_end = (key_queue_end + 1) & 0xf; return; } void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) { -// pclog("keyboard_pcjr : write %04X %02X %02X\n", port, val, keyboard_pcjr.pb); -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ switch (port) { case 0x60: @@ -138,7 +131,7 @@ void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_set_gate(2, val & 1); + pit_set_gate(&pit, 2, val & 1); sn76489_mute = speaker_mute = 1; switch (val & 0x60) { @@ -153,7 +146,7 @@ void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) case 0xa0: nmi_mask = val & 0x80; - pit_set_using_timer(1, !(val & 0x20)); + pit_set_using_timer(&pit, 1, !(val & 0x20)); break; } } @@ -161,7 +154,6 @@ void keyboard_pcjr_write(uint16_t port, uint8_t val, void *priv) uint8_t keyboard_pcjr_read(uint16_t port, void *priv) { uint8_t temp; -// pclog("keyboard_pcjr : read %04X ", port); switch (port) { case 0x60: @@ -178,21 +170,19 @@ uint8_t keyboard_pcjr_read(uint16_t port, void *priv) temp |= (ppispeakon ? 0x10 : 0); temp |= (ppispeakon ? 0x20 : 0); temp |= (keyboard_pcjr.data ? 0x40: 0); -// temp |= 0x04; if (keyboard_pcjr.data) temp |= 0x40; break; case 0xa0: keyboard_pcjr.latched = 0; + temp = 0; break; default: pclog("\nBad XT keyboard read %04X\n", port); - //dumpregs(); - //exit(-1); + temp = 0xff; } -// pclog("%02X\n", temp); return temp; } @@ -202,7 +192,6 @@ void keyboard_pcjr_reset() void keyboard_pcjr_init() { - //return; io_sethandler(0x0060, 0x0004, keyboard_pcjr_read, NULL, NULL, keyboard_pcjr_write, NULL, NULL, NULL); io_sethandler(0x00a0, 0x0008, keyboard_pcjr_read, NULL, NULL, keyboard_pcjr_write, NULL, NULL, NULL); keyboard_pcjr_reset(); diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index bb9233491..0541b2692 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -4,11 +4,14 @@ #include #include "ibm.h" +#include "device.h" #include "io.h" #include "mem.h" #include "pic.h" +#include "pit.h" #include "sound.h" #include "sound_speaker.h" +#include "tandy_eeprom.h" #include "timer.h" #include "keyboard.h" @@ -59,15 +62,9 @@ void keyboard_xt_adddata(uint8_t val) void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) { -// pclog("keyboard_xt : write %04X %02X %02X\n", port, val, keyboard_xt.pb); -/* if (ram[8] == 0xc3) - { - output = 3; - }*/ switch (port) { case 0x61: -// pclog("keyboard_xt : pb write %02X %02X %i %02X %i\n", val, keyboard_xt.pb, !(keyboard_xt.pb & 0x40), keyboard_xt.pb & 0x40, (val & 0x40)); if (!(keyboard_xt.pb & 0x40) && (val & 0x40)) /*Reset keyboard*/ { pclog("keyboard_xt : reset keyboard\n"); @@ -91,7 +88,7 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) speaker_enable = val & 2; if (speaker_enable) was_speaker_enable = 1; - pit_set_gate(2, val & 1); + pit_set_gate(&pit, 2, val & 1); break; } @@ -100,7 +97,6 @@ void keyboard_xt_write(uint16_t port, uint8_t val, void *priv) uint8_t keyboard_xt_read(uint16_t port, void *priv) { uint8_t temp; -// pclog("keyboard_xt : read %04X ", port); switch (port) { case 0x60: @@ -150,10 +146,8 @@ uint8_t keyboard_xt_read(uint16_t port, void *priv) default: pclog("\nBad XT keyboard read %04X\n", port); - //dumpregs(); - //exit(-1); + temp = 0xff; } -// pclog("%02X\n", temp); return temp; } @@ -166,7 +160,6 @@ void keyboard_xt_reset() void keyboard_xt_init() { - //return; io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); keyboard_xt_reset(); keyboard_send = keyboard_xt_adddata; @@ -178,7 +171,6 @@ void keyboard_xt_init() void keyboard_tandy_init() { - //return; io_sethandler(0x0060, 0x0004, keyboard_xt_read, NULL, NULL, keyboard_xt_write, NULL, NULL, NULL); keyboard_xt_reset(); keyboard_send = keyboard_xt_adddata; diff --git a/src/libwpcapdelay.a b/src/libwpcapdelay.a new file mode 100644 index 0000000000000000000000000000000000000000..c9d175845d939ebb7aae9a6882df7445d9e7efe9 GIT binary patch literal 88406 zcmeI54U8m5b%1Nbm^^@s%Q7r>zc0Wuiw0?S6zMMv3xq%xb5=yEV|plrPY|x^Gpa55o6gdf<0OI{6vK zFg*(2f$6bBB7NlhjA8m1=wW*Df=KxjjA0tWNn=|7FOkZ>U<}jfOCnXDVhq#tq)1y= zF^1{f---0hR~f_f6VHouVaOP!pS(__pZX4Cn4bF=k$x6*F@5&DNI&-sW0+n%Cer8r zi7`w+|87&&~})9>l-5d&a;eR z`q~MReh9)aNd~yCf*H=`XKm4AVD3 z2h(5wwn*QC`eFK8I2TOcxlN?+z6MZ&^!L!ln7;Q}k^cD}#xVWs%_9AKk1I{of+J?(1v;(;Hq8>8ev~0n;_t ziuC4hu?0-m{jx|mtg!`5H{C4K{%^7cOz(i>F}-Ul(z`d<0;c|bA|1YhEnqtGry{Ms z$QCfY?}SLVUB?zM9fz_o-T4`j?)fNNz;r+4Vfx@-iS*!eYys259}wx$e`5=n9{Vz; zEE|<;=O%-EGAu^<(^;OC<9xGVS(ep#IeMU&o+*44$h_27gb|7o3OJo&y0*2xUU+BZ<|yqMT((g;KI49CQ5(6^ z99QGD5wPHE8oAQktcD1ox$?837Ba0-j_YbrO`Zb^OkSUGKLd@56^ZX+wa2n;zCl<~_9cC$*W6RB=+VUZI-h^P)9A-n&swZF)Z`C$eJ!MTx>U6A2-bF8~_Wj$xMdU z71(C8@|l32%*m5SjEA4tDz@O(p627(re~sNMVRd!$B*{vt`3rU-VtDD>S^U;tB%pR z-ck7oZk(3yk$L)vNj^AR_$Z8rO3d}9#b#9(`Je`yJ#%&aEKh$hs%CE6nge8Ba72-h zw6XorKsIvON8UdWkx4z0Go5O|$J{8vHPNIYK*ss!iL?;o76B za*dM^sJydV6KFN(^guyLEv;d(-Jr##LJMx{Y`6tZF8r<(a7S72;tlWQxkohX%4?1m zTp22KpJ$$SkSogux%vfdIK;}5`fH8t4;=_2=bGg#o1M!i6R(Q4Sm=$P0*A{v*;0yl z{)TNG33iU8AC~N#fK!HSU$8>PL$$7%Bj@FUq}cY&h!JX?se5ap28vX^x|o)u=YDO2 zf<87cr~L1Yd^{YvrUkwy^Rv0``m`tpzRPWdS_eE0z}bZb)wEn|sxu6EM13#U9A!ag z)tDb*WeNRqJe1$-8~AlE%hz|VxTP$w0Q|NTW7l>mku1q;SIm{i7Wi|KZ9s3X_IzhA zhnFN|d9$hzb3JY}_}zfF)z~#1VWxYGQ(LVp&zJwdUKb;`TWgC=Y3q0jVR2Gy>5aB# z8x49wZ0YfKvo5swTGN{R|Ip#I#k#cM`&13f*(9$A-uY;uI9~QJS_d8!e6B*{vCcSx zT{rJL96h%r`~hwnY|v-nD7eRRcckfSjh~{5aa&AxvUqueX#pLz2B+E0uymc$gqFMl zgKBdE*EAbfsP5`{S)x24Y*JJu27M5_=P}5~!VeAluU-!Swl%2f*}w&`q+APnO64}R zh;vd#D14x7xTf+g!P;aUu_>Y1_2I4z|0_3h;|N*;{L^)IZ3+I3cZ2#`{XZL4!?X2) zN)Ot%jn*IR_m`KK7Z;DLtjgj2)0dxExD-al8M}6YvDfpzUa@eXMu6sTi>!b80Ma#I zjU8wGmkzAWW;>{{3#f$bgZ_)`tDo6 zy}QZw=z|^#%{MC>y zWv_z$m5{FDy4b##u~+gv{)KnRYx#dyz#eVFWu&_S6!mv=(ow)}lv2(kmmqq0E}T9V z-a~JIJUrfP;XM@A(Y7(I_mFjkv4njKi?Daginxckof7wuTLu)$w+G}WULjGVr=$e+ zh2%vk!4Dz%iX-_3{0Bjp6DP9!?s)L76L|-4no!uO&^{ogXdga;%?uk}{U-asGre7u zeGvDv{x$K6lK<*oF~>d}gLB)K=O;e29;XNoMkdgHDSPATEz2)pZ-hV4F1g#{OFwu! zO1_4>f5aVtB3zdkf-6C=6=ie! zW*wpVCdsX#`5r03j~*MqUeMgu5cVKryUv`S07H78M*2#BC9u`MNFZJLau+M<_M&3c-2?1jXTJ`$ws31Z#w$Z=EwH)GLn5dyyNvAf|@Sae-+8)ZvK zVt0ke?o!BZ>QV03>|#GEhTXG@T{CO3BbNDUNvq)(rVi_^$7hi%eof_Fgl##A;$tm_?qMRkN5YZ0&w}~cslWDw?B`sp{k3Q0`FWN!=&wE7tf##N^z>pZ z?itCh^IQzKN-BQx|2dL!Ez|@zV|ndxbdNm*dD8Ma4d8(6<&bD5#{@%5oO*D^636!7 z)-}!g$*qp~5D`5%`>{1EDhQ7?=td#>6V$k18i(Lk#O)-B|vLgiJEEU|0M}e_Wwe{GY@Tc}Dnw}ArG6K2% zqts~Kk%Pe~MDijGxv}-& z+6a!d#JMKeEMTz*EwQP*XNm0$63672T=Inx z2HAv$>f@?W;j_m+4*P&=(+DkS+X^JUsS&+2dd#nmcOPiJV}0h2TYSrv(>mgBTrDX! zT({0*gH=NGvT?4@VaZ7pr$}BCoq?6Uu!EJ3rT7U$v0Bw{Pg1NZ?;B+!Cs9m}0;UL*KW2iYXHsZqWZBjHzOw=DEW4BL8Dv~KtqQPFC>4k%2Pch+3DGe{g$ zV|{6)c`nDXBh4Q+9NVj$cf{L>8)>#1z{lCmBN0uF`X#SpF43`G$770UwKBe5p?@!W z9YG_wU^irw*iLc5CT4^2xo3A6pNqBDAM)82Z;IH1)>?r}c#Q_-DZc(HH7>XuK0A{7 zh(CNE@sv+AEU&}gasu~PH~eXgl;UQ_?A|K`eBWaqhELT;R8*@*Xg1a+mt?D{5y9kH z^DENULyWc6kNRYbx9xO<>KM;jQ7syvnQ4_rBAOf>4Cm9OxQemWv2m404AJtHP+hUn zVzp@7M&Ih#==&WTt=@;_jCh#WWYPQ$YHaXG=x?N%b%tS#C&Y|NKP(tFZxQ2fG3yG) zZ=Uqg3EAg9M3)*O2cU>oHii)53jk;3F<@N2YNUdBnEXYoFZJ?CW@Xv4R@gn1OA zSEy0L)FYfrbnN)uLm|=PJ&)Xib>TTGdXLa1m-H%3lJBuXjTtV7>ue?8!}uPtJ;Dcl zvgON2yD`r3R&E7sA9__v@T12*1bZ>gVW?JbW3@c#hD?&Rrp6BshjZ=HdIN^(*tO#x z5KPP0=61!8#<#}cX8h>=LcsSub_aY4meu=$ErPX(#4R;Sm}c1Vwr}&BV`n;_klb2t za_)%FOrK%ryvEuF*lHBgnnnE;Vmxr=U^trbMYyCpJykUkm;IuBstUa#+&nsU=Uc7& z{rP6SWpOlPIGZ4SQjk35{ZpdXUsf7M&VN zOf&NMmGkZyeJ{jX^dAfFg^pNs`iwjqVrNF4mqFr~8aGVq$IRt8Hp+6p#WB9z9SiS9 z4-xNZ+>GsRdwPZA$}1n3XelKTOpFt*^h2*Cy?4s=3GuBPFqMBinIKC{<}wj01F+RY;oO^p?%xp(~6 zv5n}fAveaSxKk3nzCJ3)MW&a>?S^MepLHSmun(US(zQZQB-YBNU7<}cf5R9G{ zZie7PLcsU-`=YUD4CRq!j(Msw^~#c@OPo*Sz`f}ODnDIoDmj_`%? zk@Osu8LPm!R*WBfyW}t+9iBZ1g^yCS@ zHf>fnc6{PChvI6A%WRw}x+4 zHbH;B)zIvE6~Zh7$kaFpHEx%Bc5|(A>=@fIo8fU$=fmL?zn~i&NA&DCu&Mz$#zTSInf(y~v>xM0+&q@{q%gTok>kJadDR$Sy=MopfPCaSztmx*oavbYd z9JM({r=lFM!>~n1{0e&PPOz*SAf(yKBJoU(-7TfQ9x~oGdJ*ectol56hUM749`7ME zb4={(9Z69S_1p%qQTB647MU8wOCuKu zn@{~R7s4*q!&sIy=TGf%nw z+u%w8iC1bgFO9U#GugKLST=aNBvL4KS6J_u$o162au?UAPia zir)S3(YwPo!NX!3ule327%LwVETklYsj<5>qXHpo^?+k%R2-57!$besaBFjt72{zs z>1%RwH6=%p0DYa%rmp}4TasBx@UanK_gPh!v6WJRoNlPxKUU~2p> ztw!5Kx*nB?U5&P{2%f>a&1ZEER=Iw9QsANv9U+;%8Z9oB?lyvJnZsNX*(sveL~LN2 zcRQl@9*b=C3QNSg8}^wV(c@H`1_+S0vq(IXBYJ68J%Zmh;)eb9m|67)6whlW7Saut zaU>l#GlJ1JtA13P%DW)jauUVVm|luY^J~*aajeJuZb5N5%Vy{D$ppK99kIytxU^My z8)8RHVwf7qOKXD9WjJW z_ztfa58_7!w;T3isoh??Q27zYvv`tQ0wb}OSW{w7GH@sI&8)Z!4;>~)?;_W zpTY|PQbol*e3g*G?qO;yF!c)gC1|t2vAx1~7zqnmy1Z;QX_yX z;k=?3;3Dp{67p$rp)cBZ?0ia|pT}bmCwZ<}Pe%YT-WAg;yjgRrVqazn`))9N1HaF0 z`+HnU@T12*4ts5X!$$CkZc-reO^pMtgrgpbZ{t(MM!4T@_|D7eWROp?jeI;D75v(F z;eD%bLyTcF{>3pN;QJnX96k--UL*K)2iYXHsWHLiFY{~S*?4WcWBuj*g6;KbQ4FeK z(Gj16?l0?#+Z0RoH$?gW@b~``<3rC+*#Lrme*r>_%isDf* z?#_B!^r#8EBnT_+T45=oaC?Xv?Mv%lG+F6oE`(j|`WJ6A+;+r+ps#;{%m&1QfW#{` z%9m!l&E+-L`@K%^THqUBvW;q1*L!m_;qQUQ4ve3hwy;H-+u2ew#=NeojX zcZuO$W%wGKVRS9_EW^C=A;VHkVwf7OOAPNS!&lo3kG5tTdzN8d`H*2LCNWHo&?Rpe zA>J)t;!QTgIA+=zh9kY-7-ATiL@+fvm#i>Cwrd1mWf43WRkQBQnWvAlaaKj; z11qe=6owC`NL>?~!90ocJ3QYM8>zd}Fx-)z96eHp>;}US#7NyiYNReb)6vAWjx5JM z)A2^hYdM?b^$AeOWA3X-k%c%IBhq2ul^Kf_dNLHO1)k{{L zUn}qK(A39T_1AmUqd7;j4%U6|T6Mb-8ZmbjNPJUce(4?7bNR;6sTiyNI*;$-d{waJ*e@%WP|6j8*77K zBiJ2Gi@Yvo)4{Bsc7$KL4R$JT+h8w)WP_}OGU?o*?Fhr^M& z^jxW#i5%+-zsljcD|Q%Xv*KoEA**pZl=j%2uotuHCC9EI7621H;XXP37d{t~$Tj4~ zdJwOa9CZdy^3GeUIG^pORc&amVmV3CZ44BY)}nQr_}yW5luk!)21% ze4NdSI-9O7{1`&XDsNM4OGyM%V|HmQm|vGRf@A&PR|tahL0xXch+0SJrH=*cires7LK3^w zcwAarWiGq1Gd3?_#bjDRfO)vq5pGE{Hch1^v$lZ5D>?3##u^aV-Lkd&*xFiLECikxPxbB}==jmbS;qEjRNsUGWe|mKF&Wm9~&o0ury}=vo>Z zn`dcb$Ho>oukbh-ylM!`?S`c#jg29*vf>uBT0)|h8e2OQjwXB>ek^yIHGES1pkB0Z zSQ^Xo^M3b(S;M>i1QO%a@@H{6LM-05xS3Ie>xF>td+dGinIW= mca_nr_cards) + return 0xff; + if (!mca_card_read[mca_index]) + return 0xff; + return mca_card_read[mca_index](port, mca_priv[mca_index]); +} + +void mca_write(uint16_t port, uint8_t val) +{ + if (mca_index >= mca_nr_cards) + return; + if (mca_card_write[mca_index]) + mca_card_write[mca_index](port, val, mca_priv[mca_index]); +} + +void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void *priv) +{ + int c; + + for (c = 0; c < mca_nr_cards; c++) + { + if (!mca_card_read[c] && !mca_card_write[c]) + { + mca_card_read[c] = read; + mca_card_write[c] = write; + mca_priv[c] = priv; + return; + } + } +} diff --git a/src/mca.h b/src/mca.h new file mode 100644 index 000000000..90d7f07ef --- /dev/null +++ b/src/mca.h @@ -0,0 +1,5 @@ +void mca_init(int nr_cards); +void mca_add(uint8_t (*read)(int addr, void *priv), void (*write)(int addr, uint8_t val, void *priv), void *priv); +void mca_set_index(int index); +uint8_t mca_read(uint16_t port); +void mca_write(uint16_t port, uint8_t val); diff --git a/src/mcr.c b/src/mcr.c index 32f67fd63..1cc47f441 100644 --- a/src/mcr.c +++ b/src/mcr.c @@ -21,12 +21,6 @@ void writemcr(uint16_t addr, uint8_t val) case 0x22: if (val==6 && mcr22==6) nextreg6=1; else nextreg6=0; -// if ((val&1) && (mcr22&1)) shadowbios=1; -// if (!(val&1) && !(mcr22&1)) shadowbios=0; -// if (!mcrfirst) shadowbios=val&1; -// mcrfirst=0; -// dumpregs(); -// exit(-1); break; case 0x23: if (nextreg6) shadowbios=!val; diff --git a/src/mem.c b/src/mem.c index 1f5ec3836..a48b6217d 100644 --- a/src/mem.c +++ b/src/mem.c @@ -13,6 +13,7 @@ #include "ibm.h" #include "config.h" +#include "io.h" #include "mem.h" #include "video.h" #include "x86.h" @@ -39,7 +40,7 @@ static int _mem_state[0x40000]; static mem_mapping_t base_mapping; mem_mapping_t ram_low_mapping; -static mem_mapping_t ram_high_mapping; +mem_mapping_t ram_high_mapping; static mem_mapping_t ram_mid_mapping; static mem_mapping_t ram_remapped_mapping; mem_mapping_t bios_mapping[8]; @@ -69,7 +70,6 @@ static void mem_load_atide115_bios() FILE *f; f=romfopen("roms/ide_at_1_1_5.bin","rb"); -// is486=0; if (f) { fread(romext,16384,1,f); @@ -355,7 +355,6 @@ int loadbios() fclose(f); return 1;*/ case ROM_AMI386SX: -// f=romfopen("roms/at386/at386.bin","rb"); f=romfopen("roms/ami386/ami386.bin","rb"); if (!f) break; fread(rom,65536,1,f); @@ -394,7 +393,6 @@ int loadbios() if (!f) break; fread(rom,65536,1,f); fclose(f); -// memset(romext,0x63,0x8000); return 1; case ROM_AWARD286: @@ -405,18 +403,15 @@ int loadbios() return 1; case ROM_EUROPC: -// return 0; f=romfopen("roms/europc/50145","rb"); if (!f) break; fread(rom+0x8000,32768,1,f); fclose(f); -// memset(romext,0x63,0x8000); return 1; case ROM_IBMPC: f=romfopen("roms/ibmpc/pc102782.bin","rb"); if (!f) break; -// f=fopen("pc081682.bin","rb"); fread(rom+0xE000,8192,1,f); fclose(f); f=romfopen("roms/ibmpc/basicc11.f6","rb"); @@ -458,31 +453,18 @@ int loadbios() if (!f) break; fread(rom,65536,1,f); fclose(f); - //is486=1; return 1; case ROM_WIN486: -// f=romfopen("roms/win486/win486.bin","rb"); f=romfopen("roms/win486/ALI1429G.AMW","rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); - //is486=1; return 1; -#if 0 - case ROM_PCI486: - f=romfopen("roms/hot-433/hot-433.ami","rb"); - if (!f) break; - fread(rom, 0x20000, 1, f); - fclose(f); - biosmask = 0x1ffff; - //is486=1; - return 1; -#endif - case ROM_SIS496: - f = romfopen("roms/sis496/SIS496-1.AWA", "rb"); + /* f = romfopen("roms/sis496/SIS496-1.AWA", "rb"); */ + f = romfopen("roms/sis496/SIS496_3.AWA", "rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -491,15 +473,11 @@ int loadbios() return 1; case ROM_430VX: -// f = romfopen("roms/430vx/Ga586atv.bin", "rb"); -// f = fopen("roms/430vx/vx29.BIN", "rb"); f = romfopen("roms/430vx/55XWUQ0E.BIN", "rb"); -// f=romfopen("roms/430vx/430vx","rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; return 1; case ROM_REVENGE: @@ -514,7 +492,6 @@ int loadbios() fread(rom, 0xc000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; return 1; case ROM_ENDEAVOR: f = romfopen("roms/endeavor/1006CB0_.BIO", "rb"); @@ -528,31 +505,14 @@ int loadbios() fread(rom, 0xd000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; return 1; case ROM_IBMPS1_2011: -#if 0 - f=romfopen("roms/ibmps1es/ibm_1057757_24-05-90.bin","rb"); - ff=romfopen("roms/ibmps1es/ibm_1057757_29-15-90.bin","rb"); - fseek(f, 0x10000, SEEK_SET); - fseek(ff, 0x10000, SEEK_SET); - if (!f || !ff) break; - for (c = 0x0000; c < 0x20000; c += 2) - { - rom[c] = getc(f); - rom[c+1] = getc(ff); - } - fclose(ff); - fclose(f); -#endif -//#if 0 f = romfopen("roms/ibmps1es/f80000.bin", "rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); fread(rom, 0x20000, 1, f); fclose(f); -//#endif biosmask = 0x1ffff; return 1; @@ -703,7 +663,6 @@ int loadbios() fread(rom, 0xd000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; return 1; case ROM_MB500N: @@ -714,15 +673,21 @@ int loadbios() biosmask = 0x1ffff; return 1; -#if 0 - case ROM_POWERMATE_V: - f = romfopen("roms/powermate_v/BIOS.ROM", "rb"); /* Works */ + case ROM_AP53: + f = romfopen("roms/ap53/AP53R2C0.ROM", "rb"); /* Works */ + if (!f) break; + fread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_P55T2S: + f = romfopen("roms/p55t2s/S6Y08T.ROM", "rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; -#endif case ROM_P54TP4XE: f = romfopen("roms/p54tp4xe/T15I0302.AWD", "rb"); @@ -780,22 +745,13 @@ int loadbios() biosmask = 0x1ffff; return 1; -#if 0 - case ROM_MARL: - f = romfopen("roms/marl/1008DB0_.BIO", "rb"); + case ROM_S1668: + f = romfopen("roms/tpatx/S1668P.ROM", "rb"); /* Working Tyan BIOS. */ if (!f) break; - fseek(f, 0x80, SEEK_SET); - fread(rom + 0x10000, 0x10000, 1, f); - fclose(f); - f = romfopen("roms/marl/1008DB0_.BI1", "rb"); - if (!f) break; - fseek(f, 0x80, SEEK_SET); - fread(rom, 0xd000, 1, f); + fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; return 1; -#endif case ROM_THOR: f = romfopen("roms/thor/1006CN0_.BIO", "rb"); @@ -809,7 +765,6 @@ int loadbios() fread(rom, 0x10000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; return 1; case ROM_MRTHOR: @@ -832,7 +787,58 @@ int loadbios() fread(rom, 0x10000, 1, f); fclose(f); biosmask = 0x1ffff; - //is486=1; + return 1; + + case ROM_IBMPS2_M50: + f=romfopen("roms/i8550021/90x7423.zm14","rb"); + ff=romfopen("roms/i8550021/90x7426.zm16","rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x10000; c += 2) + { + rom[c] = getc(f); + rom[c+1] = getc(ff); + } + fclose(ff); + fclose(f); + f=romfopen("roms/i8550021/90x7420.zm13","rb"); + ff=romfopen("roms/i8550021/90x7429.zm18","rb"); + if (!f || !ff) break; + for (c = 0x10000; c < 0x20000; c += 2) + { + rom[c] = getc(f); + rom[c+1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_IBMPS2_M55SX: + f=romfopen("roms/i8555081/33f8146.zm41","rb"); + ff=romfopen("roms/i8555081/33f8145.zm40","rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x20000; c += 2) + { + rom[c] = getc(f); + rom[c+1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; + return 1; + + case ROM_IBMPS2_M80: + f=romfopen("roms/i8580111/15f6637.bin","rb"); + ff=romfopen("roms/i8580111/15f6639.bin","rb"); + if (!f || !ff) break; + for (c = 0x0000; c < 0x20000; c += 2) + { + rom[c] = getc(f); + rom[c+1] = getc(ff); + } + fclose(ff); + fclose(f); + biosmask = 0x1ffff; return 1; } printf("Failed to load ROM!\n"); @@ -846,7 +852,6 @@ int loadbios() void resetreadlookup() { int c; -// /*if (output) */pclog("resetreadlookup\n"); memset(readlookup2,0xFF,1024*1024*sizeof(uintptr_t)); for (c=0;c<256;c++) readlookup[c]=0xFFFFFFFF; readlnext=0; @@ -855,8 +860,6 @@ void resetreadlookup() for (c=0;c<256;c++) writelookup[c]=0xFFFFFFFF; writelnext=0; pccache=0xFFFFFFFF; -// readlnum=writelnum=0; - } int mmuflush=0; @@ -865,12 +868,6 @@ int mmu_perm=4; void flushmmucache() { int c; -// /*if (output) */pclog("flushmmucache\n"); -/* for (c=0;c<16;c++) - { - if ( readlookup2[0xE0+c]!=0xFFFFFFFF) pclog("RL2 %02X = %08X\n",0xE0+c, readlookup2[0xE0+c]); - if (writelookup2[0xE0+c]!=0xFFFFFFFF) pclog("WL2 %02X = %08X\n",0xE0+c,writelookup2[0xE0+c]); - }*/ for (c=0;c<256;c++) { if (readlookup[c]!=0xFFFFFFFF) @@ -886,31 +883,9 @@ void flushmmucache() } } mmuflush++; -// readlnum=writelnum=0; pccache=(uint32_t)0xFFFFFFFF; pccache2=(uint8_t *)0xFFFFFFFF; -// memset(readlookup,0xFF,sizeof(readlookup)); -// memset(readlookup2,0xFF,1024*1024*4); -// memset(writelookup,0xFF,sizeof(writelookup)); -// memset(writelookup2,0xFF,1024*1024*4); -/* if (!(cr0>>31)) return;*/ - -/* for (c = 0; c < 1024*1024; c++) - { - if (readlookup2[c] != 0xFFFFFFFF) - { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); - } - if (writelookup2[c] != 0xFFFFFFFF) - { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); - } - }*/ codegen_flush(); } @@ -936,43 +911,26 @@ void flushmmucache_nopc() void flushmmucache_cr3() { int c; -// /*if (output) */pclog("flushmmucache_cr3\n"); for (c=0;c<256;c++) { - if (readlookup[c]!=0xFFFFFFFF)// && !readlookupp[c]) + if (readlookup[c]!=0xFFFFFFFF) { readlookup2[readlookup[c]] = -1; readlookup[c]=0xFFFFFFFF; } - if (writelookup[c] != 0xFFFFFFFF)// && !writelookupp[c]) + if (writelookup[c] != 0xFFFFFFFF) { page_lookup[writelookup[c]] = NULL; writelookup2[writelookup[c]] = -1; writelookup[c] = 0xFFFFFFFF; } } -/* for (c = 0; c < 1024*1024; c++) - { - if (readlookup2[c] != 0xFFFFFFFF) - { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); - } - if (writelookup2[c] != 0xFFFFFFFF) - { - pclog("Readlookup inconsistency - %05X %08X\n", c, readlookup2[c]); - dumpregs(); - exit(-1); - } - }*/ } void mem_flush_write_page(uint32_t addr, uint32_t virt) { int c; page_t *page_target = &pages[addr >> 12]; -// pclog("mem_flush_write_page %08x %08x\n", virt, addr); for (c = 0; c < 256; c++) { @@ -980,11 +938,8 @@ void mem_flush_write_page(uint32_t addr, uint32_t virt) { uintptr_t target = (uintptr_t)&ram[(uintptr_t)(addr & ~0xfff) - (virt & ~0xfff)]; -// if ((virt & ~0xfff) == 0xc022e000) -// pclog(" Checking %02x %p %p\n", (void *)writelookup2[writelookup[c]], (void *)target); if (writelookup2[writelookup[c]] == target || page_lookup[writelookup[c]] == page_target) { -// pclog(" throw out %02x %p %p\n", writelookup[c], (void *)page_lookup[writelookup[c]], (void *)writelookup2[writelookup[c]]); writelookup2[writelookup[c]] = -1; page_lookup[writelookup[c]] = NULL; writelookup[c] = 0xffffffff; @@ -1029,7 +984,6 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_ if (!(flags & 1)) { - // pclog("Trying to read or write a page that is not present!\n"); is_page_fault = 1; } @@ -1037,12 +991,10 @@ int mmu_page_fault_check(uint32_t addr, int rw, uint32_t flags, int pde, int is_ { if (!(flags & 4) && mem_cpl3_check()) { - // pclog("Trying to read a system page from user mode!\n"); is_page_fault = 1; } if (rw && !(flags & 2) && (mem_cpl3_check() || (cr0 & WP_FLAG))) { - // pclog("Trying to write a read-only-for-user page from user mode!\n"); is_page_fault = 1; } } @@ -1124,25 +1076,16 @@ uint32_t mmutranslate_noabrt(uint32_t addr, int rw) void mmu_invalidate(uint32_t addr) { -// readlookup2[addr >> 12] = writelookup2[addr >> 12] = 0xFFFFFFFF; flushmmucache_cr3(); } void addreadlookup(uint32_t virt, uint32_t phys) { -// return; -// printf("Addreadlookup %08X %08X %08X %08X %08X %08X %02X %08X\n",virt,phys,cs,ds,es,ss,opcode,cpu_state.pc); if (virt == 0xffffffff) return; if (readlookup2[virt>>12] != -1) { -/* if (readlookup2[virt>>12] != phys&~0xfff) - { - pclog("addreadlookup mismatch - %05X000 %05X000\n", readlookup[readlnext], virt >> 12); - dumpregs(); - exit(-1); - }*/ return; } @@ -1150,7 +1093,6 @@ void addreadlookup(uint32_t virt, uint32_t phys) if (readlookup[readlnext]!=0xFFFFFFFF) { readlookup2[readlookup[readlnext]] = -1; -// readlnum--; } readlookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; readlookupp[readlnext]=mmu_perm; @@ -1162,19 +1104,11 @@ void addreadlookup(uint32_t virt, uint32_t phys) void addwritelookup(uint32_t virt, uint32_t phys) { -// return; -// printf("Addwritelookup %08X %08X\n",virt,phys); if (virt == 0xffffffff) return; if (page_lookup[virt >> 12]) { -/* if (writelookup2[virt>>12] != phys&~0xfff) - { - pclog("addwritelookup mismatch - %05X000 %05X000\n", readlookup[readlnext], virt >> 12); - dumpregs(); - exit(-1); - }*/ return; } @@ -1182,16 +1116,12 @@ void addwritelookup(uint32_t virt, uint32_t phys) { page_lookup[writelookup[writelnext]] = NULL; writelookup2[writelookup[writelnext]] = -1; -// writelnum--; } -// if (page_lookup[virt >> 12] && (writelookup2[virt>>12] != 0xffffffff)) -// fatal("Bad write mapping\n"); if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) - page_lookup[virt >> 12] = &pages[phys >> 12];//(uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; + page_lookup[virt >> 12] = &pages[phys >> 12]; else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; -// pclog("addwritelookup %08x %08x %p %p %016llx %p\n", virt, phys, (void *)page_lookup[virt >> 12], (void *)writelookup2[virt >> 12], pages[phys >> 12].dirty_mask, (void *)&pages[phys >> 12]); writelookupp[writelnext] = mmu_perm; writelookup[writelnext++] = virt >> 12; writelnext &= (cachesize - 1); @@ -1255,7 +1185,6 @@ uint8_t readmembl(uint32_t addr) addr &= rammask; if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); -// pclog("Bad readmembl %08X %04X:%08X\n", addr, CS, pc); return 0xFF; } @@ -1282,7 +1211,6 @@ void writemembl(uint32_t addr, uint8_t val) addr &= rammask; if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -// else pclog("Bad writemembl %08X %02X %04X:%08X\n", addr, val, CS, pc); } uint8_t readmemb386l(uint32_t seg, uint32_t addr) @@ -1290,14 +1218,9 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! rb %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return -1; } mem_logical_addr = addr = addr + seg; -/* if (readlookup2[mem_logical_addr >> 12] != 0xFFFFFFFF) - { - return ram[readlookup2[mem_logical_addr >> 12] + (mem_logical_addr & 0xFFF)]; - }*/ if (addr < 0x100000 && ram_mapped_addr[addr >> 14]) { addr = (ram_mapped_addr[addr >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr : (ram_mapped_addr[addr >> 14] & ~0x3FFF) + (addr & 0x3FFF); @@ -1314,7 +1237,6 @@ uint8_t readmemb386l(uint32_t seg, uint32_t addr) addr &= rammask; if (_mem_read_b[addr >> 14]) return _mem_read_b[addr >> 14](addr, _mem_priv_r[addr >> 14]); -// pclog("Bad readmemb386l %08X %04X:%08X\n", addr, CS, pc); return 0xFF; } @@ -1323,7 +1245,6 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! wb %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } @@ -1347,11 +1268,7 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) addr &= rammask; -/* if (addr >= 0xa0000 && addr < 0xc0000) - pclog("writemembl %08X %02X\n", addr, val);*/ - if (_mem_write_b[addr >> 14]) _mem_write_b[addr >> 14](addr, val, _mem_priv_w[addr >> 14]); -// else pclog("Bad writememb386l %08X %02X %04X:%08X\n", addr, val, CS, pc); } uint16_t readmemwl(uint32_t seg, uint32_t addr) @@ -1374,7 +1291,6 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! rw %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return -1; } if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) @@ -1398,7 +1314,6 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) if (AT) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(addr2 + 1) >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8); else return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[(seg + ((addr + 1) & 0xffff)) >> 14](seg + ((addr + 1) & 0xffff), _mem_priv_r[addr2 >> 14]) << 8); } -// pclog("Bad readmemwl %08X\n", addr2); return 0xffff; } @@ -1434,7 +1349,6 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! ww %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) @@ -1471,7 +1385,6 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) _mem_write_b[(addr2 + 1) >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); return; } -// pclog("Bad writememwl %08X %04X\n", addr2, val); } uint32_t readmemll(uint32_t seg, uint32_t addr) @@ -1494,7 +1407,6 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return -1; } @@ -1518,7 +1430,6 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) if (_mem_read_b[addr2 >> 14]) return _mem_read_b[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | (_mem_read_b[addr2 >> 14](addr2 + 1, _mem_priv_r[addr2 >> 14]) << 8) | (_mem_read_b[addr2 >> 14](addr2 + 2, _mem_priv_r[addr2 >> 14]) << 16) | (_mem_read_b[addr2 >> 14](addr2 + 3, _mem_priv_r[addr2 >> 14]) << 24); -// pclog("Bad readmemll %08X\n", addr2); return 0xffffffff; } @@ -1540,7 +1451,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) @@ -1562,9 +1472,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) addr2&=rammask; -/* if (addr >= 0xa0000 && addr < 0xc0000) - pclog("writememll %08X %08X\n", addr, val);*/ - if (_mem_write_l[addr2 >> 14]) { _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); @@ -1584,7 +1491,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); return; } -// pclog("Bad writememll %08X %08X\n", addr2, val); } uint64_t readmemql(uint32_t seg, uint32_t addr) @@ -1603,7 +1509,6 @@ uint64_t readmemql(uint32_t seg, uint32_t addr) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return -1; } @@ -1646,7 +1551,6 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) if (seg==-1) { x86gpf("NULL segment", 0); - // printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,cpu_state.pc,opcode,addr); return; } if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) @@ -1695,7 +1599,6 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]); return; } -// pclog("Bad writememql %08X %08X\n", addr2, val); } uint8_t mem_readb_phys(uint32_t addr) @@ -1736,19 +1639,16 @@ void mem_writew_phys(uint32_t addr, uint16_t val) uint8_t mem_read_ram(uint32_t addr, void *priv) { -// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMb %08X\n", addr); addreadlookup(mem_logical_addr, addr); return ram[addr]; } uint16_t mem_read_ramw(uint32_t addr, void *priv) { -// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMw %08X\n", addr); addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; } uint32_t mem_read_raml(uint32_t addr, void *priv) { -// if (addr >= 0xc0000 && addr < 0x0c8000) pclog("Read RAMl %08X\n", addr); addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; } @@ -1758,7 +1658,6 @@ void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); -// pclog("mem_write_ramb_page: %08x %02x %08x %llx %llx\n", addr, val, cs+pc, p->dirty_mask, mask); p->dirty_mask |= mask; p->mem[addr & 0xfff] = val; } @@ -1770,7 +1669,6 @@ void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); if ((addr & 0x3f) == 0x3f) mask |= (mask << 1); -// pclog("mem_write_ramw_page: %08x %04x %08x\n", addr, val, cs+pc); p->dirty_mask |= mask; *(uint16_t *)&p->mem[addr & 0xfff] = val; } @@ -1782,7 +1680,6 @@ void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); if ((addr & 0x3f) >= 0x3d) mask |= (mask << 1); -// pclog("mem_write_raml_page: %08x %08x %08x\n", addr, val, cs+pc); p->dirty_mask |= mask; *(uint32_t *)&p->mem[addr & 0xfff] = val; } @@ -1808,21 +1705,16 @@ uint8_t mem_read_bios(uint32_t addr, void *priv) { if (AMIBIOS && (addr&0xFFFFF)==0xF8281) /*This is read constantly during AMIBIOS POST, but is never written to. It's clearly a status register of some kind, but for what?*/ { -// pclog("Read magic addr %04X(%06X):%04X\n",CS,cs,cpu_state.pc); -// if (pc==0x547D) output=3; return 0x40; } -// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, rom[addr & biosmask], CS, pc); return rom[addr & biosmask]; } uint16_t mem_read_biosw(uint32_t addr, void *priv) { -// pclog("Read BIOS %08X %04X %04X:%04X\n", addr, *(uint16_t *)&rom[addr & biosmask], CS, pc); return *(uint16_t *)&rom[addr & biosmask]; } uint32_t mem_read_biosl(uint32_t addr, void *priv) { -// pclog("Read BIOS %08X %02X %04X:%04X\n", addr, *(uint32_t *)&rom[addr & biosmask], CS, pc); return *(uint32_t *)&rom[addr & biosmask]; } @@ -1862,9 +1754,8 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) } } -static inline int mem_mapping_read_allowed(uint32_t flags, int state) +static __inline int mem_mapping_read_allowed(uint32_t flags, int state) { -// pclog("mem_mapping_read_allowed: flags=%x state=%x\n", flags, state); switch (state & MEM_READ_MASK) { case MEM_READ_ANY: @@ -1875,10 +1766,11 @@ static inline int mem_mapping_read_allowed(uint32_t flags, int state) return !(flags & MEM_MAPPING_EXTERNAL); default: fatal("mem_mapping_read_allowed : bad state %x\n", state); + return 0; } } -static inline int mem_mapping_write_allowed(uint32_t flags, int state) +static __inline int mem_mapping_write_allowed(uint32_t flags, int state) { switch (state & MEM_WRITE_MASK) { @@ -1892,6 +1784,7 @@ static inline int mem_mapping_write_allowed(uint32_t flags, int state) return !(flags & MEM_MAPPING_EXTERNAL); default: fatal("mem_mapping_write_allowed : bad state %x\n", state); + return 0; } } @@ -2061,7 +1954,6 @@ void mem_set_mem_state(uint32_t base, uint32_t size, int state) { uint32_t c; -// pclog("mem_set_pci_enable: base=%08x size=%08x\n", base, size); for (c = 0; c < size; c += 0x4000) _mem_state[(c + base) >> 14] = state; @@ -2158,7 +2050,29 @@ void mem_init() mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); -// pclog("Mem resize %i %i\n",mem_size,c); +} + +void mem_remap_top_256k() +{ + int c; + + for (c = ((mem_size * 1024) >> 12); c < (((mem_size + 256) * 1024) >> 12); c++) + { + pages[c].mem = &ram[c << 12]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } + + for (c = (mem_size / 256); c < ((mem_size + 256) / 256); c++) + { + isram[c] = 1; + if (c >= 0xa && c <= 0xd) + isram[c] = 0; + } + + mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (mem_size * 1024), MEM_MAPPING_INTERNAL, NULL); } void mem_remap_top_384k() @@ -2238,7 +2152,6 @@ void mem_resize() mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); -// pclog("Mem resize %i %i\n",mem_size,c); mem_a20_key = 2; mem_a20_recalc(); } @@ -2257,34 +2170,11 @@ void mem_reset_page_blocks() } } -/* void mem_reset() -{ - int c; - - mem_reset_page_blocks(); - - memset(isram, 0, sizeof(isram)); - for (c = 0; c < (mem_size / 256); c++) - { - isram[c] = 1; - if (c >= 0xa && c <= 0xf) - isram[c] = 0; - } - - mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); - mem_set_mem_state(0x100000, (mem_size - 1024) * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - - mem_a20_key = 2; - mem_a20_recalc(); -} */ - static int port_92_reg = 0; void mem_a20_recalc() { int state = mem_a20_key | mem_a20_alt; -// pclog("A20 recalc %i %i\n", state, mem_a20_state); if (state && !mem_a20_state) { rammask = 0xffffffff; @@ -2295,7 +2185,6 @@ void mem_a20_recalc() rammask = 0xffefffff; flushmmucache(); } -// pclog("rammask now %08X\n", rammask); mem_a20_state = state; } diff --git a/src/mem.h b/src/mem.h index 8f489411c..7e888e207 100644 --- a/src/mem.h +++ b/src/mem.h @@ -87,7 +87,9 @@ extern int mem_a20_key; void mem_a20_recalc(); uint8_t mem_readb_phys(uint32_t addr); +uint16_t mem_readw_phys(uint32_t addr); void mem_writeb_phys(uint32_t addr, uint8_t val); +void mem_writew_phys(uint32_t addr, uint16_t val); uint8_t mem_read_ram(uint32_t addr, void *priv); uint16_t mem_read_ramw(uint32_t addr, void *priv); @@ -110,6 +112,8 @@ FILE *romfopen(char *fn, char *mode); mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; +extern mem_mapping_t ram_high_mapping; + typedef struct page_t { @@ -134,7 +138,7 @@ extern page_t **page_lookup; uint32_t mmutranslate_noabrt(uint32_t addr, int rw); extern uint32_t get_phys_virt,get_phys_phys; -static inline uint32_t get_phys(uint32_t addr) +static __inline uint32_t get_phys(uint32_t addr) { if (!((addr ^ get_phys_virt) & ~0xfff)) return get_phys_phys | (addr & 0xfff); @@ -149,10 +153,10 @@ static inline uint32_t get_phys(uint32_t addr) get_phys_phys = (mmutranslatereal(addr, 0) & rammask) & ~0xfff; return get_phys_phys | (addr & 0xfff); -// return mmutranslatereal(addr, 0) & rammask; + /* return mmutranslatereal(addr, 0) & rammask; */ } -static inline uint32_t get_phys_noabrt(uint32_t addr) +static __inline uint32_t get_phys_noabrt(uint32_t addr) { if (!(cr0 >> 31)) return addr & rammask; @@ -167,11 +171,27 @@ extern uint32_t mem_logical_addr; void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p); void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p); void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p); +void mem_flush_write_page(uint32_t addr, uint32_t virt); void mem_reset_page_blocks(); extern mem_mapping_t ram_low_mapping; +void mem_remap_top_256k(); void mem_remap_top_384k(); +void flushmmucache_nopc(); + +int loadbios(); + +void mem_add_bios(); + +void mem_init(); +void mem_resize(); + +void port_92_reset(); + +void port_92_add(); +void port_92_remove(); + #endif diff --git a/src/memregs.h b/src/memregs.h index 1e3dfbcec..590aa2af2 100644 --- a/src/memregs.h +++ b/src/memregs.h @@ -2,3 +2,4 @@ see COPYING for more details */ extern void memregs_init(); +void powermate_memregs_init(); diff --git a/src/mfm_at.c b/src/mfm_at.c index a6623c92c..ebbcde2a9 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -2,6 +2,7 @@ #define _LARGEFILE64_SOURCE #define _GNU_SOURCE #include +#include #include #include #include @@ -17,7 +18,7 @@ #include "mfm_at.h" -#define IDE_TIME (TIMER_USEC*10)//(5 * 100 * (1 << TIMER_SHIFT)) +#define IDE_TIME (TIMER_USEC*10) #define STAT_ERR 0x01 #define STAT_INDEX 0x02 @@ -44,8 +45,6 @@ #define CMD_DIAGNOSE 0x90 #define CMD_SET_PARAMETERS 0x91 -extern char ide_fn[4][512]; - typedef struct mfm_drive_t { int spt, hpc; @@ -78,16 +77,15 @@ typedef struct mfm_t uint16_t mfm_readw(uint16_t port, void *p); void mfm_writew(uint16_t port, uint16_t val, void *p); -static inline void mfm_irq_raise(mfm_t *mfm) +static __inline void mfm_irq_raise(mfm_t *mfm) { -// pclog("IDE_IRQ_RAISE\n"); if (!(mfm->fdisk&2)) picint(1 << 14); mfm->irqstat=1; } -static inline void mfm_irq_lower(mfm_t *mfm) +static __inline void mfm_irq_lower(mfm_t *mfm) { picintc(1 << 14); } @@ -161,9 +159,9 @@ static void mfm_next_sector(mfm_t *mfm) } } -static void loadhd(mfm_t *mfm, int d, const char *fn) +static void loadhd(mfm_t *mfm, int c, int d, const char *fn) { - mfm_drive_t *drive = &mfm->drives[d]; + mfm_drive_t *drive = &mfm->drives[c]; if (drive->hdfile == NULL) { @@ -205,7 +203,6 @@ void mfm_write(uint16_t port, uint8_t val, void *p) { mfm_t *mfm = (mfm_t *)p; -// pclog("mfm_write: addr=%04x val=%02x\n", port, val); switch (port) { case 0x1F0: /* Data */ @@ -252,7 +249,6 @@ void mfm_write(uint16_t port, uint8_t val, void *p) switch (val & 0xf0) { case CMD_RESTORE: -// pclog("Restore\n"); mfm->command &= ~0x0f; /*Mask off step rate*/ mfm->status = STAT_BUSY; timer_process(); @@ -261,7 +257,6 @@ void mfm_write(uint16_t port, uint8_t val, void *p) break; case CMD_SEEK: -// pclog("Seek to cylinder %i\n", mfm->cylinder); mfm->command &= ~0x0f; /*Mask off step rate*/ mfm->status = STAT_BUSY; timer_process(); @@ -274,7 +269,6 @@ void mfm_write(uint16_t port, uint8_t val, void *p) { case CMD_READ: case CMD_READ+1: case CMD_READ+2: case CMD_READ+3: -// pclog("Read %i sectors from sector %i cylinder %i head %i %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head,ins); mfm->command &= ~3; if (val & 2) fatal("Read with ECC\n"); @@ -286,16 +280,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p) case CMD_WRITE: case CMD_WRITE+1: case CMD_WRITE+2: case CMD_WRITE+3: -// pclog("Write %i sectors to sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); mfm->command &= ~3; if (val & 2) fatal("Write with ECC\n"); - mfm->status = STAT_DRQ | STAT_DSC;// | STAT_BUSY; + mfm->status = STAT_DRQ | STAT_DSC; mfm->pos=0; break; case CMD_VERIFY: case CMD_VERIFY+1: -// pclog("Read verify %i sectors from sector %i cylinder %i head %i\n",mfm->secount,mfm->sector,mfm->cylinder,mfm->head); mfm->command &= ~1; mfm->status = STAT_BUSY; timer_process(); @@ -304,7 +296,6 @@ void mfm_write(uint16_t port, uint8_t val, void *p) break; case CMD_FORMAT: -// pclog("Format track %i head %i\n", mfm->cylinder, mfm->head); mfm->status = STAT_DRQ | STAT_BUSY; mfm->pos=0; break; @@ -342,7 +333,6 @@ void mfm_write(uint16_t port, uint8_t val, void *p) timer_update_outstanding(); mfm->reset = 1; mfm->status = STAT_BUSY; -// pclog("MFM Reset\n"); } if (val & 4) { @@ -356,14 +346,12 @@ void mfm_write(uint16_t port, uint8_t val, void *p) mfm_irq_update(mfm); return; } -// fatal("Bad IDE write %04X %02X\n", addr, val); } void mfm_writew(uint16_t port, uint16_t val, void *p) { mfm_t *mfm = (mfm_t *)p; -// pclog("Write IDEw %04X\n",val); mfm->buffer[mfm->pos >> 1] = val; mfm->pos += 2; @@ -416,9 +404,12 @@ uint8_t mfm_read(uint16_t port, void *p) mfm_irq_lower(mfm); temp = mfm->status; break; + + default: + temp = 0xff; + break; } -// pclog("mfm_read: addr=%04x val=%02x %04X:%04x\n", port, temp, CS, cpu_state.pc); return temp; } @@ -432,7 +423,6 @@ uint16_t mfm_readw(uint16_t port, void *p) if (mfm->pos >= 512) { -// pclog("Over! packlen %i %i\n",ide->packlen,ide->pos); mfm->pos=0; mfm->status = STAT_READY | STAT_DSC; if (mfm->command == CMD_READ) @@ -446,10 +436,13 @@ uint16_t mfm_readw(uint16_t port, void *p) mfm->callback = 6*IDE_TIME; timer_update_outstanding(); } + else + { + update_status_bar_icon(0x20, 0); + } } } -// pclog("mem_readw: temp=%04x %i\n", temp, mfm->pos); return temp; } @@ -470,7 +463,6 @@ void mfm_callback(void *p) off64_t addr; int c; -// pclog("mfm_callback: command=%02x reset=%i\n", mfm->command, mfm->reset); mfm->callback = 0; if (mfm->reset) { @@ -481,7 +473,6 @@ void mfm_callback(void *p) mfm->head = 0; mfm->cylinder = 0; mfm->reset = 0; -// pclog("Reset callback\n"); return; } switch (mfm->command) @@ -508,15 +499,12 @@ void mfm_callback(void *p) break; } -// pclog("Read %i %i %i %08X\n",ide.cylinder,ide.head,ide.sector,addr); fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(mfm->buffer, 512, 1, drive->hdfile); mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; -// pclog("Read sector callback %i %i %i offset %08X %i left %i %02X\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount,ide.spt,ide.atastat[ide.board]); -// if (addr) output=3; mfm_irq_raise(mfm); - readflash = 1; + update_status_bar_icon(0x20, 1); break; case CMD_WRITE: @@ -537,19 +525,21 @@ void mfm_callback(void *p) mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm->pos = 0; mfm_next_sector(mfm); + update_status_bar_icon(0x20, 1); } else + { mfm->status = STAT_READY | STAT_DSC; - readflash = 1; + update_status_bar_icon(0x20, 0); + } break; case CMD_VERIFY: do_seek(mfm); mfm->pos = 0; mfm->status = STAT_READY | STAT_DSC; -// pclog("Read verify callback %i %i %i offset %08X %i left\n",ide.sector,ide.cylinder,ide.head,addr,ide.secount); mfm_irq_raise(mfm); - readflash=1; + update_status_bar_icon(0x20, 1); break; case CMD_FORMAT: @@ -569,7 +559,7 @@ void mfm_callback(void *p) } mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - readflash = 1; + update_status_bar_icon(0x20, 1); break; case CMD_DIAGNOSE: @@ -597,11 +587,21 @@ void mfm_callback(void *p) void *mfm_init() { + int c, d; + mfm_t *mfm = malloc(sizeof(mfm_t)); memset(mfm, 0, sizeof(mfm_t)); - loadhd(mfm, 0, ide_fn[0]); - loadhd(mfm, 1, ide_fn[1]); + c = 0; + for (d = 0; d < HDC_NUM; d++) + { + if ((hdc[d].bus == 1) && (hdc[d].mfm_channel < MFM_NUM)) + { + loadhd(mfm, hdc[d].mfm_channel, d, hdd_fn[d]); + c++; + if (c >= MFM_NUM) break; + } + } mfm->status = STAT_READY | STAT_DSC; mfm->error = 1; /*No errors*/ diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c new file mode 100644 index 000000000..eac421b0a --- /dev/null +++ b/src/mfm_xebec.c @@ -0,0 +1,950 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include +#include "ibm.h" + +#include "device.h" +#include "dma.h" +#include "io.h" +#include "mem.h" +#include "pic.h" +#include "rom.h" +#include "timer.h" + +#include "mfm_xebec.h" + +#define XEBEC_TIME (2000 * TIMER_USEC) + +enum +{ + STATE_IDLE, + STATE_RECEIVE_COMMAND, + STATE_START_COMMAND, + STATE_RECEIVE_DATA, + STATE_RECEIVED_DATA, + STATE_SEND_DATA, + STATE_SENT_DATA, + STATE_COMPLETION_BYTE, + STATE_DUNNO +}; + +typedef struct mfm_drive_t +{ + int spt, hpc; + int tracks; + int cfg_spt; + int cfg_hpc; + int cfg_cyl; + int current_cylinder; + FILE *hdfile; +} mfm_drive_t; + +typedef struct xebec_t +{ + rom_t bios_rom; + + int callback; + + int state; + + uint8_t status; + + uint8_t command[6]; + int command_pos; + + uint8_t data[512]; + int data_pos, data_len; + + uint8_t sector_buf[512]; + + uint8_t irq_dma_mask; + + uint8_t completion_byte; + uint8_t error; + + int drive_sel; + + mfm_drive_t drives[2]; + + int sector, head, cylinder; + int sector_count; + + uint8_t switches; +} xebec_t; + +#define STAT_IRQ 0x20 +#define STAT_DRQ 0x10 +#define STAT_BSY 0x08 +#define STAT_CD 0x04 +#define STAT_IO 0x02 +#define STAT_REQ 0x01 + +#define IRQ_ENA 0x02 +#define DMA_ENA 0x01 + +#define CMD_TEST_DRIVE_READY 0x00 +#define CMD_RECALIBRATE 0x01 +#define CMD_READ_STATUS 0x03 +#define CMD_VERIFY_SECTORS 0x05 +#define CMD_FORMAT_TRACK 0x06 +#define CMD_READ_SECTORS 0x08 +#define CMD_WRITE_SECTORS 0x0a +#define CMD_SEEK 0x0b +#define CMD_INIT_DRIVE_PARAMS 0x0c +#define CMD_WRITE_SECTOR_BUFFER 0x0f +#define CMD_BUFFER_DIAGNOSTIC 0xe0 +#define CMD_CONTROLLER_DIAGNOSTIC 0xe4 +#define CMD_DTC_GET_DRIVE_PARAMS 0xfb +#define CMD_DTC_SET_STEP_RATE 0xfc +#define CMD_DTC_SET_GEOMETRY 0xfe +#define CMD_DTC_GET_GEOMETRY 0xff + +#define ERR_NOT_READY 0x04 +#define ERR_SEEK_ERROR 0x15 +#define ERR_ILLEGAL_SECTOR_ADDRESS 0x21 + +static uint8_t xebec_read(uint16_t port, void *p) +{ + xebec_t *xebec = (xebec_t *)p; + uint8_t temp = 0xff; + + switch (port) + { + case 0x320: /*Read data*/ + xebec->status &= ~STAT_IRQ; + switch (xebec->state) + { + case STATE_COMPLETION_BYTE: + if ((xebec->status & 0xf) != (STAT_CD | STAT_IO | STAT_REQ | STAT_BSY)) + fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); + + temp = xebec->completion_byte; + xebec->status = 0; + xebec->state = STATE_IDLE; + break; + + case STATE_SEND_DATA: + if ((xebec->status & 0xf) != (STAT_IO | STAT_REQ | STAT_BSY)) + fatal("Read data STATE_COMPLETION_BYTE, status=%02x\n", xebec->status); + if (xebec->data_pos >= xebec->data_len) + fatal("Data write with full data!\n"); + temp = xebec->data[xebec->data_pos++]; + if (xebec->data_pos == xebec->data_len) + { + xebec->status = STAT_BSY; + xebec->state = STATE_SENT_DATA; + xebec->callback = XEBEC_TIME; + } + break; + + default: + fatal("Read data register - %i, %02x\n", xebec->state, xebec->status); + } + break; + + case 0x321: /*Read status*/ + temp = xebec->status; + break; + + case 0x322: /*Read option jumpers*/ + temp = xebec->switches; + break; + } + + return temp; +} + +static void xebec_write(uint16_t port, uint8_t val, void *p) +{ + xebec_t *xebec = (xebec_t *)p; + + switch (port) + { + case 0x320: /*Write data*/ + switch (xebec->state) + { + case STATE_RECEIVE_COMMAND: + if ((xebec->status & 0xf) != (STAT_BSY | STAT_CD | STAT_REQ)) + fatal("Bad write data state - STATE_START_COMMAND, status=%02x\n", xebec->status); + if (xebec->command_pos >= 6) + fatal("Command write with full command!\n"); + /*Command data*/ + xebec->command[xebec->command_pos++] = val; + if (xebec->command_pos == 6) + { + xebec->status = STAT_BSY; + xebec->state = STATE_START_COMMAND; + xebec->callback = XEBEC_TIME; + } + break; + + case STATE_RECEIVE_DATA: + if ((xebec->status & 0xf) != (STAT_BSY | STAT_REQ)) + fatal("Bad write data state - STATE_RECEIVE_DATA, status=%02x\n", xebec->status); + if (xebec->data_pos >= xebec->data_len) + fatal("Data write with full data!\n"); + /*Command data*/ + xebec->data[xebec->data_pos++] = val; + if (xebec->data_pos == xebec->data_len) + { + xebec->status = STAT_BSY; + xebec->state = STATE_RECEIVED_DATA; + xebec->callback = XEBEC_TIME; + } + break; + + default: + fatal("Write data unknown state - %i %02x\n", xebec->state, xebec->status); + } + break; + + case 0x321: /*Controller reset*/ + xebec->status = 0; + break; + + case 0x322: /*Generate controller-select-pulse*/ + xebec->status = STAT_BSY | STAT_CD | STAT_REQ; + xebec->command_pos = 0; + xebec->state = STATE_RECEIVE_COMMAND; + break; + + case 0x323: /*DMA/IRQ mask register*/ + xebec->irq_dma_mask = val; + break; + } +} + +static void xebec_complete(xebec_t *xebec) +{ + xebec->status = STAT_REQ | STAT_CD | STAT_IO | STAT_BSY; + xebec->state = STATE_COMPLETION_BYTE; + if (xebec->irq_dma_mask & IRQ_ENA) + { + xebec->status |= STAT_IRQ; + picint(1 << 5); + } +} + +static void xebec_error(xebec_t *xebec, uint8_t error) +{ + xebec->completion_byte |= 0x02; + xebec->error = error; + pclog("xebec_error - %02x\n", xebec->error); +} + +static int xebec_get_sector(xebec_t *xebec, off64_t *addr) +{ + mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; + int heads = drive->cfg_hpc; + + if (drive->current_cylinder != xebec->cylinder) + { + pclog("mfm_get_sector: wrong cylinder\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + if (xebec->head > heads) + { + pclog("mfm_get_sector: past end of configured heads\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + if (xebec->head > drive->hpc) + { + pclog("mfm_get_sector: past end of heads\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + if (xebec->sector >= 17) + { + pclog("mfm_get_sector: past end of sectors\n"); + xebec->error = ERR_ILLEGAL_SECTOR_ADDRESS; + return 1; + } + + *addr = ((((off64_t) xebec->cylinder * heads) + xebec->head) * + 17) + xebec->sector; + + return 0; +} + +static void xebec_next_sector(xebec_t *xebec) +{ + mfm_drive_t *drive = &xebec->drives[xebec->drive_sel]; + + xebec->sector++; + if (xebec->sector >= 17) + { + xebec->sector = 0; + xebec->head++; + if (xebec->head >= drive->cfg_hpc) + { + xebec->head = 0; + xebec->cylinder++; + drive->current_cylinder++; + if (drive->current_cylinder >= drive->cfg_cyl) + drive->current_cylinder = drive->cfg_cyl-1; + } + } +} + +static void xebec_callback(void *p) +{ + xebec_t *xebec = (xebec_t *)p; + mfm_drive_t *drive; + + xebec->callback = 0; + + xebec->drive_sel = (xebec->command[1] & 0x20) ? 1 : 0; + xebec->completion_byte = xebec->drive_sel & 0x20; + + drive = &xebec->drives[xebec->drive_sel]; + + switch (xebec->command[0]) + { + case CMD_TEST_DRIVE_READY: + if (!drive->hdfile) + xebec_error(xebec, ERR_NOT_READY); + xebec_complete(xebec); + break; + + case CMD_RECALIBRATE: + if (!drive->hdfile) + xebec_error(xebec, ERR_NOT_READY); + else + { + xebec->cylinder = 0; + drive->current_cylinder = 0; + } + xebec_complete(xebec); + break; + + case CMD_READ_STATUS: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 4; + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + xebec->data[0] = xebec->error; + xebec->data[1] = xebec->drive_sel ? 0x20 : 0; + xebec->data[2] = xebec->data[3] = 0; + xebec->error = 0; + break; + + case STATE_SENT_DATA: + xebec_complete(xebec); + break; + } + break; + + case CMD_VERIFY_SECTORS: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + xebec->sector = xebec->command[2] & 0x1f; + xebec->sector_count = xebec->command[4]; + do + { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) + { + pclog("xebec_get_sector failed\n"); + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + xebec_next_sector(xebec); + + xebec->sector_count = (xebec->sector_count-1) & 0xff; + } while (xebec->sector_count); + + xebec_complete(xebec); + + update_status_bar_icon(0x20, 1); + break; + + default: + fatal("CMD_VERIFY_SECTORS: bad state %i\n", xebec->state); + } + break; + + case CMD_FORMAT_TRACK: + { + off64_t addr; + int c; + + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + + if (xebec_get_sector(xebec, &addr)) + { + pclog("xebec_get_sector failed\n"); + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + for (c = 0; c < 17; c++) + fwrite(xebec->sector_buf, 512, 1, drive->hdfile); + + xebec_complete(xebec); + } + break; + + case CMD_READ_SECTORS: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + xebec->sector = xebec->command[2] & 0x1f; + xebec->sector_count = xebec->command[4]; + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 512; + { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) + { + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + fread(xebec->sector_buf, 512, 1, drive->hdfile); + update_status_bar_icon(0x20, 1); + } + if (xebec->irq_dma_mask & DMA_ENA) + xebec->callback = XEBEC_TIME; + else + { + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memcpy(xebec->data, xebec->sector_buf, 512); + } + break; + + case STATE_SEND_DATA: + xebec->status = STAT_BSY; + if (xebec->irq_dma_mask & DMA_ENA) + { + for (; xebec->data_pos < 512; xebec->data_pos++) + { + int val = dma_channel_write(3, xebec->sector_buf[xebec->data_pos]); + + if (val == DMA_NODATA) + { + pclog("CMD_READ_SECTORS out of data!\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + xebec->callback = XEBEC_TIME; + return; + } + } + xebec->state = STATE_SENT_DATA; + xebec->callback = XEBEC_TIME; + } + else + fatal("Read sectors no DMA! - shouldn't get here\n"); + break; + + case STATE_SENT_DATA: + xebec_next_sector(xebec); + + xebec->data_pos = 0; + + xebec->sector_count = (xebec->sector_count-1) & 0xff; + + if (xebec->sector_count) + { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) + { + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + fread(xebec->sector_buf, 512, 1, drive->hdfile); + update_status_bar_icon(0x20, 1); + + xebec->state = STATE_SEND_DATA; + + if (xebec->irq_dma_mask & DMA_ENA) + xebec->callback = XEBEC_TIME; + else + { + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memcpy(xebec->data, xebec->sector_buf, 512); + } + } + else + { + xebec_complete(xebec); + update_status_bar_icon(0x20, 0); + } + break; + + + default: + fatal("CMD_READ_SECTORS: bad state %i\n", xebec->state); + } + break; + + case CMD_WRITE_SECTORS: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; + xebec->head = xebec->command[1] & 0x1f; + xebec->sector = xebec->command[2] & 0x1f; + xebec->sector_count = xebec->command[4]; + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 512; + if (xebec->irq_dma_mask & DMA_ENA) + xebec->callback = XEBEC_TIME; + else + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVE_DATA: + xebec->status = STAT_BSY; + if (xebec->irq_dma_mask & DMA_ENA) + { + for (; xebec->data_pos < 512; xebec->data_pos++) + { + int val = dma_channel_read(3); + + if (val == DMA_NODATA) + { + pclog("CMD_WRITE_SECTORS out of data!\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + xebec->callback = XEBEC_TIME; + return; + } + + xebec->sector_buf[xebec->data_pos] = val & 0xff; + } + + xebec->state = STATE_RECEIVED_DATA; + xebec->callback = XEBEC_TIME; + } + else + fatal("Write sectors no DMA! - should never get here\n"); + break; + + case STATE_RECEIVED_DATA: + if (!(xebec->irq_dma_mask & DMA_ENA)) + memcpy(xebec->sector_buf, xebec->data, 512); + + { + off64_t addr; + + if (xebec_get_sector(xebec, &addr)) + { + xebec_error(xebec, xebec->error); + xebec_complete(xebec); + return; + } + + fseeko64(drive->hdfile, addr * 512, SEEK_SET); + fwrite(xebec->sector_buf, 512, 1, drive->hdfile); + } + + update_status_bar_icon(0x20, 1); + + xebec_next_sector(xebec); + xebec->data_pos = 0; + xebec->sector_count = (xebec->sector_count-1) & 0xff; + + if (xebec->sector_count) + { + xebec->state = STATE_RECEIVE_DATA; + if (xebec->irq_dma_mask & DMA_ENA) + xebec->callback = XEBEC_TIME; + else + xebec->status = STAT_BSY | STAT_REQ; + } + else + xebec_complete(xebec); + break; + + default: + fatal("CMD_WRITE_SECTORS: bad state %i\n", xebec->state); + } + break; + + case CMD_SEEK: + if (!drive->hdfile) + xebec_error(xebec, ERR_NOT_READY); + else + { + int cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); + + drive->current_cylinder = (cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : cylinder; + + if (cylinder != drive->current_cylinder) + xebec_error(xebec, ERR_SEEK_ERROR); + } + xebec_complete(xebec); + break; + + case CMD_INIT_DRIVE_PARAMS: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 8; + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVED_DATA: + drive->cfg_cyl = xebec->data[1] | (xebec->data[0] << 8); + drive->cfg_hpc = xebec->data[2]; + pclog("Drive %i: cylinders=%i, heads=%i\n", xebec->drive_sel, drive->cfg_cyl, drive->cfg_hpc); + xebec_complete(xebec); + break; + + default: + fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); + } + break; + + case CMD_WRITE_SECTOR_BUFFER: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 512; + if (xebec->irq_dma_mask & DMA_ENA) + xebec->callback = XEBEC_TIME; + else + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVE_DATA: + if (xebec->irq_dma_mask & DMA_ENA) + { + xebec->status = STAT_BSY; + + for (; xebec->data_pos < 512; xebec->data_pos++) + { + int val = dma_channel_read(3); + + if (val == DMA_NODATA) + { + pclog("CMD_WRITE_SECTOR_BUFFER out of data!\n"); + xebec->status = STAT_BSY | STAT_CD | STAT_IO | STAT_REQ; + xebec->callback = XEBEC_TIME; + return; + } + + xebec->data[xebec->data_pos] = val & 0xff; + } + + xebec->state = STATE_RECEIVED_DATA; + xebec->callback = XEBEC_TIME; + } + else + fatal("CMD_WRITE_SECTOR_BUFFER - should never get here!\n"); + break; + case STATE_RECEIVED_DATA: + memcpy(xebec->sector_buf, xebec->data, 512); + xebec_complete(xebec); + break; + + default: + fatal("CMD_WRITE_SECTOR_BUFFER bad state %i\n", xebec->state); + } + break; + + case CMD_BUFFER_DIAGNOSTIC: + case CMD_CONTROLLER_DIAGNOSTIC: + xebec_complete(xebec); + break; + + case 0xfa: + xebec_complete(xebec); + break; + + case CMD_DTC_SET_STEP_RATE: + xebec_complete(xebec); + break; + + case CMD_DTC_GET_DRIVE_PARAMS: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 4; + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memset(xebec->data, 0, 4); + xebec->data[0] = drive->tracks & 0xff; + xebec->data[1] = 17 | ((drive->tracks >> 2) & 0xc0); + xebec->data[2] = drive->hpc-1; + pclog("Get drive params %02x %02x %02x %i\n", xebec->data[0], xebec->data[1], xebec->data[2], drive->tracks); + break; + + case STATE_SENT_DATA: + xebec_complete(xebec); + break; + + default: + fatal("CMD_INIT_DRIVE_PARAMS bad state %i\n", xebec->state); + } + break; + + case CMD_DTC_GET_GEOMETRY: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->state = STATE_SEND_DATA; + xebec->data_pos = 0; + xebec->data_len = 16; + xebec->status = STAT_BSY | STAT_IO | STAT_REQ; + memset(xebec->data, 0, 16); + xebec->data[0x4] = drive->tracks & 0xff; + xebec->data[0x5] = (drive->tracks >> 8) & 0xff; + xebec->data[0xa] = drive->hpc; + break; + + case STATE_SENT_DATA: + xebec_complete(xebec); + break; + } + break; + + case CMD_DTC_SET_GEOMETRY: + switch (xebec->state) + { + case STATE_START_COMMAND: + xebec->state = STATE_RECEIVE_DATA; + xebec->data_pos = 0; + xebec->data_len = 16; + xebec->status = STAT_BSY | STAT_REQ; + break; + + case STATE_RECEIVED_DATA: + /*Bit of a cheat here - we always report the actual geometry of the drive in use*/ + xebec_complete(xebec); + break; + } + break; + + default: + fatal("Unknown Xebec command - %02x %02x %02x %02x %02x %02x\n", + xebec->command[0], xebec->command[1], + xebec->command[2], xebec->command[3], + xebec->command[4], xebec->command[5]); + } +} + +static void loadhd(xebec_t *xebec, int d, const char *fn) +{ + mfm_drive_t *drive = &xebec->drives[d]; + + if (drive->hdfile == NULL) + { + /* Try to open existing hard disk image */ + drive->hdfile = fopen64(fn, "rb+"); + if (drive->hdfile == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + drive->hdfile = fopen64(fn, "wb+"); + if (drive->hdfile == NULL) + { + pclog("Cannot create file '%s': %s", + fn, strerror(errno)); + return; + } + } + else + { + /* Failed for another reason */ + pclog("Cannot open file '%s': %s", + fn, strerror(errno)); + return; + } + } + } + + drive->spt = hdc[d].spt; + drive->hpc = hdc[d].hpc; + drive->tracks = hdc[d].tracks; +} + +static struct +{ + int tracks, hpc; +} xebec_hd_types[4] = +{ + {306, 4}, /*Type 0*/ + {612, 4}, /*Type 16*/ + {615, 4}, /*Type 2*/ + {306, 8} /*Type 13*/ +}; + +static void xebec_set_switches(xebec_t *xebec) +{ + int c, d; + + xebec->switches = 0; + + for (d = 0; d < 2; d++) + { + mfm_drive_t *drive = &xebec->drives[d]; + + if (!drive->hdfile) + continue; + + for (c = 0; c < 4; c++) + { + if (drive->spt == 17 && + drive->hpc == xebec_hd_types[c].hpc && + drive->tracks == xebec_hd_types[c].tracks) + { + xebec->switches |= (c << (d ? 0 : 2)); + break; + } + } + + if (c == 4) + pclog("WARNING: Drive %c: has format not supported by Fixed Disk Adapter", d ? 'D' : 'C'); + } +} + +static void *xebec_init() +{ + int i = 0; + + xebec_t *xebec = malloc(sizeof(xebec_t)); + memset(xebec, 0, sizeof(xebec_t)); + + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == 1) + { + loadhd(xebec, hdc[i].mfm_channel, hdd_fn[i]); + } + } + + xebec_set_switches(xebec); + + rom_init(&xebec->bios_rom, "roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); + + timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec); + + return xebec; +} + +static void xebec_close(void *p) +{ + xebec_t *xebec = (xebec_t *)p; + int d; + + for (d = 0; d < 2; d++) + { + mfm_drive_t *drive = &xebec->drives[d]; + + if (drive->hdfile != NULL) + fclose(drive->hdfile); + } + + free(xebec); +} + +static int xebec_available() +{ + return rom_present("roms/ibm_xebec_62x0822_1985.bin"); +} + +device_t mfm_xebec_device = +{ + "IBM PC Fixed Disk Adapter", + 0, + xebec_init, + xebec_close, + xebec_available, + NULL, + NULL, + NULL, + NULL +}; + +static void *dtc_5150x_init() +{ + int i = 0; + + xebec_t *xebec = malloc(sizeof(xebec_t)); + memset(xebec, 0, sizeof(xebec_t)); + + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == 1) + { + loadhd(xebec, hdc[i].mfm_channel, hdd_fn[i]); + } + } + + xebec->switches = 0xff; + + xebec->drives[0].cfg_cyl = xebec->drives[0].tracks; + xebec->drives[0].cfg_hpc = xebec->drives[0].hpc; + xebec->drives[1].cfg_cyl = xebec->drives[1].tracks; + xebec->drives[1].cfg_hpc = xebec->drives[1].hpc; + + rom_init(&xebec->bios_rom, "roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + + io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); + + timer_add(xebec_callback, &xebec->callback, &xebec->callback, xebec); + + return xebec; +} +static int dtc_5150x_available() +{ + return rom_present("roms/dtc_cxd21a.bin"); +} + +device_t dtc_5150x_device = +{ + "DTC 5150X", + 0, + dtc_5150x_init, + xebec_close, + dtc_5150x_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/mfm_xebec.h b/src/mfm_xebec.h new file mode 100644 index 000000000..e6bafff17 --- /dev/null +++ b/src/mfm_xebec.h @@ -0,0 +1,2 @@ +extern device_t mfm_xebec_device; +extern device_t dtc_5150x_device; diff --git a/src/model.c b/src/model.c index fc34456dd..f92f0ea92 100644 --- a/src/model.c +++ b/src/model.c @@ -10,10 +10,10 @@ #include "mem.h" #include "model.h" #include "mouse.h" +#include "mouse_ps2.h" #include "io.h" #include "rom.h" -// #include "acer386sx.h" #include "acerm3a.h" #include "ali1429.h" #include "amstrad.h" @@ -23,6 +23,7 @@ #include "dma.h" #include "fdc.h" #include "fdc37c665.h" +#include "fdc37c669.h" #include "fdc37c932fr.h" #include "gameport.h" #include "headland.h" @@ -43,6 +44,7 @@ #include "keyboard_pcjr.h" #include "keyboard_xt.h" #include "lpt.h" +#include "mem.h" #include "memregs.h" #include "neat.h" #include "nmi.h" @@ -56,6 +58,7 @@ #include "pit.h" #include "ps1.h" #include "ps2.h" +#include "ps2_mca.h" #include "scat.h" #include "serial.h" #include "sis496.h" @@ -67,57 +70,56 @@ #include "tandy_eeprom.h" #include "tandy_rom.h" #include "um8669f.h" -// #include "um8881f.h" #include "vid_pcjr.h" #include "vid_tandy.h" #include "w83877f.h" #include "wd76c10.h" #include "xtide.h" +#include "bugger.h" -void xt_init(); -void pcjr_init(); -void tandy1k_init(); -void tandy1ksl2_init(); -void ams_init(); -void europc_init(); -void olim24_init(); -void at_init(); -void at_ide_init(); -void deskpro386_init(); -void ps1_m2011_init(); -void ps1_m2121_init(); -void ps2_m30_286_init(); -void at_neat_init(); -void at_scat_init(); -// void at_acer386sx_init(); -// void at_82335_init(); -void at_wd76c10_init(); -void at_ali1429_init(); -void at_headland_init(); -void at_opti495_init(); -// void at_um8881f_init(); -void at_sis496_init(); -void at_i430vx_init(); -void at_batman_init(); -void at_endeavor_init(); +void xt_init(); +void pcjr_init(); +void tandy1k_init(); +void tandy1ksl2_init(); +void ams_init(); +void europc_init(); +void olim24_init(); +void at_init(); +void ibm_at_init(); +void at_ide_init(); +void deskpro386_init(); +void ps1_m2011_init(); +void ps1_m2121_init(); +void ps2_m30_286_init(); +void ps2_model_50_init(); +void ps2_model_55sx_init(); +void ps2_model_80_init(); +void at_neat_init(); +void at_scat_init(); +void at_wd76c10_init(); +void at_ali1429_init(); +void at_headland_init(); +void at_opti495_init(); +void at_sis496_init(); +void at_i430vx_init(); +void at_batman_init(); +void at_endeavor_init(); -void at_dtk486_init(); -void at_r418_init(); -void at_586mc1_init(); -void at_plato_init(); -void at_mb500n_init(); -#if 0 -void at_powermate_v_init(); -#endif -void at_compaq_2000_init(); -void at_p54tp4xe_init(); -void at_acerm3a_init(); -void at_acerv35n_init(); -void at_p55t2p4_init(); -void at_p55tvp4_init(); -// void at_marl_init(); -void at_p55va_init(); -void at_i440fx_init(); +void at_dtk486_init(); +void at_r418_init(); +void at_586mc1_init(); +void at_plato_init(); +void at_mb500n_init(); +void at_p54tp4xe_init(); +void at_ap53_init(); +void at_p55t2s_init(); +void at_acerm3a_init(); +void at_acerv35n_init(); +void at_p55t2p4_init(); +void at_p55tvp4_init(); +void at_p55va_init(); +void at_i440fx_init(); +void at_s1668_init(); int model; @@ -125,72 +127,81 @@ int AMSTRAD, AT, PCI, TANDY; PCI_RESET pci_reset_handler; +int serial_enabled[2] = { 0, 0 }; +int lpt_enabled = 0, bugger_enabled = 0; + MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, - {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps2_m30_286_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_headland_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, xt_init, NULL}, + {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, + {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, + {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, + {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, + {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, + {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, ibm_at_init, NULL}, + {"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, + {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, + {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps2_m30_286_init, NULL}, + {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, + {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, + {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_headland_init, NULL}, + {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_opti495_init, NULL}, - {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_ali1429_init, NULL}, - {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_dtk486_init, NULL}, - {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_sis496_init, NULL}, - {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 256, 1, at_r418_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_batman_init, NULL}, - {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 128, 1, at_586mc1_init, NULL}, - {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 128, 1, at_mb500n_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_p54tp4xe_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_acerm3a_init, NULL}, - {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 512, 1, at_p55t2p4_init, NULL}, - {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_i430vx_init, NULL}, - {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 256, 1, at_p55tvp4_init, NULL}, - {"Award 440FX PCI", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 1024, 1, at_i440fx_init, NULL}, + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, + {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, + {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_dtk486_init, NULL}, + {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_sis496_init, NULL}, + {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_r418_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_batman_init, NULL}, + {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_586mc1_init, NULL}, + {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_plato_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, + {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_mb500n_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_endeavor_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p54tp4xe_init, NULL}, + {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_ap53_init, NULL}, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p55t2s_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_acerm3a_init, NULL}, + {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_acerv35n_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p55t2p4_init, NULL}, + {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL}, + {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL}, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55tvp4_init, NULL}, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 1024, 1, at_i440fx_init, NULL}, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 1024, 1, at_s1668_init, NULL}, {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; @@ -204,6 +215,11 @@ int model_getromset() return models[model].id; } +int model_getromset_ex(int m) +{ + return models[m].id; +} + int model_getmodel(int romset) { int c = 0; @@ -252,21 +268,34 @@ void common_init() { dma_init(); fdc_add(); - lpt_init(); + if (lpt_enabled) + { + lpt_init(); + } pic_init(); pit_init(); - serial1_init(0x3f8, 4); - serial2_init(0x2f8, 3); + if (serial_enabled[0]) + { + serial1_init(0x3f8, 4); + } + if (serial_enabled[1]) + { + serial2_init(0x2f8, 3); + } } void xt_init() { common_init(); mem_add_bios(); - pit_set_out_func(1, pit_refresh_timer_xt); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); keyboard_xt_init(); nmi_init(); if (joystick_type != 7) device_add(&gameport_device); + if (bugger_enabled) + { + bugger_init(); + } } void pcjr_init() @@ -275,8 +304,11 @@ void pcjr_init() fdc_add_pcjr(); pic_init(); pit_init(); - pit_set_out_func(0, pit_irq0_timer_pcjr); - serial1_init(0x2f8, 3); + pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); + if (serial_enabled[0]) + { + serial1_init(0x2f8, 3); + } keyboard_pcjr_init(); device_add(&sn76489_device); nmi_mask = 0x80; @@ -299,7 +331,6 @@ void tandy1k_init() } void tandy1ksl2_init() { -// TANDY = 1; common_init(); mem_add_bios(); keyboard_tandy_init(); @@ -348,14 +379,27 @@ void at_init() { AT = 1; common_init(); - lpt2_remove(); + if (lpt_enabled) + { + lpt2_remove(); + } mem_add_bios(); - pit_set_out_func(1, pit_refresh_timer_at); + pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); keyboard_at_init(); nvr_init(); pic2_init(); if (joystick_type != 7) device_add(&gameport_device); + if (bugger_enabled) + { + bugger_init(); + } +} + +void ibm_at_init() +{ + at_init(); + mem_remap_top_384k(); } void at_ide_init() @@ -375,12 +419,12 @@ void ps1_common_init() AT = 1; common_init(); mem_add_bios(); - pit_set_out_func(1, pit_refresh_timer_at); + pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); - if (romset == ROM_IBMPS1_2011) - device_add(&xtide_ps2_device); - else - ide_init(); + if (romset != ROM_IBMPS1_2011) + { + ide_init(); + } keyboard_at_init(); nvr_init(); pic2_init(); @@ -408,9 +452,8 @@ void ps2_m30_286_init() AT = 1; common_init(); mem_add_bios(); - pit_set_out_func(1, pit_refresh_timer_at); + pit_set_out_func(&pit, 1, pit_refresh_timer_at); dma16_init(); - device_add(&xtide_ps2_device); keyboard_at_init(); nvr_init(); pic2_init(); @@ -419,6 +462,41 @@ void ps2_m30_286_init() fdc_set_ps1(); } +static void ps2_common_init() +{ + AT = 1; + common_init(); + mem_add_bios(); + dma16_init(); + ps2_dma_init(); + ide_init(); + keyboard_at_init(); + keyboard_at_init_ps2(); + mouse_ps2_init(); + nvr_init(); + pic2_init(); + + pit_ps2_init(); +} + +void ps2_model_50_init() +{ + ps2_common_init(); + ps2_mca_board_model_50_init(); +} + +void ps2_model_55sx_init() +{ + ps2_common_init(); + ps2_mca_board_model_55sx_init(); +} + +void ps2_model_80_init() +{ + ps2_common_init(); + ps2_mca_board_model_80_type2_init(); +} + void at_neat_init() { at_ide_init(); @@ -564,14 +642,6 @@ void at_endeavor_init() device_add(&intel_flash_bxt_ami_device); } -#if 0 -void at_marl_init() -{ - at_advanced_common_init(); - // device_add(&intel_flash_100bxt_ami_device); -} -#endif - void at_mb500n_init() { at_ide_init(); @@ -607,6 +677,32 @@ void at_p54tp4xe_init() device_add(&intel_flash_bxt_device); } +void at_ap53_init() +{ + at_ide_init(); + memregs_init(); + powermate_memregs_init(); + pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + i430hx_init(); + piix3_init(7); + fdc37c669_init(); + acerm3a_io_init(); + device_add(&intel_flash_bxt_device); +} + +void at_p55t2s_init() +{ + at_ide_init(); + memregs_init(); + powermate_memregs_init(); + pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + i430hx_init(); + piix3_init(7); + pc87306_init(); + acerm3a_io_init(); + device_add(&intel_flash_bxt_device); +} + void at_acerm3a_init() { at_ide_init(); @@ -688,9 +784,20 @@ void at_i440fx_init() device_add(&intel_flash_bxt_device); } +void at_s1668_init() +{ + at_ide_init(); + memregs_init(); + pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + i440fx_init(); + piix3_init(7); + fdc37c665_init(); + device_add(&intel_flash_bxt_device); +} + void model_init() { - pclog("Initting as %s\n", model_getname()); + pclog("Initializing as %s\n", model_getname()); AMSTRAD = AT = PCI = TANDY = 0; io_init(); diff --git a/src/model.h b/src/model.h index 9a627a3d1..bfdc19077 100644 --- a/src/model.h +++ b/src/model.h @@ -1,15 +1,17 @@ /* Copyright holders: Sarah Walker, Tohka see COPYING for more details */ -#define MODEL_AT 1 -#define MODEL_PS2 2 -#define MODEL_AMSTRAD 4 -#define MODEL_OLIM24 8 -#define MODEL_HAS_IDE 16 -#define MODEL_NEC 32 -#define MODEL_FUJITSU 64 -#define MODEL_RM 128 -#define MODEL_PS2_HDD 256 +#define MODEL_AT 1 +#define MODEL_PS2 2 +#define MODEL_AMSTRAD 4 +#define MODEL_OLIM24 8 +#define MODEL_HAS_IDE 16 +#define MODEL_MCA 32 +#define MODEL_PCI 64 +#define MODEL_PS2_HDD 128 +#define MODEL_NEC 256 +#define MODEL_FUJITSU 512 +#define MODEL_RM 1024 typedef struct { @@ -41,3 +43,4 @@ char *model_get_internal_name(); int model_get_model_from_internal_name(char *s); void model_init(); struct device_t *model_getdevice(int model); +int model_getromset_ex(int m); diff --git a/src/mouse.c b/src/mouse.c index 467dde2e9..9fb10ccf2 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,50 +1,108 @@ #include "ibm.h" #include "mouse.h" -#include "amstrad.h" -#include "mouse_ps2.h" #include "mouse_serial.h" +#ifdef INPORT_MOUSE +# include "mouse_inport.h" +#endif +#include "mouse_ps2.h" +#include "mouse_bus.h" +#include "amstrad.h" #include "keyboard_olim24.h" -static mouse_t *mouse_list[] = -{ - &mouse_serial_microsoft, - &mouse_ps2_2_button, - &mouse_intellimouse, - &mouse_amstrad, - &mouse_olim24, - NULL + +#ifndef INPORTMOUSE +static mouse_t mouse_notimp = { + "Microsoft InPort Mouse", + "msinport", + MOUSE_TYPE_INPORT, + NULL, NULL, NULL +}; +#endif + + +static mouse_t *mouse_list[] = { + &mouse_serial_microsoft, /* 0 Microsoft Serial Mouse */ +#ifdef INPORTMOUSE + &mouse_inport, /* 1 Microsoft InPort Bus Mouse */ +#else + &mouse_notimp, /* 1 (not implemented) */ +#endif + &mouse_ps2_2_button, /* 2 PS/2 Mouse 2-button */ + &mouse_bus, /* 3 Logitech Bus Mouse 2-button */ + &mouse_intellimouse, /* 4 PS/2 Intellimouse 3-button */ + &mouse_amstrad, /* 5 Amstrad PC System Mouse */ + &mouse_olim24, /* 6 Olivetti M24 System Mouse */ +#if 0 + &mouse_msystems, /* 7 Mouse Systems */ + &mouse_genius, /* 8 Genius Bus Mouse */ +#endif + NULL }; static mouse_t *cur_mouse; static void *mouse_p; int mouse_type = 0; -void mouse_emu_init() + +void mouse_emu_init(void) { - cur_mouse = mouse_list[mouse_type]; - mouse_p = cur_mouse->init(); + cur_mouse = mouse_list[mouse_type]; + mouse_p = cur_mouse->init(); } -void mouse_emu_close() + +void mouse_emu_close(void) { - if (cur_mouse) - cur_mouse->close(mouse_p); - cur_mouse = NULL; + if (cur_mouse) + cur_mouse->close(mouse_p); + cur_mouse = NULL; } + void mouse_poll(int x, int y, int z, int b) { - if (cur_mouse) - cur_mouse->poll(x, y, z, b, mouse_p); + if (cur_mouse) + cur_mouse->poll(x, y, z, b, mouse_p); } + char *mouse_get_name(int mouse) { - if (!mouse_list[mouse]) - return NULL; - return mouse_list[mouse]->name; + if (!mouse_list[mouse]) + return(NULL); + return(mouse_list[mouse]->name); } + + +char *mouse_get_internal_name(int mouse) +{ + return(mouse_list[mouse]->internal_name); +} + + +int mouse_get_from_internal_name(char *s) +{ + int c = 0; + + while (mouse_list[c] != NULL) + { + if (!strcmp(mouse_list[c]->internal_name, s)) + return(c); + c++; + } + + return(0); +} + + int mouse_get_type(int mouse) { - return mouse_list[mouse]->type; + return(mouse_list[mouse]->type); +} + + +/* Return number of MOUSE types we know about. */ +int mouse_get_ndev(void) +{ + return(sizeof(mouse_list)/sizeof(mouse_t *) - 1); } diff --git a/src/mouse.h b/src/mouse.h index c91cf25ff..701d5de9a 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -1,26 +1,42 @@ -void mouse_emu_init(); -void mouse_emu_close(); -void mouse_poll(int x, int y, int z, int b); +#ifndef MOUSE_H +# define MOUSE_H -char *mouse_get_name(int mouse); -int mouse_get_type(int mouse); -#define MOUSE_TYPE_SERIAL 0 -#define MOUSE_TYPE_PS2 1 -#define MOUSE_TYPE_AMSTRAD 2 -#define MOUSE_TYPE_OLIM24 3 +#define MOUSE_TYPE_SERIAL 0 /* Serial Mouse */ +#define MOUSE_TYPE_INPORT 1 /* Microsoft InPort Bus Mouse */ +#define MOUSE_TYPE_PS2 2 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_BUS 3 /* Logitech/ATI Bus Mouse */ +#define MOUSE_TYPE_PS2_MS 4 +#define MOUSE_TYPE_AMSTRAD 5 /* Amstrad PC system mouse */ +#define MOUSE_TYPE_OLIM24 6 /* Olivetti M24 system mouse */ +#define MOUSE_TYPE_MSYSTEMS 7 /* Mouse Systems mouse */ +#define MOUSE_TYPE_GENIUS 8 /* Genius Bus Mouse */ -#define MOUSE_TYPE_IF_MASK 3 +#define MOUSE_TYPE_MASK 0x0f +#define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */ -#define MOUSE_TYPE_3BUTTON (1 << 31) -typedef struct -{ - char name[80]; - void *(*init)(); - void (*close)(void *p); - uint8_t (*poll)(int x, int y, int z, int b, void *p); - int type; +typedef struct { + char name[80]; + char internal_name[24]; + int type; + void *(*init)(void); + void (*close)(void *p); + uint8_t (*poll)(int x, int y, int z, int b, void *p); } mouse_t; -extern int mouse_type; + +extern int mouse_type; + + +extern void mouse_emu_init(void); +extern void mouse_emu_close(void); +extern void mouse_poll(int x, int y, int z, int b); +extern char *mouse_get_name(int mouse); +extern char *mouse_get_internal_name(int mouse); +extern int mouse_get_from_internal_name(char *s); +extern int mouse_get_type(int mouse); +extern int mouse_get_ndev(void); + + +#endif /*MOUSE_H*/ diff --git a/src/mouse_bus.c b/src/mouse_bus.c new file mode 100644 index 000000000..19ddb98cb --- /dev/null +++ b/src/mouse_bus.c @@ -0,0 +1,444 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Bus Mouse devices. + * + * These mice devices were made by both Microsoft (InPort) and + * Logitech. Sadly, they did not use the same I/O protocol, but + * they were close enough to fit into a single implementation. + * + * Although the Minix driver blindly took IRQ5, the board seems + * to be able to tell the driver what IRQ it is set for. When + * testing on MS-DOS (6.22), the 'mouse.exe' driver did not want + * to start, and only after disassembling it and inspecting the + * code it was discovered that driver actually does use the IRQ + * reporting feature. In a really, really weird way, too: it + * sets up the board, and then reads the CTRL register which is + * supposed to return that IRQ value. Depending on whether or + * not the FREEZE bit is set, it has to return either the two's + * complemented (negated) value, or (if clear) just the value. + * The mouse.com driver reads both values 10,000 times, and + * then makes up its mind. Maybe an effort to 'debounce' the + * reading of the DIP switches? Oh-well. + * + * Based on an early driver for MINIX 1.5. + * Based on the 86Box PS/2 mouse driver as a framework. + * + * NOTE: Still have to add the code for the MS InPort mouse, which + * is very similar. Almost done, but not ready for release. + * + * Version: @(#)mouse_bus.c 1.0.3 2017/04/22 + * + * Author: Fred N. van Kempen, + * Copyright 1989-2017 Fred N. van Kempen. + */ +#include +#include +#include "ibm.h" +#include "io.h" +#include "pic.h" +#include "mouse.h" +#include "mouse_bus.h" +#include "plat-mouse.h" + + +#define ENABLE_3BTN 1 /* enable 3-button mode */ + + +/* Register definitions (based on Logitech info.) */ +#define LTMOUSE_DATA 0 /* DATA register */ +#define LTMOUSE_MAGIC 1 /* signature magic register */ +# define MAGIC_BYTE1 0xa5 /* most drivers use this */ +# define MAGIC_BYTE2 0x5a /* some drivers use this */ +# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ +# define MAGIC_MSBYTE2 0xad +#define LTMOUSE_CTRL 2 /* CTRL register */ +# define CTRL_FREEZE 0x80 /* do not sample when set */ +# define CTRL_RD_Y_HI 0x60 /* plus FREEZE */ +# define CTRL_RD_Y_LO 0x40 /* plus FREEZE */ +# define CTRL_RD_X_HI 0x20 /* plus FREEZE */ +# define CTRL_RD_X_LO 0x00 /* plus FREEZE */ +# define CTRL_RD_MASK 0x60 +# define CTRL_IDISABLE 0x10 +# define CTRL_IENABLE 0x00 +# define CTRL_DFLT (CTRL_IDISABLE) +#define LTMOUSE_CONFIG 3 /* CONFIG register */ +# define CONFIG_DFLT 0x91 /* 8255 controller config */ + +#define MSMOUSE_CTRL 0 /* CTRL register */ +#define MSMOUSE_DATA 1 /* DATA register */ +#define MSMOUSE_MAGIC 2 /* MAGIC register */ +#define MSMOUSE_CONFIG 3 /* CONFIG register */ + + +/* Our mouse device. */ +typedef struct { + uint16_t port; /* I/O port range start */ + uint16_t portlen; /* length of I/O port range */ + int8_t irq; /* IRQ channel to use */ + uint8_t flags; /* device flags */ + + uint8_t r_magic; /* MAGIC register */ + uint8_t r_ctrl; /* CONTROL register (WR) */ + uint8_t r_intr; /* INTSTAT register (RO) */ + uint8_t r_conf; /* CONFIG register */ + + int8_t x, y; /* current mouse status */ + uint8_t but; +} mouse_bus_t; +#define MOUSE_ENABLED 0x80 /* device is enabled for use */ +#define MOUSE_LOGITECH 0x40 /* running as Logitech mode */ +#define MOUSE_CMDFLAG 0x01 /* next wr is a command (MS) */ + + +/* Handle a write to the control register. */ +static void +wctrl(mouse_bus_t *ms, uint8_t val) +{ + uint8_t b = (ms->r_ctrl ^ val); + + if (b & CTRL_FREEZE) { + /* Hold the sampling while we do something. */ + if (! (val & CTRL_FREEZE)) { + /* Reset current state. */ + ms->x = ms->y = 0; + if (ms->but) /* allow one more POLL for button-release */ + ms->but = 0x80; + } + } + + if (b & CTRL_IDISABLE) { + /* Disable or enable interrupts. */ + /* (we don't do anything for that here..) */ + } + + /* Save new register value. */ + ms->r_ctrl = val; +} + + +/* Handle a WRITE operation to one of our registers. */ +static void +busmouse_write(uint16_t port, uint8_t val, void *priv) +{ + mouse_bus_t *ms = (mouse_bus_t *)priv; + +#if 0 + pclog("BUSMOUSE: write(%d,%02x)\n", port-ms->port, val); +#endif + + switch (port-ms->port) { + case LTMOUSE_DATA: /* [00] data register */ + break; + + case LTMOUSE_MAGIC: /* [01] magic data register */ + if (val == MAGIC_BYTE1 || val == MAGIC_BYTE2) { + ms->flags |= MOUSE_LOGITECH; + ms->r_magic = val; + } + break; + + case LTMOUSE_CTRL: /* [02] control register */ + wctrl(ms, val); + break; + + case LTMOUSE_CONFIG: /* [03] config register */ + ms->r_conf = val; + break; + + default: + break; + } +} + + +/* Handle a READ from a Microsoft-mode register. */ +static uint8_t +ms_read(mouse_bus_t *ms, uint16_t port) +{ + uint8_t r = 0xff; + + switch (port) { + case MSMOUSE_CTRL: /* [00] control register */ + r = ms->r_ctrl; + break; + + case MSMOUSE_DATA: /* [01] data register */ + break; + + case MSMOUSE_MAGIC: /* [02] magic data register */ + /* + * Drivers for the InPort controllers usually start + * by reading this register. If they find 0xDE here, + * they will continue their probe, otherwise no go. + */ + r = ms->r_magic; + + /* For the InPort, switch magic bytes. */ + if (ms->r_magic == MAGIC_MSBYTE1) + ms->r_magic = MAGIC_MSBYTE2; + else + ms->r_magic = MAGIC_MSBYTE1; + break; + + case MSMOUSE_CONFIG: /* [03] config register */ + r = ms->r_conf; + break; + + default: + break; + } + +#if 0 + pclog("BUSMOUSE: msread(%d): %02x\n", port, r); +#endif + + return(r); +} + + +/* Handle a READ from a LOGITECH-mode register. */ +static uint8_t +lt_read(mouse_bus_t *ms, uint16_t port) +{ + uint8_t r = 0xff; + + switch (port) { + case LTMOUSE_DATA: /* [00] data register */ + if (! (ms->r_ctrl & CTRL_FREEZE)) { + r = 0x00; + } else switch(ms->r_ctrl & CTRL_RD_MASK) { + case CTRL_RD_X_LO: /* X, low bits */ + /* + * Some drivers expect the buttons to + * be in this byte. Others want it in + * the Y-LO byte. --FvK + */ + r = 0x07; + if (ms->but & 0x01) /*LEFT*/ + r &= ~0x04; + if (ms->but & 0x02) /*RIGHT*/ + r &= ~0x01; +#if ENABLE_3BTN + if (ms->but & 0x04) /*MIDDLE*/ + r &= ~0x02; +#endif + r <<= 5; + r |= (ms->x & 0x0f); + break; + + case CTRL_RD_X_HI: /* X, high bits */ + r = (ms->x >> 4) & 0x0f; + break; + + case CTRL_RD_Y_LO: /* Y, low bits */ + r = (ms->y & 0x0f); + break; + + case CTRL_RD_Y_HI: /* Y, high bits */ + /* + * Some drivers expect the buttons to + * be in this byte. Others want it in + * the X-LO byte. --FvK + */ + r = 0x07; + if (ms->but & 0x01) /*LEFT*/ + r &= ~0x04; + if (ms->but & 0x02) /*RIGHT*/ + r &= ~0x01; +#if ENABLE_3BTN + if (ms->but & 0x04) /*MIDDLE*/ + r &= ~0x02; +#endif + r <<= 5; + r |= (ms->y >> 4) & 0x0f; + break; + } + break; + + case LTMOUSE_MAGIC: /* [01] magic data register */ + /* + * Logitech drivers start out by blasting their magic + * value (0xA5) into this register, and then read it + * back to see if that worked. If it did (and we do + * support this) the controller is assumed to be a + * Logitech-protocol one, and not InPort. + */ + r = ms->r_magic; + break; + + case LTMOUSE_CTRL: /* [02] control register */ + /* + * This is the weird stuff mentioned in the file header + * above. Microsoft's "mouse.exe" does some whacky stuff + * to extract the configured IRQ channel from the board. + * + * First, it reads the current value, and then re-reads + * it another 10,000 (yes, really) times. It keeps track + * of whether or not the data has changed, most likely + * to de-bounce reading of a DIP switch for example. This + * first value is assumed to be the 2's complement of the + * actual IRQ value. + * Next, it does this a second time, but now with the + * IDISABLE bit clear (so, interrupts enabled), which is + * our cue to return the regular (not complemented) value + * to them. + * + * Since we have to fake the initial value and the settling + * of the data a bit later on, we first return a bunch of + * invalid ("random") data, and then the real value. + * + * Yes, this is weird. --FvK + */ + if (ms->r_intr++ < 250) + /* Still settling, return invalid data. */ + r = (ms->r_ctrl&CTRL_IDISABLE)?0xff:0x00; + else { + /* OK, all good, return correct data. */ + r = (ms->r_ctrl&CTRL_IDISABLE)?-ms->irq:ms->irq; + ms->r_intr = 0; + } + break; + + case LTMOUSE_CONFIG: /* [03] config register */ + r = ms->r_conf; + break; + + default: + break; + } + +#if 0 + pclog("BUSMOUSE: ltread(%d): %02x\n", port, r); +#endif + + return(r); +} + + +/* Handle a READ operation from one of our registers. */ +static uint8_t +busmouse_read(uint16_t port, void *priv) +{ + mouse_bus_t *ms = (mouse_bus_t *)priv; + uint8_t r; + + if (ms->flags & MOUSE_LOGITECH) + r = lt_read(ms, port - ms->port); + else + r = ms_read(ms, port - ms->port); + + return(r); +} + + +/* The emulator calls us with an update on the host mouse device. */ +static uint8_t +busmouse_poll(int x, int y, int z, int b, void *priv) +{ + mouse_bus_t *ms = (mouse_bus_t *)priv; + +#if 0 + pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b); +#endif + + /* Return early if nothing to do. */ + if (!x && !y && !z && (ms->but == b)) return(1); + + /* If we are not interested, return. */ + if (!(ms->flags & MOUSE_ENABLED) || + (ms->r_ctrl & CTRL_FREEZE)) return(0); + + /* Add the delta to our state. */ + x += ms->x; + if (x > 127) + x = 127; + if (x < -128) + x = -128; + ms->x = (int8_t)x; + + y += ms->y; + if (y > 127) + y = 127; + if (y < -128) + y = -128; + ms->y = (int8_t)y; + + ms->but = b; + + /* All set, generate an interrupt. */ + if (! (ms->r_ctrl & CTRL_IDISABLE)) + picint(1 << ms->irq); + + return(0); +} + + +/* Release all resources held by the device. */ +static void +busmouse_close(void *priv) +{ + mouse_bus_t *ms = (mouse_bus_t *)priv; + + /* Release our I/O range. */ + io_removehandler(ms->port, ms->portlen, + busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, + ms); + + free(ms); +} + + +/* Initialize the device for use by the user. */ +static void * +busmouse_init(void) +{ + mouse_bus_t *ms; + + ms = (mouse_bus_t *)malloc(sizeof(mouse_bus_t)); + memset(ms, 0x00, sizeof(mouse_bus_t)); + ms->port = BUSMOUSE_PORT; + ms->portlen = BUSMOUSE_PORTLEN; +#if BUSMOUSE_IRQ + ms->irq = BUSMOUSE_IRQ; +#else + ms->irq = -1; +#endif + + pclog("Logitech/Microsoft Bus Mouse, I/O=%04x, IRQ=%d\n", + ms->port, ms->irq); + /* Initialize registers. */ + ms->r_magic = MAGIC_MSBYTE1; + ms->r_conf = CONFIG_DFLT; + ms->r_ctrl = CTRL_DFLT; + + /* + * Technically this is not possible, but we fake that we + * did a power-up initialization with default config as + * set in the "conf" register. Emulators rock! --FvK + */ + ms->flags = MOUSE_ENABLED; + + /* Request an I/O range. */ + io_sethandler(ms->port, ms->portlen, + busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, + ms); + + /* Return our private data to the I/O layer. */ + return(ms); +} + + +mouse_t mouse_bus = { + "Bus Mouse", + "msbus", + MOUSE_TYPE_BUS, + busmouse_init, + busmouse_close, + busmouse_poll +}; diff --git a/src/mouse_bus.h b/src/mouse_bus.h new file mode 100644 index 000000000..24eeb50ff --- /dev/null +++ b/src/mouse_bus.h @@ -0,0 +1,34 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Bus Mouse devices. + * + * These mice devices were made by both Microsoft (InPort) and + * Logitech. Sadly, they did not use the same I/O protocol, but + * they were close enough to fit into a single implementation. + * + * Definitions for the Bus Mouse driver. + * + * Version: @(#)mouse_bus.h 1.0.3 2017/04/22 + * + * Author: Fred N. van Kempen, + * Copyright 1989-2017 Fred N. van Kempen. + */ +#ifndef MOUSE_BUS_H +# define MOUSE_BUS_H + + +#define BUSMOUSE_PORT 0x023c +#define BUSMOUSE_PORTLEN 4 +#define BUSMOUSE_IRQ 5 + + +extern mouse_t mouse_bus; + + +#endif /*MOUSE_BUS_H*/ diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index 15d2019f9..fa9eda980 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -1,3 +1,4 @@ +#include #include "ibm.h" #include "keyboard_at.h" #include "mouse.h" @@ -148,16 +149,16 @@ void mouse_ps2_write(uint8_t val, void *p) } } -void mouse_ps2_poll(int x, int y, int z, int b, void *p) +uint8_t mouse_ps2_poll(int x, int y, int z, int b, void *p) { mouse_ps2_t *mouse = (mouse_ps2_t *)p; uint8_t packet[3] = {0x08, 0, 0}; if (!x && !y && !z && b == mouse->b) - return; + return(0xff); if (!mouse_scan) - return; + return(0xff); mouse->x += x; mouse->y -= y; @@ -200,6 +201,8 @@ void mouse_ps2_poll(int x, int y, int z, int b, void *p) mouse->x = mouse->y = mouse->z = 0; } + + return(0); } void *mouse_ps2_init() @@ -237,16 +240,18 @@ void mouse_ps2_close(void *p) mouse_t mouse_ps2_2_button = { "2-button mouse (PS/2)", + "ps2", + MOUSE_TYPE_PS2, mouse_ps2_init, mouse_ps2_close, - mouse_ps2_poll, - MOUSE_TYPE_PS2 + mouse_ps2_poll }; mouse_t mouse_intellimouse = { "Microsoft Intellimouse (PS/2)", + "intellimouse", + MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON, mouse_intellimouse_init, mouse_ps2_close, - mouse_ps2_poll, - MOUSE_TYPE_PS2 | MOUSE_TYPE_3BUTTON + mouse_ps2_poll }; diff --git a/src/mouse_ps2.h b/src/mouse_ps2.h index 645e3cf73..b25cae5f2 100644 --- a/src/mouse_ps2.h +++ b/src/mouse_ps2.h @@ -1,2 +1,4 @@ extern mouse_t mouse_ps2_2_button; extern mouse_t mouse_intellimouse; + +extern void *mouse_ps2_init(); diff --git a/src/mouse_serial.c b/src/mouse_serial.c index f05e64d9e..84e85a673 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -1,98 +1,117 @@ +#include #include "ibm.h" #include "mouse.h" #include "pic.h" #include "serial.h" #include "timer.h" -typedef struct mouse_serial_t -{ - int mousepos, mousedelay; - int oldb; - SERIAL *serial; + +typedef struct mouse_serial_t { + int pos, + delay; + int oldb; + SERIAL *serial; } mouse_serial_t; -void mouse_serial_poll(int x, int y, int z, int b, void *p) + +static void +sermouse_rcr(SERIAL *serial, void *priv) { - mouse_serial_t *mouse = (mouse_serial_t *)p; - SERIAL *serial = mouse->serial; - uint8_t mousedat[3]; - - if (!(serial->ier & 1)) - return; - if (!x && !y && b == mouse->oldb) - return; - - mouse->oldb = b; - if (x>127) x=127; - if (y>127) y=127; - if (x<-128) x=-128; - if (y<-128) y=-128; - - /*Use Microsoft format*/ - mousedat[0]=0x40; - mousedat[0]|=(((y>>6)&3)<<2); - mousedat[0]|=((x>>6)&3); - if (b&1) mousedat[0]|=0x20; - if (b&2) mousedat[0]|=0x10; - mousedat[1]=x&0x3F; - mousedat[2]=y&0x3F; + mouse_serial_t *ms = (mouse_serial_t *)priv; - if (!(serial->mctrl & 0x10)) - { -// pclog("Serial data %02X %02X %02X\n", mousedat[0], mousedat[1], mousedat[2]); - serial_write_fifo(mouse->serial, mousedat[0]); - serial_write_fifo(mouse->serial, mousedat[1]); - serial_write_fifo(mouse->serial, mousedat[2]); - } + ms->pos = -1; + ms->delay = 5000 * (1 << TIMER_SHIFT); } -void mouse_serial_rcr(SERIAL *serial, void *p) -{ - mouse_serial_t *mouse = (mouse_serial_t *)p; - - mouse->mousepos = -1; - mouse->mousedelay = 5000 * (1 << TIMER_SHIFT); -} - -void mousecallback(void *p) -{ - mouse_serial_t *mouse = (mouse_serial_t *)p; - mouse->mousedelay = 0; - if (mouse->mousepos == -1) - { - mouse->mousepos = 0; - serial_write_fifo(mouse->serial, 'M'); - } +static void +sermouse_timer(void *priv) +{ + mouse_serial_t *ms = (mouse_serial_t *)priv; + + ms->delay = 0; + if (ms->pos == -1) { + ms->pos = 0; + serial_write_fifo(ms->serial, 'M'); + } } -void *mouse_serial_init() -{ - mouse_serial_t *mouse = (mouse_t *)malloc(sizeof(mouse_serial_t)); - memset(mouse, 0, sizeof(mouse_serial_t)); - mouse->serial = &serial1; - serial1.rcr_callback = mouse_serial_rcr; - serial1.rcr_callback_p = mouse; - timer_add(mousecallback, &mouse->mousedelay, &mouse->mousedelay, mouse); - - return mouse; +static uint8_t +sermouse_poll(int x, int y, int z, int b, void *priv) +{ + mouse_serial_t *ms = (mouse_serial_t *)priv; + SERIAL *sp = ms->serial; + uint8_t mousedat[3]; + + if (!(sp->ier & 1)) return(1); + + if (!x && !y && b == ms->oldb) return(1); + + ms->oldb = b; + if (x>127) x = 127; + if (y>127) y = 127; + if (x<-128) x = -128; + if (y<-128) y = -128; + + /* Use Microsoft format. */ + mousedat[0] = 0x40; + mousedat[0] |= (((y>>6)&3)<<2); + mousedat[0] |= ((x>>6)&3); + if (b&1) mousedat[0] |= 0x20; + if (b&2) mousedat[0] |= 0x10; + mousedat[1] = x & 0x3F; + mousedat[2] = y & 0x3F; + + /* FIXME: we should check in serial_write_fifo, not here! --FvK */ + if (! (sp->mctrl & 0x10)) { +#if 0 + pclog("Serial data %02X %02X %02X\n", + mousedat[0], mousedat[1], mousedat[2]); +#endif + serial_write_fifo(ms->serial, mousedat[0]); + serial_write_fifo(ms->serial, mousedat[1]); + serial_write_fifo(ms->serial, mousedat[2]); + } + + return(0); } -void mouse_serial_close(void *p) + +static void * +sermouse_init(void) { - mouse_serial_t *mouse = (mouse_serial_t *)p; - - free(mouse); - - serial1.rcr_callback = NULL; + mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(ms, 0x00, sizeof(mouse_serial_t)); + + /* Attach a serial port to the mouse. */ + ms->serial = &serial1; + serial1.rcr_callback = sermouse_rcr; + serial1.rcr_callback_p = ms; + + timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); + + return(ms); } -mouse_t mouse_serial_microsoft = + +static void +sermouse_close(void *priv) { - "Microsoft 2-button mouse (serial)", - mouse_serial_init, - mouse_serial_close, - mouse_serial_poll, - MOUSE_TYPE_SERIAL + mouse_serial_t *ms = (mouse_serial_t *)priv; + + /* Detach serial port from the mouse. */ + serial1.rcr_callback = NULL; + + free(ms); +} + + +mouse_t mouse_serial_microsoft = { + "Microsoft 2-button mouse (serial)", + "msserial", + MOUSE_TYPE_SERIAL, + sermouse_init, + sermouse_close, + sermouse_poll }; diff --git a/src/ne2000.c b/src/ne2000.c index 3f5006123..9bcad3036 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -1,22 +1,21 @@ /* Copyright holders: Peter Grehan, SA1988, Tenshi see COPYING for more details */ -///////////////////////////////////////////////////////////////////////// -// $Id: ne2k.cc,v 1.56.2.1 2004/02/02 22:37:22 cbothamy Exp $ -///////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2002 MandrakeSoft S.A. -// -// MandrakeSoft S.A. -// 43, rue d'Aboukir -// 75002 Paris - France -// http://www.linux-mandrake.com/ -// http://www.mandrakesoft.com/ -// +/* + $Id: ne2k.cc,v 1.56.2.1 2004/02/02 22:37:22 cbothamy Exp $ +*/ +/* + Copyright (C) 2002 MandrakeSoft S.A. -// Peter Grehan (grehan@iprg.nokia.com) coded all of this -// NE2000/ether stuff. -//#include "vl.h" + MandrakeSoft S.A. + 43, rue d'Aboukir + 75002 Paris - France + http://www.linux-mandrake.com/ + http://www.mandrakesoft.com/ +*/ + +/* Peter Grehan (grehan@iprg.nokia.com) coded all of this + NE2000/ether stuff. */ #include #include #include @@ -29,6 +28,7 @@ #include "ibm.h" #include "device.h" +#include "disc_random.h" #include "config.h" #include "nethandler.h" @@ -43,24 +43,25 @@ #include "pic.h" #include "timer.h" -//THIS IS THE DEFAULT MAC ADDRESS .... so it wont place nice with multiple VMs. YET. +/* THIS IS THE DEFAULT MAC ADDRESS .... so it wont place nice with multiple VMs. YET. */ uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; +uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; -#define NETBLOCKING 0 //we won't block our pcap +#define NETBLOCKING 0 /* we won't block our pcap */ pcap_t *net_pcap; queueADT slirpq; int net_slirp_inited=0; -int net_is_pcap=0; //and pretend pcap is dead. +int net_is_pcap=0; /* and pretend pcap is dead. */ int fizz=0; void slirp_tic(); #define BX_RESET_HARDWARE 0 #define BX_RESET_SOFTWARE 1 -//Never completely fill the ne2k ring so that we never -// hit the unclear completely full buffer condition. +/* Never completely fill the ne2k ring so that we never + hit the unclear completely full buffer condition. */ #define BX_NE2K_NEVER_FULL_RING (1) #define BX_NE2K_MEMSIZ (32*1024) @@ -71,151 +72,145 @@ uint8_t rtl8029as_eeprom[128]; typedef struct ne2000_t { - // - // ne2k register state + /* ne2k register state */ - // - // Page 0 - // - // Command Register - 00h read/write + /* Page 0 */ + + /* Command Register - 00h read/write */ struct CR_t { - int stop; // STP - Software Reset command - int start; // START - start the NIC - int tx_packet; // TXP - initiate packet transmission - uint8_t rdma_cmd; // RD0,RD1,RD2 - Remote DMA command - uint8_t pgsel; // PS0,PS1 - Page select + int stop; /* STP - Software Reset command */ + int start; /* START - start the NIC */ + int tx_packet; /* TXP - initiate packet transmission */ + uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ + uint8_t pgsel; /* PS0,PS1 - Page select */ } CR; - // Interrupt Status Register - 07h read/write + /* Interrupt Status Register - 07h read/write */ struct ISR_t { - int pkt_rx; // PRX - packet received with no errors - int pkt_tx; // PTX - packet transmitted with no errors - int rx_err; // RXE - packet received with 1 or more errors - int tx_err; // TXE - packet tx'd " " " " " - int overwrite; // OVW - rx buffer resources exhausted - int cnt_oflow; // CNT - network tally counter MSB's set - int rdma_done; // RDC - remote DMA complete - int reset; // RST - reset status + int pkt_rx; /* PRX - packet received with no errors */ + int pkt_tx; /* PTX - packet transmitted with no errors */ + int rx_err; /* RXE - packet received with 1 or more errors */ + int tx_err; /* TXE - packet tx'd " " " " " */ + int overwrite; /* OVW - rx buffer resources exhausted */ + int cnt_oflow; /* CNT - network tally counter MSB's set */ + int rdma_done; /* RDC - remote DMA complete */ + int reset; /* RST - reset status */ } ISR; - // Interrupt Mask Register - 0fh write + /* Interrupt Mask Register - 0fh write */ struct IMR_t { - int rx_inte; // PRXE - packet rx interrupt enable - int tx_inte; // PTXE - packet tx interrput enable - int rxerr_inte; // RXEE - rx error interrupt enable - int txerr_inte; // TXEE - tx error interrupt enable - int overw_inte; // OVWE - overwrite warn int enable - int cofl_inte; // CNTE - counter o'flow int enable - int rdma_inte; // RDCE - remote DMA complete int enable - int reserved; // D7 - reserved + int rx_inte; /* PRXE - packet rx interrupt enable */ + int tx_inte; /* PTXE - packet tx interrput enable */ + int rxerr_inte; /* RXEE - rx error interrupt enable */ + int txerr_inte; /* TXEE - tx error interrupt enable */ + int overw_inte; /* OVWE - overwrite warn int enable */ + int cofl_inte; /* CNTE - counter o'flow int enable */ + int rdma_inte; /* RDCE - remote DMA complete int enable */ + int reserved; /* D7 - reserved */ } IMR; - // Data Configuration Register - 0eh write + /* Data Configuration Register - 0eh write */ struct DCR_t { - int wdsize; // WTS - 8/16-bit select - int endian; // BOS - byte-order select - int longaddr; // LAS - long-address select - int loop; // LS - loopback select - int auto_rx; // AR - auto-remove rx packets with remote DMA - uint8_t fifo_size; // FT0,FT1 - fifo threshold + int wdsize; /* WTS - 8/16-bit select */ + int endian; /* BOS - byte-order select */ + int longaddr; /* LAS - long-address select */ + int loop; /* LS - loopback select */ + int auto_rx; /* AR - auto-remove rx packets with remote DMA */ + uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ } DCR; - // Transmit Configuration Register - 0dh write + /* Transmit Configuration Register - 0dh write */ struct TCR_t { - int crc_disable; // CRC - inhibit tx CRC - uint8_t loop_cntl; // LB0,LB1 - loopback control - int ext_stoptx; // ATD - allow tx disable by external mcast - int coll_prio; // OFST - backoff algorithm select - uint8_t reserved; // D5,D6,D7 - reserved + int crc_disable; /* CRC - inhibit tx CRC */ + uint8_t loop_cntl; /* LB0,LB1 - loopback control */ + int ext_stoptx; /* ATD - allow tx disable by external mcast */ + int coll_prio; /* OFST - backoff algorithm select */ + uint8_t reserved; /* D5,D6,D7 - reserved */ } TCR; - // Transmit Status Register - 04h read + /* Transmit Status Register - 04h read */ struct TSR_t { - int tx_ok; // PTX - tx complete without error - int reserved; // D1 - reserved - int collided; // COL - tx collided >= 1 times - int aborted; // ABT - aborted due to excessive collisions - int no_carrier; // CRS - carrier-sense lost - int fifo_ur; // FU - FIFO underrun - int cd_hbeat; // CDH - no tx cd-heartbeat from transceiver - int ow_coll; // OWC - out-of-window collision + int tx_ok; /* PTX - tx complete without error */ + int reserved; /* D1 - reserved */ + int collided; /* COL - tx collided >= 1 times */ + int aborted; /* ABT - aborted due to excessive collisions */ + int no_carrier; /* CRS - carrier-sense lost */ + int fifo_ur; /* FU - FIFO underrun */ + int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ + int ow_coll; /* OWC - out-of-window collision */ } TSR; - // Receive Configuration Register - 0ch write + /* Receive Configuration Register - 0ch write */ struct RCR_t { - int errors_ok; // SEP - accept pkts with rx errors - int runts_ok; // AR - accept < 64-byte runts - int broadcast; // AB - accept eth broadcast address - int multicast; // AM - check mcast hash array - int promisc; // PRO - accept all packets - int monitor; // MON - check pkts, but don't rx - uint8_t reserved; // D6,D7 - reserved + int errors_ok; /* SEP - accept pkts with rx errors */ + int runts_ok; /* AR - accept < 64-byte runts */ + int broadcast; /* AB - accept eth broadcast address */ + int multicast; /* AM - check mcast hash array */ + int promisc; /* PRO - accept all packets */ + int monitor; /* MON - check pkts, but don't rx */ + uint8_t reserved; /* D6,D7 - reserved */ } RCR; - // Receive Status Register - 0ch read + /* Receive Status Register - 0ch read */ struct RSR_t { - int rx_ok; // PRX - rx complete without error - int bad_crc; // CRC - Bad CRC detected - int bad_falign; // FAE - frame alignment error - int fifo_or; // FO - FIFO overrun - int rx_missed; // MPA - missed packet error - int rx_mbit; // PHY - unicast or mcast/bcast address match - int rx_disabled; // DIS - set when in monitor mode - int deferred; // DFR - collision active + int rx_ok; /* PRX - rx complete without error */ + int bad_crc; /* CRC - Bad CRC detected */ + int bad_falign; /* FAE - frame alignment error */ + int fifo_or; /* FO - FIFO overrun */ + int rx_missed; /* MPA - missed packet error */ + int rx_mbit; /* PHY - unicast or mcast/bcast address match */ + int rx_disabled; /* DIS - set when in monitor mode */ + int deferred; /* DFR - collision active */ } RSR; - uint16_t local_dma; // 01,02h read ; current local DMA addr - uint8_t page_start; // 01h write ; page start register - uint8_t page_stop; // 02h write ; page stop register - uint8_t bound_ptr; // 03h read/write ; boundary pointer - uint8_t tx_page_start; // 04h write ; transmit page start register - uint8_t num_coll; // 05h read ; number-of-collisions register - uint16_t tx_bytes; // 05,06h write ; transmit byte-count register - uint8_t fifo; // 06h read ; FIFO - uint16_t remote_dma; // 08,09h read ; current remote DMA addr - uint16_t remote_start; // 08,09h write ; remote start address register - uint16_t remote_bytes; // 0a,0bh write ; remote byte-count register - uint8_t tallycnt_0; // 0dh read ; tally counter 0 (frame align errors) - uint8_t tallycnt_1; // 0eh read ; tally counter 1 (CRC errors) - uint8_t tallycnt_2; // 0fh read ; tally counter 2 (missed pkt errors) + uint16_t local_dma; /* 01,02h read ; current local DMA addr */ + uint8_t page_start; /* 01h write ; page start register */ + uint8_t page_stop; /* 02h write ; page stop register */ + uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ + uint8_t tx_page_start; /* 04h write ; transmit page start register */ + uint8_t num_coll; /* 05h read ; number-of-collisions register */ + uint16_t tx_bytes; /* 05,06h write ; transmit byte-count register */ + uint8_t fifo; /* 06h read ; FIFO */ + uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ + uint16_t remote_start; /* 08,09h write ; remote start address register */ + uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count register */ + uint8_t tallycnt_0; /* 0dh read ; tally counter 0 (frame align errors) */ + uint8_t tallycnt_1; /* 0eh read ; tally counter 1 (CRC errors) */ + uint8_t tallycnt_2; /* 0fh read ; tally counter 2 (missed pkt errors) */ - // - // Page 1 - // - // Command Register 00h (repeated) - // - uint8_t physaddr[6]; // 01-06h read/write ; MAC address - uint8_t curr_page; // 07h read/write ; current page register - uint8_t mchash[8]; // 08-0fh read/write ; multicast hash array + /* Page 1 */ - // - // Page 2 - diagnostic use only - // - // Command Register 00h (repeated) - // - // Page Start Register 01h read (repeated) - // Page Stop Register 02h read (repeated) - // Current Local DMA Address 01,02h write (repeated) - // Transmit Page start address 04h read (repeated) - // Receive Configuration Register 0ch read (repeated) - // Transmit Configuration Register 0dh read (repeated) - // Data Configuration Register 0eh read (repeated) - // Interrupt Mask Register 0fh read (repeated) - // - uint8_t rempkt_ptr; // 03h read/write ; remote next-packet pointer - uint8_t localpkt_ptr; // 05h read/write ; local next-packet pointer - uint16_t address_cnt; // 06,07h read/write ; address counter + /* Command Register 00h (repeated) */ - // - // Page 3 - should never be modified. - // + uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ + uint8_t curr_page; /* 07h read/write ; current page register */ + uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ - // Novell ASIC state - uint8_t macaddr[32]; // ASIC ROM'd MAC address, even bytes - uint8_t mem[BX_NE2K_MEMSIZ]; // on-chip packet memory + /* Page 2 - diagnostic use only */ - // ne2k internal state + /* Command Register 00h (repeated) */ + + /* Page Start Register 01h read (repeated) + Page Stop Register 02h read (repeated) + Current Local DMA Address 01,02h write (repeated) + Transmit Page start address 04h read (repeated) + Receive Configuration Register 0ch read (repeated) + Transmit Configuration Register 0dh read (repeated) + Data Configuration Register 0eh read (repeated) + Interrupt Mask Register 0fh read (repeated) + */ + uint8_t rempkt_ptr; /* 03h read/write ; remote next-packet pointer */ + uint8_t localpkt_ptr; /* 05h read/write ; local next-packet pointer */ + uint16_t address_cnt; /* 06,07h read/write ; address counter */ + + /* Page 3 - should never be modified. */ + + /* Novell ASIC state */ + uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ + uint8_t mem[BX_NE2K_MEMSIZ]; /* on-chip packet memory */ + + /* ne2k internal state */ uint32_t base_address; int base_irq; int tx_timer_index; @@ -248,14 +243,85 @@ void ne2000_log(const char *format, ...) #endif } +static uint8_t *ne2000_mac() +{ + if (network_card_current == 2) + { + return maclocal_pci; + } + else + { + return maclocal; + } +} + +void ne2000_generate_maclocal(int mac) +{ + maclocal[0] = 0x00; /* 00:00:1B (NE2000 ISA vendor prefix). */ + maclocal[1] = 0x00; + maclocal[2] = 0x1B; + + if (mac & 0xff000000) + { + /* Generating new MAC. */ + maclocal[3] = disc_random_generate(); + maclocal[4] = disc_random_generate(); + maclocal[5] = disc_random_generate(); + } + else + { + maclocal[3] = (mac >> 16) & 0xff; + maclocal[4] = (mac >> 8) & 0xff; + maclocal[5] = mac & 0xff; + } +} + +void ne2000_generate_maclocal_pci(int mac) +{ + maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + maclocal_pci[1] = 0x20; + maclocal_pci[2] = 0x18; + + if (mac & 0xff000000) + { + /* Generating new MAC. */ + maclocal_pci[3] = disc_random_generate(); + maclocal_pci[4] = disc_random_generate(); + maclocal_pci[5] = disc_random_generate(); + } + else + { + maclocal_pci[3] = (mac >> 16) & 0xff; + maclocal_pci[4] = (mac >> 8) & 0xff; + maclocal_pci[5] = mac & 0xff; + } +} + +int net2000_get_maclocal() +{ + int temp; + temp = (((int) maclocal[3]) << 16); + temp |= (((int) maclocal[4]) << 8); + temp |= ((int) maclocal[5]); + return temp; +} + +int net2000_get_maclocal_pci() +{ + int temp; + temp = (((int) maclocal_pci[3]) << 16); + temp |= (((int) maclocal_pci[4]) << 8); + temp |= ((int) maclocal_pci[5]); + return temp; +} + static void ne2000_setirq(ne2000_t *ne2000, int irq) { ne2000->base_irq = irq; } -// -// reset - restore state to power-up, cancelling all i/o -// +/* reset - restore state to power-up, cancelling all i/o */ + static void ne2000_reset(void *p, int reset) { ne2000_t *ne2000 = (ne2000_t *)p; @@ -263,7 +329,7 @@ static void ne2000_reset(void *p, int reset) ne2000_log("ne2000 reset\n"); - // Initialise the mac address area by doubling the physical address + /* Initialise the mac address area by doubling the physical address */ ne2000->macaddr[0] = ne2000->physaddr[0]; ne2000->macaddr[1] = ne2000->physaddr[0]; ne2000->macaddr[2] = ne2000->physaddr[1]; @@ -277,20 +343,19 @@ static void ne2000_reset(void *p, int reset) ne2000->macaddr[10] = ne2000->physaddr[5]; ne2000->macaddr[11] = ne2000->physaddr[5]; - // ne2k signature + /* ne2k signature */ for (i = 12; i < 32; i++) { ne2000->macaddr[i] = 0x57; } - // Zero out registers and memory + /* Zero out registers and memory */ memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); - // memset( & ne2000->RCR, 0, sizeof(ne2000->RCR)); memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); ne2000->tx_timer_active = 0; ne2000->local_dma = 0; @@ -316,7 +381,7 @@ static void ne2000_reset(void *p, int reset) memset( & ne2000->mem, 0, sizeof(ne2000->mem)); - // Set power-up conditions + /* Set power-up conditions */ ne2000->CR.stop = 1; ne2000->CR.rdma_cmd = 4; ne2000->ISR.reset = 1; @@ -327,10 +392,9 @@ static void ne2000_reset(void *p, int reset) #include "bswap.h" -// -// read_cr/write_cr - utility routines for handling reads/writes to -// the Command Register -// +/* read_cr/write_cr - utility routines for handling reads/writes to + the Command Register */ + uint32_t ne2000_read_cr(ne2000_t *ne2000) { uint32_t val; @@ -348,14 +412,14 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) { ne2000_log("%s: wrote 0x%02x to CR\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", value); - // Validate remote-DMA + /* Validate remote-DMA */ if ((value & 0x38) == 0x00) { ne2000_log("CR write - invalid rDMA value 0\n"); value |= 0x20; /* dma_cmd == 4 is a safe default */ } - // Check for s/w reset + /* Check for s/w reset */ if (value & 0x01) { ne2000->ISR.reset = 1; @@ -366,8 +430,8 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000->CR.rdma_cmd = (value & 0x38) >> 3; - // If start command issued, the RST bit in the ISR - // must be cleared + /* If start command issued, the RST bit in the ISR */ + /* must be cleared */ if ((value & 0x02) && !ne2000->CR.start) { ne2000->ISR.reset = 0; @@ -376,16 +440,16 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000->CR.start = ((value & 0x02) == 0x02); ne2000->CR.pgsel = (value & 0xc0) >> 6; - // Check for send-packet command + /* Check for send-packet command */ if (ne2000->CR.rdma_cmd == 3) { - // Set up DMA read from receive ring + /* Set up DMA read from receive ring */ ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; ne2000->remote_bytes = (uint16_t) ne2000_chipmem_read(ne2000, ne2000->bound_ptr * 256 + 2, 2); ne2000_log("Sending buffer #x%x length %d\n", ne2000->remote_start, ne2000->remote_bytes); } - // Check for start-tx + /* Check for start-tx */ if ((value & 0x04) && ne2000->TCR.loop_cntl) { if (ne2000->TCR.loop_cntl != 1) @@ -413,7 +477,7 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000_log("CR write - tx start, tx bytes == 0\n"); } - // Send the packet to the system driver + /* Send the packet to the system driver */ ne2000->CR.tx_packet = 1; if(!net_is_pcap) { @@ -426,7 +490,7 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000_log("ne2000 pcap sending packet\n"); } - // some more debug + /* some more debug */ if (ne2000->tx_timer_active) { ne2000_log("CR write, tx timer still active\n"); @@ -435,9 +499,9 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) ne2000_tx_event(ne2000, value); } - // Linux probes for an interrupt by setting up a remote-DMA read - // of 0 bytes with remote-DMA completion interrupts enabled. - // Detect this here + /* Linux probes for an interrupt by setting up a remote-DMA read + of 0 bytes with remote-DMA completion interrupts enabled. + Detect this here */ if (ne2000->CR.rdma_cmd == 0x01 && ne2000->CR.start && ne2000->remote_bytes == 0) @@ -454,14 +518,13 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) } } -// -// chipmem_read/chipmem_write - access the 64K private RAM. -// The ne2000 memory is accessed through the data port of -// the asic (offset 0) after setting up a remote-DMA transfer. -// Both byte and word accesses are allowed. -// The first 16 bytes contains the MAC address at even locations, -// and there is 16K of buffer memory starting at 16K -// +/* chipmem_read/chipmem_write - access the 64K private RAM. + The ne2000 memory is accessed through the data port of + the asic (offset 0) after setting up a remote-DMA transfer. + Both byte and word accesses are allowed. + The first 16 bytes contains the MAC address at even locations, + and there is 16K of buffer memory starting at 16K +*/ uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len) { @@ -472,7 +535,7 @@ uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io ne2000_log("unaligned chipmem word read\n"); } - // ROM'd MAC address + /* ROM'd MAC address */ if ((address >=0) && (address <= 31)) { retval = ne2000->macaddr[address % 32]; @@ -517,8 +580,10 @@ uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io } else { - return (0xff); + return 0xff; } + + return 0xffff; } void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) @@ -547,28 +612,27 @@ void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, un } } -// -// asic_read/asic_write - This is the high 16 bytes of i/o space -// (the lower 16 bytes is for the DS8390). Only two locations -// are used: offset 0, which is used for data transfer, and -// offset 0xf, which is used to reset the device. -// The data transfer port is used to as 'external' DMA to the -// DS8390. The chip has to have the DMA registers set up, and -// after that, insw/outsw instructions can be used to move -// the appropriate number of bytes to/from the device. -// +/* asic_read/asic_write - This is the high 16 bytes of i/o space + (the lower 16 bytes is for the DS8390). Only two locations + are used: offset 0, which is used for data transfer, and + offset 0xf, which is used to reset the device. + The data transfer port is used to as 'external' DMA to the + DS8390. The chip has to have the DMA registers set up, and + after that, insw/outsw instructions can be used to move + the appropriate number of bytes to/from the device. +*/ uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { uint32_t retval = 0; switch (offset) { - case 0x0: // Data register - // - // A read remote-DMA command must have been issued, - // and the source-address and length registers must - // have been initialised. - // + case 0x0: /* Data register */ + + /* A read remote-DMA command must have been issued, + and the source-address and length registers must + have been initialised. */ + if (io_len > ne2000->remote_bytes) { ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); @@ -576,11 +640,11 @@ uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); - // - // The 8390 bumps the address and decreases the byte count - // by the selected word size after every access, not by - // the amount of data requested by the host (io_len). - // + + /* The 8390 bumps the address and decreases the byte count + by the selected word size after every access, not by + the amount of data requested by the host (io_len). */ + if (io_len == 4) { ne2000->remote_dma += io_len; @@ -595,7 +659,7 @@ uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len ne2000->remote_dma = ne2000->page_start << 8; } - // keep s.remote_bytes from underflowing + /* keep s.remote_bytes from underflowing */ if (ne2000->remote_bytes > ne2000->DCR.wdsize) { if (io_len == 4) @@ -612,7 +676,7 @@ uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len ne2000->remote_bytes = 0; } - // If all bytes have been written, signal remote-DMA complete + /* If all bytes have been written, signal remote-DMA complete */ if (ne2000->remote_bytes == 0) { ne2000->ISR.rdma_done = 1; @@ -623,7 +687,7 @@ uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len } break; - case 0xf: // Reset register + case 0xf: /* Reset register */ ne2000_reset(ne2000, BX_RESET_SOFTWARE); break; @@ -640,7 +704,7 @@ void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsign ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); switch (offset) { - case 0x0: // Data register - see asic_read for a description + case 0x0: /* Data register - see asic_read for a description */ if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) { ne2000_log("dma write length %d on byte mode operation\n", io_len); @@ -680,7 +744,7 @@ void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsign ne2000->remote_bytes = 0; } - // If all bytes have been written, signal remote-DMA complete + /* If all bytes have been written, signal remote-DMA complete */ if (ne2000->remote_bytes == 0) { ne2000->ISR.rdma_done = 1; @@ -691,20 +755,19 @@ void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsign } break; - case 0xf: // Reset register - // end of reset pulse + case 0xf: /* Reset register */ + /* end of reset pulse */ break; - default: // this is invalid, but happens under win95 device detection + default: /* this is invalid, but happens under win95 device detection */ ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); break; } } -// -// page0_read/page0_write - These routines handle reads/writes to -// the 'zeroth' page of the DS8390 register file -// +/* page0_read/page0_write - These routines handle reads/writes to + the 'zeroth' page of the DS8390 register file */ + uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { uint8_t value = 0; @@ -717,19 +780,19 @@ uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le switch (offset) { - case 0x1: // CLDA0 + case 0x1: /* CLDA0 */ value = (ne2000->local_dma & 0xff); break; - case 0x2: // CLDA1 + case 0x2: /* CLDA1 */ value = (ne2000->local_dma >> 8); break; - case 0x3: // BNRY + case 0x3: /* BNRY */ value = ne2000->bound_ptr; break; - case 0x4: // TSR + case 0x4: /* TSR */ value = ((ne2000->TSR.ow_coll << 7) | (ne2000->TSR.cd_hbeat << 6) | (ne2000->TSR.fifo_ur << 5) | @@ -739,17 +802,17 @@ uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le (ne2000->TSR.tx_ok)); break; - case 0x5: // NCR + case 0x5: /* NCR */ value = ne2000->num_coll; break; - case 0x6: // FIFO - // reading FIFO is only valid in loopback mode + case 0x6: /* FIFO */ + /* reading FIFO is only valid in loopback mode */ ne2000_log("reading FIFO not supported yet\n"); value = ne2000->fifo; break; - case 0x7: // ISR + case 0x7: /* ISR */ value = ((ne2000->ISR.reset << 7) | (ne2000->ISR.rdma_done << 6) | (ne2000->ISR.cnt_oflow << 5) | @@ -760,15 +823,15 @@ uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le (ne2000->ISR.pkt_rx)); break; - case 0x8: // CRDA0 + case 0x8: /* CRDA0 */ value = (ne2000->remote_dma & 0xff); break; - case 0x9: // CRDA1 + case 0x9: /* CRDA1 */ value = (ne2000->remote_dma >> 8); break; - case 0xa: // reserved / RTL8029ID0 + case 0xa: /* reserved / RTL8029ID0 */ if (network_card_current == 2) { value = 0x50; @@ -780,7 +843,7 @@ uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le } break; - case 0xb: // reserved / RTL8029ID1 + case 0xb: /* reserved / RTL8029ID1 */ if (network_card_current == 2) { value = 0x43; @@ -792,7 +855,7 @@ uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le } break; - case 0xc: // RSR + case 0xc: /* RSR */ value = ((ne2000->RSR.deferred << 7) | (ne2000->RSR.rx_disabled << 6) | (ne2000->RSR.rx_mbit << 5) | @@ -803,15 +866,15 @@ uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le (ne2000->RSR.rx_ok)); break; - case 0xd: // CNTR0 + case 0xd: /* CNTR0 */ value = ne2000->tallycnt_0; break; - case 0xe: // CNTR1 + case 0xe: /* CNTR1 */ value = ne2000->tallycnt_1; break; - case 0xf: // CNTR2 + case 0xf: /* CNTR2 */ value = ne2000->tallycnt_2; break; @@ -828,9 +891,9 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig { uint8_t value2; - // It appears to be a common practice to use outw on page0 regs... + /* It appears to be a common practice to use outw on page0 regs... */ - // break up outw into two outb's + /* break up outw into two outb's */ if (io_len == 2) { ne2000_page0_write(ne2000, offset, (value & 0xff), 1); @@ -845,37 +908,37 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig switch (offset) { - case 0x1: // PSTART + case 0x1: /* PSTART */ ne2000->page_start = value; break; - case 0x2: // PSTOP + case 0x2: /* PSTOP */ ne2000->page_stop = value; break; - case 0x3: // BNRY + case 0x3: /* BNRY */ ne2000->bound_ptr = value; break; - case 0x4: // TPSR + case 0x4: /* TPSR */ ne2000->tx_page_start = value; break; - case 0x5: // TBCR0 - // Clear out low byte and re-insert + case 0x5: /* TBCR0 */ + /* Clear out low byte and re-insert */ ne2000->tx_bytes &= 0xff00; ne2000->tx_bytes |= (value & 0xff); break; - case 0x6: // TBCR1 - // Clear out high byte and re-insert + case 0x6: /* TBCR1 */ + /* Clear out high byte and re-insert */ ne2000->tx_bytes &= 0x00ff; ne2000->tx_bytes |= ((value & 0xff) << 8); break; - case 0x7: // ISR - value &= 0x7f; // clear RST bit - status-only bit - // All other values are cleared iff the ISR bit is 1 + case 0x7: /* ISR */ + value &= 0x7f; /* clear RST bit - status-only bit */ + /* All other values are cleared iff the ISR bit is 1 */ ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); @@ -903,40 +966,40 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig } break; - case 0x8: // RSAR0 - // Clear out low byte and re-insert + case 0x8: /* RSAR0 */ + /* Clear out low byte and re-insert */ ne2000->remote_start &= 0xff00; ne2000->remote_start |= (value & 0xff); ne2000->remote_dma = ne2000->remote_start; break; - case 0x9: // RSAR1 - // Clear out high byte and re-insert + case 0x9: /* RSAR1 */ + /* Clear out high byte and re-insert */ ne2000->remote_start &= 0x00ff; ne2000->remote_start |= ((value & 0xff) << 8); ne2000->remote_dma = ne2000->remote_start; break; - case 0xa: // RBCR0 - // Clear out low byte and re-insert + case 0xa: /* RBCR0 */ + /* Clear out low byte and re-insert */ ne2000->remote_bytes &= 0xff00; ne2000->remote_bytes |= (value & 0xff); break; - case 0xb: // RBCR1 - // Clear out high byte and re-insert + case 0xb: /* RBCR1 */ + /* Clear out high byte and re-insert */ ne2000->remote_bytes &= 0x00ff; ne2000->remote_bytes |= ((value & 0xff) << 8); break; - case 0xc: // RCR - // Check if the reserved bits are set + case 0xc: /* RCR */ + /* Check if the reserved bits are set */ if (value & 0xc0) { ne2000_log("RCR write, reserved bits set\n"); } - // Set all other bit-fields + /* Set all other bit-fields */ ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); ne2000->RCR.broadcast = ((value & 0x04) == 0x04); @@ -944,21 +1007,21 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig ne2000->RCR.promisc = ((value & 0x10) == 0x10); ne2000->RCR.monitor = ((value & 0x20) == 0x20); - // Monitor bit is a little suspicious... + /* Monitor bit is a little suspicious... */ if (value & 0x20) { ne2000_log("RCR write, monitor bit set!\n"); } break; - case 0xd: // TCR - // Check reserved bits + case 0xd: /* TCR */ + /* Check reserved bits */ if (value & 0xe0) { ne2000_log("TCR write, reserved bits set\n"); } - // Test loop mode (not supported) + /* Test loop mode (not supported) */ if (value & 0x06) { ne2000->TCR.loop_cntl = (value & 0x6) >> 1; @@ -969,30 +1032,30 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig ne2000->TCR.loop_cntl = 0; } - // Inhibit-CRC not supported. + /* Inhibit-CRC not supported. */ if (value & 0x01) { ne2000_log("TCR write, inhibit-CRC not supported\n"); } - // Auto-transmit disable very suspicious + /* Auto-transmit disable very suspicious */ if (value & 0x08) { ne2000_log("TCR write, auto transmit disable not supported\n"); } - // Allow collision-offset to be set, although not used + /* Allow collision-offset to be set, although not used */ ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); break; - case 0xe: // DCR - // the loopback mode is not suppported yet + case 0xe: /* DCR */ + /* the loopback mode is not suppported yet */ if (!(value & 0x08)) { ne2000_log("DCR write, loopback mode selected\n"); } - // It is questionable to set longaddr and auto_rx, since they - // aren't supported on the ne2000. Print a warning and continue + /* It is questionable to set longaddr and auto_rx, since they + aren't supported on the ne2000. Print a warning and continue */ if (value & 0x04) { ne2000_log("DCR write - LAS set ???\n"); @@ -1002,23 +1065,23 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig ne2000_log("DCR write - AR set ???\n"); } - // Set other values. + /* Set other values. */ ne2000->DCR.wdsize = ((value & 0x01) == 0x01); ne2000->DCR.endian = ((value & 0x02) == 0x02); - ne2000->DCR.longaddr = ((value & 0x04) == 0x04); // illegal ? + ne2000->DCR.longaddr = ((value & 0x04) == 0x04); /* illegal ? */ ne2000->DCR.loop = ((value & 0x08) == 0x08); - ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); // also illegal ? + ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); /* also illegal ? */ ne2000->DCR.fifo_size = (value & 0x50) >> 5; break; - case 0xf: // IMR - // Check for reserved bit + case 0xf: /* IMR */ + /* Check for reserved bit */ if (value & 0x80) { ne2000_log("IMR write, reserved bit set\n"); } - // Set other values + /* Set other values */ ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); @@ -1049,17 +1112,16 @@ void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig } } -// -// page1_read/page1_write - These routines handle reads/writes to -// the first page of the DS8390 register file -// +/* page1_read/page1_write - These routines handle reads/writes to + the first page of the DS8390 register file */ + uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); switch (offset) { - case 0x1: // PAR0-5 + case 0x1: /* PAR0-5 */ case 0x2: case 0x3: case 0x4: @@ -1067,11 +1129,11 @@ uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le case 0x6: return (ne2000->physaddr[offset - 1]); - case 0x7: // CURR + case 0x7: /* CURR */ ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); return (ne2000->curr_page); - case 0x8: // MAR0-7 + case 0x8: /* MAR0-7 */ case 0x9: case 0xa: case 0xb: @@ -1093,7 +1155,7 @@ void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig switch (offset) { - case 0x1: // PAR0-5 + case 0x1: /* PAR0-5 */ case 0x2: case 0x3: case 0x4: @@ -1106,11 +1168,11 @@ void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig } break; - case 0x7: // CURR + case 0x7: /* CURR */ ne2000->curr_page = value; break; - case 0x8: // MAR0-7 + case 0x8: /* MAR0-7 */ case 0x9: case 0xa: case 0xb: @@ -1127,45 +1189,44 @@ void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig } } -// -// page2_read/page2_write - These routines handle reads/writes to -// the second page of the DS8390 register file -// +/* page2_read/page2_write - These routines handle reads/writes to + the second page of the DS8390 register file */ + uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); switch (offset) { - case 0x1: // PSTART + case 0x1: /* PSTART */ return (ne2000->page_start); - case 0x2: // PSTOP + case 0x2: /* PSTOP */ return (ne2000->page_stop); - case 0x3: // Remote Next-packet pointer + case 0x3: /* Remote Next-packet pointer */ return (ne2000->rempkt_ptr); - case 0x4: // TPSR + case 0x4: /* TPSR */ return (ne2000->tx_page_start); - case 0x5: // Local Next-packet pointer + case 0x5: /* Local Next-packet pointer */ return (ne2000->localpkt_ptr); - case 0x6: // Address counter (upper) + case 0x6: /* Address counter (upper) */ return (ne2000->address_cnt >> 8); - case 0x7: // Address counter (lower) + case 0x7: /* Address counter (lower) */ return (ne2000->address_cnt & 0xff); - case 0x8: // Reserved + case 0x8: /* Reserved */ case 0x9: case 0xa: case 0xb: ne2000_log("reserved read - page 2, register 0x%02x\n", offset); return (0xff); - case 0xc: // RCR + case 0xc: /* RCR */ return ((ne2000->RCR.monitor << 5) | (ne2000->RCR.promisc << 4) | (ne2000->RCR.multicast << 3) | @@ -1173,13 +1234,13 @@ uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le (ne2000->RCR.runts_ok << 1) | (ne2000->RCR.errors_ok)); - case 0xd: // TCR + case 0xd: /* TCR */ return ((ne2000->TCR.coll_prio << 4) | (ne2000->TCR.ext_stoptx << 3) | ((ne2000->TCR.loop_cntl & 0x3) << 1) | (ne2000->TCR.crc_disable)); - case 0xe: // DCR + case 0xe: /* DCR */ return (((ne2000->DCR.fifo_size & 0x3) << 5) | (ne2000->DCR.auto_rx << 4) | (ne2000->DCR.loop << 3) | @@ -1187,7 +1248,7 @@ uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le (ne2000->DCR.endian << 1) | (ne2000->DCR.wdsize)); - case 0xf: // IMR + case 0xf: /* IMR */ return ((ne2000->IMR.rdma_inte << 6) | (ne2000->IMR.cofl_inte << 5) | (ne2000->IMR.overw_inte << 4) | @@ -1206,26 +1267,26 @@ uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_le void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) { - // Maybe all writes here should be BX_PANIC()'d, since they - // affect internal operation, but let them through for now - // and print a warning. + /* Maybe all writes here should be BX_PANIC()'d, since they + affect internal operation, but let them through for now + and print a warning. */ ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); switch (offset) { - case 0x1: // CLDA0 - // Clear out low byte and re-insert + case 0x1: /* CLDA0 */ + /* Clear out low byte and re-insert */ ne2000->local_dma &= 0xff00; ne2000->local_dma |= (value & 0xff); break; - case 0x2: // CLDA1 - // Clear out high byte and re-insert + case 0x2: /* CLDA1 */ + /* Clear out high byte and re-insert */ ne2000->local_dma &= 0x00ff; ne2000->local_dma |= ((value & 0xff) << 8); break; - case 0x3: // Remote Next-pkt pointer + case 0x3: /* Remote Next-pkt pointer */ ne2000->rempkt_ptr = value; break; @@ -1233,18 +1294,18 @@ void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig ne2000_log("page 2 write to reserved register 0x04\n"); break; - case 0x5: // Local Next-packet pointer + case 0x5: /* Local Next-packet pointer */ ne2000->localpkt_ptr = value; break; - case 0x6: // Address counter (upper) - // Clear out high byte and re-insert + case 0x6: /* Address counter (upper) */ + /* Clear out high byte and re-insert */ ne2000->address_cnt &= 0x00ff; ne2000->address_cnt |= ((value & 0xff) << 8); break; - case 0x7: // Address counter (lower) - // Clear out low byte and re-insert + case 0x7: /* Address counter (lower) */ + /* Clear out low byte and re-insert */ ne2000->address_cnt &= 0xff00; ne2000->address_cnt |= (value & 0xff); break; @@ -1266,20 +1327,19 @@ void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsig } } -// -// page3_read/page3_write - writes to this page are illegal -// +/* page3_read/page3_write - writes to this page are illegal */ + uint32_t ne2000_page3_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) { if (network_card_current == 2) { switch (offset) { - case 0x3: // CONFIG0 + case 0x3: /* CONFIG0 */ return (0); - case 0x5: // CONFIG2 + case 0x5: /* CONFIG2 */ return (0x40); - case 0x6: // CONFIG3 + case 0x6: /* CONFIG3 */ return (0x40); default: ne2000_log("page 3 read register 0x%02x attempted\n", offset); @@ -1307,7 +1367,7 @@ void ne2000_tx_event(void *p, uint32_t val) ne2000->CR.tx_packet = 0; ne2000->TSR.tx_ok = 1; ne2000->ISR.pkt_tx = 1; - // Generate an interrupt if not masked + /* Generate an interrupt if not masked */ if (ne2000->IMR.tx_inte) { picint(1 << ne2000->base_irq); @@ -1315,17 +1375,17 @@ void ne2000_tx_event(void *p, uint32_t val) ne2000->tx_timer_active = 0; } -// -// read_handler/read - i/o 'catcher' function called from BOCHS -// mainline when the CPU attempts a read in the i/o space registered -// by this ne2000 instance -// +/* read_handler/read - i/o 'catcher' function called from BOCHS + mainline when the CPU attempts a read in the i/o space registered + by this ne2000 instance */ + uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) { - ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); uint32_t retval = 0; int offset = address - ne2000->base_address; + ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); + if (offset >= 0x10) { retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); @@ -1365,15 +1425,15 @@ uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) { - ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); int offset = address - ne2000->base_address; - // - // The high 16 bytes of i/o space are for the ne2000 asic - - // the low 16 bytes are for the DS8390, with the current - // page being selected by the PS0,PS1 registers in the - // command register - // + ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); + + /* The high 16 bytes of i/o space are for the ne2000 asic - + the low 16 bytes are for the DS8390, with the current + page being selected by the PS0,PS1 registers in the + command register */ + if (offset >= 0x10) { ne2000_asic_write(ne2000, offset - 0x10, value, io_len); @@ -1453,7 +1513,6 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) int pages; int avail; int idx; - int wrapped; int nextpage; uint8_t pkthdr[4]; uint8_t *pktbuf = (uint8_t *) buf; @@ -1473,8 +1532,8 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) return; } - // Add the pkt header + CRC to the length, and work - // out how many 256-byte pages the frame would occupy + /* Add the pkt header + CRC to the length, and work + out how many 256-byte pages the frame would occupy */ pages = (io_len + 4 + 4 + 255)/256; if (ne2000->curr_page < ne2000->bound_ptr) @@ -1484,12 +1543,11 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) else { avail = (ne2000->page_stop - ne2000->page_start) - (ne2000->curr_page - ne2000->bound_ptr); - wrapped = 1; } - // Avoid getting into a buffer overflow condition by not attempting - // to do partial receives. The emulation to handle this condition - // seems particularly painful. + /* Avoid getting into a buffer overflow condition by not attempting + to do partial receives. The emulation to handle this condition + seems particularly painful. */ if ((avail < pages) #if BX_NE2K_NEVER_FULL_RING || (avail == pages) @@ -1505,18 +1563,18 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) ne2000_log("rejected small packet, length %d\n", io_len); return; } - // some computers don't care... + /* some computers don't care... */ if (io_len < 60) { io_len=60; } - // Do address filtering if not in promiscuous mode + /* Do address filtering if not in promiscuous mode */ if (! ne2000->RCR.promisc) { /* Received. */ mac_cmp32[0] = *(uint32_t *) (buf); - mac_cmp16[0] = *(uint16_t *) (buf+4); + mac_cmp16[0] = *(uint16_t *) (((uint8_t *) buf) + 4); /* Local. */ mac_cmp32[1] = *(uint32_t *) (bcast_addr); mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); @@ -1557,19 +1615,19 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) nextpage -= ne2000->page_stop - ne2000->page_start; } - // Setup packet header - pkthdr[0] = 0; // rx status - old behavior - pkthdr[0] = 1; // Probably better to set it all the time - // rather than set it to 0, which is clearly wrong. + /* Setup packet header */ + pkthdr[0] = 0; /* rx status - old behavior + pkthdr[0] = 1; /* Probably better to set it all the time + rather than set it to 0, which is clearly wrong. */ if (pktbuf[0] & 0x01) { - pkthdr[0] |= 0x20; // rx status += multicast packet + pkthdr[0] |= 0x20; /* rx status += multicast packet */ } - pkthdr[1] = nextpage; // ptr to next packet - pkthdr[2] = (io_len + 4) & 0xff; // length-low - pkthdr[3] = (io_len + 4) >> 8; // length-hi + pkthdr[1] = nextpage; /* ptr to next packet */ + pkthdr[2] = (io_len + 4) & 0xff; /* length-low */ + pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ - // copy into buffer, update curpage, and signal interrupt if config'd + /* copy into buffer, update curpage, and signal interrupt if config'd */ startptr = & ne2000->mem[ne2000->curr_page * 256 - BX_NE2K_MEMSTART]; if ((nextpage > ne2000->curr_page) || ((ne2000->curr_page + pages) == ne2000->page_stop)) { @@ -1660,7 +1718,6 @@ void ne2000_poller(void *p) uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; - int res; if (!net_is_pcap) { while(QueuePeek(slirpq) > 0) @@ -1680,7 +1737,7 @@ void ne2000_poller(void *p) { fizz=0;slirp_tic(); } - }//end slirp + } /* end slirp */ else if (net_is_pcap && (net_pcap != NULL)) { if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) @@ -1696,11 +1753,10 @@ void ne2000_poller(void *p) mac_cmp32[0] = *(uint32_t *) (data+6); mac_cmp16[0] = *(uint16_t *) (data+10); /* Local. */ - mac_cmp32[1] = *(uint32_t *) (maclocal); - mac_cmp16[1] = *(uint16_t *) (maclocal+4); + mac_cmp32[1] = *(uint32_t *) (ne2000_mac()); + mac_cmp16[1] = *(uint16_t *) (ne2000_mac() + 4); if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { - // ne2000_log("ne2000 pcap received a frame %d bytes\n",h.caplen); ne2000_rx_frame(ne2000,data,h.caplen); } } @@ -1757,9 +1813,6 @@ void ne2000_io_remove(int16_t addr, ne2000_t *ne2000) uint8_t ne2000_pci_read(int func, int addr, void *p) { - ne2000_t *ne2000 = (ne2000_t *) p; - - // ne2000_log("NE2000 PCI read %08X\n", addr); switch (addr) { case 0x00: @@ -1827,7 +1880,6 @@ void ne2000_update_bios(ne2000_t *ne2000) { int reg_bios_enable; - // reg_bios_enable = ne2000_pci_regs[0x30]; reg_bios_enable = 1; /* PCI BIOS stuff, just enable_disable. */ @@ -1940,8 +1992,7 @@ static char errbuf[32768]; void *ne2000_init() { int rc; - int config_net_type; - int net_type; + int config_net_type; int irq; int pcap_device_available = 0; int is_rtl8029as = 0; @@ -1993,7 +2044,7 @@ void *ne2000_init() ne2000_io_set(ne2000->base_address, ne2000); - memcpy(ne2000->physaddr, maclocal, 6); + memcpy(ne2000->physaddr, ne2000_mac(), 6); if (!disable_netbios) { @@ -2030,7 +2081,6 @@ void *ne2000_init() bios_addr = 0xD0000; } - // ne2000_pci_regs[0x3C] = ide_ter_enabled ? 11 : 10; ne2000_pci_regs[0x3C] = irq; pclog("RTL8029AS IRQ: %i\n", ne2000_pci_regs[0x3C]); ne2000_pci_regs[0x3D] = 1; @@ -2047,7 +2097,7 @@ void *ne2000_init() ne2000_log("ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n",is_rtl8029as ? "pci" : "isa",ne2000->base_address,device_get_config_int("irq"),net_is_pcap); - //need a switch statment for more network types. + /* need a switch statment for more network types. */ if (!net_is_pcap) { initialize_slirp: @@ -2093,10 +2143,10 @@ initialize_pcap: { ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); net_is_pcap=0; - return(ne2000); // YUCK!!! + return(ne2000); /* YUCK!!! */ } - //Time to check that we are in non-blocking mode. + /* Time to check that we are in non-blocking mode. */ rc=pcap_getnonblock(net_pcap,errbuf); ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); switch(rc) @@ -2105,7 +2155,7 @@ initialize_pcap: ne2000_log("ne2000 Setting interface to non-blocking mode.."); rc = pcap_setnonblock(net_pcap,1,errbuf); if (rc==0) - { // no errors! + { /* no errors! */ ne2000_log(".."); rc=pcap_getnonblock(net_pcap,errbuf); if(rc == 1) @@ -2118,7 +2168,7 @@ initialize_pcap: ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); net_is_pcap=0; } - } // end set nonblock + } /* end set nonblock */ else { ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} @@ -2138,10 +2188,10 @@ initialize_pcap: char filter_exp[255]; ne2000_log("ne2000 Building packet filter..."); sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5],\ - maclocal[0], maclocal[1], maclocal[2], maclocal[3], maclocal[4], maclocal[5]); + ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5],\ + ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5]); - //I'm doing a MAC level filter so TCP/IP doesn't matter. + /* I'm doing a MAC level filter so TCP/IP doesn't matter. */ if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { ne2000_log("\nne2000 Couldn't compile filter\n"); @@ -2152,7 +2202,7 @@ initialize_pcap: if (pcap_setfilter(net_pcap, &fp) == -1) { ne2000_log("\nError installing pcap filter.\n"); - }//end of set_filter failure + } /* end of set_filter failure */ else { ne2000_log("...!\n"); @@ -2166,7 +2216,7 @@ initialize_pcap: goto initialize_slirp; } ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } // end pcap setup + } /* end pcap setup */ ne2000_log("ne2000 is_pcap %d\n", net_is_pcap); return ne2000; @@ -2196,199 +2246,120 @@ void ne2000_close(void *p) static device_config_t ne2000_config[] = { { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr", "Address", CONFIG_SELECTION, "", 0x300, { { - .description = "0x280", - .value = 0x280 + "0x280", 0x280 }, { - .description = "0x300", - .value = 0x300 + "0x300", 0x300 }, { - .description = "0x320", - .value = 0x320 + "0x320", 0x320 }, { - .description = "0x340", - .value = 0x340 + "0x340", 0x340 }, { - .description = "0x360", - .value = 0x360 + "0x360", 0x360 }, { - .description = "0x380", - .value = 0x380 + "0x380", 0x380 }, { - .description = "" + "" } }, - .default_int = 0x300 }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 10, { { - .description = "IRQ 3", - .value = 3 + "IRQ 3", 3 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "IRQ 10", - .value = 10 + "IRQ 10", 10 }, { - .description = "IRQ 11", - .value = 11 + "IRQ 11", 11 }, { - .description = "" + "" } }, - .default_int = 10 }, { - .name = "net_type", - .description = "Network type", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "net_type", "Network type", CONFIG_SELECTION, "", 0, { { - .description = "PCap", - .value = 0 + "PCap", 0 }, { - .description = "SLiRP", - .value = 1 + "SLiRP", 1 }, { - .description = "" + "" } }, - .default_int = 0 }, { - .name = "disable_netbios", - .description = "Network bios", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Enabled", - .value = 0 - }, - { - .description = "Disabled", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 + "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 }, { - .type = -1 + "", "", -1 } }; static device_config_t rtl8029as_config[] = { { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 10, { { - .description = "IRQ 3", - .value = 3 + "IRQ 3", 3 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "IRQ 10", - .value = 10 + "IRQ 10", 10 }, { - .description = "IRQ 11", - .value = 11 + "IRQ 11", 11 }, { - .description = "" + "" } }, - .default_int = 10 }, { - .name = "net_type", - .description = "Network type", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "net_type", "Network type", CONFIG_SELECTION, "", 0, { { - .description = "PCap", - .value = 0 + "PCap", 0 }, { - .description = "SLiRP", - .value = 1 + "SLiRP", 1 }, { - .description = "" + "" } }, - .default_int = 0 }, { - .name = "disable_netbios", - .description = "Network bios", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "Enabled", - .value = 0 - }, - { - .description = "Disabled", - .value = 1 - }, - { - .description = "" - } - }, - .default_int = 0 + "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 }, { - .type = -1 + "", "", -1 } }; @@ -2418,7 +2389,7 @@ device_t rtl8029as_device = rtl8029as_config }; -//SLIRP stuff +/* SLIRP stuff */ int slirp_can_output(void) { return net_slirp_inited; @@ -2434,9 +2405,9 @@ void slirp_output (const unsigned char *pkt, int pkt_len) ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); } -// Instead of calling this and crashing some times -// or experencing jitter, this is called by the -// 60Hz clock which seems to do the job. +/* Instead of calling this and crashing some times + or experencing jitter, this is called by the + 60Hz clock which seems to do the job. */ void slirp_tic() { int ret2,nfds; @@ -2450,7 +2421,7 @@ void slirp_tic() FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); - timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); // this can crash + timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); /* this can crash */ if(timeout<0) { @@ -2458,13 +2429,12 @@ void slirp_tic() } tv.tv_sec=0; - tv.tv_usec = timeout; // basilisk default 10000 + tv.tv_usec = timeout; /* basilisk default 10000 */ ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); if(ret2>=0) { slirp_select_poll(&rfds, &wfds, &xfds); } - //ne2000_log("ne2000 slirp_tic()\n"); - } // end if slirp inited + } /* end if slirp inited */ } diff --git a/src/ne2000.h b/src/ne2000.h index 53af3f72f..218685e88 100644 --- a/src/ne2000.h +++ b/src/ne2000.h @@ -1,5 +1,10 @@ /* Copyright holders: SA1988 see COPYING for more details */ +void ne2000_generate_maclocal(int mac); +void ne2000_generate_maclocal_pci(int mac); +int net2000_get_maclocal(); +int net2000_get_maclocal_pci(); + extern device_t ne2000_device; extern device_t rtl8029as_device; diff --git a/src/nethandler.c b/src/nethandler.c index eec4934bf..c399964c6 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -1,8 +1,8 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -#include #include +#include #include #include #include @@ -31,7 +31,7 @@ static NETWORK_CARD network_cards[] = {"None", "none", NULL}, {"Novell NE2000", "ne2k", &ne2000_device}, {"Realtek RTL8029AS", "ne2kpci", &rtl8029as_device}, - {"", NULL} + {"", "", NULL} }; int network_card_available(int card) @@ -96,94 +96,28 @@ static int vlan_handlers_num; static int vlan_poller_time = 0; void vlan_handler(void (*poller)(void *p), void *p) -//void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p) { - /* vlan_handlers[vlan_handlers_num].can_receive = can_receive; */ vlan_handlers[vlan_handlers_num].poller = poller; vlan_handlers[vlan_handlers_num].priv = p; vlan_handlers_num++; } -static thread_t *network_thread_h; -static event_t *network_event; - -static int network_thread_initialized = 0; -static int network_thread_enable = 0; - static void network_thread(void *param) { int c; - // pclog("Network thread\n"); - - // while(1) - // { - // pclog("Waiting...\n"); - // thread_wait_event(network_event, -1); - - // pclog("Processing\n"); - - for (c = 0; c < vlan_handlers_num; c++) - vlan_handlers[c].poller(vlan_handlers[c].priv); - // } -} - -void network_thread_init() -{ -#if 0 - pclog("network_thread_init()\n"); - - if (network_card_current) + for (c = 0; c < vlan_handlers_num; c++) { - pclog("Thread enabled...\n"); - - network_event = thread_create_event(); - network_thread_h = thread_create(network_thread, NULL); + vlan_handlers[c].poller(vlan_handlers[c].priv); } - - network_thread_enable = network_card_current ? 1 : 0; - network_thread_initialized = 1; -#endif -} - -void network_thread_reset() -{ -#if 0 - if(!network_thread_initialized) - { - network_thread_init(); - return; - } - - pclog("network_thread_reset()\n"); - if (network_card_current && !network_thread_enable) - { - pclog("Thread enabled (disabled before...\n"); - network_event = thread_create_event(); - network_thread_h = thread_create(network_thread, NULL); - } - else if (!network_card_current && network_thread_enable) - { - pclog("Thread disabled (enabled before...\n"); - thread_destroy_event(network_event); - thread_kill(network_thread_h); - network_thread_h = NULL; - } - - network_thread_enable = network_card_current ? 1 : 0; -#endif } void vlan_poller(void *priv) { - int c; - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0)); - if (/*network_thread_enable && */ vlan_handlers_num) + if (vlan_handlers_num) { - // pclog("Setting thread event...\n"); - // thread_set_event(network_event); network_thread(priv); } } diff --git a/src/nethandler.h b/src/nethandler.h index 477ecbd81..623dec93b 100644 --- a/src/nethandler.h +++ b/src/nethandler.h @@ -3,7 +3,6 @@ */ #include -//void vlan_handler(int (*can_receive)(void *p), void (*receive)(void *p, const uint8_t *buf, int size), void *p); void vlan_handler(void (*poller)(void *p), void *p); extern int network_card_current; @@ -15,6 +14,7 @@ int network_card_has_config(int card); char *network_card_get_internal_name(int card); int network_card_get_from_internal_name(char *s); void network_card_init(); +void vlan_reset(); void initpcap(); void closepcap(); diff --git a/src/nmi.c b/src/nmi.c index 0e7abdc04..a6ca4480e 100644 --- a/src/nmi.c +++ b/src/nmi.c @@ -2,6 +2,7 @@ see COPYING for more details */ #include "ibm.h" +#include "io.h" #include "nmi.h" int nmi_mask; diff --git a/src/nvr.c b/src/nvr.c index 4fea45468..76c42e7d0 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -8,7 +8,7 @@ int oldromset; int nvrmask=63; -uint8_t nvrram[128]; +char nvrram[128]; int nvraddr; int nvr_dosave = 0; @@ -41,14 +41,12 @@ void nvr_rtc(void *p) } c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); -// pclog("RTCtime now %f\n",rtctime); nvrram[RTC_REGC] |= RTC_PF; if (nvrram[RTC_REGB] & RTC_PIE) { nvrram[RTC_REGC] |= RTC_IRQF; if (AMSTRAD) picint(2); else picint(0x100); -// pclog("RTC int\n"); } } @@ -91,8 +89,6 @@ void nvr_update_end(void *p) else picint(0x100); } } - -// pclog("RTC onesec\n"); nvr_update_end_count = 0; } @@ -117,12 +113,10 @@ void nvr_onesec(void *p) void writenvr(uint16_t addr, uint8_t val, void *priv) { int c, old; -// printf("Write NVR %03X %02X %02X %04X:%04X %i\n",addr,nvraddr,val,cs>>4,pc,ins); if (addr&1) { if (nvraddr==RTC_REGC || nvraddr==RTC_REGD) return; /* Registers C and D are read-only. There's no reason to continue. */ -// if (nvraddr == 0x33) pclog("NVRWRITE33 %02X %04X:%04X %i\n",val,CS,pc,ins); if (nvraddr > RTC_REGD && nvrram[nvraddr] != val) nvr_dosave = 1; @@ -131,7 +125,6 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) if (nvraddr == RTC_REGA) { -// pclog("NVR rate %i\n",val&0xF); if (val & RTC_RS) { c = 1 << ((val & RTC_RS) - 1); @@ -170,7 +163,6 @@ void writenvr(uint16_t addr, uint8_t val, void *priv) uint8_t readnvr(uint16_t addr, void *priv) { uint8_t temp; -// printf("Read NVR %03X %02X %02X %04X:%04X\n",addr,nvraddr,nvrram[nvraddr],cs>>4,pc); if (addr&1) { if (nvraddr == RTC_REGA) @@ -185,8 +177,6 @@ uint8_t readnvr(uint16_t addr, void *priv) nvrram[RTC_REGC] = 0; return temp; } -// if (AMIBIOS && nvraddr==0x36) return 0; -// if (nvraddr==0xA) nvrram[0xA]^=0x80; return nvrram[nvraddr]; } return nvraddr; @@ -210,6 +200,9 @@ void loadnvr() case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); nvrmask = 127; break; + case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "rb"); break; + case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "rb"); break; + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "rb"); break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "rb"); break; case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "rb"); break; @@ -245,6 +238,8 @@ void loadnvr() case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "rb"); nvrmask = 127; break; #endif case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "rb"); nvrmask = 127; break; + case ROM_AP53: f = romfopen(nvr_concat("ap53.nvr"), "rb"); nvrmask = 127; break; + case ROM_P55T2S: f = romfopen(nvr_concat("p55t2s.nvr"), "rb"); nvrmask = 127; break; case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "rb"); nvrmask = 127; break; case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "rb"); nvrmask = 127; break; case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "rb"); nvrmask = 127; break; @@ -260,6 +255,7 @@ void loadnvr() #if 0 case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "rb"); nvrmask = 127; break; #endif + case ROM_S1668: f = romfopen(nvr_concat("tpatx.nvr"), "rb"); nvrmask = 127; break; default: return; } if (!f) @@ -301,6 +297,9 @@ void savenvr() case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "wb"); break; case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "wb"); break; case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "wb"); break; + case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "wb"); break; + case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "wb"); break; + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "wb"); break; case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "wb"); break; case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "wb"); break; @@ -336,6 +335,8 @@ void savenvr() case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "wb"); break; #endif case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "wb"); break; + case ROM_AP53: f = romfopen(nvr_concat("ap53.nvr"), "wb"); break; + case ROM_P55T2S: f = romfopen(nvr_concat("p55t2s.nvr"), "wb"); break; case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "wb"); break; case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "wb"); break; case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "wb"); break; @@ -351,6 +352,7 @@ void savenvr() #if 0 case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "wb"); break; #endif + case ROM_S1668: f = romfopen(nvr_concat("tpatx.nvr"), "wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/nvr.h b/src/nvr.h index a333db555..069a476a7 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -9,3 +9,7 @@ extern int nvr_dosave; void time_get(char *nvrram); +void nvr_recalc(); + +void loadnvr(); +void savenvr(); diff --git a/src/opti495.c b/src/opti495.c index c173c5be3..2567782bd 100644 --- a/src/opti495.c +++ b/src/opti495.c @@ -29,13 +29,10 @@ static void opti495_write(uint16_t addr, uint8_t val, void *p) { shadowbios = !(val & 0x80); shadowbios_write = val & 0x80; - //pclog("shadowbios %i %02x\n", shadowbios, val); if (shadowbios) mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); else mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); -// if (shadowbios) -// fatal("Here\n"); } } break; @@ -47,7 +44,6 @@ static uint8_t opti495_read(uint16_t addr, void *p) switch (addr) { case 0x24: - //printf("Read OPTI reg %02X\n",optireg); if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20]; break; } diff --git a/src/pc.c b/src/pc.c index 1b46fcba9..2c9f891ad 100644 --- a/src/pc.c +++ b/src/pc.c @@ -5,21 +5,28 @@ #include #include +#include "86box.h" +#include "ibm.h" +#include "device.h" + #ifndef __unix #define BITMAP WINDOWS_BITMAP #include #undef BITMAP #include "win.h" +#include "win-language.h" #endif -#include "86box.h" -#include "ibm.h" -#include "device.h" - #include "ali1429.h" #include "cdrom.h" #include "cdrom-ioctl.h" #include "disc.h" +#include "disc_86f.h" +#include "disc_fdi.h" +#include "disc_imd.h" +#include "disc_img.h" +#include "disc_random.h" +#include "disc_td0.h" #include "mem.h" #include "x86_ops.h" #include "codegen.h" @@ -32,25 +39,30 @@ #include "fdd.h" #include "gameport.h" #include "sound_gus.h" -#include "buslogic.h" +#include "ide.h" #include "cdrom.h" #include "scsi.h" -#include "ide.h" #include "keyboard.h" #include "keyboard_at.h" +#include "mem.h" #include "model.h" #include "mouse.h" +#include "ne2000.h" +#include "nethandler.h" #include "nvr.h" #include "pic.h" #include "pit.h" #include "plat-joystick.h" +#include "plat-midi.h" #include "plat-mouse.h" +#include "plat-keyboard.h" #include "serial.h" #include "sound.h" #include "sound_cms.h" #include "sound_dbopl.h" #include "sound_opl.h" #include "sound_sb.h" +#include "sound_speaker.h" #include "sound_ssi2001.h" #include "timer.h" #include "vid_voodoo.h" @@ -68,6 +80,7 @@ int path_len; int window_w, window_h, window_x, window_y, window_remember; +int dump_on_exit = 0; int start_in_fullscreen = 0; int CPUID; @@ -90,7 +103,6 @@ int atfullspeed; void saveconfig(); int infocus; int mousecapture; -// FILE *pclogf; void pclog(const char *format, ...) { #ifndef RELEASE_BUILD @@ -153,10 +165,10 @@ void fatal(const char *format, ...) { *newline = 0; } - MessageBox(ghwnd, msg, "86Box fatal error", MB_OK + MB_ICONERROR); + msgbox_fatal(ghwnd, msg); #endif dumppic(); - dumpregs(); + dumpregs(1); fflush(stdout); exit(-1); } @@ -167,15 +179,12 @@ int pollmouse_delay = 2; void pollmouse() { int x, y, z; -// return; pollmouse_delay--; if (pollmouse_delay) return; pollmouse_delay = 2; mouse_poll_host(); mouse_get_mickeys(&x, &y, &z); - if (mouse_poll) - mouse_poll(x, y, z, mouse_buttons); -// if (mousecapture) position_mouse(64,64); + mouse_poll(x, y, z, mouse_buttons); } /*PC1512 languages - @@ -238,22 +247,17 @@ void pc_reset() { cpu_set(); resetx86(); - //timer_reset(); dma_reset(); fdc_reset(); pic_reset(); - pit_reset(); serial_reset(); if (AT) setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); else setpitclock(14318184.0); - -// sb_reset(); ali1429_reset(); -// video_init(); } #undef printf void initpc(int argc, char *argv[]) @@ -262,7 +266,6 @@ void initpc(int argc, char *argv[]) char *config_file = NULL; int c, i; FILE *ff; -// allegro_init(); get_executable_name(pcempath,511); pclog("executable_name = %s\n", pcempath); p=get_filename(pcempath); @@ -275,13 +278,10 @@ void initpc(int argc, char *argv[]) { printf("PCem command line options :\n\n"); printf("--config file.cfg - use given config file as initial configuration\n"); + printf("--dump - always dump memory on exit\n"); printf("--fullscreen - start in fullscreen mode\n"); exit(-1); } - else if (!strcasecmp(argv[c], "--fullscreen")) - { - start_in_fullscreen = 1; - } else if (!strcasecmp(argv[c], "--config")) { if ((c+1) == argc) @@ -289,6 +289,21 @@ void initpc(int argc, char *argv[]) config_file = argv[c+1]; c++; } + else if (!strcasecmp(argv[c], "--dump")) + { + dump_on_exit = 1; + } + else if (!strcasecmp(argv[c], "--fullscreen")) + { + start_in_fullscreen = 1; + } + else if (!strcasecmp(argv[c], "--test")) + { + /* some (undocumented) test function here.. */ + + /* .. and then exit. */ + exit(0); + } } keyboard_init(); @@ -303,6 +318,8 @@ void initpc(int argc, char *argv[]) { append_filename(config_file_default, pcempath, config_file, 511); } + + disc_random_init(); loadconfig(config_file); pclog("Config loaded\n"); @@ -312,7 +329,6 @@ void initpc(int argc, char *argv[]) joystick_init(); cpuspeed2=(AT)?2:1; -// cpuspeed2=cpuspeed; atfullspeed=0; initvideo(); @@ -369,44 +385,24 @@ void initpc(int argc, char *argv[]) td0_init(); imd_init(); -#if 0 - if (network_card_current != 0) - { - vlan_reset(); //NETWORK - } - network_card_init(network_card_current); - network_thread_init(); -#endif - disc_load(0, discfns[0]); disc_load(1, discfns[1]); disc_load(2, discfns[2]); disc_load(3, discfns[3]); - //loadfont(); loadnvr(); sound_init(); resetide(); - if (buslogic_enabled) - { - device_add(&BuslogicDevice); - } + scsi_card_init(); - pit_reset(); -/* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); + fullspeed(); ali1429_reset(); -// CPUID=(is486 && (cpuspeed==7 || cpuspeed>=9)); -// pclog("Init - CPUID %i %i\n",CPUID,cpuspeed); shadowbios=0; for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].host_drive == 0) - { - cdrom_null_reset(i); - } - else + if (cdrom_drives[i].host_drive != 0) { if (cdrom_drives[i].host_drive == 200) { @@ -423,9 +419,6 @@ void initpc(int argc, char *argv[]) void resetpc() { pc_reset(); -// cpuspeed2=(AT)?2:1; -// atfullspeed=0; -///* if (romset==ROM_AMI386 || romset==ROM_AMI486) */fullspeed(); shadowbios=0; } @@ -477,7 +470,6 @@ void resetpchard() model_init(); mouse_emu_init(); - // mem_add_bios(); video_init(); speaker_init(); @@ -496,10 +488,9 @@ void resetpchard() if (network_card_current != 0) { - vlan_reset(); //NETWORK + vlan_reset(); /* NETWORK */ } network_card_init(network_card_current); - network_thread_reset(); for (i = 0; i < CDROM_NUM; i++) { @@ -510,10 +501,7 @@ void resetpchard() } resetide(); - if (buslogic_enabled) - { - device_add(&BuslogicDevice); - } + scsi_card_init(); sound_card_init(sound_card_current); if (GUS) @@ -529,10 +517,6 @@ void resetpchard() loadnvr(); -// cpuspeed2 = (AT)?2:1; -// atfullspeed = 0; -// setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); - shadowbios = 0; ali1429_reset(); @@ -540,15 +524,9 @@ void resetpchard() cpu_cache_int_enabled = cpu_cache_ext_enabled = 0; -// output=3; - for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].host_drive == 0) - { - cdrom_null_reset(i); - } - else + if (cdrom_drives[i].host_drive != 0) { if (cdrom_drives[i].host_drive == 200) { @@ -597,22 +575,24 @@ void runpc() exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); } else if (AT) + { exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); + } else + { execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); + } keyboard_poll_host(); keyboard_process(); -// checkkeys(); pollmouse(); if (joystick_type != 7) joystick_poll(); - endblit(); + endblit(); framecountx++; framecount++; if (framecountx>=100) { - // pclog("onesec\n"); framecountx=0; mips=(float)insc/1000000.0f; insc=0; @@ -673,8 +653,6 @@ void fullspeed() setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); else setpitclock(14318184.0); -// if (is386) setpitclock(clocks[2][cpuspeed2][0]); -// else setpitclock(clocks[AT?1:0][cpuspeed2][0]); } atfullspeed=1; nvr_recalc(); @@ -696,16 +674,12 @@ void closepc() { cdrom_drives[i].handler->exit(i); } -// ioctl_close(); dumppic(); -// output=7; -// setpitclock(clocks[0][0][0]); -// while (1) runpc(); disc_close(0); disc_close(1); disc_close(2); disc_close(3); - dumpregs(); + dumpregs(0); closevideo(); device_close_all(); midi_close(); @@ -729,6 +703,7 @@ void loadconfig(char *fn) int c, d; char s[512]; char *p; + char temps[512]; if (!fn) config_load(config_file_default); @@ -739,9 +714,15 @@ void loadconfig(char *fn) GUS = config_get_int(NULL, "gus", 0); SSI2001 = config_get_int(NULL, "ssi2001", 0); voodoo_enabled = config_get_int(NULL, "voodoo", 0); - buslogic_enabled = config_get_int(NULL, "buslogic", 0); - //network + /* SCSI */ + p = (char *)config_get_string(NULL, "scsicard", ""); + if (p) + scsi_card_current = scsi_card_get_from_internal_name(p); + else + scsi_card_current = 0; + + /* network */ ethif = config_get_int(NULL, "netinterface", 1); if (ethif >= inum) inum = ethif + 1; @@ -750,6 +731,8 @@ void loadconfig(char *fn) network_card_current = network_card_get_from_internal_name(p); else network_card_current = 0; + ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); + ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); p = (char *)config_get_string(NULL, "model", ""); if (p) @@ -778,29 +761,22 @@ void loadconfig(char *fn) sound_card_current = sound_card_get_from_internal_name(p); else sound_card_current = 0; + + mem_size = config_get_int(NULL, "mem_size", 4096); + if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - // d86f_unregister(0); - // d86f_unregister(1); - - p = (char *)config_get_string(NULL, "disc_a", ""); - if (p) strcpy(discfns[0], p); - else strcpy(discfns[0], ""); - ui_writeprot[0] = config_get_int(NULL, "disc_a_writeprot", 0); - - p = (char *)config_get_string(NULL, "disc_b", ""); - if (p) strcpy(discfns[1], p); - else strcpy(discfns[1], ""); - ui_writeprot[1] = config_get_int(NULL, "disc_b_writeprot", 0); - - p = (char *)config_get_string(NULL, "disc_3", ""); - if (p) strcpy(discfns[2], p); - else strcpy(discfns[2], ""); - ui_writeprot[2] = config_get_int(NULL, "disc_3_writeprot", 0); - - p = (char *)config_get_string(NULL, "disc_4", ""); - if (p) strcpy(discfns[3], p); - else strcpy(discfns[3], ""); - ui_writeprot[3] = config_get_int(NULL, "disc_4_writeprot", 0); + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + fdd_set_type(c, config_get_int(NULL, temps, (c < 2) ? 2 : 0)); + sprintf(temps, "fdd_%02i_fn", c + 1); + p = (char *)config_get_string(NULL, temps, ""); + if (p) strcpy(discfns[c], p); + else strcpy(discfns[c], ""); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = config_get_int(NULL, temps, 0); + } p = (char *)config_get_string(NULL, "hdd_controller", ""); if (p) @@ -808,130 +784,72 @@ void loadconfig(char *fn) else strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); - mem_size = config_get_int(NULL, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + ide_enable[c] = config_get_int(NULL, temps, 0); + sprintf(temps, "ide_%02i_irq", c + 1); + ide_irq[c] = config_get_int(NULL, temps, 8 + c); + } - cdrom_drives[0].host_drive = config_get_int(NULL, "cdrom_1_host_drive", 0); - cdrom_drives[0].prev_host_drive = cdrom_drives[0].host_drive; - cdrom_drives[0].enabled = config_get_int(NULL, "cdrom_1_enabled", 0); - cdrom_drives[0].sound_on = config_get_int(NULL, "cdrom_1_sound_on", 1); - cdrom_drives[0].bus_type = config_get_int(NULL, "cdrom_1_bus_type", 0); - cdrom_drives[0].atapi_dma = config_get_int(NULL, "cdrom_1_atapi_dma", 1); - cdrom_drives[0].ide_channel = config_get_int(NULL, "cdrom_1_ide_channel", 2); - cdrom_drives[0].scsi_device_id = config_get_int(NULL, "cdrom_1_scsi_device_id", 2); - cdrom_drives[0].scsi_device_lun = config_get_int(NULL, "cdrom_1_scsi_device_lun", 0); + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + hdc[c].spt = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_heads", c + 1); + hdc[c].hpc = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + hdc[c].tracks = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + hdc[c].bus = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + hdc[c].mfm_channel = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + hdc[c].ide_channel = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + hdc[c].scsi_lun = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_fn", c + 1); + p = (char *)config_get_string(NULL, temps, ""); + if (p) strcpy(hdd_fn[c], p); + else strcpy(hdd_fn[c], ""); + } - p = (char *)config_get_string(NULL, "cdrom_1_iso_path", ""); - if (p) strcpy(cdrom_iso[0].iso_path, p); - else strcpy(cdrom_iso[0].iso_path, ""); + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); + cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; + sprintf(temps, "cdrom_%02i_enabled", c + 1); + cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); - cdrom_drives[1].host_drive = config_get_int(NULL, "cdrom_2_host_drive", 0); - cdrom_drives[1].prev_host_drive = cdrom_drives[1].host_drive; - cdrom_drives[1].enabled = config_get_int(NULL, "cdrom_2_enabled", 0); - cdrom_drives[1].sound_on = config_get_int(NULL, "cdrom_2_sound_on", 1); - cdrom_drives[1].bus_type = config_get_int(NULL, "cdrom_2_bus_type", 0); - cdrom_drives[1].atapi_dma = config_get_int(NULL, "cdrom_2_atapi_dma", 1); - cdrom_drives[1].ide_channel = config_get_int(NULL, "cdrom_2_ide_channel", 3); - cdrom_drives[1].scsi_device_id = config_get_int(NULL, "cdrom_2_scsi_device_id", 3); - cdrom_drives[1].scsi_device_lun = config_get_int(NULL, "cdrom_2_scsi_device_lun", 0); - - p = (char *)config_get_string(NULL, "cdrom_2_iso_path", ""); - if (p) strcpy(cdrom_iso[1].iso_path, p); - else strcpy(cdrom_iso[1].iso_path, ""); - - cdrom_drives[2].host_drive = config_get_int(NULL, "cdrom_3_host_drive", 0); - cdrom_drives[2].prev_host_drive = cdrom_drives[2].host_drive; - cdrom_drives[2].enabled = config_get_int(NULL, "cdrom_3_enabled", 0); - cdrom_drives[2].sound_on = config_get_int(NULL, "cdrom_3_sound_on", 1); - cdrom_drives[2].bus_type = config_get_int(NULL, "cdrom_3_bus_type", 0); - cdrom_drives[2].atapi_dma = config_get_int(NULL, "cdrom_3_atapi_dma", 1); - cdrom_drives[2].ide_channel = config_get_int(NULL, "cdrom_3_ide_channel", 4); - cdrom_drives[2].scsi_device_id = config_get_int(NULL, "cdrom_3_scsi_device_id", 4); - cdrom_drives[2].scsi_device_lun = config_get_int(NULL, "cdrom_3_scsi_device_lun", 0); - - p = (char *)config_get_string(NULL, "cdrom_3_iso_path", ""); - if (p) strcpy(cdrom_iso[2].iso_path, p); - else strcpy(cdrom_iso[2].iso_path, ""); - - cdrom_drives[3].host_drive = config_get_int(NULL, "cdrom_4_host_drive", 0); - cdrom_drives[3].prev_host_drive = cdrom_drives[3].host_drive; - cdrom_drives[3].enabled = config_get_int(NULL, "cdrom_4_enabled", 0); - cdrom_drives[3].sound_on = config_get_int(NULL, "cdrom_4_sound_on", 1); - cdrom_drives[3].bus_type = config_get_int(NULL, "cdrom_4_bus_type", 0); - cdrom_drives[3].atapi_dma = config_get_int(NULL, "cdrom_4_atapi_dma", 1); - cdrom_drives[3].ide_channel = config_get_int(NULL, "cdrom_4_ide_channel", 5); - cdrom_drives[3].scsi_device_id = config_get_int(NULL, "cdrom_4_scsi_device_id", 5); - cdrom_drives[3].scsi_device_lun = config_get_int(NULL, "cdrom_4_scsi_device_lun", 0); - - p = (char *)config_get_string(NULL, "cdrom_4_iso_path", ""); - if (p) strcpy(cdrom_iso[3].iso_path, p); - else strcpy(cdrom_iso[3].iso_path, ""); + sprintf(temps, "cdrom_%02i_iso_path", c + 1); + p = (char *)config_get_string(NULL, temps, ""); + if (p) strcpy(cdrom_iso[c].iso_path, p); + else strcpy(cdrom_iso[c].iso_path, ""); + } vid_resize = config_get_int(NULL, "vid_resize", 0); vid_api = config_get_int(NULL, "vid_api", 0); video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); - hdc[0].spt = config_get_int(NULL, "hdc_sectors", 0); - hdc[0].hpc = config_get_int(NULL, "hdc_heads", 0); - hdc[0].tracks = config_get_int(NULL, "hdc_cylinders", 0); - p = (char *)config_get_string(NULL, "hdc_fn", ""); - if (p) strcpy(ide_fn[0], p); - else strcpy(ide_fn[0], ""); - hdc[1].spt = config_get_int(NULL, "hdd_sectors", 0); - hdc[1].hpc = config_get_int(NULL, "hdd_heads", 0); - hdc[1].tracks = config_get_int(NULL, "hdd_cylinders", 0); - p = (char *)config_get_string(NULL, "hdd_fn", ""); - if (p) strcpy(ide_fn[1], p); - else strcpy(ide_fn[1], ""); - hdc[2].spt = config_get_int(NULL, "hde_sectors", 0); - hdc[2].hpc = config_get_int(NULL, "hde_heads", 0); - hdc[2].tracks = config_get_int(NULL, "hde_cylinders", 0); - p = (char *)config_get_string(NULL, "hde_fn", ""); - if (p) strcpy(ide_fn[2], p); - else strcpy(ide_fn[2], ""); - hdc[3].spt = config_get_int(NULL, "hdf_sectors", 0); - hdc[3].hpc = config_get_int(NULL, "hdf_heads", 0); - hdc[3].tracks = config_get_int(NULL, "hdf_cylinders", 0); - p = (char *)config_get_string(NULL, "hdf_fn", ""); - if (p) strcpy(ide_fn[3], p); - else strcpy(ide_fn[3], ""); - hdc[4].spt = config_get_int(NULL, "hdg_sectors", 0); - hdc[4].hpc = config_get_int(NULL, "hdg_heads", 0); - hdc[4].tracks = config_get_int(NULL, "hdg_cylinders", 0); - p = (char *)config_get_string(NULL, "hdg_fn", ""); - if (p) strcpy(ide_fn[4], p); - else strcpy(ide_fn[4], ""); - hdc[5].spt = config_get_int(NULL, "hdh_sectors", 0); - hdc[5].hpc = config_get_int(NULL, "hdh_heads", 0); - hdc[5].tracks = config_get_int(NULL, "hdh_cylinders", 0); - p = (char *)config_get_string(NULL, "hdh_fn", ""); - if (p) strcpy(ide_fn[5], p); - else strcpy(ide_fn[5], ""); - hdc[6].spt = config_get_int(NULL, "hdi_sectors", 0); - hdc[6].hpc = config_get_int(NULL, "hdi_heads", 0); - hdc[6].tracks = config_get_int(NULL, "hdi_cylinders", 0); - p = (char *)config_get_string(NULL, "hdi_fn", ""); - if (p) strcpy(ide_fn[6], p); - else strcpy(ide_fn[6], ""); - hdc[7].spt = config_get_int(NULL, "hdj_sectors", 0); - hdc[7].hpc = config_get_int(NULL, "hdj_heads", 0); - hdc[7].tracks = config_get_int(NULL, "hdj_cylinders", 0); - p = (char *)config_get_string(NULL, "hdj_fn", ""); - if (p) strcpy(ide_fn[7], p); - else strcpy(ide_fn[7], ""); - - ide_enable[2] = config_get_int(NULL, "ide_ter_enable", 0); - ide_irq[2] = config_get_int(NULL, "ide_ter_irq", 10); - ide_enable[3] = config_get_int(NULL, "ide_qua_enable", 0); - ide_irq[3] = config_get_int(NULL, "ide_qua_irq", 11); - - fdd_set_type(0, config_get_int(NULL, "drive_a_type", 1)); - fdd_set_type(1, config_get_int(NULL, "drive_b_type", 1)); - fdd_set_type(2, config_get_int(NULL, "drive_3_type", 1)); - fdd_set_type(3, config_get_int(NULL, "drive_4_type", 1)); - force_43 = config_get_int(NULL, "force_43", 0); scale = config_get_int(NULL, "scale", 1); enable_overscan = config_get_int(NULL, "enable_overscan", 0); @@ -947,7 +865,11 @@ void loadconfig(char *fn) window_remember = config_get_int(NULL, "window_remember", 0); joystick_type = config_get_int(NULL, "joystick_type", 0); - mouse_type = config_get_int(NULL, "mouse_type", 0); + p = (char *)config_get_string(NULL, "mouse_type", ""); + if (p) + mouse_type = mouse_get_from_internal_name(p); + else + mouse_type = 0; enable_xtide = config_get_int(NULL, "enable_xtide", 1); enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); @@ -993,6 +915,11 @@ void loadconfig(char *fn) } path_len = strlen(nvr_path); + + serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); + serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); + lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); + bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); } char *nvr_concat(char *to_concat) @@ -1006,14 +933,19 @@ void saveconfig() { int c, d; + char temps[512]; + config_set_int(NULL, "gameblaster", GAMEBLASTER); config_set_int(NULL, "gus", GUS); config_set_int(NULL, "ssi2001", SSI2001); config_set_int(NULL, "voodoo", voodoo_enabled); - config_set_int(NULL, "buslogic", buslogic_enabled); + + config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); config_set_int(NULL, "netinterface", ethif); config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); + config_set_int(NULL, "maclocal", net2000_get_maclocal()); + config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); config_set_string(NULL, "model", model_get_internal_name()); config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); @@ -1026,109 +958,82 @@ void saveconfig() config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); config_set_int(NULL, "cpu_speed", cpuspeed); config_set_int(NULL, "has_fpu", hasfpu); - config_set_string(NULL, "disc_a", discfns[0]); - config_set_int(NULL, "disc_a_writeprot", ui_writeprot[0]); - config_set_string(NULL, "disc_b", discfns[1]); - config_set_int(NULL, "disc_b_writeprot", ui_writeprot[1]); - config_set_string(NULL, "disc_3", discfns[2]); - config_set_int(NULL, "disc_3_writeprot", ui_writeprot[2]); - config_set_string(NULL, "disc_4", discfns[3]); - config_set_int(NULL, "disc_4_writeprot", ui_writeprot[3]); - config_set_string(NULL, "hdd_controller", hdd_controller_name); config_set_int(NULL, "mem_size", mem_size); - config_set_int(NULL, "cdrom_1_host_drive", cdrom_drives[0].host_drive); - config_set_int(NULL, "cdrom_1_enabled", cdrom_drives[0].enabled); - config_set_int(NULL, "cdrom_1_sound_on", cdrom_drives[0].sound_on); - config_set_int(NULL, "cdrom_1_bus_type", cdrom_drives[0].bus_type); - config_set_int(NULL, "cdrom_1_atapi_dma", cdrom_drives[0].atapi_dma); - config_set_int(NULL, "cdrom_1_ide_channel", cdrom_drives[0].ide_channel); - config_set_int(NULL, "cdrom_1_scsi_device_id", cdrom_drives[0].scsi_device_id); - config_set_int(NULL, "cdrom_1_scsi_device_lun", cdrom_drives[0].scsi_device_lun); + memset(temps, 0, 512); + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_set_int(NULL, temps, fdd_get_type(c)); + sprintf(temps, "fdd_%02i_fn", c + 1); + config_set_string(NULL, temps, discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_set_int(NULL, temps, ui_writeprot[c]); + } - config_set_string(NULL, "cdrom_1_iso_path", cdrom_iso[0].iso_path); + config_set_string(NULL, "hdd_controller", hdd_controller_name); - config_set_int(NULL, "cdrom_2_host_drive", cdrom_drives[1].host_drive); - config_set_int(NULL, "cdrom_2_enabled", cdrom_drives[1].enabled); - config_set_int(NULL, "cdrom_2_sound_on", cdrom_drives[1].sound_on); - config_set_int(NULL, "cdrom_2_bus_type", cdrom_drives[1].bus_type); - config_set_int(NULL, "cdrom_2_ide_channel", cdrom_drives[1].ide_channel); - config_set_int(NULL, "cdrom_2_atapi_dma", cdrom_drives[1].atapi_dma); - config_set_int(NULL, "cdrom_2_scsi_device_id", cdrom_drives[1].scsi_device_id); - config_set_int(NULL, "cdrom_2_scsi_device_lun", cdrom_drives[1].scsi_device_lun); + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + config_set_int(NULL, temps, ide_enable[c]); + sprintf(temps, "ide_%02i_irq", c + 1); + config_set_int(NULL, temps, ide_irq[c]); + } - config_set_string(NULL, "cdrom_2_iso_path", cdrom_iso[1].iso_path); + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + config_set_int(NULL, temps, hdc[c].spt); + sprintf(temps, "hdd_%02i_heads", c + 1); + config_set_int(NULL, temps, hdc[c].hpc); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + config_set_int(NULL, temps, hdc[c].tracks); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + config_set_int(NULL, temps, hdc[c].bus); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + config_set_int(NULL, temps, hdc[c].mfm_channel); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, hdc[c].ide_channel); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_id); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_lun); + sprintf(temps, "hdd_%02i_fn", c + 1); + config_set_string(NULL, temps, hdd_fn[c]); + } - config_set_int(NULL, "cdrom_3_host_drive", cdrom_drives[2].host_drive); - config_set_int(NULL, "cdrom_3_enabled", cdrom_drives[2].enabled); - config_set_int(NULL, "cdrom_3_sound_on", cdrom_drives[2].sound_on); - config_set_int(NULL, "cdrom_3_bus_type", cdrom_drives[2].bus_type); - config_set_int(NULL, "cdrom_3_atapi_dma", cdrom_drives[2].atapi_dma); - config_set_int(NULL, "cdrom_3_ide_channel", cdrom_drives[2].ide_channel); - config_set_int(NULL, "cdrom_3_scsi_device_id", cdrom_drives[2].scsi_device_id); - config_set_int(NULL, "cdrom_3_scsi_device_lun", cdrom_drives[2].scsi_device_lun); + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].host_drive); + sprintf(temps, "cdrom_%02i_enabled", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].enabled); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].sound_on); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].bus_type); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].ide_channel); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); - config_set_string(NULL, "cdrom_3_iso_path", cdrom_iso[2].iso_path); - - config_set_int(NULL, "cdrom_4_host_drive", cdrom_drives[3].host_drive); - config_set_int(NULL, "cdrom_4_enabled", cdrom_drives[3].enabled); - config_set_int(NULL, "cdrom_4_sound_on", cdrom_drives[3].sound_on); - config_set_int(NULL, "cdrom_4_bus_type", cdrom_drives[3].bus_type); - config_set_int(NULL, "cdrom_4_atapi_dma", cdrom_drives[3].atapi_dma); - config_set_int(NULL, "cdrom_4_ide_channel", cdrom_drives[3].ide_channel); - config_set_int(NULL, "cdrom_4_scsi_device_id", cdrom_drives[3].scsi_device_id); - config_set_int(NULL, "cdrom_4_scsi_device_lun", cdrom_drives[3].scsi_device_lun); - - config_set_string(NULL, "cdrom_4_iso_path", cdrom_iso[3].iso_path); + sprintf(temps, "cdrom_%02i_iso_path", c + 1); + config_set_string(NULL, temps, cdrom_iso[c].iso_path); + } config_set_int(NULL, "vid_resize", vid_resize); config_set_int(NULL, "vid_api", vid_api); config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); - - config_set_int(NULL, "hdc_sectors", hdc[0].spt); - config_set_int(NULL, "hdc_heads", hdc[0].hpc); - config_set_int(NULL, "hdc_cylinders", hdc[0].tracks); - config_set_string(NULL, "hdc_fn", ide_fn[0]); - config_set_int(NULL, "hdd_sectors", hdc[1].spt); - config_set_int(NULL, "hdd_heads", hdc[1].hpc); - config_set_int(NULL, "hdd_cylinders", hdc[1].tracks); - config_set_string(NULL, "hdd_fn", ide_fn[1]); - config_set_int(NULL, "hde_sectors", hdc[2].spt); - config_set_int(NULL, "hde_heads", hdc[2].hpc); - config_set_int(NULL, "hde_cylinders", hdc[2].tracks); - config_set_string(NULL, "hde_fn", ide_fn[2]); - config_set_int(NULL, "hdf_sectors", hdc[3].spt); - config_set_int(NULL, "hdf_heads", hdc[3].hpc); - config_set_int(NULL, "hdf_cylinders", hdc[3].tracks); - config_set_string(NULL, "hdf_fn", ide_fn[3]); - config_set_int(NULL, "hdg_sectors", hdc[4].spt); - config_set_int(NULL, "hdg_heads", hdc[4].hpc); - config_set_int(NULL, "hdg_cylinders", hdc[4].tracks); - config_set_string(NULL, "hdg_fn", ide_fn[4]); - config_set_int(NULL, "hdh_sectors", hdc[5].spt); - config_set_int(NULL, "hdh_heads", hdc[5].hpc); - config_set_int(NULL, "hdh_cylinders", hdc[5].tracks); - config_set_string(NULL, "hdh_fn", ide_fn[5]); - config_set_int(NULL, "hdi_sectors", hdc[6].spt); - config_set_int(NULL, "hdi_heads", hdc[6].hpc); - config_set_int(NULL, "hdi_cylinders", hdc[6].tracks); - config_set_string(NULL, "hdi_fn", ide_fn[6]); - config_set_int(NULL, "hdj_sectors", hdc[7].spt); - config_set_int(NULL, "hdj_heads", hdc[7].hpc); - config_set_int(NULL, "hdj_cylinders", hdc[7].tracks); - config_set_string(NULL, "hdj_fn", ide_fn[7]); - - config_set_int(NULL, "ide_ter_enable", ide_enable[2]); - config_set_int(NULL, "ide_ter_irq", ide_irq[2]); - config_set_int(NULL, "ide_qua_enable", ide_enable[3]); - config_set_int(NULL, "ide_qua_irq", ide_irq[3]); - - config_set_int(NULL, "drive_a_type", fdd_get_type(0)); - config_set_int(NULL, "drive_b_type", fdd_get_type(1)); - config_set_int(NULL, "drive_3_type", fdd_get_type(2)); - config_set_int(NULL, "drive_4_type", fdd_get_type(3)); config_set_int(NULL, "force_43", force_43); config_set_int(NULL, "scale", scale); @@ -1139,7 +1044,7 @@ void saveconfig() config_set_int(NULL, "opl3_type", opl3_type); config_set_int(NULL, "joystick_type", joystick_type); - config_set_int(NULL, "mouse_type", mouse_type); + config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); config_set_int(NULL, "enable_xtide", enable_xtide); config_set_int(NULL, "enable_external_fpu", enable_external_fpu); @@ -1178,6 +1083,11 @@ void saveconfig() config_set_int(NULL, "window_x", window_x); config_set_int(NULL, "window_y", window_y); config_set_int(NULL, "window_remember", window_remember); + + config_set_int(NULL, "serial1_enabled", serial_enabled[0]); + config_set_int(NULL, "serial2_enabled", serial_enabled[1]); + config_set_int(NULL, "lpt_enabled", lpt_enabled); + config_set_int(NULL, "bugger_enabled", bugger_enabled); config_save(config_file_default); } diff --git a/src/pc.rc b/src/pc.rc deleted file mode 100644 index bf041602e..000000000 --- a/src/pc.rc +++ /dev/null @@ -1,713 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include "resources.h" - -#ifndef UPDOWN_CLASS -#define UPDOWN_CLASS L"msctls_updown32" -#endif - -MainMenu MENU DISCARDABLE -BEGIN - POPUP "&File" - BEGIN - MENUITEM "&Hard Reset", IDM_FILE_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12",IDM_FILE_RESET_CAD - MENUITEM "E&xit", IDM_FILE_EXIT - END - POPUP "&Disc" - BEGIN - MENUITEM "Change FDD& 1...", IDM_DISC_1 - MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP - MENUITEM "&Eject FDD 1", IDM_EJECT_1 - MENUITEM SEPARATOR - MENUITEM "Change FDD &2...", IDM_DISC_2 - MENUITEM "Change FDD 2 (W&rite-protected)...", IDM_DISC_2_WP - MENUITEM "E&ject FDD 2", IDM_EJECT_2 - MENUITEM SEPARATOR - MENUITEM "Change FDD &3...", IDM_DISC_3 - MENUITEM "Change FDD 3 (W&rite-protected)...", IDM_DISC_3_WP - MENUITEM "E&ject FDD 3", IDM_EJECT_3 - MENUITEM SEPARATOR - MENUITEM "Change FDD &4...", IDM_DISC_4 - MENUITEM "Change FDD 4 (W&rite-protected)...", IDM_DISC_4_WP - MENUITEM "E&ject FDD 4", IDM_EJECT_4 - MENUITEM SEPARATOR - MENUITEM "&Configure hard discs...",IDM_HDCONF - POPUP "C&D-ROM 1" - BEGIN - MENUITEM "&Enabled", IDM_CDROM_1_ENABLED - MENUITEM "S&ound enabled", IDM_CDROM_1_SOUND_ON - MENUITEM SEPARATOR - MENUITEM "&SCSI", IDM_CDROM_1_SCSI - MENUITEM "Atapi &DMA enabled", IDM_CDROM_1_DMA - MENUITEM SEPARATOR - MENUITEM "E&mpty",IDM_CDROM_1_EMPTY - MENUITEM "&Reload previous disc",IDM_CDROM_1_RELOAD - MENUITEM SEPARATOR - POPUP "&IDE channel..." - BEGIN - MENUITEM "&C:",IDM_CDROM_1_C - MENUITEM "&D:",IDM_CDROM_1_D - MENUITEM "&E:",IDM_CDROM_1_E - MENUITEM "&F:",IDM_CDROM_1_F - MENUITEM "&G:",IDM_CDROM_1_G - MENUITEM "&H:",IDM_CDROM_1_H - MENUITEM "&I:",IDM_CDROM_1_I - MENUITEM "&J:",IDM_CDROM_1_J - END - MENUITEM SEPARATOR - POPUP "S&CSI ID..." - BEGIN - MENUITEM "&0",IDM_CDROM_1_0 - MENUITEM "&1",IDM_CDROM_1_1 - MENUITEM "&2",IDM_CDROM_1_2 - MENUITEM "&3",IDM_CDROM_1_3 - MENUITEM "&4",IDM_CDROM_1_4 - MENUITEM "&5",IDM_CDROM_1_5 - MENUITEM "&6",IDM_CDROM_1_6 - MENUITEM "&8",IDM_CDROM_1_8 - MENUITEM "&9",IDM_CDROM_1_9 - MENUITEM "10",IDM_CDROM_1_10 - MENUITEM "11",IDM_CDROM_1_11 - MENUITEM "12",IDM_CDROM_1_12 - MENUITEM "13",IDM_CDROM_1_13 - MENUITEM "14",IDM_CDROM_1_14 - MENUITEM "15",IDM_CDROM_1_15 - END - POPUP "SCSI &LUN..." - BEGIN - MENUITEM "&0",IDM_CDROM_1_LUN_0 - MENUITEM "&1",IDM_CDROM_1_LUN_1 - MENUITEM "&2",IDM_CDROM_1_LUN_2 - MENUITEM "&3",IDM_CDROM_1_LUN_3 - MENUITEM "&4",IDM_CDROM_1_LUN_4 - MENUITEM "&5",IDM_CDROM_1_LUN_5 - MENUITEM "&6",IDM_CDROM_1_LUN_6 - MENUITEM "&7",IDM_CDROM_1_LUN_7 - END - MENUITEM SEPARATOR - MENUITEM "&ISO...",IDM_CDROM_1_ISO - END - POPUP "CD-&ROM 2" - BEGIN - MENUITEM "&Enabled", IDM_CDROM_2_ENABLED - MENUITEM "S&ound enabled", IDM_CDROM_2_SOUND_ON - MENUITEM SEPARATOR - MENUITEM "&SCSI", IDM_CDROM_2_SCSI - MENUITEM "Atapi &DMA enabled", IDM_CDROM_2_DMA - MENUITEM SEPARATOR - MENUITEM "E&mpty",IDM_CDROM_2_EMPTY - MENUITEM "&Reload previous disc",IDM_CDROM_2_RELOAD - MENUITEM SEPARATOR - POPUP "&IDE channel..." - BEGIN - MENUITEM "&C:",IDM_CDROM_2_C - MENUITEM "&D:",IDM_CDROM_2_D - MENUITEM "&E:",IDM_CDROM_2_E - MENUITEM "&F:",IDM_CDROM_2_F - MENUITEM "&G:",IDM_CDROM_2_G - MENUITEM "&H:",IDM_CDROM_2_H - MENUITEM "&I:",IDM_CDROM_2_I - MENUITEM "&J:",IDM_CDROM_2_J - END - MENUITEM SEPARATOR - POPUP "S&CSI ID..." - BEGIN - MENUITEM "&0",IDM_CDROM_2_0 - MENUITEM "&1",IDM_CDROM_2_1 - MENUITEM "&2",IDM_CDROM_2_2 - MENUITEM "&3",IDM_CDROM_2_3 - MENUITEM "&4",IDM_CDROM_2_4 - MENUITEM "&5",IDM_CDROM_2_5 - MENUITEM "&6",IDM_CDROM_2_6 - MENUITEM "&8",IDM_CDROM_2_8 - MENUITEM "&9",IDM_CDROM_2_9 - MENUITEM "10",IDM_CDROM_2_10 - MENUITEM "11",IDM_CDROM_2_11 - MENUITEM "12",IDM_CDROM_2_12 - MENUITEM "13",IDM_CDROM_2_13 - MENUITEM "14",IDM_CDROM_2_14 - MENUITEM "15",IDM_CDROM_2_15 - END - POPUP "SCSI &LUN..." - BEGIN - MENUITEM "&0",IDM_CDROM_2_LUN_0 - MENUITEM "&1",IDM_CDROM_2_LUN_1 - MENUITEM "&2",IDM_CDROM_2_LUN_2 - MENUITEM "&3",IDM_CDROM_2_LUN_3 - MENUITEM "&4",IDM_CDROM_2_LUN_4 - MENUITEM "&5",IDM_CDROM_2_LUN_5 - MENUITEM "&6",IDM_CDROM_2_LUN_6 - MENUITEM "&7",IDM_CDROM_2_LUN_7 - END - MENUITEM SEPARATOR - MENUITEM "&ISO...",IDM_CDROM_2_ISO - END - POPUP "CD-R&OM 3" - BEGIN - MENUITEM "&Enabled", IDM_CDROM_3_ENABLED - MENUITEM "S&ound enabled", IDM_CDROM_3_SOUND_ON - MENUITEM SEPARATOR - MENUITEM "&SCSI", IDM_CDROM_3_SCSI - MENUITEM "Atapi &DMA enabled", IDM_CDROM_3_DMA - MENUITEM SEPARATOR - MENUITEM "E&mpty",IDM_CDROM_3_EMPTY - MENUITEM "&Reload previous disc",IDM_CDROM_3_RELOAD - MENUITEM SEPARATOR - POPUP "&IDE channel..." - BEGIN - MENUITEM "&C:",IDM_CDROM_3_C - MENUITEM "&D:",IDM_CDROM_3_D - MENUITEM "&E:",IDM_CDROM_3_E - MENUITEM "&F:",IDM_CDROM_3_F - MENUITEM "&G:",IDM_CDROM_3_G - MENUITEM "&H:",IDM_CDROM_3_H - MENUITEM "&I:",IDM_CDROM_3_I - MENUITEM "&J:",IDM_CDROM_3_J - END - MENUITEM SEPARATOR - POPUP "S&CSI ID..." - BEGIN - MENUITEM "&0",IDM_CDROM_3_0 - MENUITEM "&1",IDM_CDROM_3_1 - MENUITEM "&2",IDM_CDROM_3_2 - MENUITEM "&3",IDM_CDROM_3_3 - MENUITEM "&4",IDM_CDROM_3_4 - MENUITEM "&5",IDM_CDROM_3_5 - MENUITEM "&6",IDM_CDROM_3_6 - MENUITEM "&8",IDM_CDROM_3_8 - MENUITEM "&9",IDM_CDROM_3_9 - MENUITEM "10",IDM_CDROM_3_10 - MENUITEM "11",IDM_CDROM_3_11 - MENUITEM "12",IDM_CDROM_3_12 - MENUITEM "13",IDM_CDROM_3_13 - MENUITEM "14",IDM_CDROM_3_14 - MENUITEM "15",IDM_CDROM_3_15 - END - POPUP "SCSI &LUN..." - BEGIN - MENUITEM "&0",IDM_CDROM_3_LUN_0 - MENUITEM "&1",IDM_CDROM_3_LUN_1 - MENUITEM "&2",IDM_CDROM_3_LUN_2 - MENUITEM "&3",IDM_CDROM_3_LUN_3 - MENUITEM "&4",IDM_CDROM_3_LUN_4 - MENUITEM "&5",IDM_CDROM_3_LUN_5 - MENUITEM "&6",IDM_CDROM_3_LUN_6 - MENUITEM "&7",IDM_CDROM_3_LUN_7 - END - MENUITEM SEPARATOR - MENUITEM "&ISO...",IDM_CDROM_3_ISO - END - POPUP "CD-RO&M 4" - BEGIN - MENUITEM "&Enabled", IDM_CDROM_4_ENABLED - MENUITEM "S&ound enabled", IDM_CDROM_4_SOUND_ON - MENUITEM SEPARATOR - MENUITEM "&SCSI", IDM_CDROM_4_SCSI - MENUITEM "Atapi &DMA enabled", IDM_CDROM_4_DMA - MENUITEM SEPARATOR - MENUITEM "E&mpty",IDM_CDROM_4_EMPTY - MENUITEM "&Reload previous disc",IDM_CDROM_4_RELOAD - MENUITEM SEPARATOR - POPUP "&IDE channel..." - BEGIN - MENUITEM "&C:",IDM_CDROM_4_C - MENUITEM "&D:",IDM_CDROM_4_D - MENUITEM "&E:",IDM_CDROM_4_E - MENUITEM "&F:",IDM_CDROM_4_F - MENUITEM "&G:",IDM_CDROM_4_G - MENUITEM "&H:",IDM_CDROM_4_H - MENUITEM "&I:",IDM_CDROM_4_I - MENUITEM "&J:",IDM_CDROM_4_J - END - MENUITEM SEPARATOR - POPUP "S&CSI ID..." - BEGIN - MENUITEM "&0",IDM_CDROM_4_0 - MENUITEM "&1",IDM_CDROM_4_1 - MENUITEM "&2",IDM_CDROM_4_2 - MENUITEM "&3",IDM_CDROM_4_3 - MENUITEM "&4",IDM_CDROM_4_4 - MENUITEM "&5",IDM_CDROM_4_5 - MENUITEM "&6",IDM_CDROM_4_6 - MENUITEM "&8",IDM_CDROM_4_8 - MENUITEM "&9",IDM_CDROM_4_9 - MENUITEM "10",IDM_CDROM_4_10 - MENUITEM "11",IDM_CDROM_4_11 - MENUITEM "12",IDM_CDROM_4_12 - MENUITEM "13",IDM_CDROM_4_13 - MENUITEM "14",IDM_CDROM_4_14 - MENUITEM "15",IDM_CDROM_4_15 - END - POPUP "SCSI &LUN..." - BEGIN - MENUITEM "&0",IDM_CDROM_4_LUN_0 - MENUITEM "&1",IDM_CDROM_4_LUN_1 - MENUITEM "&2",IDM_CDROM_4_LUN_2 - MENUITEM "&3",IDM_CDROM_4_LUN_3 - MENUITEM "&4",IDM_CDROM_4_LUN_4 - MENUITEM "&5",IDM_CDROM_4_LUN_5 - MENUITEM "&6",IDM_CDROM_4_LUN_6 - MENUITEM "&7",IDM_CDROM_4_LUN_7 - END - MENUITEM SEPARATOR - MENUITEM "&ISO...",IDM_CDROM_4_ISO - END - POPUP "E&xtra IDE controllers" - BEGIN - POPUP "&Tertiary IDE controller" - BEGIN - MENUITEM "&Enabled",IDM_IDE_TER_ENABLED - MENUITEM SEPARATOR - MENUITEM "&9",IDM_IDE_TER_IRQ9 - MENUITEM "1&0",IDM_IDE_TER_IRQ10 - MENUITEM "1&1",IDM_IDE_TER_IRQ11 - MENUITEM "1&2",IDM_IDE_TER_IRQ12 - MENUITEM "1&4",IDM_IDE_TER_IRQ14 - MENUITEM "1&5",IDM_IDE_TER_IRQ15 - END - POPUP "&Quaternary IDE controller" - BEGIN - MENUITEM "&Enabled",IDM_IDE_QUA_ENABLED - MENUITEM SEPARATOR - MENUITEM "&9",IDM_IDE_QUA_IRQ9 - MENUITEM "1&0",IDM_IDE_QUA_IRQ10 - MENUITEM "1&1",IDM_IDE_QUA_IRQ11 - MENUITEM "1&2",IDM_IDE_QUA_IRQ12 - MENUITEM "1&4",IDM_IDE_QUA_IRQ14 - MENUITEM "1&5",IDM_IDE_QUA_IRQ15 - END - END - END - POPUP "&Settings" - BEGIN - MENUITEM "&Configure...", IDM_CONFIG - MENUITEM SEPARATOR - MENUITEM "&Load configuration...", IDM_CONFIG_LOAD - MENUITEM "&Save configuration...", IDM_CONFIG_SAVE - MENUITEM SEPARATOR - MENUITEM "Use &Nuked OPL for OPL 3...", IDM_USE_NUKEDOPL - MENUITEM SEPARATOR - POPUP "&Video" - BEGIN - MENUITEM "&Resizeable window",IDM_VID_RESIZE - MENUITEM "R&emember size && position",IDM_VID_REMEMBER - MENUITEM SEPARATOR - MENUITEM "D&isc activity flash", IDM_VID_FLASH - MENUITEM SEPARATOR - MENUITEM "&DirectDraw", IDM_VID_DDRAW - MENUITEM "Direct&3D 9", IDM_VID_D3D - MENUITEM SEPARATOR - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - END - MENUITEM SEPARATOR - MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels", IDM_VID_FS_SQ - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - MENUITEM SEPARATOR - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT - END - MENUITEM "&Status", IDM_STATUS -#ifdef ENABLE_LOG_TOGGLES -#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG - MENUITEM SEPARATOR -#endif -#ifdef ENABLE_BUSLOGIC_LOG - MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC -#endif -#ifdef ENABLE_CDROM_LOG - MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM -#endif -#ifdef ENABLE_D86F_LOG - MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F -#endif -#ifdef ENABLE_FDC_LOG - MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC -#endif -#ifdef ENABLE_IDE_LOG - MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE -#endif -#ifdef ENABLE_NE2000_LOG - MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - MENUITEM SEPARATOR - MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT -#endif - END -END - -MainAccel ACCELERATORS -BEGIN -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_CDROM_LOG - VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_D86F_LOG - VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_FDC_LOG - VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_IDE_LOG - VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_NE2000_LOG - VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY -#endif - VK_F11, IDM_VID_SCREENSHOT, CONTROL, VIRTKEY - VK_F12, IDM_FILE_RESET_CAD, CONTROL, VIRTKEY -END - -ConfigureDlg DIALOGEX 0, 0, 252+40, 236+100 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Configure 86Box" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,64,312,50,14, WS_TABSTOP - PUSHBUTTON "Cancel",IDCANCEL,128,312,50,14, WS_TABSTOP - COMBOBOX IDC_COMBO1,62,16,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure", IDC_CONFIGUREMOD, 224, 16, 40, 14, WS_TABSTOP - COMBOBOX IDC_COMBOVID,62,36,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure", IDC_CONFIGUREVID, 224, 36, 40, 14, WS_TABSTOP - COMBOBOX IDC_COMBOCPUM,62,56,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO3,62,76,102,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Dynamic Recompiler",IDC_CHECKDYNAREC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,76,99,10 - CONTROL "Enable 287/387 FPU",IDC_CHECKFPU,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,169,96,99,10 - COMBOBOX IDC_COMBOWS, 62,96,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSPD,162,56,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBOSND,62,116,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure", IDC_CONFIGURESND, 224, 116, 40, 14, WS_TABSTOP - EDITTEXT IDC_MEMTEXT, 62, 136, 36, 14, ES_AUTOHSCROLL | ES_NUMBER - CONTROL "", IDC_MEMSPIN, UPDOWN_CLASS, UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, 98, 136, 12, 14 - LTEXT "MB", IDC_TEXT_MB, 98, 136, 10, 10 - CONTROL "CMS / Game Blaster",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,212,102,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,228,102,10 - - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,212,102,10 - CONTROL "En. XTIDE",IDC_CHECKXTIDE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,224,212,40,10 - CONTROL "SCSI Controller",IDC_CHECKBUSLOGIC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,228,102,10 - PUSHBUTTON "Configure", IDC_CONFIGUREBUSLOGIC, 224, 228, 40, 14, WS_TABSTOP - - CONTROL "Enable time sync",IDC_CHECKSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,244,102,10 - CONTROL "Voodoo Graphics",IDC_CHECKVOODOO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,118,244,102,10 - PUSHBUTTON "Configure", IDC_CONFIGUREVOODOO, 224, 244, 40, 14, WS_TABSTOP - - LTEXT "Mouse :",IDC_STATIC,15,260,40,10 - COMBOBOX IDC_COMBOMOUSE,62,260,157,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - - LTEXT "Joystick :",IDC_STATIC,15,280,40,10 - COMBOBOX IDC_COMBOJOY,62,280,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,16,296,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 2...",IDC_JOY2,80,296,50,14, WS_TABSTOP - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,144,296,50,14, WS_TABSTOP - PUSHBUTTON "Joystick 4...",IDC_JOY4,208,296,50,14, WS_TABSTOP - - LTEXT "Machine :",IDC_STATIC,15,16,40,10 - LTEXT "Video :",IDC_STATIC,15,36,34,10 - LTEXT "CPU type :",IDC_STATIC,15,56,34,10 - LTEXT "CPU :",IDC_STATIC,15,76,34,10 - LTEXT "Waitstates :",IDC_STATIC,15,96,40,10 - LTEXT "Vid.speed:",IDC_STATIC,125,56,34,10 - LTEXT "Sound card :",IDC_STATIC,15,116,40,10 - LTEXT "Network :",IDC_STATIC,125,136,34,10 - COMBOBOX IDC_COMBONET,162,136,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure", IDC_CONFIGURENET, 224, 136, 40, 14, WS_TABSTOP - LTEXT "Memory :",IDC_STATIC,15,136,40,10 - LTEXT "HDD :",IDC_STATIC,15,156,40,10 - COMBOBOX IDC_COMBOHDD, 62,156,157,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "FDD 1 :",IDC_STATIC,15,176,40,10 - LTEXT "FDD 2 :",IDC_STATIC,125,176,40,10 - COMBOBOX IDC_COMBODR1,62,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBODR2,162,176,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "FDD 3 :",IDC_STATIC,15,196,40,10 - LTEXT "FDD 4 :",IDC_STATIC,125,196,40,10 - COMBOBOX IDC_COMBODR3,62,196,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBODR4,162,196,57,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -END - -HdConfDlg DIALOGEX 0, 0, 270, DLG_HEIGHT - STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU - CAPTION "Configure Hard Discs" - FONT 9, "Segoe UI" - BEGIN - DEFPUSHBUTTON "OK",IDOK,31+12,CMD_BASE,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101+12,CMD_BASE,50,14 - - LTEXT "C:",IDC_STATIC,7,C_BASE+2,27,10 - EDITTEXT IDC_EDIT_C_FN, 7+16, C_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_CFILE,7 + 136, C_BASE, 16, 14 - PUSHBUTTON "New",IDC_CNEW,7 + 152, C_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTC, 7 + 176, C_BASE, 24, 14 - EDITTEXT IDC_EDIT_C_SPT,15,C_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_C_HPC,48,C_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_C_CYL,81,C_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,C_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,C_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,C_BASE+18,8,12 - LTEXT "", IDC_TEXT_C_SIZE, 118, C_BASE+18, 89, 12 - - LTEXT "D:",IDC_STATIC,7,D_BASE+2,27,10 - EDITTEXT IDC_EDIT_D_FN, 7+16, D_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_DFILE,7 + 136, D_BASE, 16, 14 - PUSHBUTTON "New",IDC_DNEW,7 + 152, D_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTD, 7 + 176, D_BASE, 24, 14 - EDITTEXT IDC_EDIT_D_SPT,15,D_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_D_HPC,48,D_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_D_CYL,81,D_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,D_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,D_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,D_BASE+18,8,12 - LTEXT "", IDC_TEXT_D_SIZE, 118, D_BASE+18, 89, 12 - - LTEXT "E:",IDC_STATIC,7,E_BASE+2,27,10 - EDITTEXT IDC_EDIT_E_FN, 7+16, E_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_EFILE,7 + 136, E_BASE, 16, 14 - PUSHBUTTON "New",IDC_ENEW,7 + 152, E_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTE, 7 + 176, E_BASE, 24, 14 - EDITTEXT IDC_EDIT_E_SPT,15,E_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_E_HPC,48,E_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_E_CYL,81,E_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,E_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,E_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,E_BASE+18,8,12 - LTEXT "", IDC_TEXT_E_SIZE, 118, E_BASE+18, 89, 12 - - LTEXT "F:",IDC_STATIC,7,F_BASE+2,27,10 - EDITTEXT IDC_EDIT_F_FN, 7+16, F_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_FFILE,7 + 136, F_BASE, 16, 14 - PUSHBUTTON "New",IDC_FNEW,7 + 152, F_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTF, 7 + 176, F_BASE, 24, 14 - EDITTEXT IDC_EDIT_F_SPT,15,F_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_F_HPC,48,F_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_F_CYL,81,F_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,F_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,F_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,F_BASE+18,8,12 - LTEXT "", IDC_TEXT_F_SIZE, 118, F_BASE+18, 89, 12 - - LTEXT "G:",IDC_STATIC,7,G_BASE+2,27,10 - EDITTEXT IDC_EDIT_G_FN, 7+16, G_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_GFILE,7 + 136, G_BASE, 16, 14 - PUSHBUTTON "New",IDC_GNEW,7 + 152, G_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTG, 7 + 176, G_BASE, 24, 14 - EDITTEXT IDC_EDIT_G_SPT,15,G_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_G_HPC,48,G_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_G_CYL,81,G_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,G_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,G_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,G_BASE+18,8,12 - LTEXT "", IDC_TEXT_G_SIZE, 118, G_BASE+18, 89, 12 - - LTEXT "H:",IDC_STATIC,7,H_BASE+2,27,10 - EDITTEXT IDC_EDIT_H_FN, 7+16, H_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_HFILE,7 + 136, H_BASE, 16, 14 - PUSHBUTTON "New",IDC_HNEW,7 + 152, H_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTH, 7 + 176, H_BASE, 24, 14 - EDITTEXT IDC_EDIT_H_SPT,15,H_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_H_HPC,48,H_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_H_CYL,81,H_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,H_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,H_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,H_BASE+18,8,12 - LTEXT "", IDC_TEXT_H_SIZE, 118, H_BASE+18, 89, 12 - - LTEXT "I:",IDC_STATIC,7,I_BASE+2,27,10 - EDITTEXT IDC_EDIT_I_FN, 7+16, I_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_IFILE,7 + 136, I_BASE, 16, 14 - PUSHBUTTON "New",IDC_INEW,7 + 152, I_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTI, 7 + 176, I_BASE, 24, 14 - EDITTEXT IDC_EDIT_I_SPT,15,I_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_I_HPC,48,I_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_I_CYL,81,I_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,I_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,I_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,I_BASE+18,8,12 - LTEXT "", IDC_TEXT_I_SIZE, 118, I_BASE+18, 89, 12 - - LTEXT "J:",IDC_STATIC,7,J_BASE+2,27,10 - EDITTEXT IDC_EDIT_J_FN, 7+16, J_BASE, 120, 12, WS_DISABLED - PUSHBUTTON "...",IDC_JFILE,7 + 136, J_BASE, 16, 14 - PUSHBUTTON "New",IDC_JNEW,7 + 152, J_BASE, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTJ, 7 + 176, J_BASE, 24, 14 - EDITTEXT IDC_EDIT_J_SPT,15,J_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_J_HPC,48,J_BASE+16,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_J_CYL,81,J_BASE+16,28,12, WS_DISABLED - LTEXT "S:",IDC_STATIC,7,J_BASE+18,8,12 - LTEXT "H:",IDC_STATIC,40,J_BASE+18,8,12 - LTEXT "C:",IDC_STATIC,73,J_BASE+18,8,12 - LTEXT "", IDC_TEXT_J_SIZE, 118, J_BASE+18, 89, 12 - -END - -HdNewDlg DIALOGEX 0, 0, 216, 86 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "New Hard Disc" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,31,66,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101,66,50,14 - - EDITTEXT IDC_EDITC, 7, 6, 187, 12 - PUSHBUTTON "...",IDC_CFILE,7 + 187, 6, 16, 14 - - EDITTEXT IDC_EDIT1,36,22,16,12 - EDITTEXT IDC_EDIT2,94,22,16,12 - EDITTEXT IDC_EDIT3,152,22,28,12 - EDITTEXT IDC_EDIT4,36,38,28,12 - COMBOBOX IDC_COMBOHDT,117,38,93,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Sectors:",IDC_STATIC,7,23,27,10 - LTEXT "Heads:",IDC_STATIC,63,23,29,8 - LTEXT "Cylinders:",IDC_STATIC,120,23,32,12 - LTEXT "Size:",IDC_STATIC,7,39,17,8 - LTEXT "MB",IDC_STATIC,68,39,10,8 - LTEXT "Type:",IDC_STATIC,94,39,17,8 -END - -HdSizeDlg DIALOGEX 0, 0, 216, 86 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Hard disc parameters" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,31,66,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101,66,50,14 - - LTEXT "Initial settings are based on file size (header if HDI)",IDC_STATIC,7,6,200,10 - - EDITTEXT IDC_EDIT1,36,22,16,12 - EDITTEXT IDC_EDIT2,94,22,16,12 - EDITTEXT IDC_EDIT3,152,22,28,12 - EDITTEXT IDC_EDIT4,36,38,28,12 - COMBOBOX IDC_COMBOHDT,117,38,93,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Sectors:",IDC_STATIC,7,23,27,10 - LTEXT "Heads:",IDC_STATIC,63,23,29,8 - LTEXT "Cylinders:",IDC_STATIC,120,23,32,12 - LTEXT "Size:",IDC_STATIC,7,39,17,8 - LTEXT "MB",IDC_STATIC,68,39,10,8 - LTEXT "Type:",IDC_STATIC,94,39,17,8 -END - -HdConfDlgMfm DIALOGEX 0, 0, 210, 172 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Configure Hard Discs" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,31+12,152,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101+12,152,50,14 - - LTEXT "C:",IDC_STATIC,7,6,27,10 - EDITTEXT IDC_EDIT_C_FN, 7, 22, 136, 12, WS_DISABLED - PUSHBUTTON "...",IDC_CFILE,7 + 136, 22, 16, 14 - PUSHBUTTON "New",IDC_CNEW,7 + 136 + 16, 22, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTC, 7 + 136 + 16 + 24, 22, 24, 14 - - EDITTEXT IDC_EDIT_C_SPT,36,38,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_C_HPC,94,38,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_C_CYL,152,38,28,12, WS_DISABLED - LTEXT "Sectors:",IDC_STATIC,7,38,27,10 - LTEXT "Heads:",IDC_STATIC,63,38,29,8 - LTEXT "Cylinders:",IDC_STATIC,120,38,32,12 - LTEXT "", IDC_TEXT_C_SIZE, 7, 54, 136, 12 - - LTEXT "D:",IDC_STATIC,7,76,27,10 - EDITTEXT IDC_EDIT_D_FN, 7, 92, 136, 12, WS_DISABLED - PUSHBUTTON "...",IDC_DFILE,7 + 136, 92, 16, 14 - PUSHBUTTON "New",IDC_DNEW,7 + 136 + 16, 92, 24, 14 - PUSHBUTTON "Eject", IDC_EJECTD, 7 + 136 + 16 + 24, 92, 24, 14 - - EDITTEXT IDC_EDIT_D_SPT,36,108,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_D_HPC,94,108,16,12, WS_DISABLED - EDITTEXT IDC_EDIT_D_CYL,152,108,28,12, WS_DISABLED - LTEXT "Sectors:",IDC_STATIC,7,108,27,10 - LTEXT "Heads:",IDC_STATIC,63,108,29,8 - LTEXT "Cylinders:",IDC_STATIC,120,108,32,12 - LTEXT "", IDC_TEXT_D_SIZE, 7, 124, 136, 12 -END - -HdNewDlgMfm DIALOGEX 0, 0, 186, 102 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "New Hard Disc" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,31,82,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101,82,50,14 - - EDITTEXT IDC_EDITC, 7, 6, 136, 12 - PUSHBUTTON "...",IDC_CFILE,7 + 136, 6, 16, 14 - - EDITTEXT IDC_EDIT1,36,22,16,12 - EDITTEXT IDC_EDIT2,94,22,16,12 - EDITTEXT IDC_EDIT3,152,22,28,12 - LTEXT "Sectors:",IDC_STATIC,7,22,27,10 - LTEXT "Heads:",IDC_STATIC,63,22,29,8 - LTEXT "Cylinders:",IDC_STATIC,120,22,32,12 - LTEXT "", IDC_TEXT1, 7, 38, 136, 12 - - COMBOBOX IDC_HDTYPE, 7,54,172,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - -END - -HdSizeDlgMfm DIALOGEX 0, 0, 186, 102 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Hard disc parameters" -FONT 8, "MS Sans Serif" -BEGIN - DEFPUSHBUTTON "OK",IDOK,31,82,50,14 - PUSHBUTTON "Cancel",IDCANCEL,101,82,50,14 - - LTEXT "Initial settings are based on file size",IDC_STATIC,7,6,170,10 - - EDITTEXT IDC_EDIT1,36,22,16,12 - EDITTEXT IDC_EDIT2,94,22,16,12 - EDITTEXT IDC_EDIT3,152,22,28,12 - LTEXT "Sectors:",IDC_STATIC,7,22,27,10 - LTEXT "Heads:",IDC_STATIC,63,22,29,8 - LTEXT "Cylinders:",IDC_STATIC,120,22,32,12 - LTEXT "", IDC_TEXT1, 7, 38, 136, 12 - - COMBOBOX IDC_HDTYPE, 7,54,172,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - -END - -StatusDlg DIALOGEX 0,0,186,186+20+180 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Status" -FONT 9, "Segoe UI" -BEGIN - LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 - LTEXT "1",IDC_STEXT1,16,186,180,1000 -END - -1 24 "86Box.manifest" - -#ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON "86Box-RB.ico" -#else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON "86Box.ico" -#endif diff --git a/src/pc87306.c b/src/pc87306.c index e3e930117..b62ea642c 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -11,25 +11,23 @@ #include "disc.h" #include "fdc.h" #include "fdd.h" +#include "ide.h" #include "io.h" #include "lpt.h" #include "serial.h" #include "pc87306.h" -static int pc87306_locked; static int pc87306_curreg; static uint8_t pc87306_regs[29]; static uint8_t pc87306_gpio[2] = {0xFF, 0xFB}; static uint8_t tries; static uint16_t lpt_port; -static int power_down = 0; void pc87306_gpio_remove(); void pc87306_gpio_init(); void pc87306_gpio_write(uint16_t port, uint8_t val, void *priv) { - // pclog("GPIO: Writing %02X on port: %04X\n", val, port); pc87306_gpio[port & 1] = val; } @@ -49,7 +47,6 @@ uint8_t uart1_int() { uint8_t temp; temp = ((pc87306_regs[1] >> 2) & 1) ? 3 : 4; /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ - // pclog("UART 1 set to IRQ %i\n", (pc87306_regs[0x1C] & 1) ? uart_int1() : temp); return (pc87306_regs[0x1C] & 1) ? uart_int1() : temp; } @@ -57,7 +54,6 @@ uint8_t uart2_int() { uint8_t temp; temp = ((pc87306_regs[1] >> 4) & 1) ? 3 : 4; /* 0 = COM1 (IRQ 4), 1 = COM2 (IRQ 3), 2 = COM3 (IRQ 4), 3 = COM4 (IRQ 3) */ - // pclog("UART 2 set to IRQ %i\n", (pc87306_regs[0x1C] & 1) ? uart_int2() : temp); return (pc87306_regs[0x1C] & 1) ? uart_int2() : temp; } @@ -148,15 +144,14 @@ void serial2_handler() void pc87306_write(uint16_t port, uint8_t val, void *priv) { uint8_t index; - index = (port & 1) ? 0 : 1; - int temp; uint8_t valxor; - // pclog("pc87306_write : port=%04x reg %02X = %02X locked=%i\n", port, pc87306_curreg, val, pc87306_locked); + uint16_t or_value; + + index = (port & 1) ? 0 : 1; if (index) { pc87306_curreg = val & 0x1f; - // pclog("Register set to: %02X\n", val); tries = 0; return; } @@ -184,7 +179,6 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { pc87306_gpio_remove(); } - // pclog("Register %02X set to: %02X (was: %02X)\n", pc87306_curreg, val, pc87306_regs[pc87306_curreg]); pc87306_regs[pc87306_curreg] = val; goto process_value; } @@ -201,7 +195,6 @@ process_value: switch(pc87306_curreg) { case 0: - // pclog("Register 0\n"); if (valxor & 1) { lpt1_remove(); @@ -227,7 +220,7 @@ process_value: serial2_handler(); } } - if ((valxor & 8) || (valxor & 0x20)) + if (valxor & 0x28) { fdc_remove(); if (val & 8) @@ -235,6 +228,24 @@ process_value: fdc_set_base((val & 0x20) ? 0x370 : 0x3f0, 0); } } + if (valxor & 0xc0) + { + ide_pri_disable(); + if (val & 0x80) + { + or_value = 0; + } + else + { + or_value = 0x80; + } + ide_set_base(0, 0x170 | or_value); + ide_set_side(0, 0x376 | or_value); + if (val & 0x40) + { + ide_pri_enable_ex(); + } + } break; case 1: @@ -276,7 +287,6 @@ process_value: { if (val & 1) { - // pclog("Powering down functions...\n"); lpt1_remove(); serial1_remove(); serial2_remove(); @@ -284,7 +294,6 @@ process_value: } else { - // pclog("Powering up functions...\n"); if (pc87306_regs[0] & 1) { lpt1_handler(); @@ -307,7 +316,6 @@ process_value: case 9: if (valxor & 0x44) { - // pclog("Setting DENSEL polarity to: %i (before: %i)\n", (val & 0x40 ? 1 : 0), fdc_get_densel_polarity()); fdc_update_enh_mode((val & 4) ? 1 : 0); fdc_update_densel_polarity((val & 0x40) ? 1 : 0); } @@ -366,13 +374,11 @@ process_value: uint8_t pc87306_gpio_read(uint16_t port, void *priv) { - // pclog("Read GPIO on port: %04X (%04X:%04X)\n", port, CS, cpu_state.pc); return pc87306_gpio[port & 1]; } uint8_t pc87306_read(uint16_t port, void *priv) { - // pclog("pc87306_read : port=%04x reg %02X locked=%i\n", port, pc87306_curreg, pc87306_locked); uint8_t index; index = (port & 1) ? 0 : 1; @@ -380,24 +386,20 @@ uint8_t pc87306_read(uint16_t port, void *priv) if (index) { - // pclog("PC87306: Read value %02X at the index register\n", pc87306_curreg & 0x1f); return pc87306_curreg & 0x1f; } else { if (pc87306_curreg >= 28) { - // pclog("PC87306: Read invalid at data register, index %02X\n", pc87306_curreg); return 0xff; } else if (pc87306_curreg == 8) { - // pclog("PC87306: Read ID at data register, index 08 (%04X:%04X)\n", CS, cpu_state.pc); return 0x70; } else { - // pclog("PC87306: Read value %02X at data register, index %02X\n", pc87306_regs[pc87306_curreg], pc87306_curreg); return pc87306_regs[pc87306_curreg]; } } diff --git a/src/pci.c b/src/pci.c index 7a2b3cbd0..73b056118 100644 --- a/src/pci.c +++ b/src/pci.c @@ -23,7 +23,6 @@ void pci_cf8_write(uint16_t port, uint32_t val, void *p) pci_card = (val >> 11) & 31; pci_bus = (val >> 16) & 0xff; pci_enable = (val >> 31) & 1; - // pclog("PCI card selected: %i\n", pci_card); } uint32_t pci_cf8_read(uint16_t port, void *p) @@ -33,15 +32,12 @@ uint32_t pci_cf8_read(uint16_t port, void *p) void pci_write(uint16_t port, uint8_t val, void *priv) { - // pclog("pci_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, cpu_state.pc); switch (port) { case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return; - - // pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, cpu_state.pc); - + if (!pci_bus && pci_card_write[pci_card]) pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); @@ -51,19 +47,19 @@ void pci_write(uint16_t port, uint8_t val, void *priv) uint8_t pci_read(uint16_t port, void *priv) { - // pclog("pci_read: port=%04x %08x:%08x\n", port, cs, cpu_state.pc); switch (port) { case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return 0xff; - // pclog("PCI read bus %i card %i func %i index %02X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3)); - if (!pci_bus && pci_card_read[pci_card]) return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); return 0xff; + + default: + return 0xff; } } @@ -72,7 +68,6 @@ uint8_t pci_type2_read(uint16_t port, void *priv); void pci_type2_write(uint16_t port, uint8_t val, void *priv) { -// pclog("pci_type2_write: port=%04x val=%02x %08x:%08x\n", port, val, cs, pc); if (port == 0xcf8) { pci_func = (val >> 1) & 7; @@ -91,8 +86,6 @@ void pci_type2_write(uint16_t port, uint8_t val, void *priv) pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; - // pclog("PCI write bus %i card %i func %i index %02X val %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), val, CS, cpu_state.pc); - if (!pci_bus && pci_card_write[pci_card]) pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); } @@ -100,7 +93,6 @@ void pci_type2_write(uint16_t port, uint8_t val, void *priv) uint8_t pci_type2_read(uint16_t port, void *priv) { -// pclog("pci_type2_read: port=%04x %08x:%08x\n", port, cs, pc); if (port == 0xcf8) { return pci_key | (pci_func << 1); @@ -114,8 +106,6 @@ uint8_t pci_type2_read(uint16_t port, void *priv) pci_card = (port >> 8) & 0xf; pci_index = port & 0xff; - // pclog("PCI read bus %i card %i func %i index %02X %04X:%04X\n", pci_bus, pci_card, pci_func, pci_index | (port & 3), CS, cpu_state.pc); - if (!pci_bus && pci_card_write[pci_card]) return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); } @@ -140,7 +130,11 @@ void pci_init(int type, int min_card, int max_card) } for (c = 0; c < 32; c++) - pci_card_read[c] = pci_card_write[c] = pci_priv[c] = NULL; + { + pci_card_read[c] = NULL; + pci_card_write[c] = NULL; + pci_priv[c] = NULL; + } pci_min_card = min_card; pci_max_card = max_card; @@ -164,7 +158,6 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int pci_card_read[c] = read; pci_card_write[c] = write; pci_priv[c] = priv; - // pclog("PCI device added to card: %i\n", c); return; } } diff --git a/src/pic.c b/src/pic.c index 96cca37ac..128089924 100644 --- a/src/pic.c +++ b/src/pic.c @@ -1,6 +1,7 @@ #include "ibm.h" #include "io.h" #include "pic.h" +#include "pit.h" int output; int intclear; @@ -56,7 +57,6 @@ void pic_update_mask(uint8_t *mask, uint8_t ins) if (ins & (1 << c)) { *mask = 0xff << c; - // pclog("Mask is: %02X\n", *mask); return; } } @@ -88,21 +88,16 @@ static void pic_autoeoi() void pic_write(uint16_t addr, uint8_t val, void *priv) { int c; - // if (addr&1) pclog("Write PIC %04X %02X %04X(%06X):%04X\n",addr,val,CS,cs,cpu_state.pc); if (addr&1) { - // pclog("PIC ICW is: %i\n", pic.icw); switch (pic.icw) { case 0: /*OCW1*/ -// printf("Write mask %02X %04X:%04X\n",val,CS,pc); pic.mask=val; pic_updatepending(); break; case 1: /*ICW2*/ pic.vector=val&0xF8; - // printf("PIC vector now %02X\n",pic.vector); - // output=1; if (pic.icw1&2) pic.icw=3; else pic.icw=2; break; @@ -112,7 +107,6 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) break; case 3: /*ICW4*/ pic.icw4 = val; - // pclog("ICW4 = %02x\n", val); pic.icw=0; break; } @@ -121,7 +115,6 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) { if (val&16) /*ICW1*/ { - // pclog("ICW1 = %02x\n", val); pic.mask = 0; pic.mask2=0; pic.icw=1; @@ -131,10 +124,8 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) } else if (!(val&8)) /*OCW2*/ { -// printf("Clear ints - %02X %02X\n",pic.ins,val); if ((val&0xE0)==0x60) { -// pclog("Specific EOI - %02X %i\n",pic.ins,1<<(val&7)); pic.ins&=~(1<<(val&7)); pic_update_mask(&pic.mask2, pic.ins); if (AT) @@ -142,8 +133,6 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) if ((val&7) == 2 && (pic2.pend&~pic2.mask)&~pic2.mask2) pic.pend |= (1 << 2); } -// pic.pend&=(1<<(val&7)); -// if ((val&7)==1) pollkeywaiting(); pic_updatepending(); } else @@ -164,10 +153,8 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) if (c==1 && keywaiting) { intclear&=~1; -// pollkeywaiting(); } pic_updatepending(); -// pclog("Generic EOI - Cleared int %i\n",c); return; } } @@ -175,9 +162,8 @@ void pic_write(uint16_t addr, uint8_t val, void *priv) } else /*OCW3*/ { - // if (val&4) fatal("PIC1 write OCW3 4 %02X\n",val); if (val&2) pic.read=(val&1); - if (val&0x40) { } //fatal("PIC 1 write OCW3 40 %02X\n",val); + if (val&0x40) { } } } } @@ -186,7 +172,6 @@ uint8_t pic_read(uint16_t addr, void *priv) { if (addr&1) { /*pclog("Read PIC mask %02X\n",pic.mask);*/ return pic.mask; } if (pic.read) { /*pclog("Read PIC ins %02X\n",pic.ins);*/ return pic.ins | (pic2.ins ? 4 : 0); } -// pclog("Read PIC pend %02X %08X\n",pic.pend,EDX); return pic.pend; } @@ -215,19 +200,16 @@ static void pic2_autoeoi() void pic2_write(uint16_t addr, uint8_t val, void *priv) { int c; -// pclog("Write PIC2 %04X %02X %04X:%04X %i\n",addr,val,CS,pc,ins); if (addr&1) { switch (pic2.icw) { case 0: /*OCW1*/ -// printf("PIC2 Write mask %02X %04X:%04X\n",val,CS,pc); pic2.mask=val; pic_updatepending(); break; case 1: /*ICW2*/ pic2.vector=val&0xF8; -// pclog("PIC2 vector %02X\n", val & 0xf8); if (pic2.icw1&2) pic2.icw=3; else pic2.icw=2; break; @@ -301,18 +283,14 @@ void clearpic() { pic.pend=pic.ins=0; pic_updatepending(); -// pclog("Clear PIC\n"); } int pic_current[16]; void picint(uint16_t num) { - int old_pend = pic_intpending; if (AT && (num == (1 << 2))) num = 1 << 9; -// pclog("picint : %04X\n", num); -// if (num == 0x10) pclog("PICINT 10\n"); if (num>0xFF) { if (!AT) @@ -348,7 +326,6 @@ void picintlevel(uint16_t num) c = 9; num = 1 << 9; } -// pclog("INTLEVEL %04X %i\n", num, c); if (!pic_current[c]) { pic_current[c]=1; @@ -379,7 +356,6 @@ void picintc(uint16_t num) c = 9; num = 1 << 9; } -// pclog("INTC %04X %i\n", num, c); pic_current[c]=0; if (num > 0xff) @@ -411,7 +387,10 @@ uint8_t picinterrupt() pic.pend &= ~(1 << c); pic.ins |= (1 << c); pic_update_mask(&pic.mask2, pic.ins); + pic_updatepending(); + if (!c) + pit_set_gate(&pit2, 0, 0); if (pic.icw4 & 0x02) pic_autoeoi(); @@ -445,7 +424,6 @@ uint8_t picinterrupt() pic2.ins |= (1 << c); pic_update_mask(&pic2.mask2, pic2.ins); - // pic.pend &= ~(1 << c); pic.ins |= (1 << 2); /*Cascade IRQ*/ pic_update_mask(&pic.mask2, pic.ins); diff --git a/src/pic.h b/src/pic.h index 419315c5f..74660941a 100644 --- a/src/pic.h +++ b/src/pic.h @@ -7,3 +7,4 @@ void picintlevel(uint16_t num); void picintc(uint16_t num); uint8_t picinterrupt(); void picclear(int num); +void dumppic(); diff --git a/src/piix.c b/src/piix.c index d4af9b4f1..2cb81a739 100644 --- a/src/piix.c +++ b/src/piix.c @@ -9,6 +9,7 @@ #include #include "ibm.h" +#include "dma.h" #include "ide.h" #include "io.h" #include "mem.h" @@ -27,13 +28,11 @@ static uint8_t card_piix[256], card_piix_ide[256]; void piix_write(int func, int addr, uint8_t val, void *priv) { uint16_t old_base = (card_piix_ide[0x20] & 0xf0) | (card_piix_ide[0x21] << 8); -// pclog("piix_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); if (func > 1) return; if (func == 1) /*IDE*/ { - // pclog("piix_write (IDE): func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, cpu_state.pc); switch (addr) { case 0x04: @@ -41,7 +40,6 @@ void piix_write(int func, int addr, uint8_t val, void *priv) break; case 0x07: card_piix_ide[0x07] = val & 0x3e; - // card_piix_ide[0x07] = (card_piix_ide[0x07] & ~0x38) | (val & 0x38); break; case 0x0d: card_piix_ide[0x0d] = val; @@ -91,7 +89,6 @@ void piix_write(int func, int addr, uint8_t val, void *priv) io_sethandler(base, 0x10, piix_bus_master_read, NULL, NULL, piix_bus_master_write, NULL, NULL, NULL); } } - // pclog("PIIX write %02X %02X\n", addr, val); } else { @@ -141,14 +138,11 @@ void piix_write(int func, int addr, uint8_t val, void *priv) uint8_t piix_read(int func, int addr, void *priv) { -// pclog("piix_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); if (func > 1) return 0xff; if (func == 1) /*IDE*/ { - // pclog("PIIX IDE read %02X %02X\n", addr, card_piix_ide[addr]); - if (addr == 4) { return (card_piix_ide[addr] & 5) | 2; @@ -316,6 +310,8 @@ uint8_t piix_read(int func, int addr, void *priv) else return card_piix[addr]; } + + return 0; } struct @@ -334,13 +330,11 @@ static void piix_bus_master_next_addr(int channel) piix_busmaster[channel].count = (*(uint32_t *)(&ram[piix_busmaster[channel].ptr_cur + 4])) & 0xfffe; piix_busmaster[channel].eot = (*(uint32_t *)(&ram[piix_busmaster[channel].ptr_cur + 4])) >> 31; piix_busmaster[channel].ptr_cur += 8; -// pclog("New DMA settings on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); } void piix_bus_master_write(uint16_t port, uint8_t val, void *priv) { int channel = (port & 8) ? 1 : 0; -// pclog("PIIX Bus Master write %04X %02X %04x:%08x\n", port, val, CS, pc); switch (port & 7) { case 0: @@ -381,7 +375,6 @@ void piix_bus_master_write(uint16_t port, uint8_t val, void *priv) uint8_t piix_bus_master_read(uint16_t port, void *priv) { int channel = (port & 8) ? 1 : 0; -// pclog("PIIX Bus Master read %04X %04x:%08x\n", port, CS, pc); switch (port & 7) { case 0: @@ -419,7 +412,6 @@ int piix_bus_master_dma_read_ex(int channel, uint8_t *data) mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr + piix_busmaster[channel].count - 1); - // pclog("Transferring special - %i bytes\n", piix_busmaster[channel].count); memcpy(&ram[piix_busmaster[channel].addr], data, piix_busmaster[channel].count); transferred += piix_busmaster[channel].count; piix_busmaster[channel].addr += piix_busmaster[channel].count; @@ -428,13 +420,11 @@ int piix_bus_master_dma_read_ex(int channel, uint8_t *data) if (piix_busmaster[channel].eot) /*End of transfer?*/ { - // pclog("DMA on channel %i - transfer over\n", channel); piix_busmaster[channel].status &= ~1; return -1; } else { - // pclog("DMA on channel %i - transfer continuing\n", channel); piix_bus_master_next_addr(channel); } return 0; @@ -458,7 +448,6 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) if (piix_busmaster[channel].count < (transfer_length - transferred)) { -// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); memcpy(&ram[piix_busmaster[channel].addr], data + transferred, piix_busmaster[channel].count); transferred += piix_busmaster[channel].count; piix_busmaster[channel].addr += piix_busmaster[channel].count; @@ -467,21 +456,16 @@ int piix_bus_master_dma_read(int channel, uint8_t *data, int transfer_length) } else { -// pclog("Transferring larger - %i bytes\n", transfer_length - transferred); memcpy(&ram[piix_busmaster[channel].addr], data + transferred, transfer_length - transferred); piix_busmaster[channel].addr += (transfer_length - transferred); piix_busmaster[channel].count -= (transfer_length - transferred); transferred += (transfer_length - transferred); } - // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); - if (!piix_busmaster[channel].count) { - // pclog("DMA on channel %i - block over\n", channel); if (piix_busmaster[channel].eot) /*End of transfer?*/ { - // pclog("DMA on channel %i - transfer over\n", channel); piix_busmaster[channel].status &= ~1; } else @@ -495,13 +479,9 @@ int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) { int transferred = 0; - // pclog("piix_bus_master_dma_write(%08X, %08X, %08X) on %08X data\n", channel, data, transfer_length, piix_busmaster[channel].count); - if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ - // pclog("DMA not disabled\n"); - while (transferred < transfer_length) { if ((piix_busmaster[channel].count < (transfer_length - transferred)) && piix_busmaster[channel].eot && (transfer_length == 512)) @@ -511,7 +491,6 @@ int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) if (piix_busmaster[channel].count < (transfer_length - transferred)) { -// pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); memcpy(data + transferred, &ram[piix_busmaster[channel].addr], piix_busmaster[channel].count); transferred += piix_busmaster[channel].count; piix_busmaster[channel].addr += piix_busmaster[channel].count; @@ -520,21 +499,16 @@ int piix_bus_master_dma_write(int channel, uint8_t *data, int transfer_length) } else { -// pclog("Transferring larger - %i bytes\n", transfer_length - transferred); memcpy(data + transferred, &ram[piix_busmaster[channel].addr], transfer_length - transferred); piix_busmaster[channel].addr += (transfer_length - transferred); piix_busmaster[channel].count -= (transfer_length - transferred); transferred += (transfer_length - transferred); } -// pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); - if (!piix_busmaster[channel].count) { -// pclog("DMA on channel %i - block over\n", channel); if (piix_busmaster[channel].eot) /*End of transfer?*/ { -// pclog("DMA on channel %i - transfer over\n", channel); piix_busmaster[channel].status &= ~1; } else @@ -562,12 +536,10 @@ static void rc_write(uint16_t port, uint8_t val, void *priv) { if (reset_reg & 2) { - // pclog("PIIX: Hard reset\n"); resetpchard(); } else { - // pclog("PIIX: Soft reset\n"); if (piix_type == 3) { piix3_reset(); diff --git a/src/piix.h b/src/piix.h index 4953d500e..c86a680ce 100644 --- a/src/piix.h +++ b/src/piix.h @@ -3,3 +3,10 @@ */ void piix_init(int card); void piix3_init(int card); + +uint8_t piix_bus_master_read(uint16_t port, void *priv); +void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); + +int piix_bus_master_get_count(int channel); + +int piix_bus_master_dma_read_ex(int channel, uint8_t *data); diff --git a/src/pit.c b/src/pit.c index b9804eefb..e9e4cb090 100644 --- a/src/pit.c +++ b/src/pit.c @@ -7,16 +7,17 @@ #include "ibm.h" #include "cpu.h" +#include "device.h" #include "dma.h" #include "io.h" #include "pic.h" #include "pit.h" +#include "sound_speaker.h" #include "timer.h" #include "video.h" #include "model.h" /*B0 to 40, two writes to 43, then two reads - value does not change!*/ /*B4 to 40, two writes to 43, then two reads - value _does_ change!*/ -//Tyrian writes 4300 or 17512 int displine; double PITCONST; @@ -26,7 +27,6 @@ float isa_timing, bus_timing; int firsttime=1; void setpitclock(float clock) { -// printf("PIT clock %f\n",clock); cpuclock=clock; PITCONST=clock/1193182.0; CGACONST=(clock/(19687503.0/11.0)); @@ -36,32 +36,33 @@ void setpitclock(float clock) isa_timing = clock/8000000.0; bus_timing = clock/(double)cpu_busspeed; video_updatetiming(); -// pclog("PITCONST=%f CGACONST=%f\n", PITCONST, CGACONST); -// pclog("CPUMULTI=%g\n", ((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed)); xt_cpu_multi = (int)((14318184.0*(double)(1 << TIMER_SHIFT)) / (double)models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); -// pclog("egacycles %i egacycles2 %i temp %f clock %f\n",egacycles,egacycles2,temp,clock); -/* if (video_recalctimings) - video_recalctimings();*/ RTCCONST=clock/32768.0; TIMER_USEC = (int)((clock / 1000000.0f) * (float)(1 << TIMER_SHIFT)); device_speed_changed(); } -//#define PITCONST (8000000.0/1193000.0) -//#define PITCONST (cpuclock/1193000.0) -void pit_reset() +void pit_reset(PIT *pit) { - memset(&pit,0,sizeof(PIT)); - pit.l[0]=0xFFFF; pit.c[0]=0xFFFF*PITCONST; - pit.l[1]=0xFFFF; pit.c[1]=0xFFFF*PITCONST; - pit.l[2]=0xFFFF; pit.c[2]=0xFFFF*PITCONST; - pit.m[0]=pit.m[1]=pit.m[2]=0; - pit.ctrls[0]=pit.ctrls[1]=pit.ctrls[2]=0; - pit.thit[0]=1; - pit.gate[0] = pit.gate[1] = 1; - pit.gate[2] = 0; - pit.using_timer[0] = pit.using_timer[1] = pit.using_timer[2] = 1; + void (*old_set_out_funcs[3])(int new_out, int old_out); + PIT_nr old_pit_nr[3]; + + memcpy(old_set_out_funcs, pit->set_out_funcs, 3 * sizeof(void *)); + memcpy(old_pit_nr, pit->pit_nr, 3 * sizeof(PIT_nr)); + memset(pit, 0, sizeof(PIT)); + memcpy(pit->set_out_funcs, old_set_out_funcs, 3 * sizeof(void *)); + memcpy(pit->pit_nr, old_pit_nr, 3 * sizeof(PIT_nr)); + + pit->l[0] = 0xFFFF; pit->c[0] = 0xFFFF*PITCONST; + pit->l[1] = 0xFFFF; pit->c[1] = 0xFFFF*PITCONST; + pit->l[2] = 0xFFFF; pit->c[2] = 0xFFFF*PITCONST; + pit->m[0] = pit->m[1] = pit->m[2] = 0; + pit->ctrls[0] = pit->ctrls[1] = pit->ctrls[2] = 0; + pit->thit[0]=1; + pit->gate[0] = pit->gate[1] = 1; + pit->gate[2] = 0; + pit->using_timer[0] = pit->using_timer[1] = pit->using_timer[2] = 1; } void clearpit() @@ -77,210 +78,214 @@ float pit_timer0_freq() return 1193182.0f/(float)0x10000; } -static void (*pit_set_out_funcs[3])(int new_out, int old_out); - -static void pit_set_out(int t, int out) +static void pit_set_out(PIT *pit, int t, int out) { - pit_set_out_funcs[t](out, pit.out[t]); - pit.out[t] = out; + pit->set_out_funcs[t](out, pit->out[t]); + pit->out[t] = out; } -static void pit_load(int t) +static void pit_load(PIT *pit, int t) { - int l = pit.l[t] ? pit.l[t] : 0x10000; + int l = pit->l[t] ? pit->l[t] : 0x10000; timer_process(); - pit.newcount[t] = 0; - pit.disabled[t] = 0; -// pclog("pit_load: t=%i l=%x\n", t, l); - switch (pit.m[t]) + pit->newcount[t] = 0; + pit->disabled[t] = 0; + switch (pit->m[t]) { case 0: /*Interrupt on terminal count*/ - pit.count[t] = l; - pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 0); - pit.thit[t] = 0; - pit.enabled[t] = pit.gate[t]; + pit->count[t] = l; + pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 0); + pit->thit[t] = 0; + pit->enabled[t] = pit->gate[t]; break; case 1: /*Hardware retriggerable one-shot*/ - pit.enabled[t] = 1; + pit->enabled[t] = 1; break; case 2: /*Rate generator*/ - if (pit.initial[t]) + if (pit->initial[t]) { - pit.count[t] = l - 1; - pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 1); - pit.thit[t] = 0; + pit->count[t] = l - 1; + pit->c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 1); + pit->thit[t] = 0; } - pit.enabled[t] = pit.gate[t]; + pit->enabled[t] = pit->gate[t]; break; case 3: /*Square wave mode*/ - if (pit.initial[t]) + if (pit->initial[t]) { - pit.count[t] = l; - pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 1); - pit.thit[t] = 0; + pit->count[t] = l; + pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 1); + pit->thit[t] = 0; } - pit.enabled[t] = pit.gate[t]; -// pclog("pit_load: square wave mode c=%x\n", pit.c[t]); + pit->enabled[t] = pit->gate[t]; break; case 4: /*Software triggered stobe*/ - if (!pit.thit[t] && !pit.initial[t]) - pit.newcount[t] = 1; + if (!pit->thit[t] && !pit->initial[t]) + pit->newcount[t] = 1; else { - pit.count[t] = l; - pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 0); - pit.thit[t] = 0; + pit->count[t] = l; + pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 0); + pit->thit[t] = 0; } - pit.enabled[t] = pit.gate[t]; + pit->enabled[t] = pit->gate[t]; break; case 5: /*Hardware triggered stobe*/ - pit.enabled[t] = 1; + pit->enabled[t] = 1; break; } - pit.initial[t] = 0; - pit.running[t] = pit.enabled[t] && pit.using_timer[t] && !pit.disabled[t]; + pit->initial[t] = 0; + pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; timer_update_outstanding(); -// pclog("pit_load: t=%i running=%i thit=%i enabled=%i m=%i l=%x c=%g gate=%i\n", t, pit.running[t], pit.thit[t], pit.enabled[t], pit.m[t], pit.l[t], pit.c[t], pit.gate[t]); } -void pit_set_gate(int t, int gate) +void pit_set_gate_no_timer(PIT *pit, int t, int gate) { - int l = pit.l[t] ? pit.l[t] : 0x10000; + int l = pit->l[t] ? pit->l[t] : 0x10000; - if (pit.disabled[t]) + if (pit->disabled[t]) { - pit.gate[t] = gate; + pit->gate[t] = gate; return; } - timer_process(); - switch (pit.m[t]) + switch (pit->m[t]) { case 0: /*Interrupt on terminal count*/ case 4: /*Software triggered stobe*/ - pit.enabled[t] = gate; + pit->enabled[t] = gate; break; case 1: /*Hardware retriggerable one-shot*/ case 5: /*Hardware triggered stobe*/ - if (gate && !pit.gate[t]) + if (gate && !pit->gate[t]) { - pit.count[t] = l; - pit.c[t] = (int)((l << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 0); - pit.thit[t] = 0; - pit.enabled[t] = 1; + pit->count[t] = l; + pit->c[t] = (int)((l << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 0); + pit->thit[t] = 0; + pit->enabled[t] = 1; } break; case 2: /*Rate generator*/ - if (gate && !pit.gate[t]) + if (gate && !pit->gate[t]) { - pit.count[t] = l - 1; - pit.c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 1); - pit.thit[t] = 0; + pit->count[t] = l - 1; + pit->c[t] = (int)(((l - 1) << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 1); + pit->thit[t] = 0; } - pit.enabled[t] = gate; + pit->enabled[t] = gate; break; case 3: /*Square wave mode*/ - if (gate && !pit.gate[t]) + if (gate && !pit->gate[t]) { - pit.count[t] = l; - pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 1); - pit.thit[t] = 0; + pit->count[t] = l; + pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 1); + pit->thit[t] = 0; } - pit.enabled[t] = gate; + pit->enabled[t] = gate; break; } - pit.gate[t] = gate; - pit.running[t] = pit.enabled[t] && pit.using_timer[t] && !pit.disabled[t]; - timer_update_outstanding(); -// pclog("pit_set_gate: t=%i gate=%i\n", t, gate); + pit->gate[t] = gate; + pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; } -static void pit_over(int t) +void pit_set_gate(PIT *pit, int t, int gate) { - int l = pit.l[t] ? pit.l[t] : 0x10000; - if (pit.disabled[t]) + if (pit->disabled[t]) { - pit.count[t] += 0xffff; - pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + pit->gate[t] = gate; return; } -// if (!t) pclog("pit_over: t=%i l=%x c=%x %i hit=%i\n", t, pit.l[t], pit.c[t], pit.c[t] >> TIMER_SHIFT, pit.thit[t]); - switch (pit.m[t]) + timer_process(); + + pit_set_gate_no_timer(pit, t, gate); + + timer_update_outstanding(); +} + +static void pit_over(PIT *pit, int t) +{ + int l = pit->l[t] ? pit->l[t] : 0x10000; + if (pit->disabled[t]) + { + pit->count[t] += 0xffff; + pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + return; + } + + switch (pit->m[t]) { case 0: /*Interrupt on terminal count*/ case 1: /*Hardware retriggerable one-shot*/ - if (!pit.thit[t]) - pit_set_out(t, 1); - pit.thit[t] = 1; - pit.count[t] += 0xffff; - pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + if (!pit->thit[t]) + pit_set_out(pit, t, 1); + pit->thit[t] = 1; + pit->count[t] += 0xffff; + pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); break; case 2: /*Rate generator*/ - pit.count[t] += l; - pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST); - pit_set_out(t, 0); - pit_set_out(t, 1); + pit->count[t] += l; + pit->c[t] += (int)((l << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 0); + pit_set_out(pit, t, 1); break; case 3: /*Square wave mode*/ - if (pit.out[t]) + if (pit->out[t]) { - pit_set_out(t, 0); - pit.count[t] += (l >> 1); - pit.c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 0); + pit->count[t] += (l >> 1); + pit->c[t] += (int)(((l >> 1) << TIMER_SHIFT) * PITCONST); } else { - pit_set_out(t, 1); - pit.count[t] += ((l + 1) >> 1); - pit.c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); + pit_set_out(pit, t, 1); + pit->count[t] += ((l + 1) >> 1); + pit->c[t] = (int)((((l + 1) >> 1) << TIMER_SHIFT) * PITCONST); } -// if (!t) pclog("pit_over: square wave mode c=%x %lli %f\n", pit.c[t], tsc, PITCONST); break; case 4: /*Software triggered strove*/ - if (!pit.thit[t]) + if (!pit->thit[t]) { - pit_set_out(t, 0); - pit_set_out(t, 1); + pit_set_out(pit, t, 0); + pit_set_out(pit, t, 1); } - if (pit.newcount[t]) + if (pit->newcount[t]) { - pit.newcount[t] = 0; - pit.count[t] += l; - pit.c[t] += (int)((l << TIMER_SHIFT) * PITCONST); + pit->newcount[t] = 0; + pit->count[t] += l; + pit->c[t] += (int)((l << TIMER_SHIFT) * PITCONST); } else { - pit.thit[t] = 1; - pit.count[t] += 0xffff; - pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + pit->thit[t] = 1; + pit->count[t] += 0xffff; + pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); } break; case 5: /*Hardware triggered strove*/ - if (!pit.thit[t]) + if (!pit->thit[t]) { - pit_set_out(t, 0); - pit_set_out(t, 1); + pit_set_out(pit, t, 0); + pit_set_out(pit, t, 1); } - pit.thit[t] = 1; - pit.count[t] += 0xffff; - pit.c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); + pit->thit[t] = 1; + pit->count[t] += 0xffff; + pit->c[t] += (int)((0xffff << TIMER_SHIFT) * PITCONST); break; } - pit.running[t] = pit.enabled[t] && pit.using_timer[t] && !pit.disabled[t]; + pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; } int pit_get_timer_0() { int read = (int)((pit.c[0] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT; -//pclog("pit_get_timer_0: t=%i using_timer=%i m=%i\n", 0, pit.using_timer[0], pit.m[0]); if (pit.m[0] == 2) read++; if (read < 0) @@ -292,33 +297,32 @@ int pit_get_timer_0() return read; } -static int pit_read_timer(int t) +static int pit_read_timer(PIT *pit, int t) { timer_clock(); -// pclog("pit_read_timer: t=%i using_timer=%i m=%i\n", t, pit.using_timer[t], pit.m[t]); - if (pit.using_timer[t]) + if (pit->using_timer[t]) { - int read = (int)((pit.c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT; - if (pit.m[t] == 2) + int read = (int)((pit->c[t] + ((1 << TIMER_SHIFT) - 1)) / PITCONST) >> TIMER_SHIFT; + if (pit->m[t] == 2) read++; if (read < 0) read = 0; if (read > 0x10000) read = 0x10000; - if (pit.m[t] == 3) + if (pit->m[t] == 3) read <<= 1; return read; } - if (pit.m[t] == 2) - return pit.count[t] + 1; - return pit.count[t]; + if (pit->m[t] == 2) + return pit->count[t] + 1; + return pit->count[t]; } -void pit_write(uint16_t addr, uint8_t val, void *priv) +void pit_write(uint16_t addr, uint8_t val, void *p) { + PIT *pit = (PIT *)p; int t; cycles -= (int)PITCONST; -// /*if (val != 0x40) */pclog("Write PIT %04X %02X %04X:%08X %i %i\n",addr,val,CS,pc,ins, pit.gate[0]); switch (addr&3) { @@ -328,234 +332,192 @@ void pit_write(uint16_t addr, uint8_t val, void *priv) if (!(val&0x20)) { if (val & 2) - pit.rl[0] = pit.using_timer[0] ? ((int)(pit.c[0] / PITCONST) >> TIMER_SHIFT) : pit.count[0]; + pit->rl[0] = pit->using_timer[0] ? ((int)(pit->c[0] / PITCONST) >> TIMER_SHIFT) : pit->count[0]; if (val & 4) - pit.rl[1] = pit.using_timer[1] ? ((int)(pit.c[1] / PITCONST) >> TIMER_SHIFT) : pit.count[1]; + pit->rl[1] = pit->using_timer[1] ? ((int)(pit->c[1] / PITCONST) >> TIMER_SHIFT) : pit->count[1]; if (val & 8) - pit.rl[2] = pit.using_timer[2] ? ((int)(pit.c[2] / PITCONST) >> TIMER_SHIFT) : pit.count[2]; + pit->rl[2] = pit->using_timer[2] ? ((int)(pit->c[2] / PITCONST) >> TIMER_SHIFT) : pit->count[2]; } if (!(val & 0x10)) { if (val & 2) { - pit.read_status[0] = (pit.ctrls[0] & 0x3f) | 0x40 | (pit.out[0] ? 0x80 : 0); - pit.do_read_status[0] = 1; + pit->read_status[0] = (pit->ctrls[0] & 0x3f) | 0x40 | (pit->out[0] ? 0x80 : 0); + pit->do_read_status[0] = 1; } if (val & 4) { - pit.read_status[1] = (pit.ctrls[1] & 0x3f) | 0x40 | (pit.out[1] ? 0x80 : 0); - pit.do_read_status[1] = 1; + pit->read_status[1] = (pit->ctrls[1] & 0x3f) | 0x40 | (pit->out[1] ? 0x80 : 0); + pit->do_read_status[1] = 1; } if (val & 8) { - pit.read_status[2] = (pit.ctrls[2] & 0x3f) | 0x40 | (pit.out[2] ? 0x80 : 0); - pit.do_read_status[2] = 1; + pit->read_status[2] = (pit->ctrls[2] & 0x3f) | 0x40 | (pit->out[2] ? 0x80 : 0); + pit->do_read_status[2] = 1; } } return; } t = val >> 6; - pit.ctrl=val; + pit->ctrl=val; if ((val>>7)==3) { - printf("Bad PIT reg select\n"); return; -// dumpregs(); -// exit(-1); } -// printf("CTRL write %02X\n",val); - if (!(pit.ctrl&0x30)) + if (!(pit->ctrl&0x30)) { - pit.rl[t] = pit_read_timer(t); -// pclog("Timer latch %f %04X %04X\n",pit.c[0],pit.rl[0],pit.l[0]); - pit.ctrl |= 0x30; - pit.rereadlatch[t] = 0; - pit.rm[t] = 3; - pit.latched[t] = 1; + pit->rl[t] = pit_read_timer(pit, t); + pit->ctrl |= 0x30; + pit->rereadlatch[t] = 0; + pit->rm[t] = 3; + pit->latched[t] = 1; } else { - pit.ctrls[val>>6] = val; - pit.rm[val>>6]=pit.wm[val>>6]=(pit.ctrl>>4)&3; - pit.m[val>>6]=(val>>1)&7; - if (pit.m[val>>6]>5) - pit.m[val>>6]&=3; - if (!(pit.rm[val>>6])) + pit->ctrls[t] = val; + pit->rm[t]=pit->wm[t]=(pit->ctrl>>4)&3; + pit->m[t]=(val>>1)&7; + if (pit->m[t]>5) + pit->m[t]&=3; + if (!(pit->rm[t])) { - pit.rm[val>>6]=3; - pit.rl[t] = pit_read_timer(t); + pit->rm[t]=3; + pit->rl[t] = pit_read_timer(pit, t); } - pit.rereadlatch[val>>6]=1; - if ((val>>6)==2) ppispeakon=speakon=(pit.m[2]==0)?0:1; - pit.initial[t] = 1; - if (!pit.m[val >> 6]) - pit_set_out(val >> 6, 0); + pit->rereadlatch[t]=1; + if (t == 2) ppispeakon=speakon=(pit->m[2]==0)?0:1; + pit->initial[t] = 1; + if (!pit->m[t]) + pit_set_out(pit, t, 0); else - pit_set_out(val >> 6, 1); - pit.disabled[val >> 6] = 1; -// pclog("ppispeakon %i\n",ppispeakon); + pit_set_out(pit, t, 1); + pit->disabled[t] = 1; } - pit.wp=0; - pit.thit[pit.ctrl>>6]=0; + pit->wp=0; + pit->thit[t]=0; break; case 0: case 1: case 2: /*Timers*/ t=addr&3; -// if (t==2) ppispeakon=speakon=0; -// pclog("Write timer %02X %i\n",pit.ctrls[t],pit.wm[t]); - switch (pit.wm[t]) + switch (pit->wm[t]) { case 1: - pit.l[t]=val; -// pit.thit[t]=0; - pit_load(t); -// pit.c[t]=pit.l[t]*PITCONST; -// if (!t) -// picintc(1); + pit->l[t]=val; + pit_load(pit, t); break; case 2: - pit.l[t]=(val<<8); -// pit.thit[t]=0; - pit_load(t); -// pit.c[t]=pit.l[t]*PITCONST; -// if (!t) -// picintc(1); + pit->l[t]=(val<<8); + pit_load(pit, t); break; case 0: - pit.l[t]&=0xFF; - pit.l[t]|=(val<<8); - pit_load(t); -// pit.c[t]=pit.l[t]*PITCONST; -// pclog("%04X %f\n",pit.l[t],pit.c[t]); -// pit.thit[t]=0; - pit.wm[t]=3; -// if (!t) -// picintc(1); + pit->l[t]&=0xFF; + pit->l[t]|=(val<<8); + pit_load(pit, t); + pit->wm[t]=3; break; case 3: - pit.l[t]&=0xFF00; - pit.l[t]|=val; - pit.wm[t]=0; + pit->l[t]&=0xFF00; + pit->l[t]|=val; + pit->wm[t]=0; break; } - speakval=(((float)pit.l[2]/(float)pit.l[0])*0x4000)-0x2000; -// printf("Speakval now %i\n",speakval); -// if (speakval>0x2000) -// printf("Speaker overflow - %i %i %04X %04X\n",pit.l[0],pit.l[2],pit.l[0],pit.l[2]); + speakval=(((float)pit->l[2]/(float)pit->l[0])*0x4000)-0x2000; if (speakval>0x2000) speakval=0x2000; -/* if (!pit.l[t]) - { - pit.l[t]|=0x10000; - pit.c[t]=pit.l[t]*PITCONST; - }*/ break; } } -uint8_t pit_read(uint16_t addr, void *priv) +uint8_t pit_read(uint16_t addr, void *p) { + PIT *pit = (PIT *)p; int t; uint8_t temp; cycles -= (int)PITCONST; -// printf("Read PIT %04X ",addr); switch (addr&3) { case 0: case 1: case 2: /*Timers*/ t = addr & 3; - if (pit.do_read_status[t]) + if (pit->do_read_status[t]) { - pit.do_read_status[t] = 0; - temp = pit.read_status[t]; + pit->do_read_status[t] = 0; + temp = pit->read_status[t]; break; } - if (pit.rereadlatch[addr & 3] && !pit.latched[addr & 3]) + if (pit->rereadlatch[addr & 3] && !pit->latched[addr & 3]) { - pit.rereadlatch[addr & 3] = 0; - pit.rl[t] = pit_read_timer(t); + pit->rereadlatch[addr & 3] = 0; + pit->rl[t] = pit_read_timer(pit, t); } - switch (pit.rm[addr & 3]) + switch (pit->rm[addr & 3]) { case 0: - temp = pit.rl[addr & 3] >> 8; - pit.rm[addr & 3] = 3; - pit.latched[addr & 3] = 0; - pit.rereadlatch[addr & 3] = 1; + temp = pit->rl[addr & 3] >> 8; + pit->rm[addr & 3] = 3; + pit->latched[addr & 3] = 0; + pit->rereadlatch[addr & 3] = 1; break; case 1: - temp = (pit.rl[addr & 3]) & 0xFF; - pit.latched[addr & 3] = 0; - pit.rereadlatch[addr & 3] = 1; + temp = (pit->rl[addr & 3]) & 0xFF; + pit->latched[addr & 3] = 0; + pit->rereadlatch[addr & 3] = 1; break; case 2: - temp = (pit.rl[addr & 3]) >> 8; - pit.latched[addr & 3] = 0; - pit.rereadlatch[addr & 3] = 1; + temp = (pit->rl[addr & 3]) >> 8; + pit->latched[addr & 3] = 0; + pit->rereadlatch[addr & 3] = 1; break; case 3: - temp = (pit.rl[addr & 3]) & 0xFF; - if (pit.m[addr & 3] & 0x80) - pit.m[addr & 3] &= 7; + temp = (pit->rl[addr & 3]) & 0xFF; + if (pit->m[addr & 3] & 0x80) + pit->m[addr & 3] &= 7; else - pit.rm[addr & 3] = 0; + pit->rm[addr & 3] = 0; break; } break; case 3: /*Control*/ - temp = pit.ctrl; + temp = pit->ctrl; break; } -// pclog("%02X\n", temp); -// printf("%02X %i %i %04X:%04X %i\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc, ins); return temp; } -void pit_poll() -{ -// printf("Poll pit %f %f %f\n",pit.c[0],pit.c[1],pit.c[2]); - if (pit.c[0] < 1 && pit.running[0]) - pit_over(0); - if (pit.c[1] < 1 && pit.running[1]) - pit_over(1); - if (pit.c[2] < 1 && pit.running[2]) - pit_over(2); -} - void pit_timer_over(void *p) { - int timer = (int) p; -// pclog("pit_timer_over %i\n", timer); - - pit_over(timer); + PIT_nr *pit_nr = (PIT_nr *)p; + PIT *pit = pit_nr->pit; + int timer = pit_nr->nr; + + pit_over(pit, timer); } -void pit_clock(int t) +void pit_clock(PIT *pit, int t) { - if (pit.thit[t] || !pit.enabled[t]) + if (pit->thit[t] || !pit->enabled[t]) return; - if (pit.using_timer[t]) + if (pit->using_timer[t]) return; - pit.count[t] -= (pit.m[t] == 3) ? 2 : 1; - if (!pit.count[t]) - pit_over(t); + pit->count[t] -= (pit->m[t] == 3) ? 2 : 1; + if (!pit->count[t]) + pit_over(pit, t); } -void pit_set_using_timer(int t, int using_timer) +void pit_set_using_timer(PIT *pit, int t, int using_timer) { -// pclog("pit_set_using_timer: t=%i using_timer=%i\n", t, using_timer); timer_process(); - if (pit.using_timer[t] && !using_timer) - pit.count[t] = pit_read_timer(t); - if (!pit.using_timer[t] && using_timer) - pit.c[t] = (int)((pit.count[t] << TIMER_SHIFT) * PITCONST); - pit.using_timer[t] = using_timer; - pit.running[t] = pit.enabled[t] && pit.using_timer[t] && !pit.disabled[t]; + if (pit->using_timer[t] && !using_timer) + pit->count[t] = pit_read_timer(pit, t); + if (!pit->using_timer[t] && using_timer) + pit->c[t] = (int)((pit->count[t] << TIMER_SHIFT) * PITCONST); + pit->using_timer[t] = using_timer; + pit->running[t] = pit->enabled[t] && pit->using_timer[t] && !pit->disabled[t]; timer_update_outstanding(); } -void pit_set_out_func(int t, void (*func)(int new_out, int old_out)) +void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out)) { - pit_set_out_funcs[t] = func; + pit->set_out_funcs[t] = func; } void pit_null_timer(int new_out, int old_out) @@ -575,12 +537,25 @@ void pit_irq0_timer_pcjr(int new_out, int old_out) if (new_out && !old_out) { picint(1); - pit_clock(1); + pit_clock(&pit, 1); } if (!new_out) picintc(1); } +void pit_irq0_ps2(int new_out, int old_out) +{ + if (new_out && !old_out) + { + picint(1); + pit_set_gate_no_timer(&pit2, 0, 1); + } + if (!new_out) + picintc(1); + if (!new_out && old_out) + pit_clock(&pit2, 0); +} + void pit_refresh_timer_xt(int new_out, int old_out) { if (new_out && !old_out) @@ -608,18 +583,52 @@ void pit_speaker_timer(int new_out, int old_out) } +void pit_nmi_ps2(int new_out, int old_out) +{ + nmi = new_out; + if (nmi) + nmi_auto_clear = 1; +} + void pit_init() { - io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, NULL); + pit_reset(&pit); + + io_sethandler(0x0040, 0x0004, pit_read, NULL, NULL, pit_write, NULL, NULL, &pit); pit.gate[0] = pit.gate[1] = 1; pit.gate[2] = 0; pit.using_timer[0] = pit.using_timer[1] = pit.using_timer[2] = 1; + + pit.pit_nr[0].nr = 0; + pit.pit_nr[1].nr = 1; + pit.pit_nr[2].nr = 2; + pit.pit_nr[0].pit = pit.pit_nr[1].pit = pit.pit_nr[2].pit = &pit; - timer_add(pit_timer_over, &pit.c[0], &pit.running[0], (void *)0); - timer_add(pit_timer_over, &pit.c[1], &pit.running[1], (void *)1); - timer_add(pit_timer_over, &pit.c[2], &pit.running[2], (void *)2); + timer_add(pit_timer_over, &pit.c[0], &pit.running[0], (void *)&pit.pit_nr[0]); + timer_add(pit_timer_over, &pit.c[1], &pit.running[1], (void *)&pit.pit_nr[1]); + timer_add(pit_timer_over, &pit.c[2], &pit.running[2], (void *)&pit.pit_nr[2]); - pit_set_out_func(0, pit_irq0_timer); - pit_set_out_func(1, pit_null_timer); - pit_set_out_func(2, pit_speaker_timer); + pit_set_out_func(&pit, 0, pit_irq0_timer); + pit_set_out_func(&pit, 1, pit_null_timer); + pit_set_out_func(&pit, 2, pit_speaker_timer); +} + +void pit_ps2_init() +{ + pit_reset(&pit2); + + io_sethandler(0x0044, 0x0001, pit_read, NULL, NULL, pit_write, NULL, NULL, &pit2); + io_sethandler(0x0047, 0x0001, pit_read, NULL, NULL, pit_write, NULL, NULL, &pit2); + + pit2.gate[0] = 0; + pit2.using_timer[0] = 0; + pit2.disabled[0] = 1; + + pit2.pit_nr[0].nr = 0; + pit2.pit_nr[0].pit = &pit2; + + timer_add(pit_timer_over, &pit2.c[0], &pit2.running[0], (void *)&pit2.pit_nr[0]); + + pit_set_out_func(&pit, 0, pit_irq0_ps2); + pit_set_out_func(&pit2, 0, pit_nmi_ps2); } diff --git a/src/pit.h b/src/pit.h index 3d5018bd1..a827e9581 100644 --- a/src/pit.h +++ b/src/pit.h @@ -1,10 +1,11 @@ extern double PITCONST; void pit_init(); -void pit_reset(); -void pit_set_gate(int channel, int gate); -void pit_set_using_timer(int t, int using_timer); -void pit_set_out_func(int t, void (*func)(int new_out, int old_out)); -void pit_clock(int t); +void pit_ps2_init(); +void pit_reset(PIT *pit); +void pit_set_gate(PIT *pit, int channel, int gate); +void pit_set_using_timer(PIT *pit, int t, int using_timer); +void pit_set_out_func(PIT *pit, int t, void (*func)(int new_out, int old_out)); +void pit_clock(PIT *pit, int t); void pit_null_timer(int new_out, int old_out); diff --git a/src/plat-midi.h b/src/plat-midi.h index 15b9edafe..f258cdbcb 100644 --- a/src/plat-midi.h +++ b/src/plat-midi.h @@ -4,3 +4,5 @@ void midi_init(); void midi_close(); void midi_write(uint8_t val); +int midi_get_num_devs(); +void midi_get_dev_name(int num, char *s); diff --git a/src/ppi.c b/src/ppi.c index 2d564b90c..0eb9f3a0f 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -16,7 +16,7 @@ void ppi_reset() { - ppi.pa=0x0;//0x1D; + ppi.pa=0x0; ppi.pb=0x40; } diff --git a/src/ps1.c b/src/ps1.c index 8da00c91a..a9f068bfd 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -2,10 +2,12 @@ see COPYING for more details */ #include "ibm.h" +#include "io.h" #include "mem.h" #include "ps1.h" #include "rom.h" #include "lpt.h" +#include "serial.h" static rom_t ps1_high_rom; static uint8_t ps1_92, ps1_94, ps1_102, ps1_103, ps1_104, ps1_105, ps1_190; diff --git a/src/ps2.c b/src/ps2.c index 0b6b08424..1b5c4dc06 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -1,8 +1,10 @@ #include "ibm.h" +#include "io.h" #include "mem.h" #include "ps2.h" #include "rom.h" #include "lpt.h" +#include "serial.h" static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; diff --git a/src/ps2_mca.c b/src/ps2_mca.c new file mode 100644 index 000000000..fd3201ac3 --- /dev/null +++ b/src/ps2_mca.c @@ -0,0 +1,796 @@ +#include "ibm.h" +#include "cpu.h" +#include "device.h" +#include "io.h" +#include "lpt.h" +#include "mca.h" +#include "mem.h" +#include "ps2_mca.h" +#include "ps2_nvr.h" +#include "rom.h" +#include "serial.h" +#include "x86.h" + +static struct +{ + uint8_t adapter_setup; + uint8_t option[4]; + uint8_t pos_vga; + uint8_t setup; + uint8_t sys_ctrl_port_a; + uint8_t subaddr_lo, subaddr_hi; + + uint8_t memory_bank[8]; + + uint8_t io_id; + + mem_mapping_t shadow_mapping; + mem_mapping_t split_mapping; + mem_mapping_t expansion_mapping; + + uint8_t (*planar_read)(uint16_t port); + void (*planar_write)(uint16_t port, uint8_t val); + + uint8_t mem_regs[3]; + + uint32_t split_addr; + + uint8_t mem_pos_regs[8]; +} ps2; + + +static uint8_t ps2_read_shadow_ram(uint32_t addr, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + return mem_read_ram(addr, priv); +} +static uint16_t ps2_read_shadow_ramw(uint32_t addr, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + return mem_read_ramw(addr, priv); +} +static uint32_t ps2_read_shadow_raml(uint32_t addr, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + return mem_read_raml(addr, priv); +} +static void ps2_write_shadow_ram(uint32_t addr, uint8_t val, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_ram(addr, val, priv); +} +static void ps2_write_shadow_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_ramw(addr, val, priv); +} +static void ps2_write_shadow_raml(uint32_t addr, uint32_t val, void *priv) +{ + addr = (addr & 0x1ffff) + 0xe0000; + mem_write_raml(addr, val, priv); +} + +static uint8_t ps2_read_split_ram(uint32_t addr, void *priv) +{ + addr = (addr & 0x3ffff) + 0xa0000; + return mem_read_ram(addr, priv); +} +static uint16_t ps2_read_split_ramw(uint32_t addr, void *priv) +{ + addr = (addr & 0x3ffff) + 0xa0000; + return mem_read_ramw(addr, priv); +} +static uint32_t ps2_read_split_raml(uint32_t addr, void *priv) +{ + addr = (addr & 0x3ffff) + 0xa0000; + return mem_read_raml(addr, priv); +} +static void ps2_write_split_ram(uint32_t addr, uint8_t val, void *priv) +{ + addr = (addr & 0x3ffff) + 0xa0000; + mem_write_ram(addr, val, priv); +} +static void ps2_write_split_ramw(uint32_t addr, uint16_t val, void *priv) +{ + addr = (addr & 0x3ffff) + 0xa0000; + mem_write_ramw(addr, val, priv); +} +static void ps2_write_split_raml(uint32_t addr, uint32_t val, void *priv) +{ + addr = (addr & 0x3ffff) + 0xa0000; + mem_write_raml(addr, val, priv); +} + + + +#define PS2_SETUP_IO 0x80 +#define PS2_SETUP_VGA 0x20 + +#define PS2_ADAPTER_SETUP 0x08 + +static uint8_t model_50_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xfb; + case 0x102: + return ps2.option[0]; + case 0x103: + return ps2.option[1]; + case 0x104: + return ps2.option[2]; + case 0x105: + return ps2.option[3]; + case 0x106: + return ps2.subaddr_lo; + case 0x107: + return ps2.subaddr_hi; + } + return 0xff; +} + +static uint8_t model_55sx_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xfb; + case 0x102: + return ps2.option[0]; + case 0x103: + return ps2.option[1]; + case 0x104: + return ps2.memory_bank[ps2.option[3] & 7]; + case 0x105: + return ps2.option[3]; + case 0x106: + return ps2.subaddr_lo; + case 0x107: + return ps2.subaddr_hi; + } + return 0xff; +} + +static uint8_t model_80_read(uint16_t port) +{ + switch (port) + { + case 0x100: + return 0xff; + case 0x101: + return 0xfd; + case 0x102: + return ps2.option[0]; + case 0x103: + return ps2.option[1]; + case 0x104: + return ps2.option[2]; + case 0x105: + return ps2.option[3]; + case 0x106: + return ps2.subaddr_lo; + case 0x107: + return ps2.subaddr_hi; + } + return 0xff; +} + +static void model_50_write(uint16_t port, uint8_t val) +{ + switch (port) + { + case 0x100: + ps2.io_id = val; + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) + { + if (val & 0x08) + serial1_init(0x3f8, 4); + else + serial1_init(0x2f8, 3); + } + else + serial1_remove(); + if (val & 0x10) + { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps2.option[0] = val; + break; + case 0x103: + ps2.option[1] = val; + break; + case 0x104: + ps2.option[2] = val; + break; + case 0x105: + ps2.option[3] = val; + break; + case 0x106: + ps2.subaddr_lo = val; + break; + case 0x107: + ps2.subaddr_hi = val; + break; + } +} + +static void model_55sx_write(uint16_t port, uint8_t val) +{ + switch (port) + { + case 0x100: + ps2.io_id = val; + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) + { + if (val & 0x08) + serial1_init(0x3f8, 4); + else + serial1_init(0x2f8, 3); + } + else + serial1_remove(); + if (val & 0x10) + { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps2.option[0] = val; + break; + case 0x103: + ps2.option[1] = val; + break; + case 0x104: + ps2.memory_bank[ps2.option[3] & 7] &= ~0xf; + ps2.memory_bank[ps2.option[3] & 7] |= (val & 0xf); + pclog("Write memory bank %i %02x\n", ps2.option[3] & 7, val); + break; + case 0x105: + pclog("Write POS3 %02x\n", val); + ps2.option[3] = val; + shadowbios = !(val & 0x10); + shadowbios_write = val & 0x10; + + if (shadowbios) + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + mem_mapping_disable(&ps2.shadow_mapping); + } + else + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_enable(&ps2.shadow_mapping); + } + + if ((ps2.option[1] & 1) && !(ps2.option[3] & 0x20)) + mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + break; + case 0x106: + ps2.subaddr_lo = val; + break; + case 0x107: + ps2.subaddr_hi = val; + break; + } +} + +static void model_80_write(uint16_t port, uint8_t val) +{ + switch (port) + { + case 0x100: + break; + case 0x101: + break; + case 0x102: + lpt1_remove(); + serial1_remove(); + if (val & 0x04) + { + if (val & 0x08) + serial1_init(0x3f8, 4); + else + serial1_init(0x2f8, 3); + } + else + serial1_remove(); + if (val & 0x10) + { + switch ((val >> 5) & 3) + { + case 0: + lpt1_init(0x3bc); + break; + case 1: + lpt1_init(0x378); + break; + case 2: + lpt1_init(0x278); + break; + } + } + ps2.option[0] = val; + break; + case 0x103: + ps2.option[1] = (ps2.option[1] & 0x0f) | (val & 0xf0); + break; + case 0x104: + ps2.option[2] = val; + break; + case 0x105: + ps2.option[3] = val; + break; + case 0x106: + ps2.subaddr_lo = val; + break; + case 0x107: + ps2.subaddr_hi = val; + break; + } +} + +uint8_t ps2_mca_read(uint16_t port, void *p) +{ + uint8_t temp; + + switch (port) + { + case 0x91: + fatal("Read 91 setup=%02x adapter=%02x\n", ps2.setup, ps2.adapter_setup); + case 0x92: + temp = ps2.sys_ctrl_port_a; + break; + case 0x94: + temp = ps2.setup; + break; + case 0x96: + temp = ps2.adapter_setup | 0x70; + break; + case 0x100: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if (!(ps2.setup & PS2_SETUP_VGA)) + temp = 0xfd; + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x101: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if (!(ps2.setup & PS2_SETUP_VGA)) + temp = 0xef; + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x102: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if (!(ps2.setup & PS2_SETUP_VGA)) + temp = ps2.pos_vga; + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x103: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x104: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x105: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x106: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + temp = mca_read(port); + else + temp = 0xff; + break; + case 0x107: + if (!(ps2.setup & PS2_SETUP_IO)) + temp = ps2.planar_read(port); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + temp = mca_read(port); + else + temp = 0xff; + break; + + default: + temp = 0xff; + break; + } + + pclog("ps2_read: port=%04x temp=%02x\n", port, temp); + + return temp; +} + +static void ps2_mca_write(uint16_t port, uint8_t val, void *p) +{ + pclog("ps2_write: port=%04x val=%02x %04x:%04x\n", port, val, CS,cpu_state.pc); + + switch (port) + { + case 0x0092: + if ((val & 1) && !(ps2.sys_ctrl_port_a & 1)) + { + softresetx86(); + cpu_set_edx(); + } + ps2.sys_ctrl_port_a = val; + mem_a20_alt = val & 2; + mem_a20_recalc(); + break; + case 0x94: + ps2.setup = val; + break; + case 0x96: + ps2.adapter_setup = val; + mca_set_index(val & 7); + break; + case 0x100: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + mca_write(port, val); + break; + case 0x101: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if ((ps2.setup & PS2_SETUP_VGA) && (ps2.setup & PS2_SETUP_VGA) && (ps2.adapter_setup & PS2_ADAPTER_SETUP)) + mca_write(port, val); + break; + case 0x102: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if (!(ps2.setup & PS2_SETUP_VGA)) + ps2.pos_vga = val; + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + mca_write(port, val); + break; + case 0x103: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + mca_write(port, val); + break; + case 0x104: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + mca_write(port, val); + break; + case 0x105: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + mca_write(port, val); + break; + case 0x106: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + mca_write(port, val); + break; + case 0x107: + if (!(ps2.setup & PS2_SETUP_IO)) + ps2.planar_write(port, val); + else if (ps2.adapter_setup & PS2_ADAPTER_SETUP) + mca_write(port, val); + break; + } +} + +static void ps2_mca_board_common_init() +{ + io_sethandler(0x0091, 0x0002, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); + io_sethandler(0x0094, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); + io_sethandler(0x0096, 0x0001, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); + io_sethandler(0x0100, 0x0008, ps2_mca_read, NULL, NULL, ps2_mca_write, NULL, NULL, NULL); + + ps2.setup = 0xff; + + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); + + serial1_remove(); + serial2_remove(); +} + +void ps2_mca_board_model_50_init() +{ + ps2_mca_board_common_init(); + + mem_remap_top_384k(); + mca_init(4); + + ps2.planar_read = model_50_read; + ps2.planar_write = model_50_write; +} + +void ps2_mca_board_model_55sx_init() +{ + ps2_mca_board_common_init(); + + mem_mapping_add(&ps2.shadow_mapping, + (mem_size+256) * 1024, + 128*1024, + ps2_read_shadow_ram, + ps2_read_shadow_ramw, + ps2_read_shadow_raml, + ps2_write_shadow_ram, + ps2_write_shadow_ramw, + ps2_write_shadow_raml, + &ram[0xe0000], + MEM_MAPPING_INTERNAL, + NULL); + + + mem_remap_top_256k(); + ps2.option[3] = 0x10; + + memset(ps2.memory_bank, 0xf0, 8); + switch (mem_size/1024) + { + case 1: + ps2.memory_bank[0] = 0x61; + break; + case 2: + ps2.memory_bank[0] = 0x51; + break; + case 3: + ps2.memory_bank[0] = 0x51; + ps2.memory_bank[1] = 0x61; + break; + case 4: + ps2.memory_bank[0] = 0x51; + ps2.memory_bank[1] = 0x51; + break; + case 5: + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x61; + break; + case 6: + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x51; + break; + case 7: /*Not supported*/ + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x51; + break; + case 8: + ps2.memory_bank[0] = 0x01; + ps2.memory_bank[1] = 0x01; + break; + } + + mca_init(4); + + ps2.planar_read = model_55sx_read; + ps2.planar_write = model_55sx_write; +} + +static void mem_encoding_update() +{ + if (ps2.split_addr >= mem_size*1024) + mem_mapping_disable(&ps2.split_mapping); + + ps2.split_addr = (ps2.mem_regs[0] & 0xf) << 20; + + if (ps2.mem_regs[1] & 2) + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + else + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + + if (!(ps2.mem_regs[1] & 8)) + { + if (ps2.split_addr >= mem_size*1024) + mem_mapping_set_addr(&ps2.split_mapping, ps2.split_addr, 256*1024); + } +} + +static uint8_t mem_encoding_read(uint16_t addr, void *p) +{ + switch (addr) + { + case 0xe0: + return ps2.mem_regs[0]; + case 0xe1: + return ps2.mem_regs[1]; + } + return 0xff; +} +static void mem_encoding_write(uint16_t addr, uint8_t val, void *p) +{ + switch (addr) + { + case 0xe0: + ps2.mem_regs[0] = val; + break; + case 0xe1: + ps2.mem_regs[1] = val; + break; + } + mem_encoding_update(); +} + +static uint8_t ps2_mem_expansion_read(int port, void *p) +{ + return ps2.mem_pos_regs[port & 7]; +} + +static void ps2_mem_expansion_write(int port, uint8_t val, void *p) +{ + if (port < 0x102 || port == 0x104) + return; + + ps2.mem_pos_regs[port & 7] = val; + + if (ps2.mem_pos_regs[2] & 1) + mem_mapping_enable(&ps2.expansion_mapping); + else + mem_mapping_disable(&ps2.expansion_mapping); +} + +void ps2_mca_board_model_80_type2_init() +{ + ps2_mca_board_common_init(); + + mem_remap_top_256k(); + ps2.split_addr = mem_size * 1024; + mca_init(8); + + ps2.planar_read = model_80_read; + ps2.planar_write = model_80_write; + + device_add(&ps2_nvr_device); + + io_sethandler(0x00e0, 0x0002, mem_encoding_read, NULL, NULL, mem_encoding_write, NULL, NULL, NULL); + + ps2.mem_regs[1] = 2; + + switch (mem_size/1024) + { + case 1: + ps2.option[1] = 0x0c; + break; + case 2: + ps2.option[1] = 0x0e; + break; + case 3: + ps2.option[1] = 0x02; + break; + case 4: + default: + ps2.option[1] = 0x0a; + break; + } + + mem_mapping_add(&ps2.split_mapping, + (mem_size+256) * 1024, + 256*1024, + ps2_read_split_ram, + ps2_read_split_ramw, + ps2_read_split_raml, + ps2_write_split_ram, + ps2_write_split_ramw, + ps2_write_split_raml, + &ram[0xa0000], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.split_mapping); + + if (mem_size > 4096) + { + /* Only 4 MB supported on planar, create a memory expansion card for the rest */ + mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x300000); + + ps2.mem_pos_regs[0] = 0xff; + ps2.mem_pos_regs[1] = 0xfc; + + switch (mem_size/1024) + { + case 5: + ps2.mem_pos_regs[4] = 0xfc; + break; + case 6: + ps2.mem_pos_regs[4] = 0xfe; + break; + case 7: + ps2.mem_pos_regs[4] = 0xf2; + break; + case 8: + ps2.mem_pos_regs[4] = 0xfa; + break; + case 9: + ps2.mem_pos_regs[4] = 0xca; + break; + case 10: + ps2.mem_pos_regs[4] = 0xea; + break; + case 11: + ps2.mem_pos_regs[4] = 0x2a; + break; + case 12: + ps2.mem_pos_regs[4] = 0xaa; + break; + } + + mca_add(ps2_mem_expansion_read, ps2_mem_expansion_write, NULL); + mem_mapping_add(&ps2.expansion_mapping, + 0x400000, + (mem_size - 4096)*1024, + mem_read_ram, + mem_read_ramw, + mem_read_raml, + mem_write_ram, + mem_write_ramw, + mem_write_raml, + &ram[0x400000], + MEM_MAPPING_INTERNAL, + NULL); + mem_mapping_disable(&ps2.expansion_mapping); + } +} diff --git a/src/ps2_mca.h b/src/ps2_mca.h new file mode 100644 index 000000000..8f242257e --- /dev/null +++ b/src/ps2_mca.h @@ -0,0 +1,3 @@ +void ps2_mca_board_model_50_init(); +void ps2_mca_board_model_55sx_init(); +void ps2_mca_board_model_80_type2_init(); diff --git a/src/ps2_nvr.c b/src/ps2_nvr.c new file mode 100644 index 000000000..917b0e786 --- /dev/null +++ b/src/ps2_nvr.c @@ -0,0 +1,100 @@ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "ps2_nvr.h" + +typedef struct ps2_nvr_t +{ + int addr; + uint8_t ram[8192]; +} ps2_nvr_t; + +static uint8_t ps2_nvr_read(uint16_t port, void *p) +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + + switch (port) + { + case 0x74: + return nvr->addr & 0xff; + case 0x75: + return nvr->addr >> 8; + case 0x76: + return nvr->ram[nvr->addr]; + } + + return 0xff; +} + +static void ps2_nvr_write(uint16_t port, uint8_t val, void *p) +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + + switch (port) + { + case 0x74: + nvr->addr = (nvr->addr & 0x1f00) | val; + break; + case 0x75: + nvr->addr = (nvr->addr & 0xff) | ((val & 0x1f) << 8); + break; + case 0x76: + nvr->ram[nvr->addr] = val; + break; + } +} + +static void *ps2_nvr_init() +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)malloc(sizeof(ps2_nvr_t)); + FILE *f = NULL; + + memset(nvr, 0, sizeof(ps2_nvr_t)); + + io_sethandler(0x0074, 0x0003, ps2_nvr_read, NULL, NULL, ps2_nvr_write, NULL, NULL, nvr); + + switch (romset) + { + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "rb"); break; + } + if (f) + { + fread(nvr->ram, 8192, 1, f); + fclose(f); + } + else + memset(nvr->ram, 0xFF, 8192); + + return nvr; +} + +static void ps2_nvr_close(void *p) +{ + ps2_nvr_t *nvr = (ps2_nvr_t *)p; + FILE *f = NULL; + + switch (romset) + { + case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "wb"); break; + } + if (f) + { + fwrite(nvr->ram, 8192, 1, f); + fclose(f); + } + + free(nvr); +} + +device_t ps2_nvr_device = +{ + "PS/2 NVRRAM", + 0, + ps2_nvr_init, + ps2_nvr_close, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/ps2_nvr.h b/src/ps2_nvr.h new file mode 100644 index 000000000..1656c82b0 --- /dev/null +++ b/src/ps2_nvr.h @@ -0,0 +1 @@ +extern device_t ps2_nvr_device; diff --git a/src/resource.h b/src/resource.h new file mode 100644 index 000000000..9bfe518b4 --- /dev/null +++ b/src/resource.h @@ -0,0 +1,425 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ + +/* {{NO_DEPENDENCIES}} + Microsoft Developer Studio generated include file. + Used by pc_new2.rc +*/ +#define IDHDCONFIG 3 +#define IDCDCONFIG 4 +#define CONFIGUREDLG_MACHINE 101 +#define CONFIGUREDLG_VIDEO 102 +#define CONFIGUREDLG_INPUT 103 +#define CONFIGUREDLG_SOUND 104 +#define CONFIGUREDLG_PERIPHERALS 105 +#define CONFIGUREDLG_HARD_DISKS 106 +#define CONFIGUREDLG_REMOVABLE_DEVICES 107 +#define ABOUTDLG 108 +#define CONFIGUREDLG_HARD_DISKS_ADD 109 +#define CONFIGUREDLG_MAIN 117 +#define IDC_SETTINGSCATLIST 1004 +#define IDC_LIST_HARD_DISKS 1005 +#define IDC_COMBO_MACHINE 1006 +#define IDC_COMBO_CPU_TYPE 1007 +#define IDC_COMBO_CPU 1008 +#define IDC_COMBO_WS 1009 +#define IDC_CHECK_DYNAREC 1010 +#define IDC_CHECK_FPU 1011 +#define IDC_COMBO_SCSI 1012 +#define IDC_CONFIGURE_SCSI 1013 +#define IDC_COMBO_VIDEO 1014 +#define IDC_COMBO_VIDEO_SPEED 1015 +#define IDC_CHECK_VOODOO 1016 +#define IDC_CHECKCMS 1016 +#define IDC_CONFIGURE_VOODOO 1017 +#define IDC_CHECKNUKEDOPL 1018 +#define IDC_COMBO_JOYSTICK 1018 +#define IDC_CHECK_SYNC 1019 +#define IDC_LIST_FLOPPY_DRIVES 1020 +#define IDC_LIST_CDROM_DRIVES 1021 +#define IDC_CONFIGURE_MACHINE 1022 +#define IDC_COMBO_LANG 1023 +#define IDC_BUTTON_FDD_ADD 1024 +#define IDC_BUTTON_FDD_EDIT 1025 +#define IDC_BUTTON_FDD_REMOVE 1026 +#define IDC_BUTTON_CDROM_ADD 1027 +#define IDC_BUTTON_HDD_ADD_NEW 1027 +#define IDC_BUTTON_CDROM_EDIT 1028 +#define IDC_BUTTON_HDD_ADD 1028 +#define IDC_BUTTON_CDROM_REMOVE 1029 +#define IDC_BUTTON_HDD_REMOVE 1029 +#define IDC_HDIMAGE_NEW 1035 +#define IDC_HD_BUS 1036 +#define IDC_HDIMAGE_EXISTING 1037 +#define IDC_COMBO_HD_BUS 1038 +#define IDC_EDIT_HD_FILE_NAME 1039 +#define IDC_EDIT_HD_CYL 1040 +#define IDC_EDIT_HD_HPC 1041 +#define IDC_EDIT_HD_SPT 1042 +#define IDC_EDIT_HD_SIZE 1043 +#define IDC_COMBO_HD_TYPE 1044 +#define IDC_COMBO_HD_LOCATION 1045 +#define IDC_CHECKGUS 1046 +#define IDC_COMBO_HD_CHANNEL 1047 +#define IDC_COMBO_HD_CHANNEL_IDE 1048 +#define IDC_COMBO_HD_ID 1050 +#define IDC_COMBO_HD_LUN 1051 +#define IDC_CHECKBUGGER 1052 +#define IDC_CHECKSERIAL1 1053 +#define IDC_CHECKPARALLEL 1054 +#define IDC_CHECKSERIAL2 1055 +#define IDC_COMBO_HDC 1068 +#define IDC_COMBO_MOUSE 1069 +#define IDC_COMBO_IDE_TER 1069 +#define IDC_COMBO_IDE_QUA 1070 +#define IDC_COMBO_FD_TYPE 1071 +#define IDC_COMBO_CD_BUS 1072 +#define IDC_COMBO_CD_CHANNEL_IDE 1073 +#define IDC_COMBO_CD_ID 1074 +#define IDC_COMBO_CD_LUN 1075 +#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 +#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 +#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 +#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 +#define IDS_STRING2049 2049 +#define IDS_STRING2050 2050 +#define IDS_STRING2051 2051 +#define IDS_STRING2052 2052 +#define IDS_STRING2053 2053 +#define IDS_STRING2054 2054 +#define IDS_STRING2055 2055 +#define IDS_STRING2056 2056 +#define IDS_STRING2057 2057 +#define IDS_STRING2058 2058 +#define IDS_STRING2059 2059 +#define IDS_STRING2060 2060 +#define IDS_STRING2061 2061 +#define IDS_STRING2062 2062 +#define IDS_STRING2063 2063 +#define IDS_STRING2064 2064 +#define IDS_STRING2065 2065 +#define IDS_STRING2066 2066 +#define IDS_STRING2067 2067 +#define IDS_STRING2068 2068 +#define IDS_STRING2069 2069 +#define IDS_STRING2070 2070 +#define IDS_STRING2071 2071 +#define IDS_STRING2072 2072 +#define IDS_STRING2073 2073 +#define IDS_STRING2074 2074 +#define IDS_STRING2075 2075 +#define IDS_STRING2076 2076 +#define IDS_STRING2077 2077 +#define IDS_STRING2078 2078 +#define IDS_STRING2079 2079 +#define IDM_ABOUT 40001 +#define IDC_ABOUT_ICON 65535 + +#define IDM_DISC_1 40000 +#define IDM_DISC_2 40001 +#define IDM_DISC_3 40002 +#define IDM_DISC_4 40003 +#define IDM_DISC_1_WP 40004 +#define IDM_DISC_2_WP 40005 +#define IDM_DISC_3_WP 40006 +#define IDM_DISC_4_WP 40007 +#define IDM_EJECT_1 40008 +#define IDM_EJECT_2 40009 +#define IDM_EJECT_3 40010 +#define IDM_EJECT_4 40011 + +#define IDM_FILE_RESET 40015 +#define IDM_FILE_HRESET 40016 +#define IDM_FILE_EXIT 40017 +#define IDM_FILE_RESET_CAD 40018 +#define IDM_HDCONF 40019 +#define IDM_CONFIG 40020 +#define IDM_CONFIG_LOAD 40021 +#define IDM_CONFIG_SAVE 40022 +#define IDM_USE_NUKEDOPL 40023 +#define IDM_STATUS 40030 +#define IDM_VID_RESIZE 40050 +#define IDM_VID_REMEMBER 40051 +#define IDM_VID_DDRAW 40060 +#define IDM_VID_D3D 40061 +#define IDM_VID_SCALE_1X 40064 +#define IDM_VID_SCALE_2X 40065 +#define IDM_VID_SCALE_3X 40066 +#define IDM_VID_SCALE_4X 40067 +#define IDM_VID_FULLSCREEN 40070 +#define IDM_VID_FS_FULL 40071 +#define IDM_VID_FS_43 40072 +#define IDM_VID_FS_SQ 40073 +#define IDM_VID_FS_INT 40074 +#define IDM_VID_FORCE43 40075 +#define IDM_VID_OVERSCAN 40076 +#define IDM_VID_FLASH 40077 +#define IDM_VID_SCREENSHOT 40078 +#define IDM_VID_INVERT 40079 + +#define IDM_CDROM_1_MUTE 40128 +#define IDM_CDROM_1_ISO 40144 +#define IDM_CDROM_1_RELOAD 40160 +#define IDM_CDROM_1_EMPTY 40176 +#define IDM_CDROM_1_REAL 40192 +#define IDM_CDROM_2_MUTE 40129 +#define IDM_CDROM_2_ISO 40145 +#define IDM_CDROM_2_RELOAD 40161 +#define IDM_CDROM_2_EMPTY 40177 +#define IDM_CDROM_2_REAL 40193 +#define IDM_CDROM_3_MUTE 40130 +#define IDM_CDROM_3_ISO 40146 +#define IDM_CDROM_3_RELOAD 40162 +#define IDM_CDROM_3_EMPTY 40178 +#define IDM_CDROM_3_REAL 40194 +#define IDM_CDROM_4_MUTE 40131 +#define IDM_CDROM_4_ISO 40147 +#define IDM_CDROM_4_RELOAD 40163 +#define IDM_CDROM_4_EMPTY 40179 +#define IDM_CDROM_4_REAL 40195 + +#define IDM_IDE_TER_ENABLED 44000 +#define IDM_IDE_TER_IRQ9 44009 +#define IDM_IDE_TER_IRQ10 44010 +#define IDM_IDE_TER_IRQ11 44011 +#define IDM_IDE_TER_IRQ12 44012 +#define IDM_IDE_TER_IRQ14 44014 +#define IDM_IDE_TER_IRQ15 44015 +#define IDM_IDE_QUA_ENABLED 44020 +#define IDM_IDE_QUA_IRQ9 44029 +#define IDM_IDE_QUA_IRQ10 44030 +#define IDM_IDE_QUA_IRQ11 44031 +#define IDM_IDE_QUA_IRQ12 44032 +#define IDM_IDE_QUA_IRQ14 44033 +#define IDM_IDE_QUA_IRQ15 44035 + +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG +#define IDM_LOG_BUSLOGIC 51200 +#endif +#ifdef ENABLE_CDROM_LOG +#define IDM_LOG_CDROM 51201 +#endif +#ifdef ENABLE_D86F_LOG +#define IDM_LOG_D86F 51202 +#endif +#ifdef ENABLE_FDC_LOG +#define IDM_LOG_FDC 51203 +#endif +#ifdef ENABLE_IDE_LOG +#define IDM_LOG_IDE 51204 +#endif +#ifdef ENABLE_NE2000_LOG +#define IDM_LOG_NE2000 51205 +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT +#define IDM_LOG_BREAKPOINT 51206 +#endif + +#define IDC_COMBO1 1000 +#define IDC_COMBOVID 1001 +#define IDC_COMBO3 1002 +#define IDC_COMBO4 1003 +#define IDC_COMBO5 1004 +#define IDC_COMBO386 1005 +#define IDC_COMBO486 1006 +#define IDC_COMBOSND 1007 +#define IDC_COMBONET 1008 +#define IDC_COMBOCPUM 1060 +#define IDC_COMBOSPD 1061 +#define IDC_COMBODR1 1062 +#define IDC_COMBODR2 1063 +#define IDC_COMBODR3 1064 +#define IDC_COMBODR4 1065 +#define IDC_COMBOJOY 1066 +#define IDC_COMBOWS 1067 +#define IDC_COMBOMOUSE 1068 +#define IDC_COMBOHDD 1069 +#define IDC_CHECK1 1010 +#define IDC_CHECK2 1011 +#define IDC_CHECK3 1012 +#define IDC_CHECKSSI 1014 +#define IDC_CHECKVOODOO 1015 +#define IDC_CHECKDYNAREC 1016 +#define IDC_CHECKBUSLOGIC 1017 +#define IDC_CHECKSYNC 1024 +#define IDC_CHECKXTIDE 1025 +#define IDC_CHECKFPU 1026 +#define IDC_EDIT1 1030 +#define IDC_EDIT2 1031 +#define IDC_EDIT3 1032 +#define IDC_EDIT4 1033 +#define IDC_EDIT5 1034 +#define IDC_EDIT6 1035 +#define IDC_COMBOHDT 1036 + +#define IDC_EJECTC 1040 +#define IDC_EDITC 1050 +#define IDC_CFILE 1060 +#define IDC_CNEW 1070 +#define IDC_EDIT_C_SPT 1200 +#define IDC_EDIT_C_HPC 1210 +#define IDC_EDIT_C_CYL 1220 +#define IDC_EDIT_C_FN 1230 +#define IDC_TEXT_C_SIZE 1240 + +#define IDC_EJECTD 1041 +#define IDC_EDITD 1051 +#define IDC_DFILE 1061 +#define IDC_DNEW 1071 +#define IDC_EDIT_D_SPT 1201 +#define IDC_EDIT_D_HPC 1211 +#define IDC_EDIT_D_CYL 1221 +#define IDC_EDIT_D_FN 1231 +#define IDC_TEXT_D_SIZE 1241 + +#define IDC_EJECTE 1042 +#define IDC_EDITE 1052 +#define IDC_EFILE 1062 +#define IDC_ENEW 1072 +#define IDC_EDIT_E_SPT 1202 +#define IDC_EDIT_E_HPC 1212 +#define IDC_EDIT_E_CYL 1222 +#define IDC_EDIT_E_FN 1232 +#define IDC_TEXT_E_SIZE 1242 + +#define IDC_EJECTF 1043 +#define IDC_EDITF 1053 +#define IDC_FFILE 1063 +#define IDC_FNEW 1073 +#define IDC_EDIT_F_SPT 1203 +#define IDC_EDIT_F_HPC 1213 +#define IDC_EDIT_F_CYL 1223 +#define IDC_EDIT_F_FN 1233 +#define IDC_TEXT_F_SIZE 1243 + +#define IDC_EJECTG 1044 +#define IDC_EDITG 1054 +#define IDC_GFILE 1064 +#define IDC_GNEW 1074 +#define IDC_EDIT_G_SPT 1204 +#define IDC_EDIT_G_HPC 1214 +#define IDC_EDIT_G_CYL 1224 +#define IDC_EDIT_G_FN 1234 +#define IDC_TEXT_G_SIZE 1244 + +#define IDC_EJECTH 1045 +#define IDC_EDITH 1055 +#define IDC_HFILE 1065 +#define IDC_HNEW 1075 +#define IDC_EDIT_H_SPT 1205 +#define IDC_EDIT_H_HPC 1215 +#define IDC_EDIT_H_CYL 1225 +#define IDC_EDIT_H_FN 1235 +#define IDC_TEXT_H_SIZE 1245 + +#define IDC_EJECTI 1046 +#define IDC_EDITI 1056 +#define IDC_IFILE 1066 +#define IDC_INEW 1076 +#define IDC_EDIT_I_SPT 1206 +#define IDC_EDIT_I_HPC 1216 +#define IDC_EDIT_I_CYL 1226 +#define IDC_EDIT_I_FN 1236 +#define IDC_TEXT_I_SIZE 1246 + +#define IDC_EJECTJ 1047 +#define IDC_EDITJ 1057 +#define IDC_JFILE 1067 +#define IDC_JNEW 1077 +#define IDC_EDIT_J_SPT 1207 +#define IDC_EDIT_J_HPC 1217 +#define IDC_EDIT_J_CYL 1227 +#define IDC_EDIT_J_FN 1237 +#define IDC_TEXT_J_SIZE 1247 + +#define IDC_HDTYPE 1280 + +#define IDC_RENDER 1281 +#define IDC_STATUS 1282 + +#define IDC_MEMSPIN 1100 +#define IDC_MEMTEXT 1101 +#define IDC_STEXT1 1102 +#define IDC_STEXT2 1103 +#define IDC_STEXT3 1104 +#define IDC_STEXT4 1105 +#define IDC_STEXT5 1106 +#define IDC_STEXT6 1107 +#define IDC_STEXT7 1108 +#define IDC_STEXT8 1109 +#define IDC_STEXT_DEVICE 1110 +#define IDC_TEXT_MB 1111 +#define IDC_TEXT1 1115 +#define IDC_TEXT2 1116 + +#define IDC_CONFIGUREVID 1200 +#define IDC_CONFIGURESND 1201 +#define IDC_CONFIGUREVOODOO 1202 +#define IDC_CONFIGUREMOD 1203 +#define IDC_CONFIGURENET 1204 +#define IDC_CONFIGUREBUSLOGIC 1205 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 + +#define IDC_CONFIG_BASE 1200 + +#define WM_RESETD3D WM_USER +#define WM_LEAVEFULLSCREEN WM_USER + 1 + +#define C_BASE 6 +#define D_BASE 44 +#define E_BASE 82 +#define F_BASE 120 +#define G_BASE 158 +#define H_BASE 196 +#define I_BASE 234 +#define J_BASE 272 +#define CMD_BASE 314 +#define DLG_HEIGHT 346 + +#define IDC_CHECK_CDROM_1_ENABLED 1536 +#define IDC_COMBO_CDROM_1_BUS 1544 +#define IDC_COMBO_CDROM_1_CHANNEL 1552 +#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 +#define IDC_COMBO_CDROM_1_SCSI_ID 1568 +#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 + +#define IDC_CHECK_CDROM_2_ENABLED 1537 +#define IDC_COMBO_CDROM_2_BUS 1545 +#define IDC_COMBO_CDROM_2_CHANNEL 1553 +#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 +#define IDC_COMBO_CDROM_2_SCSI_ID 1569 +#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 + +#define IDC_CHECK_CDROM_3_ENABLED 1538 +#define IDC_COMBO_CDROM_3_BUS 1546 +#define IDC_COMBO_CDROM_3_CHANNEL 1554 +#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 +#define IDC_COMBO_CDROM_3_SCSI_ID 1570 +#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 + +#define IDC_CHECK_CDROM_4_ENABLED 1539 +#define IDC_COMBO_CDROM_4_BUS 1547 +#define IDC_COMBO_CDROM_4_CHANNEL 1555 +#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 +#define IDC_COMBO_CDROM_4_SCSI_ID 1571 +#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 + +#define IDC_STATIC 1792 + +/* Next default values for new objects */ + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 110 +#define _APS_NEXT_COMMAND_VALUE 40002 +#define _APS_NEXT_CONTROL_VALUE 1055 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/resources.h b/src/resources.h deleted file mode 100644 index 4df7017c2..000000000 --- a/src/resources.h +++ /dev/null @@ -1,399 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define IDM_FILE_RESET 40000 -#define IDM_FILE_HRESET 40001 -#define IDM_FILE_EXIT 40002 -#define IDM_FILE_RESET_CAD 40003 -#define IDM_DISC_1 40010 -#define IDM_DISC_2 40011 -#define IDM_EJECT_1 40012 -#define IDM_EJECT_2 40013 -#define IDM_HDCONF 40014 -#define IDM_DISC_1_WP 40015 -#define IDM_DISC_2_WP 40016 -#define IDM_CONFIG 40020 -#define IDM_CONFIG_LOAD 40021 -#define IDM_CONFIG_SAVE 40022 -#define IDM_USE_NUKEDOPL 40023 -#define IDM_STATUS 40030 -#define IDM_VID_RESIZE 40050 -#define IDM_VID_REMEMBER 40051 -#define IDM_VID_DDRAW 40060 -#define IDM_VID_D3D 40061 -#define IDM_VID_SCALE_1X 40064 -#define IDM_VID_SCALE_2X 40065 -#define IDM_VID_SCALE_3X 40066 -#define IDM_VID_SCALE_4X 40067 -#define IDM_VID_FULLSCREEN 40070 -#define IDM_VID_FS_FULL 40071 -#define IDM_VID_FS_43 40072 -#define IDM_VID_FS_SQ 40073 -#define IDM_VID_FS_INT 40074 -#define IDM_VID_FORCE43 40075 -#define IDM_VID_OVERSCAN 40076 -#define IDM_VID_FLASH 40077 -#define IDM_VID_SCREENSHOT 40078 -#define IDM_VID_INVERT 40079 -#define IDM_DISC_3 40081 -#define IDM_DISC_4 40082 -#define IDM_EJECT_3 40083 -#define IDM_EJECT_4 40084 -#define IDM_DISC_3_WP 40085 -#define IDM_DISC_4_WP 40086 -#define IDM_CDROM_1_ISO 40100 -#define IDM_CDROM_1_RELOAD 40101 -#define IDM_CDROM_1_EMPTY 40200 -#define IDM_CDROM_1_REAL 40200 -#define IDM_CDROM_1_ENABLED 40300 -#define IDM_CDROM_1_SOUND_ON 40400 -#define IDM_CDROM_1_SCSI 40500 -#define IDM_CDROM_1_DMA 40501 -#define IDM_CDROM_1_C 40600 -#define IDM_CDROM_1_D 40601 -#define IDM_CDROM_1_E 40602 -#define IDM_CDROM_1_F 40603 -#define IDM_CDROM_1_G 40604 -#define IDM_CDROM_1_H 40605 -#define IDM_CDROM_1_I 40606 -#define IDM_CDROM_1_J 40607 -#define IDM_CDROM_1_0 40700 -#define IDM_CDROM_1_1 40701 -#define IDM_CDROM_1_2 40702 -#define IDM_CDROM_1_3 40703 -#define IDM_CDROM_1_4 40704 -#define IDM_CDROM_1_5 40705 -#define IDM_CDROM_1_6 40706 -#define IDM_CDROM_1_8 40708 -#define IDM_CDROM_1_9 40709 -#define IDM_CDROM_1_10 40710 -#define IDM_CDROM_1_11 40711 -#define IDM_CDROM_1_12 40712 -#define IDM_CDROM_1_13 40713 -#define IDM_CDROM_1_14 40714 -#define IDM_CDROM_1_15 40715 -#define IDM_CDROM_1_LUN_0 40800 -#define IDM_CDROM_1_LUN_1 40801 -#define IDM_CDROM_1_LUN_2 40802 -#define IDM_CDROM_1_LUN_3 40803 -#define IDM_CDROM_1_LUN_4 40804 -#define IDM_CDROM_1_LUN_5 40805 -#define IDM_CDROM_1_LUN_6 40806 -#define IDM_CDROM_1_LUN_7 40807 -#define IDM_CDROM_2_ISO 41100 -#define IDM_CDROM_2_RELOAD 41101 -#define IDM_CDROM_2_EMPTY 41200 -#define IDM_CDROM_2_REAL 41200 -#define IDM_CDROM_2_ENABLED 41300 -#define IDM_CDROM_2_SOUND_ON 41400 -#define IDM_CDROM_2_SCSI 41500 -#define IDM_CDROM_2_DMA 41501 -#define IDM_CDROM_2_C 41600 -#define IDM_CDROM_2_D 41601 -#define IDM_CDROM_2_E 41602 -#define IDM_CDROM_2_F 41603 -#define IDM_CDROM_2_G 41604 -#define IDM_CDROM_2_H 41605 -#define IDM_CDROM_2_I 41606 -#define IDM_CDROM_2_J 41607 -#define IDM_CDROM_2_0 41700 -#define IDM_CDROM_2_1 41701 -#define IDM_CDROM_2_2 41702 -#define IDM_CDROM_2_3 41703 -#define IDM_CDROM_2_4 41704 -#define IDM_CDROM_2_5 41705 -#define IDM_CDROM_2_6 41706 -#define IDM_CDROM_2_8 41708 -#define IDM_CDROM_2_9 41709 -#define IDM_CDROM_2_10 41710 -#define IDM_CDROM_2_11 41711 -#define IDM_CDROM_2_12 41712 -#define IDM_CDROM_2_13 41713 -#define IDM_CDROM_2_14 41714 -#define IDM_CDROM_2_15 41715 -#define IDM_CDROM_2_LUN_0 41800 -#define IDM_CDROM_2_LUN_1 41801 -#define IDM_CDROM_2_LUN_2 41802 -#define IDM_CDROM_2_LUN_3 41803 -#define IDM_CDROM_2_LUN_4 41804 -#define IDM_CDROM_2_LUN_5 41805 -#define IDM_CDROM_2_LUN_6 41806 -#define IDM_CDROM_2_LUN_7 41807 -#define IDM_CDROM_3_ISO 42100 -#define IDM_CDROM_3_RELOAD 42101 -#define IDM_CDROM_3_EMPTY 42200 -#define IDM_CDROM_3_REAL 42200 -#define IDM_CDROM_3_ENABLED 42300 -#define IDM_CDROM_3_SOUND_ON 42400 -#define IDM_CDROM_3_SCSI 42500 -#define IDM_CDROM_3_DMA 42501 -#define IDM_CDROM_3_C 42600 -#define IDM_CDROM_3_D 42601 -#define IDM_CDROM_3_E 42602 -#define IDM_CDROM_3_F 42603 -#define IDM_CDROM_3_G 42604 -#define IDM_CDROM_3_H 42605 -#define IDM_CDROM_3_I 42606 -#define IDM_CDROM_3_J 42607 -#define IDM_CDROM_3_0 42700 -#define IDM_CDROM_3_1 42701 -#define IDM_CDROM_3_2 42702 -#define IDM_CDROM_3_3 42703 -#define IDM_CDROM_3_4 42704 -#define IDM_CDROM_3_5 42705 -#define IDM_CDROM_3_6 42706 -#define IDM_CDROM_3_8 42708 -#define IDM_CDROM_3_9 42709 -#define IDM_CDROM_3_10 42710 -#define IDM_CDROM_3_11 42711 -#define IDM_CDROM_3_12 42712 -#define IDM_CDROM_3_13 42713 -#define IDM_CDROM_3_14 42714 -#define IDM_CDROM_3_15 42715 -#define IDM_CDROM_3_LUN_0 42800 -#define IDM_CDROM_3_LUN_1 42801 -#define IDM_CDROM_3_LUN_2 42802 -#define IDM_CDROM_3_LUN_3 42803 -#define IDM_CDROM_3_LUN_4 42804 -#define IDM_CDROM_3_LUN_5 42805 -#define IDM_CDROM_3_LUN_6 42806 -#define IDM_CDROM_3_LUN_7 42807 -#define IDM_CDROM_4_ISO 43100 -#define IDM_CDROM_4_RELOAD 43101 -#define IDM_CDROM_4_EMPTY 43200 -#define IDM_CDROM_4_REAL 43200 -#define IDM_CDROM_4_ENABLED 43300 -#define IDM_CDROM_4_SOUND_ON 43400 -#define IDM_CDROM_4_SCSI 43500 -#define IDM_CDROM_4_DMA 43501 -#define IDM_CDROM_4_C 43600 -#define IDM_CDROM_4_D 43601 -#define IDM_CDROM_4_E 43602 -#define IDM_CDROM_4_F 43603 -#define IDM_CDROM_4_G 43604 -#define IDM_CDROM_4_H 43605 -#define IDM_CDROM_4_I 43606 -#define IDM_CDROM_4_J 43607 -#define IDM_CDROM_4_0 43700 -#define IDM_CDROM_4_1 43701 -#define IDM_CDROM_4_2 43702 -#define IDM_CDROM_4_3 43703 -#define IDM_CDROM_4_4 43704 -#define IDM_CDROM_4_5 43705 -#define IDM_CDROM_4_6 43706 -#define IDM_CDROM_4_8 43708 -#define IDM_CDROM_4_9 43709 -#define IDM_CDROM_4_10 43710 -#define IDM_CDROM_4_11 43711 -#define IDM_CDROM_4_12 43712 -#define IDM_CDROM_4_13 43713 -#define IDM_CDROM_4_14 43714 -#define IDM_CDROM_4_15 43715 -#define IDM_CDROM_4_LUN_0 43800 -#define IDM_CDROM_4_LUN_1 43801 -#define IDM_CDROM_4_LUN_2 43802 -#define IDM_CDROM_4_LUN_3 43803 -#define IDM_CDROM_4_LUN_4 43804 -#define IDM_CDROM_4_LUN_5 43805 -#define IDM_CDROM_4_LUN_6 43806 -#define IDM_CDROM_4_LUN_7 43807 -#define IDM_IDE_TER_ENABLED 44000 -#define IDM_IDE_TER_IRQ9 44009 -#define IDM_IDE_TER_IRQ10 44010 -#define IDM_IDE_TER_IRQ11 44011 -#define IDM_IDE_TER_IRQ12 44012 -#define IDM_IDE_TER_IRQ14 44014 -#define IDM_IDE_TER_IRQ15 44015 -#define IDM_IDE_QUA_ENABLED 44020 -#define IDM_IDE_QUA_IRQ9 44029 -#define IDM_IDE_QUA_IRQ10 44030 -#define IDM_IDE_QUA_IRQ11 44031 -#define IDM_IDE_QUA_IRQ12 44032 -#define IDM_IDE_QUA_IRQ14 44033 -#define IDM_IDE_QUA_IRQ15 44035 -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG -#define IDM_LOG_BUSLOGIC 51200 -#endif -#ifdef ENABLE_CDROM_LOG -#define IDM_LOG_CDROM 51201 -#endif -#ifdef ENABLE_D86F_LOG -#define IDM_LOG_D86F 51202 -#endif -#ifdef ENABLE_FDC_LOG -#define IDM_LOG_FDC 51203 -#endif -#ifdef ENABLE_IDE_LOG -#define IDM_LOG_IDE 51204 -#endif -#ifdef ENABLE_NE2000_LOG -#define IDM_LOG_NE2000 51205 -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT -#define IDM_LOG_BREAKPOINT 51206 -#endif - -#define IDC_COMBO1 1000 -#define IDC_COMBOVID 1001 -#define IDC_COMBO3 1002 -#define IDC_COMBO4 1003 -#define IDC_COMBO5 1004 -#define IDC_COMBO386 1005 -#define IDC_COMBO486 1006 -#define IDC_COMBOSND 1007 -#define IDC_COMBONET 1008 -#define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODR1 1062 -#define IDC_COMBODR2 1063 -#define IDC_COMBOJOY 1064 -#define IDC_COMBOWS 1065 -#define IDC_COMBOMOUSE 1066 -#define IDC_COMBOHDD 1067 -#define IDC_COMBODR3 1068 -#define IDC_COMBODR4 1069 -#define IDC_CHECK1 1010 -#define IDC_CHECK2 1011 -#define IDC_CHECK3 1012 -#define IDC_CHECKGUS 1013 -#define IDC_CHECKSSI 1014 -#define IDC_CHECKVOODOO 1015 -#define IDC_CHECKDYNAREC 1016 -#define IDC_CHECKBUSLOGIC 1017 -#define IDC_STATIC 1020 -#define IDC_CHECKSYNC 1024 -#define IDC_CHECKXTIDE 1025 -#define IDC_CHECKFPU 1026 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_COMBOHDT 1036 - -#define IDC_EJECTC 1040 -#define IDC_EDITC 1050 -#define IDC_CFILE 1060 -#define IDC_CNEW 1070 -#define IDC_EDIT_C_SPT 1200 -#define IDC_EDIT_C_HPC 1210 -#define IDC_EDIT_C_CYL 1220 -#define IDC_EDIT_C_FN 1230 -#define IDC_TEXT_C_SIZE 1240 - -#define IDC_EJECTD 1041 -#define IDC_EDITD 1051 -#define IDC_DFILE 1061 -#define IDC_DNEW 1071 -#define IDC_EDIT_D_SPT 1201 -#define IDC_EDIT_D_HPC 1211 -#define IDC_EDIT_D_CYL 1221 -#define IDC_EDIT_D_FN 1231 -#define IDC_TEXT_D_SIZE 1241 - -#define IDC_EJECTE 1042 -#define IDC_EDITE 1052 -#define IDC_EFILE 1062 -#define IDC_ENEW 1072 -#define IDC_EDIT_E_SPT 1202 -#define IDC_EDIT_E_HPC 1212 -#define IDC_EDIT_E_CYL 1222 -#define IDC_EDIT_E_FN 1232 -#define IDC_TEXT_E_SIZE 1242 - -#define IDC_EJECTF 1043 -#define IDC_EDITF 1053 -#define IDC_FFILE 1063 -#define IDC_FNEW 1073 -#define IDC_EDIT_F_SPT 1203 -#define IDC_EDIT_F_HPC 1213 -#define IDC_EDIT_F_CYL 1223 -#define IDC_EDIT_F_FN 1233 -#define IDC_TEXT_F_SIZE 1243 - -#define IDC_EJECTG 1044 -#define IDC_EDITG 1054 -#define IDC_GFILE 1064 -#define IDC_GNEW 1074 -#define IDC_EDIT_G_SPT 1204 -#define IDC_EDIT_G_HPC 1214 -#define IDC_EDIT_G_CYL 1224 -#define IDC_EDIT_G_FN 1234 -#define IDC_TEXT_G_SIZE 1244 - -#define IDC_EJECTH 1045 -#define IDC_EDITH 1055 -#define IDC_HFILE 1065 -#define IDC_HNEW 1075 -#define IDC_EDIT_H_SPT 1205 -#define IDC_EDIT_H_HPC 1215 -#define IDC_EDIT_H_CYL 1225 -#define IDC_EDIT_H_FN 1235 -#define IDC_TEXT_H_SIZE 1245 - -#define IDC_EJECTI 1046 -#define IDC_EDITI 1056 -#define IDC_IFILE 1066 -#define IDC_INEW 1076 -#define IDC_EDIT_I_SPT 1206 -#define IDC_EDIT_I_HPC 1216 -#define IDC_EDIT_I_CYL 1226 -#define IDC_EDIT_I_FN 1236 -#define IDC_TEXT_I_SIZE 1246 - -#define IDC_EJECTJ 1047 -#define IDC_EDITJ 1057 -#define IDC_JFILE 1067 -#define IDC_JNEW 1077 -#define IDC_EDIT_J_SPT 1207 -#define IDC_EDIT_J_HPC 1217 -#define IDC_EDIT_J_CYL 1227 -#define IDC_EDIT_J_FN 1237 -#define IDC_TEXT_J_SIZE 1247 - -#define IDC_HDTYPE 1280 - -#define IDC_MEMSPIN 1100 -#define IDC_MEMTEXT 1101 -#define IDC_STEXT1 1102 -#define IDC_STEXT2 1103 -#define IDC_STEXT3 1104 -#define IDC_STEXT4 1105 -#define IDC_STEXT5 1106 -#define IDC_STEXT6 1107 -#define IDC_STEXT7 1108 -#define IDC_STEXT8 1109 -#define IDC_STEXT_DEVICE 1110 -#define IDC_TEXT_MB 1111 -#define IDC_TEXT1 1115 -#define IDC_TEXT2 1116 - -#define IDC_CONFIGUREVID 1200 -#define IDC_CONFIGURESND 1201 -#define IDC_CONFIGUREVOODOO 1202 -#define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENET 1204 -#define IDC_CONFIGUREBUSLOGIC 1205 -#define IDC_JOY1 1210 -#define IDC_JOY2 1211 -#define IDC_JOY3 1212 -#define IDC_JOY4 1213 - -#define IDC_CONFIG_BASE 1200 - -#define WM_RESETD3D WM_USER -#define WM_LEAVEFULLSCREEN WM_USER + 1 - -#define C_BASE 6 -#define D_BASE 44 -#define E_BASE 82 -#define F_BASE 120 -#define G_BASE 158 -#define H_BASE 196 -#define I_BASE 234 -#define J_BASE 272 -#define CMD_BASE 314 -#define DLG_HEIGHT 346 diff --git a/src/rom.c b/src/rom.c index 66549ad79..60475aac8 100644 --- a/src/rom.c +++ b/src/rom.c @@ -3,10 +3,12 @@ */ #include #include +#include "config.h" #include "ibm.h" #include "mem.h" #include "rom.h" + FILE *romfopen(char *fn, char *mode) { char s[512]; @@ -16,6 +18,7 @@ FILE *romfopen(char *fn, char *mode) return fopen(s, mode); } + int rom_present(char *fn) { FILE *f; @@ -33,25 +36,40 @@ int rom_present(char *fn) return 0; } + static uint8_t rom_read(uint32_t addr, void *p) { rom_t *rom = (rom_t *)p; -// pclog("rom_read : %08x %08x %02x\n", addr, rom->mask, rom->rom[addr & rom->mask]); +#ifdef ROM_TRACE + if (rom->mapping.base==ROM_TRACE) + pclog("ROM: read byte from BIOS at %06lX\n", addr); +#endif return rom->rom[addr & rom->mask]; } + + uint16_t rom_readw(uint32_t addr, void *p) { rom_t *rom = (rom_t *)p; -// pclog("rom_readw: %08x %08x %04x\n", addr, rom->mask, *(uint16_t *)&rom->rom[addr & rom->mask]); +#ifdef ROM_TRACE + if (rom->mapping.base==ROM_TRACE) + pclog("ROM: read word from BIOS at %06lX\n", addr); +#endif return *(uint16_t *)&rom->rom[addr & rom->mask]; } + + uint32_t rom_readl(uint32_t addr, void *p) { rom_t *rom = (rom_t *)p; -// pclog("rom_readl: %08x %08x %08x\n", addr, rom->mask, *(uint32_t *)&rom->rom[addr & rom->mask]); +#ifdef ROM_TRACE + if (rom->mapping.base==ROM_TRACE) + pclog("ROM: read long from BIOS at %06lX\n", addr); +#endif return *(uint32_t *)&rom->rom[addr & rom->mask]; } + int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { FILE *f = romfopen(fn, "rb"); @@ -82,6 +100,7 @@ int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int fil return 0; } + int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { FILE *f_low = romfopen(fn_low, "rb"); diff --git a/src/rtc.c b/src/rtc.c index eba9bfd53..323a36c6c 100644 --- a/src/rtc.c +++ b/src/rtc.c @@ -26,9 +26,6 @@ struct int year; } internal_clock; -/* When the RTC was last updated */ -static time_t rtc_set_time = 0; - /* Table for days in each month */ static int rtc_days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; @@ -45,7 +42,7 @@ static int rtc_is_leap(int org_year) static int rtc_get_days(int org_month, int org_year) { if (org_month != 2) - return rtc_days_in_month[org_month]; + return rtc_days_in_month[org_month - 1]; else return rtc_is_leap(org_year) ? 29 : 28; } diff --git a/src/rtc.h b/src/rtc.h index a287e389f..78718143b 100644 --- a/src/rtc.h +++ b/src/rtc.h @@ -24,7 +24,7 @@ enum RTC_ADDR #define RTC_CENTURY 0x32 /* When the 12-hour format is selected, the higher-order bit of the hours byte represents PM when it is logic 1. */ -#define RTC_AMPM 0b10000000 +#define RTC_AMPM 0x80 /* Register A bitflags */ enum RTC_RA_BITS @@ -41,14 +41,14 @@ enum RTC_RA_BITS Table 3 lists the periodic interrupt rates and the square wave frequencies that can be chosen with the RS bits. These four read/write bits are not affected by !RESET. */ - RTC_RS = 0b1111, + RTC_RS = 0xF, /* DV0 These three bits are used to turn the oscillator on or off and to reset the countdown chain. A pattern of 010 is the only combination of bits that turn the oscillator on and allow the RTC to keep time. A pattern of 11x enables the oscillator but holds the countdown chain in reset. The next update occurs at 500ms after a pattern of 010 is written to DV0, DV1, and DV2. */ - RTC_DV0 = 0b1110000, + RTC_DV0 = 0x70, /* Update-In-Progress (UIP) This bit is a status flag that can be monitored. When the UIP bit is a 1, the update transfer occurs soon. @@ -56,7 +56,7 @@ enum RTC_RA_BITS The time, calendar, and alarm information in RAM is fully available for access when the UIP bit is 0. The UIP bit is read-only and is not affected by !RESET. Writing the SET bit in Register B to a 1 inhibits any update transfer and clears the UIP status bit. */ - RTC_UIP = 0b10000000 + RTC_UIP = 0x80 }; /* Register B bitflags */ @@ -70,51 +70,51 @@ enum RTC_RB_BITS When DSE is enabled, the internal logic test for the first/last Sunday condition at midnight. If the DSE bit is not set when the test occurs, the daylight saving function does not operate correctly. These adjustments do not occur when the DSE bit is 0. This bit is not affected by internal functions or !RESET. */ - RTC_DSE = 0b1, + RTC_DSE = 0x1, /* 24/12 The 24/12 control bit establishes the format of the hours byte. A 1 indicates the 24-hour mode and a 0 indicates the 12-hour mode. This bit is read/write and is not affected by internal functions or !RESET. */ - RTC_2412 = 0b10, + RTC_2412 = 0x2, /* Data Mode (DM) This bit indicates whether time and calendar information is in binary or BCD format. The DM bit is set by the program to the appropriate format and can be read as required. This bit is not modified by internal functions or !RESET. A 1 in DM signifies binary data, while a 0 in DM specifies BCD data. */ - RTC_DM = 0b100, + RTC_DM = 0x4, /* Square-Wave Enable (SQWE) When this bit is set to 1, a square-wave signal at the frequency set by the rate-selection bits RS3-RS0 is driven out on the SQW pin. When the SQWE bit is set to 0, the SQW pin is held low. SQWE is a read/write bit and is cleared by !RESET. SQWE is low if disabled, and is high impedance when VCC is below VPF. SQWE is cleared to 0 on !RESET. */ - RTC_SQWE = 0b1000, + RTC_SQWE = 0x8, /* Update-Ended Interrupt Enable (UIE) This bit is a read/write bit that enables the update-end flag (UF) bit in Register C to assert !IRQ. The !RESET pin going low or the SET bit going high clears the UIE bit. The internal functions of the device do not affect the UIE bit, but is cleared to 0 on !RESET. */ - RTC_UIE = 0b10000, + RTC_UIE = 0x10, /* Alarm Interrupt Enable (AIE) This bit is a read/write bit that, when set to 1, permits the alarm flag (AF) bit in Register C to assert !IRQ. An alarm interrupt occurs for each second that the three time bytes equal the three alarm bytes, including a don't-care alarm code of binary 11XXXXXX. The AF bit does not initiate the !IRQ signal when the AIE bit is set to 0. The internal functions of the device do not affect the AIE bit, but is cleared to 0 on !RESET. */ - RTC_AIE = 0b100000, + RTC_AIE = 0x20, /* Periodic Interrupt Enable (PIE) The PIE bit is a read/write bit that allows the periodic interrupt flag (PF) bit in Register C to drive the !IRQ pin low. When the PIE bit is set to 1, periodic interrupts are generated by driving the !IRQ pin low at a rate specified by the RS3-RS0 bits of Register A. A 0 in the PIE bit blocks the !IRQ output from being driven by a periodic interrupt, but the PF bit is still set at the periodic rate. PIE is not modified by any internal device functions, but is cleared to 0 on !RESET. */ - RTC_PIE = 0b1000000, + RTC_PIE = 0x40, /* SET When the SET bit is 0, the update transfer functions normally by advancing the counts once per second. When the SET bit is written to 1, any update transfer is inhibited, and the program can initialize the time and calendar bytes without an update occurring in the midst of initializing. Read cycles can be executed in a similar manner. SET is a read/write bit and is not affected by !RESET or internal functions of the device. */ - RTC_SET = 0b10000000 + RTC_SET = 0x80 }; /* Register C bitflags */ @@ -123,23 +123,23 @@ enum RTC_RC_BITS /* Unused These bits are unused in Register C. These bits always read 0 and cannot be written. */ - RTC_RC = 0b1111, + RTC_RC = 0xF, /* Update-Ended Interrupt Flag (UF) This bit is set after each update cycle. When the UIE bit is set to 1, the 1 in UF causes the IRQF bit to be a 1, which asserts the !IRQ pin. This bit can be cleared by reading Register C or with a !RESET. */ - RTC_UF = 0b10000, + RTC_UF = 0x10, /* Alarm Interrupt Flag (AF) A 1 in the AF bit indicates that the current time has matched the alarm time. If the AIE bit is also 1, the !IRQ pin goes low and a 1 appears in the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */ - RTC_AF = 0b100000, + RTC_AF = 0x20, /* Periodic Interrupt Flag (PF) This bit is read-only and is set to 1 when an edge is detected on the selected tap of the divider chain. The RS3 through RS0 bits establish the periodic rate. PF is set to 1 independent of the state of the PIE bit. When both PF and PIE are 1s, the !IRQ signal is active and sets the IRQF bit. This bit can be cleared by reading Register C or with a !RESET. */ - RTC_PF = 0b1000000, + RTC_PF = 0x40, /* Interrupt Request Flag (IRQF) The interrupt request flag (IRQF) is set to a 1 when one or more of the following are true: @@ -149,7 +149,7 @@ enum RTC_RC_BITS Any time the IRQF bit is a 1, the !IRQ pin is driven low. All flag bits are cleared after Register C is read by the program or when the !RESET pin is low. */ - RTC_IRQF = 0b10000000 + RTC_IRQF = 0x80 }; /* Register D bitflags */ @@ -158,13 +158,13 @@ enum RTC_RD_BITS /* Unused The remaining bits of Register D are not usable. They cannot be written and they always read 0. */ - RTC_RD = 0b1111111, + RTC_RD = 0x7F, /* Valid RAM and Time (VRT) This bit indicates the condition of the battery connected to the VBAT pin. This bit is not writeable and should always be 1 when read. If a 0 is ever present, an exhausted internal lithium energy source is indicated and both the contents of the RTC data and RAM data are questionable. This bit is unaffected by !RESET. */ - RTC_VRT = 0b10000000 + RTC_VRT = 0x80 }; void rtc_tick(); diff --git a/src/scat.c b/src/scat.c index fad281b65..4759d0270 100644 --- a/src/scat.c +++ b/src/scat.c @@ -11,7 +11,6 @@ static uint8_t scat_regs[256]; static int scat_index; static uint8_t scat_port_92 = 0; static uint8_t scat_ems_reg_2xA = 0; -static mem_mapping_t scat_mapping[32]; static mem_mapping_t scat_high_mapping[16]; static scat_t scat_stat[32]; static uint32_t scat_xms_bound; @@ -20,7 +19,7 @@ static mem_mapping_t scat_512k_clip_mapping; void scat_shadow_state_update() { - int i, val, val2; + int i, val; for (i = 0; i < 24; i++) { @@ -48,8 +47,8 @@ void scat_shadow_state_update() { val |= ((scat_regs[SCAT_SHADOW_RAM_ENABLE_1 + (i >> 3)] >> (i & 7)) & 1) ? MEM_WRITE_INTERNAL : MEM_WRITE_EXTERNAL; } - mem_set_mem_state((i + 40) << 14, 0x4000, val); } + mem_set_mem_state((i + 40) << 14, 0x4000, val); } flushmmucache(); @@ -131,7 +130,6 @@ void scat_set_xms_bound(uint8_t val) uint32_t get_scat_addr(uint32_t addr, scat_t *p) { - uint32_t addr2 = addr; if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) { addr = (addr & 0x3fff) | (((p->regs_2x9 & 3) << 8) | p->regs_2x8) << 14; @@ -164,7 +162,7 @@ void scat_write(uint16_t port, uint8_t val, void *priv) scat_reg_valid = 1; break; case SCAT_POWER_MANAGEMENT: - val &= 0x40; // TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. + val &= 0x40; /* TODO - Only use AUX parity disable bit for this version. Other bits should be implemented later. */ scat_reg_valid = 1; break; case SCAT_DRAM_CONFIGURATION: @@ -345,7 +343,7 @@ uint8_t scat_read(uint16_t port, void *priv) switch (scat_index) { case SCAT_MISCELLANEOUS_STATUS: - val = (scat_regs[scat_index] & 0xbf) | ((scat_port_92 & 2) << 5); + val = (scat_regs[scat_index] & 0xbf) | ((mem_a20_key & 2) << 5); break; default: val = scat_regs[scat_index]; @@ -508,7 +506,7 @@ void scat_init() scat_stat[i].regs_2x9 = 0x03; } - // TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later. + /* TODO - Only normal CPU accessing address FF0000 to FFFFFF mapped to ROM. Normal CPU accessing address FC0000 to FEFFFF map to ROM should be implemented later. */ for (i = 12; i < 16; i++) { mem_mapping_add(&scat_high_mapping[i], (i << 14) + 0xFC0000, 0x04000, mem_read_bios, mem_read_biosw, mem_read_biosl, mem_write_null, mem_write_nullw, mem_write_nulll, rom + (i << 14), 0, NULL); @@ -519,11 +517,11 @@ void scat_init() mem_mapping_add(&scat_shadowram_mapping, 0x100000, 0x60000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); } - // Need to RAM 512kb clipping emulation if only 256KB or 64KB modules installed in memory bank. - // TODO - 512KB clipping should be applied all RAM refer. + /* Need to RAM 512kb clipping emulation if only 256KB or 64KB modules installed in memory bank. + TODO - 512KB clipping should be applied all RAM refer. */ mem_mapping_add(&scat_512k_clip_mapping, 0x80000, 0x20000, mem_read_scatems, mem_read_scatemsw, mem_read_scatemsl, mem_write_scatems, mem_write_scatemsw, mem_write_scatemsl, ram, MEM_MAPPING_INTERNAL, NULL); mem_mapping_disable(&scat_512k_clip_mapping); - // --- + /* --- */ scat_set_xms_bound(0); scat_shadow_state_update(); diff --git a/src/scsi.c b/src/scsi.c index 6a3c5746e..3dbefdf37 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -7,23 +7,108 @@ #include "86box.h" #include "ibm.h" #include "device.h" - #include "cdrom.h" #include "scsi.h" - #include "timer.h" +#include "scsi_buslogic.h" -uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; -uint8_t SCSIStatus = SCSI_STATUS_OK; -uint8_t scsi_cdrom_id = 3; /*common setting*/ +uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; +uint8_t SCSIStatus = SCSI_STATUS_OK; +uint8_t scsi_cdrom_id = 3; /*common setting*/ +char scsi_fn[SCSI_NUM][512]; +uint16_t scsi_hd_location[SCSI_NUM]; -//Initialization function for the SCSI layer +int scsi_card_current = 0; +int scsi_card_last = 0; + + +typedef struct { + char name[64]; + char internal_name[32]; + device_t *device; +} SCSI_CARD; + + +static SCSI_CARD scsi_cards[] = { + { "None", "none", NULL }, + { "Adaptec AHA-1540B", "aha1540b", &aha1540b_device }, + { "Adaptec AHA-1542CF", "aha1542cf", &aha1542cf_device }, + { "BusLogic BT-542B", "bt542b", &buslogic_device }, + { "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device }, + { "", "", NULL } +}; + + +int scsi_card_available(int card) +{ + if (scsi_cards[card].device) + return(device_available(scsi_cards[card].device)); + + return(1); +} + + +char *scsi_card_getname(int card) +{ + return(scsi_cards[card].name); +} + + +device_t *scsi_card_getdevice(int card) +{ + return(scsi_cards[card].device); +} + + +int scsi_card_has_config(int card) +{ + if (! scsi_cards[card].device) return(0); + + return(scsi_cards[card].device->config ? 1 : 0); +} + + +char *scsi_card_get_internal_name(int card) +{ + return(scsi_cards[card].internal_name); +} + + +int scsi_card_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(scsi_cards[c].internal_name)) { + if (!strcmp(scsi_cards[c].internal_name, s)) + return(c); + c++; + } + + return(0); +} + + +void scsi_card_init() +{ + if (scsi_cards[scsi_card_current].device) + device_add(scsi_cards[scsi_card_current].device); + + scsi_card_last = scsi_card_current; +} + + +/* Initialization function for the SCSI layer */ void SCSIReset(uint8_t id, uint8_t lun) { - uint8_t cdrom_id = scsi_cdrom_drives[id][lun]; + uint8_t cdrom_id = scsi_cdrom_drives[id][lun]; + uint8_t hdc_id = scsi_hard_disks[id][lun]; - if (buslogic_scsi_drive_is_cdrom(id, lun)) + if (hdc_id != 0xff) { + scsi_hd_reset(cdrom_id); + SCSIDevices[id][lun].LunType = SCSI_HDD; + } else { + if (cdrom_id != 0xff) { cdrom_reset(cdrom_id); SCSIDevices[id][lun].LunType = SCSI_CDROM; @@ -32,4 +117,5 @@ void SCSIReset(uint8_t id, uint8_t lun) { SCSIDevices[id][lun].LunType = SCSI_NONE; } + } } diff --git a/src/scsi.h b/src/scsi.h index 3a441af95..ba0334f57 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -4,8 +4,6 @@ #ifndef __SCSI_H__ #define __SCSI_H__ -//#include "scattergather.h" - #include "timer.h" #define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT)) @@ -15,6 +13,7 @@ #define GPCMD_REZERO_UNIT 0x01 #define GPCMD_REQUEST_SENSE 0x03 #define GPCMD_READ_6 0x08 +#define GPCMD_WRITE_6 0x0a #define GPCMD_SEEK_6 0x0b #define GPCMD_INQUIRY 0x12 #define GPCMD_VERIFY_6 0x13 @@ -24,6 +23,7 @@ #define GPCMD_PREVENT_REMOVAL 0x1e #define GPCMD_READ_CDROM_CAPACITY 0x25 #define GPCMD_READ_10 0x28 +#define GPCMD_WRITE_10 0x2a #define GPCMD_SEEK_10 0x2b #define GPCMD_VERIFY_10 0x2f #define GPCMD_READ_SUBCHANNEL 0x42 @@ -42,6 +42,7 @@ #define GPCMD_MODE_SENSE_10 0x5a #define GPCMD_PLAY_AUDIO_12 0xa5 #define GPCMD_READ_12 0xa8 +#define GPCMD_WRITE_12 0xaa #define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ #define GPCMD_VERIFY_12 0xaf #define GPCMD_PLAY_CD_OLD 0xb4 @@ -206,7 +207,7 @@ extern int cd_status; extern int prev_status; #define SCSI_NONE 0 -#define SCSI_HDD 1 /*not present yet*/ +#define SCSI_HDD 1 #define SCSI_CDROM 2 #define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) @@ -238,10 +239,30 @@ void SCSICDROM_Insert(); int cdrom_add_error_and_subchannel(uint8_t *b, int real_sector_type); int cdrom_LBAtoMSF_accurate(); -// int cdrom_read_data(uint8_t *buffer); int mode_select_init(uint8_t command, uint16_t pl_length, uint8_t do_save); int mode_select_terminate(int force); int mode_select_write(uint8_t val); +extern int scsi_card_current; + +int scsi_card_available(int card); +char *scsi_card_getname(int card); +struct device_t *scsi_card_getdevice(int card); +int scsi_card_has_config(int card); +char *scsi_card_get_internal_name(int card); +int scsi_card_get_from_internal_name(char *s); +void scsi_card_init(); + +extern uint8_t scsi_hard_disks[16][8]; + +int scsi_hd_err_stat_to_scsi(uint8_t id); +int scsi_hd_phase_to_scsi(uint8_t id); +int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); +void build_scsi_hd_map(); +void scsi_hd_reset(uint8_t id); +void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); +void scsi_hd_command(uint8_t id, uint8_t *cdb); +void scsi_hd_callback(uint8_t id); + #endif \ No newline at end of file diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c new file mode 100644 index 000000000..fd89a1cc5 --- /dev/null +++ b/src/scsi_aha154x.c @@ -0,0 +1,407 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of several low-level support functions for + * the AHA-154x series of ISA Host Adapters made by Adaptec. + * These functions implement the support needed by the ROM BIOS + * of these cards. + * + * Version: @(#)aha154x.c 1.0.4 2017/04/21 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#include +#include +#include +#include "ibm.h" +#include "mem.h" +#include "rom.h" +#include "device.h" +#include "scsi_buslogic.h" + + +#define AHA AHA154xCF /* set desired card type */ +#define AHA154xB 1 /* AHA-154x Rev.B */ +#define AHA154xC 2 /* AHA-154x Rev.C */ +#define AHA154xCF 3 /* AHA-154x Rev.CF */ +#define AHA154xCP 4 /* AHA-154x Rev.CP */ + + +#if AHA == AHA154xB +# define ROMFILE "roms/adaptec/aha1540b310.bin" +# define AHA_BID 'A' /* AHA-154x B */ +#endif + +#if AHA == AHA154xC +# define ROMFILE "roms/adaptec/aha1542c101.bin" +# define AHA_BID 'D' /* AHA-154x C */ +# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ +#endif + +#if AHA == AHA154xCF +# define ROMFILE "roms/adaptec/aha1542cf201.bin" +# define AHA_BID 'E' /* AHA-154x CF */ +# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ +#endif + +#if AHA == AHA154xCP +# define ROMFILE "roms/adaptec/aha1542cp102.bin" +# define AHA_BID 'F' /* AHA-154x CP */ +# define ROM_FWHIGH 0x0055 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ +#endif + +#define ROM_SIZE 16384 /* one ROM is 16K */ + + +/* EEPROM map and bit definitions. */ +#define EE0_HOSTID 0x07 /* EE(0) [2:0] */ +#define EE0_ALTFLOP 0x80 /* EE(0) [7] FDC at 370h */ +#define EE1_IRQCH 0x07 /* EE(1) [3:0] */ +#define EE1_DMACH 0x70 /* EE(1) [7:4] */ +#define EE2_RMVOK 0x01 /* EE(2) [0] Support removable disks */ +#define EE2_HABIOS 0x02 /* EE(2) [1] HA Bios Space Reserved */ +#define EE2_INT19 0x04 /* EE(2) [2] HA Bios Controls INT19 */ +#define EE2_DYNSCAN 0x08 /* EE(2) [3] Dynamically scan bus */ +#define EE2_TWODRV 0x10 /* EE(2) [4] Allow more than 2 drives */ +#define EE2_SEEKRET 0x20 /* EE(2) [5] Immediate return on seek */ +#define EE2_EXT1G 0x80 /* EE(2) [7] Extended Translation >1GB */ +#define EE3_SPEED 0x00 /* EE(3) [7:0] DMA Speed */ +#define SPEED_33 0xFF +#define SPEED_50 0x00 +#define SPEED_56 0x04 +#define SPEED_67 0x01 +#define SPEED_80 0x02 +#define SPEED_10 0x03 +#define EE4_FLOPTOK 0x80 /* EE(4) [7] Support Flopticals */ +#define EE6_PARITY 0x01 /* EE(6) [0] parity check enable */ +#define EE6_TERM 0x02 /* EE(6) [1] host term enable */ +#define EE6_RSTBUS 0x04 /* EE(6) [2] reset SCSI bus on boot */ +#define EEE_SYNC 0x01 /* EE(E) [0] Enable Sync Negotiation */ +#define EEE_DISCON 0x02 /* EE(E) [1] Enable Disconnection */ +#define EEE_FAST 0x04 /* EE(E) [2] Enable FAST SCSI */ +#define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */ + + +static rom_t aha_bios; /* active ROM */ +static uint8_t *aha_rom1; /* main BIOS */ +static uint8_t *aha_rom2; /* SCSI-Select */ +#ifdef EEP_SIZE +static uint8_t aha_eep[EEP_SIZE]; /* EEPROM storage */ +#endif +static uint16_t aha_ports[] = { + 0x0330, 0x0334, 0x0230, 0x0234, + 0x0130, 0x0134, 0x0000, 0x0000 +}; + + +/* + * Write data to the BIOS space. + * + * AHA-1542C's and up have a feature where they map a 128-byte + * RAM space into the ROM BIOS' address space, and then use it + * as working memory. This function implements the writing to + * that memory. + * + * We enable/disable this memory through AHA command 0x24. + */ +static void +aha_mem_write(uint32_t addr, uint8_t val, void *priv) +{ + rom_t *rom = (rom_t *)priv; + +#if 0 + pclog("AHA1542x: writing to BIOS space, %06lX, val %02x\n", addr, val); + pclog(" called from %04X:%04X\n", CS, cpu_state.pc); +#endif + if ((addr & rom->mask) >= 0x3F80) + rom->rom[addr & rom->mask] = val; +} + + +static uint8_t +aha_mem_read(uint32_t addr, void *priv) +{ + rom_t *rom = (rom_t *)priv; + + return(rom->rom[addr & rom->mask]); +} + + +static uint16_t +aha_mem_readw(uint32_t addr, void *priv) +{ + rom_t *rom = (rom_t *)priv; + + return(*(uint16_t *)&rom->rom[addr & rom->mask]); +} + + +static uint32_t +aha_mem_readl(uint32_t addr, void *priv) +{ + rom_t *rom = (rom_t *)priv; + + return(*(uint32_t *)&rom->rom[addr & rom->mask]); +} + + +#ifdef ROM_IOADDR +/* + * Patch the ROM BIOS image for stuff Adaptec deliberately + * made hard to understand. Well, maybe not, maybe it was + * their way of handling issues like these at the time.. + * + * Patch 1: emulate the I/O ADDR SW setting by patching a + * byte in the BIOS that indicates the I/O ADDR + * switch setting on the board. + */ +static void +aha_patch(uint8_t *romptr, uint16_t ioaddr) +{ + int i; + + /* Look up the I/O address in the table. */ + for (i=0; i<8; i++) + if (aha_ports[i] == ioaddr) break; + if (i == 8) { + pclog("AHA154x: bad news, invalid I/O address %04x selected!\n", + ioaddr); + return; + } + romptr[ROM_IOADDR] = (unsigned char)i; +} +#endif + + +/* Initialize AHA-154xNN-specific stuff. */ +void +aha154x_init(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) +{ + uint32_t bios_size; + uint32_t bios_addr; + uint32_t bios_mask; + char *bios_path; + uint32_t temp; + FILE *f; + + /* Set BIOS load address. */ + bios_addr = memaddr; + bios_path = ROMFILE; + pclog("AHA154x: loading BIOS from '%s'\n", bios_path); + + /* Open the BIOS image file and make sure it exists. */ + if ((f = fopen(bios_path, "rb")) == NULL) { + pclog("AHA154x: BIOS ROM not found!\n"); + return; + } + + /* + * Manually load and process the ROM image. + * + * We *could* use the system "rom_init" function here, but for + * this special case, we can't: we may need WRITE access to the + * memory later on. + */ + (void)fseek(f, 0L, SEEK_END); + temp = ftell(f); + (void)fseek(f, 0L, SEEK_SET); + + /* Load first chunk of BIOS (which is the main BIOS, aka ROM1.) */ + aha_rom1 = malloc(ROM_SIZE); + (void)fread(aha_rom1, ROM_SIZE, 1, f); + temp -= ROM_SIZE; + if (temp > 0) { + aha_rom2 = malloc(ROM_SIZE); + (void)fread(aha_rom2, ROM_SIZE, 1, f); + temp -= ROM_SIZE; + } else { + aha_rom2 = NULL; + } + if (temp != 0) { + pclog("AHA154x: BIOS ROM size invalid!\n"); + free(aha_rom1); + if (aha_rom2 != NULL) + free(aha_rom2); + (void)fclose(f); + return; + } + temp = ftell(f); + if (temp > ROM_SIZE) + temp = ROM_SIZE; + (void)fclose(f); + + /* Adjust BIOS size in chunks of 2K, as per BIOS spec. */ + bios_size = 0x10000; + if (temp <= 0x8000) + bios_size = 0x8000; + if (temp <= 0x4000) + bios_size = 0x4000; + if (temp <= 0x2000) + bios_size = 0x2000; + bios_mask = (bios_size - 1); + pclog("AHA154x: BIOS at 0x%06lX, size %lu, mask %08lx\n", + bios_addr, bios_size, bios_mask); + + /* Initialize the ROM entry for this BIOS. */ + memset(&aha_bios, 0x00, sizeof(rom_t)); + + /* Enable ROM1 into the memory map. */ + aha_bios.rom = aha_rom1; + + /* Set up an address mask for this memory. */ + aha_bios.mask = bios_mask; + + /* Map this system into the memory map. */ + mem_mapping_add(&aha_bios.mapping, bios_addr, bios_size, + aha_mem_read, aha_mem_readw, aha_mem_readl, + aha_mem_write, NULL, NULL, + aha_bios.rom, MEM_MAPPING_EXTERNAL, &aha_bios); + +#ifdef ROM_IOADDR + /* Patch the ROM BIOS image to work with us. */ + aha_patch(aha_bios.rom, ioaddr); +#endif + +#if ROM_FWHIGH + /* Read firmware version from the BIOS. */ + aha->fwh = aha_bios.rom[ROM_FWHIGH]; + aha->fwl = aha_bios.rom[ROM_FWHIGH+1]; +#else + /* Fake BIOS firmware version. */ + aha->fwh = '1'; + aha->fwl = '0'; +#endif + aha->bid = AHA_BID; + + /* + * Do a checksum on the ROM. + * The BIOS ROMs on the 154xC(F) boards will always fail + * the checksum, because they are incomplete: on the real + * boards, a shadow RAM and some other (config) registers + * are mapped into its space. It is assumed that boards + * have logic that automatically generate a "fixup" byte + * at the end of the data to 'make up' for this. + * + * We emulated some of those in the patch routine, so now + * it is time to "fix up" the BIOS image so that the main + * (system) BIOS considers it valid. + */ +again: + bios_mask = 0; + for (temp=0; temp<16384; temp++) + bios_mask += aha_bios.rom[temp]; + bios_mask &= 0xff; + if (bios_mask != 0x00) { + pclog("AHA154x: fixing BIOS checksum (%02x) ..\n", bios_mask); + aha_bios.rom[temp-1] += (256 - bios_mask); + goto again; + } + + /* Enable the memory. */ + mem_mapping_enable(&aha_bios.mapping); + mem_mapping_set_addr(&aha_bios.mapping, bios_addr, bios_size); + +#ifdef EEP_SIZE + /* Initialize the on-board EEPROM. */ + memset(aha_eep, 0x00, EEP_SIZE); + aha_eep[0] = 7; /* SCSI ID 7 */ + aha_eep[1] = 15-9; /* IRQ15 */ + aha_eep[1] |= (6<<4); /* DMA6 */ + aha_eep[2] = (EE2_HABIOS | /* BIOS Space Reserved */ + EE2_SEEKRET); /* Immediate return on seek */ + aha_eep[3] = SPEED_50; /* speed 5.0 MB/s */ + aha_eep[6] = (EE6_TERM | /* host term enable */ + EE6_RSTBUS); /* reset SCSI bus on boot */ +#endif +} + + +/* Mess with the AHA-154xCF's Shadow RAM. */ +uint8_t +aha154x_shram(uint8_t cmd) +{ +#ifdef ROM_SHRAM + switch(cmd) { + case 0x00: /* disable, make it look like ROM */ + memset(&aha_bios.rom[ROM_SHRAM], 0xFF, ROM_SHRAMSZ); + break; + + case 0x02: /* clear it */ + memset(&aha_bios.rom[ROM_SHRAM], 0x00, ROM_SHRAMSZ); + break; + + case 0x03: /* enable, clear for use */ + memset(&aha_bios.rom[ROM_SHRAM], 0x00, ROM_SHRAMSZ); + break; + } +#endif + + /* Firmware expects 04 status. */ + return(0x04); +} + + +uint8_t +aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) +{ + uint8_t r = 0xff; + + pclog("AHA154x: EEPROM cmd=%02x, arg=%02x len=%d, off=%02x\n", + cmd, arg, len, off); + +#ifdef EEP_SIZE + if ((off+len) > EEP_SIZE) return(r); /* no can do.. */ + + if (cmd == 0x22) { + /* Write data to the EEPROM. */ + memcpy(&aha_eep[off], bufp, len); + r = 0; + } + + if (cmd == 0x23) { + /* Read data from the EEPROM. */ + memcpy(bufp, &aha_eep[off], len); + r = len; + } +#endif + + return(r); +} + + +uint8_t +aha154x_memory(uint8_t cmd) +{ + uint8_t r = 0xff; + + pclog("AHA154x: MEMORY cmd=%02x\n", cmd); + + if (cmd == 0x27) { + /* Enable the mapper, so, set ROM2 active. */ + aha_bios.rom = aha_rom2; + } + if (cmd == 0x26) { + /* Disable the mapper, so, set ROM1 active. */ + aha_bios.rom = aha_rom1; + } + + return(0); +} diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c new file mode 100644 index 000000000..9675cfe88 --- /dev/null +++ b/src/scsi_buslogic.c @@ -0,0 +1,2800 @@ +/* Copyright holders: SA1988 + see COPYING for more details +*/ +/*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/ + +/* Emulated SCSI controllers: + 0 - Adaptec AHA-154xB ISA; + 1 - Adaptec AHA-154xCF ISA; + 2 - BusLogic BT-542B ISA; + 3 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ + +#include +#include +#include +#include +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "dma.h" +#include "pic.h" +#include "pci.h" +#include "timer.h" +#include "scsi.h" +#include "cdrom.h" +#include "scsi_buslogic.h" + + +#define BUSLOGIC_RESET_DURATION_NS UINT64_C(50000000) + + +#pragma pack(push,1) +typedef struct { + uint8_t hi; + uint8_t mid; + uint8_t lo; +} addr24; +#pragma pack(pop) + +#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) +#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) + + +/* + * Host Adapter I/O ports. + * + * READ Port x+0: STATUS + * WRITE Port x+0: CONTROL + * + * READ Port x+1: DATA + * WRITE Port x+1: COMMAND + * + * READ Port x+2: INTERRUPT STATUS + * WRITE Port x+2: (undefined?) + * + * R/W Port x+3: (undefined) + */ + +/* WRITE CONTROL commands. */ +#define CTRL_HRST 0x80 /* Hard reset */ +#define CTRL_SRST 0x40 /* Soft reset */ +#define CTRL_IRST 0x20 /* interrupt reset */ +#define CTRL_SCRST 0x10 /* SCSI bus reset */ + +/* READ STATUS. */ +#define STAT_STST 0x80 /* self-test in progress */ +#define STAT_DFAIL 0x40 /* internal diagnostic failure */ +#define STAT_INIT 0x20 /* mailbox initialization required */ +#define STAT_IDLE 0x10 /* HBA is idle */ +#define STAT_CDFULL 0x08 /* Command/Data output port is full */ +#define STAT_DFULL 0x04 /* Data input port is full */ +#define STAT_INVCMD 0x01 /* Invalid command */ + +/* READ/WRITE DATA. */ +#define CMD_NOP 0x00 /* No operation */ +#define CMD_MBINIT 0x01 /* mailbox initialization */ +#define CMD_START_SCSI 0x02 /* Start SCSI command */ +#define CMD_BIOS 0x03 /* Execute ROM BIOS command */ +#define CMD_INQUIRY 0x04 /* Adapter inquiry */ +#define CMD_EMBOI 0x05 /* enable Mailbox Out Interrupt */ +#define CMD_SELTIMEOUT 0x06 /* Set SEL timeout */ +#define CMD_BUSON_TIME 0x07 /* set bus-On time */ +#define CMD_BUSOFF_TIME 0x08 /* set bus-off time */ +#define CMD_DMASPEED 0x09 /* set ISA DMA speed */ +#define CMD_RETDEVS 0x0A /* return installed devices */ +#define CMD_RETCONF 0x0B /* return configuration data */ +#define CMD_TARGET 0x0C /* set HBA to target mode */ +#define CMD_RETSETUP 0x0D /* return setup data */ +#define CMD_ECHO 0x1F /* ECHO command data */ + +/* READ INTERRUPT STATUS. */ +#define INTR_ANY 0x80 /* any interrupt */ +#define INTR_SRCD 0x08 /* SCSI reset detected */ +#define INTR_HACC 0x04 /* HA command complete */ +#define INTR_MBOA 0x02 /* MBO empty */ +#define INTR_MBIF 0x01 /* MBI full */ + + +/* + * Auto SCSI structure which is located + * in host adapter RAM and contains several + * configuration parameters. + */ +#pragma pack(push,1) +typedef struct { + uint8_t aInternalSignature[2]; + uint8_t cbInformation; + uint8_t aHostAdaptertype[6]; + uint8_t uReserved1; + uint8_t fFloppyEnabled :1, + fFloppySecondary :1, + fLevelSensitiveInterrupt:1, + uReserved2 :2, + uSystemRAMAreForBIOS :3; + uint8_t uDMAChannel :7, + fDMAAutoConfiguration :1, + uIrqChannel :7, + fIrqAutoConfiguration :1; + uint8_t uDMATransferRate; + uint8_t uSCSIId; + uint8_t fLowByteTerminated :1, + fParityCheckingEnabled :1, + fHighByteTerminated :1, + fNoisyCablingEnvironment:1, + fFastSyncNegotiation :1, + fBusResetEnabled :1, + fReserved3 :1, + fActiveNegotiationEna :1; + uint8_t uBusOnDelay; + uint8_t uBusOffDelay; + uint8_t fHostAdapterBIOSEnabled :1, + fBIOSRedirectionOfInt19 :1, + fExtendedTranslation :1, + fMapRemovableAsFixed :1, + fReserved4 :1, + fBIOSMoreThan2Drives :1, + fBIOSInterruptMode :1, + fFlopticalSupport :1; + uint16_t u16DeviceEnabledMask; + uint16_t u16WidePermittedMask; + uint16_t u16FastPermittedMask; + uint16_t u16SynchronousPermittedMask; + uint16_t u16DisconnectPermittedMask; + uint16_t u16SendStartUnitCommandMask; + uint16_t u16IgnoreInBIOSScanMask; + unsigned char uPCIInterruptPin : 2; + unsigned char uHostAdapterIoPortAddress : 2; + uint8_t fStrictRoundRobinMode : 1; + uint8_t fVesaBusSpeedGreaterThan33MHz : 1; + uint8_t fVesaBurstWrite : 1; + uint8_t fVesaBurstRead : 1; + uint16_t u16UltraPermittedMask; + uint32_t uReserved5; + uint8_t uReserved6; + uint8_t uAutoSCSIMaximumLUN; + uint8_t fReserved7 : 1; + uint8_t fSCAMDominant : 1; + uint8_t fSCAMenabled : 1; + uint8_t fSCAMLevel2 : 1; + unsigned char uReserved8 : 4; + uint8_t fInt13Extension : 1; + uint8_t fReserved9 : 1; + uint8_t fCDROMBoot : 1; + unsigned char uReserved10 : 5; + unsigned char uBootTargetId : 4; + unsigned char uBootChannel : 4; + uint8_t fForceBusDeviceScanningOrder : 1; + unsigned char uReserved11 : 7; + uint16_t u16NonTaggedToAlternateLunPermittedMask; + uint16_t u16RenegotiateSyncAfterCheckConditionMask; + uint8_t aReserved12[10]; + uint8_t aManufacturingDiagnostic[2]; + uint16_t u16Checksum; +} AutoSCSIRam; +#pragma pack(pop) + +/* The local RAM. */ +#pragma pack(push,1) +typedef union { + uint8_t u8View[256]; /* byte view */ + struct { /* structured view */ + uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ + AutoSCSIRam autoSCSIData; /* Auto SCSI structure */ + } structured; +} HALocalRAM; +#pragma pack(pop) + +/** Structure for the INQUIRE_SETUP_INFORMATION reply. */ +#pragma pack(push,1) +typedef struct { + uint8_t uOffset :4, + uTransferPeriod :3, + fSynchronous :1; +} ReplyInquireSetupInformationSynchronousValue; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t fSynchronousInitiationEnabled :1, + fParityCheckingEnabled :1, + uReserved1 :6; + uint8_t uBusTransferRate; + uint8_t uPreemptTimeOnBus; + uint8_t uTimeOffBus; + uint8_t cMailbox; + addr24 MailboxAddress; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; + uint8_t uDisconnectPermittedId0To7; + uint8_t uSignature; + uint8_t uCharacterD; + uint8_t uHostBusType; + uint8_t uWideTransferPermittedId0To7; + uint8_t uWideTransfersActiveId0To7; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15[8]; + uint8_t uDisconnectPermittedId8To15; + uint8_t uReserved2; + uint8_t uWideTransferPermittedId8To15; + uint8_t uWideTransfersActiveId8To15; +} ReplyInquireSetupInformation; +#pragma pack(pop) + +/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ +#pragma pack(push,1) +typedef struct { + uint8_t uBusType; + uint8_t uBiosAddress; + uint16_t u16ScatterGatherLimit; + uint8_t cMailbox; + uint32_t uMailboxAddressBase; + uint8_t uReserved1 :2, + fFastEISA :1, + uReserved2 :3, + fLevelSensitiveInterrupt:1, + uReserved3 :1; + uint8_t aFirmwareRevision[3]; + uint8_t fHostWideSCSI :1, + fHostDifferentialSCSI :1, + fHostSupportsSCAM :1, + fHostUltraSCSI :1, + fHostSmartTermination :1, + uReserved4 :3; +} ReplyInquireExtendedSetupInformation; +#pragma pack(pop) + +/* Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */ +#pragma pack(push,1) +typedef struct { + uint8_t IsaIOPort; + uint8_t IRQ; + uint8_t LowByteTerminated :1, + HighByteTerminated :1, + uReserved :2, /* Reserved. */ + JP1 :1, /* Whatever that means. */ + JP2 :1, /* Whatever that means. */ + JP3 :1, /* Whatever that means. */ + InformationIsValid :1; + uint8_t uReserved2; /* Reserved. */ +} BuslogicPCIInformation_t; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Count; + addr24 Address; +} MailboxInit_t; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Count; + uint32_t Address; +} MailboxInitExtended_t; +#pragma pack(pop) + + +/* + * Mailbox Definitions. + * + * Mailbox Out (MBO) command values. + */ +#define MBO_FREE 0x00 +#define MBO_START 0x01 +#define MBO_ABORT 0x02 + +/* Mailbox In (MBI) status values. */ +#define MBI_FREE 0x00 +#define MBI_SUCCESS 0x01 +#define MBI_ABORT 0x02 +#define MBI_NOT_FOUND 0x03 +#define MBI_ERROR 0x04 + + +#pragma pack(push,1) +typedef struct { + uint8_t CmdStatus; + addr24 CCBPointer; +} Mailbox_t; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint32_t CCBPointer; + union { + struct { + uint8_t Reserved[3]; + uint8_t ActionCode; + } out; + struct { + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved; + uint8_t CompletionCode; + } in; + } u; +} Mailbox32_t; +#pragma pack(pop) + + +/* + * + * CCB - SCSI Command Control Block + * + * The CCB is a superset of the CDB (Command Descriptor Block) + * and specifies detailed information about a SCSI command. + * + */ +/* Byte 0 Command Control Block Operation Code */ +#define SCSI_INITIATOR_COMMAND 0x00 +#define TARGET_MODE_COMMAND 0x01 +#define SCATTER_GATHER_COMMAND 0x02 +#define SCSI_INITIATOR_COMMAND_RES 0x03 +#define SCATTER_GATHER_COMMAND_RES 0x04 +#define BUS_RESET 0x81 + +/* Byte 1 Address and Direction Control */ +#define CCB_TARGET_ID_SHIFT 0x06 /* CCB Op Code = 00, 02 */ +#define CCB_INITIATOR_ID_SHIFT 0x06 /* CCB Op Code = 01 */ +#define CCB_DATA_XFER_IN 0x01 +#define CCB_DATA_XFER_OUT 0x02 +#define CCB_LUN_MASK 0x07 /* Logical Unit Number */ + +/* Byte 2 SCSI_Command_Length - Length of SCSI CDB + Byte 3 Request Sense Allocation Length */ +#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ +#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ + +/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */ +/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */ +/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */ +/* Byte 13 Command Link ID - TBD (I don't know yet) */ +/* Byte 14 Host Status - Host Adapter status */ +#define CCB_COMPLETE 0x00 /* CCB completed without error */ +#define CCB_LINKED_COMPLETE 0x0A /* Linked command completed */ +#define CCB_LINKED_COMPLETE_INT 0x0B /* Linked complete with intr */ +#define CCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ +#define CCB_DATA_OVER_UNDER_RUN 0x12 +#define CCB_UNEXPECTED_BUS_FREE 0x13 /* Trg dropped SCSI BSY */ +#define CCB_PHASE_SEQUENCE_FAIL 0x14 /* Trg bus phase sequence fail */ +#define CCB_BAD_MBO_COMMAND 0x15 /* MBO command not 0, 1 or 2 */ +#define CCB_INVALID_OP_CODE 0x16 /* CCB invalid operation code */ +#define CCB_BAD_LINKED_LUN 0x17 /* Linked CCB LUN diff from 1st */ +#define CCB_INVALID_DIRECTION 0x18 /* Invalid target direction */ +#define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */ +#define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */ + +/* Byte 15 Target Status + + See scsi.h files for these statuses. + Bytes 16 and 17 Reserved (must be 0) + Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Reserved1 :3, + ControlByte :2, + TagQueued :1, + QueueTag :2; + uint8_t CdbLength; + uint8_t RequestSenseLength; + uint32_t DataLength; + uint32_t DataPointer; + uint8_t Reserved2[2]; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Id; + uint8_t Lun :5, + LegacyTagEnable :1, + LegacyQueueTag :2; + uint8_t Cdb[12]; + uint8_t Reserved3[6]; + uint32_t SensePointer; +} CCB32; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Lun :3, + ControlByte :2, + Id :3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + addr24 DataLength; + addr24 DataPointer; + addr24 LinkPointer; + uint8_t LinkId; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved[2]; + uint8_t Cdb[12]; +} CCB; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Pad1 :3, + ControlByte :2, + Pad2 :3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + uint8_t Pad3[10]; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Pad4[2]; + uint8_t Cdb[12]; +} CCBC; +#pragma pack(pop) + +#pragma pack(push,1) +typedef union { + CCB32 new; + CCB old; + CCBC common; +} CCBU; +#pragma pack(pop) + + +/* + * + * Scatter/Gather Segment List Definitions + * + * Adapter limits + */ +/* #define MAX_SG_DESCRIPTORS ((bl->chip >= CHIP_BUSLOGIC_ISA) ? 32 : 17) */ +#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ + +#pragma pack(push,1) +typedef struct { + uint32_t Segment; + uint32_t SegmentPointer; +} SGE32; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + addr24 Segment; + addr24 SegmentPointer; +} SGE; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + CCBU CmdBlock; + uint8_t *RequestSenseBuffer; + uint32_t CCBPointer; + int Is24bit; + uint8_t TargetID; + uint8_t LUN; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t MailboxCompletionCode; +} BuslogicRequests_t; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + rom_t bios; + int UseLocalRAM; + int StrictRoundRobinMode; + int ExtendedLUNCCBFormat; + HALocalRAM LocalRAM; + BuslogicRequests_t BuslogicRequests; + uint8_t Status; + uint8_t Interrupt; + uint8_t Geometry; + uint8_t Control; + uint8_t Command; + uint8_t CmdBuf[53]; + uint8_t CmdParam; + uint8_t CmdParamLeft; + uint8_t DataBuf[64]; + uint16_t DataReply; + uint16_t DataReplyLeft; + uint32_t MailboxCount; + uint32_t MailboxOutAddr; + uint32_t MailboxOutPosCur; + uint32_t MailboxInAddr; + uint32_t MailboxInPosCur; + int Base; + int PCIBase; + int MMIOBase; + int Irq; + int DmaChannel; + int IrqEnabled; + int Mbx24bit; + int MailboxOutInterrupts; + int MbiActive[256]; + int PendingInterrupt; + int Lock; + mem_mapping_t mmio_mapping; + aha_info aha; + int chip; +} Buslogic_t; +#pragma pack(pop) + + +int scsi_model = 1; +int BuslogicResetCallback = 0; +int BuslogicCallback = 0; +int BuslogicInOperation = 0; +static Buslogic_t *BuslogicResetDevice; + + +enum +{ + CHIP_AHA154XB, + CHIP_AHA154XCF, + CHIP_BUSLOGIC_ISA, + CHIP_BUSLOGIC_PCI +}; + + +static void BuslogicStartMailbox(Buslogic_t *Buslogic); + +#ifdef WALTJE +int buslogic_do_log = 1; +# define ENABLE_BUSLOGIC_LOG +#else +int buslogic_do_log = 0; +#endif + + +static void BuslogicLog(const char *format, ...) +{ +#ifdef ENABLE_BUSLOGIC_LOG + va_list ap; + + if (buslogic_do_log) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#define pclog BuslogicLog + + +static void BuslogicClearInterrupt(Buslogic_t *bl) +{ + pclog("Buslogic: Lowering Interrupt 0x%02X\n", bl->Interrupt); + bl->Interrupt = 0; + pclog("Lowering IRQ %i\n", bl->Irq); + picintc(1 << bl->Irq); + if (bl->PendingInterrupt) { + bl->Interrupt = bl->PendingInterrupt; + pclog("Buslogic: Raising Interrupt 0x%02X (Pending)\n", bl->Interrupt); + if (bl->MailboxOutInterrupts || !(bl->Interrupt & INTR_MBOA)) { + if (bl->IrqEnabled) picint(1 << bl->Irq); + } + bl->PendingInterrupt = 0; + } +} + + +static void BuslogicLocalRAM(Buslogic_t *bl) +{ + /* + * These values are mostly from what I think is right + * looking at the dmesg output from a Linux guest inside + * a VMware server VM. + * + * So they don't have to be right :) + */ + memset(bl->LocalRAM.u8View, 0, sizeof(HALocalRAM)); + bl->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; + bl->LocalRAM.structured.autoSCSIData.fParityCheckingEnabled = 1; + bl->LocalRAM.structured.autoSCSIData.fExtendedTranslation = 1; /* Same as in geometry register. */ + bl->LocalRAM.structured.autoSCSIData.u16DeviceEnabledMask = UINT16_MAX; /* All enabled. Maybe mask out non present devices? */ + bl->LocalRAM.structured.autoSCSIData.u16WidePermittedMask = UINT16_MAX; + bl->LocalRAM.structured.autoSCSIData.u16FastPermittedMask = UINT16_MAX; + bl->LocalRAM.structured.autoSCSIData.u16SynchronousPermittedMask = UINT16_MAX; + bl->LocalRAM.structured.autoSCSIData.u16DisconnectPermittedMask = UINT16_MAX; + bl->LocalRAM.structured.autoSCSIData.fStrictRoundRobinMode = bl->StrictRoundRobinMode; + bl->LocalRAM.structured.autoSCSIData.u16UltraPermittedMask = UINT16_MAX; + /** @todo calculate checksum? */ +} + + +static void BuslogicReset(Buslogic_t *bl) +{ + BuslogicCallback = 0; + BuslogicResetCallback = 0; + bl->Status = STAT_IDLE | STAT_INIT; + bl->Geometry = 0x80; + bl->Command = 0xFF; + bl->CmdParam = 0; + bl->CmdParamLeft = 0; + bl->IrqEnabled = 1; + bl->StrictRoundRobinMode = 0; + bl->ExtendedLUNCCBFormat = 0; + bl->MailboxOutPosCur = 0; + bl->MailboxInPosCur = 0; + bl->MailboxOutInterrupts = 0; + bl->PendingInterrupt = 0; + bl->Lock = 0; + BuslogicInOperation = 0; + + BuslogicClearInterrupt(bl); + + BuslogicLocalRAM(bl); +} + + +void BuslogicSoftReset(void) +{ + if (BuslogicResetDevice != NULL) { + BuslogicReset(BuslogicResetDevice); + } +} + + +static void BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) +{ + BuslogicReset(bl); + if (Reset) { + bl->Status |= STAT_STST; + bl->Status &= ~STAT_IDLE; + } + BuslogicResetCallback = BUSLOGIC_RESET_DURATION_NS * TIMER_USEC; +} + + +static void BuslogicCommandComplete(Buslogic_t *bl) +{ + bl->DataReply = 0; + bl->Status |= STAT_IDLE; + +#ifdef WALTJE + if ((bl->Command != 0x02) && (bl->Command != 0x82)) { +#else + if (bl->Command != 0x02) { +#endif + bl->Status &= ~STAT_DFULL; + bl->Interrupt = (INTR_ANY | INTR_HACC); + pclog("Raising IRQ %i\n", bl->Irq); + if (bl->IrqEnabled) + picint(1 << bl->Irq); + } + + bl->Command = 0xFF; + bl->CmdParam = 0; +} + + +static void BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) +{ + if (bl->Interrupt & INTR_HACC) { + pclog("Pending IRQ\n"); + bl->PendingInterrupt = Interrupt; + } else { + bl->Interrupt = Interrupt; + pclog("Raising IRQ %i\n", bl->Irq); + if (bl->IrqEnabled) + picint(1 << bl->Irq); + } +} + + +static void BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, + CCBU *CmdBlock, uint8_t HostStatus, + uint8_t TargetStatus, + uint8_t MailboxCompletionCode) +{ + BuslogicRequests_t *req = &bl->BuslogicRequests; + + req->CCBPointer = CCBPointer; + memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); + req->Is24bit = bl->Mbx24bit; + req->HostStatus = HostStatus; + req->TargetStatus = TargetStatus; + req->MailboxCompletionCode = MailboxCompletionCode; + + pclog("Mailbox in setup\n"); + + BuslogicInOperation = 2; +} + + +static void BuslogicMailboxIn(Buslogic_t *bl) +{ + BuslogicRequests_t *req = &bl->BuslogicRequests; + uint32_t CCBPointer = req->CCBPointer; + CCBU *CmdBlock = &(req->CmdBlock); + uint8_t HostStatus = req->HostStatus; + uint8_t TargetStatus = req->TargetStatus; + uint8_t MailboxCompletionCode = req->MailboxCompletionCode; + Mailbox32_t Mailbox32; + Mailbox_t MailboxIn; + uint32_t Incoming; + + Mailbox32.CCBPointer = CCBPointer; + Mailbox32.u.in.HostStatus = HostStatus; + Mailbox32.u.in.TargetStatus = TargetStatus; + Mailbox32.u.in.CompletionCode = MailboxCompletionCode; + + Incoming = bl->MailboxInAddr + (bl->MailboxInPosCur * (bl->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + if (MailboxCompletionCode != MBI_NOT_FOUND) { + CmdBlock->common.HostStatus = HostStatus; + CmdBlock->common.TargetStatus = TargetStatus; + + /* Rewrite the CCB up to the CDB. */ + pclog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); + DMAPageWrite(CCBPointer, (char *)CmdBlock, offsetof(CCBC, Cdb)); + } else { + pclog("Mailbox not found!\n"); + } + + pclog("Host Status 0x%02X, Target Status 0x%02X\n", + HostStatus, TargetStatus); + + if (bl->Mbx24bit) { + MailboxIn.CmdStatus = Mailbox32.u.in.CompletionCode; + U32_TO_ADDR(MailboxIn.CCBPointer, Mailbox32.CCBPointer); + pclog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); + + DMAPageWrite(Incoming, (char *)&MailboxIn, sizeof(Mailbox_t)); + pclog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); + } else { + pclog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); + + DMAPageWrite(Incoming, (char *)&Mailbox32, sizeof(Mailbox32_t)); + pclog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + } + + bl->MailboxInPosCur++; + if (bl->MailboxInPosCur >= bl->MailboxCount) + bl->MailboxInPosCur = 0; + + BuslogicRaiseInterrupt(bl, INTR_MBIF | INTR_ANY); + + BuslogicInOperation = 0; +} + + +static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) +{ + uint32_t i; + SGE SGE24[MAX_SG_DESCRIPTORS]; + + if (Is24bit) { + DMAPageRead(SGList, (char *)&SGE24, Entries * sizeof(SGE)); + + for (i=0;iCmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + } else { + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; + } + pclog("Data Buffer write: length %d, pointer 0x%04X\n", + DataLength, DataPointer); + + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { + if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || + req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { + uint32_t SGRead; + uint32_t ScatterEntry; + SGE32 SGBuffer[MAX_SG_DESCRIPTORS]; + uint32_t SGLeft = DataLength / SGEntryLength; + uint32_t SGAddrCurrent = DataPointer; + uint32_t DataToTransfer = 0; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + BuslogicReadSGEntries(Is24bit, SGAddrCurrent, SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + + pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer += SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + } + + SGAddrCurrent += SGRead * SGEntryLength; + } while (SGLeft > 0); + + pclog("Data to transfer (S/G) %d\n", DataToTransfer); + + SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without + checking its length, so do this procedure for both no read/write commands. */ + if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || + (req->CmdBlock.common.ControlByte == 0x00)) { + SGLeft = DataLength / SGEntryLength; + SGAddrCurrent = DataPointer; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + BuslogicReadSGEntries(Is24bit, SGAddrCurrent, + SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + + pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer = SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + + DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; + } + + SGAddrCurrent += SGRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + } while (SGLeft > 0); + } + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || + req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + uint32_t Address = DataPointer; + + SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + if (DataLength > 0) { + DMAPageRead(Address, + (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, + SCSIDevices[req->TargetID][req->LUN].InitLength); + } + } + } +} + + +void BuslogicDataBufferFree(BuslogicRequests_t *req) +{ + uint32_t DataPointer = 0; + uint32_t DataLength = 0; + uint32_t sg_buffer_pos = 0; + uint32_t SGRead; + uint32_t ScatterEntry; + SGE32 SGBuffer[MAX_SG_DESCRIPTORS]; + uint32_t SGEntrySize; + uint32_t SGLeft; + uint32_t SGAddrCurrent; + uint32_t Address; + uint32_t Residual; + + if (req->Is24bit) { + DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + } else { + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; + } + + if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) { + pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n", + DataLength, SCSIDevices[req->TargetID][req->LUN].InitLength); + } + + if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) { + DataLength = 0; + } + + pclog("Data Buffer read: length %d, pointer 0x%04X\n", + DataLength, DataPointer); + + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without + checking its length, so do this procedure for both read/write commands. */ + if ((DataLength > 0) && + ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || + (req->CmdBlock.common.ControlByte == 0x00))) { + if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || + (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + SGEntrySize = (req->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + SGLeft = DataLength / SGEntrySize; + SGAddrCurrent = DataPointer; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + BuslogicReadSGEntries(req->Is24bit, SGAddrCurrent, + SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + uint32_t DataToTransfer; + + pclog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer = SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G: Writing %i bytes at %08X\n", DataToTransfer, Address); + + DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; + } + + SGAddrCurrent += (SGRead * SGEntrySize); + } while (SGLeft > 0); + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || + req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + Address = DataPointer; + + pclog("BusLogic DMA: Writing %i bytes at %08X\n", DataLength, Address); + DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, DataLength); + } + } + + if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || + (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + /* Should be 0 when scatter/gather? */ + if (DataLength >= SCSIDevices[req->TargetID][req->LUN].InitLength) { + Residual = DataLength; + Residual -= SCSIDevices[req->TargetID][req->LUN].InitLength; + } else { + Residual = 0; + } + + if (req->Is24bit) { + U32_TO_ADDR(req->CmdBlock.old.DataLength, Residual); + pclog("24-bit Residual data length for reading: %d\n", + ADDR_TO_U32(req->CmdBlock.old.DataLength)); + } else { + req->CmdBlock.new.DataLength = Residual; + pclog("32-bit Residual data length for reading: %d\n", + req->CmdBlock.new.DataLength); + } + } +} + + +static uint8_t BuslogicRead(uint16_t Port, void *p) +{ + Buslogic_t *bl = (Buslogic_t *)p; + uint8_t Temp; + + switch (Port & 3) { + case 0: + Temp = bl->Status; + break; + + case 1: + if (bl->UseLocalRAM) + Temp = bl->LocalRAM.u8View[bl->DataReply]; + else + Temp = bl->DataBuf[bl->DataReply]; + if (bl->DataReplyLeft) { + bl->DataReply++; + bl->DataReplyLeft--; + if (!bl->DataReplyLeft) { + BuslogicCommandComplete(bl); + } + } + break; + + case 2: + Temp = bl->Interrupt; + break; + + case 3: + Temp = bl->Geometry; + break; + } + + if (Port < 0x1000) { + pclog("Buslogic: Read Port 0x%02X, Returned Value %02X\n", + Port, Temp); + } + + return(Temp); +} + + +static uint16_t BuslogicReadW(uint16_t Port, void *p) +{ + return BuslogicRead(Port, p); +} + + +static uint32_t BuslogicReadL(uint16_t Port, void *p) +{ + return BuslogicRead(Port, p); +} + + +/* This is BS - we just need a 'dev_present' indication.. --FvK */ +int +buslogic_dev_present(uint8_t id, uint8_t lun) +{ + if (lun > 7) return(0); + + if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); + + if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && + cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && + (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) return(1); + + return(0); +} + + +static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); +static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); +static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) +{ + int i = 0; + uint8_t j = 0; + Buslogic_t *bl = (Buslogic_t *)p; + uint8_t max_id = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 16 : 8; + uint8_t Offset; + MailboxInit_t *MailboxInit; + ReplyInquireSetupInformation *ReplyISI; + MailboxInitExtended_t *MailboxInitE; + ReplyInquireExtendedSetupInformation *ReplyIESI; + BuslogicPCIInformation_t *ReplyPI; + char aModelName[] = "542B "; /* Trailing \0 is fine, that's the filler anyway. */ + int cCharsToTransfer; + + pclog("Buslogic: Write Port 0x%02X, Value %02X\n", Port, Val); + + switch (Port & 3) { + case 0: + if ((Val & CTRL_HRST) || (Val & CTRL_SRST)) { + uint8_t Reset = !(Val & CTRL_HRST); + BuslogicResetControl(bl, Reset); + break; + } + + if (Val & CTRL_IRST) { + BuslogicClearInterrupt(bl); + } + break; + + case 1: + /* Fast path for the mailbox execution command. */ + if (((Val == 0x02) || (Val == 0x82)) && + (bl->Command == 0xFF)) { + /* If there are no mailboxes configured, don't even try to do anything. */ + if (bl->MailboxCount) { + if (!BuslogicCallback) { + BuslogicCallback = 50 * SCSI_TIME; + } + } + return; + } + + if (bl->Command == 0xFF) { + bl->Command = Val; + bl->CmdParam = 0; + bl->CmdParamLeft = 0; + + bl->Status &= ~(STAT_INVCMD | STAT_IDLE); + pclog("Buslogic: Operation Code 0x%02X\n", Val); + switch (bl->Command) { + case 0x01: + bl->CmdParamLeft = sizeof(MailboxInit_t); + break; + + case 0x03: /* Exec BIOS Command */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->CmdParamLeft = 10; + } + break; + + case 0x25: + if (bl->chip < CHIP_BUSLOGIC_ISA) { + /* Same as 0x01 for AHA. */ + bl->CmdParamLeft = sizeof(MailboxInit_t); + } else { + bl->CmdParamLeft = 1; + } + break; + + case 0x05: + case 0x07: + case 0x08: + case 0x09: + case 0x0D: + case 0x1F: + case 0x21: + case 0x24: + bl->CmdParamLeft = 1; + break; + + case 0x06: + bl->CmdParamLeft = 4; + break; + + case 0x1C: + case 0x1D: + bl->CmdParamLeft = 3; + break; + + case 0x22: /* write EEPROM */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->CmdParamLeft = 3+32; + } + break; + + case 0x23: /* read EEPROM */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->CmdParamLeft = 3; + } + break; + + case 0x29: + bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 0 : 2; + break; + + case 0x8B: + case 0x8D: + case 0x8F: + case 0x96: + bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 1 : 0; + break; + + case 0x81: + pclog("Command 0x81 on %s\n", (bl->chip >= CHIP_BUSLOGIC_ISA) ? "BusLogic" : "Adaptec"); + bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? sizeof(MailboxInitExtended_t) : 0; + break; + + case 0x8C: + bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 1 : 0; + break; + + case 0x91: + bl->CmdParamLeft = 2; + break; + + case 0x95: /* Valid only for PCI */ + bl->CmdParamLeft = (bl->chip == CHIP_BUSLOGIC_PCI) ? 1 : 0; + break; + } + } else { + bl->CmdBuf[bl->CmdParam] = Val; + bl->CmdParam++; + bl->CmdParamLeft--; + } + + if (!bl->CmdParamLeft) { + pclog("Running Operation Code 0x%02X\n", bl->Command); + switch (bl->Command) { + case 0x00: + bl->DataReplyLeft = 0; + break; + + case 0x01: +aha_0x01: + { + bl->Mbx24bit = 1; + + MailboxInit = (MailboxInit_t *)bl->CmdBuf; + + bl->MailboxCount = MailboxInit->Count; + bl->MailboxOutAddr = ADDR_TO_U32(MailboxInit->Address); + bl->MailboxInAddr = bl->MailboxOutAddr + (bl->MailboxCount * sizeof(Mailbox_t)); + + pclog("Buslogic Initialize Mailbox Command\n"); + pclog("Mailbox Out Address=0x%08X\n", bl->MailboxOutAddr); + pclog("Mailbox In Address=0x%08X\n", bl->MailboxInAddr); + pclog("Initialized Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, ADDR_TO_U32(MailboxInit->Address)); + + bl->Status &= ~STAT_INIT; + bl->DataReplyLeft = 0; + } + break; + + case 0x03: + bl->DataBuf[0] = 0x00; + bl->DataReplyLeft = 1; + break; + + case 0x04: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->DataBuf[0] = 0x41; + bl->DataBuf[1] = 0x41; + bl->DataBuf[2] = '5'; + bl->DataBuf[3] = '0'; + } else { + bl->DataBuf[0] = bl->aha.bid; + bl->DataBuf[1] = 0x30; + bl->DataBuf[2] = bl->aha.fwh; + bl->DataBuf[3] = bl->aha.fwl; + } + bl->DataReplyLeft = 4; + break; + + case 0x05: + if (bl->CmdBuf[0] <= 1) { + bl->MailboxOutInterrupts = bl->CmdBuf[0]; + pclog("Mailbox out interrupts: %s\n", bl->MailboxOutInterrupts ? "ON" : "OFF"); + } else { + bl->Status |= STAT_INVCMD; + } + bl->DataReplyLeft = 0; + break; + + case 0x06: + bl->DataReplyLeft = 0; + break; + + case 0x07: + bl->DataReplyLeft = 0; + bl->LocalRAM.structured.autoSCSIData.uBusOnDelay = bl->CmdBuf[0]; + pclog("Bus-on time: %d\n", bl->CmdBuf[0]); + break; + + case 0x08: + bl->DataReplyLeft = 0; + bl->LocalRAM.structured.autoSCSIData.uBusOffDelay = bl->CmdBuf[0]; + pclog("Bus-off time: %d\n", bl->CmdBuf[0]); + break; + + case 0x09: + bl->DataReplyLeft = 0; + bl->LocalRAM.structured.autoSCSIData.uDMATransferRate = bl->CmdBuf[0]; + pclog("DMA transfer rate: %02X\n", bl->CmdBuf[0]); + break; + + case 0x0A: + memset(bl->DataBuf, 0, 8); + for (i=0; i<7; i++) { + bl->DataBuf[i] = 0; + for (j=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + bl->DataBuf[i] |= (1 << j); + } + } + bl->DataBuf[7] = 0; + bl->DataReplyLeft = 8; + break; + + case 0x0B: + bl->DataBuf[0] = (1 << bl->DmaChannel); + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->DataBuf[1] = (1<<(bl->Irq-9)); + } else { + if (bl->Irq >= 8) + bl->DataBuf[1]=(1<<(bl->Irq-9)); + else + bl->DataBuf[1]=(1<Irq); + } + bl->DataBuf[2] = 7; /* HOST ID */ + bl->DataReplyLeft = 3; + break; + + case 0x0D: + { + bl->DataReplyLeft = bl->CmdBuf[0]; + + ReplyISI = (ReplyInquireSetupInformation *)bl->DataBuf; + memset(ReplyISI, 0, sizeof(ReplyInquireSetupInformation)); + + ReplyISI->fSynchronousInitiationEnabled = 1; + ReplyISI->fParityCheckingEnabled = 1; + ReplyISI->cMailbox = bl->MailboxCount; + U32_TO_ADDR(ReplyISI->MailboxAddress, bl->MailboxOutAddr); + + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + ReplyISI->uSignature = 'B'; + /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too + * friendly with Adaptec hardware and upsetting the HBA state. + */ + ReplyISI->uCharacterD = 'D'; /* BusLogic model. */ + ReplyISI->uHostBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'F' : 'A'; /* ISA bus. */ + } + + pclog("Return Setup Information: %d\n", bl->CmdBuf[0]); + } + break; + + case 0x1C: + { + uint32_t FIFOBuf; + addr24 Address; + + bl->DataReplyLeft = 0; + Address.hi = bl->CmdBuf[0]; + Address.mid = bl->CmdBuf[1]; + Address.lo = bl->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + DMAPageRead(FIFOBuf, (char *)&bl->LocalRAM.u8View[64], 64); + } + break; + + case 0x1D: + { + uint32_t FIFOBuf; + addr24 Address; + + bl->DataReplyLeft = 0; + Address.hi = bl->CmdBuf[0]; + Address.mid = bl->CmdBuf[1]; + Address.lo = bl->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + pclog("Buslogic FIFO: Writing 64 bytes at %08X\n", FIFOBuf); + DMAPageWrite(FIFOBuf, (char *)&bl->LocalRAM.u8View[64], 64); + } + break; + + case 0x1F: + bl->DataBuf[0] = bl->CmdBuf[0]; + bl->DataReplyLeft = 1; + break; + + case 0x20: + bl->DataReplyLeft = 0; + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + BuslogicResetControl(bl, 1); + } else { + bl->Status |= STAT_INVCMD; + } + break; + + case 0x21: + if (bl->CmdParam == 1) + bl->CmdParamLeft = bl->CmdBuf[0]; + bl->DataReplyLeft = 0; + break; + + case 0x22: /* write EEPROM */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + /* Sent by CF BIOS. */ + bl->DataReplyLeft = + aha154x_eeprom(bl->Command, + bl->CmdBuf[0], + bl->CmdBuf[1], + bl->CmdBuf[2], + &bl->CmdBuf[3]); + if (bl->DataReplyLeft == 0xff) { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + } else { + bl->Status |= STAT_INVCMD; + bl->DataReplyLeft = 0; + } + break; + + case 0x23: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + memset(bl->DataBuf, 0, 8); + for (i = 8; i < 16; i++) { + bl->DataBuf[i] = 0; + for (i=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + bl->DataBuf[i] |= (1 << j); + } + } + bl->DataReplyLeft = 8; + } else { + /* Sent by CF BIOS. */ + bl->DataReplyLeft = + aha154x_eeprom(bl->Command, + bl->CmdBuf[0], + bl->CmdBuf[1], + bl->CmdBuf[2], + bl->DataBuf); + if (bl->DataReplyLeft == 0xff) { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + } + break; + + case 0x24: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + uint16_t TargetsPresentMask = 0; + + for (i=0; i<16; i++) { + for (j=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + TargetsPresentMask |= (1 << i); + } + } + bl->DataBuf[0] = TargetsPresentMask & 0xFF; + bl->DataBuf[1] = TargetsPresentMask >> 8; + bl->DataReplyLeft = 2; + } else { + /* + * For AHA1542CF, this is the command + * to play with the Shadow RAM. BIOS + * gives us one argument (00,02,03) + * and expects a 0x04 back in the INTR + * register. --FvK + */ + bl->Interrupt = aha154x_shram(Val); + } + break; + + case 0x25: + if ((bl->chip < CHIP_BUSLOGIC_ISA)) { + goto aha_0x01; + } else { + if (bl->CmdBuf[0] == 0) + bl->IrqEnabled = 0; + else + bl->IrqEnabled = 1; + pclog("Lowering IRQ %i\n", bl->Irq); + picintc(1 << bl->Irq); + } + break; + + case 0x26: /* AHA memory mapper */ + case 0x27: /* AHA memory mapper */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->DataReplyLeft = + aha154x_memory(bl->Command); + } else { + bl->Status |= STAT_INVCMD; + bl->DataReplyLeft = 0; + } + break; + + case 0x28: + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->DataBuf[0] = 0x08; + bl->DataBuf[1] = bl->Lock; + bl->DataReplyLeft = 2; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x29: + if (bl->chip < CHIP_BUSLOGIC_ISA) { + if (bl->CmdBuf[1] == bl->Lock) { + if (bl->CmdBuf[0] & 1) { + bl->Lock = 1; + } else { + bl->Lock = 0; + } + } + bl->DataReplyLeft = 0; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x2C: /* AHA-1542CP sends this */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->DataBuf[0] = 0x00; + bl->DataReplyLeft = 1; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x33: /* AHA-1542CP sends this */ + if (bl->chip < CHIP_BUSLOGIC_ISA) { + bl->DataBuf[0] = 0x00; + bl->DataBuf[1] = 0x00; + bl->DataBuf[2] = 0x00; + bl->DataBuf[3] = 0x00; + bl->DataReplyLeft = 256; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x81: + { + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->Mbx24bit = 0; + + MailboxInitE = (MailboxInitExtended_t *)bl->CmdBuf; + + bl->MailboxCount = MailboxInitE->Count; + bl->MailboxOutAddr = MailboxInitE->Address; + bl->MailboxInAddr = MailboxInitE->Address + (bl->MailboxCount * sizeof(Mailbox32_t)); + + pclog("Buslogic Extended Initialize Mailbox Command\n"); + pclog("Mailbox Out Address=0x%08X\n", bl->MailboxOutAddr); + pclog("Mailbox In Address=0x%08X\n", bl->MailboxInAddr); + pclog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); + + bl->Status &= ~STAT_INIT; + bl->DataReplyLeft = 0; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + } + break; + + case 0x84: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->DataBuf[0] = '7'; + bl->DataReplyLeft = 1; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x85: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->DataBuf[0] = 'B'; + bl->DataReplyLeft = 1; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x86: + if (bl->chip == CHIP_BUSLOGIC_PCI) + { + ReplyPI = (BuslogicPCIInformation_t *) bl->DataBuf; + memset(ReplyPI, 0, sizeof(BuslogicPCIInformation_t)); + ReplyPI->InformationIsValid = 0; + switch(bl->Base) + { + case 0x330: + ReplyPI->IsaIOPort = 0; + break; + case 0x334: + ReplyPI->IsaIOPort = 1; + break; + case 0x230: + ReplyPI->IsaIOPort = 2; + break; + case 0x234: + ReplyPI->IsaIOPort = 3; + break; + case 0x130: + ReplyPI->IsaIOPort = 4; + break; + case 0x134: + ReplyPI->IsaIOPort = 5; + break; + default: + ReplyPI->IsaIOPort = 0xFF; + break; + } + ReplyPI->IRQ = bl->Irq; + bl->DataReplyLeft = sizeof(BuslogicPCIInformation_t); + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x8B: + { + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + /* The reply length is set by the guest and is found in the first byte of the command buffer. */ + bl->DataReplyLeft = bl->CmdBuf[0]; + memset(bl->DataBuf, 0, bl->DataReplyLeft); + if (bl->chip == CHIP_BUSLOGIC_PCI) { + aModelName[0] = '9'; + aModelName[1] = '5'; + aModelName[2] = '8'; + aModelName[3] = 'D'; + } + cCharsToTransfer = bl->DataReplyLeft <= sizeof(aModelName) + ? bl->DataReplyLeft + : sizeof(aModelName); + + for (i = 0; i < cCharsToTransfer; i++) + bl->DataBuf[i] = aModelName[i]; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + } + break; + + case 0x8C: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->DataReplyLeft = bl->CmdBuf[0]; + memset(bl->DataBuf, 0, bl->DataReplyLeft); + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x8D: + { + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + bl->DataReplyLeft = bl->CmdBuf[0]; + ReplyIESI = (ReplyInquireExtendedSetupInformation *)bl->DataBuf; + memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); + + ReplyIESI->uBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'E' : 'A'; /* ISA style */ + ReplyIESI->uBiosAddress = 0; + ReplyIESI->u16ScatterGatherLimit = 8192; + ReplyIESI->cMailbox = bl->MailboxCount; + ReplyIESI->uMailboxAddressBase = bl->MailboxOutAddr; + if (bl->chip == CHIP_BUSLOGIC_PCI) { + ReplyIESI->fLevelSensitiveInterrupt = 1; + ReplyIESI->fHostWideSCSI = 1; + ReplyIESI->fHostUltraSCSI = 1; + } + memcpy(ReplyIESI->aFirmwareRevision, "07B", sizeof(ReplyIESI->aFirmwareRevision)); + pclog("Return Extended Setup Information: %d\n", bl->CmdBuf[0]); + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + } + break; + + /* VirtualBox has these two modes implemented in reverse. + According to the BusLogic datasheet: + 0 is the strict round robin mode, which is also the one used by the AHA-154x according to the + Adaptec specification; + 1 is the aggressive round robin mode, which "hunts" for an active outgoing mailbox and then + processes it. */ + case 0x8F: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + if (bl->CmdBuf[0] == 0) + bl->StrictRoundRobinMode = 1; + else if (bl->CmdBuf[0] == 1) + bl->StrictRoundRobinMode = 0; + + bl->DataReplyLeft = 0; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x91: + { + Offset = bl->CmdBuf[0]; + bl->DataReplyLeft = bl->CmdBuf[1]; + + bl->UseLocalRAM = 1; + bl->DataReply = Offset; + } + break; + + case 0x95: + if (bl->chip == CHIP_BUSLOGIC_PCI) { + if (bl->Base != 0) { + io_removehandler(bl->Base, 4, + BuslogicRead, + BuslogicReadW, + BuslogicReadL, + BuslogicWrite, + BuslogicWriteW, + BuslogicWriteL, + bl); + } + switch(bl->CmdBuf[0]) { + case 0: + bl->Base = 0x330; + break; + case 1: + bl->Base = 0x334; + break; + case 2: + bl->Base = 0x230; + break; + case 3: + bl->Base = 0x234; + break; + case 4: + bl->Base = 0x130; + break; + case 5: + bl->Base = 0x134; + break; + default: + bl->Base = 0; + break; + } + if (bl->Base != 0) { + io_sethandler(bl->Base, 4, + BuslogicRead, + BuslogicReadW, + BuslogicReadL, + BuslogicWrite, + BuslogicWriteW, + BuslogicWriteL, + bl); + } + bl->DataReplyLeft = 0; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + case 0x96: + if (bl->chip >= CHIP_BUSLOGIC_ISA) { + if (bl->CmdBuf[0] == 0) + bl->ExtendedLUNCCBFormat = 0; + else if (bl->CmdBuf[0] == 1) + bl->ExtendedLUNCCBFormat = 1; + + bl->DataReplyLeft = 0; + } else { + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + } + break; + + default: + bl->DataReplyLeft = 0; + bl->Status |= STAT_INVCMD; + break; + } + } + + if (bl->DataReplyLeft) + bl->Status |= STAT_DFULL; + else if (!bl->CmdParamLeft) + BuslogicCommandComplete(bl); + break; + + case 2: + if (bl->chip >= CHIP_BUSLOGIC_ISA) + bl->Interrupt = Val; /* For Buslogic */ + break; + + case 3: + if (bl->chip >= CHIP_BUSLOGIC_ISA) + bl->Geometry = Val; /* For Buslogic */ + break; + } +} + + +static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) +{ + BuslogicWrite(Port, Val & 0xFF, p); +} + + +static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) +{ + BuslogicWrite(Port, Val & 0xFF, p); +} + + +static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) +{ + pclog("Unconverted Request Sense length %i\n", RequestSenseLength); + + if (RequestSenseLength == 0) + RequestSenseLength = 14; + else if (RequestSenseLength == 1) + RequestSenseLength = 0; + + pclog("Request Sense length %i\n", RequestSenseLength); + + return(RequestSenseLength); +} + + +static void BuslogicSenseBufferFree(BuslogicRequests_t *req, int Copy, int is_hd) +{ + uint8_t SenseLength = BuslogicConvertSenseLength(req->CmdBlock.common.RequestSenseLength); + uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN]; + uint8_t hdc_id = scsi_hard_disks[req->TargetID][req->LUN]; + uint32_t SenseBufferAddress; + uint8_t temp_sense[256]; + + if (SenseLength && Copy) { + if (is_hd) + { + scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength); + } + else + { + cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); + } + + /* + * The sense address, in 32-bit mode, is located in the + * Sense Pointer of the CCB, but in 24-bit mode, it is + * located at the end of the Command Descriptor Block. + */ + if (req->Is24bit) { + SenseBufferAddress = req->CCBPointer; + SenseBufferAddress += req->CmdBlock.common.CdbLength + offsetof(CCB, Cdb); + } else { + SenseBufferAddress = req->CmdBlock.new.SensePointer; + } + + pclog("Request Sense address: %02X\n", SenseBufferAddress); + + pclog("BuslogicSenseBufferFree(): Writing %i bytes at %08X\n", + SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, (char *)temp_sense, SenseLength); + pclog("Sense data written to buffer: %02X %02X %02X\n", + temp_sense[2], temp_sense[12], temp_sense[13]); + } +} + + +static void BuslogicHDCommand(Buslogic_t *bl) +{ + BuslogicRequests_t *req = &bl->BuslogicRequests; + uint8_t Id, Lun; + uint8_t hdc_id; + uint8_t hd_phase; + uint8_t temp_cdb[12]; + uint32_t i; + + Id = req->TargetID; + Lun = req->LUN; + hdc_id = scsi_hard_disks[Id][Lun]; + + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", + Id, Lun, hdc_id); + + pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) { + pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, shdc[hdc_id].cdb_len); + if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len); + } + + /* + * Since that field in the HDC struct is never used when + * the bus type is SCSI, let's use it for this scope. + */ + shdc[hdc_id].request_length = temp_cdb[1]; + + if (req->CmdBlock.common.CdbLength != 12) { + /* + * Make sure the LUN field of the temporary CDB is always 0, + * otherwise Daemon Tools drives will misbehave when a command + * is passed through to them. + */ + temp_cdb[1] &= 0x1f; + } + + /* Finally, execute the SCSI command immediately and get the transfer length. */ + SCSIPhase = SCSI_PHASE_COMMAND; + scsi_hd_command(hdc_id, temp_cdb); + SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id); + if (SCSIStatus == SCSI_STATUS_OK) { + hd_phase = scsi_hd_phase_to_scsi(hdc_id); + if (hd_phase == 2) { + /* Command completed - call the phase callback to complete the command. */ + scsi_hd_callback(hdc_id); + } else { + /* Command first phase complete - call the callback to execute the second phase. */ + scsi_hd_callback(hdc_id); + SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id); + /* Command second phase complete - call the callback to complete the command. */ + scsi_hd_callback(hdc_id); + } + } else { + /* Error (Check Condition) - call the phase callback to complete the command. */ + scsi_hd_callback(hdc_id); + } + + pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", shdc[hdc_id].sense[2], shdc[hdc_id].sense[12], shdc[hdc_id].sense[13]); + + BuslogicDataBufferFree(req); + + BuslogicSenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 1); + + pclog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + BuslogicMailboxInSetup(bl, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + BuslogicMailboxInSetup(bl, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + +static void BuslogicCDROMCommand(Buslogic_t *bl) +{ + BuslogicRequests_t *req = &bl->BuslogicRequests; + uint8_t Id, Lun; + uint8_t cdrom_id; + uint8_t cdrom_phase; + uint8_t temp_cdb[12]; + uint32_t i; + + Id = req->TargetID; + Lun = req->LUN; + cdrom_id = scsi_cdrom_drives[Id][Lun]; + + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", + Id, Lun, cdrom_id); + + pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) { + pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); + if (req->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); + } + + /* + * Since that field in the CDROM struct is never used when + * the bus type is SCSI, let's use it for this scope. + */ + cdrom[cdrom_id].request_length = temp_cdb[1]; + + if (req->CmdBlock.common.CdbLength != 12) { + /* + * Make sure the LUN field of the temporary CDB is always 0, + * otherwise Daemon Tools drives will misbehave when a command + * is passed through to them. + */ + temp_cdb[1] &= 0x1f; + } + + /* Finally, execute the SCSI command immediately and get the transfer length. */ + SCSIPhase = SCSI_PHASE_COMMAND; + cdrom_command(cdrom_id, temp_cdb); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + if (SCSIStatus == SCSI_STATUS_OK) { + cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); + if (cdrom_phase == 2) { + /* Command completed - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } else { + /* Command first phase complete - call the callback to execute the second phase. */ + cdrom_phase_callback(cdrom_id); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + /* Command second phase complete - call the callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + } else { + /* Error (Check Condition) - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + + pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); + + BuslogicDataBufferFree(req); + + BuslogicSenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0); + + pclog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + BuslogicMailboxInSetup(bl, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + BuslogicMailboxInSetup(bl, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + + +static void BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +{ + BuslogicRequests_t *req = &bl->BuslogicRequests; + uint8_t Id, Lun; + uint8_t last_id = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 15 : 7; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&req->CmdBlock, sizeof(CCB32)); + + req->Is24bit = bl->Mbx24bit; + req->CCBPointer = CCBPointer; + req->TargetID = bl->Mbx24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; + req->LUN = bl->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; + + Id = req->TargetID; + Lun = req->LUN; + if ((Id > last_id) || (Lun > 7)) { + BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock, + CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + return; + } + + pclog("Scanning SCSI Target ID %i\n", Id); + + SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[Id][Lun].InitLength = 0; + + /* Do this here, so MODE SELECT data does not get lost in transit. */ + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); + + BuslogicDataBufferAllocate(req, req->Is24bit); + + if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { + pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun); + BuslogicDataBufferFree(req); + BuslogicSenseBufferFree(req, 0, 0); + BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock, + CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); + } else { + pclog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); + + pclog("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); + pclog("CDB Length %i\n", req->CmdBlock.common.CdbLength); + pclog("CCB Opcode %x\n", req->CmdBlock.common.Opcode); + if (req->CmdBlock.common.ControlByte > 0x03) { + pclog("Invalid control byte: %02X\n", + req->CmdBlock.common.ControlByte); + } + + BuslogicInOperation = (SCSIDevices[Id][Lun].LunType == SCSI_HDD) ? 0x11 : 1; + pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType); + } +} + + +static void BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) +{ + CCBU CmdBlock; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&CmdBlock, sizeof(CCB32)); + + /* Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. */ + BuslogicMailboxInSetup(bl, CCBPointer, &CmdBlock, + 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); +} + + +static uint32_t BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) +{ + Mailbox_t MailboxOut; + uint32_t Outgoing; + + if (bl->Mbx24bit) { + Outgoing = bl->MailboxOutAddr + (bl->MailboxOutPosCur * sizeof(Mailbox_t)); + DMAPageRead(Outgoing, (char *)&MailboxOut, sizeof(Mailbox_t)); + + Mailbox32->CCBPointer = ADDR_TO_U32(MailboxOut.CCBPointer); + Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; + } else { + Outgoing = bl->MailboxOutAddr + (bl->MailboxOutPosCur * sizeof(Mailbox32_t)); + + DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t)); + } + + return Outgoing; +} + + +static void BuslogicMailboxOutAdvance(Buslogic_t *bl) +{ + bl->MailboxOutPosCur = (bl->MailboxOutPosCur + 1) % bl->MailboxCount; +} + + +static void BuslogicProcessMailbox(Buslogic_t *bl) +{ + Mailbox32_t mb32; + uint32_t Outgoing; + uint8_t CmdStatus = MBO_FREE; + uint32_t CodeOffset = 0; + + CodeOffset = bl->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + + if (! bl->StrictRoundRobinMode) { + uint8_t MailboxCur = bl->MailboxOutPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do { + /* Fetch mailbox from guest memory. */ + Outgoing = BuslogicMailboxOut(bl, &mb32); + + /* Check the next mailbox. */ + BuslogicMailboxOutAdvance(bl); + } while ((mb32.u.out.ActionCode == MBO_FREE) && (MailboxCur != bl->MailboxOutPosCur)); + } else { + Outgoing = BuslogicMailboxOut(bl, &mb32); + } + + if (mb32.u.out.ActionCode != MBO_FREE) { + /* We got the mailbox, mark it as free in the guest. */ + pclog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); + } + + if (bl->MailboxOutInterrupts) + BuslogicRaiseInterrupt(bl, INTR_MBOA | INTR_ANY); + + /* Check if the mailbox is actually loaded. */ + if (mb32.u.out.ActionCode == MBO_FREE) { + return; + } + + if (mb32.u.out.ActionCode == MBO_START) { + pclog("Start Mailbox Command\n"); + BuslogicSCSIRequestSetup(bl, mb32.CCBPointer, &mb32); + } else if (mb32.u.out.ActionCode == MBO_ABORT) { + pclog("Abort Mailbox Command\n"); + BuslogicSCSIRequestAbort(bl, mb32.CCBPointer); + } else { + pclog("Invalid action code: %02X\n", mb32.u.out.ActionCode); + } + + /* Advance to the next mailbox. */ + if (bl->StrictRoundRobinMode) + BuslogicMailboxOutAdvance(bl); +} + + +void BuslogicResetPoll(void *p) +{ + Buslogic_t *bl = (Buslogic_t *)p; + + bl->Status &= ~STAT_STST; + bl->Status |= STAT_IDLE; + + BuslogicResetCallback = 0; +} + + +void BuslogicCommandCallback(void *p) +{ + Buslogic_t *bl = (Buslogic_t *)p; + + if (BuslogicInOperation == 0) { + if (bl->MailboxCount) { + BuslogicProcessMailbox(bl); + } else { + BuslogicCallback += 50 * SCSI_TIME; + return; + } + } else if (BuslogicInOperation == 1) { + pclog("BusLogic Callback: Process CD-ROM request\n"); + BuslogicCDROMCommand(bl); + } else if (BuslogicInOperation == 2) { + pclog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(bl); + } else if (BuslogicInOperation == 0x11) { + pclog("BusLogic Callback: Process hard disk request\n"); + BuslogicHDCommand(bl); + } else { + fatal("Invalid BusLogic callback phase: %i\n", BuslogicInOperation); + } + + BuslogicCallback += 50 * SCSI_TIME; +} + + +static uint8_t mem_read_null(uint32_t addr, void *priv) +{ + return(0); +} + + +static uint16_t mem_read_nullw(uint32_t addr, void *priv) +{ + return(0); +} + + +static uint32_t mem_read_nulll(uint32_t addr, void *priv) +{ + return(0); +} + + +typedef union { + uint32_t addr; + uint8_t addr_regs[4]; +} bar_t; + + +uint8_t buslogic_pci_regs[256]; +bar_t buslogic_pci_bar[3]; + + +static uint8_t BuslogicPCIRead(int func, int addr, void *p) +{ + Buslogic_t *bl = (Buslogic_t *)p; + + switch (addr) { + case 0x00: + return 0x4b; + case 0x01: + return 0x10; + case 0x02: + return 0x40; + case 0x03: + return 0x10; + case 0x04: + return buslogic_pci_regs[0x04]; /*Respond to IO and memory accesses*/ + case 0x05: + return buslogic_pci_regs[0x05]; + case 0x07: + return 2; + case 0x08: + return 1; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + case 0x0A: + return 0; /*Subclass*/ + case 0x0B: + return 1; /* Class code*/ + case 0x10: + return (buslogic_pci_bar[0].addr_regs[0] & 0xe0) | 1; /*I/O space*/ + case 0x11: + return buslogic_pci_bar[0].addr_regs[1]; + case 0x12: + return buslogic_pci_bar[0].addr_regs[2]; + case 0x13: + return buslogic_pci_bar[0].addr_regs[3]; + case 0x14: + return (buslogic_pci_bar[1].addr_regs[0] & 0xe0); /*Memory space*/ + case 0x15: + return buslogic_pci_bar[1].addr_regs[1]; + case 0x16: + return buslogic_pci_bar[1].addr_regs[2]; + case 0x17: + return buslogic_pci_bar[1].addr_regs[3]; + case 0x2C: + return 0x4b; + case 0x2D: + return 0x10; + case 0x2E: + return 0x40; + case 0x2F: + return 0x10; + case 0x30: + return buslogic_pci_bar[2].addr_regs[0] & 0x01; /*BIOS ROM address*/ + case 0x31: + return buslogic_pci_bar[2].addr_regs[1] | 0x18; + case 0x32: + return buslogic_pci_bar[2].addr_regs[2]; + case 0x33: + return buslogic_pci_bar[2].addr_regs[3]; + case 0x3C: + return bl->Irq; + case 0x3D: + return 1; + } + + return(0); +} + + +static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) +{ + Buslogic_t *bl = (Buslogic_t *)p; + + switch (addr) { + case 0x04: + io_removehandler(bl->PCIBase, 4, + BuslogicRead, BuslogicReadW, BuslogicReadL, + BuslogicWrite, BuslogicWriteW, BuslogicWriteL, + bl); + mem_mapping_disable(&bl->mmio_mapping); + if (val & PCI_COMMAND_IO) { + if (bl->PCIBase != 0) { + io_sethandler(bl->PCIBase, 0x0020, + BuslogicRead, BuslogicReadW, + BuslogicReadL, BuslogicWrite, + BuslogicWriteW, BuslogicWriteL, + bl); + } + } + if (val & PCI_COMMAND_MEM) { + if (bl->PCIBase != 0) { + mem_mapping_set_addr(&bl->mmio_mapping, + bl->MMIOBase, 0x20); + } + } + buslogic_pci_regs[addr] = val; + break; + + case 0x10: + val &= 0xe0; + val |= 1; + + case 0x11: case 0x12: case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O. */ + io_removehandler(bl->PCIBase, 0x0020, + BuslogicRead, BuslogicReadW, BuslogicReadL, + BuslogicWrite, BuslogicWriteW, BuslogicWriteL, + bl); + /* Then let's set the PCI regs. */ + buslogic_pci_bar[0].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + bl->PCIBase = buslogic_pci_bar[0].addr & 0xffe0; + /* Log the new base. */ + pclog("BusLogic PCI: New I/O base is %04X\n" , bl->PCIBase); + /* We're done, so get out of the here. */ + if (buslogic_pci_regs[4] & PCI_COMMAND_IO) { + if (bl->PCIBase != 0) { + io_sethandler(bl->PCIBase, 0x0020, + BuslogicRead, BuslogicReadW, + BuslogicReadL, BuslogicWrite, + BuslogicWriteW, BuslogicWriteL, + bl); + } + } + return; + + case 0x14: + val &= 0xe0; + + case 0x15: case 0x16: case 0x17: + /* I/O Base set. */ + /* First, remove the old I/O. */ + mem_mapping_disable(&bl->mmio_mapping); + /* Then let's set the PCI regs. */ + buslogic_pci_bar[1].addr_regs[addr & 3] = val; + /* Then let's calculate the new I/O base. */ + bl->MMIOBase = buslogic_pci_bar[1].addr & 0xffffffe0; + /* Log the new base. */ + pclog("BusLogic PCI: New MMIO base is %04X\n" , bl->MMIOBase); + /* We're done, so get out of the here. */ + if (buslogic_pci_regs[4] & PCI_COMMAND_MEM) { + if (bl->PCIBase != 0) { + mem_mapping_set_addr(&bl->mmio_mapping, + bl->MMIOBase, 0x20); + } + } + return; + +#if 0 + /* Commented out until an APIC controller is emulated for the PIIX3, + * otherwise the BT-958 will not get an IRQ on boards using the PIIX3. + */ + case 0x3C: + buslogic_pci_regs[addr] = val; + if (val != 0xFF) { + buslogic_log("BusLogic IRQ now: %i\n", val); + bl->Irq = val; + } + return; +#endif + } +} + + +void *AdaptecInit(int has_bios, int chip) +{ + Buslogic_t *bl; + int i = 0; + int j = 0; + uint32_t bios_addr = 0; + int bios = 0; + + bl = malloc(sizeof(Buslogic_t)); + memset(bl, 0x00, sizeof(Buslogic_t)); + + BuslogicResetDevice = bl; + bl->chip = chip; + bl->Base = device_get_config_int("addr"); + bl->PCIBase = 0; + bl->MMIOBase = 0; + bl->Irq = device_get_config_int("irq"); + bl->DmaChannel = device_get_config_int("dma"); + bios = device_get_config_int("bios"); + bios_addr = device_get_config_int("bios_addr"); + + if (bl->Base != 0) { + io_sethandler(bl->Base, 4, + BuslogicRead, BuslogicReadW, NULL, + BuslogicWrite, BuslogicWriteW, NULL, bl); + } + + pclog("Building SCSI hard disk map...\n"); + build_scsi_hd_map(); + pclog("Building SCSI CD-ROM map...\n"); + build_scsi_cdrom_map(); + + for (i=0; i<16; i++) { + for (j=0; j<8; j++) + { + if (scsi_hard_disks[i][j] != 0xff) + { + SCSIDevices[i][j].LunType = SCSI_HDD; + } + } + } + + for (i=0; iBase); + + BuslogicResetControl(bl, CTRL_HRST); + + if (bios) { + /* Perform AHA-154xNN-specific initialization. */ + aha154x_init(bl->Base, bios_addr, &bl->aha); + } + + return(bl); +} + +void *AHA_154xB_Init() +{ + return AdaptecInit(0, CHIP_AHA154XB); +} + +void *AHA_154xCF_Init() +{ + return AdaptecInit(1, CHIP_AHA154XCF); +} + + +void *BuslogicInit(int chip) +{ + Buslogic_t *bl; + + int i = 0; + int j = 0; + + bl = malloc(sizeof(Buslogic_t)); + memset(bl, 0x00, sizeof(Buslogic_t)); + + BuslogicResetDevice = bl; + if (!PCI && (chip == CHIP_BUSLOGIC_PCI)) + { + chip = CHIP_BUSLOGIC_ISA; + } + bl->chip = chip; + bl->Base = device_get_config_int("addr"); + bl->PCIBase = 0; + bl->MMIOBase = 0; + bl->Irq = device_get_config_int("irq"); + bl->DmaChannel = device_get_config_int("dma"); + + if (bl->Base != 0) { + if (bl->chip == CHIP_BUSLOGIC_PCI) { + io_sethandler(bl->Base, 4, + BuslogicRead, BuslogicReadW, BuslogicReadL, + BuslogicWrite, BuslogicWriteW, BuslogicWriteL, + bl); + } else { + io_sethandler(bl->Base, 4, + BuslogicRead, BuslogicReadW, NULL, + BuslogicWrite, BuslogicWriteW, NULL, bl); + } + } + + pclog("Building SCSI hard disk map...\n"); + build_scsi_hd_map(); + pclog("Building SCSI CD-ROM map...\n"); + build_scsi_cdrom_map(); + + for (i=0; i<16; i++) { + for (j=0; j<8; j++) + { + if (scsi_hard_disks[i][j] != 0xff) + { + SCSIDevices[i][j].LunType = SCSI_HDD; + } + } + } + + for (i=0; ichip == CHIP_BUSLOGIC_PCI) { + pci_add(BuslogicPCIRead, BuslogicPCIWrite, bl); + + buslogic_pci_bar[0].addr_regs[0] = 1; + buslogic_pci_bar[1].addr_regs[0] = 0; + buslogic_pci_regs[0x04] = 1; + buslogic_pci_regs[0x05] = 0; + buslogic_pci_regs[0x07] = 2; + buslogic_pci_bar[2].addr = 0; + + mem_mapping_add(&bl->mmio_mapping, 0xfffd0000, 0x20, + mem_read_null, mem_read_nullw, mem_read_nulll, + mem_write_null, mem_write_nullw, mem_write_nulll, + NULL, MEM_MAPPING_EXTERNAL, bl); + mem_mapping_disable(&bl->mmio_mapping); + } + + pclog("Buslogic on port 0x%04X\n", bl->Base); + + BuslogicResetControl(bl, CTRL_HRST); + + return(bl); +} + +void *Buslogic_542B_Init() +{ + return BuslogicInit(CHIP_BUSLOGIC_ISA); +} + +void *Buslogic_958D_Init() +{ + return BuslogicInit(CHIP_BUSLOGIC_PCI); +} + + +void BuslogicClose(void *p) +{ + Buslogic_t *bl = (Buslogic_t *)p; + free(bl); + BuslogicResetDevice = NULL; +} + + +static device_config_t AHA154XCF_Config[] = +{ + { + "addr", "Address", CONFIG_SELECTION, "", 0x334, + { + { + "None", 0 + }, + { + "0x330", 0x330 + }, + { + "0x334", 0x334 + }, + { + "0x230", 0x230 + }, + { + "0x234", 0x234 + }, + { + "0x130", 0x130 + }, + { + "0x134", 0x134 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, + { + { + "DMA 5", 5 + }, + { + "DMA 6", 6 + }, + { + "DMA 7", 7 + }, + { + "" + } + }, + }, + { + "bios", "Enable BIOS", CONFIG_BINARY, 0 + }, + { + "bios_addr", "BIOS Address", CONFIG_SELECTION, "", 0xd8000, + { + { + "C800H", 0xc8000 + }, + { + "D000H", 0xd0000 + }, + { + "D800H", 0xd8000 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + +static device_config_t BuslogicConfig[] = +{ + { + "addr", "Address", CONFIG_SELECTION, "", 0x334, + { + { + "None", 0 + }, + { + "0x330", 0x330 + }, + { + "0x334", 0x334 + }, + { + "0x230", 0x230 + }, + { + "0x234", 0x234 + }, + { + "0x130", 0x130 + }, + { + "0x134", 0x134 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, + { + { + "DMA 5", 5 + }, + { + "DMA 6", 6 + }, + { + "DMA 7", 7 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + +device_t aha1540b_device = +{ + "Adaptec AHA-1540B", + 0, + AHA_154xB_Init, + BuslogicClose, + NULL, + NULL, + NULL, + NULL, + BuslogicConfig +}; + +device_t aha1542cf_device = +{ + "Adaptec AHA-1542CF", + 0, + AHA_154xCF_Init, + BuslogicClose, + NULL, + NULL, + NULL, + NULL, + AHA154XCF_Config +}; + +device_t buslogic_device = +{ + "Buslogic BT-542B PCI", + 0, + Buslogic_542B_Init, + BuslogicClose, + NULL, + NULL, + NULL, + NULL, + BuslogicConfig +}; + +device_t buslogic_pci_device = +{ + "Buslogic BT-542B PCI", + 0, + Buslogic_958D_Init, + BuslogicClose, + NULL, + NULL, + NULL, + NULL, + BuslogicConfig +}; diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h new file mode 100644 index 000000000..c4b6805f0 --- /dev/null +++ b/src/scsi_buslogic.h @@ -0,0 +1,27 @@ +#ifndef BUSLOGIC_H +# define BUSLOGIC_H + + +typedef struct { + uint8_t flags; /* local flags */ + uint8_t bid; /* board ID */ + char fwl, fwh; /* firmware info */ +} aha_info; +#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ + + +extern device_t aha1540b_device; +extern device_t aha1542cf_device; +extern device_t buslogic_device; +extern device_t buslogic_pci_device; + + +extern int buslogic_dev_present(uint8_t id, uint8_t lun); + +extern void aha154x_init(uint16_t, uint32_t, aha_info *); +extern uint8_t aha154x_shram(uint8_t); +extern uint8_t aha154x_eeprom(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t *); +extern uint8_t aha154x_memory(uint8_t); + + +#endif /*BUSLOGIC_H*/ diff --git a/src/scsi_hd.c b/src/scsi_hd.c new file mode 100644 index 000000000..1f2bd2788 --- /dev/null +++ b/src/scsi_hd.c @@ -0,0 +1,1164 @@ +/* SCSI hard disk emulation */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "86box.h" +#include "cdrom.h" +#include "ibm.h" +#include "ide.h" +#include "piix.h" +#include "scsi.h" +#include "timer.h" + +/* Bits of 'status' */ +#define ERR_STAT 0x01 +#define DRQ_STAT 0x08 /* Data request */ +#define DSC_STAT 0x10 +#define SERVICE_STAT 0x10 +#define READY_STAT 0x40 +#define BUSY_STAT 0x80 + +/* Bits of 'error' */ +#define ABRT_ERR 0x04 /* Command aborted */ +#define MCR_ERR 0x08 /* Media change request */ + +#define MAX_BLOCKS_AT_ONCE 340 + +#define scsi_hd_sense_error shdc[id].sense[0] +#define scsi_hd_sense_key shdc[id].sense[2] +#define scsi_hd_asc shdc[id].sense[12] +#define scsi_hd_ascq shdc[id].sense[13] + +uint8_t scsi_hard_disks[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } }; + +/* Table of all SCSI commands and their flags, needed for the new disc change / not ready handler. */ +uint8_t scsi_hd_command_flags[0x100] = +{ + IMPLEMENTED | CHECK_READY | NONDATA, /* 0x00 */ + IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ + 0, + IMPLEMENTED | ALLOW_UA, /* 0x03 */ + 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, /* 0x08 */ + 0, + IMPLEMENTED | CHECK_READY, /* 0x0A */ + 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | ALLOW_UA, /* 0x12 */ + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, /* 0x1E */ + 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, /* 0x25 */ + 0, 0, + IMPLEMENTED | CHECK_READY, /* 0x28 */ + 0, + IMPLEMENTED | CHECK_READY, /* 0x2A */ + 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x2F */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, /* 0xA8 */ + 0, + IMPLEMENTED | CHECK_READY, /* 0xAA */ + 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0xAF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED, /* 0xBD */ + 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +int scsi_hd_do_log = 0; + +void scsi_hd_log(const char *format, ...) +{ +#ifdef ENABLE_scsi_hd_LOG + if (scsi_hd_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +/* Translates ATAPI status (ERR_STAT flag) to SCSI status. */ +int scsi_hd_err_stat_to_scsi(uint8_t id) +{ + if (shdc[id].status & ERR_STAT) + { + return SCSI_STATUS_CHECK_CONDITION; + } + else + { + return SCSI_STATUS_OK; + } + + return SCSI_STATUS_OK; +} + +/* Translates ATAPI phase (DRQ, I/O, C/D) to SCSI phase (MSG, C/D, I/O). */ +int scsi_hd_phase_to_scsi(uint8_t id) +{ + if (shdc[id].status & 8) + { + switch (shdc[id].phase & 3) + { + case 0: + return 0; + case 1: + return 2; + case 2: + return 1; + case 3: + return 7; + } + } + else + { + if ((shdc[id].phase & 3) == 3) + { + return 3; + } + else + { + /* Translate reserved ATAPI phase to reserved SCSI phase. */ + return 4; + } + } + + return 0; +} + +int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) +{ + uint8_t i = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if ((hdc[i].bus == 3) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) + { + return i; + } + } + return 0xff; +} + +static void scsi_loadhd(int scsi_id, int scsi_lun, int id) +{ + uint32_t sector_size = 512; + uint32_t zero = 0; + uint64_t signature = 0xD778A82044445459ll; + uint64_t full_size = 0; + int c; + char *fn = hdd_fn[id]; + + shdc[id].base = 0; + + if (shdf[id] != NULL) + { + fclose(shdf[id]); + shdf[id] == NULL; + } + + /* Try to open existing hard disk image */ + if (fn[0] == '.') + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + return; + } + shdf[id] = fopen64(fn, "rb+"); + if (shdf[id] == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + shdf[id] = fopen64(fn, "wb+"); + if (shdf[id] == NULL) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + return; + } + else + { + memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); + if (image_is_hdi(fn)) + { + shdc[id].base = 0x1000; + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&(shdc[id].base), 1, 4, shdf[id]); + fwrite(&full_size, 1, 4, shdf[id]); + fwrite(§or_size, 1, 4, shdf[id]); + fwrite(&(hdc[id].spt), 1, 4, shdf[id]); + fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); + fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); + for (c = 0; c < 0x3f8; c++) + { + fwrite(&zero, 1, 4, shdf[id]); + } + } + else if (image_is_hdx(fn, 0)) + { + shdc[id].base = 0x28; + fwrite(&signature, 1, 8, shdf[id]); + fwrite(&full_size, 1, 8, shdf[id]); + fwrite(§or_size, 1, 4, shdf[id]); + fwrite(&(hdc[id].spt), 1, 4, shdf[id]); + fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); + fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + } + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + shdc[id].cdb_len = 12; + } + } + else + { + /* Failed for another reason */ + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + return; + } + } + else + { + memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); + if (image_is_hdi(fn)) + { + fseeko64(shdf[id], 0x8, SEEK_SET); + fread(&(shdc[id].base), 1, 4, shdf[id]); + fseeko64(shdf[id], 0x10, SEEK_SET); + fread(§or_size, 1, 4, shdf[id]); + if (sector_size != 512) + { + /* Sector size is not 512 */ + fclose(shdf[id]); + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + return; + } + fread(&(hdc[id].spt), 1, 4, shdf[id]); + fread(&(hdc[id].hpc), 1, 4, shdf[id]); + fread(&(hdc[id].tracks), 1, 4, shdf[id]); + } + else if (image_is_hdx(fn, 1)) + { + shdc[id].base = 0x28; + fseeko64(shdf[id], 0x10, SEEK_SET); + fread(§or_size, 1, 4, shdf[id]); + if (sector_size != 512) + { + /* Sector size is not 512 */ + fclose(shdf[id]); + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + return; + } + fread(&(hdc[id].spt), 1, 4, shdf[id]); + fread(&(hdc[id].hpc), 1, 4, shdf[id]); + fread(&(hdc[id].tracks), 1, 4, shdf[id]); + fread(&(hdc[id].at_spt), 1, 4, shdf[id]); + fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); + } + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + shdc[id].cdb_len = 12; + } +} + +void build_scsi_hd_map() +{ + uint8_t i = 0; + uint8_t j = 0; + + for (i = 0; i < 16; i++) + { + memset(scsi_hard_disks[i], 0xff, 8); + } + + for (i = 0; i < 16; i++) + { + for (j = 0; j < 8; j++) + { + scsi_hard_disks[i][j] = find_hdc_for_scsi_id(i, j); + if (scsi_hard_disks[i][j] != 0xff) + { + scsi_loadhd(i, j, scsi_hard_disks[i][j]); + } + } + } +} + +int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) +{ + int ret = 0; + int size = 0; + + size = shdc[id].last_sector; + memset(buffer, 0, 8); + buffer[0] = (size >> 24) & 0xff; + buffer[1] = (size >> 16) & 0xff; + buffer[2] = (size >> 8) & 0xff; + buffer[3] = size & 0xff; + buffer[6] = 2; /* 512 = 0x0200 */ + *len = 8; + + return 1; +} + +void scsi_hd_set_cdb_len(int id, int cdb_len) +{ + shdc[id].cdb_len = cdb_len; +} + +void scsi_hd_reset_cdb_len(int id) +{ + shdc[id].cdb_len = 12; +} + +void scsi_hd_update_request_length(uint8_t id, int len, int block_len) +{ + /* For media access commands, make sure the requested DRQ length matches the block length. */ + switch (shdc[id].current_cdb[0]) + { + case 0x08: + case 0x0a: + case 0x28: + case 0x2a: + case 0xa8: + case 0xaa: + if (shdc[id].request_length < block_len) + { + shdc[id].request_length = block_len; + } + /* Make sure we respect the limit of how many blocks we can transfer at once. */ + if (shdc[id].requested_blocks > shdc[id].max_blocks_at_once) + { + shdc[id].requested_blocks = shdc[id].max_blocks_at_once; + } + shdc[id].block_total = (shdc[id].requested_blocks * block_len); + if (len > shdc[id].block_total) + { + len = shdc[id].block_total; + } + break; + default: + shdc[id].packet_len = len; + break; + } + /* If the DRQ length is odd, and the total remaining length is bigger, make sure it's even. */ + if ((shdc[id].request_length & 1) && (shdc[id].request_length < len)) + { + shdc[id].request_length &= 0xfffe; + } + /* If the DRQ length is smaller or equal in size to the total remaining length, set it to that. */ + if (len <= shdc[id].request_length) + { + shdc[id].request_length = len; + } + return; +} + +static void scsi_hd_command_common(uint8_t id) +{ + shdc[id].status = BUSY_STAT; + shdc[id].phase = 1; + shdc[id].pos = 0; + if (shdc[id].packet_status == CDROM_PHASE_COMPLETE) + { + shdc[id].callback = 20 * SCSI_TIME; + } + else + { + shdc[id].callback = 60 * SCSI_TIME; + } +} + +static void scsi_hd_command_complete(uint8_t id) +{ + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + scsi_hd_command_common(id); +} + +static void scsi_hd_command_read_dma(uint8_t id) +{ + shdc[id].packet_status = CDROM_PHASE_DATA_IN_DMA; + scsi_hd_command_common(id); + shdc[id].total_read = 0; +} + +static void scsi_hd_command_write_dma(uint8_t id) +{ + shdc[id].packet_status = CDROM_PHASE_DATA_OUT_DMA; + scsi_hd_command_common(id); +} + +static void scsi_hd_data_command_finish(uint8_t id, int len, int block_len, int alloc_len, int direction) +{ + scsi_hd_log("SCSI HD %i: Finishing command (%02X): %i, %i, %i, %i, %i\n", id, shdc[id].current_cdb[0], len, block_len, alloc_len, direction, shdc[id].request_length); + shdc[id].pos=0; + if (alloc_len >= 0) + { + if (alloc_len < len) + { + len = alloc_len; + } + } + if (len == 0) + { + SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength = 0; + scsi_hd_command_complete(id); + } + else + { + if (direction == 0) + { + SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength = alloc_len; + scsi_hd_command_read_dma(id); + } + else + { + scsi_hd_command_write_dma(id); + } + } + + scsi_hd_log("SCSI HD %i: Status: %i, cylinder %i, packet length: %i, position: %i, phase: %i\n", id, shdc[id].packet_status, shdc[id].request_length, shdc[id].packet_len, shdc[id].pos, shdc[id].phase); +} + +static void scsi_hd_sense_clear(int id, int command) +{ + shdc[id].previous_command = command; + scsi_hd_sense_key = scsi_hd_asc = scsi_hd_ascq = 0; +} + +static void scsi_hd_cmd_error(uint8_t id) +{ + shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; + shdc[id].status = READY_STAT | ERR_STAT; + shdc[id].phase = 3; + shdc[id].packet_status = 0x80; + shdc[id].callback = 50 * SCSI_TIME; + scsi_hd_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", id, scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq); +} + +static void scsi_hd_invalid_lun(uint8_t id) +{ + scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_hd_asc = ASC_INV_LUN; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + +static void scsi_hd_illegal_opcode(uint8_t id) +{ + scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_hd_asc = ASC_ILLEGAL_OPCODE; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + +static void scsi_hd_lba_out_of_range(uint8_t id) +{ + scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_hd_asc = ASC_LBA_OUT_OF_RANGE; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + +static void scsi_hd_invalid_field(uint8_t id) +{ + scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_hd_asc = ASC_INV_FIELD_IN_CMD_PACKET; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); + shdc[id].status = 0x53; +} + +static void scsi_hd_data_phase_error(uint8_t id) +{ + scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; + scsi_hd_asc = ASC_DATA_PHASE_ERROR; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + +void scsi_hd_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) +{ + switch(cdb[0]) + { + case GPCMD_READ_6: + case GPCMD_WRITE_6: + cdb[1] = (lba_pos >> 16) & 0xff; + cdb[2] = (lba_pos >> 8) & 0xff; + cdb[3] = lba_pos & 0xff; + break; + + case GPCMD_READ_10: + case GPCMD_WRITE_10: + cdb[2] = (lba_pos >> 24) & 0xff; + cdb[3] = (lba_pos >> 16) & 0xff; + cdb[4] = (lba_pos >> 8) & 0xff; + cdb[5] = lba_pos & 0xff; + cdb[7] = (number_of_blocks >> 8) & 0xff; + cdb[8] = number_of_blocks & 0xff; + break; + + case GPCMD_READ_12: + case GPCMD_WRITE_12: + cdb[2] = (lba_pos >> 24) & 0xff; + cdb[3] = (lba_pos >> 16) & 0xff; + cdb[4] = (lba_pos >> 8) & 0xff; + cdb[5] = lba_pos & 0xff; + cdb[6] = (number_of_blocks >> 24) & 0xff; + cdb[7] = (number_of_blocks >> 16) & 0xff; + cdb[8] = (number_of_blocks >> 8) & 0xff; + cdb[9] = number_of_blocks & 0xff; + break; + } +} + +int scsi_hd_read_data(uint8_t id, uint32_t *len) +{ + uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; + + int temp_len = 0; + + int last_valid_data_pos = 0; + + uint64_t pos64 = (uint64_t) shdc[id].sector_pos; + + if (shdc[id].sector_pos > shdc[id].last_sector) + { + /* scsi_hd_log("SCSI HD %i: Trying to read beyond the end of disk\n", id); */ + scsi_hd_lba_out_of_range(id); + return 0; + } + + shdc[id].old_len = 0; + *len = 0; + + fseeko64(shdf[id], pos64 << 9, SEEK_SET); + fread(hdbufferb + shdc[id].data_pos, (shdc[id].sector_len << 9), 1, shdf[id]); + temp_len = (shdc[id].sector_len << 9); + + last_valid_data_pos = shdc[id].data_pos; + + shdc[id].data_pos += temp_len; + shdc[id].old_len += temp_len; + + *len += temp_len; + + scsi_hd_log("SCSI HD %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, hdbufferb[last_valid_data_pos + 0], hdbufferb[last_valid_data_pos + 1], hdbufferb[last_valid_data_pos + 2], hdbufferb[last_valid_data_pos + 3], hdbufferb[last_valid_data_pos + 4], hdbufferb[last_valid_data_pos + 5], hdbufferb[last_valid_data_pos + 6], hdbufferb[last_valid_data_pos + 7]); + + return 1; +} + +int scsi_hd_read_blocks(uint8_t id, uint32_t *len, int first_batch) +{ + int ret = 0; + + shdc[id].data_pos = 0; + + if (!shdc[id].sector_len) + { + scsi_hd_command_complete(id); + return -1; + } + + scsi_hd_log("Reading %i blocks starting from %i...\n", shdc[id].requested_blocks, shdc[id].sector_pos); + + scsi_hd_update_cdb(shdc[id].current_cdb, shdc[id].sector_pos, shdc[id].requested_blocks); + + ret = scsi_hd_read_data(id, len); + + scsi_hd_log("Read %i bytes of blocks...\n", *len); + + if (!ret) + { + return 0; + } + + shdc[id].sector_pos += shdc[id].requested_blocks; + shdc[id].sector_len -= shdc[id].requested_blocks; + + return 1; +} + +/*SCSI Sense Initialization*/ +void scsi_hd_sense_code_ok(uint8_t id) +{ + scsi_hd_sense_key = SENSE_NONE; + scsi_hd_asc = 0; + scsi_hd_ascq = 0; +} + +int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) +{ + if (((shdc[id].request_length >> 5) & 7) != hdc[id].scsi_lun) + { + scsi_hd_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((shdc[id].request_length >> 5) & 7)); + scsi_hd_invalid_lun(id); + return 0; + } + + if (!(scsi_hd_command_flags[cdb[0]] & IMPLEMENTED)) + { + scsi_hd_log("SCSI HD %i: Attempting to execute unknown command %02X\n", id, cdb[0]); + scsi_hd_illegal_opcode(id); + return 0; + } + + /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* + the UNIT ATTENTION condition if it's set. */ + if (cdb[0] != GPCMD_REQUEST_SENSE) + { + scsi_hd_sense_clear(id, cdb[0]); + } + + scsi_hd_log("SCSI HD %i: Continuing with command\n", id); + + return 1; +} + +static void scsi_hd_seek(uint8_t id, uint32_t pos) +{ + /* scsi_hd_log("SCSI HD %i: Seek %08X\n", id, pos); */ + shdc[id].seek_pos = pos; +} + +static void scsi_hd_rezero(uint8_t id) +{ + shdc[id].sector_pos = shdc[id].sector_len = 0; + scsi_hd_seek(id, 0); +} + +void scsi_hd_reset(uint8_t id) +{ + scsi_hd_rezero(id); + shdc[id].status = 0; + shdc[id].callback = 0; + shdc[id].packet_status = 0xff; +} + +void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +{ + /*Will return 18 bytes of 0*/ + if (alloc_length != 0) + { + memset(buffer, 0, alloc_length); + memcpy(buffer, shdc[id].sense, alloc_length); + } + + buffer[0] = 0x70; + + /* scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, hdbufferb[2], hdbufferb[12], hdbufferb[13]); */ + + /* Clear the sense stuff as per the spec. */ + scsi_hd_sense_clear(id, GPCMD_REQUEST_SENSE); +} + +void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) +{ + /* Do *NOT* advance the unit attention phase. */ + + scsi_hd_request_sense(id, buffer, alloc_length); +} + +int scsi_hd_read_from_dma(uint8_t id); + +void scsi_hd_command(uint8_t id, uint8_t *cdb) +{ + uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; + uint32_t len; + int pos=0; + int max_len; + unsigned idx = 0; + unsigned size_idx; + unsigned preamble_len; + uint32_t alloc_length; + int ret; + uint64_t pos64; + char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; + char device_identify_ex[14] = { '8', '6', 'B', '_', 'H', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + +#if 0 + int CdbLength; +#endif + shdc[id].status &= ~ERR_STAT; + + shdc[id].packet_len = 0; + shdc[id].request_pos = 0; + + device_identify[6] = id + 0x30; + + device_identify_ex[6] = id + 0x30; + device_identify_ex[9] = emulator_version[0]; + device_identify_ex[11] = emulator_version[2]; + device_identify_ex[12] = emulator_version[3]; + + shdc[id].data_pos = 0; + + memcpy(shdc[id].current_cdb, cdb, shdc[id].cdb_len); + + if (cdb[0] != 0) + { + scsi_hd_log("SCSI HD %i: Command 0x%02X, Sense Key %02X, Asc %02X, Ascq %02X, %i\n", id, cdb[0], scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq, ins); + scsi_hd_log("SCSI HD %i: Request length: %04X\n", id, shdc[id].request_length); + +#if 0 + for (CdbLength = 1; CdbLength < shdc[id].cdb_len; CdbLength++) + { + scsi_hd_log("SCSI HD %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); + } +#endif + } + + shdc[id].sector_len = 0; + + /* This handles the Not Ready/Unit Attention check if it has to be handled at this point. */ + if (scsi_hd_pre_execution_check(id, cdb) == 0) + { + return; + } + + switch (cdb[0]) + { + case GPCMD_TEST_UNIT_READY: + case GPCMD_VERIFY_6: + case GPCMD_VERIFY_10: + case GPCMD_VERIFY_12: + scsi_hd_command_complete(id); + break; + + case GPCMD_REZERO_UNIT: + shdc[id].sector_pos = shdc[id].sector_len = 0; + scsi_hd_seek(id, 0); + break; + + case GPCMD_REQUEST_SENSE: + /* If there's a unit attention condition and there's a buffered not ready, a standalone REQUEST SENSE + should forget about the not ready, and report unit attention straight away. */ + scsi_hd_request_sense(id, hdbufferb, cdb[4]); + scsi_hd_data_command_finish(id, 18, 18, cdb[4], 0); + break; + + case GPCMD_MECHANISM_STATUS: + len = (hdbufferb[7] << 16) | (hdbufferb[8] << 8) | hdbufferb[9]; + + memset(hdbufferb, 0, 8); + hdbufferb[5] = 1; + + scsi_hd_data_command_finish(id, 8, 8, len, 0); + break; + + case GPCMD_READ_6: + case GPCMD_READ_10: + case GPCMD_READ_12: + switch(cdb[0]) + { + case GPCMD_READ_6: + shdc[id].sector_len = cdb[4]; + shdc[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + break; + case GPCMD_READ_10: + shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; + shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); + break; + case GPCMD_READ_12: + shdc[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + shdc[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } + + if (!shdc[id].sector_len) + { + /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + shdc[id].callback = 20 * SCSI_TIME; + break; + } + + max_len = shdc[id].sector_len; + shdc[id].requested_blocks = max_len; + +#if 0 + ret = scsi_hd_read_blocks(id, &alloc_length, 1); + if (ret <= 0) + { + return; + } +#endif + + pos64 = (uint64_t) shdc[id].sector_pos; + + if (shdc[id].requested_blocks > 0) + { + fseeko64(shdf[id], pos64 << 9, SEEK_SET); + fread(hdbufferb, (shdc[id].sector_len << 9), 1, shdf[id]); + } + + alloc_length = shdc[id].packet_len = max_len << 9; + if (shdc[id].requested_blocks > 1) + { + scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 0); + } + else + { + scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 0); + } + shdc[id].all_blocks_total = shdc[id].block_total; + if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) + { + update_status_bar_icon(0x22, 1); + } + else + { + update_status_bar_icon(0x22, 0); + } + return; + + case GPCMD_WRITE_6: + case GPCMD_WRITE_10: + case GPCMD_WRITE_12: + switch(cdb[0]) + { + case GPCMD_WRITE_6: + shdc[id].sector_len = cdb[4]; + shdc[id].sector_pos = ((((uint32_t) cdb[1]) & 0x1f) << 16) | (((uint32_t) cdb[2]) << 8) | ((uint32_t) cdb[3]); + break; + case GPCMD_WRITE_10: + shdc[id].sector_len = (cdb[7] << 8) | cdb[8]; + shdc[id].sector_pos = (cdb[2] << 24) | (cdb[3] << 16) | (cdb[4] << 8) | cdb[5]; + scsi_hd_log("SCSI HD %i: Length: %i, LBA: %i\n", id, shdc[id].sector_len, shdc[id].sector_pos); + break; + case GPCMD_WRITE_12: + shdc[id].sector_len = (((uint32_t) cdb[6]) << 24) | (((uint32_t) cdb[7]) << 16) | (((uint32_t) cdb[8]) << 8) | ((uint32_t) cdb[9]); + shdc[id].sector_pos = (((uint32_t) cdb[2]) << 24) | (((uint32_t) cdb[3]) << 16) | (((uint32_t) cdb[4]) << 8) | ((uint32_t) cdb[5]); + break; + } + + if (!shdc[id].sector_len) + { + /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + shdc[id].callback = 20 * SCSI_TIME; + break; + } + + max_len = shdc[id].sector_len; + shdc[id].requested_blocks = max_len; + + scsi_hd_read_from_dma(id); + + pos64 = (uint64_t) shdc[id].sector_pos; + + if (shdc[id].requested_blocks > 0) + { + fseeko64(shdf[id], pos64 << 9, SEEK_SET); + fwrite(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + } + + alloc_length = shdc[id].packet_len = max_len << 9; + if (shdc[id].requested_blocks > 1) + { + scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); + } + else + { + scsi_hd_data_command_finish(id, alloc_length, alloc_length, alloc_length, 1); + } + shdc[id].all_blocks_total = shdc[id].block_total; + if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) + { + update_status_bar_icon(0x22, 1); + } + else + { + update_status_bar_icon(0x22, 0); + } + return; + + case GPCMD_INQUIRY: + max_len = cdb[3]; + max_len <<= 8; + max_len |= cdb[4]; + + if (cdb[1] & 1) + { + preamble_len = 4; + size_idx = 3; + + hdbufferb[idx++] = 05; + hdbufferb[idx++] = cdb[2]; + hdbufferb[idx++] = 0; + + idx++; + + switch (cdb[2]) + { + case 0x00: + hdbufferb[idx++] = 0x00; + hdbufferb[idx++] = 0x83; + break; + case 0x83: + if (idx + 24 > max_len) + { + scsi_hd_data_phase_error(id); + return; + } + + hdbufferb[idx++] = 0x02; + hdbufferb[idx++] = 0x00; + hdbufferb[idx++] = 0x00; + hdbufferb[idx++] = 20; + ide_padstr8(hdbufferb + idx, 20, "53R141"); /* Serial */ + idx += 20; + + if (idx + 72 > cdb[4]) + { + goto atapi_out; + } + hdbufferb[idx++] = 0x02; + hdbufferb[idx++] = 0x01; + hdbufferb[idx++] = 0x00; + hdbufferb[idx++] = 68; + ide_padstr8(hdbufferb + idx, 8, "86Box"); /* Vendor */ + idx += 8; + ide_padstr8(hdbufferb + idx, 40, device_identify_ex); /* Product */ + idx += 40; + ide_padstr8(hdbufferb + idx, 20, "53R141"); /* Product */ + idx += 20; + break; + default: + scsi_hd_log("INQUIRY: Invalid page: %02X\n", cdb[2]); + scsi_hd_invalid_field(id); + return; + } + } + else + { + preamble_len = 5; + size_idx = 4; + + memset(hdbufferb, 0, 8); + hdbufferb[0] = 0; /*SCSI HD*/ + hdbufferb[1] = 0; /*Fixed*/ + hdbufferb[2] = 0x02; /*SCSI-2 compliant*/ + hdbufferb[3] = 0x02; + hdbufferb[4] = 31; + + ide_padstr8(hdbufferb + 8, 8, "86Box"); /* Vendor */ + ide_padstr8(hdbufferb + 16, 16, device_identify); /* Product */ + ide_padstr8(hdbufferb + 32, 4, emulator_version); /* Revision */ + idx = 36; + } + +atapi_out: + hdbufferb[size_idx] = idx - preamble_len; + len=idx; + + scsi_hd_data_command_finish(id, len, len, max_len, 0); + break; + + case GPCMD_PREVENT_REMOVAL: + scsi_hd_command_complete(id); + break; + + case GPCMD_SEEK_6: + case GPCMD_SEEK_10: + switch(cdb[0]) + { + case GPCMD_SEEK_6: + pos = (cdb[2] << 8) | cdb[3]; + break; + case GPCMD_SEEK_10: + pos = (cdb[2] << 24) | (cdb[3]<<16) | (cdb[4]<<8) | cdb[5]; + break; + } + scsi_hd_seek(id, pos); + scsi_hd_command_complete(id); + break; + + case GPCMD_READ_CDROM_CAPACITY: + if (scsi_hd_read_capacity(id, shdc[id].current_cdb, hdbufferb, &len) == 0) + { + return; + } + + scsi_hd_data_command_finish(id, len, len, len, 0); + break; + + default: + scsi_hd_illegal_opcode(id); + break; + } + + /* scsi_hd_log("SCSI HD %i: Phase: %02X, request length: %i\n", shdc[id].phase, shdc[id].request_length); */ +} + +void scsi_hd_callback(uint8_t id); + +int scsi_hd_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +{ + uint8_t *hdbufferb; + + uint8_t id = scsi_hard_disks[scsi_id][scsi_lun]; + + hdbufferb = (uint8_t *) shdc[id].buffer; + + if (id > HDC_NUM) + { + return 0; + } + + scsi_hd_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); + memcpy(hdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSIDevices[scsi_id][scsi_lun].InitLength); + return 1; +} + +int scsi_hd_read_from_dma(uint8_t id) +{ + int ret = 0; + + ret = scsi_hd_read_from_scsi_dma(hdc[id].scsi_id, hdc[id].scsi_lun); + + if (!ret) + { + return 0; + } + + return 0; +} + +int scsi_hd_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) +{ + uint8_t *hdbufferb; + + uint8_t id = scsi_hard_disks[scsi_id][scsi_lun]; + + if (id > HDC_NUM) + { + return 0; + } + + hdbufferb = (uint8_t *) shdc[id].buffer; + + scsi_hd_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); + memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, hdbufferb, SCSIDevices[scsi_id][scsi_lun].InitLength); + scsi_hd_log("SCSI HD %i: Data from HD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7]); + scsi_hd_log("SCSI HD %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); + return 1; +} + +int scsi_hd_write_to_dma(uint8_t id) +{ + int ret = 0; + + ret = scsi_hd_write_to_scsi_dma(hdc[id].scsi_id, hdc[id].scsi_lun); + + if (!ret) + { + return 0; + } + + return 1; +} + +/* If the result is 1, issue an IRQ, otherwise not. */ +void scsi_hd_callback(uint8_t id) +{ + switch(shdc[id].packet_status) + { + case CDROM_PHASE_IDLE: + scsi_hd_log("SCSI HD %i: PHASE_IDLE\n", id); + shdc[id].pos=0; + shdc[id].phase = 1; + shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); + return; + case CDROM_PHASE_COMMAND: + scsi_hd_log("SCSI HD %i: PHASE_COMMAND\n", id); + shdc[id].status = BUSY_STAT | (shdc[id].status &ERR_STAT); + memcpy(shdc[id].hd_cdb, (uint8_t *) shdc[id].buffer, shdc[id].cdb_len); + scsi_hd_command(id, shdc[id].hd_cdb); + return; + case CDROM_PHASE_COMPLETE: + scsi_hd_log("SCSI HD %i: PHASE_COMPLETE\n", id); + shdc[id].status = READY_STAT; + shdc[id].phase = 3; + shdc[id].packet_status = 0xFF; + update_status_bar_icon(0x22, 0); + return; + case CDROM_PHASE_DATA_OUT: + scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); + shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); + shdc[id].phase = 0; + return; + case CDROM_PHASE_DATA_OUT_DMA: + scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", id); + scsi_hd_read_from_dma(id); + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + shdc[id].status = READY_STAT; + shdc[id].phase = 3; + update_status_bar_icon(0x22, 0); + return; + case CDROM_PHASE_DATA_IN: + scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); + shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); + shdc[id].phase = 2; + return; + case CDROM_PHASE_DATA_IN_DMA: + scsi_hd_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", id); + scsi_hd_write_to_dma(id); + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + shdc[id].status = READY_STAT; + shdc[id].phase = 3; + update_status_bar_icon(0x22, 0); + return; + case CDROM_PHASE_ERROR: + scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); + shdc[id].status = READY_STAT | ERR_STAT; + shdc[id].phase = 3; + return; + } +} diff --git a/src/serial.c b/src/serial.c index da41b00f9..4eb78e821 100644 --- a/src/serial.c +++ b/src/serial.c @@ -61,7 +61,6 @@ void serial_update_ints(SERIAL *serial) void serial_write_fifo(SERIAL *serial, uint8_t dat) { -// pclog("serial_write_fifo %02X\n", serial->lsr); serial->fifo[serial->fifo_write] = dat; serial->fifo_write = (serial->fifo_write + 1) & 0xFF; if (!(serial->lsr & 1)) @@ -85,8 +84,6 @@ uint8_t serial_read_fifo(SERIAL *serial) void serial_write(uint16_t addr, uint8_t val, void *p) { SERIAL *serial = (SERIAL *)p; - // pclog("Serial: Write value %02X on port: %04X\n", val, addr); -// pclog("Write serial %03X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr&7) { case 0: @@ -113,6 +110,9 @@ void serial_write(uint16_t addr, uint8_t val, void *p) serial->ier = val & 0xf; serial_update_ints(serial); break; + case 2: + serial->fcr = val; + break; case 3: serial->lcr = val; break; @@ -121,7 +121,6 @@ void serial_write(uint16_t addr, uint8_t val, void *p) { if (serial->rcr_callback) serial->rcr_callback(serial, serial->rcr_callback_p); -// pclog("RCR raised! sending M\n"); } serial->mctrl = val; if (val & 0x10) @@ -170,7 +169,6 @@ uint8_t serial_read(uint16_t addr, void *p) { SERIAL *serial = (SERIAL *)p; uint8_t temp = 0; - // pclog("Read serial %03X %04X(%08X):%04X %i %i ", addr, CS, cs, cpu_state.pc, mousedelay, ins); switch (addr&7) { case 0: @@ -200,6 +198,8 @@ uint8_t serial_read(uint16_t addr, void *p) serial->int_status &= ~SERIAL_INT_TRANSMIT; serial_update_ints(serial); } + if (serial->fcr & 1) + temp |= 0xc0; break; case 3: temp = serial->lcr; @@ -214,7 +214,6 @@ uint8_t serial_read(uint16_t addr, void *p) temp = serial->lsr; if (serial->lsr & 0x1f) serial->lsr &= ~0x1e; -// serial.lsr |= 0x60; serial->int_status &= ~SERIAL_INT_LSR; serial_update_ints(serial); break; @@ -228,8 +227,6 @@ uint8_t serial_read(uint16_t addr, void *p) temp = serial->scratch; break; } -// pclog("%02X\n",temp); - // pclog("Serial: Read value %02X on port: %04X\n", temp, addr); return temp; } @@ -266,7 +263,6 @@ void serial1_set(uint16_t addr, int irq) serial1_remove(); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); serial1.irq = irq; - // pclog("serial1_set(%04X, %02X)\n", addr, irq); serial_addr[0] = addr; serial_irq[0] = irq; } @@ -290,7 +286,6 @@ void serial2_set(uint16_t addr, int irq) serial2_remove(); io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); serial2.irq = irq; - // pclog("serial2_set(%04X, %02X)\n", addr, irq); serial_addr[1] = addr; serial_irq[1] = irq; } diff --git a/src/serial.h b/src/serial.h index 0e5995706..96104068e 100644 --- a/src/serial.h +++ b/src/serial.h @@ -18,6 +18,7 @@ typedef struct uint8_t dat; uint8_t int_status; uint8_t scratch; + uint8_t fcr; int irq; @@ -30,3 +31,5 @@ typedef struct } SERIAL; extern SERIAL serial1, serial2; + +void serial_write_fifo(SERIAL *serial, uint8_t dat); diff --git a/src/serial_bh.c b/src/serial_bh.c new file mode 100644 index 000000000..23ec556e8 --- /dev/null +++ b/src/serial_bh.c @@ -0,0 +1,606 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of host serial port services for Win32. + * + * This code is based on a universal serial port driver for + * Windows and UNIX systems, with support for FTDI and Prolific + * USB ports. Support for these has been removed. + * + * Version: @(#)serial_bh.c 1.0.1 2017/04/14 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#define _WIN32_WINNT 0x0501 +#include +#include +#include +#define BHTTY_C +#include "serial_bh.h" + + +extern void pclog(char *__fmt, ...); + + +/* Set the state of a port. */ +int +bhtty_sstate(BHTTY *pp, void *arg) +{ + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("invalid argument\n"); + return(-1); + } + + if (SetCommState(pp->handle, (DCB *)arg) == FALSE) { + /* Mark an error. */ + pclog("%s: set state: %d\n", pp->name, GetLastError()); + return(-1); + } + + return(0); +} + + +/* Fetch the state of a port. */ +int +bhtty_gstate(BHTTY *pp, void *arg) +{ + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("BHTTY: invalid argument\n"); + return(-1); + } + + if (GetCommState(pp->handle, (DCB *)arg) == FALSE) { + /* Mark an error. */ + pclog("%s: get state: %d\n", pp->name, GetLastError()); + return(-1); + } + + return(0); +} + + +/* Enable or disable RTS/CTS mode (hardware handshaking.) */ +int +bhtty_crtscts(BHTTY *pp, char yesno) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* Get the current mode. */ + if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + + switch(yesno) { + case 0: /* disable CRTSCTS */ + pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ + pp->dcb.fDsrSensitivity = 0; + + pp->dcb.fOutxCtsFlow = 0; /* disable RTS/CTS mode */ + + pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ + pp->dcb.fOutX = 0; + pp->dcb.fInX = 0; + break; + + case 1: /* enable CRTSCTS */ + pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ + pp->dcb.fDsrSensitivity = 0; + + pp->dcb.fOutxCtsFlow = 1; /* enable RTS/CTS mode */ + + pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ + pp->dcb.fOutX = 0; + pp->dcb.fInX = 0; + break; + + default: + pclog("%s: invalid parameter '%d'!\n", pp->name, yesno); + return(-1); + } + + /* Set new mode. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + + return(0); +} + + +/* Set the port parameters. */ +int +bhtty_params(BHTTY *pp, char dbit, char par, char sbit) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* Get the current mode. */ + if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + + /* Set the desired word length. */ + switch((int)dbit) { + case -1: /* no change */ + break; + + case 5: /* FTDI doesnt like these */ + case 6: + case 9: + break; + + case 7: + case 8: + pp->dcb.ByteSize = dbit; + break; + + default: + pclog("%s: invalid parameter '%d'!\n", pp->name, dbit); + return(-1); + } + + /* Set the type of parity encoding. */ + switch((int)par) { + case -1: /* no change */ + case ' ': + break; + + case 0: + case 'N': + pp->dcb.fParity = FALSE; + pp->dcb.Parity = NOPARITY; + break; + + case 1: + case 'O': + pp->dcb.fParity = TRUE; + pp->dcb.Parity = ODDPARITY; + break; + + case 2: + case 'E': + pp->dcb.fParity = TRUE; + pp->dcb.Parity = EVENPARITY; + break; + + case 3: + case 'M': + case 4: + case 'S': + break; + + default: + pclog("%s: invalid parameter '%c'!\n", pp->name, par); + return(-1); + } + + /* Set the number of stop bits. */ + switch((int)sbit) { + case -1: /* no change */ + break; + + case 1: + pp->dcb.StopBits = ONESTOPBIT; + break; + + case 2: + pp->dcb.StopBits = TWOSTOPBITS; + break; + + default: + pclog("%s: invalid parameter '%d'!\n", pp->name, sbit); + return(-1); + } + + /* Set new mode. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + + return(0); +} + + +/* Put a port in transparent ("raw") state. */ +void +bhtty_raw(BHTTY *pp, void *arg) +{ + DCB *dcb = (DCB *)arg; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("invalid parameter\n"); + return; + } + + /* Enable BINARY transparent mode. */ + dcb->fBinary = 1; + dcb->fErrorChar = 0; /* disable Error Replacement */ + dcb->fNull = 0; /* disable NUL stripping */ + + /* Disable the DTR and RTS lines. */ + dcb->fDtrControl = DTR_CONTROL_DISABLE; /* DTR line */ + dcb->fRtsControl = RTS_CONTROL_DISABLE; /* RTS line */ + + /* Disable DSR/DCD handshaking. */ + dcb->fOutxDsrFlow = 0; /* DSR handshaking */ + dcb->fDsrSensitivity = 0; /* DSR Sensitivity */ + + /* Disable RTS/CTS handshaking. */ + dcb->fOutxCtsFlow = 0; /* CTS handshaking */ + + /* Disable XON/XOFF handshaking. */ + dcb->fTXContinueOnXoff = 0; /* continue TX after Xoff */ + dcb->fOutX = 0; /* enable output X-ON/X-OFF */ + dcb->fInX = 0; /* enable input X-ON/X-OFF */ + dcb->XonChar = 0x11; /* ASCII XON */ + dcb->XoffChar = 0x13; /* ASCII XOFF */ + dcb->XonLim = 100; + dcb->XoffLim = 100; + + dcb->fParity = FALSE; + dcb->Parity = NOPARITY; + dcb->StopBits = ONESTOPBIT; + dcb->BaudRate = CBR_1200; +} + + +/* Set the port speed. */ +int +bhtty_speed(BHTTY *pp, long speed) +{ + int i; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* Get the current mode and speed. */ + if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + + /* + * Set speed. + * + * This is not entirely correct, we should use a table + * with DCB_xxx speed values here, but we removed that + * and just hardcode the speed value into DCB. --FvK + */ + pp->dcb.BaudRate = speed; + + /* Set new speed. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + + return(0); +} + + +/* Clean up and flush. */ +int +bhtty_flush(BHTTY *pp) +{ + DWORD dwErrs; + COMSTAT cs; + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* First, clear any errors. */ + (void)ClearCommError(pp->handle, &dwErrs, &cs); + + /* Now flush all buffers. */ + if (PurgeComm(pp->handle, + (PURGE_RXABORT | PURGE_TXABORT | \ + PURGE_RXCLEAR | PURGE_TXCLEAR)) == FALSE) { + pclog("%s: flush: %d\n", pp->name, GetLastError()); + return(-1); + } + + /* Re-clear any errors. */ + if (ClearCommError(pp->handle, &dwErrs, &cs) == FALSE) { + pclog("%s: clear errors: %d\n", pp->name, GetLastError()); + return(-1); + } + + return(0); +} + + +/* Close an open serial port. */ +void +bhtty_close(BHTTY *pp) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("BHTTY: invalid handle\n"); + return; + } + + if (pp->handle != INVALID_HANDLE_VALUE) { + /* Restore the previous port state, if any. */ + (void)bhtty_sstate(pp, &pp->odcb); + + /* Close the port. */ + CloseHandle(pp->handle); + pp->handle = INVALID_HANDLE_VALUE; + } + + /* Release the control block. */ + free(pp); +} + + +/* Open a host serial port for I/O. */ +BHTTY * +bhtty_open(char *port, int tmo) +{ + char buff[64]; + COMMTIMEOUTS to; +#if 0 + COMMCONFIG conf; + DWORD d; +#endif + BHTTY *pp; + int i = 0; + + /* Make sure we can do this. */ + if (port == NULL) { + pclog("invalid argument!\n"); + return(NULL); + } + + /* First things first... create a control block. */ + if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) { + pclog("%s: out of memory!\n", port); + return(NULL); + } + memset(pp, 0x00, sizeof(BHTTY)); + strncpy(pp->name, port, sizeof(pp->name)-1); + + /* Try a regular Win32 serial port. */ + sprintf(buff, "\\\\.\\%s", pp->name); + pp->handle = CreateFile(buff, + (GENERIC_READ|GENERIC_WRITE), + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0); + if (pp->handle == INVALID_HANDLE_VALUE) { + pclog("%s: open port: %d\n", pp->name, GetLastError()); + free(pp); + return(NULL); + } + +#if 0 + /* Set up buffer size of the port. */ + if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { + /* This fails on FTDI-based devices. */ + pclog("%s: set buffers: %d\n", pp->name, GetLastError()); +// CloseHandle(pp->handle); +// free(pp); +// return(NULL); + } + + /* Grab default config for the driver and set it. */ + d = sizeof(COMMCONFIG); + memset(&conf, 0x00, d); + conf.dwSize = d; + if (GetDefaultCommConfig(pp->name, &conf, &d) == TRUE) { + /* Change config here... */ + + /* Set new configuration. */ + if (SetCommConfig(pp->handle, &conf, d) == FALSE) { + /* This fails on FTDI-based devices. */ + pclog("%s: set configuration: %d\n", pp->name, GetLastError()); +// CloseHandle(pp->handle); +// free(pp); +// return(NULL); + } + } +#endif + + /* + * We now have an open port. To allow for clean exit + * of the application, we first retrieve the port's + * current settings, and save these for later. + */ + if (bhtty_gstate(pp, &pp->odcb) < 0) { + (void)bhtty_close(pp); + return(NULL); + } + memcpy(&pp->dcb, &pp->odcb, sizeof(DCB)); + + /* Force the port to BINARY mode. */ + bhtty_raw(pp, &pp->dcb); + + /* Set new state of this port. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) { + (void)bhtty_close(pp); + return(NULL); + } + + /* Just to make sure.. disable RTS/CTS mode. */ + (void)bhtty_crtscts(pp, 0); + + /* Set new timeout values. */ + if (GetCommTimeouts(pp->handle, &to) == FALSE) { + pclog("%s: error %d while getting current TO\n", + pp->name, GetLastError()); + (void)bhtty_close(pp); + return(NULL); + } + if (tmo < 0) { + /* No timeout, immediate return. */ + to.ReadIntervalTimeout = MAXDWORD; + to.ReadTotalTimeoutMultiplier = 0; + to.ReadTotalTimeoutConstant = 0; + } else if (tmo == 0) { + /* No timeout, wait for data. */ + memset(&to, 0x00, sizeof(to)); + } else { + /* Timeout specified. */ + to.ReadIntervalTimeout = MAXDWORD; + to.ReadTotalTimeoutMultiplier = MAXDWORD; + to.ReadTotalTimeoutConstant = tmo; + } + if (SetCommTimeouts(pp->handle, &to) == FALSE) { + pclog("%s: error %d while setting TO\n", + pp->name, GetLastError()); + (void)bhtty_close(pp); + return(NULL); + } + + /* Clear all errors and flush all buffers. */ + if (bhtty_flush(pp) < 0) { + (void)bhtty_close(pp); + return(NULL); + } + + return(pp); +} + + +/* A pending WRITE has finished, handle it. */ +static VOID CALLBACK +bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) +{ + BHTTY *pp = (BHTTY *)priv->hEvent; + +//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); +#if 0 + if ( + if (GetOverlappedResult(p->handle, + &p->rov, &mst, TRUE) == FALSE) { + r = GetLastError(); + if (r != ERROR_OPERATION_ABORTED) + /* OK, we're being shut down. */ + sprintf(serial_errmsg, + "%s: I/O read error!", p->name); + return(-1); + } +#endif +} + + +/* Try to write data to an open port. */ +int +bhtty_write(BHTTY *pp, unsigned char val) +{ + DWORD n; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid parameter\n"); + return(-1); + } +//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); + + /* Save the control pointer for later use. */ + pp->wov.hEvent = (HANDLE)pp; + + if (WriteFileEx(pp->handle, + &val, 1, + &pp->wov, + bhtty_write_comp) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } + + /* Its pending, so handled in the completion routine. */ + SleepEx(1, TRUE); + + return(0); +} + + +/* + * A pending READ has finished, handle it. + */ +static VOID CALLBACK +bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) +{ + BHTTY *pp = (BHTTY *)priv->hEvent; + DWORD r; +//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); + + if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { + r = GetLastError(); + if (r != ERROR_OPERATION_ABORTED) + /* OK, we're being shut down. */ + pclog("%s: I/O read error!", pp->name); + return; + } +//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); + + /* Do a callback to let them know. */ + if (pp->rd_done != NULL) + pp->rd_done(pp->rd_arg, num); +} + + +/* + * Try to read data from an open port. + * + * For now, we will use one byte per call. Eventually, + * we should go back to loading a buffer full of data, + * just to speed things up a bit. --FvK + * + * Also, not that we do not wait here. We just POST a + * read operation, and the completion routine will do + * the clean-up and notify the caller. + */ +int +bhtty_read(BHTTY *pp, unsigned char *bufp, int max) +{ + DWORD r; + + /* Just one byte. */ + max = 1; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid parameter\n"); + return(-1); + } + + /* Save the control pointer for later use. */ + pp->rov.hEvent = (HANDLE)pp; +//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); + + /* Post a READ on the device. */ + if (ReadFileEx(pp->handle, + bufp, (DWORD)max, + &pp->rov, + bhtty_read_comp) == FALSE) { + r = GetLastError(); + if (r != ERROR_IO_PENDING) { + /* OK, we're being shut down. */ + if (r != ERROR_INVALID_HANDLE) + pclog("%s: I/O read error!\n", pp->name); + return(-1); + } + } + + /* Make ourself alertable. */ + SleepEx(1, TRUE); + + /* OK, it's pending, so we are good for now. */ + return(0); +} diff --git a/src/serial_bh.h b/src/serial_bh.h new file mode 100644 index 000000000..a3f42a1ba --- /dev/null +++ b/src/serial_bh.h @@ -0,0 +1,53 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the Bottom Half of the SERIAL card. + * + * Version: @(#)serial_bh.h 1.0.1 2017/04/14 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef SERIAL_BH_H +# define SERIAL_BH_H + + +#define BHTTY_PORT1 "COM2" /* port 1 connects to .. */ +#define BHTTY_PORT2 "COM4" /* port 2 connects to .. */ + + +typedef struct { + char name[79]; /* name of open port */ + void (*rd_done)(void *, int); + void *rd_arg; +#ifdef BHTTY_C + HANDLE handle; + OVERLAPPED rov, /* READ and WRITE events */ + wov; + int tmo; /* current timeout value */ + DCB dcb, /* terminal settings */ + odcb; +#endif +} BHTTY; + + +extern BHTTY *bhtty_open(char *__port, int __tmo); +extern void bhtty_close(BHTTY *); +extern int bhtty_flush(BHTTY *); +extern void bhtty_raw(BHTTY *, void *__arg); +extern int bhtty_speed(BHTTY *, long __speed); +extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); +extern int bhtty_sstate(BHTTY *, void *__arg); +extern int bhtty_gstate(BHTTY *, void *__arg); +extern int bhtty_crtscts(BHTTY *, char __yesno); + +extern int bhtty_write(BHTTY *, unsigned char); +extern int bhtty_read(BHTTY *, unsigned char *, int); + + +#endif /*SERIAL_BH_H*/ diff --git a/src/sio.c b/src/sio.c index ffc676995..a5303935e 100644 --- a/src/sio.c +++ b/src/sio.c @@ -11,8 +11,12 @@ #include "ibm.h" #include "cdrom.h" #include "cpu.h" +#include "disc.h" +#include "dma.h" +#include "fdc.h" #include "ide.h" #include "io.h" +#include "keyboard_at.h" #include "mem.h" #include "pci.h" @@ -91,45 +95,50 @@ uint8_t trc_read(uint16_t port, void *priv) return trc_reg & 0xfb; } -void trc_write(uint16_t port, uint8_t val, void *priv) +void trc_reset(uint8_t val) { int i = 0; + if (val & 2) + { + if (pci_reset_handler.pci_master_reset) + { + pci_reset_handler.pci_master_reset(); + } + + if (pci_reset_handler.pci_set_reset) + { + pci_reset_handler.pci_set_reset(); + } + + fdc_hard_reset(); + + if (pci_reset_handler.super_io_reset) + { + pci_reset_handler.super_io_reset(); + } + + resetide(); + for (i = 0; i < CDROM_NUM; i++) + { + if (!cdrom_drives[i].bus_type) + { + cdrom_reset(i); + } + } + + port_92_reset(); + keyboard_at_reset(); + } + resetx86(); +} + +void trc_write(uint16_t port, uint8_t val, void *priv) +{ pclog("TRC Write: %02X\n", val); if (!(trc_reg & 4) && (val & 4)) { - if (val & 2) - { - if (pci_reset_handler.pci_master_reset) - { - pci_reset_handler.pci_master_reset(); - } - - if (pci_reset_handler.pci_set_reset) - { - pci_reset_handler.pci_set_reset(); - } - - fdc_hard_reset(); - - if (pci_reset_handler.super_io_reset) - { - pci_reset_handler.super_io_reset(); - } - - resetide(); - for (i = 0; i < CDROM_NUM; i++) - { - if (!cdrom_drives[i].bus_type) - { - cdrom_reset(i); - } - } - - port_92_reset(); - keyboard_at_reset(); - } - resetx86(); + trc_reset(val); } trc_reg = val & 0xfd; } diff --git a/src/sis496.c b/src/sis496.c index 1265330dd..8cdb87a95 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -51,7 +51,6 @@ void sis496_recalcmapping(sis496_t *sis496) void sis496_write(int func, int addr, uint8_t val, void *p) { sis496_t *sis496 = (sis496_t *)p; - //pclog("sis496_write : addr=%02x val=%02x\n", addr, val); switch (addr) { case 0x44: /*Shadow configure*/ diff --git a/src/sis85c471.c b/src/sis85c471.c index cf8e24add..5d12ae341 100644 --- a/src/sis85c471.c +++ b/src/sis85c471.c @@ -23,9 +23,7 @@ static uint8_t sis85c471_regs[39]; void sis85c471_write(uint16_t port, uint8_t val, void *priv) { uint8_t index = (port & 1) ? 0 : 1; - int temp; uint8_t x; - // pclog("sis85c471_write : port=%04x reg %02X = %02X\n", port, sis85c471_curreg, val); if (index) { @@ -85,7 +83,6 @@ process_value: uint8_t sis85c471_read(uint16_t port, void *priv) { - // pclog("sis85c471_read : port=%04x reg %02X\n", port, sis85c471_curreg); uint8_t index = (port & 1) ? 0 : 1; uint8_t temp; @@ -106,9 +103,6 @@ void sis85c471_init() { int i = 0; - // pclog("SiS 85c471 Init\n"); - - // ide_sec_disable(); lpt2_remove(); sis85c471_curreg = 0; diff --git a/src/slirp/debug.h b/src/slirp/debug.h index 9a8c5e8c8..a1eafa130 100644 --- a/src/slirp/debug.h +++ b/src/slirp/debug.h @@ -37,7 +37,6 @@ extern int slirp_debug; #endif void debug_init _P((char *, int)); -//void ttystats _P((struct ttys *)); void allttystats _P((void)); void ipstats _P((void)); void vjstats _P((void)); diff --git a/src/slirp/misc.c b/src/slirp/misc.c index 88c0c13e0..b39a4d9a3 100644 --- a/src/slirp/misc.c +++ b/src/slirp/misc.c @@ -92,8 +92,8 @@ getouraddr() struct hostent *he = NULL; #define ANCIENT #ifdef ANCIENT - if (gethostname(&buff,500) == 0) - he = gethostbyname(&buff); + if (gethostname(buff,500) == 0) + he = gethostbyname(buff); if (he) our_addr = *(struct in_addr *)he->h_addr; if (our_addr.s_addr == 0) diff --git a/src/slirp/queue.h b/src/slirp/queue.h index 534dcb84b..786950ab7 100644 --- a/src/slirp/queue.h +++ b/src/slirp/queue.h @@ -96,4 +96,6 @@ queueElementT QueueDelete(queueADT queue); int QueueIsEmpty(queueADT queue); int QueueIsFull(queueADT queue); +int QueuePeek(queueADT queue); + #endif /* not defined _QUEUE_H */ diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index 92cfe2fc9..b7b077527 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -12,7 +12,7 @@ #include "slirp_config.h" #ifdef _WIN32 -#ifdef __GNUC__ //MINGW? +#ifdef __GNUC__ /* MINGW? */ # include typedef uint8_t u_int8_t; typedef uint16_t u_int16_t; @@ -39,7 +39,7 @@ typedef unsigned long ioctlsockopt_t; #endif -# include //needs to be on top otherwise, it'll pull in winsock1 +# include /* needs to be on top otherwise, it'll pull in winsock1 */ # include # include @@ -243,8 +243,6 @@ int inet_aton _P((const char *cp, struct in_addr *ia)); #define PACK_END 0 #define PACKED__ #elif _MSC_VER -//#define PRAGMA_PACK_SUPPORTED 1 -//#define PACK_END 4 #define PACKED__ #else #error "Packed attribute or pragma shall be supported" @@ -323,15 +321,15 @@ void lprint _P((const char *, ...)); extern int do_echo; #ifdef _MSC_VER -#define inline +#define __inline #endif #if SIZEOF_CHAR_P == 4 # define insque_32 insque # define remque_32 remque #else - extern inline void insque_32 _P((void *, void *)); - extern inline void remque_32 _P((void *)); + extern __inline void insque_32 _P((void *, void *)); + extern __inline void remque_32 _P((void *)); #endif #ifndef _WIN32 diff --git a/src/sound.c b/src/sound.c index 53b6ae732..a00f7f9ca 100644 --- a/src/sound.c +++ b/src/sound.c @@ -36,11 +36,14 @@ static SOUND_CARD sound_cards[] = { {"None", "none", NULL}, {"Adlib", "adlib", &adlib_device}, + {"Adlib MCA", "adlib_mca", &adlib_mca_device}, {"Sound Blaster 1.0", "sb", &sb_1_device}, {"Sound Blaster 1.5", "sb1.5", &sb_15_device}, + {"Sound Blaster MCV", "sbmcv", &sb_mcv_device}, {"Sound Blaster 2.0", "sb2.0", &sb_2_device}, {"Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device}, {"Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device}, + {"Sound Blaster Pro MCV", "sbpromcv", &sb_pro_mcv_device}, {"Sound Blaster 16", "sb16", &sb_16_device}, {"Sound Blaster AWE32", "sbawe32", &sb_awe32_device}, {"Adlib Gold", "adlibgold", &adgold_device}, @@ -108,7 +111,7 @@ static struct static int sound_handlers_num; -static int sound_poll_time = 0, sound_get_buffer_time = 0, sound_poll_latch; +static int sound_poll_time = 0, sound_poll_latch; int sound_pos_global = 0; int soundon = 1; @@ -184,10 +187,8 @@ static void sound_cd_thread(void *param) /* Then, adjust input from drive according to ATAPI/SCSI volume. */ cd_buffer_temp[0] *= (float) audio_vol_l; - // cd_buffer_temp[0] /= 255.0; cd_buffer_temp[0] /= 511.0; cd_buffer_temp[1] *= (float) audio_vol_r; - // cd_buffer_temp[1] /= 255.0; cd_buffer_temp[1] /= 511.0; /*Apply ATAPI channel select*/ @@ -251,13 +252,11 @@ void sound_init() if (available_cdrom_drives) { - // pclog("One or more CD-ROM drives are available, starting CD Audio thread...\n"); sound_cd_event = thread_create_event(); sound_cd_thread_h = thread_create(sound_cd_thread, NULL); } cd_thread_enable = available_cdrom_drives ? 1 : 0; - // pclog("cd_thread_enable = %i\n", cd_thread_enable); } void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p) @@ -325,7 +324,6 @@ void sound_speed_changed() void sound_reset() { int i = 0; - int available_cdrom_drives = 0; timer_add(sound_poll, &sound_poll_time, TIMER_ALWAYS_ENABLED, NULL); @@ -357,13 +355,11 @@ void sound_cd_thread_reset() if (available_cdrom_drives && !cd_thread_enable) { - // pclog("One or more CD-ROM drives are now available, but none was before, starting the CD Audio thread...\n"); sound_cd_event = thread_create_event(); sound_cd_thread_h = thread_create(sound_cd_thread, NULL); } else if (!available_cdrom_drives && cd_thread_enable) { - // pclog("No CD-ROM drives are now available, but one or more was before, killing the CD Audio thread...\n"); thread_destroy_event(sound_cd_event); thread_kill(sound_cd_thread_h); sound_cd_thread_h = NULL; diff --git a/src/sound.h b/src/sound.h index 1878c4729..23eea439e 100644 --- a/src/sound.h +++ b/src/sound.h @@ -18,3 +18,13 @@ void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); extern int sound_pos_global; void sound_speed_changed(); + +void sound_init(); +void sound_reset(); + +void sound_cd_thread_reset(); + +void initalmain(int argc, char *argv[]); +void inital(); +void givealbuffer(float *buf); +void givealbuffer_cd(float *buf); diff --git a/src/sound_ad1848.c b/src/sound_ad1848.c index 9dd339bce..c97a6d518 100644 --- a/src/sound_ad1848.c +++ b/src/sound_ad1848.c @@ -2,7 +2,11 @@ AD1848 CODEC emulation (Windows Sound System compatible)*/ +#include + #include "ibm.h" +#include "dma.h" +#include "pic.h" #include "sound.h" #include "sound_ad1848.h" @@ -22,7 +26,6 @@ uint8_t ad1848_read(uint16_t addr, void *p) { ad1848_t *ad1848 = (ad1848_t *)p; uint8_t temp = 0xff; -// pclog("ad1848_read - addr %04X %04X(%08X):%08X ", addr, CS, cs, pc); switch (addr & 3) { case 0: /*Index*/ @@ -35,7 +38,6 @@ uint8_t ad1848_read(uint16_t addr, void *p) temp = ad1848->status; break; } -// pclog("return %02X\n", temp); return temp; } @@ -43,7 +45,6 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p) { ad1848_t *ad1848 = (ad1848_t *)p; double freq; -// pclog("ad1848_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, pc); switch (addr & 3) { case 0: /*Index*/ @@ -165,12 +166,10 @@ static void ad1848_poll(void *p) } ad1848->count--; -// pclog("ad1848_poll : enable %X %X %X %X %X %X\n", ad1848->pcm_buffer[0][ad1848->pos], ad1848->pcm_buffer[1][ad1848->pos], ad1848->out_l[0], ad1848->out_r[0], ad1848->out_l[1], ad1848->out_r[1]); } else { ad1848->out_l = ad1848->out_r = 0; -// pclog("ad1848_poll : not enable\n"); } } @@ -212,7 +211,6 @@ void ad1848_init(ad1848_t *ad1848) attenuation = pow(10, attenuation / 10); ad1848_vols[c] = (int)(attenuation * 65536); -// pclog("ad1848_vols %i = %f %i\n", c, attenuation, ad1848_vols[c]); } timer_add(ad1848_poll, &ad1848->timer_count, &ad1848->enable, ad1848); diff --git a/src/sound_ad1848.h b/src/sound_ad1848.h index b97e1e499..6c5e02c55 100644 --- a/src/sound_ad1848.h +++ b/src/sound_ad1848.h @@ -33,3 +33,5 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p); void ad1848_update(ad1848_t *ad1848); void ad1848_speed_changed(ad1848_t *ad1848); + +void ad1848_init(ad1848_t *ad1848); diff --git a/src/sound_adlib.c b/src/sound_adlib.c index f4e24bb44..70ed47b7a 100644 --- a/src/sound_adlib.c +++ b/src/sound_adlib.c @@ -1,7 +1,9 @@ #include #include "ibm.h" +#include "io.h" #include "device.h" #include "sound.h" +#include "mca.h" #include "sound_adlib.h" #include "sound_opl.h" @@ -9,6 +11,8 @@ typedef struct adlib_t { opl_t opl; + + uint8_t pos_regs[8]; } adlib_t; static void adlib_get_buffer(int32_t *buffer, int len, void *p) @@ -24,6 +28,36 @@ static void adlib_get_buffer(int32_t *buffer, int len, void *p) adlib->opl.pos = 0; } +uint8_t adlib_mca_read(int port, void *p) +{ + adlib_t *adlib = (adlib_t *)p; + + pclog("adlib_mca_read: port=%04x\n", port); + + return adlib->pos_regs[port & 7]; +} + +void adlib_mca_write(int port, uint8_t val, void *p) +{ + adlib_t *adlib = (adlib_t *)p; + + if (port < 0x102) + return; + + pclog("adlib_mca_write: port=%04x val=%02x\n", port, val); + + switch (port) + { + case 0x102: + if ((adlib->pos_regs[2] & 1) && !(val & 1)) + io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); + if (!(adlib->pos_regs[2] & 1) && (val & 1)) + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); + break; + } + adlib->pos_regs[port & 7] = val; +} + void *adlib_init() { adlib_t *adlib = malloc(sizeof(adlib_t)); @@ -36,6 +70,18 @@ void *adlib_init() return adlib; } +void *adlib_mca_init() +{ + adlib_t *adlib = adlib_init(); + + io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &adlib->opl); + mca_add(adlib_mca_read, adlib_mca_write, adlib); + adlib->pos_regs[0] = 0xd7; + adlib->pos_regs[1] = 0x70; + + return adlib; +} + void adlib_close(void *p) { adlib_t *adlib = (adlib_t *)p; @@ -54,3 +100,15 @@ device_t adlib_device = NULL, NULL }; + +device_t adlib_mca_device = +{ + "AdLib (MCA)", + DEVICE_MCA, + adlib_init, + adlib_close, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/sound_adlib.h b/src/sound_adlib.h index c8db01482..1e2c363af 100644 --- a/src/sound_adlib.h +++ b/src/sound_adlib.h @@ -1 +1,2 @@ extern device_t adlib_device; +extern device_t adlib_mca_device; diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index a0f0956a9..398ed139c 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -146,7 +146,6 @@ void adgold_update_irq_status(adgold_t *adgold) if ((adgold->adgold_status ^ 0xf) && !adgold->adgold_irq_status) { -// pclog("adgold irq %02X\n", adgold->adgold_status); picint(0x80); } @@ -161,14 +160,12 @@ void adgold_getsamp_dma(adgold_t *adgold, int channel) return; temp = dma_channel_read(1); -// pclog("adgold DMA1 return %02X %i L\n", temp, channel); if (temp == DMA_NODATA) return; adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; if (adgold->adgold_mma_regs[channel][0xc] & 0x60) { temp = dma_channel_read(1); -// pclog("adgold DMA1 return %02X %i H\n", temp, channel); adgold->adgold_mma_fifo[channel][adgold->adgold_mma_fifo_end[channel]] = temp; adgold->adgold_mma_fifo_end[channel] = (adgold->adgold_mma_fifo_end[channel] + 1) & 255; } @@ -182,7 +179,6 @@ void adgold_getsamp_dma(adgold_t *adgold, int channel) void adgold_write(uint16_t addr, uint8_t val, void *p) { adgold_t *adgold = (adgold_t *)p; -// if (addr > 0x389) pclog("adgold_write : addr %04X val %02X %04X:%04X\n", addr, val, CS, pc); switch (addr & 7) { case 0: case 1: @@ -326,12 +322,10 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) if (!(adgold->adgold_mma_regs[0][0x9] & 1)) adgold->adgold_mma.voice_count[0] = adgold->adgold_mma.voice_latch[0]; -// pclog("adgold start! FIFO fill %i %i %i %02X\n", (adgold->adgold_mma_fifo_end[0] - adgold->adgold_mma_fifo_start[0]) & 255, adgold->adgold_mma_fifo_end[0], adgold->adgold_mma_fifo_start[0], adgold->adgold_mma_regs[0][0xc]); if (adgold->adgold_mma_regs[0][0xc] & 1) { if (adgold->adgold_mma_regs[0][0xc] & 0x80) { -// pclog("adgold start interleaved %i %i adgold->adgold_mma_enable[1] = 1; adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; @@ -364,7 +358,6 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) } } } -// pclog("adgold end\n"); } adgold->adgold_mma_enable[0] = val & 0x01; break; @@ -413,7 +406,6 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) if (!(adgold->adgold_mma_regs[1][0x9] & 1)) adgold->adgold_mma.voice_count[1] = adgold->adgold_mma.voice_latch[1]; -// pclog("adgold start! FIFO fill %i %i %i %02X\n", (adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255, adgold->adgold_mma_fifo_end[1], adgold->adgold_mma_fifo_start[1], adgold->adgold_mma_regs[1][0xc]); if (adgold->adgold_mma_regs[1][0xc] & 1) { while (((adgold->adgold_mma_fifo_end[1] - adgold->adgold_mma_fifo_start[1]) & 255) < 128) @@ -421,7 +413,6 @@ void adgold_write(uint16_t addr, uint8_t val, void *p) adgold_getsamp_dma(adgold, 1); } } -// pclog("adgold end\n"); } adgold->adgold_mma_enable[1] = val & 0x01; break; @@ -514,7 +505,6 @@ uint8_t adgold_read(uint16_t addr, void *p) temp = adgold->adgold_mma_regs[1][adgold->adgold_mma_addr]; break; } -// if (addr > 0x389) pclog("adgold_read : addr %04X %02X\n", addr, temp); return temp; } @@ -570,7 +560,6 @@ void adgold_mma_poll(adgold_t *adgold, int channel) } if (((adgold->adgold_mma_fifo_end[channel] - adgold->adgold_mma_fifo_start[channel]) & 255) < adgold->adgold_mma_intpos[channel] && !(adgold->adgold_mma_status & 0x01)) { -// pclog("adgold_mma_poll - IRQ! %i\n", channel); adgold->adgold_mma_status |= 1 << channel; adgold_update_irq_status(adgold); } @@ -594,7 +583,6 @@ void adgold_timer_poll(void *p) if (!adgold->adgold_mma.timer0_count) { adgold->adgold_mma.timer0_count = adgold->adgold_mma.timer0_latch; -// pclog("Timer 0 interrupt\n"); adgold->adgold_mma_status |= 0x10; adgold_update_irq_status(adgold); } @@ -611,7 +599,6 @@ void adgold_timer_poll(void *p) if (!adgold->adgold_mma.timer1_count) { adgold->adgold_mma.timer1_count = adgold->adgold_mma.timer1_latch; -// pclog("Timer 1 interrupt\n"); adgold->adgold_mma_status |= 0x20; adgold_update_irq_status(adgold); } @@ -622,7 +609,6 @@ void adgold_timer_poll(void *p) if (!adgold->adgold_mma.timer2_count) { adgold->adgold_mma.timer2_count = adgold->adgold_mma.timer2_latch; -// pclog("Timer 2 interrupt\n"); adgold->adgold_mma_status |= 0x40; adgold_update_irq_status(adgold); } @@ -839,13 +825,10 @@ void adgold_close(void *p) static device_config_t adgold_config[] = { { - .name = "surround", - .description = "Surround module", - .type = CONFIG_BINARY, - .default_int = 1 + "surround", "Surround module", CONFIG_BINARY, "", 1 }, { - .type = -1 + "", "", -1 } }; diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index 6274b8839..1d82385f1 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -7,6 +7,7 @@ #include #include "ibm.h" #include "device.h" +#include "io.h" #include "sound.h" #include "sound_emu8k.h" #include "timer.h" @@ -40,7 +41,7 @@ static int32_t filt_w0[256]; case 2: var = (var & 0x0000ffff) | ((val) << 16); break; \ } -static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) +static __inline int16_t EMU8K_READ(emu8k_t *emu8k, uint16_t addr) { addr &= 0xffffff; if (addr < 0x80000) @@ -52,14 +53,14 @@ static inline int16_t EMU8K_READ(emu8k_t *emu8k, uint32_t addr) return emu8k->ram[addr - 0x200000]; } -static inline int16_t EMU8K_READ_INTERP(emu8k_t *emu8k, uint32_t addr) +static __inline int16_t EMU8K_READ_INTERP(emu8k_t *emu8k, uint16_t addr) { int16_t dat1 = EMU8K_READ(emu8k, addr >> 8); int16_t dat2 = EMU8K_READ(emu8k, (addr >> 8) + 1); return ((dat1 * (0xff - (addr & 0xff))) + (dat2 * (addr & 0xff))) >> 8; } -static inline void EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) +static __inline void EMU8K_WRITE(emu8k_t *emu8k, uint16_t addr, uint16_t val) { addr &= 0xffffff; if (emu8k->ram && addr >= 0x200000 && addr < emu8k->ram_end_addr) @@ -68,10 +69,10 @@ static inline void EMU8K_WRITE(emu8k_t *emu8k, uint32_t addr, uint16_t val) static int ff = 0; static int voice_count = 0; -uint16_t emu8k_inw(uint32_t addr, void *p) +uint16_t emu8k_inw(uint16_t addr, void *p) { emu8k_t *emu8k = (emu8k_t *)p; - uint16_t ret; + uint16_t ret = 0xffff; /* pclog("emu8k_inw %04X reg=%i voice=%i\n", addr, emu8k->cur_reg, emu8k->cur_voice);*/ addr -= 0x220; @@ -114,7 +115,6 @@ uint16_t emu8k_inw(uint32_t addr, void *p) { case 0: { - uint32_t val = (emu8k->voice[emu8k->cur_voice].ccca & 0xff000000) | (emu8k->voice[emu8k->cur_voice].addr >> 8); READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); return ret; } @@ -170,7 +170,6 @@ uint16_t emu8k_inw(uint32_t addr, void *p) { case 0: { - uint32_t val = (emu8k->voice[emu8k->cur_voice].ccca & 0xff000000) | (emu8k->voice[emu8k->cur_voice].addr >> 8); READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); return ret; } @@ -254,13 +253,12 @@ uint16_t emu8k_inw(uint32_t addr, void *p) return 0xffff; } -void emu8k_outw(uint32_t addr, uint16_t val, void *p) +void emu8k_outw(uint16_t addr, uint16_t val, void *p) { emu8k_t *emu8k = (emu8k_t *)p; emu8k_update(emu8k); /* pclog("emu8k_outw : addr=%08X reg=%i voice=%i val=%04X\n", addr, emu8k->cur_reg, emu8k->cur_voice, val);*/ -//emu8k_outw : addr=00000A22 reg=3 voice=21 val=0265 addr -= 0x220; switch (addr & 0xc02) { @@ -487,14 +485,14 @@ void emu8k_outw(uint32_t addr, uint16_t val, void *p) } } -uint8_t emu8k_inb(uint32_t addr, void *p) +uint8_t emu8k_inb(uint16_t addr, void *p) { if (addr & 1) return emu8k_inw(addr & ~1, p) >> 1; return emu8k_inw(addr, p) & 0xff; } -void emu8k_outb(uint32_t addr, uint8_t val, void *p) +void emu8k_outb(uint16_t addr, uint8_t val, void *p) { if (addr & 1) emu8k_outw(addr & ~1, val << 8, p); @@ -504,13 +502,13 @@ void emu8k_outb(uint32_t addr, uint8_t val, void *p) void emu8k_update(emu8k_t *emu8k) { + int32_t *buf; + int pos; + int c; + int new_pos = (sound_pos_global * 44100) / 48000; if (emu8k->pos < new_pos) { - int32_t *buf; - int pos; - int c; - int32_t out_l = 0, out_r = 0; buf = &emu8k->buffer[emu8k->pos*2]; @@ -526,10 +524,7 @@ void emu8k_update(emu8k_t *emu8k) int32_t voice_l, voice_r; int32_t dat; int lfo1_vibrato, lfo2_vibrato; - int tremolo; - tremolo = ((lfotable[(emu8k->voice[c].lfo1_count >> 8) & 4095] * emu8k->voice[c].lfo1_trem) * 4) >> 12; - if (freqtable[emu8k->voice[c].pitch] >> 32) dat = EMU8K_READ(emu8k, emu8k->voice[c].addr >> 32); else diff --git a/src/sound_gus.c b/src/sound_gus.c index 7158c7203..34b0416e4 100644 --- a/src/sound_gus.c +++ b/src/sound_gus.c @@ -93,28 +93,23 @@ void pollgusirqs(gus_t *gus) { if (gus->waveirqs[c]) { -// gus->waveirqs[c]=0; gus->irqstatus2=0x60|c; if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80; gus->irqstatus|=0x20; -// printf("Voice IRQ %i %02X %i\n",c,gus->irqstatus2,ins); if (gus->irq != -1) picint(1 << gus->irq); return; } if (gus->rampirqs[c]) { -// gus->rampirqs[c]=0; gus->irqstatus2=0xA0|c; gus->irqstatus|=0x40; -// printf("Ramp IRQ %i %02X %i\n",c,gus->irqstatus2,ins); if (gus->irq != -1) picint(1 << gus->irq); return; } } gus->irqstatus2=0xE0; -// gus->irqstatus&=~0x20; if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq); } @@ -164,7 +159,6 @@ void gus_midi_update_int_status(gus_t *gus) if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != -1)) { -// pclog("Take MIDI IRQ\n"); picint(1 << gus->irq_midi); } } @@ -174,7 +168,6 @@ void writegus(uint16_t addr, uint8_t val, void *p) gus_t *gus = (gus_t *)p; int c, d; int old; -// pclog("Write GUS %04X %02X %04X:%04X\n",addr,val,CS,pc); if (gus->latch_enable && addr != 0x24b) gus->latch_enable = 0; switch (addr) @@ -188,7 +181,6 @@ void writegus(uint16_t addr, uint8_t val, void *p) else if ((old & 3) == 3) { gus->midi_status |= MIDI_INT_TRANSMIT; -// pclog("MIDI_INT_TRANSMIT\n"); } gus_midi_update_int_status(gus); break; @@ -210,11 +202,9 @@ void writegus(uint16_t addr, uint8_t val, void *p) gus->global=val; break; case 0x344: /*Global low*/ -// if (gus->global!=0x43 && gus->global!=0x44) printf("Writing register %02X %02X %02X %i\n",gus->global,gus->voice,val, ins); switch (gus->global) { case 0: /*Voice control*/ -// if (val&1 && !(gus->ctrl[gus->voice]&1)) printf("Voice on %i\n",gus->voice); gus->ctrl[gus->voice]=val; break; case 1: /*Frequency control*/ @@ -223,41 +213,32 @@ void writegus(uint16_t addr, uint8_t val, void *p) case 2: /*Start addr high*/ gus->startx[gus->voice]=(gus->startx[gus->voice]&0xF807F)|(val<<7); gus->start[gus->voice]=(gus->start[gus->voice]&0x1F00FFFF)|(val<<16); -// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); break; case 3: /*Start addr low*/ gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFFFF00)|val; -// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); break; case 4: /*End addr high*/ gus->endx[gus->voice]=(gus->endx[gus->voice]&0xF807F)|(val<<7); gus->end[gus->voice]=(gus->end[gus->voice]&0x1F00FFFF)|(val<<16); -// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); break; case 5: /*End addr low*/ gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFFFF00)|val; -// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); break; case 0x6: /*Ramp frequency*/ gus->rfreq[gus->voice] = (int)( (double)((val & 63)*512)/(double)(1 << (3*(val >> 6)))); -// printf("RFREQ %02X %i %i %f\n",val,gus->voice,gus->rfreq[gus->voice],(double)(val & 63)/(double)(1 << (3*(val >> 6)))); break; case 0x9: /*Current volume*/ gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 6)) | (val << 6); -// printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); break; case 0xA: /*Current addr high*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16); gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); -// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0F807F00)|((val<<7)<<8); -// printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); break; case 0xB: /*Current addr low*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val; -// printf("Write %i cur %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); break; case 0x42: /*DMA address low*/ @@ -268,21 +249,16 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); gus->addr=(gus->addr&0xFFF00)|val; break; case 0x45: /*Timer control*/ -// printf("Timer control %02X\n",val); gus->tctrl=val; break; } break; case 0x345: /*Global high*/ -// if (gus->global!=0x43 && gus->global!=0x44) printf("HWriting register %02X %02X %02X %04X:%04X %i %X\n",gus->global,gus->voice,val,CS,pc, ins, gus->rcur[1] >> 10); switch (gus->global) { case 0: /*Voice control*/ if (!(val&1) && gus->ctrl[gus->voice]&1) { -// printf("Voice on %i - start %05X end %05X freq %04X\n",gus->voice,gus->start[gus->voice],gus->end[gus->voice],gus->freq[gus->voice]); -// if (val&0x40) gus->cur[gus->voice]=gus->end[gus->voice]<<8; -// else gus->cur[gus->voice]=gus->start[gus->voice]<<8; } gus->ctrl[gus->voice] = val & 0x7f; @@ -298,52 +274,40 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); case 2: /*Start addr high*/ gus->startx[gus->voice]=(gus->startx[gus->voice]&0x07FFF)|(val<<15); gus->start[gus->voice]=(gus->start[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); -// printf("Write %i start %08X %08X %02X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice],val); break; case 3: /*Start addr low*/ gus->startx[gus->voice]=(gus->startx[gus->voice]&0xFFF80)|(val&0x7F); gus->start[gus->voice]=(gus->start[gus->voice]&0x1FFF00FF)|(val<<8); -// printf("Write %i start %08X %08X\n",gus->voice,gus->start[gus->voice],gus->startx[gus->voice]); break; case 4: /*End addr high*/ gus->endx[gus->voice]=(gus->endx[gus->voice]&0x07FFF)|(val<<15); gus->end[gus->voice]=(gus->end[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); -// printf("Write %i end %08X %08X %02X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice],val); break; case 5: /*End addr low*/ gus->endx[gus->voice]=(gus->endx[gus->voice]&0xFFF80)|(val&0x7F); gus->end[gus->voice]=(gus->end[gus->voice]&0x1FFF00FF)|(val<<8); -// printf("Write %i end %08X %08X\n",gus->voice,gus->end[gus->voice],gus->endx[gus->voice]); break; case 0x6: /*Ramp frequency*/ gus->rfreq[gus->voice] = (int)( (double)((val & 63) * (1 << 10))/(double)(1 << (3 * (val >> 6)))); -// pclog("Ramp freq %02X %i %i %f %i\n", val, gus->voice, gus->rfreq[gus->voice], (double)(val & 63)/(double)(1 << (3*(val >> 6))), ins); break; case 0x7: /*Ramp start*/ gus->rstart[gus->voice] = val << 14; -// pclog("Ramp start %04X\n", gus->rstart[gus->voice] >> 10); break; case 0x8: /*Ramp end*/ gus->rend[gus->voice] = val << 14; -// pclog("Ramp end %04X\n", gus->rend[gus->voice] >> 10); break; case 0x9: /*Current volume*/ gus->curvol[gus->voice] = gus->rcur[gus->voice] = (gus->rcur[gus->voice] & ~(0xff << 14)) | (val << 14); -// printf("Vol %i is %04X\n",gus->voice,gus->curvol[gus->voice]); break; case 0xA: /*Current addr high*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x00FFFFFF)|((val&0x1F)<<24); gus->curx[gus->voice]=(gus->curx[gus->voice]&0x07FFF00)|((val<<15)<<8); -// printf("Write %i cur %08X %08X %02X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice],val); -// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x007FFF00)|((val<<15)<<8); break; case 0xB: /*Current addr low*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8); gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); -// gus->cur[gus->voice]=(gus->cur[gus->voice]&0x0FFF8000)|((val&0x7F)<<8); -// printf("Write %i cur %08X %08X\n",gus->voice,gus->cur[gus->voice],gus->curx[gus->voice]); break; case 0xC: /*Pan*/ gus->pan_l[gus->voice] = 15 - (val & 0xf); @@ -355,7 +319,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0; if (gus->rampirqs[gus->voice] != old) pollgusirqs(gus); -// printf("Ramp control %02i %02X %02X %i\n",gus->voice,val,gus->rampirqs[gus->voice],ins); break; case 0xE: @@ -363,7 +326,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); if (gus->voices>32) gus->voices=32; if (gus->voices<14) gus->voices=14; gus->global=val; -// printf("GUS voices %i\n",val&31); if (gus->voices < 14) gus->samp_latch = (int)(TIMER_USEC * (1000000.0 / 44100.0)); else @@ -373,7 +335,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); case 0x41: /*DMA*/ if (val&1 && gus->dma != -1) { -// printf("DMA start! %05X %02X\n",gus->dmaaddr,val); if (val & 2) { c=0; @@ -391,7 +352,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); if (dma_result & DMA_OVER) break; } -// printf("GUS->MEM Transferred %i bytes\n",c); gus->dmactrl=val&~0x40; if (val&0x20) gus->irqnext=1; } @@ -411,11 +371,9 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); if (d & DMA_OVER) break; } -// printf("MEM->GUS Transferred %i bytes\n",c); gus->dmactrl=val&~0x40; if (val&0x20) gus->irqnext=1; } -// exit(-1); } break; @@ -442,24 +400,16 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); gus->ad_status &= ~0x01; nmi = 0; } -// printf("Timer control %02X\n",val); -/* if ((val&4) && !(gus->tctrl&4)) - { - gus->t1=gus->t1l; - gus->t1on=1; - }*/ gus->tctrl=val; gus->sb_ctrl = val; break; case 0x46: /*Timer 1*/ gus->t1 = gus->t1l = val; gus->t1on = 1; -// printf("GUS timer 1 %i\n",val); break; case 0x47: /*Timer 2*/ gus->t2 = gus->t2l = val; gus->t2on = 1; -// printf("GUS timer 2 %i\n",val); break; case 0x4c: /*Reset*/ @@ -469,12 +419,10 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); break; case 0x347: /*DRAM access*/ gus->ram[gus->addr]=val; -// pclog("GUS RAM write %05X %02X\n",gus->addr,val); gus->addr&=0xFFFFF; break; case 0x248: case 0x388: gus->adcommand = val; -// pclog("Setting ad command %02X %02X %p\n", val, gus->adcommand, &gus->adcommand); break; case 0x389: @@ -541,7 +489,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); gus->sb_nmi = val & 0x80; } gus->latch_enable = 0; -// pclog("IRQ %i DMA %i\n", gus->irq, gus->dma); break; case 1: gus->gp1 = val; @@ -601,12 +548,10 @@ uint8_t readgus(uint16_t addr, void *p) { gus_t *gus = (gus_t *)p; uint8_t val; -// /*if (addr!=0x246) */printf("Read GUS %04X %04X(%06X):%04X %02X\n",addr,CS,cs,pc,gus->global); switch (addr) { case 0x340: /*MIDI status*/ val = gus->midi_status; -// pclog("Read MIDI status %02X\n", val); break; case 0x341: /*MIDI data*/ @@ -620,14 +565,12 @@ uint8_t readgus(uint16_t addr, void *p) val = gus->irqstatus & ~0x10; if (gus->ad_status & 0x19) val |= 0x10; -// pclog("Read IRQ status %02X\n", val); return val; case 0x24F: return 0; case 0x342: return gus->voice; case 0x343: return gus->global; case 0x344: /*Global low*/ -// /*if (gus->global!=0x43 && gus->global!=0x44) */printf("Reading register %02X %02X\n",gus->global,gus->voice); switch (gus->global) { case 0x82: /*Start addr high*/ @@ -644,7 +587,6 @@ uint8_t readgus(uint16_t addr, void *p) case 0x8F: /*IRQ status*/ val=gus->irqstatus2; -// pclog("Read IRQ status - %02X\n",val); gus->rampirqs[gus->irqstatus2&0x1F]=0; gus->waveirqs[gus->irqstatus2&0x1F]=0; pollgusirqs(gus); @@ -656,17 +598,12 @@ uint8_t readgus(uint16_t addr, void *p) case 0x0c: case 0x0d: case 0x0e: case 0x0f: val = 0xff; break; - -// default: -// fatal("Bad GUS global low read %02X\n",gus->global); } break; case 0x345: /*Global high*/ -// /*if (gus->global!=0x43 && gus->global!=0x44) */printf("HReading register %02X %02X\n",gus->global,gus->voice); switch (gus->global) { case 0x80: /*Voice control*/ -// pclog("Read voice control %02i %02X\n", gus->voice, gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0)); return gus->ctrl[gus->voice]|(gus->waveirqs[gus->voice]?0x80:0); case 0x82: /*Start addr high*/ @@ -675,7 +612,6 @@ uint8_t readgus(uint16_t addr, void *p) return gus->start[gus->voice]>>8; case 0x89: /*Current volume*/ -// pclog("Read current volume %i\n", gus->rcur[gus->voice] >> 14); return gus->rcur[gus->voice]>>14; case 0x8A: /*Current addr high*/ @@ -687,16 +623,13 @@ uint8_t readgus(uint16_t addr, void *p) return gus->pan_r[gus->voice]; case 0x8D: -// pclog("Read ramp control %02X %04X %08X %08X %08X\n",gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0),gus->rcur[gus->voice] >> 14,gus->rfreq[gus->voice],gus->rstart[gus->voice],gus->rend[gus->voice]); return gus->rctrl[gus->voice]|(gus->rampirqs[gus->voice]?0x80:0); case 0x8F: /*IRQ status*/ -// pclog("Read IRQ 1\n"); val=gus->irqstatus2; gus->rampirqs[gus->irqstatus2&0x1F]=0; gus->waveirqs[gus->irqstatus2&0x1F]=0; pollgusirqs(gus); -// pclog("Read IRQ status - %02X %i %i\n",val, gus->waveirqs[gus->irqstatus2&0x1F], gus->rampirqs[gus->irqstatus2&0x1F]); return val; case 0x41: /*DMA control*/ @@ -714,15 +647,11 @@ uint8_t readgus(uint16_t addr, void *p) case 0x0c: case 0x0d: case 0x0e: case 0x0f: val = 0xff; break; - -// default: -// fatal("Bad GUS global high read %02X\n",gus->global); } break; case 0x346: return 0xff; case 0x347: /*DRAM access*/ val=gus->ram[gus->addr]; -// pclog("GUS RAM read %05X %02X\n",gus->addr,val); gus->addr&=0xFFFFF; return val; case 0x349: return 0; @@ -753,19 +682,9 @@ uint8_t readgus(uint16_t addr, void *p) gus->sb_2xc &= 0x80; break; case 0x24e: -/* gus->ad_status |= 0x10; - if (gus->reg_ctrl & 0x80) - { - gus->reg_ctrl_r |= 0x80; - if (gus->sb_nmi) - nmi = 1; - else - picint(1 << gus->irq); - }*/ return gus->sb_2xe; case 0x248: case 0x388: -// pclog("Read ad_status %02X\n", gus->ad_status); if (gus->tctrl & GUS_TIMER_CTRL_AUTO) val = gus->sb_2xa; else @@ -785,12 +704,9 @@ uint8_t readgus(uint16_t addr, void *p) case 0x24A: val = gus->adcommand; -// pclog("Read ad command %02X %02X %p\n", gus->adcommand, val, &gus->adcommand); break; } -// printf("Bad GUS read %04X! %02X\n",addr,gus->global); -// exit(-1); return val; } @@ -799,13 +715,11 @@ void gus_poll_timer_1(void *p) gus_t *gus = (gus_t *)p; gus->timer_1 += (TIMER_USEC * 80); -// pclog("gus_poll_timer_1 %i %i %i %i %02X\n", gustime, gus->t1on, gus->t1, gus->t1l, gus->tctrl); if (gus->t1on) { gus->t1++; if (gus->t1 > 0xFF) { -// gus->t1on=0; gus->t1=gus->t1l; gus->ad_status |= 0x40; if (gus->tctrl&4) @@ -814,13 +728,11 @@ void gus_poll_timer_1(void *p) picint(1 << gus->irq); gus->ad_status |= 0x04; gus->irqstatus |= 0x04; -// pclog("GUS T1 IRQ!\n"); } } } if (gus->irqnext) { -// pclog("Take IRQ\n"); gus->irqnext=0; gus->irqstatus|=0x80; if (gus->irq != -1) @@ -834,13 +746,11 @@ void gus_poll_timer_2(void *p) gus_t *gus = (gus_t *)p; gus->timer_2 += (TIMER_USEC * 320); -// pclog("pollgus2 %i %i %i %i %02X\n", gustime, gus->t2on, gus->t2, gus->t2l, gus->tctrl); if (gus->t2on) { gus->t2++; if (gus->t2 > 0xFF) { -// gus->t2on=0; gus->t2=gus->t2l; gus->ad_status |= 0x20; if (gus->tctrl&8) @@ -849,13 +759,11 @@ void gus_poll_timer_2(void *p) picint(1 << gus->irq); gus->ad_status |= 0x02; gus->irqstatus |= 0x08; -// pclog("GUS T2 IRQ!\n"); } } } if (gus->irqnext) { -// pclog("Take IRQ\n"); gus->irqnext=0; gus->irqstatus|=0x80; if (gus->irq != -1) @@ -899,7 +807,6 @@ void gus_poll_wave(void *p) if ((gus->reset & 3) != 3) return; -//pclog("gus_poll_wave\n"); for (d=0;d<32;d++) { if (!(gus->ctrl[d] & 3)) @@ -929,10 +836,8 @@ void gus_poll_wave(void *p) v = (int16_t)(int8_t)((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); } -// pclog("Voice %i : %04X %05X %04X ", d, v, gus->cur[d] >> 9, gus->rcur[d] >> 10); if ((gus->rcur[d] >> 14) > 4095) v = (int16_t)(float)(v) * 24.0 * vol16bit[4095]; else v = (int16_t)(float)(v) * 24.0 * vol16bit[(gus->rcur[d]>>10) & 4095]; -// pclog("%f %04X\n", vol16bit[(gus->rcur[d]>>10) & 4095], v); gus->out_l += (v * gus->pan_l[d]) / 7; gus->out_r += (v * gus->pan_r[d]) / 7; @@ -959,7 +864,6 @@ void gus_poll_wave(void *p) { gus->waveirqs[d] = 1; update_irqs = 1; -// pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d); } } } @@ -986,7 +890,6 @@ void gus_poll_wave(void *p) { gus->waveirqs[d] = 1; update_irqs = 1; -// pclog("Causing wave IRQ %02X %i\n", gus->ctrl[d], d); } } } @@ -1014,14 +917,12 @@ void gus_poll_wave(void *p) { gus->rampirqs[d] = 1; update_irqs = 1; -// pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d); } } } else { gus->rcur[d] += gus->rfreq[d]; -// if (d == 1) printf("RCUR+ %i %08X %08X %08X %08X\n",d,gus->rfreq[d],gus->rcur[d],gus->rstart[d],gus->rend[d]); if (gus->rcur[d] >= gus->rend[d]) { int diff = gus->rcur[d] - gus->rend[d]; @@ -1040,7 +941,6 @@ void gus_poll_wave(void *p) { gus->rampirqs[d] = 1; update_irqs = 1; -// pclog("Causing ramp IRQ %02X %i\n",gus->rctrl[d], d); } } } @@ -1087,7 +987,7 @@ void *gus_init() } for (c=4095;c>=0;c--) { - vol16bit[c]=out;//(float)c/4095.0;//out; + vol16bit[c]=out; out/=1.002709201; /* 0.0235 dB Steps */ } diff --git a/src/sound_mpu401_uart.c b/src/sound_mpu401_uart.c index 3ff22de61..5d70b5427 100644 --- a/src/sound_mpu401_uart.c +++ b/src/sound_mpu401_uart.c @@ -1,5 +1,6 @@ #include "ibm.h" #include "io.h" +#include "plat-midi.h" #include "sound_mpu401_uart.h" enum diff --git a/src/sound_pas16.c b/src/sound_pas16.c index cc5a23538..69c245f5e 100644 --- a/src/sound_pas16.c +++ b/src/sound_pas16.c @@ -149,7 +149,7 @@ static int pas16_sb_dmas[8] = {0, 1, 2, 3}; enum { PAS16_INT_SAMP = 0x04, - PAS16_INT_PCM = 0x08, + PAS16_INT_PCM = 0x08 }; enum @@ -260,6 +260,10 @@ static uint8_t pas16_in(uint16_t port, void *p) case 0xff8b: /*Master mode read*/ temp = 0x20 | 0x10 | 0x01; /*AT bus, XT/AT timing*/ break; + + default: + temp = 0xff; + break; } /* if (port != 0x388 && port != 0x389 && port != 0xb8b) */pclog("pas16_in : port %04X return %02X %04X:%04X\n", port, temp, CS,cpu_state.pc); /* if (CS == 0x1FF4 && pc == 0x0585) @@ -289,7 +293,6 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) case 0xb89: pas16->irq_stat &= ~val; -// pas16_update_irqs(); break; case 0xb8a: @@ -299,7 +302,6 @@ static void pas16_out(uint16_t port, uint8_t val, void *p) case 0xb8b: pas16->irq_ena = val; -// pas16_update_irqs(); break; case 0xf88: @@ -490,9 +492,8 @@ static void pas16_pit_out(uint16_t port, uint8_t val, void *p) static uint8_t pas16_pit_in(uint16_t port, void *p) { pas16_t *pas16 = (pas16_t *)p; - uint8_t temp; + uint8_t temp = 0xff; int t = port & 3; -// printf("Read PIT %04X ",addr); switch (port & 3) { case 0: case 1: case 2: /*Timers*/ @@ -538,7 +539,6 @@ static uint8_t pas16_pit_in(uint16_t port, void *p) temp = pas16->pit.ctrl; break; } -// printf("%02X %i %i %04X:%04X\n",temp,pit.rm[addr&3],pit.wp,cs>>4,pc); return temp; } @@ -552,8 +552,6 @@ static void pas16_pcm_poll(void *p) pas16_t *pas16 = (pas16_t *)p; pas16_update(pas16); -// if (pas16->pcm_ctrl & PAS16_PCM_ENA) -// pclog("pas16_pcm_poll : poll %i %i ", pas16->pit.c[0], pas16->pit.l[0]); if (pas16->pit.m[0] & 2) { if (pas16->pit.l[0]) @@ -566,13 +564,10 @@ static void pas16_pcm_poll(void *p) pas16->pit.c[0] = -1; pas16->pit.enable[0] = 0; } -// if (pas16->pcm_ctrl & PAS16_PCM_ENA) -// pclog(" %i\n", pas16->pit.c[0]); pas16->irq_stat |= PAS16_INT_SAMP; if (pas16->irq_ena & PAS16_INT_SAMP) picint(1 << pas16->irq); -// pas16_update_irqs(); /*Update sample rate counter*/ if (pas16->pit.enable[1]) @@ -602,11 +597,6 @@ static void pas16_pcm_poll(void *p) pas16->stereo_lr = !pas16->stereo_lr; } -// pclog("pas16_pcm_poll : %04X %i\n", temp, pas16->stereo_lr); -// pclog("pas16_pcm_poll : %i %02X %i\n", pas16->pit.c[1], temp, pas16->pit.c[0]); -/* if (!pas16_pcm) - pas16_pcm=fopen("pas16->pcm", "wb"); - putc(temp, pas16_pcm);*/ } if (pas16->sys_conf_2 & PAS16_SC2_16BIT) pas16->pit.c[1] -= 2; @@ -614,8 +604,6 @@ static void pas16_pcm_poll(void *p) pas16->pit.c[1]--; if (pas16->pit.c[1] == 0) { -// if (pas16->pcm_ctrl & PAS16_PCM_ENA) -// pclog("pas16_pcm_poll : buffer over\n"); if (pas16->pit.m[1] & 2) { if (pas16->pit.l[1]) diff --git a/src/sound_ps1.c b/src/sound_ps1.c index 4f42cd4d8..6c2498e7e 100644 --- a/src/sound_ps1.c +++ b/src/sound_ps1.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "device.h" #include "io.h" +#include "pic.h" #include "sound.h" #include "sound_ps1.h" #include "sound_sn76489.h" @@ -36,8 +37,6 @@ static uint8_t ps1_audio_read(uint16_t port, void *p) { ps1_audio_t *ps1 = (ps1_audio_t *)p; uint8_t temp; - -// pclog("ps1_audio_read %04x %04x:%04x\n", port, CS, pc); switch (port & 7) { @@ -52,7 +51,6 @@ static uint8_t ps1_audio_read(uint16_t port, void *p) temp |= 0x08; /*FIFO full*/ if (ps1->fifo_read_idx == ps1->fifo_write_idx) temp |= 0x04; /*FIFO empty*/ -// pclog("Return status %02x\n", temp); return temp; case 3: /*FIFO timer*/ /*PS/1 technical reference says this should return the current value, @@ -67,13 +65,10 @@ static uint8_t ps1_audio_read(uint16_t port, void *p) static void ps1_audio_write(uint16_t port, uint8_t val, void *p) { ps1_audio_t *ps1 = (ps1_audio_t *)p; - -// pclog("ps1_audio_write %04x %02x\n", port, val); - + switch (port & 7) { case 0: /*DAC output*/ -// pclog("DAC write %08x %08x %i\n", ps1->fifo_write_idx, ps1->fifo_read_idx, ps1->fifo_write_idx - ps1->fifo_read_idx); if ((ps1->fifo_write_idx - ps1->fifo_read_idx) < 2048) { ps1->fifo[ps1->fifo_write_idx & 2047] = val; @@ -114,10 +109,8 @@ static void ps1_audio_callback(void *p) ps1->dac_val = ps1->fifo[ps1->fifo_read_idx & 2047]; ps1->fifo_read_idx++; } -// pclog("ps1_callback %08x %08x %08x\n", ps1->fifo_write_idx, ps1->fifo_read_idx, ps1->fifo_threshold); if ((ps1->fifo_write_idx - ps1->fifo_read_idx) == ps1->fifo_threshold) { -// pclog("FIFO almost empty\n"); ps1->status |= 0x02; /*FIFO almost empty*/ } ps1->status |= 0x10; /*ADC data ready*/ diff --git a/src/sound_pssj.c b/src/sound_pssj.c index 0e4963d5d..bda1442fd 100644 --- a/src/sound_pssj.c +++ b/src/sound_pssj.c @@ -41,7 +41,6 @@ static void pssj_write(uint16_t port, uint8_t val, void *p) { pssj_t *pssj = (pssj_t *)p; -// pclog("pssj_write: port=%04x val=%02x\n", port, val); switch (port & 3) { case 0: @@ -77,7 +76,6 @@ static uint8_t pssj_read(uint16_t port, void *p) { pssj_t *pssj = (pssj_t *)p; -// pclog("pssj_read: port=%04x %02x\n", port, (pssj->ctrl & ~0x88) | (pssj->irq ? 8 : 0)); switch (port & 3) { case 0: @@ -99,7 +97,11 @@ static uint8_t pssj_read(uint16_t port, void *p) return pssj->freq & 0xff; case 3: return (pssj->freq >> 8) | (pssj->amplitude << 4); + default: + return 0xff; } + + return 0xff; } static void pssj_update(pssj_t *pssj) @@ -123,7 +125,6 @@ static void pssj_callback(void *p) if (data != DMA_NODATA) { pssj->dac_val = data & 0xff; -// pclog("DAC_val=%02x\n", data); } } else @@ -133,7 +134,6 @@ static void pssj_callback(void *p) if ((data & DMA_OVER) && data != DMA_NODATA) { -// pclog("Check IRQ %i %02x\n", pssj->irq, pssj->ctrl); if (pssj->ctrl & 0x08) { pssj->irq = 1; diff --git a/src/sound_sb.c b/src/sound_sb.c index 20baaa547..d29f5028e 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -1,6 +1,11 @@ #include #include "ibm.h" #include "device.h" +#include "io.h" +#include "mca.h" +#include "mem.h" +#include "rom.h" +#include "sound.h" #include "sound_emu8k.h" #include "sound_mpu401_uart.h" #include "sound_opl.h" @@ -32,6 +37,8 @@ typedef struct sb_t emu8k_t emu8k; int pos; + + uint8_t pos_regs[8]; } sb_t; static int sb_att[]= @@ -103,7 +110,6 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) sb_dsp_update(&sb->dsp); for (c = 0; c < len * 2; c += 2) { - // int c_emu8k = (((c/2) * 44100) / 48000)*2; int32_t out_l, out_r; out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); @@ -226,8 +232,6 @@ void sb_pro_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->treble_l = mixer->treble_r = 8; sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); -// pclog("%02X %02X %02X\n", mixer->regs[0x04], mixer->regs[0x22], mixer->regs[0x26]); -// pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); if (mixer->index == 0xe) sb_dsp_set_stereo(&sb->dsp, val & 2); } @@ -301,8 +305,6 @@ void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) mixer->filter = 0; sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); -// pclog("%02X %02X %02X %02X %02X %02X\n", mixer->regs[0x30], mixer->regs[0x31], mixer->regs[0x32], mixer->regs[0x33], mixer->regs[0x34], mixer->regs[0x35]); -// pclog("Mixer - %04X %04X %04X %04X %04X %04X\n", mixer->master_l, mixer->master_r, mixer->voice_l, mixer->voice_r, mixer->fm_l, mixer->fm_r); } } @@ -357,7 +359,6 @@ uint8_t sb_16_mixer_read(uint16_t addr, void *p) temp |= 0x00; break; } - // return 0x22; /*DMA 1 and 5*/ return temp; case 0x82: return ((sb->dsp.sb_irq8) ? 1 : 0) | ((sb->dsp.sb_irq16) ? 2 : 0); @@ -377,6 +378,89 @@ void sb_mixer_init(sb_mixer_t *mixer) sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 65535, ((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 65535); } + +static uint16_t sb_mcv_addr[8] = {0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270}; + +uint8_t sb_mcv_read(int port, void *p) +{ + sb_t *sb = (sb_t *)p; + + pclog("sb_mcv_read: port=%04x\n", port); + + return sb->pos_regs[port & 7]; +} + +void sb_mcv_write(int port, uint8_t val, void *p) +{ + uint16_t addr; + sb_t *sb = (sb_t *)p; + + if (port < 0x102) + return; + + pclog("sb_mcv_write: port=%04x val=%02x\n", port, val); + + addr = sb_mcv_addr[sb->pos_regs[4] & 7]; + io_removehandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); + io_removehandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); + sb_dsp_setaddr(&sb->dsp, 0); + + sb->pos_regs[port & 7] = val; + + if (sb->pos_regs[2] & 1) + { + addr = sb_mcv_addr[sb->pos_regs[4] & 7]; + + io_sethandler(addr+8, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); + io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl); + sb_dsp_setaddr(&sb->dsp, addr); + } +} + +static int sb_pro_mcv_irqs[4] = {7, 5, 3, 3}; + +uint8_t sb_pro_mcv_read(int port, void *p) +{ + sb_t *sb = (sb_t *)p; + + pclog("sb_pro_mcv_read: port=%04x\n", port); + + return sb->pos_regs[port & 7]; +} + +void sb_pro_mcv_write(int port, uint8_t val, void *p) +{ + uint16_t addr; + sb_t *sb = (sb_t *)p; + + if (port < 0x102) + return; + + pclog("sb_pro_mcv_write: port=%04x val=%02x\n", port, val); + + addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; + io_removehandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_removehandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_removehandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_removehandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); + sb_dsp_setaddr(&sb->dsp, 0); + + sb->pos_regs[port & 7] = val; + + if (sb->pos_regs[2] & 1) + { + addr = (sb->pos_regs[2] & 0x20) ? 0x220 : 0x240; + + io_sethandler(addr+0, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr+8, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + io_sethandler(addr+4, 0x0002, sb_pro_mixer_read, NULL, NULL, sb_pro_mixer_write, NULL, NULL, sb); + + sb_dsp_setaddr(&sb->dsp, addr); + } + sb_dsp_setirq(&sb->dsp, sb_pro_mcv_irqs[(sb->pos_regs[5] >> 4) & 3]); + sb_dsp_setdma8(&sb->dsp, sb->pos_regs[4] & 3); +} void *sb_1_init() { @@ -412,6 +496,24 @@ void *sb_15_init() sound_add_handler(sb_get_buffer_opl2, sb); return sb; } + +void *sb_mcv_init() +{ + sb_t *sb = malloc(sizeof(sb_t)); + memset(sb, 0, sizeof(sb_t)); + + opl2_init(&sb->opl); + sb_dsp_init(&sb->dsp, SB15); + sb_dsp_setaddr(&sb->dsp, 0); + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma")); + sb_mixer_init(&sb->mixer); + sound_add_handler(sb_get_buffer_opl2, sb); + mca_add(sb_mcv_read, sb_mcv_write, sb); + sb->pos_regs[0] = 0x84; + sb->pos_regs[1] = 0x50; + return sb; +} void *sb_2_init() { sb_t *sb = malloc(sizeof(sb_t)); @@ -485,6 +587,32 @@ void *sb_pro_v2_init() return sb; } +void *sb_pro_mcv_init() +{ + sb_t *sb = malloc(sizeof(sb_t)); + memset(sb, 0, sizeof(sb_t)); + + opl3_init(&sb->opl); + sb_dsp_init(&sb->dsp, SBPRO2); + /*sb_dsp_setaddr(&sb->dsp, addr); + sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); + sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));*/ + sb_mixer_init(&sb->mixer); + io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); + sound_add_handler(sb_get_buffer_opl3, sb); + + sb->mixer.regs[0x22] = 0xff; + sb->mixer.regs[0x04] = 0xff; + sb->mixer.regs[0x26] = 0xff; + sb->mixer.regs[0xe] = 0; + + mca_add(sb_pro_mcv_read, sb_pro_mcv_write, sb); + sb->pos_regs[0] = 0x03; + sb->pos_regs[1] = 0x51; + + return sb; +} + void *sb_16_init() { sb_t *sb = malloc(sizeof(sb_t)); @@ -605,462 +733,367 @@ void sb_add_status_info(char *s, int max_len, void *p) static device_config_t sb_config[] = { { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr", "Address", CONFIG_SELECTION, "", 0x220, { { - .description = "0x220", - .value = 0x220 + "0x220", 0x220 }, { - .description = "0x240", - .value = 0x240 + "0x240", 0x240 }, { - .description = "" + "" } - }, - .default_int = 0x220 + } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 7, { { - .description = "IRQ 2", - .value = 2 + "IRQ 2", 2 }, { - .description = "IRQ 3", - .value = 3 + "IRQ 3", 3 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "" + "" } - }, - .default_int = 7 + } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = + "dma", "DMA", CONFIG_SELECTION, "", 1, { { - .description = "DMA 1", - .value = 1 + "DMA 1", 1 }, { - .description = "DMA 3", - .value = 3 + "DMA 3", 3 }, { - .description = "" + "" } - }, - .default_int = 1 + } }, { - .type = -1 + "", "", -1 + } +}; + +static device_config_t sb_mcv_config[] = +{ + { + "irq", "IRQ", CONFIG_SELECTION, "", 7, + { + { + "IRQ 3", 3 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "" + } + } + }, + { + "dma", "DMA", CONFIG_SELECTION, "", 1, + { + { + "DMA 1", 1 + }, + { + "DMA 3", 3 + }, + { + "" + } + } + }, + { + "", "", -1 } }; static device_config_t sb_pro_config[] = { { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr", "Address", CONFIG_SELECTION, "", 0x220, { { - .description = "0x220", - .value = 0x220 + "0x220", 0x220 }, { - .description = "0x240", - .value = 0x240 + "0x240", 0x240 }, { - .description = "" + "" } - }, - .default_int = 0x220 + } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 7, { { - .description = "IRQ 2", - .value = 2 + "IRQ 2", 2 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "IRQ 10", - .value = 10 + "IRQ 10", 10 }, { - .description = "" + "" } - }, - .default_int = 7 + } }, { - .name = "dma", - .description = "DMA", - .type = CONFIG_SELECTION, - .selection = + "dma", "DMA", CONFIG_SELECTION, "", 1, { { - .description = "DMA 1", - .value = 1 + "DMA 1", 1 }, { - .description = "DMA 3", - .value = 3 + "DMA 3", 3 }, { - .description = "" + "" } - }, - .default_int = 1 + } }, { - .type = -1 + "", "", -1 } }; static device_config_t sb_16_config[] = { { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr", "Address", CONFIG_SELECTION, "", 0x220, { { - .description = "0x220", - .value = 0x220 + "0x220", 0x220 }, { - .description = "0x240", - .value = 0x240 + "0x240", 0x240 }, { - .description = "0x260", - .value = 0x260 + "0x260", 0x260 }, { - .description = "0x280", - .value = 0x280 + "0x280", 0x280 }, { - .description = "" + "" } - }, - .default_int = 0x220 + } }, { - .name = "addr401", - .description = "MPU-401 Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr401", "MPU-401 Address", CONFIG_SELECTION, "", 0x330, { { - .description = "0x300", - .value = 0x300 + "0x300", 0x300 }, { - .description = "0x330", - .value = 0x330 + "0x330", 0x330 }, { - .description = "" + "" } - }, - .default_int = 0x330 + } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 5, { { - .description = "IRQ 2", - .value = 2 + "IRQ 2", 2 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "IRQ 10", - .value = 10 + "IRQ 10", 10 }, { - .description = "" + "" } - }, - .default_int = 5 + } }, { - .name = "dma", - .description = "Low DMA channel", - .type = CONFIG_SELECTION, - .selection = + "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, { { - .description = "DMA 0", - .value = 0 + "DMA 0", 0 }, { - .description = "DMA 1", - .value = 1 + "DMA 1", 1 }, { - .description = "DMA 3", - .value = 3 + "DMA 3", 3 }, { - .description = "" + "" } - }, - .default_int = 1 + } }, { - .name = "dma16", - .description = "High DMA channel", - .type = CONFIG_SELECTION, - .selection = + "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, { { - .description = "DMA 5", - .value = 5 + "DMA 5", 5 }, { - .description = "DMA 6", - .value = 6 + "DMA 6", 6 }, { - .description = "DMA 7", - .value = 7 + "DMA 7", 7 }, { - .description = "" + "" } - }, - .default_int = 5 + } }, { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 + "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, { - .type = -1 + "", "", -1 } }; static device_config_t sb_awe32_config[] = { { - .name = "addr", - .description = "Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr", "Address", CONFIG_SELECTION, "", 0x220, { { - .description = "0x220", - .value = 0x220 + "0x220", 0x220 }, { - .description = "0x240", - .value = 0x240 + "0x240", 0x240 }, { - .description = "0x260", - .value = 0x260 + "0x260", 0x260 }, { - .description = "0x280", - .value = 0x280 + "0x280", 0x280 }, { - .description = "" + "" } - }, - .default_int = 0x220 + } }, { - .name = "addr401", - .description = "MPU-401 Address", - .type = CONFIG_BINARY, - .type = CONFIG_SELECTION, - .selection = + "addr401", "MPU-401 Address", CONFIG_SELECTION, "", 0x330, { { - .description = "0x300", - .value = 0x300 + "0x300", 0x300 }, { - .description = "0x330", - .value = 0x330 + "0x330", 0x330 }, { - .description = "" + "" } - }, - .default_int = 0x330 + } }, { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 5, { { - .description = "IRQ 2", - .value = 2 + "IRQ 2", 2 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "IRQ 10", - .value = 10 + "IRQ 10", 10 }, { - .description = "" + "" } - }, - .default_int = 5 + } }, { - .name = "dma", - .description = "Low DMA channel", - .type = CONFIG_SELECTION, - .selection = + "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, { { - .description = "DMA 0", - .value = 0 + "DMA 0", 0 }, { - .description = "DMA 1", - .value = 1 + "DMA 1", 1 }, { - .description = "DMA 3", - .value = 3 + "DMA 3", 3 }, { - .description = "" + "" } - }, - .default_int = 1 + } }, { - .name = "dma16", - .description = "High DMA channel", - .type = CONFIG_SELECTION, - .selection = + "dma16", "High DMA channel", CONFIG_SELECTION, "", 5, { { - .description = "DMA 5", - .value = 5 + "DMA 5", 5 }, { - .description = "DMA 6", - .value = 6 + "DMA 6", 6 }, { - .description = "DMA 7", - .value = 7 + "DMA 7", 7 }, { - .description = "" + "" } - }, - .default_int = 5 + } }, { - .name = "midi", - .description = "MIDI out device", - .type = CONFIG_MIDI, - .default_int = 0 + "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, { - .name = "onboard_ram", - .description = "Onboard RAM", - .type = CONFIG_SELECTION, - .selection = + "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, { { - .description = "None", - .value = 0 + "None", 0 }, { - .description = "512 KB", - .value = 512 + "512 KB", 512 }, { - .description = "2 MB", - .value = 2048 + "2 MB", 2048 }, { - .description = "8 MB", - .value = 8192 + "8 MB", 8192 }, { - .description = "28 MB", - .value = 28*1024 + "28 MB", 28*1024 }, { - .description = "" + "" } - }, - .default_int = 512 + } }, { - .type = -1 + "", "", -1 } }; @@ -1088,6 +1121,18 @@ device_t sb_15_device = sb_add_status_info, sb_config }; +device_t sb_mcv_device = +{ + "Sound Blaster MCV", + DEVICE_MCA, + sb_mcv_init, + sb_close, + NULL, + sb_speed_changed, + NULL, + sb_add_status_info, + sb_mcv_config +}; device_t sb_2_device = { "Sound Blaster v2.0", @@ -1124,6 +1169,18 @@ device_t sb_pro_v2_device = sb_add_status_info, sb_pro_config }; +device_t sb_pro_mcv_device = +{ + "Sound Blaster Pro MCV", + DEVICE_MCA, + sb_pro_mcv_init, + sb_close, + NULL, + sb_speed_changed, + NULL, + sb_add_status_info, + NULL +}; device_t sb_16_device = { "Sound Blaster 16", diff --git a/src/sound_sb.h b/src/sound_sb.h index 81130fecd..4a0b974b8 100644 --- a/src/sound_sb.h +++ b/src/sound_sb.h @@ -1,7 +1,9 @@ extern device_t sb_1_device; extern device_t sb_15_device; +extern device_t sb_mcv_device; extern device_t sb_2_device; extern device_t sb_pro_v1_device; extern device_t sb_pro_v2_device; +extern device_t sb_pro_mcv_device; extern device_t sb_16_device; extern device_t sb_awe32_device; diff --git a/src/sound_sb_dsp.c b/src/sound_sb_dsp.c index 40dd6e0e7..13298d446 100644 --- a/src/sound_sb_dsp.c +++ b/src/sound_sb_dsp.c @@ -100,7 +100,6 @@ uint16_t sb_dsp_versions[] = {0, 0, 0x105, 0x200, 0x201, 0x300, 0x302, 0x405, 0x void sb_irq(sb_dsp_t *dsp, int irq8) { -// pclog("IRQ %i %02X\n",irq8,pic.mask); if (irq8) dsp->sb_irq8 = 1; else dsp->sb_irq16 = 1; picint(1 << dsp->sb_irqnum); @@ -193,7 +192,6 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len timer_update_outstanding(); dsp->sbleftright = 0; dsp->sbdacpos = 0; -// pclog("Start 8-bit DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); } else { @@ -207,7 +205,6 @@ void sb_start_dma(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int len timer_process(); dsp->sbenable = dsp->sb_16_enable; timer_update_outstanding(); -// pclog("Start 16-bit DMA addr %06X len %04X\n",dma16.ac[1]+(dma16.page[1]<<16),len); } } @@ -225,7 +222,6 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l timer_process(); dsp->sb_enable_i = dsp->sb_8_enable; timer_update_outstanding(); -// pclog("Start 8-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); } else { @@ -239,7 +235,6 @@ void sb_start_dma_i(sb_dsp_t *dsp, int dma8, int autoinit, uint8_t format, int l timer_process(); dsp->sb_enable_i = dsp->sb_16_enable; timer_update_outstanding(); -// pclog("Start 16-bit input DMA addr %06X len %04X\n",dma.ac[1]+(dma.page[1]<<16),len); } } @@ -278,7 +273,6 @@ void sb_dsp_setdma16(sb_dsp_t *dsp, int dma) void sb_exec_command(sb_dsp_t *dsp) { int temp,c; -// pclog("sb_exec_command : SB command %02X\n", dsp->sb_command); switch (dsp->sb_command) { case 0x01: /*???*/ @@ -298,7 +292,6 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x17: /*2-bit ADPCM output with reference*/ dsp->sbref = sb_8_read_dma(dsp); dsp->sbstep = 0; -// pclog("Ref byte 2 %02X\n",sbref); case 0x16: /*2-bit ADPCM output*/ sb_start_dma(dsp, 1, 0, ADPCM_2, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = sb_8_read_dma(dsp); @@ -329,14 +322,12 @@ void sb_exec_command(sb_dsp_t *dsp) dsp->sblatcho = dsp->sblatchi = TIMER_USEC * (256 - dsp->sb_data[0]); temp = 256 - dsp->sb_data[0]; temp = 1000000 / temp; -// pclog("Sample rate - %ihz (%i)\n",temp, dsp->sblatcho); dsp->sb_freq = temp; break; case 0x41: /*Set output sampling rate*/ case 0x42: /*Set input sampling rate*/ if (dsp->sb_type < SB16) break; dsp->sblatcho = (int)(TIMER_USEC * (1000000.0f / (float)(dsp->sb_data[1] + (dsp->sb_data[0] << 8)))); -// pclog("Sample rate - %ihz (%i)\n",dsp->sb_data[1]+(dsp->sb_data[0]<<8), dsp->sblatcho); dsp->sb_freq = dsp->sb_data[1] + (dsp->sb_data[0] << 8); dsp->sb_timeo = 256 + dsp->sb_freq; dsp->sblatchi = dsp->sblatcho; @@ -348,7 +339,6 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x75: /*4-bit ADPCM output with reference*/ dsp->sbref = sb_8_read_dma(dsp); dsp->sbstep = 0; -// pclog("Ref byte 4 %02X\n",sbref); case 0x74: /*4-bit ADPCM output*/ sb_start_dma(dsp, 1, 0, ADPCM_4, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = sb_8_read_dma(dsp); @@ -357,7 +347,6 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x77: /*2.6-bit ADPCM output with reference*/ dsp->sbref = sb_8_read_dma(dsp); dsp->sbstep = 0; -// pclog("Ref byte 26 %02X\n",sbref); case 0x76: /*2.6-bit ADPCM output*/ sb_start_dma(dsp, 1, 0, ADPCM_26, dsp->sb_data[0] + (dsp->sb_data[1] << 8)); dsp->sbdat2 = sb_8_read_dma(dsp); @@ -377,7 +366,6 @@ void sb_exec_command(sb_dsp_t *dsp) break; case 0x80: /*Pause DAC*/ dsp->sb_pausetime = dsp->sb_data[0] + (dsp->sb_data[1] << 8); -// pclog("SB pause %04X\n",sb_pausetime); timer_process(); dsp->sbenable = 1; timer_update_outstanding(); @@ -483,7 +471,6 @@ void sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, dsp->sb_test); break; case 0xF2: /*Trigger 8-bit IRQ*/ -// pclog("Trigger IRQ\n"); sb_irq(dsp, 1); break; case 0xE7: /*???*/ @@ -499,13 +486,10 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x0E: /*ASP set register*/ if (dsp->sb_type < SB16) break; dsp->sb_asp_regs[dsp->sb_data[0]] = dsp->sb_data[1]; -// pclog("ASP write reg %02X %02X\n", sb_data[0], sb_data[1]); break; case 0x0F: /*ASP get register*/ if (dsp->sb_type < SB16) break; -// sb_add_data(0); sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); -// pclog("ASP read reg %02X %02X\n", sb_data[0], sb_asp_regs[sb_data[0]]); break; case 0xF9: if (dsp->sb_type < SB16) break; @@ -516,15 +500,12 @@ void sb_exec_command(sb_dsp_t *dsp) case 0x04: case 0x05: break; -// default: -// fatal("Exec bad SB command %02X\n",sb_command); } } void sb_write(uint16_t a, uint8_t v, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *)priv; -// pclog("sb_write : Write soundblaster %04X %02X %04X:%04X %02X\n",a,v,CS,pc,dsp->sb_command); switch (a&0xF) { case 6: /*Reset*/ @@ -542,7 +523,6 @@ void sb_write(uint16_t a, uint8_t v, void *priv) timer_update_outstanding(); if (dsp->asp_data_len) { -// pclog("ASP data %i\n", dsp->asp_data_len); dsp->asp_data_len--; if (!dsp->asp_data_len) sb_add_data(dsp, 0); @@ -553,8 +533,6 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sb_command = v; if (v == 0x01) sb_add_data(dsp, 0); -// if (sb_commands[v]==-1) -// fatal("Bad SB command %02X\n",v); dsp->sb_data_stat++; } else @@ -571,8 +549,6 @@ void sb_write(uint16_t a, uint8_t v, void *priv) uint8_t sb_read(uint16_t a, void *priv) { sb_dsp_t *dsp = (sb_dsp_t *)priv; -// if (a==0x224) output=1; -// pclog("sb_read : Read soundblaster %04X %04X:%04X\n",a,CS,pc); switch (a & 0xf) { case 0xA: /*Read data*/ @@ -582,7 +558,6 @@ uint8_t sb_read(uint16_t a, void *priv) dsp->sb_read_rp++; dsp->sb_read_rp &= 0xFF; } -// pclog("SB read %02X\n",sbreaddat); return dsp->sbreaddat; case 0xC: /*Write data ready*/ if (dsp->wb_full) @@ -627,7 +602,6 @@ void sb_dsp_init(sb_dsp_t *dsp, int type) void sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr) { -// pclog("sb_dsp_setaddr : %04X\n", addr); io_removehandler(dsp->sb_addr + 6, 0x0002, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); io_removehandler(dsp->sb_addr + 0xa, 0x0006, sb_read, NULL, NULL, sb_write, NULL, NULL, dsp); dsp->sb_addr = addr; @@ -649,13 +623,11 @@ void pollsb(void *p) int tempi,ref; dsp->sbcount += dsp->sblatcho; -// pclog("PollSB %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && dsp->sb_8_output) { int data[2]; sb_dsp_update(dsp); -// pclog("Dopoll %i %02X %i\n", sb_8_length, sb_8_format, sblatcho); switch (dsp->sb_8_format) { case 0x00: /*Mono unsigned*/ @@ -805,9 +777,6 @@ void pollsb(void *p) else dsp->sbdatl = dsp->sbdatr = dsp->sbdat; break; - -// default: - //fatal("Unrecognised SB 8-bit format %02X\n",sb_8_format); } if (dsp->sb_8_length < 0) @@ -841,14 +810,10 @@ void pollsb(void *p) dsp->sbdatr = sb_16_read_dma(dsp); dsp->sb_16_length -= 2; break; - -// default: -// fatal("Unrecognised SB 16-bit format %02X\n",sb_16_format); } if (dsp->sb_16_length < 0) { -// pclog("16DMA over %i\n",dsp->sb_16_autoinit); if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen; else dsp->sb_16_enable = dsp->sbenable = 0; sb_irq(dsp, 0); @@ -861,7 +826,6 @@ void pollsb(void *p) { sb_irq(dsp, 1); dsp->sbenable = dsp->sb_8_enable; -// pclog("SB pause over\n"); } } } @@ -871,7 +835,6 @@ void sb_poll_i(void *p) sb_dsp_t *dsp = (sb_dsp_t *)p; dsp->sb_count_i += dsp->sblatchi; -// pclog("PollSBi %i %i %i %i\n",sb_8_enable,sb_8_pause,sb_pausetime,sb_8_output); if (dsp->sb_8_enable && !dsp->sb_8_pause && dsp->sb_pausetime < 0 && !dsp->sb_8_output) { switch (dsp->sb_8_format) @@ -894,14 +857,10 @@ void sb_poll_i(void *p) sb_8_write_dma(dsp, 0x00); dsp->sb_8_length -= 2; break; - -// default: -// fatal("Unrecognised SB 8-bit input format %02X\n",sb_8_format); } if (dsp->sb_8_length < 0) { -// pclog("Input DMA over %i\n",sb_8_autoinit); if (dsp->sb_8_autoinit) dsp->sb_8_length = dsp->sb_8_autolen; else dsp->sb_8_enable = dsp->sbenable = 0; sb_irq(dsp, 1); @@ -929,14 +888,10 @@ void sb_poll_i(void *p) sb_16_write_dma(dsp, 0); dsp->sb_16_length -= 2; break; - -// default: -// fatal("Unrecognised SB 16-bit input format %02X\n",sb_16_format); } if (dsp->sb_16_length < 0) { -// pclog("16iDMA over %i\n",sb_16_autoinit); if (dsp->sb_16_autoinit) dsp->sb_16_length = dsp->sb_16_autolen; else dsp->sb_16_enable = dsp->sbenable = 0; sb_irq(dsp, 0); @@ -956,7 +911,6 @@ void sb_dsp_update(sb_dsp_t *dsp) void sb_dsp_add_status_info(char *s, int max_len, sb_dsp_t *dsp) { char temps[128]; - int len; int freq; if (dsp->sb_timeo < 256) diff --git a/src/sound_sn76489.c b/src/sound_sn76489.c index 2dae07669..7d6fe80a1 100644 --- a/src/sound_sn76489.c +++ b/src/sound_sn76489.c @@ -1,4 +1,5 @@ #include +#include #include "ibm.h" #include "device.h" #include "io.h" @@ -15,8 +16,6 @@ static float volslog[16]= 7.51785f,9.46440f,11.9194f,15.0000f }; -//#define PSGCONST ((3579545.0 / 64.0) / 48000.0) - void sn76489_update(sn76489_t *sn76489) { for (; sn76489->pos < sound_pos_global; sn76489->pos++) diff --git a/src/sound_speaker.c b/src/sound_speaker.c index 8e678253e..f4bc7086d 100644 --- a/src/sound_speaker.c +++ b/src/sound_speaker.c @@ -15,7 +15,6 @@ void speaker_update() { int16_t val; -// printf("SPeaker - %i %i %i %02X\n",speakval,gated,speakon,pit.m[2]); for (; speaker_pos < sound_pos_global; speaker_pos++) { if (speaker_gated && was_speaker_enable) diff --git a/src/sound_ssi2001.c b/src/sound_ssi2001.c index fd675c309..d0a7e2136 100644 --- a/src/sound_ssi2001.c +++ b/src/sound_ssi2001.c @@ -1,6 +1,7 @@ #include #include "ibm.h" #include "device.h" +#include "io.h" #include "sound.h" #include "sound_resid.h" diff --git a/src/sound_wss.c b/src/sound_wss.c index b5fecd08f..f8a5bcbd6 100644 --- a/src/sound_wss.c +++ b/src/sound_wss.c @@ -10,6 +10,7 @@ #include "dma.h" #include "io.h" #include "pic.h" +#include "sound.h" #include "sound_ad1848.h" #include "sound_opl.h" #include "sound_wss.h" @@ -27,7 +28,6 @@ static int wss_dma[4] = {0, 0, 1, 3}; static int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /*W95 only uses 7-9, others may be wrong*/ -static uint16_t wss_addr[4] = {0x530, 0x604, 0xe80, 0xf40}; typedef struct wss_t { @@ -41,16 +41,13 @@ uint8_t wss_read(uint16_t addr, void *p) { wss_t *wss = (wss_t *)p; uint8_t temp; -// pclog("wss_read - addr %04X %04X(%08X):%08X ", addr, CS, cs, pc); temp = 4 | (wss->config & 0x40); -// pclog("return %02X\n", temp); return temp; } void wss_write(uint16_t addr, uint8_t val, void *p) { wss_t *wss = (wss_t *)p; -// pclog("wss_write - addr %04X val %02X %04X(%08X):%08X\n", addr, val, CS, cs, pc); wss->config = val; ad1848_setdma(&wss->ad1848, wss_dma[val & 3]); @@ -78,8 +75,6 @@ static void wss_get_buffer(int32_t *buffer, int len, void *p) void *wss_init() { wss_t *wss = malloc(sizeof(wss_t)); - int c; - double attenuation; memset(wss, 0, sizeof(wss_t)); diff --git a/src/sound_ym7128.c b/src/sound_ym7128.c index 7c1aa06ff..be0b3946c 100644 --- a/src/sound_ym7128.c +++ b/src/sound_ym7128.c @@ -27,46 +27,37 @@ void ym7128_write(ym7128_t *ym7128, uint8_t val) int new_dat = val & 1; int new_sci = val & 2; int new_a0 = val & 4; -// pclog("ym7128_write %i %i %i\n", new_dat, new_sci, new_a0); if (!ym7128->sci && new_sci) ym7128->dat = (ym7128->dat << 1) | new_dat; if (ym7128->a0 != new_a0) { -// pclog("ym7128 write %i %02x\n", ym7128->a0, ym7128->dat); if (!ym7128->a0) ym7128->reg_sel = ym7128->dat & 0x1f; else { -// pclog("YM7128 write %02x %02x\n", ym7128->reg_sel, ym7128->dat); switch (ym7128->reg_sel) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x04: case 0x05: case 0x06: case 0x07: ym7128->gl[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); -// pclog(" GL[%i] = %04x\n", ym7128->reg_sel & 7, GET_ATTENUATION(ym7128->dat)); break; case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: ym7128->gr[ym7128->reg_sel & 7] = GET_ATTENUATION(ym7128->dat); -// pclog(" GR[%i] = %04x\n", ym7128->reg_sel & 7, GET_ATTENUATION(ym7128->dat)); break; case 0x10: ym7128->vm = GET_ATTENUATION(ym7128->dat); -// pclog(" VM = %04x\n", GET_ATTENUATION(ym7128->dat)); break; case 0x11: ym7128->vc = GET_ATTENUATION(ym7128->dat); -// pclog(" VC = %04x\n", GET_ATTENUATION(ym7128->dat)); break; case 0x12: ym7128->vl = GET_ATTENUATION(ym7128->dat); -// pclog(" VL = %04x\n", GET_ATTENUATION(ym7128->dat)); break; case 0x13: ym7128->vr = GET_ATTENUATION(ym7128->dat); -// pclog(" VR = %04x\n", GET_ATTENUATION(ym7128->dat)); break; case 0x14: @@ -83,7 +74,6 @@ void ym7128_write(ym7128_t *ym7128, uint8_t val) case 0x16: case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: ym7128->t[ym7128->reg_sel - 0x16] = tap_position[ym7128->dat & 0x1f]; -// pclog(" T[%i] = %i\n", ym7128->reg_sel - 0x16, tap_position[ym7128->dat & 0x1f]); break; } ym7128->regs[ym7128->reg_sel] = ym7128->dat; diff --git a/src/soundopenal.c b/src/soundopenal.c index 45322c1a8..8cb065fbd 100644 --- a/src/soundopenal.c +++ b/src/soundopenal.c @@ -12,9 +12,9 @@ FILE *allog; #ifdef USE_OPENAL -ALuint buffers[4]; // front and back buffers -ALuint buffers_cd[4]; // front and back buffers -static ALuint source[2]; // audio source +ALuint buffers[4]; /* front and back buffers */ +ALuint buffers_cd[4]; /* front and back buffers */ +static ALuint source[2]; /* audio source */ #endif #define FREQ 48000 #define BUFLEN SOUNDBUFLEN @@ -25,13 +25,13 @@ ALvoid alutInit(ALint *argc,ALbyte **argv) ALCcontext *Context; ALCdevice *Device; - //Open device - Device=alcOpenDevice((ALubyte*)""); - //Create context(s) + /* Open device */ + Device=alcOpenDevice((ALCchar *)""); + /* Create context(s) */ Context=alcCreateContext(Device,NULL); - //Set active context + /* Set active context */ alcMakeContextCurrent(Context); - //Register extensions + /* Register extensions */ } ALvoid alutExit(ALvoid) @@ -39,26 +39,24 @@ ALvoid alutExit(ALvoid) ALCcontext *Context; ALCdevice *Device; - //Unregister extensions + /* Unregister extensions */ - //Get active context + /* Get active context */ Context=alcGetCurrentContext(); - //Get device for active context + /* Get device for active context */ Device=alcGetContextsDevice(Context); - //Disable context + /* Disable context */ alcMakeContextCurrent(NULL); - //Release context(s) + /* Release context(s) */ alcDestroyContext(Context); - //Close device + /* Close device */ alcCloseDevice(Device); } void initalmain(int argc, char *argv[]) { #ifdef USE_OPENAL alutInit(0,0); -// printf("AlutInit\n"); atexit(closeal); -// printf("AlutInit\n"); #endif } @@ -69,18 +67,6 @@ void closeal() #endif } -void check() -{ -#ifdef USE_OPENAL - ALenum error; - if ((error = alGetError()) != AL_NO_ERROR) - { -// printf("Error : %08X\n", error); -// exit(-1); - } -#endif -} - void inital() { #ifdef USE_OPENAL @@ -89,37 +75,25 @@ void inital() float cd_buf[CD_BUFLEN*2]; -// printf("1\n"); - check(); - -// printf("2\n"); alGenBuffers(4, buffers); - check(); alGenBuffers(4, buffers_cd); - check(); -// printf("3\n"); alGenSources(2, source); - check(); -// printf("4\n"); alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); - check(); alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); - check(); memset(buf,0,BUFLEN*2*sizeof(float)); memset(cd_buf,0,BUFLEN*2*sizeof(float)); -// printf("5\n"); for (c = 0; c < 4; c++) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); @@ -127,81 +101,35 @@ void inital() } alSourceQueueBuffers(source[0], 4, buffers); - check(); alSourceQueueBuffers(source[1], 4, buffers_cd); - check(); -// printf("6 %08X\n",source); alSourcePlay(source[0]); - check(); alSourcePlay(source[1]); - check(); -// printf("InitAL!!! %08X\n",source); #endif } void givealbuffer(float *buf) { #ifdef USE_OPENAL - int16_t buf16[BUFLEN*2]; int processed; int state; - - //return; - -// printf("Start\n"); - check(); - -// printf("GiveALBuffer %08X\n",source); - + ALuint buffer; + alGetSourcei(source[0], AL_SOURCE_STATE, &state); - check(); - if (state==0x1014) { alSourcePlay(source[0]); -// printf("Resetting sound\n"); } -// printf("State - %i %08X\n",state,state); alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); -// printf("P "); - check(); -// printf("Processed - %i\n",processed); - if (processed>=1) { - int c; - ALuint buffer; - alSourceUnqueueBuffers(source[0], 1, &buffer); -// printf("U "); - check(); - /* for (c=0;c 32767) - buf16[c] = 32767; - else - buf16[c] = buf[c]; - } */ -// for (c=0;c=1) { ALuint buffer; alSourceUnqueueBuffers(source[1], 1, &buffer); -// printf("U "); - check(); -// for (c=0;c #include "ibm.h" #include "device.h" +#include "io.h" #include "tandy_eeprom.h" typedef struct @@ -34,7 +35,6 @@ void tandy_eeprom_write(uint16_t addr, uint8_t val, void *p) if ((val & 4) && !eeprom->clock) { -// pclog("eeprom_write %02x %i %i\n", val, eeprom->state, eeprom->count); switch (eeprom->state) { case EEPROM_IDLE: @@ -65,7 +65,6 @@ void tandy_eeprom_write(uint16_t addr, uint8_t val, void *p) if (eeprom->count == 8) { eeprom->count = 0; -// pclog("EEPROM get operation %02x\n", eeprom->data); eeprom->addr = eeprom->data & 0x3f; switch (eeprom->data & 0xc0) { @@ -75,7 +74,6 @@ void tandy_eeprom_write(uint16_t addr, uint8_t val, void *p) case 0x80: eeprom->state = EEPROM_READ; eeprom->data = eeprom->store[eeprom->addr]; -// pclog("EEPROM read data %02x %04x\n", eeprom->addr, eeprom->data); break; default: eeprom->state = EEPROM_IDLE; @@ -101,7 +99,6 @@ void tandy_eeprom_write(uint16_t addr, uint8_t val, void *p) { eeprom->count = 0; eeprom->state = EEPROM_IDLE; -// pclog("EEPROM write %04x to %02x\n", eeprom->data, eeprom->addr); eeprom->store[eeprom->addr] = eeprom->data; } break; @@ -113,7 +110,6 @@ void tandy_eeprom_write(uint16_t addr, uint8_t val, void *p) int tandy_eeprom_read() { -// pclog("tandy_eeprom_read: data_out=%x\n", eeprom_data_out); return eeprom_data_out; } diff --git a/src/tandy_rom.c b/src/tandy_rom.c index bfa8738ef..fb4c6bdfd 100644 --- a/src/tandy_rom.c +++ b/src/tandy_rom.c @@ -4,6 +4,7 @@ #include #include "ibm.h" #include "device.h" +#include "io.h" #include "mem.h" #include "tandy_rom.h" @@ -15,19 +16,15 @@ static mem_mapping_t tandy_rom_mapping; uint8_t tandy_read_rom(uint32_t addr, void *p) { uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; -// if (!nopageerrors) pclog("tandy_read_rom: %05x %05x %02x %04x:%04x\n", addr, addr2, tandy_rom[addr2], CS,pc); return tandy_rom[addr2]; } uint16_t tandy_read_romw(uint32_t addr, void *p) { uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; -// if (!nopageerrors) pclog("tandy_read_romw: %05x %05x %04x %04x:%04x\n", addr, addr2, *(uint16_t *)&tandy_rom[addr2], CS,pc); return *(uint16_t *)&tandy_rom[addr2]; } uint32_t tandy_read_roml(uint32_t addr, void *p) { - uint32_t addr2 = (addr & 0xffff) + tandy_rom_offset; -// if (!nopageerrors) pclog("tandy_read_roml: %05x %05x %08x\n", addr, addr2, *(uint32_t *)&tandy_rom[addr2]); return *(uint32_t *)&tandy_rom[addr]; } @@ -45,10 +42,7 @@ void tandy_rom_bank_write(uint16_t port, uint8_t val, void *p) tandy_rom_bank = val; tandy_rom_offset = ((val ^ 4) & 7) * 0x10000; mem_mapping_set_exec(&tandy_rom_mapping, &tandy_rom[tandy_rom_offset]); -// pclog("tandy_rom_bank_write: port=%04x val=%02x offset=%05x\n", port, val, tandy_rom_offset); } -// else -// pclog("Bad tandy write port=%04x val=%02x\n", port, val); } void *tandy_rom_init() diff --git a/src/timer.c b/src/timer.c index 7020fdf6c..07cc7c336 100644 --- a/src/timer.c +++ b/src/timer.c @@ -30,7 +30,6 @@ int timer_start = 0; void timer_process() { int c; - int retry; int process = 0; /*Get actual elapsed time*/ int diff = timer_latch - timer_count; @@ -93,7 +92,6 @@ void timer_reset() pclog("timer_reset\n"); timers_present = 0; timer_latch = timer_count = 0; -// timer_process(); } int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv) @@ -109,12 +107,11 @@ int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv) { if (timers[i].present && (timers[i].callback == callback) && (timers[i].priv == priv) && (timers[i].count == count) && (timers[i].enable == enable)) { - return; + return 0; } } } -// pclog("timer_add : adding timer %i\n", timers_present); timers[timers_present].present = 1; timers[timers_present].callback = callback; timers[timers_present].priv = priv; diff --git a/src/um8669f.c b/src/um8669f.c index 63b7fffc4..a20b1589e 100644 --- a/src/um8669f.c +++ b/src/um8669f.c @@ -21,6 +21,13 @@ C1 bits 7-6 = LPT1 mode : 11 = ECP/EPP, 01 = EPP, 10 = SPP bit 3 = clear when LPT1 = 278 +Added by OBattler based on more sources: + C2 + bit 2 = I430FX: floppy drive swap (1 = swap, 0 = do not swap) + I430VX: DENSEL polarity + bits 3-6 = IR stuff + bits 3-4 = 00 = Normal, 01 = Infrared (HPSIR), 10 - Amplitude Shift Keyed IR (ASKIR), 11 - Reserved + C3 bits 7-6 = LPT1 DMA mode : 11 = ECP/EPP DMA1, 10 = ECP/EPP DMA3, 01 = EPP/SPP, 00 = ECP bits 5-4 = LPT1 addr : 10 = 278/IRQ5, 01 = 3BC/IRQ7, 00 = 378/IRQ7 @@ -43,6 +50,7 @@ COM2 : #include "disc.h" #include "fdc.h" +#include "fdd.h" #include "io.h" #include "lpt.h" #include "serial.h" @@ -55,7 +63,6 @@ static uint8_t um8669f_regs[256]; void um8669f_write(uint16_t port, uint8_t val, void *priv) { int temp; -// pclog("um8669f_write : port=%04x reg %02X = %02X locked=%i\n", port, um8669f_curreg, val, um8669f_locked); if (um8669f_locked) { if (port == 0x108 && val == 0xaa) @@ -105,7 +112,20 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) case 3: serial2_set(0x2e8, 3); break; } } - + + if (um8669f_curreg == 0xC2) + { + /* Make sure to invert this. */ + if (romset == ROM_430VX) + { + fdc_update_densel_polarity(val & 4 ? 0 : 1); + } + else + { + fdd_setswap(val & 4 ? 1 : 0); + } + } + lpt1_remove(); lpt2_remove(); temp = (um8669f_regs[0xc3] >> 4) & 3; @@ -121,7 +141,6 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) uint8_t um8669f_read(uint16_t port, void *priv) { -// pclog("um8669f_read : port=%04x reg %02X locked=%i\n", port, um8669f_curreg, um8669f_locked); if (um8669f_locked) return 0xff; diff --git a/src/usb.c b/src/usb.c index 9a1d424c0..330f408de 100644 --- a/src/usb.c +++ b/src/usb.c @@ -10,7 +10,7 @@ #include "usb.h" -uint8_t (*usb_packet_handle[32])(usb_packet_t* packet, void *priv); +void (*usb_packet_handle[32])(usb_packet_t* packet, void *priv); void *usb_priv[32]; static int usb_min_card, usb_max_card; @@ -45,4 +45,4 @@ void usb_add(void (*packet_handle)(usb_packet_t *packet, void *priv), void *priv return; } } -} \ No newline at end of file +} diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index 110980f41..068d2bcd5 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -30,8 +30,6 @@ void ati18800_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = &ati18800->svga; uint8_t old; -// pclog("ati18800_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -106,8 +104,6 @@ uint8_t ati18800_in(uint16_t addr, void *p) svga_t *svga = &ati18800->svga; uint8_t temp; -// if (addr != 0x3da) pclog("ati18800_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; switch (addr) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 69004067c..821185883 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -34,8 +34,6 @@ void ati28800_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = &ati28800->svga; uint8_t old; -// pclog("ati28800_out : %04X %02X %04X:%04X\n", addr, val, CS,cpu_state.pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; @@ -104,8 +102,6 @@ uint8_t ati28800_in(uint16_t addr, void *p) svga_t *svga = &ati28800->svga; uint8_t temp; -// if (addr != 0x3da) pclog("ati28800_in : %04X ", addr); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; switch (addr) @@ -158,7 +154,6 @@ void ati28800_svga_recalctimings(ati28800_t *ati28800) { double crtcconst; double _dispontime, _dispofftime, disptime; - int hdisp_old; svga_t *svga = &ati28800->svga; svga->vtotal = svga->crtc[6]; @@ -280,8 +275,6 @@ void ati28800_svga_recalctimings(ati28800_t *ati28800) } } -// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); - svga->linedbl = svga->crtc[9] & 0x80; svga->rowcount = svga->crtc[9] & 31; if (svga->recalctimings_ex) @@ -295,7 +288,6 @@ void ati28800_svga_recalctimings(ati28800_t *ati28800) disptime = svga->htotal; _dispontime = svga->hdisp_time; -// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; @@ -313,15 +305,16 @@ void ati28800_svga_recalctimings(ati28800_t *ati28800) void ati28800_recalctimings(svga_t *svga) { ati28800_t *ati28800 = (ati28800_t *)svga->p; + uint8_t clock_sel = (svga->miscout >> 2) & 3; + double freq; + #ifndef RELEASE_BUILD pclog("ati28800_recalctimings\n"); #endif svga->interlace = (!svga->scrblank && (ati28800->regs[0x3e] & 2)); - uint8_t clock_sel = (svga->miscout >> 2) & 3; clock_sel |= (ati28800->regs[0x39] & 2) << 2; clock_sel |= (ati28800->regs[0x3e] & 0x10) >> 1; - double freq; switch(clock_sel) { case 0x00: freq = 42954000; break; @@ -446,58 +439,45 @@ void ati28800_add_status_info(char *s, int max_len, void *p) static device_config_t ati28800_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 512, { { - .description = "256 kB", - .value = 256 + "256 kB", 256 }, { - .description = "512 kB", - .value = 512 + "512 kB", 512 }, { - .description = "" + "" } - }, - .default_int = 512 + } }, { - .type = -1 + "", "", -1 } }; static device_config_t ati28800_wonderxl_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 512, { { - .description = "256 kB", - .value = 256 + "256 kB", 256 }, { - .description = "512 kB", - .value = 512 + "512 kB", 512 }, { - .description = "1 MB", - .value = 1024 + "1 MB", 1024 }, { - .description = "" + "" } - }, - .default_int = 512 + } }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_ati68860_ramdac.c b/src/vid_ati68860_ramdac.c index 58cc899c0..a8c2f132d 100644 --- a/src/vid_ati68860_ramdac.c +++ b/src/vid_ati68860_ramdac.c @@ -30,7 +30,6 @@ bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) { -// pclog("ati68860_out : addr %04X val %02X %04X:%04X\n", addr, val, CS,pc); switch (addr) { case 0: @@ -151,7 +150,6 @@ uint8_t ati68860_ramdac_in(uint16_t addr, ati68860_ramdac_t *ramdac, svga_t *svg ret = ramdac->regs[addr & 0xf]; break; } -// pclog("ati68860_in : addr %04X ret %02X %04X:%04X\n", addr, ret, CS,pc); return ret; } diff --git a/src/vid_ati_eeprom.c b/src/vid_ati_eeprom.c index 8111c30ab..ffc2a04d8 100644 --- a/src/vid_ati_eeprom.c +++ b/src/vid_ati_eeprom.c @@ -57,7 +57,6 @@ void ati_eeprom_save(ati_eeprom_t *eeprom) void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) { int c; -// pclog("EEPROM write %i %i %i\n", ena, clk, dat); if (!ena) { eeprom->out = 1; @@ -73,7 +72,6 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) } else if (ena) { -// pclog("EEPROM receive %i %i %i\n", ena, clk, dat); switch (eeprom->state) { case EEPROM_WAIT: @@ -86,7 +84,6 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) eeprom->count--; if (!eeprom->count) { -// pclog("EEPROM opcode - %i\n", eeprom->opcode); switch (eeprom->opcode) { case EEPROM_OP_WRITE: @@ -118,11 +115,9 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) eeprom->count--; if (!eeprom->count) { -// pclog("EEPROM dat - %02X\n", eeprom->dat); switch (eeprom->opcode) { case EEPROM_OP_WRITE: -// pclog("EEPROM_OP_WRITE addr %02X eeprom_dat %04X\n", (eeprom->dat >> 16) & (eeprom->type ? 255 : 63), eeprom->dat & 0xffff); if (!eeprom->wp) { eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff; @@ -136,10 +131,8 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) eeprom->count = 17; eeprom->state = EEPROM_OUTPUT; eeprom->dat = eeprom->data[eeprom->dat]; -// pclog("Trigger EEPROM_OUTPUT %04X\n", eeprom->dat); break; case EEPROM_OP_EW: -// pclog("EEPROM_OP_EW %i\n", eeprom->dat); switch (eeprom->dat) { case EEPROM_OP_EWDS: @@ -165,7 +158,6 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) break; case EEPROM_OP_ERASE: -// pclog("EEPROM_OP_ERASE %i\n", eeprom->dat); if (!eeprom->wp) { eeprom->data[eeprom->dat] = 0xffff; @@ -176,7 +168,6 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) break; case EEPROM_OP_WRALMAIN: -// pclog("EEPROM_OP_WRAL %04X\n", eeprom->dat); if (!eeprom->wp) { for (c = 0; c < 256; c++) @@ -202,11 +193,9 @@ void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat) case EEPROM_OUTPUT: eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0; eeprom->dat <<= 1; -// pclog("EEPROM_OUTPUT - data %i\n", eeprom->out); eeprom->count--; if (!eeprom->count) { -// pclog("EEPROM_OUTPUT complete\n"); eeprom->state = EEPROM_IDLE; } break; diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index f2faa8138..46d7f53a7 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -9,12 +9,11 @@ #include "thread.h" #include "video.h" #include "vid_svga.h" +#include "vid_svga_render.h" #include "vid_ati68860_ramdac.h" #include "vid_ati_eeprom.h" #include "vid_ics2595.h" -//#define MACH64_DEBUG - #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) @@ -40,11 +39,18 @@ typedef struct uint32_t val; } fifo_entry_t; +enum +{ + MACH64_GX = 0, + MACH64_VT2 +}; + typedef struct mach64_t { mem_mapping_t linear_mapping; mem_mapping_t mmio_mapping; mem_mapping_t mmio_linear_mapping; + mem_mapping_t mmio_linear_mapping_2; ati68860_ramdac_t ramdac; ati_eeprom_t eeprom; @@ -55,6 +61,8 @@ typedef struct mach64_t uint8_t regs[256]; int index; + + int type; uint8_t pci_regs[256]; @@ -179,6 +187,34 @@ typedef struct mach64_t int blitter_busy; uint64_t blitter_time; uint64_t status_time; + + uint16_t pci_id; + uint32_t config_chip_id; + uint32_t block_decoded_io; + + int pll_addr; + uint8_t pll_regs[16]; + double pll_freq[4]; + + uint32_t config_stat0; + + uint32_t cur_clr0, cur_clr1; + + uint32_t overlay_dat[1024]; + uint32_t overlay_graphics_key_clr, overlay_graphics_key_msk; + uint32_t overlay_video_key_clr, overlay_video_key_msk; + uint32_t overlay_key_cntl; + uint32_t overlay_scale_inc; + uint32_t overlay_scale_cntl; + uint32_t overlay_y_x_start, overlay_y_x_end; + + uint32_t scaler_height_width; + int scaler_format; + int scaler_update; + + uint32_t buf_offset[2], buf_pitch[2]; + + int overlay_v_acc; } mach64_t; enum @@ -272,8 +308,6 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; -// pclog("mach64 out %04X %02X\n", addr, val); - switch (addr) { case 0x1ce: @@ -286,7 +320,10 @@ void mach64_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, svga); + else + svga_out(addr, val, svga); return; case 0x3cf: @@ -334,8 +371,6 @@ uint8_t mach64_in(uint16_t addr, void *p) if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; -// pclog("IN mach64 %04X\n", addr); - switch (addr) { case 0x1ce: @@ -344,7 +379,9 @@ uint8_t mach64_in(uint16_t addr, void *p) return mach64->regs[mach64->index & 0x3f]; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); + if (mach64->type == MACH64_GX) + return ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, svga); + return svga_in(addr, svga); case 0x3D4: return svga->crtcreg; @@ -373,45 +410,48 @@ void mach64_recalctimings(svga_t *svga) svga->linedbl = svga->rowcount = 0; svga->split = 0xffffff; svga->vblankstart = svga->dispend; -// svga_htotal <<= 1; -// svga_hdisp <<= 1; + svga->rowcount = mach64->crtc_gen_cntl & 1; svga->rowoffset <<= 1; - svga->render = mach64->ramdac.render; + if (mach64->type == MACH64_GX) + svga->render = mach64->ramdac.render; switch ((mach64->crtc_gen_cntl >> 8) & 7) { case 1: -// svga->render = svga_render_4bpp_highres; + if (mach64->type != MACH64_GX) + svga->render = svga_render_4bpp_highres; svga->hdisp *= 8; break; case 2: -// svga->render = svga_render_8bpp_highres; + if (mach64->type != MACH64_GX) + svga->render = svga_render_8bpp_highres; svga->hdisp *= 8; svga->rowoffset /= 2; break; case 3: -// svga->render = svga_render_15bpp_highres; + if (mach64->type != MACH64_GX) + svga->render = svga_render_15bpp_highres; svga->hdisp *= 8; - //svga_rowoffset *= 2; break; case 4: -// svga->render = svga_render_16bpp_highres; + if (mach64->type != MACH64_GX) + svga->render = svga_render_16bpp_highres; svga->hdisp *= 8; - //svga_rowoffset *= 2; break; case 5: -// svga->render = svga_render_24bpp_highres; + if (mach64->type != MACH64_GX) + svga->render = svga_render_24bpp_highres; svga->hdisp *= 8; svga->rowoffset = (svga->rowoffset * 3) / 2; break; case 6: -// svga->render = svga_render_32bpp_highres; + if (mach64->type != MACH64_GX) + svga->render = svga_render_32bpp_highres; svga->hdisp *= 8; svga->rowoffset *= 2; break; } svga->vrammask = mach64->vram_mask; -// pclog("mach64_recalctimings : frame %i,%i disp %i,%i vsync at %i rowoffset %i pixel clock %f MA %08X\n", svga->htotal, svga->vtotal, svga->hdisp, svga->dispend, svga->vsyncstart, svga->rowoffset, svga->clock, svga->ma); } else { @@ -430,11 +470,11 @@ void mach64_updatemapping(mach64_t *mach64) mem_mapping_disable(&mach64->linear_mapping); mem_mapping_disable(&mach64->mmio_mapping); mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); return; } mem_mapping_disable(&mach64->mmio_mapping); -// pclog("Write mapping %02X\n", val); switch (svga->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ @@ -465,30 +505,41 @@ void mach64_updatemapping(mach64_t *mach64) } if (mach64->linear_base) { - if ((mach64->config_cntl & 3) == 2) - { - /*8 MB aperture*/ - pclog("8 MB aperture\n"); - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x007FFC00); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x007FFC00, 0x400); - } - else - { - /*4 MB aperture*/ - pclog("4 MB aperture\n"); - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x003FFC00); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x003FFC00, 0x400); - } - svga->linear_base = mach64->linear_base; + if (mach64->type == MACH64_GX) + { + if ((mach64->config_cntl & 3) == 2) + { + /*8 MB aperture*/ + pclog("8 MB aperture\n"); + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x007FFC00); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x007FFC00, 0x400); + } + else + { + /*4 MB aperture*/ + pclog("4 MB aperture\n"); + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x003FFC00); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x003FFC00, 0x400); + } + svga->linear_base = mach64->linear_base; + } + else + { + /*2*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); + } } else { mem_mapping_disable(&mach64->linear_mapping); mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); } } -static inline void wake_fifo_thread(mach64_t *mach64) +static __inline void wake_fifo_thread(mach64_t *mach64) { thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -520,7 +571,6 @@ static void mach64_wait_fifo_idle(mach64_t *mach64) static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val) { -// pclog("mach64_accel_write_fifo: addr=%08x val=%02x\n", addr, val); switch (addr & 0x3ff) { case 0x100: case 0x101: case 0x102: case 0x103: @@ -543,8 +593,8 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val case 0x11e: case 0x11f: WRITE8(addr, mach64->dst_height_width, val); case 0x113: - if ((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || - ((addr & 0x3ff) == 0x113) && !(val & 0x80)) + if (((addr & 0x3ff) == 0x11b) || ((addr & 0x3ff) == 0x11f) || + (((addr & 0x3ff) == 0x113) && !(val & 0x80))) { mach64_start_fill(mach64); #ifdef MACH64_DEBUG @@ -725,7 +775,6 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val } static void mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t val) { -// pclog("mach64_accel_write_fifo_w: addr=%08x val=%04x\n", addr, val); switch (addr & 0x3fe) { case 0x200: case 0x202: case 0x204: case 0x206: @@ -753,7 +802,6 @@ static void mach64_accel_write_fifo_w(mach64_t *mach64, uint32_t addr, uint16_t } static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t val) { -// pclog("mach64_accel_write_fifo_l: addr=%08x %02x val=%08x\n", addr, addr >> 2, val); switch (addr & 0x3fc) { case 0x32c: @@ -788,6 +836,10 @@ static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t static void fifo_thread(void *param) { mach64_t *mach64 = (mach64_t *)param; + fifo_entry_t *fifo; + + uint64_t start_time = 0; + uint64_t end_time = 0; while (1) { @@ -797,10 +849,8 @@ static void fifo_thread(void *param) mach64->blitter_busy = 1; while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; + start_time = timer_read(); + fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; switch (fifo->addr_type & FIFO_TYPE) { @@ -831,7 +881,6 @@ static void fifo_thread(void *param) static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_write_idx & FIFO_MASK]; - int c; if (FIFO_FULL) { @@ -853,7 +902,6 @@ static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t void mach64_cursor_dump(mach64_t *mach64) { - svga_t *svga = &mach64->svga; /* pclog("Mach64 cursor :\n"); pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff);*/ } @@ -918,11 +966,6 @@ void mach64_start_fill(mach64_t *mach64) mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - -/* mach64->accel.src_x *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_x *= mach64_inc[mach64->accel.dst_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ if (mach64->accel.src_size == WIDTH_1BIT) mach64->accel.src_offset <<= 3; @@ -934,39 +977,24 @@ void mach64_start_fill(mach64_t *mach64) else mach64->accel.dst_offset >>= mach64->accel.dst_size; -/* if (mach64->accel.source_fg == SRC_BLITSRC || mach64->accel.source_bg == SRC_BLITSRC) - {*/ - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; -/* } - else - { - mach64->accel.xinc = mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.yinc = 1; - }*/ + mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - - -// pclog("mach64_start_fill : pattern %08X %08X\n", mach64->pat_reg0, mach64->pat_reg1); + for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { uint32_t temp = (y & 4) ? mach64->pat_reg1 : mach64->pat_reg0; mach64->accel.pattern[y][x] = (temp >> (x + ((y & 3) * 8))) & 1; -// pclog("%i ", mach64->accel.pattern[y][x]); } -// pclog("\n"); } mach64->accel.sc_left = mach64->sc_left_right & 0x1fff; mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; - -/* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width]; - mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/ mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; @@ -1411,8 +1439,6 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); - -// pclog("Blit %i,%i %i,%i %X %X %i %02X %02X %i ", mach64->accel.src_x, mach64->accel.src_y, mach64->accel.dst_x, mach64->accel.dst_y, (mach64->accel.src_offset + (mach64->accel.src_y * mach64->accel.src_pitch) + mach64->accel.src_x) & 0x7fffff, (mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x) & 0x7fffff, count, src_dat, dest_dat, mix); switch (mach64->accel.clr_cmp_fn) { @@ -1430,8 +1456,6 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) MIX -// pclog("%02X %i\n", dest_dat, mach64->accel.dst_height); - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); } @@ -1569,11 +1593,113 @@ void mach64_load_context(mach64_t *mach64) } } +#define PLL_REF_DIV 0x2 +#define VCLK_POST_DIV 0x6 +#define VCLK0_FB_DIV 0x7 + +static void pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) +{ + int c; + + switch (addr & 3) + { + case 0: /*Clock sel*/ + break; + case 1: /*Addr*/ + mach64->pll_addr = (val >> 2) & 0xf; + break; + case 2: /*Data*/ + mach64->pll_regs[mach64->pll_addr] = val; + pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); + + for (c = 0; c < 4; c++) + { + double m = (double)mach64->pll_regs[PLL_REF_DIV]; + double n = (double)mach64->pll_regs[VCLK0_FB_DIV+c]; + double r = 14318184.0; + double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c*2)) & 3)); + + pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); + mach64->pll_freq[c] = (2.0 * r * n) / (m * p); + pclog(" %g\n", mach64->pll_freq[c]); + } + break; + } +} + +#define OVERLAY_EN (1 << 30) +static void mach64_vblank_start(svga_t *svga) +{ + mach64_t *mach64 = (mach64_t *)svga->p; + int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; + + mach64->crtc_int_cntl |= 4; + + svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; + svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; + + svga->overlay.xsize = ((mach64->overlay_y_x_end >> 16) & 0x7ff) - svga->overlay.x; + svga->overlay.ysize = (mach64->overlay_y_x_end & 0x7ff) - svga->overlay.y; + + svga->overlay.addr = mach64->buf_offset[0] & 0x3ffff8; + svga->overlay.pitch = mach64->buf_pitch[0] & 0xfff; + + svga->overlay.ena = (mach64->overlay_scale_cntl & OVERLAY_EN) && (overlay_cmp_mix != 1); + + mach64->overlay_v_acc = 0; + mach64->scaler_update = 1; +} + uint8_t mach64_ext_readb(uint32_t addr, void *p) { mach64_t *mach64 = (mach64_t *)p; uint8_t ret; - switch (addr & 0x3ff) + if (!(addr & 0x400)) + { + switch (addr & 0x3ff) + { + case 0x00: case 0x01: case 0x02: case 0x03: + READ8(addr, mach64->overlay_y_x_start); + break; + case 0x04: case 0x05: case 0x06: case 0x07: + READ8(addr, mach64->overlay_y_x_end); + break; + case 0x08: case 0x09: case 0x0a: case 0x0b: + READ8(addr, mach64->overlay_video_key_clr); + break; + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + READ8(addr, mach64->overlay_video_key_msk); + break; + case 0x10: case 0x11: case 0x12: case 0x13: + READ8(addr, mach64->overlay_graphics_key_clr); + break; + case 0x14: case 0x15: case 0x16: case 0x17: + READ8(addr, mach64->overlay_graphics_key_msk); + break; + case 0x18: case 0x19: case 0x1a: case 0x1b: + READ8(addr, mach64->overlay_key_cntl); + break; + + case 0x20: case 0x21: case 0x22: case 0x23: + READ8(addr, mach64->overlay_scale_inc); + break; + case 0x24: case 0x25: case 0x26: case 0x27: + READ8(addr, mach64->overlay_scale_cntl); + break; + case 0x28: case 0x29: case 0x2a: case 0x2b: + READ8(addr, mach64->scaler_height_width); + break; + + case 0x4a: + ret = mach64->scaler_format; + break; + + default: + ret = 0xff; + break; + } + } + else switch (addr & 0x3ff) { case 0x00: case 0x01: case 0x02: case 0x03: READ8(addr, mach64->crtc_h_total_disp); @@ -1613,6 +1739,12 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->ovr_wid_top_bottom); break; + case 0x60: case 0x61: case 0x62: case 0x63: + READ8(addr, mach64->cur_clr0); + break; + case 0x64: case 0x65: case 0x66: case 0x67: + READ8(addr, mach64->cur_clr1); + break; case 0x68: case 0x69: case 0x6a: case 0x6b: READ8(addr, mach64->cur_offset); break; @@ -1630,6 +1762,10 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->scratch_reg1); break; + case 0x79: + ret = 0x30; + break; + case 0x90: case 0x91: case 0x92: case 0x93: READ8(addr, mach64->clock_cntl); break; @@ -1639,18 +1775,33 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) break; case 0xc0: case 0xc1: case 0xc2: case 0xc3: - ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + if (mach64->type == MACH64_GX) + ret = ati68860_ramdac_in((addr & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + else + ret = ati68860_ramdac_in(addr & 3, &mach64->ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: + if (mach64->type == MACH64_VT2) + mach64->dac_cntl |= (4 << 24); READ8(addr, mach64->dac_cntl); break; case 0xd0: case 0xd1: case 0xd2: case 0xd3: READ8(addr, mach64->gen_test_cntl); break; - + + case 0xdc: case 0xdd: case 0xde: case 0xdf: + if (mach64->type == MACH64_GX) + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); + else + mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); + READ8(addr, mach64->config_cntl); + break; case 0xe0: case 0xe1: case 0xe2: case 0xe3: - READ8(addr, 0x020000d7); /*88800GX-2*/ + READ8(addr, mach64->config_chip_id); + break; + case 0xe4: case 0xe5: case 0xe6: case 0xe7: + READ8(addr, mach64->config_stat0); break; case 0x100: case 0x101: case 0x102: case 0x103: @@ -1872,9 +2023,15 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) } uint16_t mach64_ext_readw(uint32_t addr, void *p) { - mach64_t *mach64 = (mach64_t *)p; uint16_t ret; - switch (addr & 0x3ff) + if (!(addr & 0x400)) + { +#ifdef MACH64_DEBUG + pclog("nmach64_ext_readw: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); +#endif + ret = 0xffff; + } + else switch (addr & 0x3ff) { default: #ifdef MACH64_DEBUG @@ -1896,7 +2053,11 @@ uint32_t mach64_ext_readl(uint32_t addr, void *p) { mach64_t *mach64 = (mach64_t *)p; uint32_t ret; - switch (addr & 0x3ff) + if (!(addr & 0x400)) + { + ret = 0xffffffff; + } + else switch (addr & 0x3ff) { case 0x18: ret = mach64->crtc_int_cntl & ~1; @@ -1933,9 +2094,69 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) mach64_t *mach64 = (mach64_t *)p; svga_t *svga = &mach64->svga; #ifdef MACH64_DEBUG - pclog("mach64_ext_writeb : addr %08X val %02X\n", addr, val); + pclog("mach64_ext_writeb : addr %08X val %02X %04x(%08x):%08x\n", addr, val, CS,cs,cpu_state.pc); #endif - if (addr & 0x300) + if (!(addr & 0x400)) + { + switch (addr & 0x3ff) + { + case 0x00: case 0x01: case 0x02: case 0x03: + WRITE8(addr, mach64->overlay_y_x_start, val); + break; + case 0x04: case 0x05: case 0x06: case 0x07: + WRITE8(addr, mach64->overlay_y_x_end, val); + break; + case 0x08: case 0x09: case 0x0a: case 0x0b: + WRITE8(addr, mach64->overlay_video_key_clr, val); + break; + case 0x0c: case 0x0d: case 0x0e: case 0x0f: + WRITE8(addr, mach64->overlay_video_key_msk, val); + break; + case 0x10: case 0x11: case 0x12: case 0x13: + WRITE8(addr, mach64->overlay_graphics_key_clr, val); + break; + case 0x14: case 0x15: case 0x16: case 0x17: + WRITE8(addr, mach64->overlay_graphics_key_msk, val); + break; + case 0x18: case 0x19: case 0x1a: case 0x1b: + WRITE8(addr, mach64->overlay_key_cntl, val); + break; + + case 0x20: case 0x21: case 0x22: case 0x23: + WRITE8(addr, mach64->overlay_scale_inc, val); + break; + case 0x24: case 0x25: case 0x26: case 0x27: + WRITE8(addr, mach64->overlay_scale_cntl, val); + break; + case 0x28: case 0x29: case 0x2a: case 0x2b: + WRITE8(addr, mach64->scaler_height_width, val); + break; + + case 0x4a: + mach64->scaler_format = val & 0xf; + break; + + case 0x80: case 0x81: case 0x82: case 0x83: + WRITE8(addr, mach64->buf_offset[0], val); + break; + + case 0x8c: case 0x8d: case 0x8e: case 0x8f: + WRITE8(addr, mach64->buf_pitch[0], val); + break; + + case 0x98: case 0x99: case 0x9a: case 0x9b: + WRITE8(addr, mach64->buf_offset[1], val); + break; + + case 0xa4: case 0xa5: case 0xa6: case 0xa7: + WRITE8(addr, mach64->buf_pitch[1], val); + break; + } +#ifdef MACH64_DEBUG + pclog("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); +#endif + } + else if (addr & 0x300) { mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); } @@ -1961,7 +2182,9 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) break; case 0x18: - mach64->crtc_int_cntl = val; + mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); + if (val & 4) + mach64->crtc_int_cntl &= ~4; break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -1983,6 +2206,16 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) WRITE8(addr, mach64->ovr_wid_top_bottom, val); break; + case 0x60: case 0x61: case 0x62: case 0x63: + WRITE8(addr, mach64->cur_clr0, val); + if (mach64->type == MACH64_VT2) + mach64->ramdac.pallook[0] = makecol32((mach64->cur_clr0 >> 24) & 0xff, (mach64->cur_clr0 >> 16) & 0xff, (mach64->cur_clr0 >> 8) & 0xff); + break; + case 0x64: case 0x65: case 0x66: case 0x67: + WRITE8(addr, mach64->cur_clr1, val); + if (mach64->type == MACH64_VT2) + mach64->ramdac.pallook[1] = makecol32((mach64->cur_clr1 >> 24) & 0xff, (mach64->cur_clr1 >> 16) & 0xff, (mach64->cur_clr1 >> 8) & 0xff); + break; case 0x68: case 0x69: case 0x6a: case 0x6b: WRITE8(addr, mach64->cur_offset, val); svga->hwcursor.addr = (mach64->cur_offset & 0xfffff) * 8; @@ -2010,7 +2243,13 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0x90: case 0x91: case 0x92: case 0x93: WRITE8(addr, mach64->clock_cntl, val); - ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); + if (mach64->type == MACH64_GX) + ics2595_write(&mach64->ics2595, val & 0x40, val & 0xf); + else + { + pll_write(mach64, addr, val); + mach64->ics2595.output_clock = mach64->pll_freq[mach64->clock_cntl & 3]; + } svga_recalctimings(&mach64->svga); break; @@ -2044,7 +2283,10 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) break; case 0xc0: case 0xc1: case 0xc2: case 0xc3: - ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((addr & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + else + ati68860_ramdac_out(addr & 3, val, &mach64->ramdac, &mach64->svga); break; case 0xc4: case 0xc5: case 0xc6: case 0xc7: WRITE8(addr, mach64->dac_cntl, val); @@ -2054,12 +2296,21 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) case 0xd0: case 0xd1: case 0xd2: case 0xd3: WRITE8(addr, mach64->gen_test_cntl, val); -// if (val == 2) output = 3; ati_eeprom_write(&mach64->eeprom, mach64->gen_test_cntl & 0x10, mach64->gen_test_cntl & 2, mach64->gen_test_cntl & 1); mach64->gen_test_cntl = (mach64->gen_test_cntl & ~8) | (ati_eeprom_read(&mach64->eeprom) ? 8 : 0); svga->hwcursor.ena = mach64->gen_test_cntl & 0x80; mach64_cursor_dump(mach64); break; + + case 0xdc: case 0xdd: case 0xde: case 0xdf: + WRITE8(addr, mach64->config_cntl, val); + mach64_updatemapping(mach64); + break; + + case 0xe4: case 0xe5: case 0xe6: case 0xe7: + if (mach64->type != MACH64_GX) + WRITE8(addr, mach64->config_stat0, val); + break; } } void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) @@ -2068,7 +2319,15 @@ void mach64_ext_writew(uint32_t addr, uint16_t val, void *p) #ifdef MACH64_DEBUG pclog("mach64_ext_writew : addr %08X val %04X\n", addr, val); #endif - if (addr & 0x300) + if (!(addr & 0x400)) + { +#ifdef MACH64_DEBUG + pclog("nmach64_ext_writew: addr=%04x val=%04x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); +#endif + mach64_ext_writeb(addr, val, p); + mach64_ext_writeb(addr + 1, val >> 8, p); + } + else if (addr & 0x300) { mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); } @@ -2093,7 +2352,15 @@ void mach64_ext_writel(uint32_t addr, uint32_t val, void *p) if ((addr & 0x3c0) != 0x200) pclog("mach64_ext_writel : addr %08X val %08X\n", addr, val); #endif - if (addr & 0x300) + if (!(addr & 0x400)) + { +#ifdef MACH64_DEBUG + pclog("nmach64_ext_writel: addr=%04x val=%08x %04x(%08x):%08x\n", addr, val, CS, cs, cpu_state.pc); +#endif + mach64_ext_writew(addr, val, p); + mach64_ext_writew(addr + 2, val >> 16, p); + } + else if (addr & 0x300) { mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); } @@ -2116,93 +2383,101 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) { mach64_t *mach64 = (mach64_t *)p; uint8_t ret; -// if (CS == 0x2be7) output = 3; switch (port) { case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - ret = mach64_ext_readb(0x00 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x00 | (port & 3), p); break; case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - ret = mach64_ext_readb(0x08 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x08 | (port & 3), p); break; case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - ret = mach64_ext_readb(0x0c | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x0c | (port & 3), p); break; case 0x12ec: case 0x12ed: case 0x12ee: case 0x12ef: - ret = mach64_ext_readb(0x10 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x10 | (port & 3), p); break; case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - ret = mach64_ext_readb(0x14 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x14 | (port & 3), p); break; case 0x1aec: - ret = mach64_ext_readb(0x18, p); + ret = mach64_ext_readb(0x400 | 0x18, p); break; case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - ret = mach64_ext_readb(0x1c | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x1c | (port & 3), p); break; case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - ret = mach64_ext_readb(0x40 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x40 | (port & 3), p); break; case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - ret = mach64_ext_readb(0x44 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x44 | (port & 3), p); break; case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - ret = mach64_ext_readb(0x48 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x48 | (port & 3), p); + break; + case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: + ret = mach64_ext_readb(0x400 | 0x60 | (port & 3), p); break; + case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: + ret = mach64_ext_readb(0x400 | 0x64 | (port & 3), p); + break; case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - ret = mach64_ext_readb(0x68 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x68 | (port & 3), p); break; case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - ret = mach64_ext_readb(0x6c | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x6c | (port & 3), p); break; case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - ret = mach64_ext_readb(0x70 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x70 | (port & 3), p); break; case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - ret = mach64_ext_readb(0x80 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x80 | (port & 3), p); break; case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - ret = mach64_ext_readb(0x84 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x84 | (port & 3), p); break; case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - ret = mach64_ext_readb(0x90 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0x90 | (port & 3), p); break; case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - ret = mach64_ext_readb(0xb0 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xb0 | (port & 3), p); break; case 0x56ec: - ret = mach64_ext_readb(0xb4, p); + ret = mach64_ext_readb(0x400 | 0xb4, p); break; case 0x56ed: case 0x56ee: - ret = mach64_ext_readb(0xb5, p); + ret = mach64_ext_readb(0x400 | 0xb5, p); break; case 0x5aec: - ret = mach64_ext_readb(0xb8, p); + ret = mach64_ext_readb(0x400 | 0xb8, p); break; case 0x5aed: case 0x5aee: - ret = mach64_ext_readb(0xb9, p); + ret = mach64_ext_readb(0x400 | 0xb9, p); break; case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + if (mach64->type == MACH64_GX) + ret = ati68860_ramdac_in((port & 3) | ((mach64->dac_cntl & 3) << 2), &mach64->ramdac, &mach64->svga); + else + ret = ati68860_ramdac_in(port & 3, &mach64->ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - ret = mach64_ext_readb(0xc4 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xc4 | (port & 3), p); break; case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - ret = mach64_ext_readb(0xd0 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xd0 | (port & 3), p); break; case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: @@ -2211,18 +2486,11 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) break; case 0x6eec: case 0x6eed: case 0x6eee: case 0x6eef: - ret = mach64_ext_readb(0xe0 | (port & 3), p); + ret = mach64_ext_readb(0x400 | 0xe0 | (port & 3), p); break; - case 0x72ec: - if (PCI) - ret = 7 | (3 << 3); /*PCI, 256Kx16 DRAM*/ - else - ret = 6 | (3 << 3); /*VLB, 256Kx16 DRAM*/ - break; - case 0x72ed: - ret = 5 << 1; /*ATI-68860*/ - break; + case 0x72ec: case 0x72ed: case 0x72ee: case 0x72ef: + ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); default: ret = 0; @@ -2235,7 +2503,6 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) } uint16_t mach64_ext_inw(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; uint16_t ret; switch (port) { @@ -2257,15 +2524,14 @@ uint16_t mach64_ext_inw(uint16_t port, void *p) } uint32_t mach64_ext_inl(uint16_t port, void *p) { - mach64_t *mach64 = (mach64_t *)p; uint32_t ret; switch (port) { case 0x56ec: - ret = mach64_ext_readl(0xb4, p); + ret = mach64_ext_readl(0x400 | 0xb4, p); break; case 0x5aec: - ret = mach64_ext_readl(0xb8, p); + ret = mach64_ext_readl(0x400 | 0xb8, p); break; default: @@ -2295,84 +2561,93 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) { case 0x02ec: case 0x02ed: case 0x02ee: case 0x02ef: case 0x7eec: case 0x7eed: case 0x7eee: case 0x7eef: - mach64_ext_writeb(0x00 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x00 | (port & 3), val, p); break; case 0x0aec: case 0x0aed: case 0x0aee: case 0x0aef: - mach64_ext_writeb(0x08 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x08 | (port & 3), val, p); break; case 0x0eec: case 0x0eed: case 0x0eee: case 0x0eef: - mach64_ext_writeb(0x0c | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x0c | (port & 3), val, p); break; case 0x16ec: case 0x16ed: case 0x16ee: case 0x16ef: - mach64_ext_writeb(0x14 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x14 | (port & 3), val, p); break; case 0x1aec: - mach64_ext_writeb(0x18, val, p); + mach64_ext_writeb(0x400 | 0x18, val, p); break; case 0x1eec: case 0x1eed: case 0x1eee: case 0x1eef: - mach64_ext_writeb(0x1c | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x1c | (port & 3), val, p); break; case 0x22ec: case 0x22ed: case 0x22ee: case 0x22ef: - mach64_ext_writeb(0x40 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x40 | (port & 3), val, p); break; case 0x26ec: case 0x26ed: case 0x26ee: case 0x26ef: - mach64_ext_writeb(0x44 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x44 | (port & 3), val, p); break; case 0x2aec: case 0x2aed: case 0x2aee: case 0x2aef: - mach64_ext_writeb(0x48 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x48 | (port & 3), val, p); + break; + case 0x2eec: case 0x2eed: case 0x2eee: case 0x2eef: + mach64_ext_writeb(0x400 | 0x60 | (port & 3), val, p); break; + case 0x32ec: case 0x32ed: case 0x32ee: case 0x32ef: + mach64_ext_writeb(0x400 | 0x64 | (port & 3), val, p); + break; case 0x36ec: case 0x36ed: case 0x36ee: case 0x36ef: - mach64_ext_writeb(0x68 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x68 | (port & 3), val, p); break; case 0x3aec: case 0x3aed: case 0x3aee: case 0x3aef: - mach64_ext_writeb(0x6c | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x6c | (port & 3), val, p); break; case 0x3eec: case 0x3eed: case 0x3eee: case 0x3eef: - mach64_ext_writeb(0x70 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x70 | (port & 3), val, p); break; case 0x42ec: case 0x42ed: case 0x42ee: case 0x42ef: - mach64_ext_writeb(0x80 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x80 | (port & 3), val, p); break; case 0x46ec: case 0x46ed: case 0x46ee: case 0x46ef: - mach64_ext_writeb(0x84 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x84 | (port & 3), val, p); break; case 0x4aec: case 0x4aed: case 0x4aee: case 0x4aef: - mach64_ext_writeb(0x90 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0x90 | (port & 3), val, p); break; case 0x52ec: case 0x52ed: case 0x52ee: case 0x52ef: - mach64_ext_writeb(0xb0 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0xb0 | (port & 3), val, p); break; case 0x56ec: - mach64_ext_writeb(0xb4, val, p); + mach64_ext_writeb(0x400 | 0xb4, val, p); break; case 0x56ed: case 0x56ee: - mach64_ext_writeb(0xb5, val, p); + mach64_ext_writeb(0x400 | 0xb5, val, p); break; case 0x5aec: - mach64_ext_writeb(0xb8, val, p); + mach64_ext_writeb(0x400 | 0xb8, val, p); break; case 0x5aed: case 0x5aee: - mach64_ext_writeb(0xb9, val, p); + mach64_ext_writeb(0x400 | 0xb9, val, p); break; case 0x5eec: case 0x5eed: case 0x5eee: case 0x5eef: - ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + if (mach64->type == MACH64_GX) + ati68860_ramdac_out((port & 3) | ((mach64->dac_cntl & 3) << 2), val, &mach64->ramdac, &mach64->svga); + else + ati68860_ramdac_out(port & 3, val, &mach64->ramdac, &mach64->svga); break; case 0x62ec: case 0x62ed: case 0x62ee: case 0x62ef: - mach64_ext_writeb(0xc4 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0xc4 | (port & 3), val, p); break; case 0x66ec: case 0x66ed: case 0x66ee: case 0x66ef: - mach64_ext_writeb(0xd0 | (port & 3), val, p); + mach64_ext_writeb(0x400 | 0xd0 | (port & 3), val, p); break; case 0x6aec: case 0x6aed: case 0x6aee: case 0x6aef: @@ -2383,7 +2658,6 @@ void mach64_ext_outb(uint16_t port, uint8_t val, void *p) } void mach64_ext_outw(uint16_t port, uint16_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; #ifdef MACH64_DEBUG pclog("mach64_ext_outw : port %04X val %04X\n", port, val); #endif @@ -2403,7 +2677,6 @@ void mach64_ext_outw(uint16_t port, uint16_t val, void *p) } void mach64_ext_outl(uint16_t port, uint32_t val, void *p) { - mach64_t *mach64 = (mach64_t *)p; pclog("mach64_ext_outl : port %04X val %08X\n", port, val); switch (port) { @@ -2420,13 +2693,73 @@ void mach64_ext_outl(uint16_t port, uint32_t val, void *p) } } +static uint8_t mach64_block_inb(uint16_t port, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + uint8_t ret; + + ret = mach64_ext_readb(0x400 | (port & 0x3ff), mach64); +#ifdef MACH64_DEBUG + pclog("mach64_block_inb : port %04X ret %02X %04x:%04x\n", port, ret, CS,cpu_state.pc); +#endif + return ret; +} +static uint16_t mach64_block_inw(uint16_t port, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + uint16_t ret; + + ret = mach64_ext_readw(0x400 | (port & 0x3ff), mach64); +#ifdef MACH64_DEBUG + pclog("mach64_block_inw : port %04X ret %04X\n", port, ret); +#endif + return ret; +} +static uint32_t mach64_block_inl(uint16_t port, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + uint32_t ret; + + ret = mach64_ext_readl(0x400 | (port & 0x3ff), mach64); +#ifdef MACH64_DEBUG + pclog("mach64_block_inl : port %04X ret %08X\n", port, ret); +#endif + return ret; +} + +static void mach64_block_outb(uint16_t port, uint8_t val, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + +#ifdef MACH64_DEBUG + pclog("mach64_block_outb : port %04X val %02X\n ", port, val); +#endif + mach64_ext_writeb(0x400 | (port & 0x3ff), val, mach64); +} +static void mach64_block_outw(uint16_t port, uint16_t val, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + +#ifdef MACH64_DEBUG + pclog("mach64_block_outw : port %04X val %04X\n ", port, val); +#endif + mach64_ext_writew(0x400 | (port & 0x3ff), val, mach64); +} +static void mach64_block_outl(uint16_t port, uint32_t val, void *p) +{ + mach64_t *mach64 = (mach64_t *)p; + +#ifdef MACH64_DEBUG + pclog("mach64_block_outl : port %04X val %08X\n ", port, val); +#endif + mach64_ext_writel(0x400 | (port & 0x3ff), val, mach64); +} + void mach64_write(uint32_t addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; svga_t *svga = &mach64->svga; -// pclog("mach64_write : %05X %02X ", addr, val); addr = (addr & 0x7fff) + mach64->bank_w[(addr >> 15) & 1]; -// pclog("%08X\n", addr); svga_write_linear(addr, val, svga); } @@ -2435,10 +2768,8 @@ uint8_t mach64_read(uint32_t addr, void *p) mach64_t *mach64 = (mach64_t *)p; svga_t *svga = &mach64->svga; uint8_t ret; -// pclog("mach64_read : %05X ", addr); addr = (addr & 0x7fff) + mach64->bank_r[(addr >> 15) & 1]; ret = svga_read_linear(addr, svga); -// pclog("%08X %02X\n", addr, ret); return ret; } @@ -2473,6 +2804,270 @@ void mach64_hwcursor_draw(svga_t *svga, int displine) svga->hwcursor_latch.addr += 16; } +#define CLAMP(x) do \ + { \ + if ((x) & ~0xff) \ + x = ((x) < 0) ? 0 : 0xff; \ + } \ + while (0) + +#define DECODE_ARGB1555() \ + do \ + { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ + { \ + uint16_t dat = ((uint16_t *)src)[x]; \ + \ + int b = dat & 0x1f; \ + int g = (dat >> 5) & 0x1f; \ + int r = (dat >> 10) & 0x1f; \ + \ + b = (b << 3) | (b >> 2); \ + g = (g << 3) | (g >> 2); \ + r = (r << 3) | (r >> 2); \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_RGB565() \ + do \ + { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ + { \ + uint16_t dat = ((uint16_t *)src)[x]; \ + \ + int b = dat & 0x1f; \ + int g = (dat >> 5) & 0x3f; \ + int r = (dat >> 11) & 0x1f; \ + \ + b = (b << 3) | (b >> 2); \ + g = (g << 2) | (g >> 4); \ + r = (r << 3) | (r >> 2); \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_ARGB8888() \ + do \ + { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) \ + { \ + int b = src[0]; \ + int g = src[1]; \ + int r = src[2]; \ + src += 4; \ + \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_VYUY422() \ + do \ + { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ + { \ + uint8_t y1, y2; \ + int8_t u, v; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + y1 = src[0]; \ + u = src[1] - 0x80; \ + y2 = src[2]; \ + v = src[3] - 0x80; \ + src += 4; \ + \ + dR = (359*v) >> 8; \ + dG = (88*u + 183*v) >> 8; \ + dB = (453*u) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +#define DECODE_YVYU422() \ + do \ + { \ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x += 2) \ + { \ + uint8_t y1, y2; \ + int8_t u, v; \ + int dR, dG, dB; \ + int r, g, b; \ + \ + u = src[0] - 0x80; \ + y1 = src[1]; \ + v = src[2] - 0x80; \ + y2 = src[3]; \ + src += 4; \ + \ + dR = (359*v) >> 8; \ + dG = (88*u + 183*v) >> 8; \ + dB = (453*u) >> 8; \ + \ + r = y1 + dR; \ + CLAMP(r); \ + g = y1 - dG; \ + CLAMP(g); \ + b = y1 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x] = (r << 16) | (g << 8) | b; \ + \ + r = y2 + dR; \ + CLAMP(r); \ + g = y2 - dG; \ + CLAMP(g); \ + b = y2 + dB; \ + CLAMP(b); \ + mach64->overlay_dat[x+1] = (r << 16) | (g << 8) | b; \ + } \ + } while (0) + +void mach64_overlay_draw(svga_t *svga, int displine) +{ + mach64_t *mach64 = (mach64_t *)svga->p; + int x; + int h_acc = 0; + int h_max = (mach64->scaler_height_width >> 16) & 0x3ff; + int h_inc = mach64->overlay_scale_inc >> 16; + int v_max = mach64->scaler_height_width & 0x3ff; + int v_inc = mach64->overlay_scale_inc & 0xffff; + uint32_t *p; + uint8_t *src = &svga->vram[svga->overlay.addr]; + int old_y = mach64->overlay_v_acc; + int y_diff; + int video_key_fn = mach64->overlay_key_cntl & 5; + int graphics_key_fn = (mach64->overlay_key_cntl >> 4) & 5; + int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; + + p = &((uint32_t *)buffer32->line[displine])[32 + mach64->svga.overlay_latch.x]; + + if (mach64->scaler_update) + { + switch (mach64->scaler_format) + { + case 0x3: + DECODE_ARGB1555(); + break; + case 0x4: + DECODE_RGB565(); + break; + case 0x6: + DECODE_ARGB8888(); + break; + case 0xb: + DECODE_VYUY422(); + break; + case 0xc: + DECODE_YVYU422(); + break; + + default: + pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); + /*Fill buffer with something recognisably wrong*/ + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + mach64->overlay_dat[x] = 0xff00ff; + break; + } + } + + if (overlay_cmp_mix == 2) + { + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + { + int h = h_acc >> 12; + + p[x] = mach64->overlay_dat[h]; + + h_acc += h_inc; + if (h_acc > (h_max << 12)) + h_acc = (h_max << 12); + } + } + else + { + for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) + { + int h = h_acc >> 12; + int gr_cmp = 0, vid_cmp = 0; + int use_video; + + switch (video_key_fn) + { + case 0: vid_cmp = 0; break; + case 1: vid_cmp = 1; break; + case 4: vid_cmp = ((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; + case 5: vid_cmp = !((mach64->overlay_dat[h] ^ mach64->overlay_video_key_clr) & mach64->overlay_video_key_msk); break; + } + switch (graphics_key_fn) + { + case 0: gr_cmp = 0; break; + case 1: gr_cmp = 1; break; + case 4: gr_cmp = (((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; + case 5: gr_cmp = !(((p[x]) ^ mach64->overlay_graphics_key_clr) & mach64->overlay_graphics_key_msk & 0xffffff); break; + } + vid_cmp = vid_cmp ? -1 : 0; + gr_cmp = gr_cmp ? -1 : 0; + + switch (overlay_cmp_mix) + { + case 0x0: use_video = gr_cmp; break; + case 0x1: use_video = 0; break; + case 0x2: use_video = ~0; break; + case 0x3: use_video = ~gr_cmp; break; + case 0x4: use_video = ~vid_cmp; break; + case 0x5: use_video = gr_cmp ^ vid_cmp; break; + case 0x6: use_video = ~gr_cmp ^ vid_cmp; break; + case 0x7: use_video = vid_cmp; break; + case 0x8: use_video = ~gr_cmp | ~vid_cmp; break; + case 0x9: use_video = gr_cmp | ~vid_cmp; break; + case 0xa: use_video = ~gr_cmp | vid_cmp; break; + case 0xb: use_video = gr_cmp | vid_cmp; break; + case 0xc: use_video = gr_cmp & vid_cmp; break; + case 0xd: use_video = ~gr_cmp & vid_cmp; break; + case 0xe: use_video = gr_cmp & ~vid_cmp; break; + case 0xf: use_video = ~gr_cmp & ~vid_cmp; break; + } + + if (use_video) + p[x] = mach64->overlay_dat[h]; + + h_acc += h_inc; + if (h_acc > (h_max << 12)) + h_acc = (h_max << 12); + } + } + + mach64->overlay_v_acc += v_inc; + if (mach64->overlay_v_acc > (v_max << 12)) + mach64->overlay_v_acc = v_max << 12; + + y_diff = (mach64->overlay_v_acc >> 12) - (old_y >> 12); + + if (mach64->scaler_format == 6) + svga->overlay.addr += svga->overlay.pitch*4*y_diff; + else + svga->overlay.addr += svga->overlay.pitch*2*y_diff; + + mach64->scaler_update = y_diff; +} + static void mach64_io_remove(mach64_t *mach64) { int c; @@ -2488,6 +3083,9 @@ static void mach64_io_remove(mach64_t *mach64) } io_removehandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + + if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + io_removehandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } static void mach64_io_set(mach64_t *mach64) @@ -2507,41 +3105,48 @@ static void mach64_io_set(mach64_t *mach64) } io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); + + if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } uint8_t mach64_pci_read(int func, int addr, void *p) { mach64_t *mach64 = (mach64_t *)p; - svga_t *svga = &mach64->svga; - -// pclog("Mach64 PCI read %08X\n", addr); switch (addr) { case 0x00: return 0x02; /*ATi*/ case 0x01: return 0x10; - case 0x02: return 'X'; /*88800GX*/ - case 0x03: return 'G'; + case 0x02: return mach64->pci_id & 0xff; + case 0x03: return mach64->pci_id >> 8; case PCI_REG_COMMAND: return mach64->pci_regs[PCI_REG_COMMAND]; /*Respond to IO and memory accesses*/ case 0x07: return 1 << 1; /*Medium DEVSEL timing*/ - case 0x08: return 0; /*Revision ID*/ + case 0x08: /*Revision ID*/ + if (mach64->type == MACH64_GX) + return 0; + return 0x40; + case 0x09: return 0; /*Programming interface*/ - // case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ case 0x0a: return 0x00; case 0x0b: return 0x03; case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - // case 0x12: return mach64->linear_base >> 16; case 0x12: return 0x00; case 0x13: return mach64->linear_base >> 24; + case 0x14: return 0x01; /*Block decoded IO address*/ + case 0x15: return mach64->block_decoded_io >> 8; + case 0x16: return mach64->block_decoded_io >> 16; + case 0x17: return mach64->block_decoded_io >> 24; + case 0x30: return mach64->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; case 0x32: return mach64->pci_regs[0x32]; @@ -2555,8 +3160,6 @@ uint32_t bios_base = 0x000c0000; void mach64_pci_write(int func, int addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; - -// pclog("Mach64 PCI write %08X %02X\n", addr, val); switch (addr) { @@ -2571,6 +3174,10 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) mach64_updatemapping(mach64); break; + case 0x12: + if (mach64->type == MACH64_VT2) + val = 0; + break; /* case 0x12: mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); mach64_updatemapping(mach64); @@ -2580,6 +3187,37 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) mach64_updatemapping(mach64); break; + case 0x15: + if (mach64->type == MACH64_VT2) + { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0xffff0000) | ((val & 0xfc) << 8); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x16: + if (mach64->type == MACH64_VT2) + { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0xff00fc00) | (val << 16); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x17: + if (mach64->type == MACH64_VT2) + { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->block_decoded_io = (mach64->block_decoded_io & 0x00fffc00) | (val << 24); + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; + case 0x30: case 0x32: case 0x33: mach64->pci_regs[addr] = val; if (mach64->pci_regs[0x30] & 0x01) @@ -2598,9 +3236,8 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) } } -void *mach64gx_init() +static void *mach64_common_init() { - int c; mach64_t *mach64 = malloc(sizeof(mach64_t)); memset(mach64, 0, sizeof(mach64_t)); @@ -2611,15 +3248,15 @@ void *mach64gx_init() mach64_recalctimings, mach64_in, mach64_out, mach64_hwcursor_draw, - NULL); + mach64_overlay_draw); - rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&mach64->bios_rom.mapping); - mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); - mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); - mem_mapping_add(&mach64->mmio_mapping, 0xbfc00, 0x00400, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->linear_mapping, 0, 0, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear, NULL, 0, &mach64->svga); + mem_mapping_add(&mach64->mmio_linear_mapping, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->mmio_linear_mapping_2, 0, 0, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); + mem_mapping_add(&mach64->mmio_mapping, 0xbc000, 0x04000, mach64_ext_readb, mach64_ext_readw, mach64_ext_readl, mach64_ext_writeb, mach64_ext_writew, mach64_ext_writel, NULL, 0, mach64); mem_mapping_disable(&mach64->mmio_mapping); mach64_io_set(mach64); @@ -2631,12 +3268,8 @@ void *mach64gx_init() mach64->pci_regs[0x32] = 0x0c; mach64->pci_regs[0x33] = 0x00; - ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); - ati68860_ramdac_init(&mach64->ramdac); - mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ - mach64->dst_cntl = 3; mach64->wake_fifo_thread = thread_create_event(); @@ -2646,17 +3279,66 @@ void *mach64gx_init() return mach64; } +static void *mach64gx_init() +{ + mach64_t *mach64 = mach64_common_init(); + + mach64->type = MACH64_GX; + mach64->pci_id = (int)'X' | ((int)'G' << 8); + mach64->config_chip_id = 0x020000d7; + mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ + mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ + if (PCI) + mach64->config_stat0 |= 0; /*PCI, 256Kx16 DRAM*/ + else + mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ + + ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); + + rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + return mach64; +} +static void *mach64vt2_init() +{ + mach64_t *mach64 = mach64_common_init(); + svga_t *svga = &mach64->svga; + + mach64->type = MACH64_VT2; + mach64->pci_id = 0x5654; + mach64->config_chip_id = 0x40005654; + mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ + mach64->config_stat0 = 4; + + ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); + + rom_init(&mach64->bios_rom, "roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + + svga->vblank_start = mach64_vblank_start; + + return mach64; +} + int mach64gx_available() { return rom_present("roms/mach64gx/bios.bin"); } +int mach64vt2_available() +{ + return rom_present("roms/atimach64vt2pci.bin"); +} + void mach64_close(void *p) { mach64_t *mach64 = (mach64_t *)p; svga_close(&mach64->svga); + thread_kill(mach64->fifo_thread); + thread_destroy_event(mach64->wake_fifo_thread); + thread_destroy_event(mach64->fifo_not_full_event); + free(mach64); } @@ -2725,31 +3407,45 @@ void mach64_add_status_info(char *s, int max_len, void *p) static device_config_t mach64gx_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 4, { { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "" + "" } - }, - .default_int = 4 + } }, { - .type = -1 + "", "", -1 + } +}; + +static device_config_t mach64vt2_config[] = +{ + { + "memory", "Memory size", CONFIG_SELECTION, "", 4, + { + { + "2 MB", 2 + }, + { + "4 MB", 4 + }, + { + "" + } + } + }, + { + "", "", -1 } }; @@ -2765,3 +3461,16 @@ device_t mach64gx_device = mach64_add_status_info, mach64gx_config }; + +device_t mach64vt2_device = +{ + "ATI Mach64VT2", + DEVICE_PCI, + mach64vt2_init, + mach64_close, + mach64vt2_available, + mach64_speed_changed, + mach64_force_redraw, + mach64_add_status_info, + mach64vt2_config +}; diff --git a/src/vid_ati_mach64.h b/src/vid_ati_mach64.h index 95a7e9744..2db76fa79 100644 --- a/src/vid_ati_mach64.h +++ b/src/vid_ati_mach64.h @@ -1 +1,2 @@ extern device_t mach64gx_device; +extern device_t mach64vt2_device; diff --git a/src/vid_cga.c b/src/vid_cga.c index aeb0d3e73..a665e45d9 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -34,7 +34,6 @@ void cga_out(uint16_t addr, uint8_t val, void *p) { cga_t *cga = (cga_t *)p; uint8_t old; -// pclog("CGA_OUT %04X %02X\n", addr, val); switch (addr) { case 0x3D4: @@ -80,7 +79,6 @@ void cga_out(uint16_t addr, uint8_t val, void *p) uint8_t cga_in(uint16_t addr, void *p) { cga_t *cga = (cga_t *)p; -// pclog("CGA_IN %04X\n", addr); switch (addr) { case 0x3D4: @@ -96,7 +94,6 @@ uint8_t cga_in(uint16_t addr, void *p) void cga_write(uint32_t addr, uint8_t val, void *p) { cga_t *cga = (cga_t *)p; -// pclog("CGA_WRITE %04X %02X\n", addr, val); /* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */ if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) return; if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) return; @@ -121,7 +118,6 @@ uint8_t cga_read(uint32_t addr, void *p) cga->charbuffer[(((int)(((cga->dispontime - cga->vidtime) * 2) / CGACONST)) & 0xfc) | 1] = cga->vram[addr & 0x3fff]; } egareads++; -// pclog("CGA_READ %04X\n", addr); return cga->vram[addr & 0x3fff]; } @@ -141,10 +137,8 @@ void cga_recalctimings(cga_t *cga) _dispontime = cga->crtc[1] << 1; } _dispofftime = disptime - _dispontime; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); _dispontime *= CGACONST; _dispofftime *= CGACONST; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); cga->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } @@ -176,7 +170,6 @@ void cga_poll(void *p) { cga->firstline = cga->displine; video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); } cga->lastline = cga->displine; for (c = 0; c < 8; c++) @@ -507,87 +500,63 @@ void cga_speed_changed(void *p) static device_config_t cga_config[] = { { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = + "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, { { - .description = "RGB", - .value = CGA_RGB + "RGB", CGA_RGB }, { - .description = "Composite", - .value = CGA_COMPOSITE + "Composite", CGA_COMPOSITE }, { - .description = "" + "" } - }, - .default_int = CGA_RGB + } }, { - .name = "composite_type", - .description = "Composite type", - .type = CONFIG_SELECTION, - .selection = + "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, { { - .description = "Old", - .value = COMPOSITE_OLD + "Old", COMPOSITE_OLD }, { - .description = "New", - .value = COMPOSITE_NEW + "New", COMPOSITE_NEW }, { - .description = "" + "" } - }, - .default_int = COMPOSITE_OLD + } }, #ifndef __unix { - .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, - .selection = + "rgb_type", "RGB type", CONFIG_SELECTION, "", 0, { { - .description = "Color", - .value = 0 + "Color", 0 }, { - .description = "Green Monochrome", - .value = 1 + "Green Monochrome", 1 }, { - .description = "Amber Monochrome", - .value = 2 + "Amber Monochrome", 2 }, { - .description = "Gray Monochrome", - .value = 3 + "Gray Monochrome", 3 }, { - .description = "Color (no brown)", - .value = 4 + "Color (no brown)", 4 }, { - .description = "" + "" } - }, - .default_int = 0 + } }, #endif { - .name = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1 + "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_cl_gd.c b/src/vid_cl_gd.c index b9b49c141..7c0899a95 100644 --- a/src/vid_cl_gd.c +++ b/src/vid_cl_gd.c @@ -648,6 +648,9 @@ uint8_t cirrus_mmio_blt_read(uint32_t address, void *p) case (CIRRUS_MMIO_BLTTRANSPARENTCOLORMASK + 1): value = svga->gdcreg[0x39]; break; + default: + value = 0xff; + break; } return value; diff --git a/src/vid_cl_gd_blit.c b/src/vid_cl_gd_blit.c index fbf63d72c..b312f0012 100644 --- a/src/vid_cl_gd_blit.c +++ b/src/vid_cl_gd_blit.c @@ -24,6 +24,8 @@ #define glue(a,b) glue_hidden(a,b) #define glue_hidden(a,b) a ## b +static uint8_t rop_to_index[256]; + int cl_gd_ABS(int sval) { if (sval < 0) @@ -65,11 +67,11 @@ bool blit_is_unsafe(clgd_t *clgd, svga_t *svga) return false; } -void cirrus_bitblt_rop_nop(clgd_t *clgd, uint8_t *dst, const uint8_t *src, int dstpitch, int srcpitch, int bltwidth, int bltheight) +void cirrus_bitblt_rop_nop(clgd_t *clgd, svga_t *svga, uint8_t *dst, const uint8_t *src, int dstpitch, int srcpitch, int bltwidth, int bltheight) { } -void cirrus_bitblt_fill_nop(clgd_t *clgd, uint8_t *dst, int dstpitch, int bltwidth, int bltheight) +void cirrus_bitblt_fill_nop(clgd_t *clgd, svga_t *svga, uint8_t *dst, int dstpitch, int bltwidth, int bltheight) { } @@ -346,7 +348,7 @@ const cirrus_fill_t cirrus_fill[16][4] = { ROP2(cirrus_fill_notsrc_and_notdst), }; -static inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) +inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) { unsigned int color; switch (clgd->blt.pixel_width) @@ -369,7 +371,7 @@ static inline void cirrus_bitblt_fgcol(clgd_t *clgd, svga_t *svga) } } -static inline void cirrus_bitblt_bgcol(clgd_t *clgd, svga_t *svga) +inline void cirrus_bitblt_bgcol(clgd_t *clgd, svga_t *svga) { unsigned int color; switch (clgd->blt.pixel_width) @@ -394,7 +396,7 @@ static inline void cirrus_bitblt_bgcol(clgd_t *clgd, svga_t *svga) void cirrus_invalidate_region(clgd_t *clgd, svga_t *svga, int off_begin, int off_pitch, int bytesperline, int lines) { - int y; + int x, y; int off_cur; int off_cur_end; @@ -404,6 +406,10 @@ void cirrus_invalidate_region(clgd_t *clgd, svga_t *svga, int off_begin, int off off_cur_end = ((off_cur + bytesperline) & svga->vrammask); // Memory region set dirty off_begin += off_pitch; + for (x = (off_cur >> 12); x <= (off_cur_end >> 12); x++) + { + svga->changedvram[x]++; + } } } @@ -818,4 +824,4 @@ void init_rops() rop_to_index[CIRRUS_ROP_NOTSRC] = 13; rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14; rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15; -} \ No newline at end of file +} diff --git a/src/vid_cl_gd_blit.h b/src/vid_cl_gd_blit.h index c315ff3aa..ebf22eb56 100644 --- a/src/vid_cl_gd_blit.h +++ b/src/vid_cl_gd_blit.h @@ -1,5 +1,3 @@ -static uint8_t rop_to_index[256]; - #define le32_to_cpu(x) (x) #define le16_to_cpu(x) (x) diff --git a/src/vid_cl_gd_vga_rop.h b/src/vid_cl_gd_vga_rop.h index 2b2b263fc..d03516ba3 100644 --- a/src/vid_cl_gd_vga_rop.h +++ b/src/vid_cl_gd_vga_rop.h @@ -22,17 +22,17 @@ * THE SOFTWARE. */ -static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src) +inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src) { *dst = ROP_FN(*dst, src); } -static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) +inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src) { *dst = ROP_FN(*dst, src); } -static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) +inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src) { *dst = ROP_FN(*dst, src); } diff --git a/src/vid_colorplus.c b/src/vid_colorplus.c index cb3ab38b3..13a661b04 100644 --- a/src/vid_colorplus.c +++ b/src/vid_colorplus.c @@ -33,7 +33,6 @@ void colorplus_out(uint16_t addr, uint8_t val, void *p) { colorplus_t *colorplus = (colorplus_t *)p; -// pclog("COLORPLUS_OUT %04X %02X\n", addr, val); if (addr == 0x3DD) { colorplus->control = val & 0x70; @@ -55,7 +54,6 @@ void colorplus_write(uint32_t addr, uint8_t val, void *p) { colorplus_t *colorplus = (colorplus_t *)p; -// pclog("COLORPLUS_WRITE %04X %02X\n", addr, val); if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) @@ -97,7 +95,6 @@ uint8_t colorplus_read(uint32_t addr, void *p) colorplus->cga.charbuffer[(((int)(((colorplus->cga.dispontime - colorplus->cga.vidtime) * 2) / CGACONST)) & 0xfc) | 1] = colorplus->cga.vram[addr & 0x7fff]; } egareads++; -// pclog("COLORPLUS_READ %04X\n", addr); return colorplus->cga.vram[addr & 0x7fff]; } @@ -145,7 +142,6 @@ void colorplus_poll(void *p) { colorplus->cga.firstline = colorplus->cga.displine; video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); } colorplus->cga.lastline = colorplus->cga.displine; /* Left / right border */ @@ -225,7 +221,7 @@ void colorplus_poll(void *p) for (c = 0; c < x; c++) buffer32->line[colorplus->cga.displine][c] = buffer->line[colorplus->cga.displine][c] & 0xf; - Composite_Process(&colorplus->cga, 0, x >> 2, buffer32->line[colorplus->cga.displine]); + Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]); } colorplus->cga.sc = oldsc; @@ -380,7 +376,7 @@ void *colorplus_standalone_init() colorplus->cga.vram = malloc(0x8000); - cga_comp_init(&colorplus->cga); + cga_comp_init(1); timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus); mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, 0, colorplus); io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); @@ -406,53 +402,38 @@ void colorplus_speed_changed(void *p) static device_config_t colorplus_config[] = { { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = + "display_type", "Display type", CONFIG_SELECTION, "", CGA_RGB, { { - .description = "RGB", - .value = CGA_RGB + "RGB", CGA_RGB }, { - .description = "Composite", - .value = CGA_COMPOSITE + "Composite", CGA_COMPOSITE }, { - .description = "" + "" } - }, - .default_int = CGA_RGB + } }, { - .name = "composite_type", - .description = "Composite type", - .type = CONFIG_SELECTION, - .selection = + "composite_type", "Composite type", CONFIG_SELECTION, "", COMPOSITE_OLD, { { - .description = "Old", - .value = COMPOSITE_OLD + "Old", COMPOSITE_OLD }, { - .description = "New", - .value = COMPOSITE_NEW + "New", COMPOSITE_NEW }, { - .description = "" + "" } - }, - .default_int = COMPOSITE_OLD + } }, { - .name = "snow_enabled", - .description = "Snow emulation", - .type = CONFIG_BINARY, - .default_int = 1 + "snow_enabled", "Snow emulation", CONFIG_BINARY, "", 1 }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_ega.c b/src/vid_ega.c index a900b3e49..2e98235d3 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -20,6 +20,8 @@ int egaswitchread,egaswitches=9; /*7=CGA mode (200 lines), 9=EGA mode (350 lines static int old_overscan_color = 0; +int update_overscan = 0; + void ega_out(uint16_t addr, uint8_t val, void *p) { ega_t *ega = (ega_t *)p; @@ -104,7 +106,6 @@ void ega_out(uint16_t addr, uint8_t val, void *p) ega->chain2_read = val & 0x10; break; case 6: -// pclog("Write mapping %02X\n", val); switch (val & 0xc) { case 0x0: /*128k at A0000*/ @@ -128,14 +129,10 @@ void ega_out(uint16_t addr, uint8_t val, void *p) break; case 0x3d0: case 0x3d4: - // pclog("Write 3d4 %02X %04X:%04X\n", val, CS, cpu_state.pc); ega->crtcreg = val & 31; return; case 0x3d1: case 0x3d5: - // pclog("Write 3d5 %02X %02X %02X\n", ega->crtcreg, val, ega->crtc[0x11]); -// if (ega->crtcreg == 1 && val == 0x14) -// fatal("Here\n"); if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; old = ega->crtc[ega->crtcreg]; ega->crtc[ega->crtcreg] = val; @@ -177,8 +174,6 @@ uint8_t ega_in(uint16_t addr, void *p) { ega_t *ega = (ega_t *)p; -if (addr != 0x3da && addr != 0x3ba) - // pclog("ega_in %04X\n", addr); if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -189,7 +184,6 @@ if (addr != 0x3da && addr != 0x3ba) case 0x3c1: return ega->attrregs[ega->attraddr]; case 0x3c2: -// printf("Read egaswitch %02X %02X %i\n",egaswitchread,egaswitches,VGA); return ega_get_input_status_0(ega); break; case 0x3c4: @@ -215,7 +209,6 @@ if (addr != 0x3da && addr != 0x3ba) ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ return ega->stat; } -// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); return 0xff; } @@ -250,15 +243,12 @@ void ega_recalctimings(ega_t *ega) ega->rowoffset = ega->crtc[0x13]; - // printf("Recalc! %i %i %i %i %i %02X\n", ega->vtotal, ega->dispend, ega->vsyncstart, ega->split, ega->hdisp, ega->attrregs[0x16]); - if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); disptime = ega->crtc[0] + 2; _dispontime = ega->crtc[1] + 1; - // printf("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, ega->crtc[1] * 8); if (ega->seqregs[1] & 8) { disptime*=2; @@ -270,11 +260,6 @@ void ega_recalctimings(ega_t *ega) ega->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); - /* pclog("dispontime %i (%f) dispofftime %i (%f)\n", ega->dispontime, (float)ega->dispontime / (1 << TIMER_SHIFT), - ega->dispofftime, (float)ega->dispofftime / (1 << TIMER_SHIFT)); */ -// printf("EGA horiz total %i display end %i clock rate %i vidclock %i %i\n",crtc[0],crtc[1],egaswitchread,vidclock,((ega3c2>>2)&3) | ((tridentnewctrl2<<2)&4)); -// printf("EGA vert total %i display end %i max row %i vsync %i\n",ega_vtotal,ega_dispend,(crtc[9]&31)+1,ega_vsyncstart); -// printf("total %f on %f cycles off %f cycles frame %f sec %f %02X\n",disptime*crtcconst,dispontime,dispofftime,(dispontime+dispofftime)*ega_vtotal,(dispontime+dispofftime)*ega_vtotal*70,seqregs[1]); } void ega_poll(void *p) @@ -292,6 +277,7 @@ void ega_poll(void *p) int y_add_ex = enable_overscan ? 28 : 0; int x_add_ex = enable_overscan ? 16 : 0; uint32_t *q, *r, i, j; + int wx = 640, wy = 350; if (!ega->linepos) { @@ -524,7 +510,6 @@ void ega_poll(void *p) else { ega->vidtime += ega->dispontime; -// if (output) printf("Display on %f\n",vidtime); if (ega->dispon) ega->stat &= ~1; ega->linepos = 0; @@ -549,17 +534,14 @@ void ega_poll(void *p) } ega->vc++; ega->vc &= 1023; -// printf("Line now %i %i ma %05X\n",vc,displine,ma); if (ega->vc == ega->split) { -// printf("Split at line %i %i\n",displine,vc); ega->ma = ega->maback = 0; if (ega->attrregs[0x10] & 0x20) ega->scrollcache = 0; } if (ega->vc == ega->dispend) { -// printf("Display over at line %i %i\n",displine,vc); ega->dispon=0; if (ega->crtc[10] & 0x20) ega->cursoron = 0; else ega->cursoron = ega->blink & 16; @@ -572,21 +554,32 @@ void ega_poll(void *p) } if (ega->vc == ega->vsyncstart) { - int wx, wy; ega->dispon = 0; -// printf("Vsync on at line %i %i\n",displine,vc); ega->stat |= 8; if (ega->seqregs[1] & 8) x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9) * 2; else x = ega->hdisp * ((ega->seqregs[1] & 1) ? 8 : 9); -// pclog("Cursor %02X %02X\n",crtc[10],crtc[11]); -// pclog("Firstline %i Lastline %i wx %i %i\n",firstline,lastline,wx,oddeven); -// doblit(); - if (x != xsize || (ega->lastline - ega->firstline) != ysize) + if ((x != xsize || (ega->lastline - ega->firstline) != ysize) || update_overscan) { xsize = x; ysize = ega->lastline - ega->firstline; - if (xsize < 64) xsize = 656; + if (xsize < 64) xsize = 640; if (ysize < 32) ysize = 200; + y_add = enable_overscan ? 14 : 0; + x_add = enable_overscan ? 8 : 0; + y_add_ex = enable_overscan ? 28 : 0; + x_add_ex = enable_overscan ? 16 : 0; + + if ((xsize > 2032) || (ysize > 2032)) + { + x_add = x_add_ex = 0; + y_add = y_add_ex = 0; + suppress_overscan = 1; + } + else + { + suppress_overscan = 0; + } + if (ega->vres) updatewindowsize(xsize + x_add_ex, (ysize << 1) + y_add_ex); else @@ -646,9 +639,7 @@ void ega_poll(void *p) ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; } -// wakeupblit(); readflash=0; - //framecount++; ega->firstline = 2000; ega->lastline = 0; @@ -700,7 +691,6 @@ void ega_write(uint32_t addr, uint8_t val, void *p) if (!(ega->gdcreg[6] & 1)) fullchange = 2; -// pclog("%i %08X %i %i %02X %02X %02X %02X %02X\n",chain4,addr,writemode,writemask,gdcreg[8],vram[0],vram[1],vram[2],vram[3]); switch (ega->writemode) { case 1: @@ -730,7 +720,6 @@ void ega_write(uint32_t addr, uint8_t val, void *p) else valc = val; if (ega->gdcreg[1] & 8) vald = (ega->gdcreg[0] & 8) ? 0xff : 0; else vald = val; -// pclog("Write %02X %01X %02X %02X %02X %02X %02X\n",gdcreg[3]&0x18,writemask,vala,valb,valc,vald,gdcreg[8]); switch (ega->gdcreg[3] & 0x18) { case 0: /*Set*/ @@ -758,7 +747,6 @@ void ega_write(uint32_t addr, uint8_t val, void *p) if (writemask2 & 8) ega->vram[addr | 0x3] = (vald & ega->gdcreg[8]) ^ ega->ld; break; } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); } break; case 2: @@ -816,7 +804,6 @@ uint8_t ega_read(uint32_t addr, void *p) egareads++; cycles -= video_timing_b; cycles_lost += video_timing_b; -// pclog("Readega %06X ",addr); if (addr >= 0xb0000) addr &= 0x7fff; else addr &= 0xffff; @@ -901,11 +888,12 @@ void ega_common_defaults(ega_t *ega) ega->seqregs[4] |= 2; ega->extvram = 1; + + update_overscan = 0; } void *ega_standalone_init() { - int c, d, e; ega_t *ega = malloc(sizeof(ega_t)); memset(ega, 0, sizeof(ega_t)); @@ -944,7 +932,6 @@ void *ega_standalone_init() void *cpqega_standalone_init() { - int c, d, e; ega_t *ega = malloc(sizeof(ega_t)); memset(ega, 0, sizeof(ega_t)); @@ -956,7 +943,6 @@ void *cpqega_standalone_init() if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { int c; - // pclog("Read EGA ROM in reverse\n"); for (c = 0; c < 0x2000; c++) { @@ -967,25 +953,21 @@ void *cpqega_standalone_init() } ega->crtc[0] = 63; - // ega->crtc[6] = 255; ega->dispontime = 1000 * (1 << TIMER_SHIFT); ega->dispofftime = 1000 * (1 << TIMER_SHIFT); ega_init(ega); - // ega->attrregs[0x10] |= 0xF7; ega_common_defaults(ega); mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); - // io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; } void *sega_standalone_init() { - int c, d, e; ega_t *ega = malloc(sizeof(ega_t)); memset(ega, 0, sizeof(ega_t)); @@ -997,7 +979,6 @@ void *sega_standalone_init() if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { int c; - // pclog("Read EGA ROM in reverse\n"); for (c = 0; c < 0x2000; c++) { @@ -1008,18 +989,15 @@ void *sega_standalone_init() } ega->crtc[0] = 63; - // ega->crtc[6] = 255; ega->dispontime = 1000 * (1 << TIMER_SHIFT); ega->dispofftime = 1000 * (1 << TIMER_SHIFT); ega_init(ega); - // ega->attrregs[0x10] |= 0xF7; ega_common_defaults(ega); mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); - // io_sethandler(0x03a0, 0x0040, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; } diff --git a/src/vid_ega.h b/src/vid_ega.h index 0d3c12439..9b0e215d8 100644 --- a/src/vid_ega.h +++ b/src/vid_ega.h @@ -70,6 +70,8 @@ typedef struct ega_t int video_res_x, video_res_y, video_bpp; } ega_t; +extern int update_overscan; + void *ega_standalone_init(); void ega_out(uint16_t addr, uint8_t val, void *p); uint8_t ega_in(uint16_t addr, void *p); @@ -77,6 +79,7 @@ void ega_poll(void *p); void ega_recalctimings(struct ega_t *ega); void ega_write(uint32_t addr, uint8_t val, void *p); uint8_t ega_read(uint32_t addr, void *p); +void ega_init(ega_t *ega); extern device_t ega_device; extern device_t cpqega_device; diff --git a/src/vid_et4000.c b/src/vid_et4000.c index aae35bdb5..ca845982b 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -46,8 +46,6 @@ void et4000_out(uint16_t addr, uint8_t val, void *p) if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; -// pclog("ET4000 out %04X %02X\n", addr, val); - switch (addr) { case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: @@ -58,13 +56,11 @@ void et4000_out(uint16_t addr, uint8_t val, void *p) svga->write_bank = (val & 0xf) * 0x10000; svga->read_bank = ((val >> 4) & 0xf) * 0x10000; et4000->banking = val; -// pclog("Banking write %08X %08X %02X\n", svga->write_bank, svga->read_bank, val); return; case 0x3D4: svga->crtcreg = val & 0x3f; return; case 0x3D5: - // pclog("ET4000 Write: CRTC %02X = %02X\n", svga->crtcreg, val); if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -92,9 +88,7 @@ uint8_t et4000_in(uint16_t addr, void *p) if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; - -// if (addr != 0x3da) pclog("IN ET4000 %04X\n", addr); - + switch (addr) { case 0x3C5: @@ -116,8 +110,6 @@ uint8_t et4000_in(uint16_t addr, void *p) void et4000_recalctimings(svga_t *svga) { - et4000_t *et4000 = (et4000_t *)svga->p; - svga->ma_latch |= (svga->crtc[0x33]&3)<<16; if (svga->crtc[0x35] & 1) svga->vblankstart += 0x400; if (svga->crtc[0x35] & 2) svga->vtotal += 0x400; @@ -128,8 +120,6 @@ void et4000_recalctimings(svga_t *svga) if (svga->crtc[0x3f] & 1) svga->htotal += 256; if (svga->attrregs[0x16] & 0x20) svga->hdisp <<= 1; -// pclog("Rowoffset %i\n",svga_rowoffset); - switch (((svga->miscout >> 2) & 3) | ((svga->crtc[0x34] << 1) & 4)) { case 0: case 1: break; diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index 430bf7347..bac8c5fa7 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -120,17 +120,9 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = &et4000->svga; uint8_t old; -// pclog("et4000w32p_out: addr %04X val %02X %04X:%04X %02X %02X\n", addr, val, CS, pc, ram[0x487], ram[0x488]); - -/* if (ram[0x487] == 0x62) - fatal("mono\n");*/ -// if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("ET4000W32p out %04X %02X %04X:%04X ",addr,val,CS,pc); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// if (!(addr==0x3D4 && (val&~1)==0xE) && !(addr==0x3D5 && (crtcreg&~1)==0xE)) pclog("%04X\n",addr); - switch (addr) { case 0x3c2: @@ -156,7 +148,6 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) { case 6: svga->gdcreg[svga->gdcaddr & 15] = val; - //et4k_b8000=((crtc[0x36]&0x38)==0x28) && ((gdcreg[6]&0xC)==4); et4000w32p_recalcmapping(et4000); return; } @@ -165,7 +156,6 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga->crtcreg = val & 63; return; case 0x3D5: -// pclog("Write CRTC R%02X %02X\n", crtcreg, val); if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -191,8 +181,6 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) { et4000->linearbase = val << 22; } - // et4000->linearbase = val * 0x400000; -// pclog("Linear base now at %08X %02X\n", et4000w32p_linearbase, val); et4000w32p_recalcmapping(et4000); } if (svga->crtcreg == 0x32 || svga->crtcreg == 0x36) @@ -213,7 +201,6 @@ void et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = et4000->regs[0xF7] & 0x80; svga->hwcursor.xoff = et4000->regs[0xE2] & 63; svga->hwcursor.yoff = et4000->regs[0xE6] & 63; -// pclog("HWCURSOR X %i Y %i\n",svga->hwcursor_x,svga->hwcursor_y); return; } @@ -225,18 +212,10 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) et4000w32p_t *et4000 = (et4000w32p_t *)p; svga_t *svga = &et4000->svga; uint8_t temp; -// if (addr==0x3DA) pclog("In 3DA %04X(%06X):%04X\n",CS,cs,pc); - -// pclog("ET4000W32p in %04X %04X:%04X ",addr,CS,pc); -// if (addr != 0x3da && addr != 0x3ba) -// pclog("et4000w32p_in: addr %04X %04X:%04X %02X %02X\n", addr, CS, pc, ram[0x487], ram[0x488]); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// pclog("%04X\n",addr); - switch (addr) { case 0x3c5: @@ -254,7 +233,6 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) case 0x3D4: return svga->crtcreg; case 0x3D5: -// pclog("Read CRTC R%02X %02X\n", crtcreg, crtc[crtcreg]); return svga->crtc[svga->crtcreg]; case 0x3DA: @@ -263,7 +241,6 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) temp = svga->cgastat & 0x39; if (svga->hdisp_on) temp |= 2; if (!(svga->cgastat & 8)) temp |= 0x80; -// pclog("3DA in %02X\n",temp); return temp; case 0x210A: case 0x211A: case 0x212A: case 0x213A: @@ -286,9 +263,7 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) void et4000w32p_recalctimings(svga_t *svga) { et4000w32p_t *et4000 = (et4000w32p_t *)svga->p; -// pclog("Recalc %08X ",svga_ma); svga->ma_latch |= (svga->crtc[0x33] & 0x7) << 16; -// pclog("SVGA_MA %08X %i\n", svga_ma, (svga_miscout >> 2) & 3); if (svga->crtc[0x35] & 0x01) svga->vblankstart += 0x400; if (svga->crtc[0x35] & 0x02) svga->vtotal += 0x400; if (svga->crtc[0x35] & 0x04) svga->dispend += 0x400; @@ -321,14 +296,12 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000) if (!(et4000->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - // pclog("Update mapping - PCI disabled\n"); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&et4000->linear_mapping); mem_mapping_disable(&et4000->mmu_mapping); return; } - // pclog("recalcmapping %p\n", svga); if (svga->crtc[0x36] & 0x10) /*Linear frame buffer*/ { mem_mapping_set_addr(&et4000->linear_mapping, et4000->linearbase, 0x200000); @@ -381,7 +354,6 @@ void et4000w32p_recalcmapping(et4000w32p_t *et4000) } mem_mapping_disable(&et4000->linear_mapping); -// pclog("ET4K map %02X\n", map); } et4000->linearbase_old = et4000->linearbase; @@ -472,6 +444,11 @@ static void et4000w32p_accel_write_mmu(et4000w32p_t *et4000, uint32_t addr, uint static void fifo_thread(void *param) { et4000w32p_t *et4000 = (et4000w32p_t *)param; + + uint64_t start_time = 0; + uint64_t end_time = 0; + + fifo_entry_t *fifo; while (1) { @@ -481,10 +458,8 @@ static void fifo_thread(void *param) et4000->blitter_busy = 1; while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; + start_time = timer_read(); + fifo = &et4000->fifo[et4000->fifo_read_idx & FIFO_MASK]; switch (fifo->addr_type & FIFO_TYPE) { @@ -509,7 +484,7 @@ static void fifo_thread(void *param) } } -static inline void wake_fifo_thread(et4000w32p_t *et4000) +static __inline void wake_fifo_thread(et4000w32p_t *et4000) { thread_set_event(et4000->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -526,7 +501,6 @@ static void et4000w32p_wait_fifo_idle(et4000w32p_t *et4000) static void et4000w32p_queue(et4000w32p_t *et4000, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &et4000->fifo[et4000->fifo_write_idx & FIFO_MASK]; - int c; if (FIFO_FULL) { @@ -551,8 +525,6 @@ void et4000w32p_mmu_write(uint32_t addr, uint8_t val, void *p) et4000w32p_t *et4000 = (et4000w32p_t *)p; svga_t *svga = &et4000->svga; int bank; -// pclog("ET4K write %08X %02X %02X %04X(%08X):%08X\n",addr,val,et4000->acl.status,et4000->acl.internal.ctrl_routing,CS,cs,pc); -// et4000->acl.status |= ACL_RDST; switch (addr & 0x6000) { case 0x0000: /*MMU 0*/ @@ -603,7 +575,6 @@ uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) svga_t *svga = &et4000->svga; int bank; uint8_t temp; -// pclog("ET4K read %08X %04X(%08X):%08X\n",addr,CS,cs,pc); switch (addr & 0x6000) { case 0x0000: /*MMU 0*/ @@ -650,13 +621,11 @@ uint8_t et4000w32p_mmu_read(uint32_t addr, void *p) case 0x7f36: temp = et4000->acl.status; -// et4000->acl.status &= ~ACL_RDST; temp &= ~0x03; if (!FIFO_EMPTY) temp |= 0x02; if (FIFO_FULL) temp |= 0x01; -// if (et4000->acl.internal.pos_x!=et4000->acl.internal.count_x || et4000->acl.internal.pos_y!=et4000->acl.internal.count_y) return et4000->acl.status | ACL_XYST; return temp; case 0x7f80: return et4000->acl.internal.pattern_addr; case 0x7f81: return et4000->acl.internal.pattern_addr >> 8; @@ -701,10 +670,6 @@ static int et4000w32_wrap_y[8]={1,2,4,8,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF int bltout=0; void et4000w32_blit_start(et4000w32p_t *et4000) { -// if (et4000->acl.queued.xy_dir&0x80) -// pclog("Blit - %02X %08X (%i,%i) %08X (%i,%i) %08X (%i,%i) %i %i %i %02X %02X %02X\n",et4000->acl.queued.xy_dir,et4000->acl.internal.pattern_addr,(et4000->acl.internal.pattern_addr/3)%640,(et4000->acl.internal.pattern_addr/3)/640,et4000->acl.internal.source_addr,(et4000->acl.internal.source_addr/3)%640,(et4000->acl.internal.source_addr/3)/640,et4000->acl.internal.dest_addr,(et4000->acl.internal.dest_addr/3)%640,(et4000->acl.internal.dest_addr/3)/640,et4000->acl.internal.xy_dir,et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.internal.rop_fg,et4000->acl.internal.rop_bg, et4000->acl.internal.ctrl_routing); -// bltout=1; -// bltout=(et4000->acl.internal.count_x==1541); if (!(et4000->acl.queued.xy_dir & 0x20)) et4000->acl.internal.error = et4000->acl.internal.dmaj / 2; et4000->acl.pattern_addr= et4000->acl.internal.pattern_addr; @@ -824,8 +789,6 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et400 int mixdat; if (!(et4000->acl.status & ACL_XYST)) return; -// if (count>400) pclog("New blit - %i,%i %06X (%i,%i) %06X %06X\n",et4000->acl.internal.count_x,et4000->acl.internal.count_y,et4000->acl.dest_addr,et4000->acl.dest_addr%640,et4000->acl.dest_addr/640,et4000->acl.source_addr,et4000->acl.pattern_addr); - //pclog("Blit exec - %i %i %i\n",count,et4000->acl.internal.pos_x,et4000->acl.internal.pos_y); if (et4000->acl.internal.xy_dir & 0x80) /*Line draw*/ { while (count--) @@ -874,7 +837,6 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et400 et4000->acl.cpu_dat_pos++; } -// pclog("%i %i\n",et4000->acl.pix_pos,(et4000->acl.internal.pixel_depth>>4)&3); et4000->acl.pix_pos++; et4000->acl.internal.pos_x++; if (et4000->acl.pix_pos <= ((et4000->acl.internal.pixel_depth >> 4) & 3)) @@ -904,11 +866,9 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et400 break; case 4: case 6: /*X+*/ et4000w32_incx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - //et4000->acl.internal.pos_x++; break; case 5: case 7: /*X-*/ et4000w32_decx(((et4000->acl.internal.pixel_depth >> 4) & 3) + 1, et4000); - //et4000->acl.internal.pos_x++; break; } et4000->acl.internal.error += et4000->acl.internal.dmin; @@ -939,7 +899,6 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et400 et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { et4000->acl.status &= ~(ACL_XYST | ACL_SSO); -// pclog("Blit line over\n"); return; } } @@ -1022,7 +981,6 @@ void et4000w32_blit(int count, uint32_t mix, uint32_t sdat, int cpu_input, et400 if (et4000->acl.internal.pos_y > et4000->acl.internal.count_y) { et4000->acl.status &= ~(ACL_XYST | ACL_SSO); -// pclog("Blit over\n"); return; } if (cpu_input) return; @@ -1042,9 +1000,10 @@ void et4000w32p_hwcursor_draw(svga_t *svga, int displine) { int x, offset; uint8_t dat; - offset = svga->hwcursor_latch.xoff; int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + offset = svga->hwcursor_latch.xoff; + for (x = 0; x < 64 - svga->hwcursor_latch.xoff; x += 4) { dat = svga->vram[svga->hwcursor_latch.addr + (offset >> 2)]; @@ -1098,12 +1057,9 @@ static void et4000w32p_io_set(et4000w32p_t *et4000) uint8_t et4000w32p_pci_read(int func, int addr, void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; - svga_t *svga = &et4000->svga; addr &= 0xff; - // pclog("ET4000 PCI read %08X\n", addr); - switch (addr) { case 0x00: return 0x0c; /*Tseng Labs*/ @@ -1141,12 +1097,9 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; svga_t *svga = &et4000->svga; - uint32_t temp = 0; addr &= 0xff; - // pclog("ET4000 PCI Write: value %02X to address %08X\n"); - switch (addr) { case PCI_REG_COMMAND: @@ -1174,7 +1127,6 @@ void et4000w32p_pci_write(int func, int addr, uint8_t val, void *p) et4000->pci_regs[0x33] &= 0xf0; if (et4000->pci_regs[0x30] & 0x01) { - // uint32_t addr = ((et4000->pci_regs[0x31] & 0x80) << 8) | ((et4000->pci_regs[0x32] & 0x0f) << 16) | (et4000->pci_regs[0x33] << 24); uint32_t addr = (et4000->pci_regs[0x33] << 24); if (!addr) { @@ -1252,6 +1204,10 @@ void et4000w32p_close(void *p) svga_close(&et4000->svga); + thread_kill(et4000->fifo_thread); + thread_destroy_event(et4000->wake_fifo_thread); + thread_destroy_event(et4000->fifo_not_full_event); + free(et4000); } @@ -1288,27 +1244,21 @@ void et4000w32p_add_status_info(char *s, int max_len, void *p) static device_config_t et4000w32p_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 2, { { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_genius.c b/src/vid_genius.c new file mode 100644 index 000000000..bc9ca6e1c --- /dev/null +++ b/src/vid_genius.c @@ -0,0 +1,629 @@ +/* MDSI Genius VHR emulation*/ +#include +#include "ibm.h" +#include "device.h" +#include "io.h" +#include "mem.h" +#include "rom.h" +#include "timer.h" +#include "video.h" +#include "vid_genius.h" + +#define GENIUS_XSIZE 728 +#define GENIUS_YSIZE 1008 + +void updatewindowsize(int x, int y); +void loadfont(char *s, int format); + +extern uint8_t fontdat8x12[256][16]; + +/* I'm at something of a disadvantage writing this emulation: I don't have an + * MDSI Genius card, nor do I have the BIOS extension (VHRBIOS.SYS) that came + * with it. What I do have are the GEM and Windows 1.04 drivers, plus a driver + * for a later MCA version of the card. The latter can be found at + * and is necessary if you + * want the Windows driver to work. + * + * This emulation appears to work correctly with: + * The MCA drivers GMC_ANSI.SYS and INS_ANSI.SYS + * The GEM driver SDGEN9.VGA + * The Windows 1.04 driver GENIUS.DRV + * + * As far as I can see, the card uses a fixed resolution of 728x1008 pixels. + * It has the following modes of operation: + * + * > MDA-compatible: 80x25 text, each character 9x15 pixels. + * > CGA-compatible: 640x200 mono graphics + * > Dual: MDA text in the top half, CGA graphics in the bottom + * > Native text: 80x66 text, each character 9x15 pixels. + * > Native graphics: 728x1008 mono graphics. + * + * Under the covers, this seems to translate to: + * > Text framebuffer. At B000:0000, 16k. Displayed if enable bit is set + * in the MDA control register. + * > Graphics framebuffer. In native modes goes from A000:0000 to A000:FFFF + * and B800:0000 to B800:FFFF. In CGA-compatible + * mode only the section at B800:0000 to B800:7FFF + * is visible. Displayed if enable bit is set in the + * CGA control register. + * + * Two card-specific registers control text and graphics display: + * + * 03B0: Control register. + * Bit 0: Map all graphics framebuffer into memory. + * Bit 2: Unknown. Set by GMC /M; cleared by mode set or GMC /T. + * Bit 4: Set for CGA-compatible graphics, clear for native graphics. + * Bit 5: Set for black on white, clear for white on black. + * + * 03B1: Character height register. + * Bits 0-1: Character cell height (0 => 15, 1 => 14, 2 => 13, 3 => 12) + * Bit 4: Set to double character cell height (scanlines are doubled) + * Bit 7: Unknown, seems to be set for all modes except 80x66 + * + * Not having the card also means I don't have its font. According to the + * card brochure the font is an 8x12 bitmap in a 9x15 character cell. I + * therefore generated it by taking the MDA font, increasing graphics to + * 16 pixels in height and reducing the height of characters so they fit + * in an 8x12 cell if necessary. + */ + + + +typedef struct genius_t +{ + mem_mapping_t mapping; + + uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ + int mda_crtcreg; /* Current CRTC register */ + uint8_t genius_control; /* Native control register + * I think bit 0 enables the full + * framebuffer. + */ + uint8_t genius_charh; /* Native character height register: + * 00h => chars are 15 pixels high + * 81h => chars are 14 pixels high + * 83h => chars are 12 pixels high + * 90h => chars are 30 pixels high [15 x 2] + * 93h => chars are 24 pixels high [12 x 2] + */ + uint8_t genius_mode; /* Current mode (see list at top of file) */ + uint8_t cga_ctrl; /* Emulated CGA control register */ + uint8_t mda_ctrl; /* Emulated MDA control register */ + uint8_t cga_colour; /* Emulated CGA colour register (ignored) */ + + uint8_t mda_stat; /* MDA status (IN 0x3BA) */ + uint8_t cga_stat; /* CGA status (IN 0x3DA) */ + + int font; /* Current font, 0 or 1 */ + int enabled; /* Display enabled, 0 or 1 */ + int detach; /* Detach cursor, 0 or 1 */ + + int dispontime, dispofftime; + int vidtime; + + int linepos, displine; + int vc; + int dispon, blink; + int vsynctime; + + uint8_t *vram; +} genius_t; + +/* Mapping of attributes to colours, in MDA emulation mode */ +static int mdacols[256][2][2]; + +void genius_recalctimings(genius_t *genius); +void genius_write(uint32_t addr, uint8_t val, void *p); +uint8_t genius_read(uint32_t addr, void *p); + + +void genius_out(uint16_t addr, uint8_t val, void *p) +{ + genius_t *genius = (genius_t *)p; + + switch (addr) + { + case 0x3b0: /* Command / control register */ + genius->genius_control = val; + if (val & 1) + { + mem_mapping_set_addr(&genius->mapping, 0xa0000, 0x28000); + } + else + { + mem_mapping_set_addr(&genius->mapping, 0xb0000, 0x10000); + } + + break; + + case 0x3b1: + genius->genius_charh = val; + break; + + /* Emulated CRTC, register select */ + case 0x3b2: case 0x3b4: case 0x3b6: + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: + genius->mda_crtcreg = val & 31; + break; + + /* Emulated CRTC, value */ + case 0x3b3: case 0x3b5: case 0x3b7: + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + genius->mda_crtc[genius->mda_crtcreg] = val; + genius_recalctimings(genius); + return; + + /* Emulated MDA control register */ + case 0x3b8: + genius->mda_ctrl = val; + return; + /* Emulated CGA control register */ + case 0x3D8: + genius->cga_ctrl = val; + return; + /* Emulated CGA colour register */ + case 0x3D9: + genius->cga_colour = val; + return; + } +} + +uint8_t genius_in(uint16_t addr, void *p) +{ + genius_t *genius = (genius_t *)p; + + switch (addr) + { + case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6: + case 0x3d0: case 0x3d2: case 0x3d4: case 0x3d6: + return genius->mda_crtcreg; + case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7: + case 0x3d1: case 0x3d3: case 0x3d5: case 0x3d7: + return genius->mda_crtc[genius->mda_crtcreg]; + case 0x3b8: + return genius->mda_ctrl; + case 0x3d9: + return genius->cga_colour; + case 0x3ba: + return genius->mda_stat; + case 0x3d8: + return genius->cga_ctrl; + case 0x3da: + return genius->cga_stat; + } + return 0xff; +} + + + +void genius_write(uint32_t addr, uint8_t val, void *p) +{ + genius_t *genius = (genius_t *)p; + egawrites++; + + if (genius->genius_control & 1) + { + addr = addr % 0x28000; + } + else + /* If hi-res memory is disabled, only visible in the B000 segment */ + { + addr = (addr & 0xFFFF) + 0x10000; + } + genius->vram[addr] = val; +} + + + +uint8_t genius_read(uint32_t addr, void *p) +{ + genius_t *genius = (genius_t *)p; + egareads++; + + if (genius->genius_control & 1) + { + addr = addr % 0x28000; + } + else + /* If hi-res memory is disabled, only visible in the B000 segment */ + { + addr = (addr & 0xFFFF) + 0x10000; + } + return genius->vram[addr]; +} + + + +void genius_recalctimings(genius_t *genius) +{ + double disptime; + double _dispontime, _dispofftime; + + disptime = 0x31; + _dispontime = 0x28; + _dispofftime = disptime - _dispontime; + _dispontime *= MDACONST; + _dispofftime *= MDACONST; + genius->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); + genius->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); +} + + +/* Draw a single line of the screen in either text mode */ +void genius_textline(genius_t *genius, uint8_t background) +{ + int x; + int w = 80; /* 80 characters across */ + int cw = 9; /* Each character is 9 pixels wide */ + uint8_t chr, attr; + uint8_t bitmap[2]; + int blink, c, row; + int drawcursor, cursorline; + uint16_t addr; + uint8_t sc; + int charh; + uint16_t ma = (genius->mda_crtc[13] | (genius->mda_crtc[12] << 8)) & 0x3fff; + uint16_t ca = (genius->mda_crtc[15] | (genius->mda_crtc[14] << 8)) & 0x3fff; + unsigned char *framebuf = genius->vram + 0x10000; + uint8_t col; + + /* Character height is 12-15 */ + charh = 15 - (genius->genius_charh & 3); + if (genius->genius_charh & 0x10) + { + row = ((genius->displine >> 1) / charh); + sc = ((genius->displine >> 1) % charh); + } + else + { + row = (genius->displine / charh); + sc = (genius->displine % charh); + } + addr = ((ma & ~1) + row * w) * 2; + + ma += (row * w); + + if ((genius->mda_crtc[10] & 0x60) == 0x20) + { + cursorline = 0; + } + else + { + cursorline = ((genius->mda_crtc[10] & 0x1F) <= sc) && + ((genius->mda_crtc[11] & 0x1F) >= sc); + } + + for (x = 0; x < w; x++) + { + chr = framebuf[(addr + 2 * x) & 0x3FFF]; + attr = framebuf[(addr + 2 * x + 1) & 0x3FFF]; + drawcursor = ((ma == ca) && cursorline && genius->enabled && + (genius->mda_ctrl & 8)); + + switch (genius->mda_crtc[10] & 0x60) + { + case 0x00: drawcursor = drawcursor && (genius->blink & 16); break; + case 0x60: drawcursor = drawcursor && (genius->blink & 32); break; + } + blink = ((genius->blink & 16) && + (genius->mda_ctrl & 0x20) && + (attr & 0x80) && !drawcursor); + + if (genius->mda_ctrl & 0x20) attr &= 0x7F; + /* MDA underline */ + if (sc == charh && ((attr & 7) == 1)) + { + col = mdacols[attr][blink][1]; + + if (genius->genius_control & 0x20) + { + col ^= 15; + } + + for (c = 0; c < cw; c++) + { + if (col != background) + buffer->line[genius->displine][(x * cw) + c] = col; + } + } + else /* Draw 8 pixels of character */ + { + bitmap[0] = fontdat8x12[chr][sc]; + for (c = 0; c < 8; c++) + { + col = mdacols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; + if (!(genius->enabled) || !(genius->mda_ctrl & 8)) + col = mdacols[0][0][0]; + + if (genius->genius_control & 0x20) + { + col ^= 15; + } + if (col != background) + { + buffer->line[genius->displine][(x * cw) + c] = col; + } + } + /* The ninth pixel column... */ + if ((chr & ~0x1f) == 0xc0) + { + /* Echo column 8 for the graphics chars */ + col = buffer->line[genius->displine][(x * cw) + 7]; + if (col != background) buffer->line[genius->displine][(x * cw) + 8] = col; + } + else /* Otherwise fill with background */ + { + col = mdacols[attr][blink][0]; + if (genius->genius_control & 0x20) + { + col ^= 15; + } + if (col != background) buffer->line[genius->displine][(x * cw) + 8] = col; + } + if (drawcursor) + { + for (c = 0; c < cw; c++) + buffer->line[genius->displine][(x * cw) + c] ^= mdacols[attr][0][1]; + } + ++ma; + } + } +} + + + + +/* Draw a line in the CGA 640x200 mode */ +void genius_cgaline(genius_t *genius) +{ + int x, c; + uint32_t dat; + uint8_t ink; + uint32_t addr; + + ink = (genius->genius_control & 0x20) ? 16 : 16+15; + /* We draw the CGA at row 600 */ + if (genius->displine < 600) + { + return; + } + addr = 0x18000 + 80 * ((genius->displine - 600) >> 2); + if ((genius->displine - 600) & 2) + { + addr += 0x2000; + } + + for (x = 0; x < 80; x++) + { + dat = genius->vram[addr]; + addr++; + + for (c = 0; c < 8; c++) + { + if (dat & 0x80) + { + buffer->line[genius->displine][x*8 + c] = ink; + } + dat = dat << 1; + } + } +} + + + + +/* Draw a line in the native high-resolution mode */ +void genius_hiresline(genius_t *genius) +{ + int x, c; + uint32_t dat; + uint8_t ink; + uint32_t addr; + + ink = (genius->genius_control & 0x20) ? 16 : 16+15; + /* The first 512 lines live at A0000 */ + if (genius->displine < 512) + { + addr = 128 * genius->displine; + } + else /* The second 496 live at B8000 */ + { + addr = 0x18000 + 128 * (genius->displine - 512); + } + + for (x = 0; x < 91; x++) + { + dat = genius->vram[addr]; + addr++; + + for (c = 0; c < 8; c++) + { + if (dat & 0x80) + { + buffer->line[genius->displine][x*8 + c] = ink; + } + dat = dat << 1; + } + } +} + + + + +void genius_poll(void *p) +{ + genius_t *genius = (genius_t *)p; + int x; + uint8_t background; + + if (!genius->linepos) + { + genius->vidtime += genius->dispofftime; + genius->cga_stat |= 1; + genius->mda_stat |= 1; + genius->linepos = 1; + if (genius->dispon) + { + if (genius->genius_control & 0x20) + { + background = 16 + 15; + } + else + { + background = 16; + } + if (genius->displine == 0) + { + video_wait_for_buffer(); + } + /* Start off with a blank line */ + for (x = 0; x < GENIUS_XSIZE; x++) + { + buffer->line[genius->displine][x] = background; + } + /* If graphics display enabled, draw graphics on top + * of the blanked line */ + if (genius->cga_ctrl & 8) + { + if (genius->genius_control & 8) + { + genius_cgaline(genius); + } + else + { + genius_hiresline(genius); + } + } + /* If MDA display is enabled, draw MDA text on top + * of the lot */ + if (genius->mda_ctrl & 8) + { + genius_textline(genius, background); + } + } + genius->displine++; + /* Hardcode a fixed refresh rate and VSYNC timing */ + if (genius->displine == 1008) /* Start of VSYNC */ + { + genius->cga_stat |= 8; + genius->dispon = 0; + } + if (genius->displine == 1040) /* End of VSYNC */ + { + genius->displine = 0; + genius->cga_stat &= ~8; + genius->dispon = 1; + } + } + else + { + if (genius->dispon) + { + genius->cga_stat &= ~1; + genius->mda_stat &= ~1; + } + genius->vidtime += genius->dispontime; + genius->linepos = 0; + + if (genius->displine == 1008) + { +/* Hardcode GENIUS_XSIZE * GENIUS_YSIZE window size */ + if (GENIUS_XSIZE != xsize || GENIUS_YSIZE != ysize) + { + xsize = GENIUS_XSIZE; + ysize = GENIUS_YSIZE; + if (xsize < 64) xsize = 656; + if (ysize < 32) ysize = 200; + updatewindowsize(xsize, ysize); + } + video_blit_memtoscreen_8(0, 0, xsize, ysize); + + frames++; + /* Fixed 728x1008 resolution */ + video_res_x = GENIUS_XSIZE; + video_res_y = GENIUS_YSIZE; + video_bpp = 1; + genius->blink++; + } + } +} + +void *genius_init() +{ + int c; + genius_t *genius = malloc(sizeof(genius_t)); + memset(genius, 0, sizeof(genius_t)); + + /* 160k video RAM */ + genius->vram = malloc(0x28000); + + timer_add(genius_poll, &genius->vidtime, TIMER_ALWAYS_ENABLED, genius); + + /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in + * high-resolution modes) */ + mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, 0, genius); + /* Respond to both MDA and CGA I/O ports */ + io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); + io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); + + /* MDA attributes */ + /* I don't know if the Genius's MDA emulation actually does + * emulate bright / non-bright. For the time being pretend it does. */ + for (c = 0; c < 256; c++) + { + mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16; + if (c & 8) mdacols[c][0][1] = 15 + 16; + else mdacols[c][0][1] = 7 + 16; + } + mdacols[0x70][0][1] = 16; + mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15; + mdacols[0xF0][0][1] = 16; + mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15; + mdacols[0x78][0][1] = 16 + 7; + mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15; + mdacols[0xF8][0][1] = 16 + 7; + mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15; + mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16; + mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16; + mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16; + mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16; + +/* Start off in 80x25 text mode */ + genius->cga_stat = 0xF4; + genius->genius_mode = 2; + genius->enabled = 1; + genius->genius_charh = 0x90; /* Native character height register */ + return genius; +} + +void genius_close(void *p) +{ + genius_t *genius = (genius_t *)p; + + free(genius->vram); + free(genius); +} + +static int genius_available() +{ + return rom_present("roms/8x12.bin"); +} + +void genius_speed_changed(void *p) +{ + genius_t *genius = (genius_t *)p; + + genius_recalctimings(genius); +} + +device_t genius_device = +{ + "Genius VHR", + 0, + genius_init, + genius_close, + genius_available, + genius_speed_changed, + NULL, + NULL +}; diff --git a/src/vid_genius.h b/src/vid_genius.h new file mode 100644 index 000000000..77dce66f0 --- /dev/null +++ b/src/vid_genius.h @@ -0,0 +1 @@ +extern device_t genius_device; diff --git a/src/vid_hercules.c b/src/vid_hercules.c index 2c96a5654..4a9606b32 100644 --- a/src/vid_hercules.c +++ b/src/vid_hercules.c @@ -6,6 +6,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "io.h" #include "timer.h" #include "video.h" #include "vid_hercules.h" @@ -131,7 +132,6 @@ void hercules_poll(void *p) int oldvc; uint8_t chr, attr; uint16_t dat; - int cols[4]; int oldsc; int blink; if (!hercules->linepos) @@ -151,8 +151,6 @@ void hercules_poll(void *p) video_wait_for_buffer(); } hercules->lastline = hercules->displine; - cols[0] = 0; - cols[1] = 7; if ((hercules->ctrl & 2) && (hercules->ctrl2 & 1)) { ca = (hercules->sc & 3) * 0x2000; @@ -171,8 +169,8 @@ void hercules_poll(void *p) { for (x = 0; x < hercules->crtc[1]; x++) { - chr = hercules->vram[(hercules->ma << 1) & 0x3fff]; - attr = hercules->vram[((hercules->ma << 1) + 1) & 0x3fff]; + chr = hercules->vram[(hercules->ma << 1) & 0xfff]; + attr = hercules->vram[((hercules->ma << 1) + 1) & 0xfff]; drawcursor = ((hercules->ma == ca) && hercules->con && hercules->cursoron); blink = ((hercules->blink & 16) && (hercules->ctrl & 0x20) && (attr & 0x80) && !drawcursor); if (hercules->sc == 12 && ((attr & 7) == 1)) @@ -376,35 +374,27 @@ void hercules_speed_changed(void *p) static device_config_t hercules_config[] = { { - .name = "rgb_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = + "rgb_type", "Display type", CONFIG_SELECTION, "", 0, { { - .description = "Default", - .value = 0 + "Default", 0 }, { - .description = "Green", - .value = 1 + "Green", 1 }, { - .description = "Amber", - .value = 2 + "Amber", 2 }, { - .description = "Gray", - .value = 3 + "Gray", 3 }, { - .description = "" + "" } - }, - .default_int = 0 + } }, { - .type = -1 + "", "", -1 } }; #endif diff --git a/src/vid_herculesplus.c b/src/vid_herculesplus.c index 6a35c8bcf..7af5d4a9c 100644 --- a/src/vid_herculesplus.c +++ b/src/vid_herculesplus.c @@ -7,6 +7,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "io.h" #include "timer.h" #include "video.h" #include "vid_herculesplus.h" @@ -171,7 +172,6 @@ static void herculesplus_draw_char_rom(herculesplus_t *herculesplus, int x, uint unsigned val; unsigned ifg, ibg; const unsigned char *fnt; - uint32_t fg, bg; int cw = HERCULESPLUS_CW; blk = 0; @@ -248,9 +248,8 @@ static void herculesplus_draw_char_ram4(herculesplus_t *herculesplus, int x, uin int elg, blk; unsigned ull; unsigned val; - unsigned ifg, ibg, cfg, pmask, plane; + unsigned ifg, ibg, cfg; const unsigned char *fnt; - uint32_t fg; int cw = HERCULESPLUS_CW; int blink = herculesplus->ctrl & HERCULESPLUS_CTRL_BLINK; @@ -318,7 +317,6 @@ static void herculesplus_draw_char_ram4(herculesplus_t *herculesplus, int x, uin { /* Generate pixel colour */ cfg = 0; - pmask = 1; /* cfg = colour of foreground pixels */ if ((attr & 0x77) == 0) cfg = ibg; /* 'blank' attribute */ @@ -332,11 +330,10 @@ static void herculesplus_draw_char_ram48(herculesplus_t *herculesplus, int x, ui { unsigned i; int elg, blk, ul, ol, bld; - unsigned ull, oll, ulc, olc; + unsigned ull, oll, ulc = 0, olc = 0; unsigned val; - unsigned ifg, ibg, cfg, pmask, plane; + unsigned ibg, cfg; const unsigned char *fnt; - uint32_t fg; int cw = HERCULESPLUS_CW; int blink = herculesplus->ctrl & HERCULESPLUS_CTRL_BLINK; int font = (attr & 0x0F); @@ -452,8 +449,8 @@ static void herculesplus_text_line(herculesplus_t *herculesplus, uint16_t ca) for (x = 0; x < herculesplus->crtc[1]; x++) { - chr = herculesplus->vram[(herculesplus->ma << 1) & 0x3fff]; - attr = herculesplus->vram[((herculesplus->ma << 1) + 1) & 0x3fff]; + chr = herculesplus->vram[(herculesplus->ma << 1) & 0xfff]; + attr = herculesplus->vram[((herculesplus->ma << 1) + 1) & 0xfff]; drawcursor = ((herculesplus->ma == ca) && herculesplus->con && herculesplus->cursoron); @@ -488,10 +485,8 @@ static void herculesplus_text_line(herculesplus_t *herculesplus, uint16_t ca) static void herculesplus_graphics_line(herculesplus_t *herculesplus) { - uint8_t mask; uint16_t ca; - int x, c, plane, col; - uint8_t ink; + int x, c, plane = 0; uint16_t val; /* Graphics mode. */ @@ -524,7 +519,6 @@ void herculesplus_poll(void *p) if (!herculesplus->linepos) { -// pclog("InColor poll %i %i\n", herculesplus->vc, herculesplus->sc); herculesplus->vidtime += herculesplus->dispofftime; herculesplus->stat |= 1; herculesplus->linepos = 1; @@ -552,7 +546,6 @@ void herculesplus_poll(void *p) if (herculesplus->vc == herculesplus->crtc[7] && !herculesplus->sc) { herculesplus->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); } herculesplus->displine++; if (herculesplus->displine >= 500) @@ -570,7 +563,6 @@ void herculesplus_poll(void *p) if (!herculesplus->vsynctime) { herculesplus->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); } } if (herculesplus->sc == (herculesplus->crtc[11] & 31) || ((herculesplus->crtc[8] & 3) == 3 && herculesplus->sc == ((herculesplus->crtc[11] & 31) >> 1))) @@ -602,7 +594,6 @@ void herculesplus_poll(void *p) herculesplus->dispon = 0; if (oldvc == herculesplus->crtc[4]) { -// printf("Display over at %i\n",displine); herculesplus->vc = 0; herculesplus->vadj = herculesplus->crtc[5]; if (!herculesplus->vadj) herculesplus->dispon=1; @@ -614,10 +605,9 @@ void herculesplus_poll(void *p) { herculesplus->dispon = 0; herculesplus->displine = 0; - herculesplus->vsynctime = 16;//(crtcm[3]>>4)+1; + herculesplus->vsynctime = 16; if (herculesplus->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); if ((herculesplus->ctrl & HERCULESPLUS_CTRL_GRAPH) && (herculesplus->ctrl2 & HERCULESPLUS_CTRL2_GRAPH)) { x = herculesplus->crtc[1] << 4; @@ -631,7 +621,6 @@ void herculesplus_poll(void *p) { xsize = x; ysize = herculesplus->lastline - herculesplus->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; updatewindowsize(xsize, ysize); @@ -665,7 +654,6 @@ void herculesplus_poll(void *p) if ((herculesplus->sc == (herculesplus->crtc[10] & 31) || ((herculesplus->crtc[8] & 3) == 3 && herculesplus->sc == ((herculesplus->crtc[10] & 31) >> 1)))) { herculesplus->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); } } } diff --git a/src/vid_icd2061.c b/src/vid_icd2061.c index 8b57e5bb7..bc75d4999 100644 --- a/src/vid_icd2061.c +++ b/src/vid_icd2061.c @@ -10,10 +10,9 @@ void icd2061_write(icd2061_t *icd2061, int val) { - int q, p, m, i, a; + int q, p, m, a; if ((val & 1) && !(icd2061->state & 1)) { - // pclog("ICD2061 write %02X %i %08X %i\n", val, icd2061->unlock, icd2061->data, icd2061->pos); if (!icd2061->status) { if (val & 2) @@ -35,24 +34,19 @@ void icd2061_write(icd2061_t *icd2061, int val) icd2061->pos++; if (icd2061->pos == 26) { - // pclog("ICD2061 data - %08X\n", icd2061->data); a = (icd2061->data >> 21) & 0x7; if (!(a & 4)) { q = (icd2061->data & 0x7f) - 2; m = 1 << ((icd2061->data >> 7) & 0x7); p = ((icd2061->data >> 10) & 0x7f) - 3; - i = (icd2061->data >> 17) & 0xf; - // pclog("p %i q %i m %i\n", p, q, m); if (icd2061->ctrl & (1 << a)) p <<= 1; icd2061->freq[a] = ((double)p / (double)q) * 2.0 * 14318184.0 / (double)m; - // pclog("ICD2061 freq %i = %f\n", a, icd2061->freq[a]); } else if (a == 6) { icd2061->ctrl = val; - // pclog("ICD2061 ctrl = %08X\n", val); } icd2061->unlock = icd2061->data = 0; icd2061->status = 0; @@ -64,6 +58,5 @@ void icd2061_write(icd2061_t *icd2061, int val) double icd2061_getfreq(icd2061_t *icd2061, int i) { - // pclog("Return freq %f\n", icd2061->freq[i]); return icd2061->freq[i]; } diff --git a/src/vid_ics2595.c b/src/vid_ics2595.c index 024cacd93..15c397729 100644 --- a/src/vid_ics2595.c +++ b/src/vid_ics2595.c @@ -18,12 +18,10 @@ static int ics2595_div[4] = {8, 4, 2, 1}; void ics2595_write(ics2595_t *ics2595, int strobe, int dat) { -// pclog("ics2595_write : %i %i\n", strobe, dat); if (strobe) { if ((dat & 8) && !ics2595->oldfs3) /*Data clock*/ { -// pclog(" - new dat %i\n", dat & 4); switch (ics2595->state) { case ICS2595_IDLE: @@ -38,13 +36,11 @@ void ics2595_write(ics2595_t *ics2595, int strobe, int dat) if (ics2595->pos == 20) { int d, n, l; -// pclog("ICS2595_WRITE : dat %08X\n", ics2595->dat); l = (ics2595->dat >> 2) & 0xf; n = ((ics2595->dat >> 7) & 255) + 257; d = ics2595_div[(ics2595->dat >> 16) & 3]; ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d; -// pclog("ICS2595 clock set - L %i N %i D %i freq = %f\n", l, n, d, (14318181.8 * ((double)n / 46.0)) / (double)d); ics2595->state = ICS2595_IDLE; } break; diff --git a/src/vid_incolor.c b/src/vid_incolor.c index df81b1636..4185978b0 100644 --- a/src/vid_incolor.c +++ b/src/vid_incolor.c @@ -7,6 +7,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "io.h" #include "timer.h" #include "video.h" #include "vid_incolor.h" @@ -72,71 +73,71 @@ static uint32_t incolor_rgb[64]; /* Mapping of inks to RGB */ static unsigned char init_rgb[64][3] = { - // rgbRGB - { 0x00, 0x00, 0x00 }, // 000000 - { 0x00, 0x00, 0xaa }, // 000001 - { 0x00, 0xaa, 0x00 }, // 000010 - { 0x00, 0xaa, 0xaa }, // 000011 - { 0xaa, 0x00, 0x00 }, // 000100 - { 0xaa, 0x00, 0xaa }, // 000101 - { 0xaa, 0xaa, 0x00 }, // 000110 - { 0xaa, 0xaa, 0xaa }, // 000111 - { 0x00, 0x00, 0x55 }, // 001000 - { 0x00, 0x00, 0xff }, // 001001 - { 0x00, 0xaa, 0x55 }, // 001010 - { 0x00, 0xaa, 0xff }, // 001011 - { 0xaa, 0x00, 0x55 }, // 001100 - { 0xaa, 0x00, 0xff }, // 001101 - { 0xaa, 0xaa, 0x55 }, // 001110 - { 0xaa, 0xaa, 0xff }, // 001111 - { 0x00, 0x55, 0x00 }, // 010000 - { 0x00, 0x55, 0xaa }, // 010001 - { 0x00, 0xff, 0x00 }, // 010010 - { 0x00, 0xff, 0xaa }, // 010011 - { 0xaa, 0x55, 0x00 }, // 010100 - { 0xaa, 0x55, 0xaa }, // 010101 - { 0xaa, 0xff, 0x00 }, // 010110 - { 0xaa, 0xff, 0xaa }, // 010111 - { 0x00, 0x55, 0x55 }, // 011000 - { 0x00, 0x55, 0xff }, // 011001 - { 0x00, 0xff, 0x55 }, // 011010 - { 0x00, 0xff, 0xff }, // 011011 - { 0xaa, 0x55, 0x55 }, // 011100 - { 0xaa, 0x55, 0xff }, // 011101 - { 0xaa, 0xff, 0x55 }, // 011110 - { 0xaa, 0xff, 0xff }, // 011111 - { 0x55, 0x00, 0x00 }, // 100000 - { 0x55, 0x00, 0xaa }, // 100001 - { 0x55, 0xaa, 0x00 }, // 100010 - { 0x55, 0xaa, 0xaa }, // 100011 - { 0xff, 0x00, 0x00 }, // 100100 - { 0xff, 0x00, 0xaa }, // 100101 - { 0xff, 0xaa, 0x00 }, // 100110 - { 0xff, 0xaa, 0xaa }, // 100111 - { 0x55, 0x00, 0x55 }, // 101000 - { 0x55, 0x00, 0xff }, // 101001 - { 0x55, 0xaa, 0x55 }, // 101010 - { 0x55, 0xaa, 0xff }, // 101011 - { 0xff, 0x00, 0x55 }, // 101100 - { 0xff, 0x00, 0xff }, // 101101 - { 0xff, 0xaa, 0x55 }, // 101110 - { 0xff, 0xaa, 0xff }, // 101111 - { 0x55, 0x55, 0x00 }, // 110000 - { 0x55, 0x55, 0xaa }, // 110001 - { 0x55, 0xff, 0x00 }, // 110010 - { 0x55, 0xff, 0xaa }, // 110011 - { 0xff, 0x55, 0x00 }, // 110100 - { 0xff, 0x55, 0xaa }, // 110101 - { 0xff, 0xff, 0x00 }, // 110110 - { 0xff, 0xff, 0xaa }, // 110111 - { 0x55, 0x55, 0x55 }, // 111000 - { 0x55, 0x55, 0xff }, // 111001 - { 0x55, 0xff, 0x55 }, // 111010 - { 0x55, 0xff, 0xff }, // 111011 - { 0xff, 0x55, 0x55 }, // 111100 - { 0xff, 0x55, 0xff }, // 111101 - { 0xff, 0xff, 0x55 }, // 111110 - { 0xff, 0xff, 0xff }, // 111111 + /* rgbRGB */ + { 0x00, 0x00, 0x00 }, /* 000000 */ + { 0x00, 0x00, 0xaa }, /* 000001 */ + { 0x00, 0xaa, 0x00 }, /* 000010 */ + { 0x00, 0xaa, 0xaa }, /* 000011 */ + { 0xaa, 0x00, 0x00 }, /* 000100 */ + { 0xaa, 0x00, 0xaa }, /* 000101 */ + { 0xaa, 0xaa, 0x00 }, /* 000110 */ + { 0xaa, 0xaa, 0xaa }, /* 000111 */ + { 0x00, 0x00, 0x55 }, /* 001000 */ + { 0x00, 0x00, 0xff }, /* 001001 */ + { 0x00, 0xaa, 0x55 }, /* 001010 */ + { 0x00, 0xaa, 0xff }, /* 001011 */ + { 0xaa, 0x00, 0x55 }, /* 001100 */ + { 0xaa, 0x00, 0xff }, /* 001101 */ + { 0xaa, 0xaa, 0x55 }, /* 001110 */ + { 0xaa, 0xaa, 0xff }, /* 001111 */ + { 0x00, 0x55, 0x00 }, /* 010000 */ + { 0x00, 0x55, 0xaa }, /* 010001 */ + { 0x00, 0xff, 0x00 }, /* 010010 */ + { 0x00, 0xff, 0xaa }, /* 010011 */ + { 0xaa, 0x55, 0x00 }, /* 010100 */ + { 0xaa, 0x55, 0xaa }, /* 010101 */ + { 0xaa, 0xff, 0x00 }, /* 010110 */ + { 0xaa, 0xff, 0xaa }, /* 010111 */ + { 0x00, 0x55, 0x55 }, /* 011000 */ + { 0x00, 0x55, 0xff }, /* 011001 */ + { 0x00, 0xff, 0x55 }, /* 011010 */ + { 0x00, 0xff, 0xff }, /* 011011 */ + { 0xaa, 0x55, 0x55 }, /* 011100 */ + { 0xaa, 0x55, 0xff }, /* 011101 */ + { 0xaa, 0xff, 0x55 }, /* 011110 */ + { 0xaa, 0xff, 0xff }, /* 011111 */ + { 0x55, 0x00, 0x00 }, /* 100000 */ + { 0x55, 0x00, 0xaa }, /* 100001 */ + { 0x55, 0xaa, 0x00 }, /* 100010 */ + { 0x55, 0xaa, 0xaa }, /* 100011 */ + { 0xff, 0x00, 0x00 }, /* 100100 */ + { 0xff, 0x00, 0xaa }, /* 100101 */ + { 0xff, 0xaa, 0x00 }, /* 100110 */ + { 0xff, 0xaa, 0xaa }, /* 100111 */ + { 0x55, 0x00, 0x55 }, /* 101000 */ + { 0x55, 0x00, 0xff }, /* 101001 */ + { 0x55, 0xaa, 0x55 }, /* 101010 */ + { 0x55, 0xaa, 0xff }, /* 101011 */ + { 0xff, 0x00, 0x55 }, /* 101100 */ + { 0xff, 0x00, 0xff }, /* 101101 */ + { 0xff, 0xaa, 0x55 }, /* 101110 */ + { 0xff, 0xaa, 0xff }, /* 101111 */ + { 0x55, 0x55, 0x00 }, /* 110000 */ + { 0x55, 0x55, 0xaa }, /* 110001 */ + { 0x55, 0xff, 0x00 }, /* 110010 */ + { 0x55, 0xff, 0xaa }, /* 110011 */ + { 0xff, 0x55, 0x00 }, /* 110100 */ + { 0xff, 0x55, 0xaa }, /* 110101 */ + { 0xff, 0xff, 0x00 }, /* 110110 */ + { 0xff, 0xff, 0xaa }, /* 110111 */ + { 0x55, 0x55, 0x55 }, /* 111000 */ + { 0x55, 0x55, 0xff }, /* 111001 */ + { 0x55, 0xff, 0x55 }, /* 111010 */ + { 0x55, 0xff, 0xff }, /* 111011 */ + { 0xff, 0x55, 0x55 }, /* 111100 */ + { 0xff, 0x55, 0xff }, /* 111101 */ + { 0xff, 0xff, 0x55 }, /* 111110 */ + { 0xff, 0xff, 0xff }, /* 111111 */ }; @@ -240,7 +241,7 @@ void incolor_write(uint32_t addr, uint8_t val, void *p) unsigned char wmode = incolor->crtc[INCOLOR_CRTC_RWCTRL] & INCOLOR_RWCTRL_WRMODE; unsigned char fg = incolor->crtc[INCOLOR_CRTC_RWCOL] & 0x0F; unsigned char bg = (incolor->crtc[INCOLOR_CRTC_RWCOL] >> 4)&0x0F; - unsigned char w; + unsigned char w = 0; unsigned char vmask; /* Mask of bit within byte */ unsigned char pmask; /* Mask of plane within colour value */ unsigned char latch; @@ -596,9 +597,9 @@ static void incolor_draw_char_ram48(incolor_t *incolor, int x, uint8_t chr, uint { unsigned i; int elg, blk, ul, ol, bld; - unsigned ull, oll, ulc, olc; + unsigned ull, oll, ulc = 0, olc = 0; unsigned val[4]; - unsigned ifg, ibg, cfg, pmask, plane; + unsigned ifg = 0, ibg, cfg, pmask, plane; const unsigned char *fnt; uint32_t fg; int cw = INCOLOR_CW; @@ -764,8 +765,8 @@ static void incolor_text_line(incolor_t *incolor, uint16_t ca) for (x = 0; x < incolor->crtc[1]; x++) { - chr = incolor->vram[(incolor->ma << 1) & 0x3fff]; - attr = incolor->vram[((incolor->ma << 1) + 1) & 0x3fff]; + chr = incolor->vram[(incolor->ma << 1) & 0xfff]; + attr = incolor->vram[((incolor->ma << 1) + 1) & 0xfff]; drawcursor = ((incolor->ma == ca) && incolor->con && incolor->cursoron); @@ -866,7 +867,6 @@ void incolor_poll(void *p) if (!incolor->linepos) { -// pclog("InColor poll %i %i\n", incolor->vc, incolor->sc); incolor->vidtime += incolor->dispofftime; incolor->stat |= 1; incolor->linepos = 1; @@ -894,7 +894,6 @@ void incolor_poll(void *p) if (incolor->vc == incolor->crtc[7] && !incolor->sc) { incolor->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); } incolor->displine++; if (incolor->displine >= 500) @@ -912,7 +911,6 @@ void incolor_poll(void *p) if (!incolor->vsynctime) { incolor->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); } } if (incolor->sc == (incolor->crtc[11] & 31) || ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[11] & 31) >> 1))) @@ -944,7 +942,6 @@ void incolor_poll(void *p) incolor->dispon = 0; if (oldvc == incolor->crtc[4]) { -// printf("Display over at %i\n",displine); incolor->vc = 0; incolor->vadj = incolor->crtc[5]; if (!incolor->vadj) incolor->dispon=1; @@ -956,10 +953,9 @@ void incolor_poll(void *p) { incolor->dispon = 0; incolor->displine = 0; - incolor->vsynctime = 16;//(crtcm[3]>>4)+1; + incolor->vsynctime = 16; if (incolor->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); if ((incolor->ctrl & INCOLOR_CTRL_GRAPH) && (incolor->ctrl2 & INCOLOR_CTRL2_GRAPH)) { x = incolor->crtc[1] << 4; @@ -973,7 +969,6 @@ void incolor_poll(void *p) { xsize = x; ysize = incolor->lastline - incolor->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; updatewindowsize(xsize, ysize); @@ -1007,7 +1002,6 @@ void incolor_poll(void *p) if ((incolor->sc == (incolor->crtc[10] & 31) || ((incolor->crtc[8] & 3) == 3 && incolor->sc == ((incolor->crtc[10] & 31) >> 1)))) { incolor->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); } } } diff --git a/src/vid_mda.c b/src/vid_mda.c index bf3b9e459..4b45debc3 100644 --- a/src/vid_mda.c +++ b/src/vid_mda.c @@ -117,7 +117,6 @@ void mda_poll(void *p) int x, c; int oldvc; uint8_t chr, attr; - int cols[4]; int oldsc; int blink; if (!mda->linepos) @@ -135,12 +134,10 @@ void mda_poll(void *p) mda->firstline = mda->displine; } mda->lastline = mda->displine; - cols[0] = 0; - cols[1] = 7; for (x = 0; x < mda->crtc[1]; x++) { - chr = mda->vram[(mda->ma << 1) & 0x3fff]; - attr = mda->vram[((mda->ma << 1) + 1) & 0x3fff]; + chr = mda->vram[(mda->ma << 1) & 0xfff]; + attr = mda->vram[((mda->ma << 1) + 1) & 0xfff]; drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron); blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor); if (mda->sc == 12 && ((attr & 7) == 1)) @@ -167,7 +164,6 @@ void mda_poll(void *p) if (mda->vc == mda->crtc[7] && !mda->sc) { mda->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); } mda->displine++; if (mda->displine >= 500) @@ -184,7 +180,6 @@ void mda_poll(void *p) if (!mda->vsynctime) { mda->stat&=~8; -// printf("VSYNC off %i %i\n",vc,sc); } } if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) @@ -216,7 +211,6 @@ void mda_poll(void *p) mda->dispon=0; if (oldvc == mda->crtc[4]) { -// printf("Display over at %i\n",displine); mda->vc = 0; mda->vadj = mda->crtc[5]; if (!mda->vadj) mda->dispon = 1; @@ -231,14 +225,12 @@ void mda_poll(void *p) mda->vsynctime = 16; if (mda->crtc[7]) { -// printf("Lastline %i Firstline %i %i\n",lastline,firstline,lastline-firstline); x = mda->crtc[1] * 9; mda->lastline++; if (x != xsize || (mda->lastline - mda->firstline) != ysize) { xsize = x; ysize = mda->lastline - mda->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtcm[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; updatewindowsize(xsize, ysize); @@ -263,7 +255,6 @@ void mda_poll(void *p) if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) { mda->con = 1; -// printf("Cursor on - %02X %02X %02X\n",crtcm[8],crtcm[10],crtcm[11]); } } } @@ -332,35 +323,27 @@ void mda_speed_changed(void *p) static device_config_t mda_config[] = { { - .name = "rgb_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = + "rgb_type", "Display type", CONFIG_SELECTION, "", 0, { { - .description = "Default", - .value = 0 + "Default", 0 }, { - .description = "Green", - .value = 1 + "Green", 1 }, { - .description = "Amber", - .value = 2 + "Amber", 2 }, { - .description = "Gray", - .value = 3 + "Gray", 3 }, { - .description = "" + "" } - }, - .default_int = 0 + } }, { - .type = -1 + "", "", -1 } }; #endif diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 152b2f963..de8c93fcc 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -8,6 +8,7 @@ #include "io.h" #include "mem.h" #include "pci.h" +#include "pic.h" #include "rom.h" #include "thread.h" #include "timer.h" @@ -1794,7 +1795,7 @@ static void riva128_pusher_run(int chanid, void *p) { uint32_t dmaget = riva128->pfifo.channels[chanid].dmaget; uint32_t cmd = ((uint32_t*)svga->vram)[dmaget >> 2]; - uint32_t* params = ((uint32_t*)svga->vram)[(dmaget + 4) >> 2]; + uint32_t* params = (uint32_t *)(((uint32_t*)svga->vram)[(dmaget + 4) >> 2]); if(((cmd & 0xe0000003) == 0x20000000) && (riva128->card_id >= 0x04)) { //old nv4 jump command diff --git a/src/vid_olivetti_m24.c b/src/vid_olivetti_m24.c index c60061e62..8b6e62983 100644 --- a/src/vid_olivetti_m24.c +++ b/src/vid_olivetti_m24.c @@ -55,7 +55,6 @@ void m24_out(uint16_t addr, uint8_t val, void *p) { m24_t *m24 = (m24_t *)p; uint8_t old; -// pclog("m24_out %04X %02X\n", addr, val); switch (addr) { case 0x3d4: @@ -129,10 +128,8 @@ void m24_recalctimings(m24_t *m24) _dispontime = m24->crtc[1] << 1; } _dispofftime = disptime - _dispontime; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); _dispontime *= CGACONST / 2; _dispofftime *= CGACONST / 2; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); m24->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } @@ -151,7 +148,6 @@ void m24_poll(void *p) int oldsc; if (!m24->linepos) { -// pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine); m24->vidtime += m24->dispofftime; m24->stat |= 1; m24->linepos = 1; @@ -160,11 +156,9 @@ void m24_poll(void *p) m24->sc = (m24->sc << 1) & 7; if (m24->dispon) { - // pclog("dispon %i\n", m24->linepos); if (m24->displine < m24->firstline) { m24->firstline = m24->displine; -// printf("Firstline %i\n",firstline); } m24->lastline = m24->displine; for (c = 0; c < 8; c++) @@ -325,7 +319,6 @@ void m24_poll(void *p) } else { -// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj); m24->vidtime += m24->dispontime; if (m24->dispon) m24->stat &= ~1; m24->linepos = 0; @@ -453,7 +446,6 @@ void m24_poll(void *p) void *m24_init() { - int c; m24_t *m24 = malloc(sizeof(m24_t)); memset(m24, 0, sizeof(m24_t)); diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 202da0466..c1f0f0b0c 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -35,8 +35,6 @@ void oti067_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = &oti067->svga; uint8_t old; -// pclog("oti067_out : %04X %02X %02X %i\n", addr, val, ram[0x489], ins); - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -95,8 +93,6 @@ uint8_t oti067_in(uint16_t addr, void *p) svga_t *svga = &oti067->svga; uint8_t temp; -// if (addr != 0x3da && addr != 0x3ba) pclog("oti067_in : %04X ", addr); - if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -110,7 +106,6 @@ uint8_t oti067_in(uint16_t addr, void *p) case 0x3DE: temp = oti067->index | (oti067->chip_id << 5); - // temp = oti067->index | (2 << 5); break; case 0x3DF: if (oti067->index==0x10) temp = 0x18; @@ -121,7 +116,6 @@ uint8_t oti067_in(uint16_t addr, void *p) temp = svga_in(addr, svga); break; } -// if (addr != 0x3da && addr != 0x3ba) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } @@ -153,7 +147,6 @@ void oti067_recalctimings(svga_t *svga) if (oti067->regs[0x14] & 0x08) svga->ma_latch |= 0x10000; if (oti067->regs[0x0d] & 0x0c) svga->rowoffset <<= 1; - // svga->interlace = oti067->regs[0x14] & 0x80; if (oti067->regs[0x14] & 0x80) { svga->vtotal *= 2; @@ -265,73 +258,48 @@ void oti067_add_status_info(char *s, int max_len, void *p) static device_config_t oti067_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 512, { { - .description = "256 kB", - .value = 256 + "256 kB", 256 }, { - .description = "512 kB", - .value = 512 + "512 kB", 512 }, { - .description = "" + "" } - }, - .default_int = 512 + } }, { - .type = -1 + "", "", -1 } }; static device_config_t oti077_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 1024, { { - .description = "256 kB", - .value = 256 + "256 kB", 256 }, { - .description = "512 kB", - .value = 512 + "512 kB", 512 }, { - .description = "1 MB", - .value = 1024 + "1 MB", 1024 }, { - .description = "" + "" } - }, - .default_int = 1024 + } }, { - .type = -1 + "", "", -1 } }; -/* device_t oti037_device = -{ - "Oak OTI-037", - 0, - oti037_init, - oti067_close, - oti037_available, - oti067_speed_changed, - oti067_force_redraw, - oti067_add_status_info, - oti067_config -}; */ device_t oti067_device = { "Oak OTI-067", diff --git a/src/vid_paradise.c b/src/vid_paradise.c index e6ce2ee06..859695459 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -9,6 +9,7 @@ #include #include "ibm.h" #include "device.h" +#include "io.h" #include "mem.h" #include "rom.h" #include "video.h" @@ -45,8 +46,6 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// output = 3; -// pclog("Paradise out %04X %02X %04X:%04X\n", addr, val, CS, pc); switch (addr) { case 0x3c5: @@ -71,7 +70,6 @@ void paradise_out(uint16_t addr, uint8_t val, void *p) { if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { -// pclog("Write mapping %02X\n", val); switch (val&0xC) { case 0x0: /*128k at A0000*/ @@ -151,7 +149,6 @@ uint8_t paradise_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// if (addr != 0x3da) pclog("Paradise in %04X\n", addr); switch (addr) { case 0x3c2: @@ -197,7 +194,6 @@ void paradise_remap(paradise_t *paradise) if (svga->seqregs[0x11] & 0x80) { -// pclog("Remap 1\n"); paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; @@ -207,7 +203,6 @@ void paradise_remap(paradise_t *paradise) { if (svga->gdcreg[0x6] & 0xc) { -// pclog("Remap 2\n"); paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0xa] & 0x7f) << 12; paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); @@ -215,7 +210,6 @@ void paradise_remap(paradise_t *paradise) } else { -// pclog("Remap 3\n"); paradise->read_bank[0] = paradise->write_bank[0] = (svga->gdcreg[0xa] & 0x7f) << 12; paradise->read_bank[1] = paradise->write_bank[1] = ((svga->gdcreg[0xa] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); paradise->read_bank[2] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; @@ -224,13 +218,11 @@ void paradise_remap(paradise_t *paradise) } else { - // pclog("Remap 4\n"); paradise->read_bank[0] = paradise->read_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; paradise->read_bank[1] = paradise->read_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); paradise->write_bank[0] = paradise->write_bank[2] = (svga->gdcreg[0x9] & 0x7f) << 12; paradise->write_bank[1] = paradise->write_bank[3] = ((svga->gdcreg[0x9] & 0x7f) << 12) + ((svga->gdcreg[6] & 0x08) ? 0 : 0x8000); } -// pclog("Remap - %04X %04X\n", paradise->read_bank[0], paradise->write_bank[0]); } void paradise_recalctimings(svga_t *svga) @@ -243,9 +235,8 @@ void paradise_recalctimings(svga_t *svga) void paradise_write(uint32_t addr, uint8_t val, void *p) { paradise_t *paradise = (paradise_t *)p; -// pclog("paradise_write : %05X %02X ", addr, val); addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3]; -// pclog("%08X\n", addr); + /* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */ if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) return; if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) return; @@ -255,9 +246,7 @@ void paradise_write(uint32_t addr, uint8_t val, void *p) uint8_t paradise_read(uint32_t addr, void *p) { paradise_t *paradise = (paradise_t *)p; -// pclog("paradise_read : %05X ", addr); addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3]; -// pclog("%08X\n", addr); return svga_read_linear(addr, ¶dise->svga); } diff --git a/src/vid_paradise.h b/src/vid_paradise.h index e28bb4fae..83dd1042b 100644 --- a/src/vid_paradise.h +++ b/src/vid_paradise.h @@ -5,4 +5,3 @@ extern device_t paradise_pvga1a_pc2086_device; extern device_t paradise_pvga1a_pc3086_device; extern device_t paradise_wd90c11_megapc_device; extern device_t paradise_wd90c11_device; -// extern device_t cpqvga_device; diff --git a/src/vid_pc1512.c b/src/vid_pc1512.c index 5f75ed157..466db6f8f 100644 --- a/src/vid_pc1512.c +++ b/src/vid_pc1512.c @@ -57,7 +57,6 @@ static void pc1512_out(uint16_t addr, uint8_t val, void *p) { pc1512_t *pc1512 = (pc1512_t *)p; uint8_t old; -// pclog("PC1512 out %04X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr) { case 0x3d4: @@ -101,7 +100,6 @@ static void pc1512_out(uint16_t addr, uint8_t val, void *p) static uint8_t pc1512_in(uint16_t addr, void *p) { pc1512_t *pc1512 = (pc1512_t *)p; -// pclog("PC1512 in %04X %02X %04X:%04X\n",addr,CS,pc); switch (addr) { case 0x3d4: @@ -153,10 +151,8 @@ static void pc1512_recalctimings(pc1512_t *pc1512) disptime = 128; /*Fixed on PC1512*/ _dispontime = 80; _dispofftime = disptime - _dispontime; -// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]); _dispontime *= CGACONST; _dispofftime *= CGACONST; -// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92); pc1512->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT)); pc1512->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } @@ -167,7 +163,6 @@ static void pc1512_poll(void *p) uint16_t ca = (pc1512->crtc[15] | (pc1512->crtc[14] << 8)) & 0x3fff; int drawcursor; int x, c; - int oldvc; uint8_t chr, attr; uint16_t dat, dat2, dat3, dat4; int cols[4]; @@ -338,7 +333,6 @@ static void pc1512_poll(void *p) pc1512->displine++; if (pc1512->displine >= 360) pc1512->displine = 0; -// pclog("Line %i %i %i %i %i %i\n",displine,cgadispon,firstline,lastline,vc,sc); } else { @@ -376,11 +370,10 @@ static void pc1512_poll(void *p) { pc1512->maback = pc1512->ma; pc1512->sc = 0; - oldvc = pc1512->vc; pc1512->vc++; pc1512->vc &= 127; - if (pc1512->displine == 32)//oldvc == (cgamode & 2) ? 127 : 31) + if (pc1512->displine == 32) { pc1512->vc = 0; pc1512->vadj = 6; @@ -388,7 +381,7 @@ static void pc1512_poll(void *p) else pc1512->cursoron = pc1512->blink & 16; } - if (pc1512->displine >= 262)//vc == (cgamode & 2) ? 111 : 27) + if (pc1512->displine >= 262) { pc1512->dispon = 0; pc1512->displine = 0; @@ -409,11 +402,6 @@ static void pc1512_poll(void *p) } video_blit_memtoscreen_8(0, pc1512->firstline - 4, xsize, (pc1512->lastline - pc1512->firstline) + 8); -// blit(buffer,vbuf,0,firstline-4,0,0,xsize,(lastline-firstline)+8+1); -// if (vid_resize) stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,winsizex,winsizey); -// else stretch_blit(vbuf,screen,0,0,xsize,(lastline-firstline)+8+1,0,0,xsize,((lastline-firstline)<<1)+16+2); -// if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF); -// readflash=0; video_res_x = xsize - 16; video_res_y = ysize; @@ -457,7 +445,6 @@ static void pc1512_poll(void *p) static void *pc1512_init() { - int c; pc1512_t *pc1512 = malloc(sizeof(pc1512_t)); memset(pc1512, 0, sizeof(pc1512_t)); diff --git a/src/vid_pcjr.c b/src/vid_pcjr.c index de5c1bc94..b10cb475c 100644 --- a/src/vid_pcjr.c +++ b/src/vid_pcjr.c @@ -4,8 +4,10 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "pic.h" #include "timer.h" #include "video.h" +#include "dosbox/vid_cga_comp.h" #include "vid_pcjr.h" #define PCJR_RGB 0 @@ -21,7 +23,7 @@ typedef struct pcjr_t int array_index; uint8_t array[32]; int array_ff; - int memctrl;//=-1; + int memctrl; uint8_t stat; int addr_mode; @@ -53,14 +55,12 @@ void pcjr_out(uint16_t addr, uint8_t val, void *p) { pcjr_t *pcjr = (pcjr_t *)p; uint8_t old; -// pclog("pcjr OUT %04X %02X\n",addr,val); switch (addr) { case 0x3d4: pcjr->crtcreg = val & 0x1f; return; case 0x3d5: -// pclog("CRTC write %02X %02x\n", pcjr->crtcreg, val); old = pcjr->crtc[pcjr->crtcreg]; pcjr->crtc[pcjr->crtcreg] = val & crtcmask[pcjr->crtcreg]; if (old != val) @@ -73,7 +73,6 @@ void pcjr_out(uint16_t addr, uint8_t val, void *p) } return; case 0x3da: -// pclog("Array write %02X %02X\n", pcjr->array_index, val); if (!pcjr->array_ff) pcjr->array_index = val & 0x1f; else @@ -97,7 +96,6 @@ void pcjr_out(uint16_t addr, uint8_t val, void *p) uint8_t pcjr_in(uint16_t addr, void *p) { pcjr_t *pcjr = (pcjr_t *)p; -// if (addr!=0x3DA) pclog("pcjr IN %04X\n",addr); switch (addr) { case 0x3d4: @@ -118,13 +116,11 @@ void pcjr_recalcaddress(pcjr_t *pcjr) { pcjr->vram = &ram[(pcjr->memctrl & 0x06) << 14]; pcjr->b8000 = &ram[(pcjr->memctrl & 0x30) << 11]; -// printf("VRAM at %05X B8000 at %05X\n",((pcjr->memctrl&0x6)<<14)+pcjr->base,((pcjr->memctrl&0x30)<<11)+pcjr->base); } else { pcjr->vram = &ram[(pcjr->memctrl & 0x07) << 14]; pcjr->b8000 = &ram[(pcjr->memctrl & 0x38) << 11]; -// printf("VRAM at %05X B8000 at %05X\n",((pcjr->memctrl&0x7)<<14)+pcjr->base,((pcjr->memctrl&0x38)<<11)+pcjr->base); } } @@ -135,7 +131,6 @@ void pcjr_write(uint32_t addr, uint8_t val, void *p) return; egawrites++; -// pclog("pcjr VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); pcjr->b8000[addr & 0x3fff] = val; } @@ -146,7 +141,6 @@ uint8_t pcjr_read(uint32_t addr, void *p) return 0xff; egareads++; -// pclog("pcjr VRAM read %05X %02X %04X:%04X\n",addr,pcjr->b8000[addr&0x7FFF],CS,pc); return pcjr->b8000[addr & 0x3fff]; } @@ -171,27 +165,8 @@ void pcjr_recalctimings(pcjr_t *pcjr) } -static int ntsc_col[8][8]= -{ - {0,0,0,0,0,0,0,0}, /*Black*/ - {0,0,1,1,1,1,0,0}, /*Blue*/ - {1,0,0,0,0,1,1,1}, /*Green*/ - {0,0,0,0,1,1,1,1}, /*Cyan*/ - {1,1,1,1,0,0,0,0}, /*Red*/ - {0,1,1,1,1,0,0,0}, /*Magenta*/ - {1,1,0,0,0,0,1,1}, /*Yellow*/ - {1,1,1,1,1,1,1,1} /*White*/ -}; - -/*static int cga4pal[8][4]= -{ - {0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7}, - {0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15} -};*/ - void pcjr_poll(void *p) { -// int *cgapal=cga4pal[((pcjr->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; pcjr_t *pcjr = (pcjr_t *)p; uint16_t ca = (pcjr->crtc[15] | (pcjr->crtc[14] << 8)) & 0x3fff; int drawcursor; @@ -200,16 +175,9 @@ void pcjr_poll(void *p) uint8_t chr, attr; uint16_t dat; int cols[4]; - int col; int oldsc; - int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot; - int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot; - int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot; - int r, g, b; if (!pcjr->linepos) { -// cgapal[0]=pcjr->col&15; -// printf("Firstline %i Lastline %i pcjr->displine %i\n",firstline,lastline,pcjr->displine); pcjr->vidtime += pcjr->dispofftime; pcjr->stat &= ~1; pcjr->linepos = 1; @@ -333,7 +301,6 @@ void pcjr_poll(void *p) for (c = 0; c < 8; c++) buffer->line[pcjr->displine][(x << 3) + c + 8] = cols[(fontdat[chr][pcjr->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } -// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma); if (drawcursor) { for (c = 0; c < 8; c++) @@ -424,7 +391,6 @@ void pcjr_poll(void *p) } else { -// cols[0] = ((pcjr->mode & 0x12) == 0x12) ? 0 : (pcjr->col & 0xf) + 16; cols[0] = pcjr->array[0 + 16] + 16; if (pcjr->array[0] & 1) hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 3) + 16, cols[0]); else hline(buffer, 0, pcjr->displine, (pcjr->crtc[1] << 4) + 16, cols[0]); @@ -443,7 +409,6 @@ void pcjr_poll(void *p) if (pcjr->vc == pcjr->crtc[7] && !pcjr->sc) { pcjr->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); } pcjr->displine++; if (pcjr->displine >= 360) @@ -461,7 +426,6 @@ void pcjr_poll(void *p) if (!pcjr->vsynctime) { pcjr->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); } } if (pcjr->sc == (pcjr->crtc[11] & 31) || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == ((pcjr->crtc[11] & 31) >> 1))) @@ -480,25 +444,19 @@ void pcjr_poll(void *p) pcjr->dispon = 1; pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; pcjr->sc = 0; -// printf("Display on!\n"); } } else if (pcjr->sc == pcjr->crtc[9] || ((pcjr->crtc[8] & 3) == 3 && pcjr->sc == (pcjr->crtc[9] >> 1))) { pcjr->maback = pcjr->ma; -// con=0; -// coff=0; pcjr->sc = 0; oldvc = pcjr->vc; pcjr->vc++; pcjr->vc &= 127; -// pclog("VC %i %i\n", pcjr->vc, pcjr->crtc[7]); -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],pcjr->dispon); if (pcjr->vc == pcjr->crtc[6]) pcjr->dispon = 0; if (oldvc == pcjr->crtc[4]) { -// printf("Display over at %i\n",pcjr->displine); pcjr->vc = 0; pcjr->vadj = pcjr->crtc[5]; if (!pcjr->vadj) @@ -507,19 +465,15 @@ void pcjr_poll(void *p) pcjr->ma = pcjr->maback = (pcjr->crtc[13] | (pcjr->crtc[12] << 8)) & 0x3fff; if ((pcjr->crtc[10] & 0x60) == 0x20) pcjr->cursoron = 0; else pcjr->cursoron = pcjr->blink & 16; -// printf("CRTC10 %02X %i\n",crtc[10],cursoron); } if (pcjr->vc == pcjr->crtc[7]) { pcjr->dispon = 0; pcjr->displine = 0; - pcjr->vsynctime = 16;//(crtc[3]>>4)+1; + pcjr->vsynctime = 16; picint(1 << 5); -// printf("pcjr->vsynctime %i %02X\n",pcjr->vsynctime,crtc[3]); -// pcjr->stat|=8; if (pcjr->crtc[7]) { -// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); if (pcjr->array[0] & 1) x = (pcjr->crtc[1] << 3) + 16; else x = (pcjr->crtc[1] << 4) + 16; pcjr->lastline++; @@ -527,13 +481,10 @@ void pcjr_poll(void *p) { xsize = x; ysize = pcjr->lastline - pcjr->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; updatewindowsize(xsize, (ysize << 1) + 16); } -// printf("Blit %i %i\n",firstline,lastline); -//printf("Xsize is %i\n",xsize); if (pcjr->composite) video_blit_memtoscreen(0, pcjr->firstline-4, 0, (pcjr->lastline - pcjr->firstline) + 8, xsize, (pcjr->lastline - pcjr->firstline) + 8); @@ -606,27 +557,21 @@ device_t pcjr_video_device = static device_config_t pcjr_config[] = { { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = + "display_type", "Display type", CONFIG_SELECTION, "", PCJR_RGB, { { - .description = "RGB", - .value = PCJR_RGB + "RGB", PCJR_RGB }, { - .description = "Composite", - .value = PCJR_COMPOSITE + "Composite", PCJR_COMPOSITE }, { - .description = "" + "" } - }, - .default_int = PCJR_RGB + } }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_ps1_svga.c b/src/vid_ps1_svga.c index 4c0ce9963..86b10c8ec 100644 --- a/src/vid_ps1_svga.c +++ b/src/vid_ps1_svga.c @@ -34,8 +34,6 @@ void ps1_m2121_svga_out(uint16_t addr, uint8_t val, void *p) svga_t *svga = &ps1->svga; uint8_t old; -// pclog("svga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,cpu_state.pc, ram[0x489], ins); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -86,8 +84,6 @@ uint8_t ps1_m2121_svga_in(uint16_t addr, void *p) svga_t *svga = &ps1->svga; uint8_t temp; -// if (addr != 0x3da) pclog("svga_in : %04X ", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -118,7 +114,6 @@ uint8_t ps1_m2121_svga_in(uint16_t addr, void *p) temp = svga_in(addr, svga); break; } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } @@ -136,7 +131,6 @@ void *ps1_m2121_svga_init() io_sethandler(0x0100, 0x0002, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); io_sethandler(0x03c0, 0x0020, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); io_sethandler(0x2100, 0x0010, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); -// io_sethandler(0x210a, 0x0001, ps1_m2121_svga_in, NULL, NULL, ps1_m2121_svga_out, NULL, NULL, ps1); ps1->svga.bpp = 8; ps1->svga.miscout = 1; diff --git a/src/vid_s3.c b/src/vid_s3.c index 18e9a7607..3c0a3371b 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -1,6 +1,3 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ /*S3 emulation*/ #include #include "ibm.h" @@ -14,13 +11,11 @@ #include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "vid_bt485_ramdac.h" #include "vid_sdac_ramdac.h" enum { S3_VISION864, - /* S3_VISION964, */ S3_TRIO32, S3_TRIO64 }; @@ -71,7 +66,6 @@ typedef struct s3_t svga_t svga; sdac_ramdac_t ramdac; - // bt485_ramdac_t bt485_ramdac; uint8_t bank; uint8_t ma_ext; @@ -146,7 +140,7 @@ void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); uint8_t s3_accel_read(uint32_t addr, void *p); -static inline void wake_fifo_thread(s3_t *s3) +static __inline void wake_fifo_thread(s3_t *s3) { thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -407,7 +401,6 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { -// pclog("Accel out w %04X %04X\n", port, val); if (s3->accel.cmd & 0x100) { if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) @@ -423,7 +416,6 @@ static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { -// pclog("Accel out l %04X %08X\n", port, val); if (s3->accel.cmd & 0x100) { if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) @@ -467,7 +459,6 @@ static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) { -// pclog("Write S3 accel %08X %02X\n", addr, val); if (s3->packed_mmio) { int addr_lo = addr & 1; @@ -573,7 +564,6 @@ static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { -// pclog("Write S3 accel w %08X %04X\n", addr, val); if (addr & 0x8000) { s3_accel_write_fifo(s3, addr, val); @@ -597,7 +587,6 @@ static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { -// pclog("Write S3 accel l %08X %08X\n", addr, val); if (addr & 0x8000) { s3_accel_write_fifo(s3, addr, val); @@ -664,7 +653,6 @@ static void fifo_thread(void *param) uint64_t start_time = timer_read(); uint64_t end_time; fifo_entry_t *fifo = &s3->fifo[s3->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; switch (fifo->addr_type & FIFO_TYPE) { @@ -723,39 +711,6 @@ static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) wake_fifo_thread(s3); } -void s3_update_linear_size(s3_t *s3) -{ - svga_t *svga = &s3->svga; - - switch (svga->crtc[0x58] & 3) - { - case 0: /*64k*/ - s3->linear_size = 0x10000; - break; - case 1: /*1mb*/ - s3->linear_size = 0x100000; - break; - case 2: /*2mb*/ - s3->linear_size = 0x200000; - break; - case 3: /*8mb*/ - switch(s3->chip) - { - case S3_TRIO32: - s3->linear_size = 0x200000; - svga->crtc[0x58] &= 0xfe; - break; - case S3_TRIO64: - s3->linear_size = 0x400000; - break; - default: - s3->linear_size = 0x800000; - break; - } - break; - } -} - void s3_out(uint16_t addr, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; @@ -764,8 +719,6 @@ void s3_out(uint16_t addr, uint8_t val, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; - -// pclog("S3 out %04X %02X %04x:%08x\n", addr, val, CS, pc); switch (addr) { @@ -788,19 +741,20 @@ void s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: -// pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - /* if (s3->chip != S3_VISION964) */ + if (s3->chip < S3_TRIO32) + { sdac_ramdac_out(addr, val, &s3->ramdac, svga); - /* else - bt485_ramdac_out(addr, val, &s3->bt485_ramdac, svga); - return; */ + } + else + { + svga_out(addr, val, svga); + } + return; case 0x3D4: svga->crtcreg = val & 0x7f; return; case 0x3D5: - if (svga->crtcreg <= 0x18) - val &= mask_crtc[svga->crtcreg]; if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -835,20 +789,17 @@ void s3_out(uint16_t addr, uint8_t val, void *p) case 0x35: s3->bank = (s3->bank & 0x70) | (val & 0xf); -// pclog("CRTC write R35 %02X\n", val); if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x51: s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); -// pclog("CRTC write R51 %02X\n", val); if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: s3->bank = val; -// pclog("CRTC write R6a %02X\n", val); if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; else svga->write_bank = svga->read_bank = s3->bank << 14; break; @@ -868,28 +819,12 @@ void s3_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.xoff = svga->crtc[0x4e] & 63; svga->hwcursor.yoff = svga->crtc[0x4f] & 63; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) + if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && (svga->bpp == 32) && (s3->id == 0xe1)) svga->hwcursor.x <<= 1; break; case 0x53: - s3_updatemapping(s3); - break; - case 0x58: - s3_update_linear_size(s3); - // s3->linear_base &= ((s3->linear_size - 1) ^ 0xffffffff); - s3_updatemapping(s3); - break; - case 0x59: - s3->linear_base &= 0x00ffffff; - s3->linear_base |= (((uint32_t) val) << 24); - // s3->linear_base &= ((s3->linear_size - 1) ^ 0xffffffff); - s3_updatemapping(s3); - break; - case 0x5a: - s3->linear_base &= 0xff00ffff; - s3->linear_base |= (((uint32_t) val) << 16); - // s3->linear_base &= ((s3->linear_size - 1) ^ 0xffffffff); + case 0x58: case 0x59: case 0x5a: s3_updatemapping(s3); break; @@ -906,25 +841,6 @@ void s3_out(uint16_t addr, uint8_t val, void *p) } } break; -#if 0 - case 0x55: case 0x43: - if (s3->chip == S3_VISION964) - { - if (svga->crtc[0x55] & 3) - { - bt485_set_rs2(svga->crtc[0x55] & 1, &s3->bt485_ramdac); - bt485_set_rs3(svga->crtc[0x55] & 2, &s3->bt485_ramdac); - } - else - { - bt485_set_rs2(svga->crtc[0x43] & 2, &s3->bt485_ramdac); - bt485_set_rs3(0, &s3->bt485_ramdac); - } - pclog("RS2 is now %i, RS3 is now %i\n", s3->bt485_ramdac.rs2, s3->bt485_ramdac.rs3); - } - break; -#endif -// pclog("Write CRTC R%02X %02X\n", crtcreg, val); } if (old != val) { @@ -947,7 +863,6 @@ uint8_t s3_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// if (addr != 0x3da) pclog("S3 in %04X %08x:%02x\n", addr, CS, pc); switch (addr) { case 0x3c1: @@ -961,31 +876,33 @@ uint8_t s3_in(uint16_t addr, void *p) break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: -// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - // if (s3->chip != S3_VISION964) - return sdac_ramdac_in(addr, &s3->ramdac, svga); - /* else - return bt485_ramdac_in(addr, &s3->bt485_ramdac, svga); */ + if (s3->chip < S3_TRIO32) + { + return sdac_ramdac_in(addr, &s3->ramdac, svga); + } + else + { + return svga_in(addr, svga); + } case 0x3d4: return svga->crtcreg; case 0x3d5: -// pclog("Read CRTC R%02X %02x %04X:%04X\n", svga->crtcreg, svga->crtc[svga->crtcreg], CS, pc); switch (svga->crtcreg) { case 0x2d: return 0x88; /*Extended chip ID*/ - case 0x2e: - // if ((s3->chip != S3_TRIO32) && (s3->chip != S3_TRIO64)) return 0xFF; - return s3->id_ext; /*New chip ID*/ + case 0x2e: return s3->id_ext; /*New chip ID*/ case 0x2f: return 0; /*Revision level*/ case 0x30: return s3->id; /*Chip ID*/ case 0x31: return (svga->crtc[0x31] & 0xcf) | ((s3->ma_ext & 3) << 4); case 0x35: return (svga->crtc[0x35] & 0xf0) | (s3->bank & 0xf); case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); - case 0x59: return ((s3->linear_base >> 24) & 0xff); - case 0x5a: return ((s3->linear_base >> 16) & 0xff); case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; + case 0x6b: + pclog("Returning value: %02X\n", svga->crtc[0x6b]); + return 0xff; + break; } return svga->crtc[svga->crtcreg]; } @@ -997,10 +914,7 @@ void s3_recalctimings(svga_t *svga) s3_t *s3 = (s3_t *)svga->p; svga->hdisp = svga->hdisp_old; -// pclog("%i %i\n", svga->hdisp, svga->hdisp_time); -// pclog("recalctimings\n"); svga->ma_latch |= (s3->ma_ext << 16); -// pclog("SVGA_MA %08X\n", svga_ma); if (svga->crtc[0x5d] & 0x01) svga->htotal += 0x100; if (svga->crtc[0x5d] & 0x02) { @@ -1057,20 +971,15 @@ void s3_recalctimings(svga_t *svga) void s3_updatemapping(s3_t *s3) { svga_t *svga = &s3->svga; - uint32_t lbase; - -// video_write_a000_w = video_write_a000_l = NULL; if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { -// pclog("Update mapping - PCI disabled\n"); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&s3->linear_mapping); mem_mapping_disable(&s3->mmio_mapping); return; } -// pclog("Update mapping - bank %02X ", svga->gdcreg[6] & 0xc); switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ @@ -1091,12 +1000,10 @@ void s3_updatemapping(s3_t *s3) break; } -// pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ { mem_mapping_disable(&svga->mapping); -#if 0 s3->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); switch (svga->crtc[0x58] & 3) { @@ -1110,47 +1017,12 @@ void s3_updatemapping(s3_t *s3) s3->linear_size = 0x200000; break; case 3: /*8mb*/ - switch(s3->chip) - { - case S3_TRIO32: - s3->linear_size = 0x200000; - svga->crtc[0x58] &= 0xfe; - break; - case S3_TRIO64: - s3->linear_size = 0x400000; - break; - default: - s3->linear_size = 0x800000; - break; - } + s3->linear_size = 0x800000; break; } s3->linear_base &= ~(s3->linear_size - 1); -#endif -// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); -// pclog("Linear framebuffer at %08X size %08X\n", s3->linear_base, s3->linear_size); - - if ((svga->crtc[0x68] & 0x80) && (s3->chip != S3_TRIO32)) - { - if (s3->linear_base & 0xe0000000) - { - /* If bits 31-29 are not all clear, disable linear base. */ - mem_mapping_disable(&s3->linear_mapping); - return; - } - else - { - lbase = s3->linear_base & 0x1fffffff; - } - } - else - { - lbase = s3->linear_base; - } - - svga->linear_base = lbase & ((s3->linear_size - 1) ^ 0xffffffff); - - if (lbase == 0xa0000) + svga->linear_base = s3->linear_base; + if (s3->linear_base == 0xa0000) { mem_mapping_disable(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) @@ -1158,15 +1030,13 @@ void s3_updatemapping(s3_t *s3) mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } -// mem_mapping_set_addr(&s3->linear_mapping, 0xa0000, 0x10000); } else - mem_mapping_set_addr(&s3->linear_mapping, lbase, s3->linear_size); + mem_mapping_set_addr(&s3->linear_mapping, s3->linear_base, s3->linear_size); } else mem_mapping_disable(&s3->linear_mapping); -// pclog("Memory mapped IO %02X\n", svga->crtc[0x53] & 0x10); if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ { mem_mapping_disable(&svga->mapping); @@ -1182,14 +1052,12 @@ static float s3_trio64_getclock(int clock, void *p) svga_t *svga = &s3->svga; float t; int m, n1, n2; -// pclog("Trio64_getclock %i %02X %02X\n", clock, svga->seqregs[0x13], svga->seqregs[0x12]); if (clock == 0) return 25175000.0; if (clock == 1) return 28322000.0; m = svga->seqregs[0x13] + 2; n1 = (svga->seqregs[0x12] & 0x1f) + 2; n2 = ((svga->seqregs[0x12] >> 5) & 0x07); t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); -// pclog("TRIO64 clock %i %i %i %f %f %i\n", m, n1, n2, t, 14318184.0 * ((float)m / (float)n1), 1 << n2); return t; } @@ -1197,8 +1065,7 @@ static float s3_trio64_getclock(int clock, void *p) void s3_accel_out(uint16_t port, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; -// pclog("Accel out %04X %02X\n", port, val); - + if (port >= 0x8000) { s3_queue(s3, port, val, FIFO_OUT_BYTE); @@ -1222,14 +1089,12 @@ void s3_accel_out(uint16_t port, uint8_t val, void *p) void s3_accel_out_w(uint16_t port, uint16_t val, void *p) { s3_t *s3 = (s3_t *)p; -// pclog("Accel out w %04X %04X\n", port, val); s3_queue(s3, port, val, FIFO_OUT_WORD); } void s3_accel_out_l(uint16_t port, uint32_t val, void *p) { s3_t *s3 = (s3_t *)p; -// pclog("Accel out l %04X %08X\n", port, val); s3_queue(s3, port, val, FIFO_OUT_DWORD); } @@ -1237,7 +1102,6 @@ uint8_t s3_accel_in(uint16_t port, void *p) { s3_t *s3 = (s3_t *)p; int temp; -// pclog("Accel in %04X\n", port); switch (port) { case 0x42e8: @@ -1425,19 +1289,16 @@ uint8_t s3_accel_in(uint16_t port, void *p) void s3_accel_write(uint32_t addr, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; -// pclog("s3_accel_write %08x %02x\n", addr, val); s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_BYTE); } void s3_accel_write_w(uint32_t addr, uint16_t val, void *p) { s3_t *s3 = (s3_t *)p; -// pclog("s3_accel_write_w %08x %04x\n", addr, val); s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_WORD); } void s3_accel_write_l(uint32_t addr, uint32_t val, void *p) { s3_t *s3 = (s3_t *)p; -// pclog("s3_accel_write_l %08x %08x\n", addr, val); s3_queue(s3, addr & 0xffff, val, FIFO_WRITE_DWORD); } @@ -1499,14 +1360,11 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat int clip_b = s3->accel.multifunc[3] & 0xfff; int clip_r = s3->accel.multifunc[4] & 0xfff; int vram_mask = (s3->accel.multifunc[0xa] & 0xc0) == 0xc0; - uint32_t mix_mask; + uint32_t mix_mask = 0; uint16_t *vram_w = (uint16_t *)svga->vram; uint32_t *vram_l = (uint32_t *)svga->vram; uint32_t compare = s3->accel.color_cmp; int compare_mode = (s3->accel.multifunc[0xe] >> 7) & 3; -//return; -// if (!cpu_input) pclog("Start S3 command %i %i, %i %i, %i (clip %i, %i to %i, %i %i)\n", s3->accel.cmd >> 13, s3->accel.cur_x, s3->accel.cur_y, s3->accel.maj_axis_pcnt & 0xfff, s3->accel.multifunc[0] & 0xfff, clip_l, clip_t, clip_r, clip_b, s3->accel.multifunc[0xe] & 0x20); -// else pclog(" S3 command %i, %i, %08x %08x\n", s3->accel.cmd >> 13, count, mix_dat, cpu_dat); if (!cpu_input) s3->accel.dat_count = 0; if (cpu_input && (s3->accel.multifunc[0xa] & 0xc0) != 0x80) @@ -1627,12 +1485,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { READ((s3->accel.cy * s3->width) + s3->accel.cx, dest_dat); -// pclog("Line : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X (%02X %02X) ", s3->accel.cx, s3->accel.cy, s3->accel.dest + s3->accel.cx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat & mix_mask, s3->accel.src + s3->accel.cx, dest_dat, s3->accel.frgd_color, s3->accel.bkgd_color); - MIX -// pclog("%02X\n", dest_dat); - WRITE((s3->accel.cy * s3->width) + s3->accel.cx); } } @@ -1642,8 +1496,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->bpp == 0) cpu_dat >>= 8; else cpu_dat >>= 16; -// pclog("%i, %i - %i %i %i %i\n", s3->accel.cx, s3->accel.cy, s3->accel.err_term, s3->accel.maj_axis_pcnt, s3->accel.desty_axstp, s3->accel.destx_distp); - if (!s3->accel.sy) break; @@ -1696,12 +1548,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; s3->accel.dest = s3->accel.cy * s3->width; - -// pclog("Dest %08X (%i, %i) %04X %04X\n", s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.cur_x, s3->accel.cur_x & 0x1000); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ -// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ -// return; frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; @@ -1724,14 +1572,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat compare_mode < 2) { READ(s3->accel.dest + s3->accel.cx, dest_dat); - - -// if (CS != 0xc000) pclog("Write %05X %02X %02X %04X (%02X %02X) ", s3->accel.dest + s3->accel.cx, src_dat, dest_dat, mix_dat, s3->accel.frgd_mix, s3->accel.bkgd_mix); MIX -// if (CS != 0xc000) pclog("%02X\n", dest_dat); - WRITE(s3->accel.dest + s3->accel.cx); } } @@ -1748,10 +1591,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; -// s3->accel.dest -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; -// s3->accel.dest += s3_width; if (s3->accel.cmd & 0x80) s3->accel.cy++; else s3->accel.cy--; @@ -1787,12 +1628,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.src = s3->accel.cy * s3->width; s3->accel.dest = s3->accel.dy * s3->width; - -// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ -// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ -// return; if (s3->accel.sy < 0) return; @@ -1866,13 +1703,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); - -// pclog("BitBlt : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat); MIX -// pclog("%02X\n", dest_dat); - WRITE(s3->accel.dest + s3->accel.dx); } } @@ -1926,8 +1759,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (cpu_input/* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; if (s3->accel.sy < 0) { -// s3->accel.cur_x = s3->accel.cx; -// s3->accel.cur_y = s3->accel.cy; return; } } @@ -1952,9 +1783,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.cur_y & 0x1000) s3->accel.cy |= ~0xfff; /*Align source with destination*/ -// s3->accel.cx = (s3->accel.cx & ~7) | (s3->accel.dx & 7); -// s3->accel.cy = (s3->accel.cy & ~7) | (s3->accel.dy & 7); - s3->accel.pattern = (s3->accel.cy * s3->width) + s3->accel.cx; s3->accel.dest = s3->accel.dy * s3->width; @@ -1962,14 +1790,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.cy = s3->accel.dy & 7; s3->accel.src = s3->accel.pattern + (s3->accel.cy * s3->width); - -// pclog("Source %08X Dest %08X (%i, %i) - (%i, %i)\n", s3->accel.src, s3->accel.dest, s3->accel.cx, s3->accel.cy, s3->accel.dx, s3->accel.dy); -// dumpregs(); -// exit(-1); } if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ -// if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80 && !cpu_input) /*Mix data from CPU*/ -// return; frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; @@ -1997,13 +1819,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); - -// pclog("Pattern fill : %04i, %04i (%06X) - %02X (%02X %04X %05X) %02X ", s3->accel.dx, s3->accel.dy, s3->accel.dest + s3->accel.dx, src_dat, vram[s3->accel.src + s3->accel.cx], mix_dat, s3->accel.src + s3->accel.cx, dest_dat); MIX -// pclog("%02X\n", dest_dat); - WRITE(s3->accel.dest + s3->accel.dx); } } @@ -2075,7 +1893,6 @@ void s3_hwcursor_draw(svga_t *svga, int displine) if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; -// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); for (x = 0; x < 64; x += 16) { dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; @@ -2088,7 +1905,6 @@ void s3_hwcursor_draw(svga_t *svga, int displine) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? 0xffffff : 0; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); } offset++; @@ -2161,7 +1977,7 @@ uint8_t s3_pci_read(int func, int addr, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; -// pclog("S3 PCI read %08X\n", addr); + /* pclog("S3 PCI read %08X\n", addr); */ switch (addr) { case 0x00: return 0x33; /*'S3'*/ @@ -2183,8 +1999,8 @@ uint8_t s3_pci_read(int func, int addr, void *p) case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return ((s3->linear_base & ((s3->linear_size - 1) ^ 0xffffffff)) >> 16) & 0xff; - case 0x13: return ((s3->linear_base & ((s3->linear_size - 1) ^ 0xffffffff)) >> 24) & 0xff; + case 0x12: return svga->crtc[0x5a] & 0x80; + case 0x13: return svga->crtc[0x59]; case 0x30: return s3->pci_regs[0x30] & 0x01; /*BIOS ROM address*/ case 0x31: return 0x00; @@ -2198,7 +2014,7 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; -// pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); + /* pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); */ switch (addr) { case PCI_REG_COMMAND: @@ -2211,15 +2027,11 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) break; case 0x12: - s3->linear_base &= 0xff00ffff; - s3->linear_base |= (((uint32_t) val) << 16); - s3->linear_base &= ((s3->linear_size - 1) ^ 0xffffffff); + svga->crtc[0x5a] = val & 0x80; s3_updatemapping(s3); break; case 0x13: - s3->linear_base &= 0x00ffffff; - s3->linear_base |= (((uint32_t) val) << 24); - s3->linear_base &= ((s3->linear_size - 1) ^ 0xffffffff); + svga->crtc[0x59] = val; s3_updatemapping(s3); break; @@ -2228,12 +2040,10 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) if (s3->pci_regs[0x30] & 0x01) { uint32_t addr = (s3->pci_regs[0x32] << 16) | (s3->pci_regs[0x33] << 24); -// pclog("S3 bios_rom enabled at %08x\n", addr); mem_mapping_set_addr(&s3->bios_rom.mapping, addr, 0x8000); } else { -// pclog("S3 bios_rom disabled\n"); mem_mapping_disable(&s3->bios_rom.mapping); } return; @@ -2245,10 +2055,10 @@ static int vram_sizes[] = 7, /*512 kB*/ 6, /*1 MB*/ 4, /*2 MB*/ - 2, /*3 MB*/ + 0, 0, /*4 MB*/ 0, - 5, /*6 MB*/ + 0, 0, 3 /*8 MB*/ }; @@ -2259,9 +2069,9 @@ static void *s3_init(char *bios_fn, int chip) svga_t *svga = &s3->svga; int vram; uint32_t vram_size; - + memset(s3, 0, sizeof(s3_t)); - + vram = device_get_config_int("memory"); if (vram) vram_size = vram << 20; @@ -2287,21 +2097,23 @@ static void *s3_init(char *bios_fn, int chip) svga->crtc[0x36] = 2 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); else svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); - /* Set video BIOS to 32k (bit 2 = set). */ - svga->crtc[0x37] = 5 | (7 << 5); - // if (s3->chip == S3_VISION964) svga->crtc[0x37] |= 0xe; + svga->crtc[0x37] = 1 | (7 << 5); + + svga->crtc[0x53] = 1 << 3; + svga->crtc[0x59] = 0x70; s3_io_set(s3); - pci_add(s3_pci_read, s3_pci_write, s3); + if (PCI) + { + pci_add(s3_pci_read, s3_pci_write, s3); + } - s3->pci_regs[0x04] = 7; + s3->pci_regs[0x04] = 3; s3->pci_regs[0x30] = 0x00; s3->pci_regs[0x32] = 0x0c; s3->pci_regs[0x33] = 0x00; - - s3->linear_size = 0x10000; s3->chip = chip; @@ -2312,12 +2124,12 @@ static void *s3_init(char *bios_fn, int chip) return s3; } -void *s3_bahamas64_init() +void *s3_vision864_init(char *bios_fn) { - s3_t *s3 = s3_init("roms/bahamas64.BIN", S3_VISION864); + s3_t *s3 = s3_init(bios_fn, S3_VISION864); - s3->id = 0xc0; /*Vision864P*/ - s3->id_ext = s3->id_ext_pci = 0xc0; + s3->id = 0xc1; /*Vision864P*/ + s3->id_ext = s3->id_ext_pci = 0xc1; s3->packed_mmio = 0; s3->getclock = sdac_getclock; @@ -2326,34 +2138,31 @@ void *s3_bahamas64_init() return s3; } +void *s3_bahamas64_init() +{ + s3_t *s3 = s3_vision864_init("roms/bahamas64.BIN"); + return s3; +} + +void *s3_phoenix_vision864_init() +{ + s3_t *s3 = s3_vision864_init("roms/86c864p.bin"); + return s3; +} + int s3_bahamas64_available() { return rom_present("roms/bahamas64.BIN"); } -void *s3_9fx_init() +int s3_phoenix_vision864_available() { - s3_t *s3 = s3_init("roms/s3_764.bin", S3_TRIO64); - - s3->id = 0xe1; /*Trio64*/ - s3->id_ext = s3->id_ext_pci = 0x11; - s3->packed_mmio = 1; - - s3->getclock = s3_trio64_getclock; - s3->getclock_p = s3; - - return s3; -} - -int s3_9fx_available() -{ - return rom_present("roms/s3_764.bin"); + return rom_present("roms/86c864p.bin"); } void *s3_phoenix_trio32_init() { s3_t *s3 = s3_init("roms/86C732P.bin", S3_TRIO32); - svga_t *svga = &s3->svga; s3->id = 0xe1; /*Trio32*/ s3->id_ext = 0x10; @@ -2371,13 +2180,22 @@ int s3_phoenix_trio32_available() return rom_present("roms/86C732P.bin"); } -void *s3_phoenix_trio64_init() +void *s3_trio64_init(char *bios_fn) { - s3_t *s3 = s3_init("roms/86c764x1.bin", S3_TRIO64); - svga_t *svga = &s3->svga; + int card_id = 0; + s3_t *s3 = s3_init(bios_fn, S3_TRIO64); - s3->id = 0xe1; /*Trio64*/ - s3->id_ext = s3->id_ext_pci = 0x11; + card_id = device_get_config_int("card_id"); + + if (card_id) + { + s3->id = 0xc1; /*Vision864P*/ + } + else + { + s3->id = 0xe1; /*Trio64*/ + } + s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; s3->getclock = s3_trio64_getclock; @@ -2386,43 +2204,32 @@ void *s3_phoenix_trio64_init() return s3; } +void *s3_9fx_init() +{ + s3_t *s3 = s3_trio64_init("roms/s3_764.bin"); + return s3; +} + +void *s3_phoenix_trio64_init() +{ + s3_t *s3 = s3_trio64_init("roms/86C764X1.bin"); + return s3; +} + +void *s3_diamond_stealth64_init() +{ + s3_t *s3 = s3_trio64_init("roms/STEALT64.BIN"); + return s3; +} + +int s3_9fx_available() +{ + return rom_present("roms/s3_764.bin"); +} + int s3_phoenix_trio64_available() { - return rom_present("roms/86c764x1.bin"); -} - -void *s3_phoenix_vision864_init() -{ - s3_t *s3 = s3_init("roms/86c864p.bin", S3_VISION864); - - s3->id = 0xc1; /*Vision864P*/ - s3->id_ext = s3->id_ext_pci = 0xc1; - s3->packed_mmio = 0; - - s3->getclock = sdac_getclock; - s3->getclock_p = &s3->ramdac; - - return s3; -} - -int s3_phoenix_vision864_available() -{ - return rom_present("roms/86c864p.BIN"); -} - -/* void *s3_diamond_stealth64_init() -{ - s3_t *s3 = s3_init("roms/STEALT64.BIN", S3_VISION864); - svga_t *svga = &s3->svga; - - s3->id = 0xc0; - s3->id_ext = s3->id_ext_pci = 0xc1; - s3->packed_mmio = 0; - - s3->getclock = sdac_getclock; - s3->getclock_p = &s3->ramdac; - - return s3; + return rom_present("roms/86C764X1.bin"); } int s3_diamond_stealth64_available() @@ -2430,31 +2237,16 @@ int s3_diamond_stealth64_available() return rom_present("roms/STEALT64.BIN"); } -void *s3_miro_vision964_init() -{ - s3_t *s3 = s3_init("roms/mirocrystal.VBI", S3_VISION964); - - s3->id = 0xd0; - s3->id_ext = s3->id_ext_pci = 0xd1; - s3->packed_mmio = 1; - - s3->getclock = bt485_getclock; - s3->getclock_p = &s3->bt485_ramdac; - - return s3; -} - -int s3_miro_vision964_available() -{ - return rom_present("roms/mirocrystal.VBI"); -} */ - void s3_close(void *p) { s3_t *s3 = (s3_t *)p; svga_close(&s3->svga); + thread_kill(s3->fifo_thread); + thread_destroy_event(s3->wake_fifo_thread); + thread_destroy_event(s3->fifo_not_full_event); + free(s3); } @@ -2493,246 +2285,129 @@ void s3_add_status_info(char *s, int max_len, void *p) static device_config_t s3_bahamas64_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 4, { { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, /*Vision864 also supports 8 MB, however the Paradise BIOS is buggy (VESA modes don't work correctly)*/ { - .description = "" + "" } - }, - .default_int = 4 + } }, { - .type = -1 + "", "", -1 } }; static device_config_t s3_9fx_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 2, { { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, /*Trio64 also supports 4 MB, however the Number Nine BIOS does not*/ { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .type = -1 + "is_pci", "Bus", CONFIG_SELECTION, "", 1, + { + { + "VLB", 0 + }, + { + "PCI", 1 + }, + { + "" + } + } + }, + { + "", "", -1 } }; static device_config_t s3_phoenix_trio32_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 2, { { - .description = "512 KB", - .value = 0 + "512 KB", 0 }, { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .type = -1 + "", "", -1 } }; static device_config_t s3_phoenix_trio64_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 2, { { - .description = "512 KB", - .value = 0 + "512 KB", 0 }, { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .type = -1 + "card_id", "Card ID", CONFIG_SELECTION, "", 1, + { + { + "S3 Trio64", 0 + }, + { + "S3 Vision864", 1 + }, + { + "" + } + } + }, + { + "", "", -1 } }; -static device_config_t s3_phoenix_vision864_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "512 KB", - .value = 0 - }, - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -/* static device_config_t s3_diamond_stealth64_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "512 KB", - .value = 0 - }, - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "3 MB", - .value = 3 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "" - } - }, - .default_int = 2 - }, - { - .type = -1 - } -}; - -static device_config_t s3_miro_vision964_config[] = -{ - { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = - { - { - .description = "1 MB", - .value = 1 - }, - { - .description = "2 MB", - .value = 2 - }, - { - .description = "3 MB", - .value = 3 - }, - { - .description = "4 MB", - .value = 4 - }, - { - .description = "6 MB", - .value = 6 - }, - { - .description = "8 MB", - .value = 8 - }, - { - .description = "" - } - }, - .default_int = 4 - }, - { - .type = -1 - } -}; */ - device_t s3_bahamas64_device = { "Paradise Bahamas 64 (S3 Vision864)", @@ -2795,12 +2470,12 @@ device_t s3_phoenix_vision864_device = s3_speed_changed, s3_force_redraw, s3_add_status_info, - s3_phoenix_vision864_config + s3_bahamas64_config }; -/* device_t s3_diamond_stealth64_device = +device_t s3_diamond_stealth64_device = { - "S3 Vision864 (Diamond Stealth64)", + "S3 Trio64 (Diamond Stealth64 DRAM)", 0, s3_diamond_stealth64_init, s3_close, @@ -2808,18 +2483,5 @@ device_t s3_phoenix_vision864_device = s3_speed_changed, s3_force_redraw, s3_add_status_info, - s3_diamond_stealth64_config + s3_phoenix_trio64_config }; - -device_t s3_miro_vision964_device = -{ - "Micro Crystal S3 Vision964", - 0, - s3_miro_vision964_init, - s3_close, - s3_miro_vision964_available, - s3_speed_changed, - s3_force_redraw, - s3_add_status_info, - s3_miro_vision964_config -}; */ diff --git a/src/vid_s3.h b/src/vid_s3.h index 34ae21b47..396e6523b 100644 --- a/src/vid_s3.h +++ b/src/vid_s3.h @@ -6,5 +6,5 @@ device_t s3_9fx_device; device_t s3_phoenix_trio32_device; device_t s3_phoenix_trio64_device; device_t s3_phoenix_vision864_device; -/* device_t s3_diamond_stealth64_device; -device_t s3_miro_vision964_device; */ +device_t s3_diamond_stealth64_device; +/* device_t s3_miro_vision964_device; */ diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index 6319a3950..cecdcb427 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -50,7 +50,7 @@ enum FIFO_INVALID = (0x00 << 24), FIFO_WRITE_BYTE = (0x01 << 24), FIFO_WRITE_WORD = (0x02 << 24), - FIFO_WRITE_DWORD = (0x03 << 24), + FIFO_WRITE_DWORD = (0x03 << 24) }; typedef struct @@ -229,7 +229,7 @@ typedef struct virge_t int virge_busy; } virge_t; -static inline void wake_fifo_thread(virge_t *virge) +static __inline void wake_fifo_thread(virge_t *virge) { thread_set_event(virge->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -300,8 +300,6 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// pclog("S3 out %04X %02X %04X:%08X %04X %04X %i\n", addr, val, CS, pc, ES, BX, ins); - switch (addr) { case 0x3c5: @@ -318,16 +316,10 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) } break; - //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: -// pclog("Write RAMDAC %04X %02X %04X:%04X\n", addr, val, CS, pc); - //sdac_ramdac_out(addr,val); - //return; - case 0x3d4: - svga->crtcreg = val;// & 0x7f; + svga->crtcreg = val; return; case 0x3d5: - //pclog("Write CRTC R%02X %02X %04x(%08x):%08x\n", svga->crtcreg, val, CS, cs, pc); if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) return; if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) @@ -366,7 +358,6 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x35: virge->bank = (virge->bank & 0x70) | (val & 0xf); -// pclog("CRTC write R35 %02X\n", val); if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; else svga->write_bank = svga->read_bank = virge->bank << 14; break; @@ -378,7 +369,6 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) break; case 0x6a: virge->bank = val; -// pclog("CRTC write R6a %02X\n", val); if (svga->chain4) svga->write_bank = svga->read_bank = virge->bank << 16; else svga->write_bank = svga->read_bank = virge->bank << 14; break; @@ -420,15 +410,13 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x67: switch (val >> 4) { - case 3: svga->bpp = 15; break; - case 5: svga->bpp = 16; break; + case 2: case 3: svga->bpp = 15; break; + case 4: case 5: svga->bpp = 16; break; case 7: svga->bpp = 24; break; - case 13: svga->bpp = 32; break; + case 13: svga->bpp = (gfxcard == GFX_VIRGEVX) ? 24 : 32; break; default: svga->bpp = 8; break; } break; - //case 0x55: case 0x43: -// pclog("Write CRTC R%02X %02X\n", crtcreg, val); } if (old != val) { @@ -452,7 +440,6 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; -// if (addr != 0x3da) pclog("S3 in %04X %04X:%08X ", addr, CS, pc); switch (addr) { case 0x3c1: @@ -461,9 +448,6 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) else ret = svga_in(addr, svga); break; - //case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: -// pclog("Read RAMDAC %04X %04X:%04X\n", addr, CS, pc); - //return sdac_ramdac_in(addr); case 0x3c5: if (svga->seqaddr >= 8) @@ -478,7 +462,6 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) ret = svga->crtcreg; break; case 0x3D5: - //pclog("Read CRTC R%02X %04X:%04X (%02x)\n", svga->crtcreg, CS, pc, svga->crtc[svga->crtcreg]); switch (svga->crtcreg) { case 0x2d: ret = virge->virge_id_high; break; /*Extended chip ID*/ @@ -500,7 +483,6 @@ static uint8_t s3_virge_in(uint16_t addr, void *p) ret = svga_in(addr, svga); break; } -// if (addr != 0x3da) pclog("%02X\n", ret); return ret; } @@ -520,7 +502,6 @@ static void s3_virge_recalctimings(svga_t *svga) if ((svga->crtc[0x67] & 0xc) != 0xc) /*VGA mode*/ { svga->ma_latch |= (virge->ma_ext << 16); -//pclog("VGA mode\n"); if (svga->crtc[0x51] & 0x30) svga->rowoffset += (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) svga->rowoffset += 0x100; if (!svga->rowoffset) svga->rowoffset = 256; @@ -546,19 +527,20 @@ static void s3_virge_recalctimings(svga_t *svga) break; } } - -// pclog("svga->rowoffset = %i bpp=%i\n", svga->rowoffset, svga->bpp); - if (svga->bpp == 15 || svga->bpp == 16) - { - svga->htotal >>= 1; - svga->hdisp >>= 1; - } - if (svga->bpp == 24) - { - svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ - } + + if (gfxcard != GFX_VIRGEVX) + { + if ((svga->bpp == 15) || (svga->bpp == 16)) + { + svga->htotal >>= 1; + svga->hdisp >>= 1; + } + if (svga->bpp == 24) + { + svga->rowoffset = (svga->rowoffset * 3) / 4; /*Hack*/ + } + } svga->vrammask = (svga->crtc[0x32] & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); -//pclog("VGA mode x_disp=%i dispend=%i vtotal=%i\n", svga->hdisp, svga->dispend, svga->vtotal); } else /*Streams mode*/ { @@ -582,7 +564,6 @@ static void s3_virge_recalctimings(svga_t *svga) svga->overlay.ena = (svga->overlay.x >= 0); svga->overlay.v_acc = virge->streams.dda_vert_accumulator; -//pclog("Streams mode x_disp=%i dispend=%i vtotal=%i x=%i y=%i ysize=%i\n", svga->hdisp, svga->dispend, svga->vtotal, svga->overlay.x, svga->overlay.y, svga->overlay.ysize); svga->rowoffset = virge->streams.pri_stride >> 3; switch ((virge->streams.pri_ctrl >> 24) & 0x7) @@ -611,7 +592,7 @@ static void s3_virge_recalctimings(svga_t *svga) if (((svga->miscout >> 2) & 3) == 3) { int n = svga->seqregs[0x12] & 0x1f; - int r = (svga->seqregs[0x12] >> 5) & (virge->is_375 ? 7 : 3); + int r = (svga->seqregs[0x12] >> 5) & ((virge->is_375 || (gfxcard == GFX_VIRGEVX)) ? 7 : 3); int m = svga->seqregs[0x13] & 0x7f; double freq = (((double)m + 2) / (((double)n + 2) * (double)(1 << r))) * 14318184.0; @@ -625,7 +606,6 @@ static void s3_virge_updatemapping(virge_t *virge) if (!(virge->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { -// pclog("Update mapping - PCI disabled\n"); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&virge->linear_mapping); mem_mapping_disable(&virge->mmio_mapping); @@ -676,7 +656,6 @@ static void s3_virge_updatemapping(virge_t *virge) } virge->linear_base &= ~(virge->linear_size - 1); svga->linear_base = virge->linear_base; -// pclog("%08X %08X %02X %02X %02X\n", linear_base, linear_size, crtc[0x58], crtc[0x59], crtc[0x5a]); pclog("Linear framebuffer at %08X size %08X\n", virge->linear_base, virge->linear_size); if (virge->linear_base == 0xa0000) { @@ -726,7 +705,6 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) uint8_t ret; reg_reads++; -// pclog("New MMIO readb %08X\n", addr); switch (addr & 0xffff) { case 0x8505: @@ -757,7 +735,6 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *p) static uint16_t s3_virge_mmio_read_w(uint32_t addr, void *p) { reg_reads++; -// pclog("New MMIO readw %08X\n", addr); switch (addr & 0xfffe) { default: @@ -770,7 +747,6 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) virge_t *virge = (virge_t *)p; uint32_t ret = 0xffffffff; reg_reads++; -// pclog("New MMIO readl %08X %04X(%08X):%08X ", addr, CS, cs, pc); switch (addr & 0xfffc) { case 0x8180: @@ -847,7 +823,6 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) ret = (0x10 << 8) | (1 << 13); if (!virge->virge_busy) wake_fifo_thread(virge); -// pclog("Read status %04x %i\n", ret, virge->s3d_busy); break; case 0xa4d4: s3_virge_wait_fifo_idle(virge); @@ -913,7 +888,6 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) default: ret = s3_virge_mmio_read_w(addr, p) | (s3_virge_mmio_read_w(addr + 2, p) << 16); } -// /*if ((addr & 0xfffc) != 0x8504) */pclog("%02x\n", ret); return ret; } @@ -1270,7 +1244,6 @@ static void fifo_thread(void *param) static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &virge->fifo[virge->fifo_write_idx & FIFO_MASK]; - int c; if (FIFO_FULL) { @@ -1295,9 +1268,7 @@ static void s3_virge_queue(virge_t *virge, uint32_t addr, uint32_t val, uint32_t static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; - svga_t *svga = &virge->svga; -// pclog("New MMIO writeb %08X %02X %04x(%08x):%08x\n", addr, val, CS, cs, pc); reg_writes++; if ((addr & 0xfffc) < 0x8000) { @@ -1327,7 +1298,6 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { virge_t *virge = (virge_t *)p; reg_writes++; -// pclog("New MMIO writew %08X %04X %04x(%08x):%08x\n", addr, val, CS, cs, pc); if ((addr & 0xfffc) < 0x8000) { s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); @@ -1345,8 +1315,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; reg_writes++; -// if ((addr & 0xfffc) >= 0xb400 && (addr & 0xfffc) < 0xb800) -// pclog("New MMIO writel %08X %08X %04x(%08x):%08x\n", addr, val, CS, cs, pc); if ((addr & 0xfffc) < 0x8000) { @@ -1389,13 +1357,11 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->streams.blend_ctrl = val; break; case 0x81c0: -// pclog("Write pri_fb0 %08x\n", val); virge->streams.pri_fb0 = val & 0x3fffff; svga_recalctimings(svga); svga->fullchange = changeframecount; break; case 0x81c4: -// pclog("Write pri_fb1 %08x\n", val); virge->streams.pri_fb1 = val & 0x3fffff; svga_recalctimings(svga); svga->fullchange = changeframecount; @@ -1406,7 +1372,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) svga->fullchange = changeframecount; break; case 0x81cc: -// pclog("Write buffer_ctrl %08x\n", val); virge->streams.buffer_ctrl = val; svga_recalctimings(svga); svga->fullchange = changeframecount; @@ -1659,11 +1624,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->s3d_tri.cmd_set = val; if (!(val & CMD_SET_AE)) queue_triangle(virge); -/* { - thread_set_event(virge->wake_render_thread); - thread_wait_event(virge->wake_main_thread, -1); - } */ -// s3_virge_triangle(virge); break; case 0xb504: virge->s3d_tri.tbv = val & 0xfffff; @@ -1768,12 +1728,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->s3d_tri.tlr = val >> 31; if (virge->s3d_tri.cmd_set & CMD_SET_AE) queue_triangle(virge); -/* { - thread_set_event(virge->wake_render_thread); - thread_wait_event(virge->wake_main_thread, -1); - }*/ - -// s3_virge_triangle(virge); break; } } @@ -1874,7 +1828,6 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) { - int cpu_input = (count != -1); uint8_t *vram = virge->svga.vram; uint32_t mono_pattern[64]; int count_mask; @@ -1884,6 +1837,11 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) int x_mul; int cpu_dat_shift; uint32_t *pattern_data; + uint32_t src_addr; + uint32_t dest_addr; + uint32_t source = 0, dest, pattern; + uint32_t out = 0; + int update; switch (virge->s3d.cmd_set & CMD_SET_FORMAT_MASK) { @@ -1976,11 +1934,10 @@ static void s3_virge_bitblt(virge_t *virge, int count, uint32_t cpu_dat) return; while (count) { - uint32_t src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); - uint32_t dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); - uint32_t source, dest, pattern; - uint32_t out = 0; - int update = 1; + src_addr = virge->s3d.src_base + (virge->s3d.src_x * x_mul) + (virge->s3d.src_y * virge->s3d.src_str); + dest_addr = virge->s3d.dest_base + (virge->s3d.dest_x * x_mul) + (virge->s3d.dest_y * virge->s3d.dest_str); + out = 0; + update = 1; switch (virge->s3d.cmd_set & (CMD_SET_MS | CMD_SET_IDS)) { @@ -2221,14 +2178,12 @@ skip_line: virge->s3d.dest_l = virge->s3d.plxstart; virge->s3d.h = virge->s3d.pycnt & 0x7ff; virge->s3d.rop = (virge->s3d.cmd_set >> 17) & 0xff; - //pclog("Start poly - l=%08x r=%08x h=%i rop=%02x\n", virge->s3d.dest_l, virge->s3d.dest_r, virge->s3d.h, virge->s3d.rop); while (virge->s3d.h) { int x = virge->s3d.dest_l >> 20; int xend = virge->s3d.dest_r >> 20; int y = virge->s3d.pystart & 0x7ff; int xdir = (x < xend) ? 1 : -1; - //pclog(" %03i: %i - %i %08x-%08x\n", y, x, xend, virge->s3d.dest_l, virge->s3d.dest_r); do { uint32_t dest_addr = virge->s3d.dest_base + (x * x_mul) + (y * virge->s3d.dest_str); @@ -2894,6 +2849,21 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 uint32_t dest_offset, z_offset; + uint32_t src_col; + int src_r = 0, src_g = 0, src_b = 0; + + int x; + int xe; + uint32_t z; + + uint32_t dest_addr, z_addr; + int dx; + int x_offset; + int xz_offset; + + int update; + uint16_t src_z = 0; + if (s3d_tri->cmd_set & CMD_SET_HC) { if (state->y < s3d_tri->clip_t) @@ -2930,21 +2900,20 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 for (; y_count > 0; y_count--) { - int x = (state->x1 + ((1 << 20) - 1)) >> 20; - int xe = (state->x2 + ((1 << 20) - 1)) >> 20; - uint32_t z = (state->base_z > 0) ? (state->base_z << 1) : 0; + x = (state->x1 + ((1 << 20) - 1)) >> 20; + xe = (state->x2 + ((1 << 20) - 1)) >> 20; + z = (state->base_z > 0) ? (state->base_z << 1) : 0; if (x_dir < 0) { x--; xe--; } - if (x != xe && (x_dir > 0 && x < xe) || (x_dir < 0 && x > xe)) + if (((x != xe) && ((x_dir > 0) && (x < xe))) || ((x_dir < 0) && (x > xe))) { - uint32_t dest_addr, z_addr; - int dx = (x_dir > 0) ? ((31 - ((state->x1-1) >> 15)) & 0x1f) : (((state->x1-1) >> 15) & 0x1f); - int x_offset = x_dir * (bpp + 1); - int xz_offset = x_dir << 1; + dx = (x_dir > 0) ? ((31 - ((state->x1-1) >> 15)) & 0x1f) : (((state->x1-1) >> 15) & 0x1f); + x_offset = x_dir * (bpp + 1); + xz_offset = x_dir << 1; if (x_dir > 0) dx += 1; state->r = state->base_r + ((s3d_tri->TdRdX * dx) >> 5); @@ -2957,8 +2926,6 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 state->d = state->base_d + ((s3d_tri->TdDdX * dx) >> 5); z += ((s3d_tri->TdZdX * dx) >> 5); -// pclog("Draw Y=%i X=%i to XE=%i %i %08x %08x %08x %08x %08x %08x %08x %08x %i %08x\n", state->y, x, xe, dx, state->x1, state->x2, dx1, virge->s3d.TdWdX, state->u, state->v, virge->s3d.TdUdX, virge->s3d.TdUdY, dx, (virge->s3d.TdUdX * dx) >> 4); - if (s3d_tri->cmd_set & CMD_SET_HC) { if (x_dir > 0) @@ -3020,8 +2987,7 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 for (; x != xe; x = (x + x_dir) & 0xfff) { - int update = 1; - uint16_t src_z; + update = 1; _x = x; _y = state->y; if (use_z) @@ -3038,9 +3004,6 @@ static void tri(virge_t *virge, s3d_t *s3d_tri, s3d_state_t *state, int yc, int3 if (s3d_tri->cmd_set & CMD_SET_ABC_ENABLE) { - uint32_t src_col; - int src_r, src_g, src_b; - switch (bpp) { case 0: /*8 bpp*/ @@ -3167,7 +3130,6 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) { case 0: dest_pixel = dest_pixel_gouraud_shaded_triangle; -// pclog("dest_pixel_gouraud_shaded_triangle\n"); break; case 1: case 5: @@ -3175,15 +3137,12 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) { case 0: dest_pixel = dest_pixel_lit_texture_reflection; -// pclog("dest_pixel_lit_texture_reflection\n"); break; case 1: dest_pixel = dest_pixel_lit_texture_modulate; -// pclog("dest_pixel_lit_texture_modulate\n"); break; case 2: dest_pixel = dest_pixel_lit_texture_decal; -// pclog("dest_pixel_lit_texture_decal\n"); break; default: pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); @@ -3193,7 +3152,6 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) case 2: case 6: dest_pixel = dest_pixel_unlit_texture_triangle; -// pclog("dest_pixel_unlit_texture_triangle\n"); break; default: pclog("bad triangle type %x\n", (s3d_tri->cmd_set >> 27) & 0xf); @@ -3204,47 +3162,39 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) { case 0: case 1: tex_sample = tex_sample_mipmap; -// pclog("use tex_sample_mipmap\n"); break; case 2: case 3: tex_sample = virge->bilinear_enabled ? tex_sample_mipmap_filter : tex_sample_mipmap; -// pclog("use tex_sample_mipmap_filter\n"); break; case 4: case 5: tex_sample = tex_sample_normal; -// pclog("use tex_sample_normal\n"); break; case 6: case 7: tex_sample = virge->bilinear_enabled ? tex_sample_normal_filter : tex_sample_normal; -// pclog("use tex_sample_normal_filter\n"); break; case (0 | 8): case (1 | 8): if (virge->is_375) tex_sample = tex_sample_persp_mipmap_375; else tex_sample = tex_sample_persp_mipmap; -// pclog("use tex_sample_persp_mipmap\n"); break; case (2 | 8): case (3 | 8): if (virge->is_375) tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter_375 : tex_sample_persp_mipmap_375; else tex_sample = virge->bilinear_enabled ? tex_sample_persp_mipmap_filter : tex_sample_persp_mipmap; -// pclog("use tex_sample_persp_mipmap_filter\n"); break; case (4 | 8): case (5 | 8): if (virge->is_375) tex_sample = tex_sample_persp_normal_375; else tex_sample = tex_sample_persp_normal; -// pclog("use tex_sample_persp_normal\n"); break; case (6 | 8): case (7 | 8): if (virge->is_375) tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter_375 : tex_sample_persp_normal_375; else tex_sample = virge->bilinear_enabled ? tex_sample_persp_normal_filter : tex_sample_persp_normal; -// pclog("use tex_sample_persp_normal_filter\n"); break; } @@ -3255,19 +3205,15 @@ static void s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) break; case 1: tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB4444 : tex_ARGB4444_nowrap; -// pclog("tex_ARGB4444\n"); break; case 2: tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; -// pclog("tex_ARGB1555 %i\n", (s3d_tri->cmd_set >> 5) & 7); break; default: pclog("bad texture type %i\n", (s3d_tri->cmd_set >> 5) & 7); tex_read = (s3d_tri->cmd_set & CMD_SET_TWE) ? tex_ARGB1555 : tex_ARGB1555_nowrap; break; } - -// pclog("Triangle %i %i,%i to %i,%i %08x\n", y, x1 >> 20, y, s3d_tri->txend01 >> 20, y - (s3d_tri->ty01 + s3d_tri->ty12), state.cmd_set); state.y = s3d_tri->tys; state.x1 = s3d_tri->txs; @@ -3306,15 +3252,12 @@ static void render_thread(void *param) static void queue_triangle(virge_t *virge) { - int c; -// pclog("queue_triangle: read=%i write=%i RB_ENTRIES=%i RB_FULL=%i\n", virge->s3d_read_idx, virge->s3d_write_idx, RB_ENTRIES, RB_FULL); if (RB_FULL) { thread_reset_event(virge->not_full_event); if (RB_FULL) thread_wait_event(virge->not_full_event, -1); /*Wait for room in ringbuffer*/ } -// pclog(" add at read=%i write=%i %i\n", virge->s3d_read_idx, virge->s3d_write_idx, virge->s3d_write_idx & RB_MASK); virge->s3d_buffer[virge->s3d_write_idx & RB_MASK] = virge->s3d_tri; virge->s3d_write_idx++; if (!virge->s3d_busy) @@ -3331,7 +3274,9 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; -// pclog("HWcursor %i %i\n", svga->hwcursor_latch.x, svga->hwcursor_latch.y); + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + for (x = 0; x < 64; x += 16) { dat[0] = (svga->vram[svga->hwcursor_latch.addr] << 8) | svga->vram[svga->hwcursor_latch.addr + 1]; @@ -3363,7 +3308,6 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = virge->hwcursor_col[dat[1] >> 15]; else if (dat[1] & 0x8000) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga->hwcursor_on, dat[0], dat[1]); } offset++; @@ -3373,6 +3317,8 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) } svga->hwcursor_latch.addr += 4; } + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; } #define DECODE_YCbCr() \ @@ -3448,18 +3394,18 @@ static void s3_virge_hwcursor_draw(svga_t *svga, int displine) b[x_write+1] = y2 + dB; \ CLAMP(b[x_write+1]); \ \ - r[x_write+2] = y2 + dR; \ + r[x_write+2] = y3 + dR; \ CLAMP(r[x_write+2]); \ - g[x_write+2] = y2 - dG; \ + g[x_write+2] = y3 - dG; \ CLAMP(g[x_write+2]); \ - b[x_write+2] = y2 + dB; \ + b[x_write+2] = y3 + dB; \ CLAMP(b[x_write+2]); \ \ - r[x_write+3] = y2 + dR; \ + r[x_write+3] = y4 + dR; \ CLAMP(r[x_write+3]); \ - g[x_write+3] = y2 - dG; \ + g[x_write+3] = y4 - dG; \ CLAMP(g[x_write+3]); \ - b[x_write+3] = y2 + dB; \ + b[x_write+3] = y4 + dB; \ CLAMP(b[x_write+3]); \ \ x_write = (x_write + 4) & 7; \ @@ -3608,9 +3554,6 @@ static void s3_virge_overlay_draw(svga_t *svga, int displine) int offset = (virge->streams.sec_x - virge->streams.pri_x) + 1; int h_acc = virge->streams.dda_horiz_accumulator; int r[8], g[8], b[8]; - int r_samp[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - int g_samp[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - int b_samp[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int x_size, x_read = 4, x_write = 4; int x; uint32_t *p; @@ -3655,7 +3598,6 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; uint8_t ret = 0; -// pclog("S3 PCI read %08X ", addr); switch (addr) { case 0x00: ret = 0x33; break; /*'S3'*/ @@ -3694,7 +3636,6 @@ static uint8_t s3_virge_pci_read(int func, int addr, void *p) case 0x3f: ret = 0xff; break; } -// pclog("%02X\n", ret); return ret; } @@ -3702,7 +3643,6 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; -// pclog("S3 PCI write %08X %02X %04X:%08X\n", addr, val, CS, pc); switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: @@ -3738,13 +3678,11 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) if (virge->pci_regs[0x30] & 0x01) { uint32_t addr = (virge->pci_regs[0x32] << 16) | (virge->pci_regs[0x33] << 24); -// pclog("Virge bios_rom enabled at %08x\n", addr); mem_mapping_set_addr(&virge->bios_rom.mapping, addr, 0x8000); mem_mapping_enable(&virge->bios_rom.mapping); } else { -// pclog("Virge bios_rom disabled\n"); mem_mapping_disable(&virge->bios_rom.mapping); } return; @@ -3829,7 +3767,102 @@ static void *s3_virge_init() break; } - virge->svga.crtc[0x37] = 1;// | (7 << 5); + virge->svga.crtc[0x37] = 1; + virge->svga.crtc[0x53] = 1 << 3; + virge->svga.crtc[0x59] = 0x70; + + virge->is_375 = 0; + + pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + + virge->wake_render_thread = thread_create_event(); + virge->wake_main_thread = thread_create_event(); + virge->not_full_event = thread_create_event(); + virge->render_thread = thread_create(render_thread, virge); + + virge->wake_fifo_thread = thread_create_event(); + virge->fifo_not_full_event = thread_create_event(); + virge->fifo_thread = thread_create(fifo_thread, virge); + + return virge; +} + +static void *s3_virge_988_init() +{ + virge_t *virge = malloc(sizeof(virge_t)); + memset(virge, 0, sizeof(virge_t)); + + virge->bilinear_enabled = device_get_config_int("bilinear"); + virge->dithering_enabled = device_get_config_int("dithering"); + virge->memory_size = device_get_config_int("memory"); + + svga_init(&virge->svga, virge, virge->memory_size << 20, + s3_virge_recalctimings, + s3_virge_in, s3_virge_out, + s3_virge_hwcursor_draw, + s3_virge_overlay_draw); + + rom_init(&virge->bios_rom, "roms/diamondstealth3000.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + if (PCI) + mem_mapping_disable(&virge->bios_rom.mapping); + + mem_mapping_add(&virge->mmio_mapping, 0, 0, s3_virge_mmio_read, + s3_virge_mmio_read_w, + s3_virge_mmio_read_l, + s3_virge_mmio_write, + s3_virge_mmio_write_w, + s3_virge_mmio_write_l, + NULL, + 0, + virge); + mem_mapping_add(&virge->new_mmio_mapping, 0, 0, s3_virge_mmio_read, + s3_virge_mmio_read_w, + s3_virge_mmio_read_l, + s3_virge_mmio_write, + s3_virge_mmio_write_w, + s3_virge_mmio_write_l, + NULL, + 0, + virge); + mem_mapping_add(&virge->linear_mapping, 0, 0, svga_read_linear, + svga_readw_linear, + svga_readl_linear, + svga_write_linear, + svga_writew_linear, + svga_writel_linear, + NULL, + 0, + &virge->svga); + + io_sethandler(0x03c0, 0x0020, s3_virge_in, NULL, NULL, s3_virge_out, NULL, NULL, virge); + + virge->pci_regs[4] = 3; + virge->pci_regs[5] = 0; + virge->pci_regs[6] = 0; + virge->pci_regs[7] = 2; + virge->pci_regs[0x32] = 0x0c; + virge->pci_regs[0x3c] = device_get_config_int("irq"); + virge->pci_regs[0x3d] = 1; + virge->pci_regs[0x3e] = 4; + virge->pci_regs[0x3f] = 0xff; + + virge->virge_id_high = 0x88; + virge->virge_id_low = 0x3d; + virge->virge_rev = 0; + virge->virge_id = 0xe1; + + switch (virge->memory_size) + { + case 2: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (4 << 5); + break; + case 4: + default: + virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); + break; + } + + virge->svga.crtc[0x37] = 1; virge->svga.crtc[0x53] = 1 << 3; virge->svga.crtc[0x59] = 0x70; @@ -3923,8 +3956,7 @@ static void *s3_virge_375_init() virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4) | (0 << 5); break; } -// virge->svga.crtc[0x36] = 2 | (0 << 2) | (1 << 4); - virge->svga.crtc[0x37] = 1;// | (7 << 5); + virge->svga.crtc[0x37] = 1; virge->svga.crtc[0x53] = 1 << 3; virge->svga.crtc[0x59] = 0x70; @@ -3960,6 +3992,10 @@ static void s3_virge_close(void *p) thread_destroy_event(virge->wake_main_thread); thread_destroy_event(virge->wake_render_thread); + thread_kill(virge->fifo_thread); + thread_destroy_event(virge->wake_fifo_thread); + thread_destroy_event(virge->fifo_not_full_event); + svga_close(&virge->svga); free(virge); @@ -3970,6 +4006,11 @@ static int s3_virge_available() return rom_present("roms/s3virge.bin"); } +static int s3_virge_988_available() +{ + return rom_present("roms/diamondstealth3000.VBI"); +} + static int s3_virge_375_available() { return rom_present("roms/86c375_1.bin"); @@ -4013,91 +4054,66 @@ static void s3_virge_add_status_info(char *s, int max_len, void *p) static device_config_t s3_virge_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 4, { { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "" + "" } - }, - .default_int = 4 + } }, { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dithering", - .description = "Dithering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "irq", - .description = "IRQ", - .type = CONFIG_SELECTION, - .selection = + "irq", "IRQ", CONFIG_SELECTION, "", 3, { { - .description = "IRQ 3", - .value = 3 + "IRQ 3", 3 }, { - .description = "IRQ 4", - .value = 4 + "IRQ 4", 4 }, { - .description = "IRQ 5", - .value = 5 + "IRQ 5", 5 }, { - .description = "IRQ 7", - .value = 7 + "IRQ 7", 7 }, { - .description = "IRQ 9", - .value = 9 + "IRQ 9", 9 }, { - .description = "IRQ 10", - .value = 10 + "IRQ 10", 10 }, { - .description = "IRQ 11", - .value = 11 + "IRQ 11", 11 }, { - .description = "IRQ 12", - .value = 12 + "IRQ 12", 12 }, { - .description = "IRQ 14", - .value = 14 + "IRQ 14", 14 }, { - .description = "IRQ 15", - .value = 15 + "IRQ 15", 15 }, { - .description = "" + "" } }, .default_int = 3 }, { - .type = -1 + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dithering", "Dithering", CONFIG_BINARY, "", 1 + }, + { + "", "", -1 } }; @@ -4114,6 +4130,19 @@ device_t s3_virge_device = s3_virge_config }; +device_t s3_virge_988_device = +{ + "Diamond Stealth 3D 3000 (S3 ViRGE/VX)", + 0, + s3_virge_988_init, + s3_virge_close, + s3_virge_988_available, + s3_virge_speed_changed, + s3_virge_force_redraw, + s3_virge_add_status_info, + s3_virge_config +}; + device_t s3_virge_375_device = { "S3 ViRGE/DX", diff --git a/src/vid_s3_virge.h b/src/vid_s3_virge.h index 3419b8657..2e8dfbe91 100644 --- a/src/vid_s3_virge.h +++ b/src/vid_s3_virge.h @@ -2,4 +2,5 @@ see COPYING for more details */ extern device_t s3_virge_device; +extern device_t s3_virge_988_device; extern device_t s3_virge_375_device; diff --git a/src/vid_sdac_ramdac.c b/src/vid_sdac_ramdac.c index 412e4836e..c1dad85d2 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/vid_sdac_ramdac.c @@ -25,7 +25,6 @@ int sdac_get_clock_divider(sdac_ramdac_t *ramdac) void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t *svga) { -// /*if (CS!=0xC000) */pclog("OUT RAMDAC %04X %02X %i %04X:%04X %i\n",addr,val,sdac_ramdac.magic_count,CS,pc, sdac_ramdac.rs2); switch (addr) { case 0x3C6: @@ -39,19 +38,18 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t * if (ramdac->magic_count == 4) { ramdac->command = val; -// pclog("RAMDAC command reg now %02X\n", val); switch (val >> 4) { case 0x2: case 0x3: case 0x8: case 0xa: svga->bpp = 15; break; case 0x4: case 0x9: case 0xe: svga->bpp = 24; break; case 0x5: case 0x6: case 0xc: svga->bpp = 16; break; - case 0x7: svga->bpp = 32; break; + case 0x7: case 0xd: svga->bpp = 32; break; case 0: case 1: default: svga->bpp = 8; break; } svga_recalctimings(svga); + pclog("RAMDAC: Mode: %i, BPP: %i\n", val >> 4, svga->bpp); } - //ramdac->magic_count = 0; break; case 0x3C7: @@ -71,7 +69,6 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t * if (!ramdac->reg_ff) ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0xff00) | val; else ramdac->regs[ramdac->windex] = (ramdac->regs[ramdac->windex] & 0x00ff) | (val << 8); ramdac->reg_ff = !ramdac->reg_ff; -// pclog("RAMDAC reg %02X now %04X\n", ramdac->windex, ramdac->regs[ramdac->windex]); if (!ramdac->reg_ff) ramdac->windex++; } break; @@ -82,7 +79,6 @@ void sdac_ramdac_out(uint16_t addr, uint8_t val, sdac_ramdac_t *ramdac, svga_t * uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) { uint8_t temp; -// /*if (CS!=0xC000) */pclog("IN RAMDAC %04X %04X:%04X %i\n",addr,CS,pc, ramdac->rs2); switch (addr) { case 0x3C6: @@ -101,27 +97,15 @@ uint8_t sdac_ramdac_in(uint16_t addr, sdac_ramdac_t *ramdac, svga_t *svga) } return temp; case 0x3C7: -// if (ramdac->magic_count < 4) -// { ramdac->magic_count=0; -// break; -// } if (ramdac->rs2) return ramdac->rindex; break; case 0x3C8: -// if (ramdac->magic_count < 4) -// { ramdac->magic_count=0; -// break; -// } if (ramdac->rs2) return ramdac->windex; break; case 0x3C9: -// if (ramdac->magic_count < 4) -// { ramdac->magic_count=0; -// break; -// } if (ramdac->rs2) { if (!ramdac->reg_ff) temp = ramdac->regs[ramdac->rindex] & 0xff; @@ -144,7 +128,6 @@ float sdac_getclock(int clock, void *p) sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p; float t; int m, n1, n2; -// pclog("SDAC_Getclock %i %04X\n", clock, ramdac->regs[clock]); if (clock == 0) return 25175000.0; if (clock == 1) return 28322000.0; clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ @@ -152,6 +135,5 @@ float sdac_getclock(int clock, void *p) n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2; n2 = ((ramdac->regs[clock] >> 13) & 0x07); t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); -// pclog("SDAC clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2); return t; } diff --git a/src/vid_stg_ramdac.c b/src/vid_stg_ramdac.c index 7fbd69785..2aa3fee19 100644 --- a/src/vid_stg_ramdac.c +++ b/src/vid_stg_ramdac.c @@ -10,11 +10,9 @@ static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; -static int stg_state_indexed = 0; void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) { - int oldbpp = svga->bpp; if (ramdac->command & 0x8) { switch (ramdac->regs[3]) @@ -43,7 +41,6 @@ void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *svga) { int didwrite, old; - //if (CS!=0xC000) pclog("OUT RAMDAC %04X %02X %i %04X:%04X\n",addr,val,stg_ramdac.magic_count,CS,pc); switch (addr) { case 0x3c6: @@ -65,7 +62,6 @@ void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *sv stg_ramdac_set_bpp(svga, ramdac); } } - // pclog("Write RAMDAC command %02X\n",val); break; case 5: ramdac->index = (ramdac->index & 0xff00) | val; @@ -74,7 +70,6 @@ void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *sv ramdac->index = (ramdac->index & 0xff) | (val << 8); break; case 7: - // pclog("Write RAMDAC reg %02X %02X\n", ramdac->index, val); if (ramdac->index < 0x100) { ramdac->regs[ramdac->index] = val; @@ -96,8 +91,7 @@ void stg_ramdac_out(uint16_t addr, uint8_t val, stg_ramdac_t *ramdac, svga_t *sv uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) { - uint8_t temp; - //if (CS!=0xC000) pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); + uint8_t temp = 0xff; switch (addr) { case 0x3c6: @@ -116,7 +110,6 @@ uint8_t stg_ramdac_in(uint16_t addr, stg_ramdac_t *ramdac, svga_t *svga) temp = ramdac->index >> 8; break; case 7: - // pclog("Read RAMDAC index %04X\n",ramdac->index); switch (ramdac->index) { case 0: @@ -151,7 +144,6 @@ float stg_getclock(int clock, void *p) float t; int m, n1, n2; float d; -// pclog("STG_Getclock %i %04X\n", clock, ramdac->regs[clock]); if (clock == 0) return 25175000.0; if (clock == 1) return 28322000.0; clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/ @@ -173,8 +165,6 @@ float stg_getclock(int clock, void *p) d = 8.0; break; } - // t = (14318184.0 * ((float)m / (float)n1)) / (float)(1 << n2); t = (14318184.0 * ((float)m / d)) / (float)n1; -// pclog("STG clock %i %i %i %f %04X %f %i\n", m, n1, n2, t, ramdac->regs[2], 14318184.0 * ((float)m / (float)n1), 1 << n2); return t; } diff --git a/src/vid_svga.c b/src/vid_svga.c index 2e2b34da7..9db83a709 100644 --- a/src/vid_svga.c +++ b/src/vid_svga.c @@ -21,9 +21,7 @@ extern uint8_t edatlookup[4][4]; uint8_t svga_rotate[8][256]; -static uint8_t mask_gdc[9] = {0x0F, 0x0F, 0x0F, 0x1F, 0x03, 0x7B, 0xFF, 0x0F, 0xFF}; uint8_t mask_crtc[0x19] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0xEF, 0xFF}; -static uint8_t mask_seq[5] = {0x03, 0x3D, 0x0F, 0x3F, 0x0E}; /*Primary SVGA device. As multiple video cards are not yet supported this is the only SVGA device.*/ @@ -31,8 +29,6 @@ static svga_t *svga_pri; static int old_overscan_color = 0; -static int sense_switches = 0xE; - svga_t *svga_pointer; svga_t *svga_get_pri() @@ -52,21 +48,23 @@ typedef union pci_bar uint8_t bytes[2]; } ichar; +#ifdef DEV_BRANCH ichar char12x24[65536][48]; uint8_t charedit_on = 0; ichar charcode; uint8_t charmode = 0; uint8_t charptr = 0; uint8_t charsettings = 0xEE; +#endif void svga_out(uint16_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; int c; uint8_t o; - // printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); switch (addr) { +#ifdef DEV_BRANCH case 0x32CB: printf("Write 32CB: %04X\n", val); charedit_on = (val & 0x10) ? 1 : 0; @@ -81,7 +79,6 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 0x22CF: printf("Write 22CF: %04X\n", val); - // if (!charedit_on) return; switch(charmode) { case 1: case 2: @@ -100,6 +97,7 @@ void svga_out(uint16_t addr, uint8_t val, void *p) case 0x22CA: case 0x22CE: case 0x32CA: printf("OUT SVGA %03X %02X %04X:%04X\n",addr,val,CS,cpu_state.pc); return; +#endif case 0x3C0: case 0x3C1: @@ -127,7 +125,6 @@ void svga_out(uint16_t addr, uint8_t val, void *p) if (svga->attrregs[0x10] & 0x80) svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 3) << 4); else svga->egapal[c] = (svga->attrregs[c] & 0x3f); - // if (svga->attrregs[0x10] & 0x40) svga->egapal[c] |= ((svga->attrregs[0x14] & 0x0c) << 4); /* It seems these should always be enabled. */ svga->egapal[c] |= ((svga->attrregs[0x14] & 0x0c) << 4); } @@ -150,15 +147,13 @@ void svga_out(uint16_t addr, uint8_t val, void *p) svga->miscout = val; svga->enablevram = (val & 2) ? 1 : 0; svga->oddeven_page = (val & 0x20) ? 0 : 1; - svga->vidclock = val & 4;// printf("3C2 write %02X\n",val); + svga->vidclock = val & 4; if (val & 1) { -// pclog("Remove mono handler\n"); io_removehandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); } else { -// pclog("Set mono handler\n"); io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); } svga_recalctimings(svga); @@ -269,11 +264,9 @@ void svga_out(uint16_t addr, uint8_t val, void *p) svga->chain2_read = val & 0x10; break; case 6: -// pclog("svga_out recalcmapping %p\n", svga); svga->oddeven_chain = (val & 2) ? 1 : 0; if ((svga->gdcreg[6] & 0xc) != (val & 0xc)) { -// pclog("Write mapping %02X\n", val); switch (val&0xC) { case 0x0: /*128k at A0000*/ @@ -349,22 +342,20 @@ uint8_t svga_in(uint16_t addr, void *p) { svga_t *svga = (svga_t *)p; uint8_t temp; - // if (addr!=0x3da) pclog("Read port %04X\n",addr); switch (addr) { +#ifdef DEV_BRANCH case 0x22CA: pclog("Read port %04X\n", addr); return 0xAA; case 0x22CB: pclog("Read port %04X\n", addr); - // return charmode; return 0xF0 | (charmode & 0x1F); case 0x22CE: pclog("Read port %04X\n", addr); return 0xCC; case 0x22CF: /* Read character bitmap */ pclog("Read port %04X\n", addr); - // if (!charedit_on) return 0xFF; switch(charmode) { case 1: case 2: @@ -384,7 +375,7 @@ uint8_t svga_in(uint16_t addr, void *p) case 0x32CB: pclog("Read port %04X\n", addr); return 0xEE; - // return 0xEE | (charedit_on ? 0x10 : 0); +#endif case 0x3C0: return svga->attraddr | svga->attr_palette_enable; @@ -470,7 +461,6 @@ uint8_t svga_in(uint16_t addr, void *p) svga->cgastat ^= 0x30; return svga->cgastat; } -// printf("Bad EGA read %04X %04X:%04X\n",addr,cs>>4,pc); return 0xFF; } @@ -496,7 +486,6 @@ void svga_recalctimings(svga_t *svga) { double crtcconst; double _dispontime, _dispofftime, disptime; - int hdisp_old; svga->vtotal = svga->crtc[6]; svga->dispend = svga->crtc[0x12]; @@ -632,8 +621,6 @@ void svga_recalctimings(svga_t *svga) } } -// pclog("svga_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", svga_render, svga_render_text_40, svga_render_text_80, svga_render_8bpp_lowres, svga_render_8bpp_highres, svga_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); - svga->linedbl = svga->crtc[9] & 0x80; svga->rowcount = svga->crtc[9] & 31; if (svga->recalctimings_ex) @@ -647,7 +634,6 @@ void svga_recalctimings(svga_t *svga) disptime = svga->htotal; _dispontime = svga->hdisp_time; -// printf("Disptime %f dispontime %f hdisp %i\n",disptime,dispontime,crtc[1]*8); if (svga->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; @@ -703,7 +689,6 @@ void svga_poll(void *p) if (!svga->linepos) { -// if (!(vc & 15)) pclog("VC %i %i\n", vc, GetTickCount()); if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { svga->hwcursor_on = 64 - svga->hwcursor_latch.yoff; @@ -728,7 +713,6 @@ void svga_poll(void *p) } svga->vidtime += svga->dispofftime; -// if (output) printf("Display off %f\n",vidtime); svga->cgastat |= 1; svga->linepos = 1; @@ -771,27 +755,21 @@ void svga_poll(void *p) svga->lastline = svga->displine; } -// pclog("%03i %06X %06X\n",displine,ma,vrammask); svga->displine++; if (svga->interlace) svga->displine++; if ((svga->cgastat & 8) && ((svga->displine & 15) == (svga->crtc[0x11] & 15)) && svga->vslines) { -// printf("Vsync off at line %i\n",displine); svga->cgastat &= ~8; } svga->vslines++; if (svga->displine > 1500) svga->displine = 0; -// pclog("Col is %08X %08X %08X %i %i %08X\n",((uint32_t *)buffer32->line[displine])[320],((uint32_t *)buffer32->line[displine])[321],((uint32_t *)buffer32->line[displine])[322], -// displine, vc, ma); } else { -// pclog("VC %i ma %05X\n", svga->vc, svga->ma); svga->vidtime += svga->dispontime; -// if (output) printf("Display on %f\n",vidtime); if (svga->dispon) svga->cgastat &= ~1; svga->hdisp_on = 0; @@ -830,14 +808,14 @@ void svga_poll(void *p) if (svga->vc == svga->split) { -// pclog("VC split\n"); svga->ma = svga->maback = 0; if (svga->attrregs[0x10] & 0x20) svga->scrollcache = 0; } if (svga->vc == svga->dispend) { -// pclog("VC dispend\n"); + if (svga->vblank_start) + svga->vblank_start(svga); svga->dispon=0; if (svga->crtc[10] & 0x20) svga->cursoron = 0; else svga->cursoron = svga->blink & 16; @@ -850,14 +828,12 @@ void svga_poll(void *p) if (svga->changedvram[x]) svga->changedvram[x]--; } -// memset(changedvram,0,2048); if (svga->fullchange) svga->fullchange--; } if (svga->vc == svga->vsyncstart) { int wx, wy; -// pclog("VC vsync %i %i\n", svga->firstline_draw, svga->lastline_draw); svga->dispon=0; svga->cgastat |= 8; x = svga->hdisp; @@ -894,7 +870,6 @@ void svga_poll(void *p) svga->video_res_x = wx; svga->video_res_y = wy + 1; -// pclog("%i %i %i\n", svga->video_res_x, svga->video_res_y, svga->lowres); if (!(svga->gdcreg[6] & 1)) /*Text mode*/ { svga->video_res_x /= (svga->seqregs[1] & 1) ? 8 : 9; @@ -918,16 +893,9 @@ void svga_poll(void *p) case 0x40: case 0x60: svga->video_bpp = svga->bpp; break; } } -// if (svga_interlace && oddeven) ma=maback=ma+(svga_rowoffset<<2); - -// pclog("Addr %08X vson %03X vsoff %01X %02X %02X %02X %i %i\n",ma,svga_vsyncstart,crtc[0x11]&0xF,crtc[0xD],crtc[0xC],crtc[0x33], svga_interlace, oddeven); } if (svga->vc == svga->vtotal) { -// pclog("VC vtotal\n"); - - -// printf("Frame over at line %i %i %i %i\n",displine,vc,svga_vsyncstart,svga_dispend); svga->vc = 0; svga->sc = 0; svga->dispon = 1; @@ -940,15 +908,10 @@ void svga_poll(void *p) svga->overlay_on = 0; svga->overlay_latch = svga->overlay; -// pclog("Latch HWcursor addr %08X\n", svga_hwcursor_latch.addr); - -// pclog("ADDR %08X\n",hwcursor_addr); } if (svga->sc == (svga->crtc[10] & 31)) svga->con = 1; } -// printf("2 %i\n",svga_vsyncstart); -//pclog("svga_poll %i %i %i %i %i %i %i\n", ins, svga->dispofftime, svga->dispontime, svga->vidtime, cyc_total, svga->linepos, svga->vc); } int svga_init(svga_t *svga, void *p, int memsize, @@ -993,7 +956,6 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->video_out = video_out; svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; -// _svga_recalctimings(svga); mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga); @@ -1066,7 +1028,6 @@ void svga_write(uint32_t addr, uint8_t val, void *p) { addr<<=2; } - // addr %= svga->vram_limit; if (addr >= svga->vram_limit) return; @@ -1132,7 +1093,6 @@ void svga_write(uint32_t addr, uint8_t val, void *p) if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); } break; case 2: @@ -1238,19 +1198,12 @@ uint8_t svga_read(uint32_t addr, void *p) cycles_lost += video_timing_b; egareads++; -// pclog("Readega %06X ",addr); addr &= svga->banked_mask; addr += svga->read_bank; - // latch_addr = (addr << 2) % svga->vram_limit; latch_addr = svga_mask_addr(addr << 2, svga); - // latch_addr = (addr << 2); - -// pclog("%05X %i %04X:%04X %02X %02X %i\n",addr,svga->chain4,CS,pc, vram[addr & 0x7fffff], vram[(addr << 2) & 0x7fffff], svga->readmode); -// pclog("%i\n", svga->readmode); if (svga->chain4 || svga->fb_only) { - // addr %= svga->vram_limit; if (addr >= svga->vram_limit) return 0xff; return svga->vram[svga_mask_addr(addr, svga)]; @@ -1263,9 +1216,7 @@ uint8_t svga_read(uint32_t addr, void *p) } else addr<<=2; - - // addr %= svga->vram_limit; - + if (addr >= svga->vram_limit) return 0xff; @@ -1297,7 +1248,6 @@ uint8_t svga_read(uint32_t addr, void *p) temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; return ~(temp | temp2 | temp3 | temp4); } -//pclog("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); return svga->vram[addr | readplane]; } @@ -1405,7 +1355,6 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) if (writemask2 & 8) svga->vram[addr | 0x3] = (vald & svga->gdcreg[8]) ^ svga->ld; break; } -// pclog("- %02X %02X %02X %02X %08X\n",vram[addr],vram[addr|0x1],vram[addr|0x2],vram[addr|0x3],addr); } break; case 2: @@ -1497,7 +1446,6 @@ uint8_t svga_read_linear(uint32_t addr, void *p) { svga_t *svga = (svga_t *)p; uint8_t temp, temp2, temp3, temp4; - uint32_t latch_addr; int readplane = svga->readplane; cycles -= video_timing_b; @@ -1506,8 +1454,6 @@ uint8_t svga_read_linear(uint32_t addr, void *p) egareads++; addr -= svga->linear_base; - - latch_addr = svga_mask_addr(addr << 2, svga); if (svga->chain4 || svga->fb_only) { @@ -1517,7 +1463,6 @@ uint8_t svga_read_linear(uint32_t addr, void *p) } if (addr >= svga->vram_limit) return 0xff; - // return svga->vram[svga_mask_addr(addr, svga)]; return svga->vram[addr]; } else if (svga->chain2_read) @@ -1537,8 +1482,6 @@ uint8_t svga_read_linear(uint32_t addr, void *p) if (addr >= svga->vram_limit) return 0xff; - // addr = svga_mask_addr(addr, svga); - svga->la = svga->vram[addr]; svga->lb = svga->vram[addr | 0x1]; svga->lc = svga->vram[addr | 0x2]; @@ -1559,7 +1502,6 @@ uint8_t svga_read_linear(uint32_t addr, void *p) temp4 ^= (svga->colourcompare & 8) ? 0xff : 0; return ~(temp | temp2 | temp3 | temp4); } -//printf("Read %02X %04X %04X\n",vram[addr|svga->readplane],addr,svga->readplane); return svga->vram[addr | readplane]; } @@ -1569,10 +1511,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) int x_add = (enable_overscan) ? 16 : 0; uint32_t *p, *q, i, j; -// pclog("svga_doblit start\n"); svga->frames++; -// pclog("doblit %i %i\n", y1, y2); -// pclog("svga_doblit %i %i\n", wx, svga->hdisp); if ((xsize > 2032) || (ysize > 2032)) { @@ -1658,7 +1597,6 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) } video_blit_memtoscreen(32, 0, y1, y2 + y_add, xsize + x_add, ysize + y_add); -// pclog("svga_doblit end\n"); } void svga_writew(uint32_t addr, uint16_t val, void *p) @@ -1734,10 +1672,8 @@ uint16_t svga_readw(uint32_t addr, void *p) cycles -= video_timing_w; cycles_lost += video_timing_w; -// pclog("Readw %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; if ((!svga->extvram) && (addr >= 0x10000)) return 0xffff; -// pclog("%08X %04X\n", addr, *(uint16_t *)&vram[addr]); if (addr >= svga->vram_limit) return 0xffff; return *(uint16_t *)&svga->vram[addr]; @@ -1760,10 +1696,8 @@ uint32_t svga_readl(uint32_t addr, void *p) cycles -= video_timing_l; cycles_lost += video_timing_l; -// pclog("Readl %05X ", addr); addr = (addr & svga->banked_mask) + svga->read_bank; if ((!svga->extvram) && (addr >= 0x10000)) return 0xffffffff; -// pclog("%08X %08X\n", addr, *(uint32_t *)&vram[addr]); if (addr >= svga->vram_limit) return 0xffffffff; return *(uint32_t *)&svga->vram[addr]; @@ -1793,7 +1727,6 @@ void svga_writew_linear(uint32_t addr, uint16_t val, void *p) { addr &= 0x7fffff; } - // if ((!svga->extvram) && (addr >= 0x10000)) return; if (addr >= svga->vram_limit) return; svga->changedvram[addr >> 12] = changeframecount; @@ -1826,7 +1759,6 @@ void svga_writel_linear(uint32_t addr, uint32_t val, void *p) { addr &= 0x7fffff; } - // if ((!svga->extvram) && (addr >= 0x10000)) return; if (addr >= svga->vram_limit) return; svga->changedvram[addr >> 12] = changeframecount; @@ -1852,7 +1784,6 @@ uint16_t svga_readw_linear(uint32_t addr, void *p) { addr &= 0x7fffff; } - // if ((!svga->extvram) && (addr >= 0x10000)) return 0xffff; if (addr >= svga->vram_limit) return 0xffff; return *(uint16_t *)&svga->vram[addr]; @@ -1877,7 +1808,6 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) { addr &= 0x7fffff; } - // if ((!svga->extvram) && (addr >= 0x10000)) return 0xffffffff; if (addr >= svga->vram_limit) return 0xffffffff; return *(uint32_t *)&svga->vram[addr]; diff --git a/src/vid_svga.h b/src/vid_svga.h index dce4278be..f7c05906f 100644 --- a/src/vid_svga.h +++ b/src/vid_svga.h @@ -91,8 +91,9 @@ typedef struct svga_t int ena; int x, y; int xoff, yoff; - int ysize; + int xsize, ysize; uint32_t addr; + uint32_t pitch; int v_acc, h_acc; } hwcursor, hwcursor_latch, overlay, overlay_latch; @@ -112,6 +113,8 @@ typedef struct svga_t void (*overlay_draw)(struct svga_t *svga, int displine); + void (*vblank_start)(struct svga_t *svga); + /*If set then another device is driving the monitor output and the SVGA card should not attempt to display anything */ int override; @@ -157,3 +160,10 @@ void svga_set_override(svga_t *svga, int val); void svga_set_ramdac_type(svga_t *svga, int type); extern uint8_t mask_crtc[0x19]; + +void svga_close(svga_t *svga); + +uint32_t svga_mask_addr(uint32_t addr, svga_t *svga); +uint32_t svga_mask_changedaddr(uint32_t addr, svga_t *svga); + +void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); diff --git a/src/vid_svga_render.c b/src/vid_svga_render.c index 56907c4ba..cf6caac68 100644 --- a/src/vid_svga_render.c +++ b/src/vid_svga_render.c @@ -531,8 +531,6 @@ void svga_render_8bpp_lowres(svga_t *svga) p += 8; } } - - // return NULL; } void svga_render_8bpp_highres(svga_t *svga) @@ -570,8 +568,6 @@ void svga_render_8bpp_highres(svga_t *svga) p += 8; } } - - // return NULL; } void svga_render_15bpp_lowres(svga_t *svga) diff --git a/src/vid_tandy.c b/src/vid_tandy.c index 0cc52235d..e9deb6798 100644 --- a/src/vid_tandy.c +++ b/src/vid_tandy.c @@ -22,7 +22,7 @@ typedef struct tandy_t int array_index; uint8_t array[32]; - int memctrl;//=-1; + int memctrl; uint32_t base; uint8_t mode, col; uint8_t stat; @@ -56,7 +56,6 @@ void tandy_out(uint16_t addr, uint8_t val, void *p) { tandy_t *tandy = (tandy_t *)p; uint8_t old; -// pclog("Tandy OUT %04X %02X\n",addr,val); switch (addr) { case 0x3d4: @@ -103,7 +102,6 @@ void tandy_out(uint16_t addr, uint8_t val, void *p) uint8_t tandy_in(uint16_t addr, void *p) { tandy_t *tandy = (tandy_t *)p; -// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); switch (addr) { case 0x3d4: @@ -123,28 +121,24 @@ void tandy_recalcaddress(tandy_t *tandy) tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base]; tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base]; tandy->b8000_mask = 0x7fff; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base); } else { tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base]; tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base]; tandy->b8000_mask = 0x3fff; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base); } } void tandy_ram_write(uint32_t addr, uint8_t val, void *p) { tandy_t *tandy = (tandy_t *)p; -// pclog("Tandy RAM write %05X %02X %04X:%04X\n",addr,val,CS,pc); ram[tandy->base + (addr & 0x1ffff)] = val; } uint8_t tandy_ram_read(uint32_t addr, void *p) { tandy_t *tandy = (tandy_t *)p; -// pclog("Tandy RAM read %05X %02X %04X:%04X\n",addr,ram[tandy->base + (addr & 0x1ffff)],CS,pc); return ram[tandy->base + (addr & 0x1ffff)]; } @@ -155,7 +149,6 @@ void tandy_write(uint32_t addr, uint8_t val, void *p) return; egawrites++; -// pclog("Tandy VRAM write %05X %02X %04X:%04X %04X:%04X\n",addr,val,CS,pc,DS,SI); tandy->b8000[addr & tandy->b8000_mask] = val; } @@ -166,7 +159,6 @@ uint8_t tandy_read(uint32_t addr, void *p) return 0xff; egareads++; -// pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc); return tandy->b8000[addr & tandy->b8000_mask]; } @@ -190,28 +182,8 @@ void tandy_recalctimings(tandy_t *tandy) tandy->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } - -static int ntsc_col[8][8]= -{ - {0,0,0,0,0,0,0,0}, /*Black*/ - {0,0,1,1,1,1,0,0}, /*Blue*/ - {1,0,0,0,0,1,1,1}, /*Green*/ - {0,0,0,0,1,1,1,1}, /*Cyan*/ - {1,1,1,1,0,0,0,0}, /*Red*/ - {0,1,1,1,1,0,0,0}, /*Magenta*/ - {1,1,0,0,0,0,1,1}, /*Yellow*/ - {1,1,1,1,1,1,1,1} /*White*/ -}; - -/*static int cga4pal[8][4]= -{ - {0,2,4,6},{0,3,5,7},{0,3,4,7},{0,3,4,7}, - {0,10,12,14},{0,11,13,15},{0,11,12,15},{0,11,12,15} -};*/ - void tandy_poll(void *p) { -// int *cgapal=cga4pal[((tandy->col&0x10)>>2)|((cgamode&4)>>1)|((cgacol&0x20)>>5)]; tandy_t *tandy = (tandy_t *)p; uint16_t ca = (tandy->crtc[15] | (tandy->crtc[14] << 8)) & 0x3fff; int drawcursor; @@ -222,14 +194,8 @@ void tandy_poll(void *p) int cols[4]; int col; int oldsc; - int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot; - int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot; - int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot; - int r, g, b; if (!tandy->linepos) { -// cgapal[0]=tandy->col&15; -// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); tandy->vidtime += tandy->dispofftime; tandy->stat |= 1; tandy->linepos = 1; @@ -242,7 +208,6 @@ void tandy_poll(void *p) { tandy->firstline = tandy->displine; video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); } tandy->lastline = tandy->displine; cols[0] = (tandy->array[2] & 0xf) + 16; @@ -267,8 +232,6 @@ void tandy_poll(void *p) else buffer->line[tandy->displine][c + (tandy->crtc[1] << 4) + 8] = (tandy->col & 15) + 16; } } -// printf("X %i %i\n",c+(crtc[1]<<4)+8,c+(crtc[1]<<3)+8); -// printf("Drawing %i %i %i\n",tandy->displine,vc,sc); if ((tandy->array[3] & 0x10) && (tandy->mode & 1)) /*320x200x16*/ { for (x = 0; x < tandy->crtc[1]; x++) @@ -356,7 +319,6 @@ void tandy_poll(void *p) for (c = 0; c < 8; c++) buffer->line[tandy->displine][(x << 3) + c + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } -// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma); if (drawcursor) { for (c = 0; c < 8; c++) @@ -485,7 +447,6 @@ void tandy_poll(void *p) if (tandy->vc == tandy->crtc[7] && !tandy->sc) { tandy->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); } tandy->displine++; if (tandy->displine >= 360) @@ -503,7 +464,6 @@ void tandy_poll(void *p) if (!tandy->vsynctime) { tandy->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); } } if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) @@ -522,24 +482,19 @@ void tandy_poll(void *p) tandy->dispon = 1; tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; tandy->sc = 0; -// printf("Display on!\n"); } } else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1))) { tandy->maback = tandy->ma; -// con=0; -// coff=0; tandy->sc = 0; oldvc = tandy->vc; tandy->vc++; tandy->vc &= 127; -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); if (tandy->vc == tandy->crtc[6]) tandy->dispon = 0; if (oldvc == tandy->crtc[4]) { -// printf("Display over at %i\n",tandy->displine); tandy->vc = 0; tandy->vadj = tandy->crtc[5]; if (!tandy->vadj) @@ -548,18 +503,14 @@ void tandy_poll(void *p) tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; if ((tandy->crtc[10] & 0x60) == 0x20) tandy->cursoron = 0; else tandy->cursoron = tandy->blink & 16; -// printf("CRTC10 %02X %i\n",crtc[10],cursoron); } if (tandy->vc == tandy->crtc[7]) { tandy->dispon = 0; tandy->displine = 0; - tandy->vsynctime = 16;//(crtc[3]>>4)+1; -// printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); -// tandy->stat|=8; + tandy->vsynctime = 16; if (tandy->crtc[7]) { -// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; else x = (tandy->crtc[1] << 4) + 16; tandy->lastline++; @@ -567,13 +518,10 @@ void tandy_poll(void *p) { xsize = x; ysize = tandy->lastline - tandy->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; updatewindowsize(xsize, (ysize << 1) + 16); } -// printf("Blit %i %i\n",firstline,lastline); -//printf("Xsize is %i\n",xsize); if (tandy->composite) video_blit_memtoscreen(0, tandy->firstline-4, 0, (tandy->lastline - tandy->firstline) + 8, xsize, (tandy->lastline - tandy->firstline) + 8); @@ -685,27 +633,21 @@ device_t tandy_device = static device_config_t tandy_config[] = { { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .selection = + "display_type", "Display type", CONFIG_SELECTION, "", TANDY_RGB, { { - .description = "RGB", - .value = TANDY_RGB + "RGB", TANDY_RGB }, { - .description = "Composite", - .value = TANDY_COMPOSITE + "Composite", TANDY_COMPOSITE }, { - .description = "" + "" } - }, - .default_int = TANDY_RGB + } }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_tandysl.c b/src/vid_tandysl.c index 48d53d496..0ad656aaf 100644 --- a/src/vid_tandysl.c +++ b/src/vid_tandysl.c @@ -22,7 +22,7 @@ typedef struct tandysl_t int array_index; uint8_t array[32]; - int memctrl;//=-1; + int memctrl; uint32_t base; uint8_t mode, col; uint8_t stat; @@ -60,17 +60,14 @@ static void tandysl_out(uint16_t addr, uint8_t val, void *p) { tandysl_t *tandy = (tandysl_t *)p; uint8_t old; -// pclog("TandySL OUT %04X %02X\n",addr,val); switch (addr) { case 0x3d4: tandy->crtcreg = val & 0x1f; return; case 0x3d5: -// pclog("Write CRTC R%02x %02x ",tandy->crtcreg, val); old = tandy->crtc[tandy->crtcreg]; tandy->crtc[tandy->crtcreg] = val & crtcmask[tandy->crtcreg]; -// pclog("now %02x\n", tandy->crtc[tandy->crtcreg]); if (old != val) { if (tandy->crtcreg < 0xe || tandy->crtcreg > 0x10) @@ -101,7 +98,6 @@ static void tandysl_out(uint16_t addr, uint8_t val, void *p) break; case 0x3df: tandy->memctrl = val; -// pclog("tandy 3df write %02x\n", val); tandysl_recalcaddress(tandy); break; case 0x65: @@ -123,7 +119,6 @@ static void tandysl_out(uint16_t addr, uint8_t val, void *p) static uint8_t tandysl_in(uint16_t addr, void *p) { tandysl_t *tandy = (tandysl_t *)p; -// if (addr!=0x3DA) pclog("Tandy IN %04X\n",addr); switch (addr) { case 0x3d4: @@ -133,7 +128,6 @@ static uint8_t tandysl_in(uint16_t addr, void *p) case 0x3da: return tandy->stat; } -// pclog("Bad Tandy IN %04x\n", addr); return 0xFF; } @@ -149,13 +143,11 @@ static void tandysl_recalcaddress(tandysl_t *tandy) { tandy->vram = &ram[((tandy->memctrl & 0x06) << 14) + tandy->base]; tandy->b8000 = &ram[((tandy->memctrl & 0x30) << 11) + tandy->base]; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x6)<<14)+tandy->base,((tandy->memctrl&0x30)<<11)+tandy->base); } else { tandy->vram = &ram[((tandy->memctrl & 0x07) << 14) + tandy->base]; tandy->b8000 = &ram[((tandy->memctrl & 0x38) << 11) + tandy->base]; -// printf("VRAM at %05X B8000 at %05X\n",((tandy->memctrl&0x7)<<14)+tandy->base,((tandy->memctrl&0x38)<<11)+tandy->base); if ((tandy->memctrl & 0x38) == 0x38) tandy->b8000_limit = 0x4000; } @@ -167,40 +159,32 @@ static void tandysl_recalcmapping(tandysl_t *tandy) io_removehandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); if (tandy->planar_ctrl & 4) { -// pclog("Enable VRAM mapping\n"); mem_mapping_enable(&tandy->mapping); if (tandy->array[5] & 1) { -// pclog("Tandy mapping at A0000 %p %p\n", tandy_ram_write, tandy_write); mem_mapping_set_addr(&tandy->mapping, 0xa0000, 0x10000); } else { -// pclog("Tandy mapping at B8000\n"); mem_mapping_set_addr(&tandy->mapping, 0xb8000, 0x8000); } -// mem_mapping_enable(&tandy->vram_mapping); io_sethandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); } else { -// pclog("Disable VRAM mapping\n"); mem_mapping_disable(&tandy->mapping); -// mem_mapping_disable(&tandy->vram_mapping); io_removehandler(0x03d0, 0x0010, tandysl_in, NULL, NULL, tandysl_out, NULL, NULL, tandy); } } static void tandysl_ram_write(uint32_t addr, uint8_t val, void *p) { tandysl_t *tandy = (tandysl_t *)p; -// pclog("Tandy RAM write %05X %02X %04X:%04X %08x\n",addr,val,CS,pc, tandy->base); ram[tandy->base + (addr & 0x1ffff)] = val; } static uint8_t tandysl_ram_read(uint32_t addr, void *p) { tandysl_t *tandy = (tandysl_t *)p; -// if (!nopageerrors) pclog("Tandy RAM read %05X %02X %04X:%04X\n",addr,ram[tandy->base + (addr & 0x1ffff)],CS,pc); return ram[tandy->base + (addr & 0x1ffff)]; } @@ -211,7 +195,6 @@ static void tandysl_write(uint32_t addr, uint8_t val, void *p) return; egawrites++; -// pclog("Tandy VRAM write %05X %02X %04X:%04X %02x %x\n",addr,val,CS,pc,tandy->array[5], (uintptr_t)&tandy->b8000[addr & 0xffff] - (uintptr_t)ram); if (tandy->array[5] & 1) tandy->b8000[addr & 0xffff] = val; else @@ -229,7 +212,6 @@ static uint8_t tandysl_read(uint32_t addr, void *p) return 0xff; egareads++; -// if (!nopageerrors) pclog("Tandy VRAM read %05X %02X %04X:%04X\n",addr,tandy->b8000[addr&0x7FFF],CS,pc); if (tandy->array[5] & 1) return tandy->b8000[addr & 0xffff]; if ((addr & 0x7fff) >= tandy->b8000_limit) @@ -273,9 +255,6 @@ static void tandysl_poll(void *p) if (!tandy->linepos) { -// pclog("tandy_poll vc=%i sc=%i dispon=%i\n", tandy->vc, tandy->sc, tandy->dispon); -// cgapal[0]=tandy->col&15; -// printf("Firstline %i Lastline %i tandy->displine %i\n",firstline,lastline,tandy->displine); tandy->vidtime += tandy->dispofftime; tandy->stat |= 1; tandy->linepos = 1; @@ -288,7 +267,6 @@ static void tandysl_poll(void *p) { tandy->firstline = tandy->displine; video_wait_for_buffer(); -// printf("Firstline %i\n",firstline); } tandy->lastline = tandy->displine; cols[0] = (tandy->array[2] & 0xf) + 16; @@ -413,7 +391,6 @@ static void tandysl_poll(void *p) for (c = 0; c < 8; c++) buffer->line[tandy->displine][(x << 3) + c + 8] = cols[(fontdat[chr][tandy->sc & 7] & (1 << (c ^ 7))) ? 1 : 0]; } -// if (!((ma^(crtc[15]|(crtc[14]<<8)))&0x3FFF)) printf("Cursor match! %04X\n",ma); if (drawcursor) { for (c = 0; c < 8; c++) @@ -533,7 +510,6 @@ static void tandysl_poll(void *p) if (tandy->vc == tandy->crtc[7] && !tandy->sc) { tandy->stat |= 8; -// printf("VSYNC on %i %i\n",vc,sc); } tandy->displine++; if (tandy->displine >= 360) @@ -551,7 +527,6 @@ static void tandysl_poll(void *p) if (!tandy->vsynctime) { tandy->stat &= ~8; -// printf("VSYNC off %i %i\n",vc,sc); } } if (tandy->sc == (tandy->crtc[11] & 31) || ((tandy->crtc[8] & 3) == 3 && tandy->sc == ((tandy->crtc[11] & 31) >> 1))) @@ -573,28 +548,21 @@ static void tandysl_poll(void *p) else tandy->ma = tandy->maback = (tandy->crtc[13] | (tandy->crtc[12] << 8)) & 0x3fff; tandy->sc = 0; -// printf("Display on!\n"); } } else if (tandy->sc == tandy->crtc[9] || ((tandy->crtc[8] & 3) == 3 && tandy->sc == (tandy->crtc[9] >> 1))) { tandy->maback = tandy->ma; -// con=0; -// coff=0; tandy->sc = 0; oldvc = tandy->vc; tandy->vc++; tandy->vc &= 255; -// printf("VC %i %i %i %i %i\n",vc,crtc[4],crtc[6],crtc[7],tandy->dispon); if (tandy->vc == tandy->crtc[6]) { -// pclog("Display off\n"); tandy->dispon = 0; } if (oldvc == tandy->crtc[4]) { -// pclog("Display over\n"); -// printf("Display over at %i\n",tandy->displine); tandy->vc = 0; tandy->vadj = tandy->crtc[5]; if (!tandy->vadj) @@ -608,18 +576,14 @@ static void tandysl_poll(void *p) } if ((tandy->crtc[10] & 0x60) == 0x20) tandy->cursoron = 0; else tandy->cursoron = tandy->blink & 16; -// printf("CRTC10 %02X %i\n",crtc[10],cursoron); } if (tandy->vc == tandy->crtc[7]) { tandy->dispon = 0; tandy->displine = 0; - tandy->vsynctime = 16;//(crtc[3]>>4)+1; -// printf("tandy->vsynctime %i %02X\n",tandy->vsynctime,crtc[3]); -// tandy->stat|=8; + tandy->vsynctime = 16; if (tandy->crtc[7]) { -// printf("Lastline %i Firstline %i %i %i %i\n",lastline,firstline,lastline-firstline,crtc[1],xsize); if (tandy->mode & 1) x = (tandy->crtc[1] << 3) + 16; else x = (tandy->crtc[1] << 4) + 16; tandy->lastline++; @@ -627,13 +591,10 @@ static void tandysl_poll(void *p) { xsize = x; ysize = tandy->lastline - tandy->firstline; -// printf("Resize to %i,%i - R1 %i\n",xsize,ysize,crtc[1]); if (xsize < 64) xsize = 656; if (ysize < 32) ysize = 200; updatewindowsize(xsize, (ysize << 1) + 16); } -// printf("Blit %i %i\n",firstline,lastline); -//printf("Xsize is %i\n",xsize); video_blit_memtoscreen_8(0, tandy->firstline-4, xsize, (tandy->lastline - tandy->firstline) + 8); @@ -690,7 +651,6 @@ static void tandysl_poll(void *p) static void *tandysl_init() { - int c; tandysl_t *tandy = malloc(sizeof(tandysl_t)); memset(tandy, 0, sizeof(tandysl_t)); diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index d6ce6ad8b..f369c8370 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -7,6 +7,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "pci.h" #include "rom.h" #include "thread.h" #include "video.h" @@ -120,7 +121,6 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) uint8_t old; -// pclog("tgui_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -211,7 +211,6 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) val = (svga->crtc[7] & ~0x10) | (val & 0x10); old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; -// if (svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X\n", svga->crtcreg, val); if (old != val) { if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) @@ -253,11 +252,9 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) if (svga->gdcreg[0xf] & 4) { svga->write_bank = (val & 0x1f) * 65536; -// pclog("SVGAWBANK 3D8 %08X %04X:%04X\n",svgawbank,CS,pc); if (!(svga->gdcreg[0xf] & 1)) { svga->read_bank = (val & 0x1f) * 65536; -// pclog("SVGARBANK 3D8 %08X %04X:%04X\n",svgarbank,CS,pc); } } return; @@ -266,7 +263,6 @@ void tgui_out(uint16_t addr, uint8_t val, void *p) if ((svga->gdcreg[0xf] & 5) == 5) { svga->read_bank = (val & 0x1F) * 65536; -// pclog("SVGARBANK 3D9 %08X %04X:%04X\n",svgarbank,CS,pc); } return; @@ -287,8 +283,6 @@ uint8_t tgui_in(uint16_t addr, void *p) tgui_t *tgui = (tgui_t *)p; svga_t *svga = &tgui->svga; -// if (addr != 0x3da) pclog("tgui_in : %04X %04X:%04X\n", addr, CS,pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -296,15 +290,9 @@ uint8_t tgui_in(uint16_t addr, void *p) case 0x3C5: if ((svga->seqaddr & 0xf) == 0xb) { -// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); tgui->oldmode = 0; return 0xe3; /*TGUI9440AGi*/ } - if ((svga->seqaddr & 0xf) == 0xc) - { -// printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); -// return 0x20; /*2 DRAM banks*/ - } if ((svga->seqaddr & 0xf) == 0xd) { if (tgui->oldmode) return tgui->oldctrl2; @@ -355,10 +343,8 @@ void tgui_recalctimings(svga_t *svga) svga->lowres = !(svga->crtc[0x2a] & 0x40); - // svga->interlace = svga->crtc[0x1e] & 4; if (svga->crtc[0x1e] & 4) { - // svga->rowoffset >>= 1; svga->vtotal *= 2; svga->dispend *= 2; svga->vblankstart *= 2; @@ -397,20 +383,16 @@ void tgui_recalctimings(svga_t *svga) void tgui_recalcmapping(tgui_t *tgui) { svga_t *svga = &tgui->svga; - -// pclog("tgui_recalcmapping : %02X %02X\n", svga->crtc[0x21], svga->gdcreg[6]); if (svga->crtc[0x21] & 0x20) { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&tgui->linear_mapping, tgui->linear_base, tgui->linear_size); svga->linear_base = tgui->linear_base; -// pclog("Trident linear framebuffer at %08X - size %06X\n", tgui->linear_base, tgui->linear_size); mem_mapping_enable(&tgui->accel_mapping); } else { -// pclog("Write mapping %02X\n", val); mem_mapping_disable(&tgui->linear_mapping); mem_mapping_disable(&tgui->accel_mapping); switch (svga->gdcreg[6] & 0xC) @@ -454,7 +436,6 @@ void tgui_hwcursor_draw(svga_t *svga, int displine) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x80000000) ? 0xffffff : 0; else if (dat[1] & 0x80000000) ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; -// pclog("Plot %i, %i (%i %i) %04X %04X\n", offset, displine, x+xx, svga_hwcursor_on, dat[0], dat[1]); } offset++; @@ -467,9 +448,6 @@ void tgui_hwcursor_draw(svga_t *svga, int displine) uint8_t tgui_pci_read(int func, int addr, void *p) { tgui_t *tgui = (tgui_t *)p; - svga_t *svga = &tgui->svga; - -// pclog("Trident PCI read %08X\n", addr); switch (addr) { @@ -507,8 +485,6 @@ void tgui_pci_write(int func, int addr, uint8_t val, void *p) tgui_t *tgui = (tgui_t *)p; svga_t *svga = &tgui->svga; -// pclog("Trident PCI write %08X %02X\n", addr, val); - switch (addr) { case 0x12: @@ -569,6 +545,10 @@ void tgui_close(void *p) svga_close(&tgui->svga); + thread_kill(tgui->fifo_thread); + thread_destroy_event(tgui->wake_fifo_thread); + thread_destroy_event(tgui->fifo_not_full_event); + free(tgui); } @@ -658,7 +638,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } if (tgui->accel.flags & TGUI_SOLIDFILL) { -// pclog("SOLIDFILL\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) @@ -669,7 +648,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } else if (tgui->accel.flags & TGUI_PATMONO) { -// pclog("PATMONO\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) @@ -682,7 +660,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { if (tgui->accel.bpp == 0) { -// pclog("OTHER 8-bit\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) @@ -693,7 +670,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } else { -// pclog("OTHER 16-bit\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) @@ -703,15 +679,9 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } } } -/* for (y = 0; y < 8; y++) - { - if (count == -1) pclog("Pattern %i : %02X %02X %02X %02X %02X %02X %02X %02X\n", y, tgui->accel.tgui_pattern[y][0], tgui->accel.tgui_pattern[y][1], tgui->accel.tgui_pattern[y][2], tgui->accel.tgui_pattern[y][3], tgui->accel.tgui_pattern[y][4], tgui->accel.tgui_pattern[y][5], tgui->accel.tgui_pattern[y][6], tgui->accel.tgui_pattern[y][7]); - }*/ -// if (count == -1) pclog("Command %i %i %p\n", tgui->accel.command, TGUI_BITBLT, tgui); switch (tgui->accel.command) { case TGUI_BITBLT: -// if (count == -1) pclog("BITBLT src %i,%i dst %i,%i size %i,%i flags %04X\n", tgui->accel.src_x, tgui->accel.src_y, tgui->accel.dst_x, tgui->accel.dst_y, tgui->accel.size_x, tgui->accel.size_y, tgui->accel.flags); if (count == -1) { tgui->accel.src = tgui->accel.src_old = tgui->accel.src_x + (tgui->accel.src_y * tgui->accel.pitch); @@ -725,7 +695,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) case TGUI_SRCCPU: if (count == -1) { -// pclog("Blit start TGUI_SRCCPU\n"); if (svga->crtc[0x21] & 0x20) mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l); @@ -734,7 +703,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) } else count >>= 3; -// pclog("TGUI_SRCCPU\n"); while (count) { if (tgui->accel.bpp == 0) @@ -758,8 +726,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) WRITE(tgui->accel.dst, out); } -// pclog(" %i,%i %02X %02X %02X %02X\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out); - tgui->accel.src += xdir; tgui->accel.dst += xdir; tgui->accel.pat_x += xdir; @@ -780,7 +746,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { if (svga->crtc[0x21] & 0x20) { -// pclog("Blit end\n"); mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear); } return; @@ -795,15 +760,12 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) case TGUI_SRCMONO | TGUI_SRCCPU: if (count == -1) { -// pclog("Blit start TGUI_SRCMONO | TGUI_SRCCPU\n"); if (svga->crtc[0x21] & 0x20) mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, tgui_accel_write_fb_b, tgui_accel_write_fb_w, tgui_accel_write_fb_l); -// pclog(" %i\n", tgui->accel.command); if (tgui->accel.use_src) return; } -// pclog("TGUI_SRCMONO | TGUI_SRCCPU\n"); while (count) { src_dat = ((cpu_dat >> 31) ? tgui->accel.fg_col : tgui->accel.bg_col); @@ -819,7 +781,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) WRITE(tgui->accel.dst, out); } -// pclog(" %i,%i %02X %02X %02X %02X %i\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out, (!(tgui->accel.flags & TGUI_TRANSENA) || src_dat != trans_col)); cpu_dat <<= 1; tgui->accel.src += xdir; tgui->accel.dst += xdir; @@ -841,7 +802,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) { if (svga->crtc[0x21] & 0x20) { -// pclog("Blit end\n"); mem_mapping_set_handler(&tgui->linear_mapping, svga_read_linear, svga_readw_linear, svga_readl_linear, svga_write_linear, svga_writew_linear, svga_writel_linear); } return; @@ -866,7 +826,6 @@ void tgui_accel_command(int count, uint32_t cpu_dat, tgui_t *tgui) WRITE(tgui->accel.dst, out); } -// pclog(" %i,%i %02X %02X %02X %02X\n", tgui->accel.x, tgui->accel.y, src_dat,dst_dat,pat_dat, out); tgui->accel.src += xdir; tgui->accel.dst += xdir; @@ -914,7 +873,6 @@ static void tgui_accel_write_fifo(tgui_t *tgui, uint32_t addr, uint8_t val) case 0x27: /*ROP*/ tgui->accel.rop = val; tgui->accel.use_src = (val & 0x33) ^ ((val >> 2) & 0x33); -// pclog("Write ROP %02X %i\n", val, tgui->accel.use_src); break; case 0x28: /*Flags*/ @@ -1034,6 +992,9 @@ static void tgui_accel_write_fifo_fb_l(tgui_t *tgui, uint32_t addr, uint32_t val static void fifo_thread(void *param) { tgui_t *tgui = (tgui_t *)param; + uint64_t start_time; + uint64_t end_time; + fifo_entry_t *fifo; while (1) { @@ -1043,10 +1004,8 @@ static void fifo_thread(void *param) tgui->blitter_busy = 1; while (!FIFO_EMPTY) { - uint64_t start_time = timer_read(); - uint64_t end_time; - fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_read_idx & FIFO_MASK]; - uint32_t val = fifo->val; + start_time = timer_read(); + fifo = &tgui->fifo[tgui->fifo_read_idx & FIFO_MASK]; switch (fifo->addr_type & FIFO_TYPE) { @@ -1077,7 +1036,7 @@ static void fifo_thread(void *param) } } -static inline void wake_fifo_thread(tgui_t *tgui) +static __inline void wake_fifo_thread(tgui_t *tgui) { thread_set_event(tgui->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -1094,7 +1053,6 @@ static void tgui_wait_fifo_idle(tgui_t *tgui) static void tgui_queue(tgui_t *tgui, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &tgui->fifo[tgui->fifo_write_idx & FIFO_MASK]; - int c; if (FIFO_FULL) { @@ -1118,7 +1076,6 @@ static void tgui_queue(tgui_t *tgui, uint32_t addr, uint32_t val, uint32_t type) void tgui_accel_write(uint32_t addr, uint8_t val, void *p) { tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_write : %08X %02X %04X(%08X):%08X %02X\n", addr, val, CS,cs,pc, opcode); if ((addr & ~0xff) != 0xbff00) return; tgui_queue(tgui, addr, val, FIFO_WRITE_BYTE); @@ -1127,7 +1084,6 @@ void tgui_accel_write(uint32_t addr, uint8_t val, void *p) void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) { tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_write_w %08X %04X\n", addr, val); tgui_accel_write(addr, val, tgui); tgui_accel_write(addr + 1, val >> 8, tgui); } @@ -1135,7 +1091,6 @@ void tgui_accel_write_w(uint32_t addr, uint16_t val, void *p) void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) { tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_write_l %08X %08X\n", addr, val); tgui_accel_write(addr, val, tgui); tgui_accel_write(addr + 1, val >> 8, tgui); tgui_accel_write(addr + 2, val >> 16, tgui); @@ -1145,7 +1100,6 @@ void tgui_accel_write_l(uint32_t addr, uint32_t val, void *p) uint8_t tgui_accel_read(uint32_t addr, void *p) { tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_read : %08X\n", addr); if ((addr & ~0xff) != 0xbff00) return 0xff; if ((addr & 0xff) != 0x20) @@ -1245,14 +1199,12 @@ uint8_t tgui_accel_read(uint32_t addr, void *p) uint16_t tgui_accel_read_w(uint32_t addr, void *p) { tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_read_w %08X\n", addr); return tgui_accel_read(addr, tgui) | (tgui_accel_read(addr + 1, tgui) << 8); } uint32_t tgui_accel_read_l(uint32_t addr, void *p) { tgui_t *tgui = (tgui_t *)p; -// pclog("tgui_accel_read_l %08X\n", addr); return tgui_accel_read_w(addr, tgui) | (tgui_accel_read_w(addr + 2, tgui) << 16); } @@ -1260,7 +1212,6 @@ void tgui_accel_write_fb_b(uint32_t addr, uint8_t val, void *p) { svga_t *svga = (svga_t *)p; tgui_t *tgui = (tgui_t *)svga->p; -// pclog("tgui_accel_write_fb_b %08X %02X\n", addr, val); tgui_queue(tgui, addr, val, FIFO_WRITE_FB_BYTE); } @@ -1268,7 +1219,6 @@ void tgui_accel_write_fb_w(uint32_t addr, uint16_t val, void *p) { svga_t *svga = (svga_t *)p; tgui_t *tgui = (tgui_t *)svga->p; -// pclog("tgui_accel_write_fb_w %08X %04X\n", addr, val); tgui_queue(tgui, addr, val, FIFO_WRITE_FB_WORD); } @@ -1276,7 +1226,6 @@ void tgui_accel_write_fb_l(uint32_t addr, uint32_t val, void *p) { svga_t *svga = (svga_t *)p; tgui_t *tgui = (tgui_t *)svga->p; -// pclog("tgui_accel_write_fb_l %08X %08X\n", addr, val); tgui_queue(tgui, addr, val, FIFO_WRITE_FB_LONG); } @@ -1299,27 +1248,21 @@ void tgui_add_status_info(char *s, int max_len, void *p) static device_config_t tgui9440_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 2, { { - .description = "1 MB", - .value = 1 + "1 MB", 1 }, { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_tkd8001_ramdac.c b/src/vid_tkd8001_ramdac.c index de75edaaa..3d22d987c 100644 --- a/src/vid_tkd8001_ramdac.c +++ b/src/vid_tkd8001_ramdac.c @@ -8,12 +8,8 @@ #include "vid_svga.h" #include "vid_tkd8001_ramdac.h" -static int tkd8001_state=0; -static uint8_t tkd8001_ctrl; - void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) { -// pclog("OUT RAMDAC %04X %02X %04X:%04X\n",addr,val,CS,pc); switch (addr) { case 0x3C6: @@ -38,7 +34,6 @@ void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, sv } return; } - // tkd8001_state = 0; break; case 0x3C7: case 0x3C8: case 0x3C9: ramdac->state = 0; @@ -49,13 +44,11 @@ void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, sv uint8_t tkd8001_ramdac_in(uint16_t addr, tkd8001_ramdac_t *ramdac, svga_t *svga) { -// pclog("IN RAMDAC %04X %04X:%04X\n",addr,CS,pc); switch (addr) { case 0x3C6: if (ramdac->state == 4) { - //tkd8001_state = 0; return ramdac->ctrl; } ramdac->state++; diff --git a/src/vid_tvga.c b/src/vid_tvga.c index f5fa8f4bb..3e70422cb 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -53,7 +53,6 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) uint8_t old; -// pclog("tvga_out : %04X %02X %04X:%04X %i\n", addr, val, CS,pc, svga->bpp); if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -119,7 +118,6 @@ void tvga_out(uint16_t addr, uint8_t val, void *p) old = svga->crtc[svga->crtcreg]; val &= crtc_mask[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; -// if (svga->crtcreg != 0xC && svga->crtcreg != 0xE && svga->crtcreg != 0xF) pclog("CRTC R%02X = %02X %04X:%04X\n", svga->crtcreg, val, CS, pc); if (old != val) { if (svga->crtcreg < 0xE || svga->crtcreg > 0x10) @@ -158,8 +156,6 @@ uint8_t tvga_in(uint16_t addr, void *p) tvga_t *tvga = (tvga_t *)p; svga_t *svga = &tvga->svga; -// if (addr != 0x3da) pclog("tvga_in : %04X %04X:%04X\n", addr, CS,pc); - if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60; switch (addr) @@ -167,15 +163,9 @@ uint8_t tvga_in(uint16_t addr, void *p) case 0x3C5: if ((svga->seqaddr & 0xf) == 0xb) { -// printf("Read Trident ID %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); tvga->oldmode = 0; return 0x33; /*TVGA8900D*/ } - if ((svga->seqaddr & 0xf) == 0xc) - { -// printf("Read Trident Power Up 1 %04X:%04X %04X\n",CS,pc,readmemw(ss,SP)); -// return 0x20; /*2 DRAM banks*/ - } if ((svga->seqaddr & 0xf) == 0xd) { if (tvga->oldmode) return tvga->oldctrl2; @@ -213,8 +203,6 @@ static void tvga_recalcbanking(tvga_t *tvga) svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536; else svga->read_bank = svga->write_bank; - -// pclog("recalcbanking: write_bank=%08x read_bank=%08x GDC[E]=%02x GDC[F]=%02x SEQ[E]=%02x 3d8=%02x 3d9=%02x\n", svga->read_bank, svga->write_bank, svga->gdcreg[0xe], svga->gdcreg[0xf], svga->seqregs[0xe], tvga->tvga_3d8, tvga->tvga_3d9); } void tvga_recalctimings(svga_t *svga) @@ -245,7 +233,6 @@ void tvga_recalctimings(svga_t *svga) svga->hdisp_time *= 2; } - // svga->interlace = svga->crtc[0x1e] & 4; if (svga->crtc[0x1e] & 4) { svga->rowoffset >>= 1; @@ -349,32 +336,25 @@ void tvga_add_status_info(char *s, int max_len, void *p) static device_config_t tvga_config[] = { { - .name = "memory", - .description = "Memory size", - .type = CONFIG_SELECTION, - .selection = + "memory", "Memory size", CONFIG_SELECTION, "", 1024, { { - .description = "256 kB", - .value = 256 + "256 kB", 256 }, { - .description = "512 kB", - .value = 512 + "512 kB", 512 }, { - .description = "1 MB", - .value = 1024 + "1 MB", 1024 }, /*Chip supports 2mb, but drivers are buggy*/ { - .description = "" + "" } - }, - .default_int = 1024 + } }, { - .type = -1 + "", "", -1 } }; diff --git a/src/vid_unk_ramdac.c b/src/vid_unk_ramdac.c index cc57b3bb5..0b6fc6aea 100644 --- a/src/vid_unk_ramdac.c +++ b/src/vid_unk_ramdac.c @@ -13,7 +13,6 @@ void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga) { - // pclog("OUT RAMDAC %04X %02X\n",addr,val); int oldbpp = 0; switch (addr) { @@ -63,7 +62,6 @@ void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *sv { svga_recalctimings(svga); } - // pclog("unk_ramdac: set to %02X (b5 = %i) [%02X], %i bpp\n", (val&1)|((val&0xC0)>>5), val & 0x20 ? 1 : 0, val, svga->bpp); return; } ramdac->state = 0; @@ -77,7 +75,6 @@ void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *sv uint8_t unk_ramdac_in(uint16_t addr, unk_ramdac_t *ramdac, svga_t *svga) { - // pclog("IN RAMDAC %04X\n",addr); switch (addr) { case 0x3C6: diff --git a/src/vid_vga.c b/src/vid_vga.c index da010a595..f5ff18ed6 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -24,9 +24,7 @@ void vga_out(uint16_t addr, uint8_t val, void *p) vga_t *vga = (vga_t *)p; svga_t *svga = &vga->svga; uint8_t old; - -// pclog("vga_out : %04X %02X %04X:%04X %02X %i\n", addr, val, CS,pc, ram[0x489], ins); - + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -63,8 +61,6 @@ uint8_t vga_in(uint16_t addr, void *p) svga_t *svga = &vga->svga; uint8_t temp; -// if (addr != 0x3da) pclog("vga_in : %04X ", addr); - if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; @@ -80,7 +76,6 @@ uint8_t vga_in(uint16_t addr, void *p) temp = svga_in(addr, svga); break; } -// if (addr != 0x3da) pclog("%02X %04X:%04X\n", temp, CS,pc); return temp; } @@ -128,6 +123,7 @@ void *vga_chips_init() } #endif +#ifdef DEV_BRANCH void *trigem_unk_init() { vga_t *vga = malloc(sizeof(vga_t)); @@ -152,6 +148,7 @@ void *trigem_unk_init() return vga; } +#endif /*PS/1 uses a standard VGA controller, but with no option ROM*/ void *ps1vga_init() @@ -178,10 +175,10 @@ static int vga_available() return rom_present("roms/ibm_vga.bin"); } -static int vga_chips_available() +/* static int vga_chips_available() { return rom_present("roms/SD620.04M"); -} +} */ void vga_close(void *p) { @@ -235,6 +232,7 @@ device_t vga_device = vga_force_redraw, vga_add_status_info }; */ +#ifdef DEV_BRANCH device_t trigem_unk_device = { "VGA", @@ -246,6 +244,7 @@ device_t trigem_unk_device = vga_force_redraw, vga_add_status_info }; +#endif device_t ps1vga_device = { "PS/1 VGA", diff --git a/src/vid_vga.h b/src/vid_vga.h index 1f8fbe700..5ee66fc0b 100644 --- a/src/vid_vga.h +++ b/src/vid_vga.h @@ -2,6 +2,5 @@ see COPYING for more details */ extern device_t vga_device; -// extern device_t vga_chips_device; extern device_t trigem_unk_device; extern device_t ps1vga_device; diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index 98b21e7c7..a1a5e93e7 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -380,9 +380,9 @@ typedef struct voodoo_t int wake_timer; - uint8_t thefilter[256][256]; // pixel filter, feeding from one or two - uint8_t thefilterg[256][256]; // for green - uint8_t thefilterb[256][256]; // for blue + uint8_t thefilter[256][256]; /* pixel filter, feeding from one or two */ + uint8_t thefilterg[256][256]; /* for green */ + uint8_t thefilterb[256][256]; /* for blue */ /* the voodoo adds purple lines for some reason */ uint16_t purpleline[256][3]; @@ -398,7 +398,7 @@ typedef struct voodoo_t void *codegen_data; } voodoo_t; -static inline void wait_for_render_thread_idle(voodoo_t *voodoo); +static __inline void wait_for_render_thread_idle(voodoo_t *voodoo); enum { @@ -549,6 +549,7 @@ enum SST_fbiInit4 = 0x200, + SST_vRetrace = 0x204, SST_backPorch = 0x208, SST_videoDimensions = 0x20c, SST_fbiInit0 = 0x210, @@ -710,7 +711,7 @@ enum SST_remap_fdAdY = 0x00d8 | 0x400, SST_remap_fdSdY = 0x00e4 | 0x400, SST_remap_fdTdY = 0x00f0 | 0x400, - SST_remap_fdWdY = 0x00fc | 0x400, + SST_remap_fdWdY = 0x00fc | 0x400 }; enum @@ -1238,7 +1239,6 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) lod_min = (params->tLOD[tmu] >> 2) & 15; lod_max = (params->tLOD[tmu] >> 8) & 15; -// pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max); for (lod = lod_min; lod <= lod_max; lod++) { @@ -1247,10 +1247,7 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) int x, y; int shift = 8 - params->tex_lod[tmu][lod]; rgba_u *pal; - - //pclog(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); - switch (params->tformat[tmu]) { case TEX_RGB332: @@ -1488,7 +1485,6 @@ static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) int c; memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); -// pclog("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); for (c = 0; c < TEX_CACHE_MAX; c++) { if (voodoo->texture_cache[tmu][c].base != -1) @@ -1500,7 +1496,6 @@ static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) if (dirty_addr >= (addr_start & voodoo->texture_mask & ~0x3ff) && dirty_addr < (((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff)) { -// pclog(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) @@ -1595,7 +1590,7 @@ static uint8_t logtable[256] = 0xf4,0xf5,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff }; -static inline int fastlog(uint64_t val) +static __inline int fastlog(uint64_t val) { uint64_t oldval = val; int exp = 63; @@ -1604,32 +1599,32 @@ static inline int fastlog(uint64_t val) if (!val || val & (1ULL << 63)) return 0x80000000; - if (!(val & 0xffffffff00000000)) + if (!(val & 0xffffffff00000000ll)) { exp -= 32; val <<= 32; } - if (!(val & 0xffff000000000000)) + if (!(val & 0xffff000000000000ll)) { exp -= 16; val <<= 16; } - if (!(val & 0xff00000000000000)) + if (!(val & 0xff00000000000000ll)) { exp -= 8; val <<= 8; } - if (!(val & 0xf000000000000000)) + if (!(val & 0xf000000000000000ll)) { exp -= 4; val <<= 4; } - if (!(val & 0xc000000000000000)) + if (!(val & 0xc000000000000000ll)) { exp -= 2; val <<= 2; } - if (!(val & 0x8000000000000000)) + if (!(val & 0x8000000000000000ll)) { exp -= 1; val <<= 1; @@ -1643,11 +1638,10 @@ static inline int fastlog(uint64_t val) return (exp << 8) | logtable[frac]; } -static inline int fls(uint16_t val) +static __inline int fls(uint16_t val) { int num = 0; -//pclog("fls(%04x) = ", val); if (!(val & 0xff00)) { num += 8; @@ -1668,7 +1662,6 @@ static inline int fls(uint16_t val) num += 1; val <<= 1; } -//pclog("%i %04x\n", num, val); return num; } @@ -1679,7 +1672,7 @@ typedef struct voodoo_texture_state_t int tex_shift; } voodoo_texture_state_t; -static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) +static __inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) { uint32_t dat; @@ -1719,7 +1712,7 @@ static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *textu #define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) #define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) -static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) +static __inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) { rgba_u dat[4]; @@ -1772,7 +1765,7 @@ static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *tex state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; } -static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +static __inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { rgba_u tex_samples[4]; voodoo_texture_state_t texture_state; @@ -1810,54 +1803,26 @@ static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, s >>= 4; t >>= 4; -//if (x == 80) -//if (voodoo_output) -// pclog("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); + d[0] = (16 - _ds) * (16 - dt); d[1] = _ds * (16 - dt); d[2] = (16 - _ds) * dt; d[3] = _ds * dt; -// texture_state.s = s; -// texture_state.t = t; tex_read_4(state, &texture_state, s, t, d, tmu, x); - - -/* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; - state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; - state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; - state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ -/* state->tex_r = tex_samples[0].r; - state->tex_g = tex_samples[0].g; - state->tex_b = tex_samples[0].b; - state->tex_a = tex_samples[0].a;*/ } else { - // rgba_t tex_samples; - // voodoo_texture_state_t texture_state; -// int s = state->tex_s >> (18+state->lod); -// int t = state->tex_t >> (18+state->lod); - // int s, t; - -// state->tex_s -= 1 << (17+state->lod); -// state->tex_t -= 1 << (17+state->lod); - s = state->tex_s >> (4+tex_lod); t = state->tex_t >> (4+tex_lod); texture_state.s = s; texture_state.t = t; tex_read(state, &texture_state, tmu); - -/* state->tex_r = tex_samples[0].rgba.r; - state->tex_g = tex_samples[0].rgba.g; - state->tex_b = tex_samples[0].rgba.b; - state->tex_a = tex_samples[0].rgba.a;*/ } } -static inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { if (params->textureMode[tmu] & 1) { @@ -2247,7 +2212,7 @@ static inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, v #define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) /*Perform texture fetch and blending for both TMUs*/ -static inline voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) +static __inline voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) { int r,g,b,a; int c_reverse, a_reverse; @@ -2538,8 +2503,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; -// int last_x; -// pclog("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); for (c = 0; c <= LOD_MAX; c++) { @@ -2584,7 +2547,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood yend = params->clipHighY; state->y = ystart; -// yend--; #ifndef NO_CODEGEN if (voodoo->use_recompiler) @@ -2593,7 +2555,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (voodoo_output) pclog("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); -// pclog("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); for (; state->y < yend; state->y++) { int x, x2; @@ -2745,7 +2706,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (voodoo_output) pclog(" X=%03i T=%08x\n", x, state->tmu0_t); -// if (voodoo->fbzMode & FBZ_RGB_WMASK) { int update = 1; uint8_t cother_r, cother_g, cother_b, aother; @@ -2771,8 +2731,6 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood w_depth = 0xffff; } -// w_depth = CLAMP16(w_depth); - if (params->fbzMode & FBZ_W_BUFFER) new_depth = w_depth; else @@ -3321,14 +3279,14 @@ static void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_e voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); } -static inline void wake_render_thread(voodoo_t *voodoo) +static __inline void wake_render_thread(voodoo_t *voodoo) { thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/ if (voodoo->render_threads == 2) thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ } -static inline void wait_for_render_thread_idle(voodoo_t *voodoo) +static __inline void wait_for_render_thread_idle(voodoo_t *voodoo) { while (!PARAM_EMPTY_1 || (voodoo->render_threads == 2 && !PARAM_EMPTY_2) || voodoo->render_voodoo_busy[0] || (voodoo->render_threads == 2 && voodoo->render_voodoo_busy[1])) { @@ -3381,7 +3339,7 @@ static void render_thread_2(void *param) render_thread(param, 1); } -static inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) +static __inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) { voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; @@ -3856,7 +3814,7 @@ skip_pixel_fill: case BLIT_COMMAND_SGRAM_FILL: /*32x32 tiles - 2kb*/ dst_y = voodoo->bltDstY & 0x3ff; - size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb + size_x = voodoo->bltSizeX & 0x1ff; size_y = voodoo->bltSizeY & 0x3ff; dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | @@ -4071,7 +4029,6 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) chip = 0xf; tempif.i = val; -//pclog("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); addr &= 0x3fc; if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) @@ -4079,7 +4036,6 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) switch (addr) { case SST_swapbufferCMD: -// pclog(" start swap buffer command\n"); if (TRIPLE_BUFFER) { @@ -4096,7 +4052,6 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.swapbufferCMD = val; pclog("Swap buffer %08x %d %p\n", val, voodoo->swap_count, &voodoo->swap_count); -// voodoo->front_offset = params->front_offset; wait_for_render_thread_idle(voodoo); if (!(val & 1)) { @@ -4554,12 +4509,10 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_sVx: tempif.i = val; voodoo->verts[3].sVx = tempif.f; -// pclog("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); break; case SST_sVy: tempif.i = val; voodoo->verts[3].sVy = tempif.f; -// pclog("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); break; case SST_sARGB: voodoo->verts[3].sBlue = (float)(val & 0xff); @@ -4617,13 +4570,11 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_sBeginTriCMD: -// pclog("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); voodoo->verts[0] = voodoo->verts[3]; voodoo->vertex_num = 1; voodoo->num_verticies = 1; break; case SST_sDrawTriCMD: -// pclog("sDrawTriCMD %i %i %i\n", voodoo->num_verticies, voodoo->vertex_num, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); if (voodoo->vertex_num == 3) voodoo->vertex_num = (voodoo->sSetupMode & SETUPMODE_STRIP_MODE) ? 1 : 0; voodoo->verts[voodoo->vertex_num] = voodoo->verts[3]; @@ -4632,7 +4583,6 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->vertex_num++; if (voodoo->num_verticies == 3) { -// pclog("triangle_setup\n"); triangle_setup(voodoo); voodoo->num_verticies = 2; @@ -4645,13 +4595,11 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltSrcBaseAddr = val & 0x3fffff; break; case SST_bltDstBaseAddr: -// pclog("Write bltDstBaseAddr %08x\n", val); voodoo->bltDstBaseAddr = val & 0x3fffff; break; case SST_bltXYStrides: voodoo->bltSrcXYStride = val & 0xfff; voodoo->bltDstXYStride = (val >> 16) & 0xfff; -// pclog("Write bltXYStrides %08x\n", val); break; case SST_bltSrcChromaRange: voodoo->bltSrcChromaRange = val; @@ -4685,14 +4633,12 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltSrcY = (val >> 16) & 0x7ff; break; case SST_bltDstXY: -// pclog("Write bltDstXY %08x\n", val); voodoo->bltDstX = val & 0x7ff; voodoo->bltDstY = (val >> 16) & 0x7ff; if (val & (1 << 31)) blit_start(voodoo); break; case SST_bltSize: -// pclog("Write bltSize %08x\n", val); voodoo->bltSizeX = val & 0xfff; if (voodoo->bltSizeX & 0x800) voodoo->bltSizeX |= 0xfffff000; @@ -4709,14 +4655,12 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltRop[3] = (val >> 12) & 0xf; break; case SST_bltColor: -// pclog("Write bltColor %08x\n", val); voodoo->bltColorFg = val & 0xffff; voodoo->bltColorBg = (val >> 16) & 0xffff; break; case SST_bltCommand: voodoo->bltCommand = val; -// pclog("Write bltCommand %08x\n", val); if (val & (1 << 31)) blit_start(voodoo); break; @@ -5187,7 +5131,6 @@ static uint16_t voodoo_fb_readw(uint32_t addr, void *p) temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); -// pclog("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); return temp; } static uint32_t voodoo_fb_readl(uint32_t addr, void *p) @@ -5206,11 +5149,10 @@ static uint32_t voodoo_fb_readl(uint32_t addr, void *p) temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); -// pclog("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width); return temp; } -static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) +static __inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) { int r, g, b; @@ -5252,13 +5194,7 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) depth_data = voodoo->params.zaColor & 0xffff; alpha_data = voodoo->params.zaColor >> 24; - -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); - -// pclog("voodoo_fb_writew : %08X %04X\n", addr, val); - - + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { case LFB_FORMAT_RGB565: @@ -5293,8 +5229,6 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - -// pclog("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); if (voodoo->lfbMode & 0x100) { @@ -5375,11 +5309,7 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; -// while (!RB_EMPTY) -// thread_reset_event(voodoo->not_full_event); - -// pclog("voodoo_fb_writel : %08X %08X\n", addr, val); - + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { case LFB_FORMAT_RGB565: @@ -5431,8 +5361,6 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); - -// pclog("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); if (voodoo->lfbMode & 0x100) { @@ -5525,8 +5453,6 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) if (tmu && !voodoo->dual_tmus) return; -// pclog("voodoo_tex_writel : %08X %08X %i\n", addr, val, voodoo->params.tformat); - lod = (addr >> 17) & 0xf; t = (addr >> 9) & 0xff; if (voodoo->params.tformat[tmu] & 8) @@ -5541,24 +5467,20 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) if (lod > LOD_MAX) return; - -// if (addr >= 0x200000) -// return; - + if (voodoo->params.tformat[tmu] & 8) addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; else addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { -// pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); } *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; } #define WAKE_DELAY (TIMER_USEC * 100) -static inline void wake_fifo_thread(voodoo_t *voodoo) +static __inline void wake_fifo_thread(voodoo_t *voodoo) { if (!voodoo->wake_timer) { @@ -5572,7 +5494,7 @@ static inline void wake_fifo_thread(voodoo_t *voodoo) } } -static inline void wake_fifo_thread_now(voodoo_t *voodoo) +static __inline void wake_fifo_thread_now(voodoo_t *voodoo) { thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -5586,7 +5508,7 @@ static void voodoo_wake_timer(void *p) thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } -static inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) +static __inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) { fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; int c; @@ -5769,6 +5691,10 @@ static uint32_t voodoo_readl(uint32_t addr, void *p) temp = voodoo->fbiInit3; break; + case SST_vRetrace: + timer_clock(); + temp = voodoo->line & 0x1fff; + break; case SST_hvRetrace: timer_clock(); temp = voodoo->line & 0x1fff; @@ -5842,9 +5768,7 @@ static void voodoo_pixelclock_update(voodoo_t *voodoo) t /= 2.0f; line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); - -// pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); - + voodoo->pixel_clock = t; clock_const = cpuclock / t; @@ -5882,7 +5806,6 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { -// pclog("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; voodoo->cmdfifo_depth_wr++; if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) @@ -5945,7 +5868,6 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) { voodoo->fbiInit4 = val; voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); -// pclog("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); } break; case SST_backPorch: @@ -5978,7 +5900,6 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->fbiInit1 = val; voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); -// pclog("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); } break; case SST_fbiInit2: @@ -6021,7 +5942,6 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->dac_readdata = 0xff; if (val & 0x800) { -// pclog(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); if (voodoo->dac_reg == 5) { switch (voodoo->dac_data[7]) @@ -6042,7 +5962,6 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; else voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); -// pclog("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); voodoo->dac_reg_ff = !voodoo->dac_reg_ff; if (!voodoo->dac_reg_ff) voodoo->dac_data[4]++; @@ -6086,7 +6005,6 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) case SST_cmdFifoBaseAddr: voodoo->cmdfifo_base = (val & 0x3ff) << 12; voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; -// pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); break; case SST_cmdFifoRdPtr: @@ -6131,11 +6049,10 @@ static uint32_t cmdfifo_get(voodoo_t *voodoo) voodoo->cmdfifo_depth_rd++; voodoo->cmdfifo_rp += 4; -// pclog(" CMDFIFO get %08x\n", val); return val; } -static inline float cmdfifo_get_f(voodoo_t *voodoo) +static __inline float cmdfifo_get_f(voodoo_t *voodoo) { union { @@ -6216,13 +6133,10 @@ static void fifo_thread(void *param) int num; int num_verticies; int v_num; - -// pclog(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); - + switch (header & 7) { case 0: -// pclog("CMDFIFO0\n"); switch ((header >> 3) & 7) { case 0: /*NOP*/ @@ -6230,7 +6144,6 @@ static void fifo_thread(void *param) case 3: /*JMP local frame buffer*/ voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; -// pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); break; default: @@ -6241,7 +6154,6 @@ static void fifo_thread(void *param) case 1: num = header >> 16; addr = (header & 0x7ff8) >> 1; -// pclog("CMDFIFO1 addr=%08x\n",addr); while (num--) { uint32_t val = cmdfifo_get(voodoo); @@ -6258,15 +6170,13 @@ static void fifo_thread(void *param) case 3: num = (header >> 29) & 7; - mask = header;//(header >> 10) & 0xff; + mask = header; smode = (header >> 22) & 0xf; voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); num_verticies = (header >> 6) & 0xf; v_num = 0; if (((header >> 3) & 7) == 2) v_num = 1; -// pclog("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); -// pclog("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); while (num_verticies--) { @@ -6323,7 +6233,6 @@ static void fifo_thread(void *param) num = (header >> 29) & 7; mask = (header >> 15) & 0x3fff; addr = (header & 0x7ff8) >> 1; -// pclog("CMDFIFO4 addr=%08x\n",addr); while (mask) { if (mask & 1) @@ -6348,7 +6257,6 @@ static void fifo_thread(void *param) fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); num = (header >> 3) & 0x7ffff; addr = cmdfifo_get(voodoo) & 0xffffff; -// pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); switch (header >> 30) { case 2: /*Framebuffer*/ @@ -6406,8 +6314,6 @@ uint8_t voodoo_pci_read(int func, int addr, void *p) if (func) return 0; -// pclog("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); - switch (addr) { case 0x00: return 0x1a; /*3dfx*/ @@ -6453,8 +6359,6 @@ void voodoo_pci_write(int func, int addr, uint8_t val, void *p) if (func) return; -// pclog("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); - switch (addr) { case 0x04: @@ -6501,10 +6405,7 @@ static void voodoo_calc_clutData(voodoo_t *voodoo) int r = (c >> 8) & 0xf8; int g = (c >> 3) & 0xfc; int b = (c << 3) & 0xf8; -// r |= (r >> 5); -// g |= (g >> 6); -// b |= (b >> 5); - + voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; } } @@ -6526,9 +6427,9 @@ static void voodoo_generate_filter_v1(voodoo_t *voodoo) fcg = FILTCAPG * 6; fcb = FILTCAPB * 5; - for (g=0;g -fcr)) thiscol = g + (difference / 2); if ((diffg < fcg) || (-diffg > -fcg)) @@ -6604,7 +6500,7 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) float clr, clg, clb = 0; float fcr, fcg, fcb = 0; - // pre-clamping + /* pre-clamping */ fcr = FILTCAP; fcg = FILTCAPG; @@ -6614,9 +6510,9 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) if (fcg > 32) fcg = 32; if (fcb > 32) fcb = 32; - for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into + for (g=0;g<256;g++) /* pixel 1 - our target pixel we want to bleed into */ { - for (h=0;h<256;h++) // pixel 2 - our main pixel + for (h=0;h<256;h++) /* pixel 2 - our main pixel */ { float avg; float avgdiff; @@ -6629,7 +6525,7 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) thiscol = thiscolg = thiscolb = g; - // try lighten + /* try lighten */ if (h > g) { clr = clg = clb = avgdiff; @@ -6667,7 +6563,7 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) if (difference > FILTCAPB) thiscolb = g; - // clamp + /* clamp */ if (thiscol < 0) thiscol = 0; if (thiscolg < 0) thiscolg = 0; if (thiscolb < 0) thiscolb = 0; @@ -6676,14 +6572,10 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) if (thiscolg > 255) thiscolg = 255; if (thiscolb > 255) thiscolb = 255; - // add to the table + /* add to the table */ voodoo->thefilter[g][h] = (thiscol); voodoo->thefilterg[g][h] = (thiscolg); voodoo->thefilterb[g][h] = (thiscolb); - - // debug the ones that don't give us much of a difference - //if (difference < FILTCAP) - //pclog("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); } lined = g + 3; @@ -6728,7 +6620,7 @@ static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uin { int x; - // Scratchpad for avoiding feedback streaks + /* Scratchpad for avoiding feedback streaks */ uint8_t fil3[(voodoo->h_disp) * 3]; /* 16 to 32-bit */ @@ -6738,7 +6630,7 @@ static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uin fil[x*3+1] = (((src[x] >> 5) & 63) << 2); fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - // Copy to our scratchpads + /* Copy to our scratchpads */ fil3[x*3+0] = fil[x*3+0]; fil3[x*3+1] = fil[x*3+1]; fil3[x*3+2] = fil[x*3+2]; @@ -6794,13 +6686,13 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin { int x; - // Scratchpad for blending filter + /* Scratchpad for blending filter */ uint8_t fil3[(voodoo->h_disp) * 3]; /* 16 to 32-bit */ for (x=0; x> 5) & 63) << 2); fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); @@ -6827,7 +6719,7 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; } - // unroll for edge cases + /* unroll for edge cases */ fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; @@ -6908,7 +6800,6 @@ void voodoo_callback(void *p) } if (voodoo->line == voodoo->v_disp) { -// pclog("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); voodoo->retrace_count++; if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { @@ -7003,7 +6894,6 @@ static void voodoo_speed_changed(void *p) voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); -// pclog("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); } void *voodoo_init() @@ -7192,118 +7082,84 @@ void voodoo_close(void *p) static device_config_t voodoo_config[] = { { - .name = "type", - .description = "Voodoo type", - .type = CONFIG_SELECTION, - .selection = + "type", "Voodoo type", CONFIG_SELECTION, "", 0, { { - .description = "Voodoo Graphics", - .value = VOODOO_1 + "Voodoo Graphics", VOODOO_1 }, { - .description = "Obsidian SB50 + Amethyst (2 TMUs)", - .value = VOODOO_SB50 + "Obsidian SB50 + Amethyst (2 TMUs)", VOODOO_SB50 }, { - .description = "Voodoo 2", - .value = VOODOO_2 + "Voodoo 2", VOODOO_2 }, { - .description = "" + "" } - }, - .default_int = 0 + } }, { - .name = "framebuffer_memory", - .description = "Framebuffer memory size", - .type = CONFIG_SELECTION, - .selection = + "framebuffer_memory", "Framebuffer memory size", CONFIG_SELECTION, "", 2, { { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB", 4 }, { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .name = "texture_memory", - .description = "Texture memory size", - .type = CONFIG_SELECTION, - .selection = + "texture_memory", "Texture memory size", CONFIG_SELECTION, "", 2, { { - .description = "2 MB", - .value = 2 + "2 MB", 2 }, { - .description = "4 MB", - .value = 4 + "4 MB",4 }, { - .description = "" + "" } - }, - .default_int = 2 + } }, { - .name = "bilinear", - .description = "Bilinear filtering", - .type = CONFIG_BINARY, - .default_int = 1 - }, - { - .name = "dacfilter", - .description = "Screen Filter", - .type = CONFIG_BINARY, - .default_int = 0 - }, - { - .name = "render_threads", - .description = "Render threads", - .type = CONFIG_SELECTION, - .selection = + "render_threads", "Render threads", CONFIG_SELECTION, "", 2, { { - .description = "1", - .value = 1 + "1", 1 }, { - .description = "2", - .value = 2 + "2", 2 }, { - .description = "" + "" } - }, - .default_int = 2 + } + }, + { + "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 + }, + { + "dacfilter", "Screen Filter", CONFIG_BINARY, "", 0 }, #ifndef NO_CODEGEN { - .name = "recompiler", - .description = "Recompiler", - .type = CONFIG_BINARY, - .default_int = 1 + "recompiler", "Recompiler", CONFIG_BINARY, "", 1 }, #endif { - .type = -1 + "", "", -1 } }; device_t voodoo_device = { "3DFX Voodoo Graphics", - 0, + DEVICE_PCI, voodoo_init, voodoo_close, NULL, diff --git a/src/vid_voodoo_codegen_x86.h b/src/vid_voodoo_codegen_x86.h index f0aba4a59..fd3d09587 100644 --- a/src/vid_voodoo_codegen_x86.h +++ b/src/vid_voodoo_codegen_x86.h @@ -63,20 +63,20 @@ static int next_block_to_write[2] = {0, 0}; fatal("Over!\n") -static __m128i xmm_01_w;// = 0x0001000100010001ull; -static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; -static __m128i xmm_ff_b;// = 0x00000000ffffffffull; +static __m128i xmm_01_w; +static __m128i xmm_ff_w; +static __m128i xmm_ff_b; static uint32_t zero = 0; static double const_1_48 = (double)(1ull << 4); static __m128i alookup[257], aminuslookup[256]; -static __m128i minus_254;// = 0xff02ff02ff02ff02ull; +static __m128i minus_254; static __m128i bilinear_lookup[256*2]; static __m128i xmm_00_ff_w[2]; static uint32_t i_00_ff_w[2] = {0, 0xff}; -static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) +static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) { if (params->textureMode[tmu] & 1) { @@ -653,7 +653,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v return block_pos; } -static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) +static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) { int block_pos = 0; int z_skip_pos = 0; @@ -662,24 +662,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo int depth_jump_pos = 0; int depth_jump_pos2 = 0; int loop_jump_pos = 0; -// xmm_01_w = (__m128i)0x0001000100010001ull; -// xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; -// xmm_ff_b = (__m128i)0x00000000ffffffffull; xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); -// *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; -// block_pos = 0; -// voodoo_get_depth = &code_block[block_pos]; - /*W at (%esp+4) - Z at (%esp+12) - new_depth at (%esp+16)*/ -// if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) -// { -// addbyte(0xC3); /*RET*/ -// return; -// } addbyte(0x55); /*PUSH EBP*/ addbyte(0x57); /*PUSH EDI*/ addbyte(0x56); /*PUSH ESI*/ @@ -711,7 +697,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x75); /*JNZ got_depth*/ depth_jump_pos = block_pos; addbyte(0); -// addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0x8b); /*MOV EDX, w*/ addbyte(0x97); addlong(offsetof(voodoo_state_t, w)); @@ -725,7 +710,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x74); /*JZ got_depth*/ depth_jump_pos2 = block_pos; addbyte(0); -// addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0xb9); /*MOV ECX, 19*/ addlong(19); addbyte(0x0f); /*BSR EAX, EDX*/ @@ -891,17 +875,8 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) { addbyte(0xC3); /*RET*/ -// addbyte(0x30); /*XOR EAX, EAX*/ -// addbyte(0xc0); } -// else -// { -// addbyte(0xb0); /*MOV AL, 1*/ -// addbyte(1); -// } - -// voodoo_combine = &code_block[block_pos]; /*XMM0 = colour*/ /*XMM2 = 0 (for unpacking*/ @@ -2172,12 +2147,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x05); addlong(&xmm_ff_b); } -//#if 0 -// addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ -// addbyte(0x0f); -// addbyte(0x7e); -// addbyte(0x87); -// addlong(offsetof(voodoo_state_t, out)); if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) @@ -2272,11 +2241,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(10); addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); - -/* int fog_idx = (w_depth >> 10) & 0x3f; - - fog_a = params->fogTable[fog_idx].fog; - fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ break; case FOG_Z: @@ -2288,7 +2252,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(12); addbyte(0x25); /*AND EAX, 0xff*/ addlong(0xff); -// fog_a = (z >> 20) & 0xff; break; case FOG_ALPHA: @@ -2310,7 +2273,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); -// fog_a = CLAMP(ia >> 12); break; case FOG_W: @@ -2331,12 +2293,10 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); -// fog_a = CLAMP(w >> 32); break; } addbyte(0x01); /*ADD EAX, EAX*/ addbyte(0xc0); -// fog_a++; addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ addbyte(0x0f); @@ -2808,13 +2768,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x67); addbyte(0xc0); } -//#endif - -// addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ -// addbyte(0x54); -// addbyte(0x24); -// addbyte(12); - addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); @@ -2827,10 +2780,6 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo if (params->fbzMode & FBZ_RGB_WMASK) { -// addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ -// addbyte(0x87); -// addlong(offsetof(voodoo_state_t, rgb_out)); - if (dither) { addbyte(0x8b); /*MOV ESI, real_y (ESP+16)*/ @@ -3232,7 +3181,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo } static int voodoo_recomp = 0; -static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) +static __inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { int c; int b = last_block[odd_even]; @@ -3262,7 +3211,6 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, } voodoo_recomp++; data = &codegen_data[odd_even + next_block_to_write[odd_even]*2]; -// code_block = data->code_block; voodoo_generate(data->code_block, voodoo, params, state, depth_op); @@ -3300,7 +3248,7 @@ static void voodoo_codegen_init(voodoo_t *voodoo) #ifdef __linux__ start = (void *)((long)voodoo->codegen_data & pagemask); - len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM) + pagesize) & pagemask; + len = ((sizeof(voodoo_x86_data_t) * BLOCK_NUM*2) + pagesize) & pagemask; if (mprotect(start, len, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { perror("mprotect"); diff --git a/src/vid_wy700.c b/src/vid_wy700.c index 41bb73ffb..80def235f 100644 --- a/src/vid_wy700.c +++ b/src/vid_wy700.c @@ -3,6 +3,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "io.h" #include "timer.h" #include "video.h" #include "vid_wy700.h" @@ -499,7 +500,7 @@ void wy700_textline(wy700_t *wy700) int x; int w = (wy700->wy700_mode == 0) ? 40 : 80; int cw = (wy700->wy700_mode == 0) ? 32 : 16; - uint8_t chr, attr, fg, bg; + uint8_t chr, attr; uint8_t bitmap[2]; uint8_t *fontbase = &fontdatw[0][0]; int blink, c; @@ -591,7 +592,7 @@ void wy700_cgaline(wy700_t *wy700) { int x, c; uint32_t dat; - uint8_t bitmap, ink; + uint8_t ink; uint16_t addr; uint16_t ma = (wy700->cga_crtc[13] | (wy700->cga_crtc[12] << 8)) & 0x3fff; @@ -651,7 +652,7 @@ void wy700_medresline(wy700_t *wy700) { int x, c; uint32_t dat; - uint8_t bitmap, ink; + uint8_t ink; uint32_t addr; addr = (wy700->displine >> 1) * 80 + 4 * wy700->wy700_base; @@ -709,7 +710,7 @@ void wy700_hiresline(wy700_t *wy700) { int x, c; uint32_t dat; - uint8_t bitmap, ink; + uint8_t ink; uint32_t addr; addr = (wy700->displine >> 1) * 160 + 4 * wy700->wy700_base; @@ -765,10 +766,6 @@ void wy700_hiresline(wy700_t *wy700) void wy700_poll(void *p) { wy700_t *wy700 = (wy700_t *)p; - int x, c; - int oldvc; - uint8_t chr, attr; - uint16_t dat; int mode; if (!wy700->linepos) diff --git a/src/video.c b/src/video.c index 9ac3a3040..1176824ee 100644 --- a/src/video.c +++ b/src/video.c @@ -24,17 +24,22 @@ #include "vid_ati28800.h" #include "vid_ati_mach64.h" #include "vid_cga.h" -#include "vid_cl_ramdac.h" //vid_cl_gd.c needs this +#ifdef DEV_BRANCH +#include "vid_cl_ramdac.h" /* vid_cl_gd.c needs this */ #include "vid_cl_gd.h" +#endif #include "vid_ega.h" #include "vid_et4000.h" #include "vid_et4000w32.h" +#include "vid_genius.h" #include "vid_hercules.h" #include "vid_herculesplus.h" #include "vid_incolor.h" #include "vid_colorplus.h" #include "vid_mda.h" +#ifdef DEV_BRANCH #include "vid_nv_riva128.h" +#endif #include "vid_olivetti_m24.h" #include "vid_oti067.h" #include "vid_paradise.h" @@ -65,29 +70,25 @@ typedef struct static VIDEO_CARD video_cards[] = { {"ATI Graphics Pro Turbo (Mach64 GX)", "mach64x", &mach64gx_device, GFX_MACH64GX}, + {"ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, GFX_MACH64VT2}, {"ATI VGA Charger (ATI-28800-5)", "ati28800", &ati28800_device, GFX_VGACHARGER}, {"ATI VGA Wonder XL24 (ATI-28800-6)", "ati28800w", &ati28800_wonderxl24_device, GFX_VGAWONDERXL24}, {"ATI VGA Edge-16 (ATI-18800)", "ati18800", &ati18800_device, GFX_VGAEDGE16}, {"CGA", "cga", &cga_device, GFX_CGA}, - {"Cirrus Logic CL-GD5429", "cl_gd5429", &gd5429_device, GFX_CL_GD5429}, {"Diamond Stealth 32 (Tseng ET4000/w32p)", "stealth32", &et4000w32p_device, GFX_ET4000W32}, - /* {"Diamond Stealth 64 DRAM (S3 Vision864)", "stealth64d", &s3_diamond_stealth64_device,GFX_STEALTH64}, */ + {"Diamond Stealth 64 DRAM (S3 Trio64)", "stealth64d", &s3_diamond_stealth64_device,GFX_STEALTH64}, {"Diamond Stealth 3D 2000 (S3 ViRGE)", "stealth3d_2000", &s3_virge_device, GFX_VIRGE}, + {"Diamond Stealth 3D 3000 (S3 ViRGE/VX)", "stealth3d_3000", &s3_virge_988_device, GFX_VIRGEVX}, {"EGA", "ega", &ega_device, GFX_EGA}, {"Chips & Technologies SuperEGA", "superega", &sega_device, GFX_SUPER_EGA}, {"Compaq ATI VGA Wonder XL (ATI-28800-5)", "compaq_ati28800", &compaq_ati28800_device, GFX_VGAWONDERXL}, {"Compaq EGA", "compaq_ega", &cpqega_device, GFX_COMPAQ_EGA}, - /* {"Compaq/Paradise VGA", "compaq_vga", &cpqvga_device, GFX_COMPAQ_VGA}, */ {"Hercules", "hercules", &hercules_device, GFX_HERCULES}, {"Hercules Plus", "hercules_plus", &herculesplus_device, GFX_HERCULESPLUS}, {"Hercules InColor", "incolor", &incolor_device, GFX_INCOLOR}, {"MDA", "mda", &mda_device, GFX_MDA}, - /* {"Miro Crystal S3 Vision964", "mc_vision964", &s3_miro_vision964_device, GFX_MIRO_VISION964}, */ + {"MDSI Genius", "genius", &genius_device, GFX_GENIUS}, {"Number Nine 9FX (S3 Trio64)", "n9_9fx", &s3_9fx_device, GFX_N9_9FX}, - {"nVidia RIVA 128 (Experimental)", "nv_riva128", &riva128_device, GFX_RIVA128}, - {"nVidia RIVA TNT (Experimental)", "nv_rivatnt", &rivatnt_device, GFX_RIVATNT}, - {"nVidia RIVA TNT2 (Experimental)", "nv_rivatnt2", &rivatnt2_device, GFX_RIVATNT2}, - {"OAK OTI-067", "oti067", &oti067_device, GFX_OTI067}, {"OAK OTI-077", "oti077", &oti077_device, GFX_OTI077}, {"Paradise Bahamas 64 (S3 Vision864)", "bahamas64", &s3_bahamas64_device, GFX_BAHAMAS64}, @@ -99,7 +100,6 @@ static VIDEO_CARD video_cards[] = {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA}, - {"TriGem Unknown Adapter", "trigem_unk", &trigem_unk_device, GFX_TRIGEM_UNK}, {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000}, {"VGA", "vga", &vga_device, GFX_VGA}, {"Wyse 700", "wy700", &wy700_device, GFX_WY700}, @@ -332,6 +332,10 @@ void video_init() return; case ROM_IBMPS1_2011: + case ROM_IBMPS2_M30_286: + case ROM_IBMPS2_M50: + case ROM_IBMPS2_M55SX: + case ROM_IBMPS2_M80: device_add(&ps1vga_device); return; @@ -348,6 +352,7 @@ BITMAP *buffer, *buffer32; uint8_t fontdat[256][8]; uint8_t fontdatm[256][16]; uint8_t fontdatw[512][32]; /* Wyse700 font */ +uint8_t fontdat8x12[256][16]; /* MDSI Genius font */ int xsize=1,ysize=1; @@ -431,6 +436,16 @@ void loadfont(char *s, int format) } } break; + case 4: /* MDSI Genius */ + for (c=0;c<256;c++) + { + for (d=0;d<16;d++) + { + fontdat8x12[c][d]=getc(f); + } + } + break; + } fclose(f); } @@ -452,7 +467,7 @@ static void blit_thread(void *param); int calc_6to8(int c) { int ic, i8; - double dc, d8; + double d8; ic = c; if (ic == 64) { @@ -462,7 +477,6 @@ int calc_6to8(int c) { ic &= 0x3f; } - dc = (double) ic; d8 = (ic / 63.0) * 255.0; i8 = (int) d8; return i8 & 0xff; @@ -542,7 +556,6 @@ void initvideo() if (d & 1) edatlookup[c][d] |= 2; if (c & 2) edatlookup[c][d] |= 0x10; if (d & 2) edatlookup[c][d] |= 0x20; -// printf("Edat %i,%i now %02X\n",c,d,edatlookup[c][d]); } } diff --git a/src/video.h b/src/video.h index c01bb812b..7461f130b 100644 --- a/src/video.h +++ b/src/video.h @@ -112,3 +112,12 @@ void ddraw_fs_take_screenshot(char *fn); #endif extern int cga_palette; + +void loadfont(char *s, int format); +void initvideo(); +void video_init(); +void closevideo(); +void video_updatetiming(); + +void hline(BITMAP *b, int x1, int y, int x2, uint32_t col); +void updatewindowsize(int x, int y); diff --git a/src/w83877f.c b/src/w83877f.c index 0096b998d..ebb22513d 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -203,7 +203,6 @@ static void w83877f_remap() winbond_port = (HEFRAS ? 0x3f0 : 0x250); winbond_key_times = HEFRAS + 1; winbond_key = (HEFRAS ? 0x86 : 0x88) | HEFERE; - // pclog("W83877F mapped to %04X, with key %02X required %i times\n", winbond_port, winbond_key, winbond_key_times); } static uint8_t is_in_array(uint16_t *port_array, uint8_t max, uint16_t port) @@ -267,7 +266,6 @@ static uint16_t make_port(uint8_t reg) break; } - // pclog("Made port %04X (reg %02X)\n", p, reg); return p; } @@ -276,21 +274,16 @@ void w83877f_write(uint16_t port, uint8_t val, void *priv) uint8_t index = (port & 1) ? 0 : 1; uint8_t valxor = 0; uint8_t max = 0x2A; - int temp; if (index) { - // pclog("w83877f_write : port=%04x = %02X locked=%i\n", port, val, w83877f_locked); - if ((val == winbond_key) && !w83877f_locked) { if (winbond_key_times == 2) { if (tries) { - // pclog("W83877F Locked (2 tries)\n"); w83877f_locked = 1; - // fdc_3f1_enable(0); tries = 0; } else @@ -300,23 +293,18 @@ void w83877f_write(uint16_t port, uint8_t val, void *priv) } else { - // pclog("W83877F Locked (1 try)\n"); w83877f_locked = 1; - // fdc_3f1_enable(0); tries = 0; } } else { - // pclog("w83877f_write : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, val, w83877f_locked); - if (w83877f_locked) { if (val < max) w83877f_curreg = val; if (val == 0xaa) { w83877f_locked = 0; - // fdc_3f1_enable(1); } } else @@ -328,8 +316,6 @@ void w83877f_write(uint16_t port, uint8_t val, void *priv) } else { - // pclog("w83877f_write : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, val, w83877f_locked); - if (w83877f_locked) { if (w83877f_rw_locked) return; @@ -379,20 +365,17 @@ process_value: } break; case 7: - // pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val); if (valxor & 3) fdc_update_rwc(0, FDDA_TYPE); if (valxor & 0xC) fdc_update_rwc(1, FDDB_TYPE); if (valxor & 0x30) fdc_update_rwc(2, FDDC_TYPE); if (valxor & 0xC0) fdc_update_rwc(3, FDDD_TYPE); break; case 8: - // pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val); if (valxor & 3) fdc_update_boot_drive(FD_BOOT); if (valxor & 0x10) swwp = SWWP ? 1 : 0; if (valxor & 0x20) disable_write = DISFDDWR ? 1 : 0; break; case 9: - // pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val); if (valxor & 0x20) { fdc_update_enh_mode(EN3MODE ? 1 : 0); @@ -403,7 +386,6 @@ process_value: } break; case 0xB: - // pclog("W83877F Write [Reg. %02X]: %02X\n", w83877f_curreg, val); if (valxor & 1) fdc_update_drv2en(DRV2EN_NEG ? 0 : 1); if (valxor & 2) fdc_update_densel_polarity(INVERTZ ? 1 : 0); break; @@ -459,13 +441,11 @@ uint8_t w83877f_read(uint16_t port, void *priv) if (!w83877f_locked) { - // pclog("w83877f_read : port=%04x = FF locked=%i\n", port, w83877f_locked); return 0xff; } if (index) { - // pclog("w83877f_read : port=%04x = %02X locked=%i\n", port, w83877f_curreg, w83877f_locked); return w83877f_curreg; } else @@ -473,10 +453,8 @@ uint8_t w83877f_read(uint16_t port, void *priv) if ((w83877f_curreg < 0x18) && w83877f_rw_locked) return 0xff; if (w83877f_curreg == 7) { - // pclog("w83877f_read : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2)), w83877f_locked); return (fdc_get_rwc(0) | (fdc_get_rwc(1) << 2)); } - // pclog("w83877f_read : port=%04x reg %02X = %02X locked=%i\n", port, w83877f_curreg, w83877f_regs[w83877f_curreg], w83877f_locked); return w83877f_regs[w83877f_curreg]; } } diff --git a/src/win-cgapal.h b/src/win-cgapal.h index 40056a2b1..d6ac7ffd8 100644 --- a/src/win-cgapal.h +++ b/src/win-cgapal.h @@ -7,6 +7,7 @@ extern uint32_t pal_lookup[256]; extern "C" { #endif void cgapal_rebuild(); +void destroy_bitmap(BITMAP *b); #ifdef __cplusplus } #endif diff --git a/src/win-config.c b/src/win-config.c deleted file mode 100644 index 66c99315c..000000000 --- a/src/win-config.c +++ /dev/null @@ -1,923 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include - -#include "nethandler.h" -#include "ibm.h" -#include "ide.h" -#include "cpu.h" -#include "device.h" -#include "buslogic.h" -#include "fdd.h" -#include "gameport.h" -#include "hdd.h" -#include "model.h" -#include "mouse.h" -#include "nvr.h" -#include "resources.h" -#include "sound.h" -#include "video.h" -#include "vid_voodoo.h" -#include "win.h" - -extern int is486; -static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; -static int settings_sound_to_list[20], settings_list_to_sound[20]; -static int settings_mouse_to_list[20], settings_list_to_mouse[20]; -static int settings_network_to_list[20], settings_list_to_network[20]; -static char *hdd_names[16]; - -static int mouse_valid(int type, int model) -{ - if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_PS2) && !(models[model].flags & MODEL_PS2)) - return 0; - if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_AMSTRAD) && !(models[model].flags & MODEL_AMSTRAD)) - return 0; - if (((type & MOUSE_TYPE_IF_MASK) == MOUSE_TYPE_OLIM24) && !(models[model].flags & MODEL_OLIM24)) - return 0; - return 1; -} - -static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) -{ - HWND h; - - h = GetDlgItem(hdlg, IDC_COMBOHDD); - - if (models[model].flags & MODEL_PS2_HDD) - { - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"XTIDE for PS/2"); - EnableWindow(h, FALSE); - SendMessage(h, CB_SETCURSEL, 0, 0); - } - else if (models[model].flags & MODEL_HAS_IDE) - { - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Internal IDE"); - EnableWindow(h, FALSE); - SendMessage(h, CB_SETCURSEL, 0, 0); - } - else - { - char *s; - int valid = 0; - char old_name[16]; - int c, d; - - if (use_selected_hdd) - { - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (c != -1 && hdd_names[c]) - strncpy(old_name, hdd_names[c], sizeof(old_name)-1); - else - strcpy(old_name, "none"); - } - else - strncpy(old_name, hdd_controller_name, sizeof(old_name)-1); - - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) - { - s = hdd_controller_get_name(c); - if (s[0] == 0) - break; - if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) - { - c++; - continue; - } - if (!hdd_controller_available(c)) - { - c++; - continue; - } - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - hdd_names[d] = hdd_controller_get_internal_name(c); - if (!strcmp(old_name, hdd_names[d])) - { - SendMessage(h, CB_SETCURSEL, d, 0); - valid = 1; - } - c++; - d++; - } - - if (!valid) - SendMessage(h, CB_SETCURSEL, 0, 0); - } -} - -static BOOL CALLBACK config_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - char temp_str[256]; - HWND h; - int c, d; - int rom, gfx, mem, fpu; - int temp_cpu, temp_cpu_m, temp_model; - int temp_GAMEBLASTER, temp_GUS, temp_SSI2001, temp_voodoo, temp_buslogic, temp_sound_card_current; - int temp_dynarec; - int cpu_flags; - int temp_fd1_type, temp_fd2_type, temp_fd3_type, temp_fd4_type; - int temp_network_card_current; - int temp_network_interface_current; - int temp_joystick_type; - int temp_mouse_type; - int cpu_type; - int temp_xtide; - int temp_fpu; - - UDACCEL accel; -// pclog("Dialog msg %i %08X\n",message,message); - switch (message) - { - case WM_INITDIALOG: - pause = 1; - h = GetDlgItem(hdlg, IDC_COMBO1); - for (c = 0; c < ROM_MAX; c++) - romstolist[c] = 0; - c = d = 0; - while (models[c].id != -1) - { - pclog("INITDIALOG : %i %i %i\n",c,models[c].id,romspresent[models[c].id]); - if (romspresent[models[c].id]) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)models[c].name); - modeltolist[c] = d; - listtomodel[d] = c; - romstolist[models[c].id] = d; - romstomodel[models[c].id] = c; - d++; - } - c++; - } - SendMessage(h, CB_SETCURSEL, modeltolist[model], 0); - - h = GetDlgItem(hdlg, IDC_COMBOVID); - c = d = 0; - while (1) - { - char *s = video_card_getname(c); - - if (!s[0]) - break; - - if (video_card_available(c) && gfx_present[video_new_to_old(c)]) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - if (video_new_to_old(c) == gfxcard) - SendMessage(h, CB_SETCURSEL, d, 0); - - d++; - } - - c++; - } - if (models[model].fixed_gfxcard) - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBOCPUM); - c = 0; - while (models[romstomodel[romset]].cpu[c].cpus != NULL && c < 4) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)models[romstomodel[romset]].cpu[c].name); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, cpu_manufacturer, 0); - if (c == 1) EnableWindow(h, FALSE); - else EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO3); - c = 0; - while (models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].cpu_type != -1) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[c].name); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, cpu, 0); - - h = GetDlgItem(hdlg, IDC_COMBOSND); - c = d = 0; - while (1) - { - char *s = sound_card_getname(c); - - if (!s[0]) - break; - - settings_sound_to_list[c] = d; - - if (sound_card_available(c)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - settings_list_to_sound[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_sound_to_list[sound_card_current], 0); - - /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBONET); - c = d = 0; - while (1) - { - char *s = network_card_getname(c); - - if (!s[0]) - break; - - settings_network_to_list[c] = d; - - if (network_card_available(c)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - settings_list_to_network[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_network_to_list[network_card_current], 0); - - h=GetDlgItem(hdlg, IDC_CHECK3); - SendMessage(h, BM_SETCHECK, GAMEBLASTER, 0); - - h=GetDlgItem(hdlg, IDC_CHECKGUS); - SendMessage(h, BM_SETCHECK, GUS, 0); - - h=GetDlgItem(hdlg, IDC_CHECKSSI); - SendMessage(h, BM_SETCHECK, SSI2001, 0); - - h=GetDlgItem(hdlg, IDC_CHECKSYNC); - SendMessage(h, BM_SETCHECK, enable_sync, 0); - - h=GetDlgItem(hdlg, IDC_CHECKVOODOO); - SendMessage(h, BM_SETCHECK, voodoo_enabled, 0); - - h=GetDlgItem(hdlg, IDC_CHECKBUSLOGIC); - SendMessage(h, BM_SETCHECK, buslogic_enabled, 0); - - cpu_flags = models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; - h=GetDlgItem(hdlg, IDC_CHECKDYNAREC); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - EnableWindow(h, FALSE); - else - EnableWindow(h, TRUE); - SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); - - h=GetDlgItem(hdlg, IDC_CHECKXTIDE); - SendMessage(h, BM_SETCHECK, enable_xtide, 0); - - h=GetDlgItem(hdlg, IDC_CHECKFPU); - SendMessage(h, BM_SETCHECK, enable_external_fpu, 0); - - h = GetDlgItem(hdlg, IDC_COMBOSPD); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"8-bit"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Slow 16-bit"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Fast 16-bit"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Slow VLB/PCI"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Mid VLB/PCI"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"Fast VLB/PCI"); - SendMessage(h, CB_SETCURSEL, video_speed, 0); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); - SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[romset]].min_ram << 16) | models[romstomodel[romset]].max_ram); - accel.nSec = 0; - accel.nInc = models[model].ram_granularity; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - if (!(models[model].flags & MODEL_AT)) - SendMessage(h, UDM_SETPOS, 0, mem_size); - else - SendMessage(h, UDM_SETPOS, 0, mem_size / 1024); - - h = GetDlgItem(hdlg, IDC_CONFIGUREMOD); - if (model_getdevice(model)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); - if (video_card_has_config(video_old_to_new(gfxcard))) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURESND); - if (sound_card_has_config(sound_card_current)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURENET); - if (network_card_has_config(network_card_current)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBODR1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 360k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M Dual RPM"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 720k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M PS/2"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.25M PC-98"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M 3-Mode"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 2.88M"); - SendMessage(h, CB_SETCURSEL, fdd_get_type(0), 0); - h = GetDlgItem(hdlg, IDC_COMBODR2); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 360k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M Dual RPM"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 720k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M PS/2"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.25M PC-98"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M 3-Mode"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 2.88M"); - SendMessage(h, CB_SETCURSEL, fdd_get_type(1), 0); - h = GetDlgItem(hdlg, IDC_COMBODR3); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 360k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M Dual RPM"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 720k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M PS/2"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.25M PC-98"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M 3-Mode"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 2.88M"); - SendMessage(h, CB_SETCURSEL, fdd_get_type(2), 0); - h = GetDlgItem(hdlg, IDC_COMBODR4); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 360k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5.25\" 1.2M Dual RPM"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 720k"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M PS/2"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.25M PC-98"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 1.44M 3-Mode"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3.5\" 2.88M"); - SendMessage(h, CB_SETCURSEL, fdd_get_type(3), 0); - - h = GetDlgItem(hdlg, IDC_TEXT_MB); - if (models[model].flags & MODEL_AT) - SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"MB"); - else - SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"KB"); - - h = GetDlgItem(hdlg, IDC_COMBOJOY); - c = 0; - while (joystick_get_name(c)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)joystick_get_name(c)); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, joystick_type, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(joystick_type) >= 4) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_COMBOWS); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"System default"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"0 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"1 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"2 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"3 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"4 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"5 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"6 W/S"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"7 W/S"); - SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); - cpu_type = models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].cpu_type; - if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBOMOUSE); - c = d = 0; - while (1) - { - char *s = mouse_get_name(c); - int type; - - if (!s) - break; - - type = mouse_get_type(c); - - settings_mouse_to_list[c] = d; - - if (mouse_valid(type, model)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - - settings_list_to_mouse[d] = c; - d++; - } - c++; - } - - SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[mouse_type], 0); - - recalc_hdd_list(hdlg, romstomodel[romset], 0); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - h = GetDlgItem(hdlg, IDC_COMBO1); - temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)temp_str); - sscanf(temp_str, "%i", &mem); - mem &= ~(models[temp_model].ram_granularity - 1); - if (mem < models[temp_model].min_ram) - mem = models[temp_model].min_ram; - else if (mem > models[temp_model].max_ram) - mem = models[temp_model].max_ram; - if (models[temp_model].flags & MODEL_AT) - mem *= 1024; - - h = GetDlgItem(hdlg, IDC_COMBOVID); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str); - gfx = video_new_to_old(video_card_getid(temp_str)); - - h = GetDlgItem(hdlg, IDC_COMBOCPUM); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO3); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - fpu = (models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type >= CPU_i486DX) ? 1 : 0; - - h = GetDlgItem(hdlg, IDC_CHECK3); - temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKGUS); - temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKSSI); - temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKSYNC); - enable_sync = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKVOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKBUSLOGIC); - temp_buslogic = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CHECKDYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKXTIDE); - temp_xtide = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKFPU); - temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_network_card_current = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBODR1); - temp_fd1_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBODR2); - temp_fd2_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBODR3); - temp_fd3_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBODR4); - temp_fd4_type = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBOMOUSE); - temp_mouse_type = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBOHDD); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (temp_model != model || gfx != gfxcard || mem != mem_size || temp_cpu != cpu || temp_cpu_m != cpu_manufacturer || - fpu != hasfpu || temp_GAMEBLASTER != GAMEBLASTER || temp_GUS != GUS || temp_fpu != enable_external_fpu || - temp_SSI2001 != SSI2001 || temp_sound_card_current != sound_card_current || temp_xtide != enable_xtide || - temp_voodoo != voodoo_enabled || temp_buslogic != buslogic_enabled || temp_dynarec != cpu_use_dynarec || temp_mouse_type != mouse_type || - temp_fd1_type != fdd_get_type(0) || temp_fd2_type != fdd_get_type(1) || temp_fd3_type != fdd_get_type(2) || temp_fd4_type != fdd_get_type(3) || - temp_network_card_current != network_card_current || strncmp(hdd_names[c], hdd_controller_name, sizeof(hdd_controller_name)-1)) - { - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL)==IDOK) - { - savenvr(); - model = temp_model; - romset = model_getromset(); - gfxcard = gfx; - mem_size = mem; - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - GAMEBLASTER = temp_GAMEBLASTER; - GUS = temp_GUS; - SSI2001 = temp_SSI2001; - sound_card_current = temp_sound_card_current; - voodoo_enabled = temp_voodoo; - buslogic_enabled = temp_buslogic; - cpu_use_dynarec = temp_dynarec; - mouse_type = temp_mouse_type; - enable_xtide = temp_xtide; - enable_external_fpu = temp_fpu; - - fdd_set_type(0, temp_fd1_type); - fdd_set_type(1, temp_fd2_type); - fdd_set_type(2, temp_fd3_type); - fdd_set_type(3, temp_fd4_type); - - network_card_current = temp_network_card_current; - - if (hdd_names[c]) - strncpy(hdd_controller_name, hdd_names[c], sizeof(hdd_controller_name)-1); - else - strcpy(hdd_controller_name, "none"); - - mem_resize(); - loadbios(); - resetpchard(); - } - else - { - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - } - } - - h = GetDlgItem(hdlg, IDC_COMBOSPD); - video_speed = SendMessage(h, CB_GETCURSEL, 0, 0); - - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - cpu_set(); - - h = GetDlgItem(hdlg, IDC_COMBOWS); - cpu_waitstates = SendMessage(h, CB_GETCURSEL, 0, 0); - cpu_update_waitstates(); - - saveconfig(); - - speedchanged(); - - joystick_type = temp_joystick_type; - if (joystick_type != 7) gameport_update_joystick_type(); - - case IDCANCEL: - EndDialog(hdlg, 0); - pause=0; - return TRUE; - case IDC_COMBO1: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg,IDC_COMBO1); - temp_model = listtomodel[SendMessage(h,CB_GETCURSEL,0,0)]; - - /*Enable/disable gfxcard list*/ - h = GetDlgItem(hdlg, IDC_COMBOVID); - if (!models[temp_model].fixed_gfxcard) - { - char *s = video_card_getname(video_old_to_new(gfxcard)); - - EnableWindow(h, TRUE); - - c = 0; - while (1) - { - SendMessage(h, CB_GETLBTEXT, c, (LPARAM)temp_str); - if (!strcmp(temp_str, s)) - break; - c++; - } - SendMessage(h, CB_SETCURSEL, c, 0); - } - else - EnableWindow(h, FALSE); - - /*Rebuild manufacturer list*/ - h = GetDlgItem(hdlg, IDC_COMBOCPUM); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[temp_model].cpu[c].cpus != NULL && c < 4) - { - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)models[temp_model].cpu[c].name); - c++; - } - if (temp_cpu_m >= c) temp_cpu_m = c - 1; - SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); - if (c == 1) EnableWindow(h, FALSE); - else EnableWindow(h, TRUE); - - /*Rebuild CPU list*/ - h = GetDlgItem(hdlg, IDC_COMBO3); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[temp_model].cpu[temp_cpu_m].cpus[c].cpu_type != -1) - { - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)models[temp_model].cpu[temp_cpu_m].cpus[c].name); - c++; - } - if (temp_cpu >= c) temp_cpu = c - 1; - SendMessage(h, CB_SETCURSEL, temp_cpu, 0); - - h = GetDlgItem(hdlg, IDC_CHECKDYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); - - cpu_flags = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - h=GetDlgItem(hdlg, IDC_CHECKDYNAREC); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - EnableWindow(h, FALSE); - else - EnableWindow(h, TRUE); - SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); - - h = GetDlgItem(hdlg, IDC_TEXT_MB); - if (models[temp_model].flags & MODEL_AT) - SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"MB"); - else - SendMessage(h, WM_SETTEXT, 0, (LPARAM)(LPCSTR)"KB"); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)temp_str); - sscanf(temp_str, "%i", &mem); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (models[temp_model].min_ram << 16) | models[temp_model].max_ram); - mem &= ~(models[temp_model].ram_granularity - 1); - if (mem < models[temp_model].min_ram) - mem = models[temp_model].min_ram; - else if (mem > models[temp_model].max_ram) - mem = models[temp_model].max_ram; - SendMessage(h, UDM_SETPOS, 0, mem); - accel.nSec = 0; - accel.nInc = models[temp_model].ram_granularity; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - - h = GetDlgItem(hdlg, IDC_COMBOWS); - cpu_type = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGUREMOD); - if (model_getdevice(temp_model)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - h = GetDlgItem(hdlg, IDC_COMBOMOUSE); - temp_mouse_type = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) - { - char *s = mouse_get_name(c); - int type; - - if (!s) - break; - - type = mouse_get_type(c); - settings_mouse_to_list[c] = d; - - if (mouse_valid(type, temp_model)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - - settings_list_to_mouse[d] = c; - d++; - } - - c++; - } - if (mouse_valid(temp_mouse_type, temp_model)) - SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse_type], 0); - else - SendMessage(h, CB_SETCURSEL, 0, 0); - - recalc_hdd_list(hdlg, temp_model, 1); - } - break; - case IDC_COMBOCPUM: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO1); - temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; - h = GetDlgItem(hdlg, IDC_COMBOCPUM); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - - /*Rebuild CPU list*/ - h=GetDlgItem(hdlg, IDC_COMBO3); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[temp_model].cpu[temp_cpu_m].cpus[c].cpu_type != -1) - { - SendMessage(h,CB_ADDSTRING,0,(LPARAM)(LPCSTR)models[temp_model].cpu[temp_cpu_m].cpus[c].name); - c++; - } - if (temp_cpu >= c) temp_cpu = c - 1; - SendMessage(h, CB_SETCURSEL, temp_cpu, 0); - - h = GetDlgItem(hdlg, IDC_CHECKDYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); - - cpu_flags = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - h=GetDlgItem(hdlg, IDC_CHECKDYNAREC); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - EnableWindow(h, FALSE); - else - EnableWindow(h, TRUE); - SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); - - h = GetDlgItem(hdlg, IDC_COMBOWS); - cpu_type = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - - } - break; - case IDC_COMBO3: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO1); - temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; - h = GetDlgItem(hdlg, IDC_COMBOCPUM); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - h=GetDlgItem(hdlg, IDC_COMBO3); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKDYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); - - cpu_flags = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - h=GetDlgItem(hdlg, IDC_CHECKDYNAREC); - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - EnableWindow(h, FALSE); - else - EnableWindow(h, TRUE); - SendMessage(h, BM_SETCHECK, ((cpu_flags & CPU_SUPPORTS_DYNAREC) && temp_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC), 0); - - h = GetDlgItem(hdlg, IDC_COMBOWS); - cpu_type = models[temp_model].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if (cpu_type >= CPU_286 && cpu_type <= CPU_386DX) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - } - break; - - case IDC_CONFIGUREMOD: - h = GetDlgItem(hdlg, IDC_COMBO1); - temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); - break; - - case IDC_CONFIGUREVID: - h = GetDlgItem(hdlg, IDC_COMBOVID); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str); - - deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(temp_str))); - break; - - case IDC_COMBOVID: - h = GetDlgItem(hdlg, IDC_COMBOVID); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM)temp_str); - gfx = video_card_getid(temp_str); - - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); - if (video_card_has_config(gfx)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - break; - - case IDC_CONFIGURESND: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card_current)); - break; - - case IDC_COMBOSND: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card_current = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURESND); - if (sound_card_has_config(temp_sound_card_current)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - break; - - case IDC_CONFIGURENET: - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_network_card_current = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_network_card_current)); - break; - - case IDC_COMBONET: - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_network_card_current = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURENET); - if (network_card_has_config(temp_network_card_current)) - EnableWindow(h, TRUE); - else - EnableWindow(h, FALSE); - break; - - case IDC_CONFIGUREVOODOO: - deviceconfig_open(hdlg, (void *)&voodoo_device); - break; - - case IDC_CONFIGUREBUSLOGIC: - deviceconfig_open(hdlg, (void *)&BuslogicDevice); - break; - - case IDC_COMBOJOY: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick_type) >= 4) ? TRUE : FALSE); - } - break; - - case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 0, temp_joystick_type); - break; - case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 1, temp_joystick_type); - break; - case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 2, temp_joystick_type); - break; - case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick_type = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 3, temp_joystick_type); - break; - } - break; - } - return FALSE; -} - -void config_open(HWND hwnd) -{ - DialogBox(hinstance, TEXT("ConfigureDlg"), hwnd, config_dlgproc); -} diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 6a4c2acbb..b3378e1e6 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -8,7 +8,7 @@ #undef BITMAP #include #include "86box.h" -#include "resources.h" +#include "resource.h" #include "video.h" #include "win-d3d-fs.h" #include "win.h" @@ -210,12 +210,10 @@ static void d3d_fs_close_objects() static void d3d_fs_init_objects() { - HRESULT hr; D3DLOCKED_RECT dr; - int y; RECT r; - hr = d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), 0, D3DFVF_XYZRHW | D3DFVF_TEX1, D3DPOOL_MANAGED, @@ -373,11 +371,10 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) VOID* pVoid; D3DLOCKED_RECT dr; RECT window_rect; - uint32_t *p, *src; int yy; double l, t, r, b; - if (y1 == y2) + if ((y1 == y2) || (d3dTexture == NULL)) { video_blit_complete(); return; /*Nothing to do*/ @@ -396,7 +393,7 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) fatal("LockRect failed\n"); for (yy = y1; yy < y2; yy++) - memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), (uint32_t *) &(buffer32->line[yy + y][x]), w * 4); video_blit_complete(); d3dTexture->UnlockRect(0); @@ -472,11 +469,11 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) VOID* pVoid; D3DLOCKED_RECT dr; RECT window_rect; - uint32_t *p, *src; + uint32_t *p; int xx, yy; double l, t, r, b; - if (!h) + if (!h || (d3dTexture == NULL)) { video_blit_complete(); return; /*Nothing to do*/ @@ -496,7 +493,7 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) for (yy = 0; yy < h; yy++) { - uint32_t *p = (uint32_t *)(dr.pBits + (yy * dr.Pitch)); + p = (uint32_t *) &(((uint8_t *) dr.pBits)[yy * dr.Pitch]); if ((y + yy) >= 0 && (y + yy) < buffer->h) { for (xx = 0; xx < w; xx++) @@ -575,13 +572,12 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) void d3d_fs_take_screenshot(char *fn) { - HRESULT hr = D3D_OK; LPDIRECT3DSURFACE9 d3dSurface = NULL; if (!d3dTexture) return; - hr = d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - hr = D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); d3dSurface->Release(); d3dSurface = NULL; diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 03292c61a..561873c58 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -6,7 +6,7 @@ #include #undef BITMAP #include -#include "resources.h" +#include "resource.h" #include "win-d3d.h" #include "video.h" #include "win-cgapal.h" @@ -49,7 +49,6 @@ static CUSTOMVERTEX d3d_verts[] = int d3d_init(HWND h) { - int c; HRESULT hr; cgapal_rebuild(); @@ -108,12 +107,10 @@ void d3d_close_objects() void d3d_init_objects() { - HRESULT hr; D3DLOCKED_RECT dr; - int y; RECT r; - hr = d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), 0, D3DFVF_XYZRHW | D3DFVF_TEX1, D3DPOOL_MANAGED, @@ -146,8 +143,6 @@ void d3d_init_objects() void d3d_resize(int x, int y) { - HRESULT hr; - d3dpp.BackBufferWidth = x; d3dpp.BackBufferHeight = y; @@ -219,13 +214,12 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) VOID* pVoid; D3DLOCKED_RECT dr; RECT r; - uint32_t *p, *src; int yy; - if (y1 == y2) - { + if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (y1 == y2) || (y1 < 0) || (y1 > 2048) || (y2 < 0) || (y2 > 2048) || (d3dTexture == NULL)) + { video_blit_complete(); - return; /*Nothing to do*/ + return; /*Nothing to do*/ } r.top = y1; @@ -239,7 +233,7 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) fatal("LockRect failed\n"); for (yy = y1; yy < y2; yy++) - memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); video_blit_complete(); d3dTexture->UnlockRect(0); @@ -301,11 +295,11 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) VOID* pVoid; D3DLOCKED_RECT dr; RECT r; - uint32_t *p, *src; + uint32_t *p; int yy, xx; HRESULT hr = D3D_OK; - if (h == 0) + if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (d3dTexture == NULL)) { video_blit_complete(); return; /*Nothing to do*/ @@ -320,10 +314,10 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) { if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - + for (yy = 0; yy < h; yy++) { - uint32_t *p = (uint32_t *)(dr.pBits + (yy * dr.Pitch)); + p = (uint32_t *) &((((uint8_t *) dr.pBits)[yy * dr.Pitch])); if ((y + yy) >= 0 && (y + yy) < buffer->h) { for (xx = 0; xx < w; xx++) @@ -388,13 +382,12 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) void d3d_take_screenshot(char *fn) { - HRESULT hr = D3D_OK; LPDIRECT3DSURFACE9 d3dSurface = NULL; if (!d3dTexture) return; - hr = d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - hr = D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); d3dSurface->Release(); d3dSurface = NULL; diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index b64447b51..9c7bedbb0 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -36,8 +36,6 @@ static int ddraw_w, ddraw_h; int ddraw_fs_init(HWND h) { - int c; - ddraw_w = GetSystemMetrics(SM_CXSCREEN); ddraw_h = GetSystemMetrics(SM_CYSCREEN); @@ -180,6 +178,12 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h HRESULT hr; DDBLTFX ddbltfx; + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -197,7 +201,7 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h } for (yy = y1; yy < y2; yy++) { - if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), ((uint32_t *) &(((uint8_t *)buffer32->line[y + yy]))[x]), w * 4); } video_blit_complete(); lpdds_back->Unlock(NULL); @@ -253,6 +257,12 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) HRESULT hr; DDBLTFX ddbltfx; + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -273,7 +283,7 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) { if ((y + yy) >= 0 && (y + yy) < buffer->h) { - uint32_t *p = (uint32_t *)(ddsd.lpSurface + (yy * ddsd.lPitch)); + uint32_t *p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); for (xx = 0; xx < w; xx++) { p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc index 353b00705..55c2ff730 100644 --- a/src/win-ddraw-screenshot.cc +++ b/src/win-ddraw-screenshot.cc @@ -122,7 +122,7 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; - bmpFileHeader.bfType='MB'; + bmpFileHeader.bfType=0x4D42; bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 6b7ca19e9..347c6a752 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -36,8 +36,6 @@ static HWND ddraw_hwnd; int ddraw_init(HWND h) { - int c; - cgapal_rebuild(); if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) @@ -136,6 +134,12 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) HRESULT hr; // pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -154,7 +158,7 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) for (yy = y1; yy < y2; yy++) { if ((y + yy) >= 0 && (y + yy) < buffer->h) - memcpy(ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); } video_blit_complete(); lpdds_back->Unlock(NULL); @@ -180,6 +184,7 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) if (readflash) { readflash = 0; +#ifdef LEGACY_READ_FLASH if (enable_flash) { hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); @@ -192,11 +197,12 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) if (!ddsd.lpSurface) return; for (yy = 8; yy < 14; yy++) { - p = (uint32_t *)(ddsd.lpSurface + (yy * ddsd.lPitch)); + p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); for (xx = (w - 40); xx < (w - 8); xx++) p[xx] = 0xffffffff; } } +#endif } lpdds_back2->Unlock(NULL); @@ -218,6 +224,12 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) uint32_t *p; HRESULT hr; + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -238,14 +250,14 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) { if ((y + yy) >= 0 && (y + yy) < buffer->h) { - p = (uint32_t *)(ddsd.lpSurface + (yy * ddsd.lPitch)); + p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); for (xx = 0; xx < w; xx++) { p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; } } } - p = (uint32_t *)(ddsd.lpSurface + (4 * ddsd.lPitch)); + p = &(((uint32_t *) ddsd.lpSurface)[4 * ddsd.lPitch]); lpdds_back->Unlock(NULL); video_blit_complete(); @@ -282,7 +294,7 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) if (!ddsd.lpSurface) return; for (yy = 8; yy < 14; yy++) { - p = (uint32_t *)(ddsd.lpSurface + (yy * ddsd.lPitch)); + p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); for (xx = (w - 40); xx < (w - 8); xx++) p[xx] = 0xffffffff; } diff --git a/src/win-deviceconfig.c b/src/win-deviceconfig.c index bff026317..6d00a0050 100644 --- a/src/win-deviceconfig.c +++ b/src/win-deviceconfig.c @@ -9,13 +9,19 @@ #include "ibm.h" #include "config.h" #include "device.h" -#include "resources.h" +#include "plat-midi.h" +#include "resource.h" #include "win.h" static device_t *config_device; static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND h; + int val_int; + int num; + char s[80]; + switch (message) { case WM_INITDIALOG: @@ -27,11 +33,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam while (config->type != -1) { device_config_selection_t *selection = config->selection; - HWND h = GetDlgItem(hdlg, id); - int val_int; - char *val_string; - int num; - char s[80]; + h = GetDlgItem(hdlg, id); switch (config->type) { @@ -92,9 +94,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam while (config->type != -1) { device_config_selection_t *selection = config->selection; - HWND h = GetDlgItem(hdlg, id); - int val_int; - char *val_string; + h = GetDlgItem(hdlg, id); switch (config->type) { @@ -153,9 +153,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam while (config->type != -1) { device_config_selection_t *selection = config->selection; - HWND h = GetDlgItem(hdlg, id); - int val_int; - char *val_string; + h = GetDlgItem(hdlg, id); switch (config->type) { @@ -247,11 +245,11 @@ void deviceconfig_open(HWND hwnd, device_t *device) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0080; // button class + *data++ = 0x0080; /* button class */ data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; // no creation data - + *data++ = 0; /* no creation data */ + y += 20; break; @@ -270,10 +268,10 @@ void deviceconfig_open(HWND hwnd, device_t *device) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0085; // combo box class + *data++ = 0x0085; /* combo box class */ data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -291,10 +289,10 @@ void deviceconfig_open(HWND hwnd, device_t *device) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0082; // static class + *data++ = 0x0082; /* static class */ data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -311,23 +309,20 @@ void deviceconfig_open(HWND hwnd, device_t *device) dlg->cdit = (id - IDC_CONFIG_BASE) + 2; -// DEFPUSHBUTTON "OK",IDOK,64,232,50,14, WS_TABSTOP -// PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP - item = (DLGITEMTEMPLATE *)data; item->x = 20; item->y = y; item->cx = 50; item->cy = 14; - item->id = IDOK; // OK button identifier + item->id = IDOK; /* OK button identifier */ item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0080; // button class + *data++ = 0x0080; /* button class */ data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -337,15 +332,15 @@ void deviceconfig_open(HWND hwnd, device_t *device) item->y = y; item->cx = 50; item->cy = 14; - item->id = IDCANCEL; // OK button identifier + item->id = IDCANCEL; /* OK button identifier */ item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0080; // button class + *data++ = 0x0080; /* button class */ data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ dlg->cy = y + 20; diff --git a/src/win-hdconf.c b/src/win-hdconf.c deleted file mode 100644 index 73df0c97f..000000000 --- a/src/win-hdconf.c +++ /dev/null @@ -1,664 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "ide.h" -#include "resources.h" -#include "win.h" - -static int hd_changed = 0; - -static char hd_new_name[512]; -static uint64_t hd_new_spt, hd_new_hpc, hd_new_cyl; -static int hd_new_hdi; -static int new_cdrom_channel; - -int hdnew_no_update = 0; - -hard_disk_t hdnew_temp_hd; - -int hdsize_no_update = 0; - -hard_disk_t hdsize_temp_hd; - -char s[260]; - -static int hdconf_initialize_hdt_combo(HWND hdlg, hard_disk_t *internal_hd) -{ - HWND h; - int i = 0; - uint64_t size = 0; - uint64_t size_mb = 0; - uint64_t size_shift = 11; - int selection = 127; - - h = GetDlgItem(hdlg, IDC_COMBOHDT); - for (i = 0; i < 127; i++) - { - size = hdt[i][0] * hdt[i][1] * hdt[i][2]; - size_mb = size >> size_shift; - sprintf(s, "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")", size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)s); - if ((internal_hd->tracks == hdt[i][0]) && (internal_hd->hpc == hdt[i][1]) && (internal_hd->spt == hdt[i][2])) - { - selection = i; - } - } - sprintf(s, "Custom..."); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)s); - SendMessage(h, CB_SETCURSEL, selection, 0); - return selection; -} - -static void hdconf_update_text_boxes(HWND hdlg, BOOL enable) -{ - HWND h; - - h=GetDlgItem(hdlg, IDC_EDIT1); - EnableWindow(h, enable); - h=GetDlgItem(hdlg, IDC_EDIT2); - EnableWindow(h, enable); - h=GetDlgItem(hdlg, IDC_EDIT3); - EnableWindow(h, enable); - h=GetDlgItem(hdlg, IDC_EDIT4); - EnableWindow(h, enable); -} - -void hdconf_set_text_boxes(HWND hdlg, hard_disk_t *internal_hd) -{ - HWND h; - - uint64_t size_shift = 11; - - h = GetDlgItem(hdlg, IDC_EDIT1); - sprintf(s, "%" PRIu64, internal_hd->spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT2); - sprintf(s, "%" PRIu64, internal_hd->hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT3); - sprintf(s, "%" PRIu64, internal_hd->tracks); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - h = GetDlgItem(hdlg, IDC_EDIT4); - sprintf(s, "%" PRIu64, (internal_hd->spt * internal_hd->hpc * internal_hd->tracks) >> size_shift); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); -} - -BOOL hdconf_initdialog_common(HWND hdlg, hard_disk_t *internal_hd, int *no_update, uint64_t spt, uint64_t hpc, uint64_t tracks) -{ - HWND h; - int selection = 127; - - internal_hd->spt = spt; - internal_hd->hpc = hpc; - internal_hd->tracks = tracks; - *no_update = 1; - - hdconf_set_text_boxes(hdlg, internal_hd); - - selection = hdconf_initialize_hdt_combo(hdlg, internal_hd); - - if (selection < 127) - { - hdconf_update_text_boxes(hdlg, FALSE); - } - else - { - hdconf_update_text_boxes(hdlg, TRUE); - } - - *no_update = 0; - - return TRUE; -} - -int hdconf_idok_common(HWND hdlg) -{ - HWND h; - - h = GetDlgItem(hdlg, IDC_EDIT1); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &hd_new_spt); - h = GetDlgItem(hdlg, IDC_EDIT2); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &hd_new_hpc); - h = GetDlgItem(hdlg, IDC_EDIT3); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &hd_new_cyl); - - if (hd_new_spt > 63) - { - MessageBox(ghwnd, "Drive has too many sectors (maximum is 63)", "86Box error", MB_OK); - return 1; - } - if (hd_new_hpc > 16) - { - MessageBox(ghwnd, "Drive has too many heads (maximum is 16)", "86Box error", MB_OK); - return 1; - } - if (hd_new_cyl > 266305) - { - MessageBox(ghwnd, "Drive has too many cylinders (maximum is 266305)", "86Box error", MB_OK); - return 1; - } - - return 0; -} - -BOOL hdconf_process_edit_boxes(HWND hdlg, WORD control, uint64_t *var, hard_disk_t *internal_hd, int *no_update) -{ - HWND h; - uint64_t size_shift = 11; - - if (*no_update) - { - return FALSE; - } - - h = GetDlgItem(hdlg, control); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, var); - - *no_update = 1; - if(!(*var)) - { - *var = 1; - sprintf(s, "%" PRIu64, *var); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - } - - if (control == IDC_EDIT4) - { - *var <<= 11; /* Convert to sectors */ - *var /= internal_hd->hpc; - *var /= internal_hd->spt; - internal_hd->tracks = *var; - - h = GetDlgItem(hdlg, IDC_EDIT3); - sprintf(s, "%" PRIu64, internal_hd->tracks); - SendMessage(h, WM_SETTEXT, 1, (LPARAM)s); - } - else if ((control >= IDC_EDIT1) && (control <= IDC_EDIT3)) - { - h = GetDlgItem(hdlg, IDC_EDIT4); - sprintf(s, "%" PRIu64, (internal_hd->spt * internal_hd->hpc * internal_hd->tracks) >> size_shift); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - } - - *no_update = 0; - return TRUE; -} - -BOOL hdconf_process_hdt_combo(HWND hdlg, hard_disk_t *internal_hd, int *no_update, WPARAM wParam) -{ - HWND h; - int selection = 127; - - if (*no_update) - { - return FALSE; - } - - if (HIWORD(wParam) == CBN_SELCHANGE) - { - *no_update = 1; - - h = GetDlgItem(hdlg,IDC_COMBOHDT); - selection = SendMessage(h,CB_GETCURSEL,0,0); - - if (selection < 127) - { - hdconf_update_text_boxes(hdlg, FALSE); - - internal_hd->tracks = hdt[selection][0]; - internal_hd->hpc = hdt[selection][1]; - internal_hd->spt = hdt[selection][2]; - - hdconf_set_text_boxes(hdlg, internal_hd); - } - else - { - hdconf_update_text_boxes(hdlg, TRUE); - } - - *no_update = 0; - } - else - { - return FALSE; - } - - return TRUE; -} - -BOOL CALLBACK hdconf_common_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam, int type, hard_disk_t *internal_hd, int *no_update, uint64_t spt, uint64_t hpc, uint64_t tracks) -{ - HWND h; - uint64_t c; - FILE *f; - uint8_t buf[512]; - int is_hdi; - int is_hdx; - uint64_t size; - uint64_t signature = 0xD778A82044445459; - uint32_t zero = 0; - uint32_t sector_size = 512; - uint32_t base = 0x1000; - uint64_t full_size = 0; - uint64_t full_size_bytes = 0; - uint64_t size_shift = 11; - int selection = 127; - switch (message) - { - case WM_INITDIALOG: - if (!type) - { - h = GetDlgItem(hdlg, IDC_EDITC); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)""); - } - return hdconf_initdialog_common(hdlg, internal_hd, no_update, spt, hpc, tracks); - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - if (!type) - { - h = GetDlgItem(hdlg, IDC_EDITC); - SendMessage(h, WM_GETTEXT, 511, (LPARAM)hd_new_name); - if (!hd_new_name[0]) - { - MessageBox(ghwnd,"Please enter a valid filename","86Box error",MB_OK); - return TRUE; - } - } - - if (hdconf_idok_common(hdlg)) - { - return TRUE; - } - - if (!type) - { - f = fopen64(hd_new_name, "wb"); - if (!f) - { - MessageBox(ghwnd, "Can't open file for write", "86Box error", MB_OK); - return TRUE; - } - full_size = (hd_new_cyl * hd_new_hpc * hd_new_spt); - full_size_bytes = full_size * 512; - if (image_is_hdi(hd_new_name)) - { - if (full_size_bytes >= 0x100000000) - { - MessageBox(ghwnd, "Drive is HDI and 4 GB or bigger (size filed in HDI header is 32-bit)", "86Box error", MB_OK); - fclose(f); - return TRUE; - } - - hd_new_hdi = 1; - - fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&full_size_bytes, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&hd_new_spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hd_new_hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&hd_new_cyl, 1, 4, f); /* 0000001C: Cylinders */ - - for (c = 0; c < 0x3f8; c++) - { - fwrite(&zero, 1, 4, f); - } - } - else if (image_is_hdx(hd_new_name, 0)) - { - if (full_size_bytes > 0xffffffffffffffff) - { - MessageBox(ghwnd, "Drive is HDX and way too big (size filed in HDX header is 64-bit)", "86Box error", MB_OK); - fclose(f); - return TRUE; - } - - hd_new_hdi = 1; - - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&full_size_bytes, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&hd_new_spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hd_new_hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&hd_new_cyl, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } - memset(buf, 0, 512); - for (c = 0; c < full_size; c++) - fwrite(buf, 512, 1, f); - fclose(f); - - MessageBox(ghwnd, "Remember to partition and format the new drive", "86Box", MB_OK); - } - - EndDialog(hdlg,1); - return TRUE; - - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!type) - { - if (!getsfile(hdlg, "Hard disc image (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0", "")) - { - h = GetDlgItem(hdlg, IDC_EDITC); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - } - return TRUE; - } - else - { - break; - } - - case IDC_EDIT1: - return hdconf_process_edit_boxes(hdlg, IDC_EDIT1, &(internal_hd->spt), internal_hd, no_update); - - case IDC_EDIT2: - return hdconf_process_edit_boxes(hdlg, IDC_EDIT2, &(internal_hd->hpc), internal_hd, no_update); - - case IDC_EDIT3: - return hdconf_process_edit_boxes(hdlg, IDC_EDIT3, &(internal_hd->tracks), internal_hd, no_update); - - case IDC_EDIT4: - return hdconf_process_edit_boxes(hdlg, IDC_EDIT4, &size, internal_hd, no_update); - - case IDC_COMBOHDT: - return hdconf_process_hdt_combo(hdlg, internal_hd, no_update, wParam); - } - break; - - } - return FALSE; -} - -static BOOL CALLBACK hdnew_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - return hdconf_common_dlgproc(hdlg, message, wParam, lParam, 0, &hdnew_temp_hd, &hdnew_no_update, 63, 16, 511); -} - -BOOL CALLBACK hdsize_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - return hdconf_common_dlgproc(hdlg, message, wParam, lParam, 1, &hdsize_temp_hd, &hdsize_no_update, hd_new_spt, hd_new_hpc, hd_new_cyl); -} - -static void hdconf_eject(HWND hdlg, int drive_num, hard_disk_t *hd) -{ - hd->spt = 0; - hd->hpc = 0; - hd->tracks = 0; - ide_fn[drive_num][0] = 0; - SetDlgItemText(hdlg, IDC_EDIT_C_SPT + drive_num, "0"); - SetDlgItemText(hdlg, IDC_EDIT_C_HPC + drive_num, "0"); - SetDlgItemText(hdlg, IDC_EDIT_C_CYL + drive_num, "0"); - SetDlgItemText(hdlg, IDC_EDIT_C_FN + drive_num, ""); - hd_changed = 1; - return; -} - -static void hdconf_new(HWND hdlg, int drive_num) -{ - HWND h; - - if (DialogBox(hinstance, TEXT("HdNewDlg"), hdlg, hdnew_dlgproc) == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT + drive_num); - sprintf(s, "%" PRIu64, hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC + drive_num); - sprintf(s, "%" PRIu64, hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL + drive_num); - sprintf(s, "%" PRIu64, hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN + drive_num); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)hd_new_name); - - h= GetDlgItem(hdlg, IDC_TEXT_C_SIZE + drive_num); - sprintf(s, "Size: %" PRIu64 " MB", (hd_new_cyl*hd_new_hpc*hd_new_spt) >> 11); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - return; -} - -static void hdconf_file(HWND hdlg, int drive_num) -{ - HWND h; - FILE *f; - off64_t sz; - uint32_t sector_size = 512; - uint32_t base = 0x1000; - int ret; - - if (!getfile(hdlg, "Hard disc image (*.HDI;*.HDX;*.IMA;*.IMG;*.VHD)\0*.HDI;*.HDX;*.IMA;*.IMG;*.VHD\0All files (*.*)\0*.*\0", "")) - { - f = fopen64(openfilestring, "rb"); - if (!f) - { - MessageBox(ghwnd,"Can't open file for read","86Box error",MB_OK); - return; - } - - if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) - { - fseeko64(f, 0x10, SEEK_SET); - fread(§or_size, 1, 4, f); - if (sector_size != 512) - { - MessageBox(ghwnd,"HDI or HDX image with a sector size that is not 512","86Box error",MB_OK); - fclose(f); - return; - } - fread(&hd_new_spt, 1, 4, f); - fread(&hd_new_hpc, 1, 4, f); - fread(&hd_new_cyl, 1, 4, f); - - ret = 1; - } - else - { - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - hd_new_spt = 63; - hd_new_hpc = 16; - hd_new_cyl = ((sz / 512) / 16) / 63; - - ret = DialogBox(hinstance, TEXT("HdSizeDlg"), hdlg, hdsize_dlgproc); - } - if (ret == 1) - { - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT + drive_num); - sprintf(s, "%" PRIu64, hd_new_spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC + drive_num); - sprintf(s, "%" PRIu64, hd_new_hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL + drive_num); - sprintf(s, "%" PRIu64, hd_new_cyl); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN + drive_num); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)openfilestring); - - h = GetDlgItem(hdlg, IDC_TEXT_C_SIZE + drive_num); - sprintf(s, "Size: %" PRIu64 " MB", (hd_new_cyl*hd_new_hpc*hd_new_spt) >> 11); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - - hd_changed = 1; - } - } - return; -} - -static void hdconf_edit_boxes(HWND hdlg, int drive_num, hard_disk_t *hd) -{ - HWND h; - - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT + drive_num); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &(hd->spt)); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC + drive_num); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &(hd->hpc)); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL + drive_num); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &(hd->tracks)); - - h = GetDlgItem(hdlg, IDC_TEXT_C_SIZE + drive_num); - sprintf(s, "Size: %" PRIu64 " MB", (hd->tracks*hd->hpc*hd->spt) >> 11); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - return; -} - -static BOOL CALLBACK hdconf_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - hard_disk_t hd[IDE_NUM]; - int drive_num = 0; - switch (message) - { - case WM_INITDIALOG: - pause = 1; - - for (drive_num = 0; drive_num < IDE_NUM; drive_num++) - { - hd[drive_num] = hdc[drive_num]; - - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT + drive_num); - sprintf(s, "%" PRIu64, hdc[drive_num].spt); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC + drive_num); - sprintf(s, "%" PRIu64, hdc[drive_num].hpc); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL + drive_num); - sprintf(s, "%" PRIu64, hdc[drive_num].tracks); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN + drive_num); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)ide_fn[drive_num]); - - h = GetDlgItem(hdlg, IDC_TEXT_C_SIZE + drive_num); - sprintf(s, "Size: %" PRIu64 " MB", (hd[drive_num].tracks*hd[drive_num].hpc*hd[drive_num].spt) >> 11); - SendMessage(h, WM_SETTEXT, 0, (LPARAM)s); - } - - hd_changed = 0; - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - if (hd_changed) - { - if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) == IDOK) - { - for (drive_num = 0; drive_num < IDE_NUM; drive_num++) - { - h = GetDlgItem(hdlg, IDC_EDIT_C_SPT + drive_num); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &hd[drive_num].spt); - h = GetDlgItem(hdlg, IDC_EDIT_C_HPC + drive_num); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &hd[drive_num].hpc); - h = GetDlgItem(hdlg, IDC_EDIT_C_CYL + drive_num); - SendMessage(h, WM_GETTEXT, 255, (LPARAM)s); - sscanf(s, "%" PRIu64, &hd[drive_num].tracks); - h = GetDlgItem(hdlg, IDC_EDIT_C_FN + drive_num); - SendMessage(h, WM_GETTEXT, 511, (LPARAM)ide_fn[drive_num]); - - hdc[drive_num] = hd[drive_num]; - } - - saveconfig(); - - resetpchard(); - } - } - case IDCANCEL: - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - - case IDC_EJECTC: - case IDC_EJECTD: - case IDC_EJECTE: - case IDC_EJECTF: - case IDC_EJECTG: - case IDC_EJECTH: - case IDC_EJECTI: - case IDC_EJECTJ: - drive_num = LOWORD(wParam) % 10; - hdconf_eject(hdlg, drive_num, &(hd[drive_num])); - return TRUE; - - case IDC_CNEW: - case IDC_DNEW: - case IDC_ENEW: - case IDC_FNEW: - case IDC_GNEW: - case IDC_HNEW: - case IDC_INEW: - case IDC_JNEW: - drive_num = LOWORD(wParam) % 10; - hdconf_new(hdlg, drive_num); - return TRUE; - - case IDC_CFILE: - case IDC_DFILE: - case IDC_EFILE: - case IDC_FFILE: - case IDC_GFILE: - case IDC_HFILE: - case IDC_IFILE: - case IDC_JFILE: - drive_num = LOWORD(wParam) % 10; - hdconf_file(hdlg, drive_num); - return TRUE; - - case IDC_EDIT_C_SPT: case IDC_EDIT_C_HPC: case IDC_EDIT_C_CYL: - case IDC_EDIT_D_SPT: case IDC_EDIT_D_HPC: case IDC_EDIT_D_CYL: - case IDC_EDIT_E_SPT: case IDC_EDIT_E_HPC: case IDC_EDIT_E_CYL: - case IDC_EDIT_F_SPT: case IDC_EDIT_F_HPC: case IDC_EDIT_F_CYL: - case IDC_EDIT_G_SPT: case IDC_EDIT_G_HPC: case IDC_EDIT_G_CYL: - case IDC_EDIT_H_SPT: case IDC_EDIT_H_HPC: case IDC_EDIT_H_CYL: - case IDC_EDIT_I_SPT: case IDC_EDIT_I_HPC: case IDC_EDIT_I_CYL: - case IDC_EDIT_J_SPT: case IDC_EDIT_J_HPC: case IDC_EDIT_J_CYL: - drive_num = LOWORD(wParam) % 10; - hdconf_edit_boxes(hdlg, drive_num, &(hd[drive_num])); - return TRUE; - } - break; - - } - return FALSE; -} - -void hdconf_open(HWND hwnd) -{ - if (hdd_controller_current_is_mfm()) - DialogBox(hinstance, TEXT("HdConfDlgMfm"), hwnd, hdconf_dlgproc); - else - DialogBox(hinstance, TEXT("HdConfDlg"), hwnd, hdconf_dlgproc); -} diff --git a/src/win-joystick.cc b/src/win-joystick.cc index 12c94e396..13cc3c1ff 100644 --- a/src/win-joystick.cc +++ b/src/win-joystick.cc @@ -111,7 +111,6 @@ void joystick_init() DIPROPRANGE joy_axis_range; DIDEVICEINSTANCE device_instance; DIDEVCAPS devcaps; - int d; if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL))) fatal("joystick_init : CreateDevice failed\n"); diff --git a/src/win-joystickconfig.c b/src/win-joystickconfig.c index 8c75d303f..cabb75358 100644 --- a/src/win-joystickconfig.c +++ b/src/win-joystickconfig.c @@ -151,14 +151,21 @@ static int get_pov(HWND hdlg, int id) static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND h; + int c; + int id; + int joystick; + int nr_axes; + int nr_povs; + int mapping; + switch (message) { case WM_INITDIALOG: { - HWND h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - int c, d; - int id = IDC_CONFIG_BASE + 2; - int joystick = joystick_state[joystick_nr].plat_joystick_nr; + h = GetDlgItem(hdlg, IDC_CONFIG_BASE); + id = IDC_CONFIG_BASE + 2; + joystick = joystick_state[joystick_nr].plat_joystick_nr; SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); @@ -171,8 +178,8 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar if (joystick_state[joystick_nr].plat_joystick_nr) { - int nr_axes = plat_joystick_state[joystick-1].nr_axes; - int nr_povs = plat_joystick_state[joystick-1].nr_povs; + nr_axes = plat_joystick_state[joystick-1].nr_axes; + nr_povs = plat_joystick_state[joystick-1].nr_povs; for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) { int mapping = joystick_state[joystick_nr].axis_mapping[c]; @@ -194,8 +201,6 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar } for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) { - int mapping; - h = GetDlgItem(hdlg, id); mapping = joystick_state[joystick_nr].pov_mapping[c][0]; if (mapping & POV_X) @@ -229,10 +234,7 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar case IDOK: { - HWND h; - int joystick; - int c, d; - int id = IDC_CONFIG_BASE + 2; + id = IDC_CONFIG_BASE + 2; h = GetDlgItem(hdlg, IDC_CONFIG_BASE); joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -272,7 +274,6 @@ static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wPar void joystickconfig_open(HWND hwnd, int joy_nr, int type) { -// device_config_t *config = device->config; uint16_t *data_block = malloc(16384); uint16_t *data; DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block; @@ -318,10 +319,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0085; // combo box class + *data++ = 0x0085; /* combo box class */ data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -339,10 +340,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0082; // static class + *data++ = 0x0082; /* static class */ data += MultiByteToWideChar(CP_ACP, 0, "Device :", -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -365,10 +366,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0085; // combo box class + *data++ = 0x0085; /* combo box class */ data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -386,10 +387,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0082; // static class + *data++ = 0x0082; /* static class */ data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -412,10 +413,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0085; // combo box class + *data++ = 0x0085; /* combo box class */ data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -433,10 +434,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0082; // static class + *data++ = 0x0082; /* static class */ data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -461,14 +462,14 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0085; // combo box class + *data++ = 0x0085; /* combo box class */ if (c & 1) sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2)); else sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2)); data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -486,10 +487,10 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0082; // static class + *data++ = 0x0082; /* static class */ data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -499,23 +500,20 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) dlg->cdit = (id - IDC_CONFIG_BASE) + 2; -// DEFPUSHBUTTON "OK",IDOK,64,232,50,14, WS_TABSTOP -// PUSHBUTTON "Cancel",IDCANCEL,128,232,50,14, WS_TABSTOP - item = (DLGITEMTEMPLATE *)data; item->x = 20; item->y = y; item->cx = 50; item->cy = 14; - item->id = IDOK; // OK button identifier + item->id = IDOK; /* OK button identifier */ item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0080; // button class + *data++ = 0x0080; /* button class */ data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ if (((unsigned long)data) & 2) data++; @@ -525,20 +523,18 @@ void joystickconfig_open(HWND hwnd, int joy_nr, int type) item->y = y; item->cx = 50; item->cy = 14; - item->id = IDCANCEL; // OK button identifier + item->id = IDCANCEL; /* OK button identifier */ item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; data = (uint16_t *)(item + 1); *data++ = 0xFFFF; - *data++ = 0x0080; // button class + *data++ = 0x0080; /* button class */ data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; // no creation data + *data++ = 0; /* no creation data */ dlg->cy = y + 20; - -// config_device = device; - + DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc); free(data_block); diff --git a/src/win-language.c b/src/win-language.c new file mode 100644 index 000000000..353fb1302 --- /dev/null +++ b/src/win-language.c @@ -0,0 +1,179 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include + +#include "ibm.h" +#include "device.h" +#include "ide.h" +#include "resource.h" +#include "win.h" +#include "win-language.h" + +LCID dwLanguage; + +uint32_t dwLangID, dwSubLangID; + +#define STRINGS_NUM 148 + +WCHAR lpResourceString[STRINGS_NUM][512]; + +char openfilestring[260]; + +void win_language_set() +{ + SetThreadLocale(dwLanguage); +} + +void win_language_load_common_strings() +{ + int i = 0; + + for (i = 0; i < STRINGS_NUM; i++) + { + LoadString(hinstance, 2048 + i, lpResourceString[i], 512); + } +} + +LPTSTR win_language_get_settings_category(int i) +{ + return lpResourceString[17 + i]; +} + +void win_language_update() +{ + win_language_set(); + win_menu_update(); + win_language_load_common_strings(); +} + +void win_language_check() +{ + LCID dwLanguageNew = MAKELCID(dwLangID, dwSubLangID); + if (dwLanguageNew != dwLanguage) + { + dwLanguage = dwLanguageNew; + win_language_update(); + } +} + +LPTSTR win_language_get_string_from_id(int i) +{ + return lpResourceString[i - 2048]; +} + +LPTSTR win_language_get_string_from_string(char *str) +{ + return lpResourceString[atoi(str) - 2048]; +} + +int msgbox_reset(HWND hwndParent) +{ + return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION); +} + +int msgbox_reset_yn(HWND hwndParent) +{ + return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION); +} + +int msgbox_question(HWND hwndParent, int i) +{ + return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION); +} + +void msgbox_info(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + +void msgbox_error(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); +} + +void msgbox_critical(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR); +} + +void msgbox_fatal(HWND hwndParent, char *string) +{ + LPTSTR lptsTemp; + lptsTemp = (LPTSTR) malloc(512); + + mbstowcs(lptsTemp, string, strlen(string) + 1); + + MessageBox(hwndParent, lptsTemp, lpResourceString[2], MB_OK | MB_ICONERROR); + + free(lptsTemp); +} + +int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) +{ + OPENFILENAME ofn; /* common dialog box structure */ + BOOL r; + DWORD err; + WCHAR ufn[260]; + WCHAR uofs[260]; + + /* Convert file name to Unicode */ + mbstowcs(ufn, fn, strlen(fn) + 1); + + /* Initialize OPENFILENAME */ + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFile = uofs; + /* + Set lpstrFile[0] to '\0' so that GetOpenFileName does not + use the contents of szFile to initialize itself. + */ + memcpy(ofn.lpstrFile, ufn, (wcslen(ufn) << 1) + 2); + ofn.nMaxFile = 259; + ofn.lpstrFilter = f; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST; + if (!save) + { + ofn.Flags |= OFN_FILEMUSTEXIST; + } + + /* Display the Open dialog box. */ + + if (save) + { + pclog("GetSaveFileName - lpstrFile = %s\n", ofn.lpstrFile); + r = GetSaveFileName(&ofn); + } + else + { + pclog("GetOpenFileName - lpstrFile = %s\n", ofn.lpstrFile); + r = GetOpenFileName(&ofn); + } + if (r) + { + wcstombs(openfilestring, uofs, 520); + pclog("File dialog return true\n"); + return 0; + } + pclog("File dialog return false\n"); + err = CommDlgExtendedError(); + pclog("CommDlgExtendedError return %04X\n", err); + return 1; +} + +int file_dlg_st(HWND hwnd, int i, char *fn, int save) +{ + file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); +} diff --git a/src/win-language.h b/src/win-language.h new file mode 100644 index 000000000..47fde8df8 --- /dev/null +++ b/src/win-language.h @@ -0,0 +1,19 @@ +int msgbox_reset(HWND hwndParent); +int msgbox_reset_yn(HWND hwndParent); +int msgbox_question(HWND hwndParent, int i); +void msgbox_info(HWND hwndParent, int i); +void msgbox_error(HWND hwndParent, int i); +void msgbox_fatal(HWND hwndParent, char *string); +void msgbox_critical(HWND hwndParent, int i); + +int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save); +int file_dlg_st(HWND hwnd, int i, char *fn, int save); + +void win_language_load_common_strings(); +LPTSTR win_language_get_settings_category(int i); + +void win_language_update(); +void win_language_check(); + +LPTSTR win_language_get_string_from_id(int i); +LPTSTR win_language_get_string_from_string(char *str); diff --git a/src/win-midi.c b/src/win-midi.c index bb0bc2d78..8fa56c768 100644 --- a/src/win-midi.c +++ b/src/win-midi.c @@ -4,6 +4,7 @@ #include #include #include "ibm.h" +#include "config.h" #include "plat-midi.h" static int midi_id; @@ -13,9 +14,6 @@ void midi_close(); void midi_init() { - int c; - int n; - MIDIOUTCAPS ocaps; MMRESULT hr; midi_id = config_get_int(NULL, "midi", 0); @@ -62,12 +60,11 @@ static int midi_pos, midi_len; static uint32_t midi_command; static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; static int midi_insysex; -static uint8_t midi_sysex_data[1024+2]; +static char midi_sysex_data[1024+2]; static void midi_send_sysex() { MIDIHDR hdr; - int c; hdr.lpData = midi_sysex_data; hdr.dwBufferLength = midi_pos; diff --git a/src/win-settings.c b/src/win-settings.c new file mode 100644 index 000000000..4790ce717 --- /dev/null +++ b/src/win-settings.c @@ -0,0 +1,3502 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include + +#include + +#include "nethandler.h" +#include "ibm.h" +#include "ide.h" +#include "cdrom.h" +#include "cpu.h" +#include "device.h" +#include "scsi_buslogic.h" +#include "disc.h" +#include "fdd.h" +#include "gameport.h" +#include "hdd.h" +#include "mem.h" +#include "model.h" +#include "mouse.h" +#include "nvr.h" +#include "resource.h" +#include "scsi.h" +#include "sound.h" +#include "sound_dbopl.h" +#include "video.h" +#include "vid_voodoo.h" +#include "win.h" +#include "win-language.h" + +#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + +/* Machine category */ +int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; + +/* Video category */ +int temp_gfxcard, temp_video_speed, temp_voodoo; + +/* Input devices category */ +int temp_mouse, temp_joystick; + +/* Sound category */ +int temp_sound_card, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; + +/* Peripherals category */ +int temp_scsi_card, temp_net_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; +int temp_serial[2], temp_lpt, temp_bugger; + +char temp_hdc_name[16]; + +/* Hard disks category */ +hard_disk_t temp_hdc[HDC_NUM]; +char temp_hdd_fn[HDC_NUM][512]; + +/* Removable devices category */ +int temp_fdd_types[FDD_NUM]; +cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; + +static HWND hwndParentDialog, hwndChildDialog; + +int hdd_controller_current; + +int displayed_category = 0; + +extern int is486; +static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; +static int settings_sound_to_list[20], settings_list_to_sound[20]; +static int settings_mouse_to_list[20], settings_list_to_mouse[20]; +static int settings_scsi_to_list[20], settings_list_to_scsi[20]; +static int settings_network_to_list[20], settings_list_to_network[20]; +static char *hdd_names[16]; + +/* This does the initial read of global variables into the temporary ones. */ +static void win_settings_init() +{ + int i = 0; + + /* Machine category */ + temp_model = model; + temp_cpu_m = cpu_manufacturer; + temp_cpu = cpu; + temp_mem_size = mem_size; + temp_dynarec = cpu_use_dynarec; + temp_fpu = enable_external_fpu; + temp_sync = enable_sync; + + /* Video category */ + temp_gfxcard = gfxcard; + temp_video_speed = video_speed; + temp_voodoo = voodoo_enabled; + + /* Input devices category */ + temp_mouse = mouse_type; + temp_joystick = joystick_type; + + /* Sound category */ + temp_sound_card = sound_card_current; + temp_SSI2001 = SSI2001; + temp_GAMEBLASTER = GAMEBLASTER; + temp_GUS = GUS; + temp_opl3_type = opl3_type; + + /* Peripherals category */ + temp_scsi_card = scsi_card_current; + temp_net_card = network_card_current; + strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + temp_ide_ter = ide_enable[2]; + temp_ide_ter_irq = ide_irq[2]; + temp_ide_qua = ide_enable[3]; + temp_ide_qua_irq = ide_irq[3]; + temp_serial[0] = serial_enabled[0]; + temp_serial[1] = serial_enabled[1]; + temp_lpt = lpt_enabled; + temp_bugger = bugger_enabled; + + /* Hard disks category */ + memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(temp_hdd_fn[i], hdd_fn[i], 512); + } + + /* Removable devices category */ + for (i = 0; i < FDD_NUM; i++) + { + temp_fdd_types[i] = fdd_get_type(i); + } + memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); +} + +/* This returns 1 if any variable has changed, 0 if not. */ +static int win_settings_changed() +{ + int i = 0; + int j = 0; + + /* Machine category */ + i = i || (model != temp_model); + i = i || (cpu_manufacturer != temp_cpu_m); + i = i || (cpu != temp_cpu); + i = i || (mem_size != temp_mem_size); + i = i || (temp_dynarec != cpu_use_dynarec); + i = i || (temp_fpu != enable_external_fpu); + i = i || (temp_sync != enable_sync); + + /* Video category */ + i = i || (gfxcard != temp_gfxcard); + i = i || (video_speed != temp_video_speed); + i = i || (voodoo_enabled != temp_voodoo); + + /* Input devices category */ + i = i || (mouse_type != temp_mouse); + i = i || (joystick_type != temp_joystick); + + /* Sound category */ + i = i || (sound_card_current != temp_sound_card); + i = i || (SSI2001 != temp_SSI2001); + i = i || (GAMEBLASTER != temp_GAMEBLASTER); + i = i || (GUS != temp_GUS); + i = i || (opl3_type != temp_opl3_type); + + /* Peripherals category */ + i = i || (scsi_card_current != temp_scsi_card); + i = i || (network_card_current != temp_net_card); + i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + i = i || (temp_ide_ter != ide_enable[2]); + i = i || (temp_ide_ter_irq != ide_irq[2]); + i = i || (temp_ide_qua != ide_enable[3]); + i = i || (temp_ide_qua_irq != ide_irq[3]); + i = i || (temp_serial[0] != serial_enabled[0]); + i = i || (temp_serial[1] != serial_enabled[1]); + i = i || (temp_lpt != lpt_enabled); + i = i || (temp_bugger != bugger_enabled); + + /* Hard disks category */ + i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + for (j = 0; j < HDC_NUM; j++) + { + i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 512); + } + + /* Removable devices category */ + for (j = 0; j < FDD_NUM; j++) + { + i = i || (temp_fdd_types[j] != fdd_get_type(j)); + } + i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + + return i; +} + +static int settings_msgbox_reset() +{ + int i = 0; + int changed = 0; + + changed = win_settings_changed(); + + if (changed) + { + i = msgbox_reset(hwndParentDialog); + + if (i == IDNO) + { + return 1; + } + else if (i == IDCANCEL) + { + return 0; + } + else + { + return 2; + } + } + else +{ + return 1; + } +} + +/* This saves the settings back to the global variables. */ +static void win_settings_save() +{ + int i = 0; + + /* Machine category */ + model = temp_model; + romset = model_getromset(); + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + mem_size = temp_mem_size; + cpu_use_dynarec = temp_dynarec; + enable_external_fpu = temp_fpu; + enable_sync = temp_sync; + + /* Video category */ + gfxcard = temp_gfxcard; + video_speed = temp_video_speed; + voodoo_enabled = temp_voodoo; + + /* Input devices category */ + mouse_type = temp_mouse; + joystick_type = temp_joystick; + + /* Sound category */ + sound_card_current = temp_sound_card; + SSI2001 = temp_SSI2001; + GAMEBLASTER = temp_GAMEBLASTER; + GUS = temp_GUS; + opl3_type = temp_opl3_type; + + /* Peripherals category */ + scsi_card_current = temp_scsi_card; + network_card_current = temp_net_card; + strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); + ide_enable[2] = temp_ide_ter; + ide_irq[2] = temp_ide_ter_irq; + ide_enable[3] = temp_ide_qua; + ide_irq[3] = temp_ide_qua_irq; + serial_enabled[0] = temp_serial[0]; + serial_enabled[1] = temp_serial[1]; + lpt_enabled = temp_lpt; + bugger_enabled = temp_bugger; + + /* Hard disks category */ + memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(hdd_fn[i], temp_hdd_fn[i], 512); + } + + /* Removable devices category */ + for (i = 0; i < FDD_NUM; i++) + { + fdd_set_type(i, temp_fdd_types[i]); + } + memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + + mem_resize(); + loadbios(); + + resetpchard(); + + cpu_set(); + + cpu_update_waitstates(); + + saveconfig(); + + speedchanged(); + + if (joystick_type != 7) gameport_update_joystick_type(); + + update_status_bar_panes(hwndStatus); +} + +static void win_settings_machine_recalc_cpu(HWND hdlg) +{ + HWND h; + int temp_romset = 0; + int cpu_flags; + int cpu_type; + + temp_romset = model_getromset_ex(temp_model); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + cpu_flags = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) + { + fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); + } + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + { + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) + { + temp_dynarec = 0; + } + if (cpu_flags & CPU_REQUIRES_DYNAREC) + { + temp_dynarec = 1; + } + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } + + h = GetDlgItem(hdlg, IDC_CHECK_FPU); + cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) + { + EnableWindow(h, TRUE); + } + else if (cpu_type < CPU_286) + { + temp_fpu = 0; + EnableWindow(h, FALSE); + } + else + { + temp_fpu = 1; + EnableWindow(h, FALSE); + } + SendMessage(h, BM_SETCHECK, temp_fpu, 0); +} + +static void win_settings_machine_recalc_cpu_m(HWND hdlg) +{ + HWND h; + int c = 0; + int temp_romset = 0; + LPTSTR lptsTemp; + char *stransi; + + temp_romset = model_getromset_ex(temp_model); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + stransi = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cpu, 0); + + win_settings_machine_recalc_cpu(hdlg); + + free(lptsTemp); +} + +static void win_settings_machine_recalc_model(HWND hdlg) +{ + HWND h; + int c = 0; + int temp_romset = 0; + LPTSTR lptsTemp; + char *stransi; + UDACCEL accel; + + temp_romset = model_getromset_ex(temp_model); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); + if (model_getdevice(temp_model)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (models[romstomodel[temp_romset]].cpu[c].cpus != NULL && c < 4) + { + stransi = models[romstomodel[temp_romset]].cpu[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); + if (c == 1) + { + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } + + win_settings_machine_recalc_cpu_m(hdlg); + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[temp_romset]].min_ram << 16) | models[romstomodel[temp_romset]].max_ram); + accel.nSec = 0; + accel.nInc = models[romstomodel[temp_romset]].ram_granularity; + SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); + if (!(models[romstomodel[temp_romset]].flags & MODEL_AT)) + { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); + } + else + { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); + } + + free(lptsTemp); +} + +static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + char *stransi; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + for (c = 0; c < ROM_MAX; c++) + { + romstolist[c] = 0; + } + c = d = 0; + while (models[c].id != -1) + { + if (romspresent[models[c].id]) + { + stransi = models[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + modeltolist[c] = d; + listtomodel[d] = c; + romstolist[models[c].id] = d; + romstomodel[models[c].id] = c; + d++; + } + c++; + } + SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); + + for (c = 0; c < 8; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2132), c); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + SendMessage(h, BM_SETCHECK, temp_sync, 0); + + win_settings_machine_recalc_model(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_MACHINE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_model = listtomodel[SendMessage(h,CB_GETCURSEL,0,0)]; + + win_settings_machine_recalc_model(hdlg); + } + break; + case IDC_COMBO_CPU_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); + + temp_cpu = 0; + win_settings_machine_recalc_cpu_m(hdlg); + } + break; + case IDC_COMBO_CPU: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); + + win_settings_machine_recalc_cpu(hdlg); + } + break; + case IDC_CONFIGURE_MACHINE: + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); + break; + } + + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_FPU); + temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_MEMTEXT); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + sscanf(stransi, "%i", &temp_mem_size); + temp_mem_size &= ~(models[temp_model].ram_granularity - 1); + if (temp_mem_size < models[temp_model].min_ram) + { + temp_mem_size = models[temp_model].min_ram; + } + else if (temp_mem_size > models[temp_model].max_ram) + { + temp_mem_size = models[temp_model].max_ram; + } + if (models[temp_model].flags & MODEL_AT) + { + temp_mem_size *= 1024; + } + + free(stransi); + free(lptsTemp); + + default: + return FALSE; + } + + return FALSE; +} + +static void recalc_vid_list(HWND hdlg) +{ + HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + int c = 0, d = 0; + int found_card = 0; + WCHAR szText[512]; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, 0); + + while (1) + { + char *s = video_card_getname(c); + + if (!s[0]) + break; + + if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + ((models[temp_model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) + { + mbstowcs(szText, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if (video_new_to_old(c) == gfxcard) + { + + SendMessage(h, CB_SETCURSEL, d, 0); + found_card = 1; + } + + d++; + } + + c++; + } + if (!found_card) + SendMessage(h, CB_SETCURSEL, 0, 0); + EnableWindow(h, models[temp_model].fixed_gfxcard ? FALSE : TRUE); + + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); +} + +static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + char *stransi; + char *s; + int gfx = 0; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + recalc_vid_list(hdlg); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); + SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); + SendMessage(h, BM_SETCHECK, temp_voodoo, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + gfx = video_card_getid(stransi); + + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + if (video_card_has_config(gfx)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + free(stransi); + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_VIDEO: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + gfx = video_card_getid(stransi); + temp_gfxcard = video_new_to_old(gfx); + + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + if (video_card_has_config(gfx)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + free(stransi); + free(lptsTemp); + break; + + case IDC_CHECK_VOODOO: + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + EnableWindow(h, temp_voodoo ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_VOODOO: + deviceconfig_open(hdlg, (void *)&voodoo_device); + break; + + case IDC_CONFIGUREVID: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); + + free(stransi); + free(lptsTemp); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + temp_gfxcard = video_new_to_old(video_card_getid(stransi)); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); + temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + + free(stransi); + free(lptsTemp); + + default: + return FALSE; + } + return FALSE; +} + + +static int mouse_valid(int type, int model) +{ + type &= MOUSE_TYPE_MASK; + + if ((type == MOUSE_TYPE_PS2) && + !(models[model].flags & MODEL_PS2)) return(0); + + if ((type == MOUSE_TYPE_AMSTRAD) && + !(models[model].flags & MODEL_AMSTRAD)) return(0); + + if ((type == MOUSE_TYPE_OLIM24) && + !(models[model].flags & MODEL_OLIM24)) return(0); + + return(1); +} + + +static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + int type; + int str_id = 0; + + switch (message) + { + case WM_INITDIALOG: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + c = d = 0; + for (c = 0; c < mouse_get_ndev(); c++) + { + type = mouse_get_type(c); + + settings_mouse_to_list[c] = d; + + if (mouse_valid(type, temp_model)) + { + switch(c) + { + case 0: /* MS Serial */ + default: + str_id = 2139; + break; + case 1: /* MS InPort Bus */ + str_id = 2177; + break; + case 2: /* PS2 2b */ + str_id = 2140; + break; + case 3: /* MS/logi bus 2b */ + str_id = 2161; + break; + case 4: /* PS2 intelli 3b */ + str_id = 2141; + break; + case 5: /* Amstrad */ + str_id = 2142; + break; + case 6: /* Olivetti M24 */ + str_id = 2143; + break; + case 7: /* MouseSystems */ + str_id = 2162; + break; + case 8: /* Genius Bus */ + str_id = 2178; + break; + } + + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id)); + + settings_list_to_mouse[d] = c; + d++; + } + } + + SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + c = 0; + while (joystick_get_name(c)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2144 + c)); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_joystick, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_JOYSTICK: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + } + break; + + case IDC_JOY1: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 0, temp_joystick); + break; + + case IDC_JOY2: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 1, temp_joystick); + break; + + case IDC_JOY3: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 2, temp_joystick); + break; + + case IDC_JOY4: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 3, temp_joystick); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + +static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) +{ + HWND h; + + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + LPTSTR lptsTemp; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + + if (models[model].flags & MODEL_HAS_IDE) + { + hdc_ignore = 1; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); + EnableWindow(h, FALSE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } + else + { + hdc_ignore = 0; + + valid = 0; + + if (use_selected_hdd) + { + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + { + strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); + } + else + { + strcpy(old_name, "none"); + } + } + else + { + strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); + } + + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + s = hdd_controller_get_name(c); + if (s[0] == 0) + { + break; + } + if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) + { + c++; + continue; + } + if ((hdd_controller_get_flags(c) & DEVICE_PS2) && !(models[model].flags & MODEL_PS2_HDD)) + { + c++; + continue; + } + if ((hdd_controller_get_flags(c) & DEVICE_MCA) && !(models[model].flags & MODEL_MCA)) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + if (c < 2) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152 + c)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + SendMessage(h, CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + EnableWindow(h, TRUE); + } + + free(lptsTemp); +} + +int valid_ide_irqs[11] = { 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 }; + +int find_irq_in_array(int irq, int def) +{ + int i = 0; + + for (i = 0; i < 11; i++) + { + if (valid_ide_irqs[i] == irq) + { + return i + 1; + } + } + + return 7 + def; +} + +static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *sound_dev; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBOSND); + c = d = 0; + while (1) + { + char *s = sound_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_sound_to_list[c] = d; + + if (sound_card_available(c)) + { + sound_dev = sound_card_getdevice(c); + + if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_sound[d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURESND); + if (sound_card_has_config(temp_sound_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h=GetDlgItem(hdlg, IDC_CHECKCMS); + SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); + + h=GetDlgItem(hdlg, IDC_CHECKGUS); + SendMessage(h, BM_SETCHECK, temp_GUS, 0); + + h=GetDlgItem(hdlg, IDC_CHECKSSI); + SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); + + h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIGURESND: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); + break; + + case IDC_COMBOSND: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURESND); + if (sound_card_has_config(temp_sound_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CHECKCMS); + temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKGUS); + temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKSSI); + temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + +static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + /*NIC config*/ + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + c = d = 0; + while (1) + { + char *s = scsi_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_scsi_to_list[c] = d; + + if (scsi_card_available(c)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_scsi[d] = c; + d++; + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_scsi_to_list[temp_scsi_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + recalc_hdd_list(hdlg, temp_model, 0); + + /*NIC config*/ + h = GetDlgItem(hdlg, IDC_COMBONET); + c = d = 0; + while (1) + { + char *s = network_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_network_to_list[c] = d; + + if (network_card_available(c)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_network[d] = c; + d++; + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURENET); + if (network_card_has_config(temp_net_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + + for (c = 0; c < 11; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + if (temp_ide_ter) + { + SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_ter_irq, 0), 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + + for (c = 0; c < 11; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + if (temp_ide_qua) + { + SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_qua_irq, 1), 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); + SendMessage(h, BM_SETCHECK, temp_serial[0], 0); + + h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); + SendMessage(h, BM_SETCHECK, temp_serial[1], 0); + + h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); + SendMessage(h, BM_SETCHECK, temp_lpt, 0); + + h=GetDlgItem(hdlg, IDC_CHECKBUGGER); + SendMessage(h, BM_SETCHECK, temp_bugger, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIGURENET: + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); + break; + + case IDC_COMBONET: + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURENET); + if (network_card_has_config(temp_net_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + + case IDC_CONFIGURE_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); + break; + + case IDC_COMBO_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + } + return FALSE; + + case WM_SAVESETTINGS: + if (hdc_ignore == 0) + { + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + c = SendMessage(h, CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + { + strncpy(temp_hdc_name, hdd_names[c], sizeof(temp_hdc_name) - 1); + } + else + { + strcpy(temp_hdc_name, "none"); + } + } + else + { + strcpy(temp_hdc_name, "none"); + } + + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER); + temp_ide_ter = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_ide_ter > 1) + { + temp_ide_ter_irq = valid_ide_irqs[temp_ide_ter - 1]; + temp_ide_ter = 1; + } + + h = GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); + temp_ide_qua = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_ide_qua > 1) + { + temp_ide_qua_irq = valid_ide_irqs[temp_ide_qua - 1]; + temp_ide_qua = 1; + } + + h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); + temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); + temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); + temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKBUGGER); + temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + +static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 6; i += 2) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +int next_free_id = 0; + +static void normalize_hd_list() +{ + hard_disk_t ihdc[HDC_NUM]; + char ifn[HDC_NUM][512]; + int i, j; + + j = 0; + memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memset(ifn[i], 0, 512); + } + for (i = 0; i < HDC_NUM; i++) + { + if ((temp_hdc[i].bus == 3) && (temp_hdc[i].scsi_id == 7)) + { + /* SCSI ID 7 is the host adapter, so any hard disk set to SCSI bus and ID 7 is to be treated as disabled and marked as such. */ + temp_hdc[i].bus = 0; + } + if (temp_hdc[i].bus > 0) + { + memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); + memcpy(ifn[j], temp_hdd_fn[i], 512); + j++; + } + } + + memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(temp_hdd_fn[i], ifn[i], 512); + } +} + +int hdc_id_to_listview_index[HDC_NUM]; +int hd_listview_items; + +hard_disk_t new_hdc; +int hdlv_current_sel; + +static int get_selected_hard_disk(HWND hdlg) +{ + int hard_disk = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + hard_disk = i; + } + } + + return hard_disk; +} + +static void add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + for (i = 0; i < 3; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2166 + i)); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + for (i = 0; i < 16; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} + +static void recalc_location_controls(HWND hdlg, int is_add_dlg) +{ + int i = 0; + HWND h; + + int bus = 0; + + for (i = 1799; i < 1803; i++) + { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + if ((hd_listview_items > 0) || is_add_dlg) + { + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + + switch(bus) + { + case 0: /* MFM/RLL */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); + break; + case 1: /* IDE */ + h = GetDlgItem(hdlg, 1802); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); + break; + case 2: /* SCSI */ + h = GetDlgItem(hdlg, 1800); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, 1801); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_id : temp_hdc[hdlv_current_sel].scsi_id, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_lun : temp_hdc[hdlv_current_sel].scsi_lun, 0); + break; + } + } + + if ((hd_listview_items == 0) && !is_add_dlg) + { + h = GetDlgItem(hdlg, 1798); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + else + { + h = GetDlgItem(hdlg, 1798); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + } +} + +static void recalc_next_free_id(HWND hdlg) +{ + HWND h; + int i; + + int c_mfm = 0; + int c_ide = 0; + int c_scsi = 0; + int enable_add = 0; + + next_free_id = -1; + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus == 1) + { + c_mfm++; + } + else if (temp_hdc[i].bus == 2) + { + c_ide++; + } + else if (temp_hdc[i].bus == 3) + { + c_scsi++; + } + } + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus == 0) + { + next_free_id = i; + break; + } + } + + /* pclog("Next free ID: %i\n", next_free_id); */ + + enable_add = enable_add || (next_free_id >= 0); + /* pclog("Enable add: %i\n", enable_add); */ + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide < IDE_NUM) || (c_scsi < SCSI_NUM)); + /* pclog("Enable add: %i\n", enable_add); */ + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); + + if (enable_add) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); + + if (enable_add) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); + + if ((c_mfm == 0) && (c_ide == 0) && (c_scsi == 0)) + { + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } +} + +static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column) +{ + LVITEM lvI; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = column; + lvI.iItem = i; + + if (column == 0) + { + switch(temp_hdc[i].bus) + { + case 1: + wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + break; + case 2: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; + } + lvI.pszText = szText; + lvI.iImage = temp_hdc[i].bus - 1; + } + else if (column == 1) + { + mbstowcs(szText, temp_hdd_fn[i], strlen(temp_hdd_fn[i]) + 1); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 2) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 3) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 4) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 5) + { + wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + lvI.pszText = szText; + lvI.iImage = 0; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + int j = 0; + WCHAR szText[256]; + + hd_listview_items = 0; + hdlv_current_sel = -1; + + ListView_DeleteAllItems(hwndList); + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus > 0) + { + hdc_id_to_listview_index[i] = j; + lvI.iSubItem = 0; + switch(temp_hdc[i].bus) + { + case 1: + wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + break; + case 2: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; + } + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = temp_hdc[i].bus - 1; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 1; + mbstowcs(szText, temp_hdd_fn[i], strlen(temp_hdd_fn[i]) + 1); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 2; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 3; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 4; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 5; + wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + j++; + } + else + { + hdc_id_to_listview_index[i] = -1; + } + } + + hd_listview_items = j; + + return TRUE; +} + +/* Icon, Bus, File, C, H, S, Size */ +#define C_COLUMNS_HARD_DISKS 6 + +static BOOL win_settings_hard_disks_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + int iCol; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) + { + lvc.iSubItem = iCol; + lvc.pszText = win_language_get_string_from_id(2082 + iCol); + + switch(iCol) + { + + case 0: /* Bus */ + lvc.cx = 85; + lvc.fmt = LVCFMT_LEFT; + break; + case 2: /* Cylinders */ + lvc.cx = 51; + lvc.fmt = LVCFMT_RIGHT; + break; + case 3: /* Heads */ + case 4: /* Sectors */ + lvc.cx = 25; + lvc.fmt = LVCFMT_RIGHT; + break; + case 1: /* File */ + lvc.cx = 180; + lvc.fmt = LVCFMT_LEFT; + break; + case 5: /* Size (MB) 8 */ + lvc.cx = 51; + lvc.fmt = LVCFMT_RIGHT; + break; + } + + if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) + { + return FALSE; + } + } + + return TRUE; +} + +static void get_edit_box_contents(HWND hdlg, int id, uint64_t *val) +{ + HWND h; + WCHAR szText[256]; + char stransi[256]; + + h = GetDlgItem(hdlg, id); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); + wcstombs(stransi, szText, (wcslen(szText) * 2) + 2); + sscanf(stransi, "%" PRIu64, val); +} + +static void get_combo_box_selection(HWND hdlg, int id, uint64_t *val) +{ + HWND h; + + h = GetDlgItem(hdlg, id); + *val = SendMessage(h, CB_GETCURSEL, 0, 0); +} + +static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) +{ + HWND h; + WCHAR szText[256]; + + h = GetDlgItem(hdlg, id); + wsprintf(szText, win_language_get_string_from_id(2160), val); + SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); +} + +int hard_disk_added = 0; +int max_spt = 63; + +int no_update = 0; + +int existing = 0; +uint64_t selection = 127; + +uint64_t spt, hpc, tracks, size; +char hd_file_name[512]; + +static int hdconf_initialize_hdt_combo(HWND hdlg) +{ + HWND h; + int i = 0; + uint64_t temp_size = 0; + uint64_t size_mb = 0; + WCHAR szText[256]; + + selection = 127; + + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) + { + temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; + size_mb = temp_size >> 11; + wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + { + selection = i; + } + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187)); + SendMessage(h, CB_SETCURSEL, selection, 0); + return selection; +} + +static void recalc_selection(HWND hdlg) +{ + HWND h; + int i = 0; + + selection = 127; + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) + { + if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + { + selection = i; + } + } + if ((selection == 127) && (hpc == 16) && (spt == 63)) + { + selection = 128; + } + SendMessage(h, CB_SETCURSEL, selection, 0); +} + +static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int64_t i = 0; + int bus; + uint64_t temp; + WCHAR szText[256]; + FILE *f; + uint32_t sector_size = 512; + uint32_t zero = 0; + uint32_t base = 0x1000; + uint64_t signature = 0xD778A82044445459ll; + char buf[512]; + + switch (message) + { + case WM_INITDIALOG: + memset(hd_file_name, 0, 512); + + no_update = 1; + spt = existing ? 0 : 17; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + hpc = existing ? 0 : 15; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + tracks = existing ? 0 : 1023; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + hdconf_initialize_hdt_combo(hdlg); + if (existing) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + } + add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, 1, 0); + recalc_location_controls(hdlg, 1); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + SendMessage(h, CB_SETCURSEL, 0, 0); + no_update = 0; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (strlen(hd_file_name) == 0) + { + msgbox_error(hwndParentDialog, 2056); + return TRUE; + } + + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(temp_hdc[next_free_id].spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(temp_hdc[next_free_id].hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(temp_hdc[next_free_id].tracks)); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + temp_hdc[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + temp_hdc[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + temp_hdc[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + memset(temp_hdd_fn[next_free_id], 0, 512); + memcpy(temp_hdd_fn[next_free_id], hd_file_name, strlen(hd_file_name) + 1); + + sector_size = 512; + + if (!existing && (strlen(hd_file_name) > 0)) + { + f = fopen(hd_file_name, "wb"); + + if (image_is_hdi(hd_file_name)) + { + if (size >= 0x100000000ll) + { + fclose(f); + msgbox_error(hwndParentDialog, 2058); + return TRUE; + } + + fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ + fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ + fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ + fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + + for (i = 0; i < 0x3f8; i++) + { + fwrite(&zero, 1, 4, f); + } + } + else if (image_is_hdx(hd_file_name, 0)) + { + if (size > 0xffffffffffffffffll) + { + fclose(f); + msgbox_error(hwndParentDialog, 2163); + return TRUE; + } + + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + } + + memset(buf, 0, 512); + size >>= 9; + for (i = 0; i < size; i++) + { + fwrite(buf, 512, 1, f); + } + + fclose(f); + msgbox_info(hwndParentDialog, 2059); + } + + hard_disk_added = 1; + EndDialog(hdlg, 0); + return TRUE; + + case IDCANCEL: + hard_disk_added = 0; + EndDialog(hdlg, 0); + return TRUE; + + case IDC_CFILE: + if (!file_dlg(hdlg, win_language_get_string_from_id(2172), "", !existing)) + { + f = fopen(openfilestring, existing ? "rb" : "wb"); + if (f == NULL) + { + msgbox_error(hwndParentDialog, existing ? 2060 : 2057); + return TRUE; + } + if (existing) + { + if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) + { + fseeko64(f, 0x10, SEEK_SET); + fread(§or_size, 1, 4, f); + if (sector_size != 512) + { + msgbox_error(hwndParentDialog, 2061); + fclose(f); + return TRUE; + } + spt = hpc = tracks = 0; + fread(&spt, 1, 4, f); + fread(&hpc, 1, 4, f); + fread(&tracks, 1, 4, f); + } + else + { + fseeko64(f, 0, SEEK_END); + size = ftello64(f); + fclose(f); + if (((size % 17) == 0) && (size <= 133693440)) + { + spt = 17; + if (size <= 26738688) + { + hpc = 4; + } + else if (size <= 53477376) + { + hpc = 6; + } + else if (size <= 71303168) + { + hpc = 8; + } + else + { + hpc = 15; + } + } + else + { + spt = 63; + hpc = 16; + } + + tracks = ((size >> 9) / hpc) / spt; + } + + no_update = 1; + + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, TRUE); + + no_update = 0; + } + else + { + fclose(f); + } + } + + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + mbstowcs(szText, openfilestring, strlen(openfilestring) + 1); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) szText); + memcpy(hd_file_name, openfilestring, strlen(openfilestring) + 1); + + return TRUE; + + case IDC_EDIT_HD_CYL: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); + if (temp != tracks) + { + tracks = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_HPC: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); + if (temp != hpc) + { + hpc = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_SPT: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); + if (temp != spt) + { + spt = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_SIZE: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); + if (temp != (size >> 20)) + { + size = temp << 20; + tracks = ((size >> 9) / hpc) / spt; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_COMBO_HD_TYPE: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); + if ((temp != selection) && (temp != 127) && (temp != 128)) + { + selection = temp; + tracks = hdt[selection][0]; + hpc = hdt[selection][1]; + spt = hdt[selection][2]; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + } + else if ((temp != selection) && (temp == 127)) + { + selection = temp; + } + else if ((temp != selection) && (temp == 128)) + { + selection = temp; + hpc = 16; + spt = 63; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + } + no_update = 0; + break; + + case IDC_COMBO_HD_BUS: + if (no_update) + { + return FALSE; + } + + no_update = 1; + recalc_location_controls(hdlg, 1); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); + max_spt = (bus == 2) ? 99 : 63; + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; + break; + } + + return FALSE; + } + + return FALSE; +} + +void hard_disk_add_open(HWND hwnd, int is_existing) +{ + BOOL ret; + + existing = !!is_existing; + hard_disk_added = 0; + ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); +} + +int ignore_change = 0; + +static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int old_sel = 0; + + switch (message) + { + case WM_INITDIALOG: + ignore_change = 1; + + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. + This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list + (which can only happen by manually editing the configuration file). */ + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_init_columns(h); + win_settings_hard_disks_image_list_init(h); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + add_locations(hdlg); + if (hd_listview_items > 0) + { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + hdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + } + else + { + hdlv_current_sel = -1; + } + recalc_location_controls(hdlg, 0); + + ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if ((hd_listview_items == 0) || ignore_change) + { + return FALSE; + } + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) + { + old_sel = hdlv_current_sel; + hdlv_current_sel = get_selected_hard_disk(hdlg); + if (hdlv_current_sel == old_sel) + { + return FALSE; + } + else if (hdlv_current_sel == -1) + { + ignore_change = 1; + hdlv_current_sel = old_sel; + ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; + return FALSE; + } + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[hdlv_current_sel].bus - 1, 0); + recalc_location_controls(hdlg, 0); + ignore_change = 0; + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_HD_BUS: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + recalc_location_controls(hdlg, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_CHANNEL: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_CHANNEL_IDE: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + temp_hdc[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_ID: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + temp_hdc[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_LUN: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + temp_hdc[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_BUTTON_HDD_ADD: + hard_disk_add_open(hdlg, 1); + if (hard_disk_added) + { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + ignore_change = 0; + } + return FALSE; + + case IDC_BUTTON_HDD_ADD_NEW: + hard_disk_add_open(hdlg, 0); + if (hard_disk_added) + { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + ignore_change = 0; + } + return FALSE; + + case IDC_BUTTON_HDD_REMOVE: + strncpy(temp_hdd_fn[hdlv_current_sel], "", strlen("") + 1); + temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + if (hd_listview_items > 0) + { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + hdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + } + else + { + hdlv_current_sel = -1; + } + recalc_location_controls(hdlg, 0); + ignore_change = 0; + return FALSE; + } + + default: + return FALSE; + } + + return FALSE; +} + +int fdlv_current_sel; +int cdlv_current_sel; + +static void combo_id_to_bus(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + temp_cdrom_drives[cdlv_current_sel].enabled = 0; + break; + case 1: /* Atapi (PIO-only) */ + temp_cdrom_drives[cdlv_current_sel].enabled = 1; + temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + temp_cdrom_drives[cdlv_current_sel].atapi_dma = 0; + break; + case 2: /* Atapi (PIA and DMA) */ + temp_cdrom_drives[cdlv_current_sel].enabled = 1; + temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + temp_cdrom_drives[cdlv_current_sel].atapi_dma = 1; + break; + case 3: /* SCSI */ + temp_cdrom_drives[cdlv_current_sel].enabled = 1; + temp_cdrom_drives[cdlv_current_sel].bus_type = 1; + temp_cdrom_drives[cdlv_current_sel].atapi_dma = 0; + break; + } +} + +static int combo_id_to_string_id(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + return 2151; + break; + case 1: /* Atapi (PIO-only) */ + return 2189; + break; + case 2: /* Atapi (PIA and DMA) */ + return 2190; + break; + case 3: /* SCSI */ + return 2168; + break; + } +} + +static int combo_id_to_format_string_id(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + return 2151; + break; + case 1: /* Atapi (PIO-only) */ + return 2191; + break; + case 2: /* Atapi (PIA and DMA) */ + return 2192; + break; + case 3: /* SCSI */ + return 2158; + break; + } +} + +static int bus_to_combo_id(int id) +{ + if (temp_cdrom_drives[id].enabled) + { + if (temp_cdrom_drives[id].bus_type) + { + return 3; + } + else + { + if (temp_cdrom_drives[id].atapi_dma) + { + return 2; + } + else + { + return 1; + } + } + } + else + { + return 0; + } + + return 0; +} + +static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 14; i++) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) fdd_type_to_icon(i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + int j = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 514); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 160); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 162); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 164); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 4; i++) + { + if (temp_fdd_types[i] > 0) + { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } + else + { + lvI.pszText = win_language_get_string_from_id(2151); + } + lvI.iItem = i; + lvI.iImage = temp_fdd_types[i]; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; + int bid = 0; + int fsid = 0; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 4; i++) + { + bid = bus_to_combo_id(i); + fsid = combo_id_to_format_string_id(bid); + + switch (bid) + { + case 0: + default: + lvI.pszText = win_language_get_string_from_id(fsid); + break; + case 1: + case 2: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + lvI.pszText = szText; + break; + } + + lvI.iItem = i; + lvI.iImage = bid; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = win_language_get_string_from_id(2188); + + lvc.cx = 392; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + { + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = win_language_get_string_from_id(2082); + + lvc.cx = 392; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + { + return FALSE; + } + + return TRUE; +} + +static int get_selected_floppy_drive(HWND hdlg) +{ + int floppy_drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + floppy_drive = i; + } + } + + return floppy_drive; +} + +static int get_selected_cdrom_drive(HWND hdlg) +{ + int cd_drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + cd_drive = i; + } + } + + return cd_drive; +} + +static void win_settings_floppy_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + if (temp_fdd_types[i] > 0) + { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } + else + { + lvI.pszText = win_language_get_string_from_id(2151); + } + lvI.iImage = temp_fdd_types[i]; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + int bid; + int fsid; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + bid = bus_to_combo_id(i); + fsid = combo_id_to_format_string_id(bid); + + switch (bid) + { + case 0: + default: + lvI.pszText = win_language_get_string_from_id(fsid); + break; + case 1: + case 2: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + lvI.pszText = szText; + break; + } + + lvI.iImage = bid; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static void cdrom_add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + for (i = 0; i < 4; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + for (i = 0; i < 16; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} +static void cdrom_recalc_location_controls(HWND hdlg) +{ + int i = 0; + HWND h; + + int bus = bus_to_combo_id(cdlv_current_sel); + + for (i = 1800; i < 1803; i++) + { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + switch(bus) + { + case 1: /* ATAPI (PIO-only) */ + case 2: /* ATAPI (PIO and DMA) */ + h = GetDlgItem(hdlg, 1802); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); + break; + case 3: /* SCSI */ + h = GetDlgItem(hdlg, 1800); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, 1801); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); + break; + } +} + + +int rd_ignore_change = 0; + +static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int i = 0; + int old_sel = 0; + int cid = 0; + WCHAR szText[256]; + + switch (message) + { + case WM_INITDIALOG: + rd_ignore_change = 1; + + fdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_init_columns(h); + win_settings_floppy_drives_image_list_init(h); + win_settings_floppy_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + for (i = 0; i < 14; i++) + { + if (i == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + } + else + { + mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + } + } + SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + + cdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_init_columns(h); + win_settings_cdrom_drives_image_list_init(h); + win_settings_cdrom_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + cdrom_add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + SendMessage(h, CB_SETCURSEL, bus_to_combo_id(cdlv_current_sel), 0); + cdrom_recalc_location_controls(hdlg); + + rd_ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if (rd_ignore_change) + { + return FALSE; + } + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) + { + old_sel = fdlv_current_sel; + fdlv_current_sel = get_selected_floppy_drive(hdlg); + if (fdlv_current_sel == old_sel) + { + return FALSE; + } + else if (fdlv_current_sel == -1) + { + rd_ignore_change = 1; + fdlv_current_sel = old_sel; + ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + rd_ignore_change = 0; + return FALSE; + } + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + rd_ignore_change = 0; + } + else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) + { + old_sel = cdlv_current_sel; + cdlv_current_sel = get_selected_cdrom_drive(hdlg); + if (cdlv_current_sel == old_sel) + { + return FALSE; + } + else if (cdlv_current_sel == -1) + { + rd_ignore_change = 1; + cdlv_current_sel = old_sel; + ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + rd_ignore_change = 0; + return FALSE; + } + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + SendMessage(h, CB_SETCURSEL, bus_to_combo_id(cdlv_current_sel), 0); + cdrom_recalc_location_controls(hdlg); + rd_ignore_change = 0; + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_FD_TYPE: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, fdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_BUS: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + cid = SendMessage(h, CB_GETCURSEL, 0, 0); + combo_id_to_bus(cid); + cdrom_recalc_location_controls(hdlg); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_ID: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_LUN: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_CHANNEL_IDE: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + } + + default: + return FALSE; + } + + return FALSE; +} + +void win_settings_show_child(HWND hwndParent, DWORD child_id) +{ + if (child_id == displayed_category) + { + return; + } + else + { + displayed_category = child_id; + } + + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + + DestroyWindow(hwndChildDialog); + + switch(child_id) + { + case 0: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); + break; + case 1: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); + break; + case 2: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); + break; + case 3: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); + break; + case 4: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + break; + case 5: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + break; + case 6: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); + break; + default: + fatal("Invalid child dialog ID\n"); + return; + } + + ShowWindow(hwndChildDialog, SW_SHOWNORMAL); +} + +static BOOL win_settings_main_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 7; i++) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_main_insert_categories(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 7; i++) + { + lvI.pszText = win_language_get_settings_category(i); + lvI.iItem = i; + lvI.iImage = i; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int category; + int i = 0; + int j = 0; + + hwndParentDialog = hdlg; + + switch (message) + { + case WM_INITDIALOG: + pause = 1; + win_settings_init(); + displayed_category = -1; + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + win_settings_main_image_list_init(h); + win_settings_main_insert_categories(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, 2047); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + return TRUE; + case WM_NOTIFY: + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) + { + category = -1; + for (i = 0; i < 7; i++) + { + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + category = i; + /* pclog("Category %i selected\n", i); */ + } + } + if (category != -1) + { + /* pclog("Showing child: %i\n", category); */ + win_settings_show_child(hdlg, category); + } + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + /* pclog("Saving settings...\n"); */ + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + i = settings_msgbox_reset(); + if (i > 0) + { + if (i == 2) + { + win_settings_save(); + } + + /* pclog("Destroying window...\n"); */ + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + } + else + { + return FALSE; + } + case IDCANCEL: + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + pause=0; + return TRUE; + } + break; + default: + return FALSE; + } + + return FALSE; +} + +void win_settings_open(HWND hwnd) +{ + DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); +} diff --git a/src/win-status.c b/src/win-status.c index 345f9e2e5..b907d6942 100644 --- a/src/win-status.c +++ b/src/win-status.c @@ -9,7 +9,7 @@ #include "ibm.h" #include "device.h" #include "video.h" -#include "resources.h" +#include "resource.h" #include "win.h" #include "x86_ops.h" #include "mem.h" @@ -39,9 +39,6 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR "CPU speed : %f MIPS\n" "FPU speed : %f MFLOPS\n\n" -/* "Cache misses (read) : %i/sec\n" - "Cache misses (write) : %i/sec\n\n"*/ - "Video throughput (read) : %i bytes/sec\n" "Video throughput (write) : %i bytes/sec\n\n" "Effective clockspeed : %iHz\n\n" @@ -50,13 +47,8 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS" -// "\nFully recompiled ins %% : %f%%" ,mips, flops, -/*#ifndef DYNAREC - sreadlnum, - swritelnum, -#endif*/ segareads, segawrites, clockrate - scycles_lost, @@ -69,13 +61,8 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR cpu_recomp_reuse_latched, cpu_recomp_removed_latched, ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq) -// ((double)cpu_recomp_full_ins_latched / (double)cpu_recomp_ins_latched) * 100.0 -// cpu_reps_latched, cpu_notreps_latched ); main_time = 0; -/*#ifndef DYNAREC - device_add_status_info(device_s, 4096); -#endif*/ SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); device_s[0] = 0; @@ -104,3 +91,14 @@ void status_open(HWND hwnd) status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); ShowWindow(status_hwnd, SW_SHOW); } + + +#if 0 +void +set_bugui(char *str) +{ + if (str == NULL) + str = "L:R GGGGGGGG-RRRRRRRR"; + SendMessage(status_hwnd, SB_SETTEXT, 2, (WPARAM)str); +} +#endif diff --git a/src/win-video.c b/src/win-video.c index eed0059c6..dd6b3788f 100644 --- a/src/win-video.c +++ b/src/win-video.c @@ -5,6 +5,7 @@ #include #include #include "video.h" +#include "win-cgapal.h" BITMAP *screen; diff --git a/src/win.c b/src/win.c index ac2dd3a19..9c6695efa 100644 --- a/src/win.c +++ b/src/win.c @@ -16,7 +16,12 @@ #include #include #include +#include #include "86box.h" +#include "device.h" +#include "disc.h" +#include "fdd.h" +#include "hdd.h" #include "ibm.h" #include "ide.h" #include "cdrom-null.h" @@ -24,9 +29,10 @@ #include "cdrom-iso.h" #include "config.h" #include "video.h" -#include "resources.h" +#include "resource.h" #include "cpu.h" #include "cdrom.h" +#include "mem.h" #include "model.h" #include "mouse.h" #include "nethandler.h" @@ -34,8 +40,10 @@ #include "sound.h" #include "sound_dbopl.h" #include "thread.h" -#include "disc.h" +#include "rom.h" +#include "vid_ega.h" +#include "plat-mouse.h" #include "plat-midi.h" #include "plat-keyboard.h" @@ -44,8 +52,7 @@ #include "win-ddraw-fs.h" #include "win-d3d.h" #include "win-d3d-fs.h" -//#include "win-opengl.h" -#include "win-crashdump.h" +#include "win-language.h" #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 @@ -100,6 +107,10 @@ int mousecapture=0; LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +LONG OriginalStatusBarProcedure; + HWND ghwnd; HINSTANCE hinstance; @@ -119,16 +130,23 @@ static int unscaled_size_y = 0; int scale = 0; +HWND hwndRender, hwndStatus; + void updatewindowsize(int x, int y) { - RECT r; + int owsx = winsizex; + int owsy = winsizey; + + int temp_overscan_x = overscan_x; + int temp_overscan_y = overscan_y; + if (vid_resize) return; if (x < 160) x = 160; if (y < 100) y = 100; - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; + if (x > 2048) x = 2048; + if (y > 2048) y = 2048; if (suppress_overscan) { @@ -189,7 +207,14 @@ void updatewindowsize(int x, int y) break; } - win_doresize = 1; + if ((owsx != winsizex) || (owsy != winsizey)) + { + win_doresize = 1; + } + else + { + win_doresize = 0; + } } void uws_natural() @@ -229,11 +254,12 @@ uint64_t end_time; void mainthread(LPVOID param) { - int t = 0; int frames = 0; DWORD old_time, new_time; -// Sleep(500); + RECT r; + int sb_borders[3]; + drawits=0; old_time = GetTickCount(); while (!quited) @@ -265,15 +291,27 @@ void mainthread(LPVOID param) else Sleep(1); - if (!video_fullscreen && win_doresize) + if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) { - RECT r; video_wait_for_blit(); + SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); GetWindowRect(ghwnd, &r); - MoveWindow(ghwnd, r.left, r.top, - winsizex + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2), - winsizey + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1, + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, TRUE); + GetWindowRect(hwndRender, &r); + MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), + winsizex, + 17, + TRUE); + GetWindowRect(ghwnd, &r); + + MoveWindow(ghwnd, r.left, r.top, + winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), + winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, + TRUE); + win_doresize = 0; } @@ -353,16 +391,17 @@ void thread_destroy_event(event_t *_event) free(event); } +HMENU smenu; + static void initmenu(void) { int i, c; - HMENU dm, m; + HMENU m; char s[32]; - dm=GetSubMenu(menu,1); /*Disc*/ for (i = 0; i < CDROM_NUM; i++) { - m=GetSubMenu(dm,17+i); /*CD-ROM*/ + m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ /* Loop through each Windows drive letter and test to see if it's a CDROM */ @@ -372,7 +411,7 @@ static void initmenu(void) if (GetDriveType(s)==DRIVE_CDROM) { sprintf(s, "Host CD/DVD Drive (%c:)", c); - AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+c+(i * 1000),s); + AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); } } } @@ -441,7 +480,7 @@ void get_registry_key_map() { char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; char *valueName = "Scancode Map"; - char buf[32768]; + unsigned char buf[32768]; DWORD bufSize; HKEY hKey; int j; @@ -547,7 +586,6 @@ static void process_command_line() argbuf[i] = 0; i++; } - // pclog("Arg %i - %s\n",argc-1,argv[argc-1]); } } @@ -579,6 +617,467 @@ int find_in_array(int *array, int val, int len, int menu_base) HANDLE hinstAcc; +HICON LoadIconEx(PCTSTR pszIconName) +{ + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, 0); +} + +HICON LoadIconBig(PCTSTR pszIconName) +{ + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 64, 64, 0); +} + +int fdd_type_to_icon(int type) +{ + switch(type) + { + default: + case 0: + return 512; + case 1: + return 128; + case 2: + return 130; + case 3: + return 132; + case 4: + case 5: + case 6: + return 134; + case 7: + return 144; + case 8: + return 146; + case 9: + case 10: + case 11: + case 12: + return 150; + case 13: + return 152; + } +} + +int sb_parts = 10; + +int sb_part_meanings[12]; +int sb_part_icons[12]; + +int sb_icon_width = 24; + +int count_hard_disks(int bus) +{ + int i = 0; + + int c = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == bus) + { + c++; + } + } + + return c; +} + +HICON hIcon[512]; + +int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; + +#define SBI_FLAG_ACTIVE 1 +#define SBI_FLAG_EMPTY 256 + +int sb_icon_flags[512]; + +/* This is for the disk activity indicator. */ +void update_status_bar_icon(int tag, int active) +{ + int i = 0; + int found = -1; + int temp_flags = 0; + + if ((tag & 0xf0) >= 0x30) + { + return; + } + + temp_flags |= active; + + for (i = 0; i < 12; i++) + { + if (sb_part_meanings[i] == tag) + { + found = i; + break; + } + } + + if (found != -1) + { + if (temp_flags != (sb_icon_flags[found] & 1)) + { + sb_icon_flags[found] &= ~1; + sb_icon_flags[found] |= active; + + sb_part_icons[found] &= ~257; + sb_part_icons[found] |= sb_icon_flags[found]; + + DestroyIcon(hIcon[found]); + hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]); + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]); + } + } +} + +/* This is for the drive state indicator. */ +void update_status_bar_icon_state(int tag, int state) +{ + int i = 0; + int found = -1; + + if ((tag & 0xf0) >= 0x20) + { + return; + } + + for (i = 0; i < 12; i++) + { + if (sb_part_meanings[i] == tag) + { + found = i; + break; + } + } + + if (found != -1) + { + sb_icon_flags[found] &= ~256; + sb_icon_flags[found] |= state ? 256 : 0; + + sb_part_icons[found] &= ~257; + sb_part_icons[found] |= sb_icon_flags[found]; + + DestroyIcon(hIcon[found]); + hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]); + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]); + } +} + +char sbTips[24][512]; + +void create_floppy_tip(int part) +{ + WCHAR *szText; + char ansi_text[2][512]; + + int drive = sb_part_meanings[part] & 0xf; + szText = (WCHAR *) win_language_get_string_from_id(2179); + wcstombs(ansi_text[0], szText, (wcslen(szText) << 1) + 2); + szText = (WCHAR *) win_language_get_string_from_id(2185); + wcstombs(ansi_text[1], szText, (wcslen(szText) << 1) + 2); + if (strlen(discfns[drive]) == 0) + { + sprintf(sbTips[part], ansi_text[0], drive + 1, fdd_getname(fdd_get_type(drive)), ansi_text[1]); + } + else + { + sprintf(sbTips[part], ansi_text[0], drive + 1, fdd_getname(fdd_get_type(drive)), discfns[drive]); + } +} + +void create_cdrom_tip(int part) +{ + WCHAR *szText; + char ansi_text[4][512]; + + int drive = sb_part_meanings[part] & 0xf; + szText = (WCHAR *) win_language_get_string_from_id(2180); + wcstombs(ansi_text[0], szText, (wcslen(szText) << 1) + 2); + szText = (WCHAR *) win_language_get_string_from_id(2185); + wcstombs(ansi_text[1], szText, (wcslen(szText) << 1) + 2); + szText = (WCHAR *) win_language_get_string_from_id(2186); + wcstombs(ansi_text[2], szText, (wcslen(szText) << 1) + 2); + if (cdrom_drives[drive].host_drive == 200) + { + if (strlen(cdrom_iso[drive].iso_path) == 0) + { + sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[1]); + } + else + { + sprintf(sbTips[part], ansi_text[0], drive + 1, cdrom_iso[drive].iso_path); + } + } + else if (cdrom_drives[drive].host_drive < 0x41) + { + sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[1]); + } + else + { + sprintf(ansi_text[3], ansi_text[2], cdrom_drives[drive].host_drive & ~0x20); + sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[3]); + } +} + +void create_hd_tip(int part) +{ + WCHAR *szText; + + int bus = sb_part_meanings[part] & 0xf; + szText = (WCHAR *) win_language_get_string_from_id(2182 + bus); + wcstombs(sbTips[part], szText, (wcslen(szText) << 1) + 2); +} + +void update_tip(int meaning) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == meaning) + { + part = i; + } + } + + if (part != -1) + { + switch(meaning & 0x30) + { + case 0x00: + create_floppy_tip(part); + break; + case 0x10: + create_cdrom_tip(part); + break; + case 0x20: + create_hd_tip(part); + break; + default: + break; + } + + SendMessage(hwndStatus, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); + } +} + +static int get_floppy_state(int id) +{ + return (strlen(discfns[id]) == 0) ? 1 : 0; +} + +static int get_cd_state(int id) +{ + if (cdrom_drives[id].host_drive < 0x41) + { + return 1; + } + else + { + if (cdrom_drives[id].host_drive == 0x200) + { + return (strlen(cdrom_iso[id].iso_path) == 0) ? 1 : 0; + } + else + { + return 0; + } + } +} + +void update_status_bar_panes(HWND hwnds) +{ + int i, j, id; + int edge = 0; + + int c_rll = 0; + int c_mfm = 0; + int c_ide = 0; + int c_scsi = 0; + + c_mfm = count_hard_disks(1); + c_ide = count_hard_disks(2); + c_scsi = count_hard_disks(3); + + sb_parts = 0; + memset(sb_part_meanings, 0, 40); + for (i = 0; i < 4; i++) + { + if (fdd_get_type(i) != 0) + { + /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x00 | i; + sb_parts++; + } + } + for (i = 0; i < 4; i++) + { + if (cdrom_drives[i].enabled != 0) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x10 | i; + sb_parts++; + } + } + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x20; + sb_parts++; + } + if (c_ide && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x21; + sb_parts++; + } + if (c_scsi) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x22; + sb_parts++; + } + if (sb_parts) + { + iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); + } + iStatusWidths[sb_parts] = -1; + sb_part_meanings[sb_parts] = 0x30; + sb_parts++; + + SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); + + for (i = 0; i < sb_parts; i++) + { + switch (sb_part_meanings[i] & 0x30) + { + case 0x00: + /* Floppy */ + sb_icon_flags[i] = (strlen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; + create_floppy_tip(i); + break; + case 0x10: + /* CD-ROM */ + id = sb_part_meanings[i] & 0xf; + if (cdrom_drives[id].host_drive < 0x41) + { + sb_icon_flags[i] = 256; + } + else + { + if (cdrom_drives[id].host_drive == 0x200) + { + sb_icon_flags[i] = (strlen(cdrom_iso[id].iso_path) == 0) ? 256 : 0; + } + else + { + sb_icon_flags[i] = 0; + } + } + if (cdrom_drives[id].bus_type == 1) + { + j = 164; + } + else + { + j = (cdrom_drives[id].atapi_dma) ? 162 : 160; + } + sb_part_icons[i] = j | sb_icon_flags[i]; + create_cdrom_tip(i); + break; + case 0x20: + /* Hard disk */ + sb_part_icons[i] = 176 + ((sb_part_meanings[i] & 0xf) << 1); + create_hd_tip(i); + break; + case 0x30: + /* Status text */ + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) "Hello from 86Box UX lab! :p"); + sb_part_icons[i] = -1; + break; + } + if (sb_part_icons[i] != -1) + { + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); + DestroyIcon(hIcon[i]); + hIcon[i] = LoadIconEx((PCTSTR) sb_part_icons[i]); + SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[i]); + SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); + /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ + } + else + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + } +} + +HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) +{ + HWND hwndStatus; + int i; + RECT rectDialog; + int dw, dh; + + GetWindowRect(hwndParent, &rectDialog); + dw = rectDialog.right - rectDialog.left; + dh = rectDialog.bottom - rectDialog.top; + + InitCommonControls(); + + hwndStatus = CreateWindowEx( + 0, + STATUSCLASSNAME, + (PCTSTR) NULL, + SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, + 0, dh - 17, dw, 17, + hwndParent, + (HMENU) idStatus, + hinst, + NULL); + + GetWindowRect(hwndStatus, &rectDialog); + + SetWindowPos( + hwndStatus, + HWND_TOPMOST, + rectDialog.left, + rectDialog.top, + rectDialog.right - rectDialog.left, + rectDialog.bottom - rectDialog.top, + SWP_SHOWWINDOW); + + SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); + + update_status_bar_panes(hwndStatus); + + return hwndStatus; +} + +void win_menu_update() +{ +#if 0 + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); + initmenu(); + + SetMenu(ghwnd, menu); + + win_title_update = 1; +#endif +} + int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, @@ -589,13 +1088,13 @@ int WINAPI WinMain (HINSTANCE hThisInstance, MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ int c, d, e, bRet; - char emulator_title[200]; + char emulator_title[200]; LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ - - // InitCrashDump(); // First thing to do before anything else is to make sure crash dumps get created. process_command_line(); + + win_language_load_common_strings(); hinstance=hThisInstance; /* The Window structure */ @@ -606,9 +1105,9 @@ int WINAPI WinMain (HINSTANCE hThisInstance, wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon (hinstance, 100); - wincl.hIconSm = LoadIcon (hinstance, 100); - wincl.hCursor = NULL;//LoadCursor (NULL, IDC_ARROW); + wincl.hIcon = LoadIcon(hinstance, (LPCSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCSTR) 100); + wincl.hCursor = NULL; wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ wincl.cbWndExtra = 0; /* structure or the window instance */ @@ -626,7 +1125,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, return 0; menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - initmenu(); sprintf(emulator_title, "86Box v%s", emulator_version); @@ -635,7 +1133,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, 0, /* Extended possibilites for variation */ szClassName, /* Classname */ emulator_title, /* Title Text */ - WS_OVERLAPPEDWINDOW&~WS_SIZEBOX, /* default window */ + (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ @@ -654,8 +1152,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (haccel == NULL) fatal("haccel is null\n"); -// win_set_window(hwnd); - memset(rawinputkey, 0, sizeof(rawinputkey)); device.usUsagePage = 0x01; device.usUsage = 0x06; @@ -673,10 +1169,19 @@ int WINAPI WinMain (HINSTANCE hThisInstance, initpc(argc, argv); - // pclog("Setting video API...\n"); - if (vid_apis[0][vid_api].init(ghwnd) == 0) + hwndRender = CreateWindow("STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + + hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); + + OriginalStatusBarProcedure = GetWindowLong(hwndStatus, GWL_WNDPROC); + SetWindowLong(hwndStatus, GWL_WNDPROC, (LONG) &StatusBarProcedure); + + smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); + initmenu(); + + if (vid_apis[0][vid_api].init(hwndRender) == 0) { - if (vid_apis[0][vid_api ^ 1].init(ghwnd) == 0) + if (vid_apis[0][vid_api ^ 1].init(hwndRender) == 0) { fatal("Both DirectDraw and Direct3D renderers failed to initialize\n"); } @@ -686,80 +1191,33 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } } - // pclog("Resizing window...\n"); if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); - // pclog("Checking CD-ROM menu item...\n"); - /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ for (e = 0; e < CDROM_NUM; e++) { - if (cdrom_drives[e].enabled) - CheckMenuItem(menu, IDM_CDROM_1_ENABLED + (e * 1000), MF_CHECKED); - - if (cdrom_drives[e].sound_on) - CheckMenuItem(menu, IDM_CDROM_1_SOUND_ON + (e * 1000), MF_CHECKED); - - if (cdrom_drives[e].bus_type) - CheckMenuItem(menu, IDM_CDROM_1_SCSI + (e * 1000), MF_CHECKED); - - if (cdrom_drives[e].atapi_dma) - CheckMenuItem(menu, IDM_CDROM_1_DMA + (e * 1000), MF_CHECKED); - - if (!find_in_array(valid_ide_channels, cdrom_drives[e].ide_channel, 8, IDM_CDROM_1_C + (e * 1000))) + if (!cdrom_drives[e].sound_on) { - fatal("CD-ROM %i: Invalid IDE channel\n", e); + CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); } - CheckMenuItem(menu, IDM_CDROM_1_C + (e * 1000) + cdrom_drives[e].ide_channel, MF_CHECKED); - - if (!find_in_array(valid_scsi_ids, cdrom_drives[e].scsi_device_id, 15, IDM_CDROM_1_0 + (e * 1000))) - { - fatal("CD-ROM %i: Invalid SCSI ID\n", e); - } - - CheckMenuItem(menu, IDM_CDROM_1_0 + (e * 1000) + cdrom_drives[e].scsi_device_id, MF_CHECKED); - - if (!find_in_array(valid_scsi_luns, cdrom_drives[e].scsi_device_lun, 8, IDM_CDROM_1_LUN_0 + (e * 1000))) - { - fatal("CD-ROM %i: Invalid SCSI LUN\n", e); - } - - CheckMenuItem(menu, IDM_CDROM_1_LUN_0 + (e * 1000) + cdrom_drives[e].scsi_device_lun, MF_CHECKED); - if (cdrom_drives[e].host_drive == 200) { - CheckMenuItem(menu, IDM_CDROM_1_ISO + (e * 1000), MF_CHECKED); + CheckMenuItem(smenu, IDM_CDROM_1_ISO + e, MF_CHECKED); + } + else if (cdrom_drives[e].host_drive >= 65) + { + CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); } else { - CheckMenuItem(menu, IDM_CDROM_1_REAL + (e * 1000) + cdrom_drives[e].host_drive, MF_CHECKED); + CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); } } - if (ide_enable[2]) - CheckMenuItem(menu, IDM_IDE_TER_ENABLED, MF_CHECKED); - - if (!find_in_array(valid_irqs, ide_irq[2], 6, IDM_IDE_TER_IRQ9 - 9)) - { - fatal("Tertiary IDE controller: Invalid IRQ\n"); - } - - CheckMenuItem(menu, IDM_IDE_TER_IRQ9 - 9 + ide_irq[2], MF_CHECKED); - - if (ide_enable[3]) - CheckMenuItem(menu, IDM_IDE_QUA_ENABLED, MF_CHECKED); - - if (!find_in_array(valid_irqs, ide_irq[3], 6, IDM_IDE_QUA_IRQ9 - 9)) - { - fatal("Quaternary IDE controller: Invalid IRQ\n"); - } - - CheckMenuItem(menu, IDM_IDE_QUA_IRQ9 - 9 + ide_irq[3], MF_CHECKED); - #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); @@ -781,23 +1239,16 @@ int WINAPI WinMain (HINSTANCE hThisInstance, #endif #endif - CheckMenuItem(menu, IDM_USE_NUKEDOPL, opl3_type ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_FLASH, enable_flash ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); - // pclog("Checking video resize menu item...\n"); if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); - // pclog("Checking video API menu item...\n"); CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - // pclog("Checking video fill screen menu item...\n"); CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); -// set_display_switch_mode(SWITCH_BACKGROUND); CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - // pclog("Preparing ROM sets...\n"); d=romset; for (c=0;c= 0; c--) { if (gfx_present[c]) @@ -862,10 +1319,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, atexit(releasemouse); -// QueryPerformanceFrequency(&counter_base); -/// QueryPerformanceCounter(&counter_posold); -// counter_posold.QuadPart*=100; - ghMutex = CreateMutex(NULL, FALSE, NULL); mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); @@ -876,18 +1329,13 @@ int WINAPI WinMain (HINSTANCE hThisInstance, QueryPerformanceFrequency(&qpc_freq); timer_freq = qpc_freq.QuadPart; -// focus=1; -// setrefresh(100); - -// ShowCursor(TRUE); - if (start_in_fullscreen) { startblit(); mouse_close(); vid_apis[0][vid_api].close(); video_fullscreen = 1; - vid_apis[1][vid_api].init(ghwnd); + vid_apis[1][vid_api].init(hwndRender); mouse_init(); leave_fullscreen_flag = 0; endblit(); @@ -900,29 +1348,21 @@ int WINAPI WinMain (HINSTANCE hThisInstance, window_h, TRUE); } + else + { + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + MoveWindow(hwndStatus, 0, winsizey + 6, + winsizex, + 17, + TRUE); + } /* Run the message loop. It will run until GetMessage() returns 0 */ while (!quited) { -/* if (infocus) - { - if (drawits) - { - drawits--; - if (drawits>10) drawits=0; - runpc(); - } -//; else -// sleep(0); - // if ((recv_key[KEY_LCONTROL] || recv_key[KEY_RCONTROL]) && recv_key[KEY_END] && mousecapture) - // if ((recv_key[KEY_LCONTROL] || recv_key[KEY_RCONTROL]) && recv_key[0x58] && mousecapture) - // if (recv_key[0x58] && recv_key[0x42] && mousecapture) - { - ClipCursor(&oldclip); - mousecapture=0; - } - }*/ - while (((bRet = GetMessage(&messages,NULL,0,0)) != 0) && !quited) { if (bRet == -1) @@ -936,7 +1376,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, TranslateMessage(&messages); DispatchMessage(&messages); } - // if ((recv_key[KEY_LCONTROL] || recv_key[KEY_RCONTROL]) && recv_key[KEY_END] && mousecapture) if (recv_key[0x58] && recv_key[0x42] && mousecapture) { @@ -955,28 +1394,20 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } quited=1; -// else -// sleep(10); } startblit(); -// pclog("Sleep 1000\n"); Sleep(200); -// pclog("TerminateThread\n"); TerminateThread(mainthreadh,0); -// pclog("Quited? %i\n",quited); -// pclog("Closepc\n"); savenvr(); saveconfig(); if (save_window_pos && window_remember) saveconfig(); closepc(); -// pclog("dumpregs\n"); vid_apis[video_fullscreen][vid_api].close(); timeEndPeriod(1); -// dumpregs(); if (mousecapture) { ClipCursor(&oldclip); @@ -986,114 +1417,29 @@ int WINAPI WinMain (HINSTANCE hThisInstance, UnregisterClass(szSubClassName, hinstance); UnregisterClass(szClassName, hinstance); -// pclog("Ending! %i %i\n",messages.wParam,quited); return messages.wParam; } -char openfilestring[260]; -int getfile(HWND hwnd, char *f, char *fn) -{ - OPENFILENAME ofn; // common dialog box structure - BOOL r; - DWORD err; - - // Initialize OPENFILENAME - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFile = openfilestring; - // - // Set lpstrFile[0] to '\0' so that GetOpenFileName does not - // use the contents of szFile to initialize itself. - // -// ofn.lpstrFile[0] = '\0'; - strcpy(ofn.lpstrFile,fn); - ofn.nMaxFile = sizeof(openfilestring); - ofn.lpstrFilter = f;//"All\0*.*\0Text\0*.TXT\0"; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - // Display the Open dialog box. - - pclog("GetOpenFileName - lpstrFile = %s\n", ofn.lpstrFile); - r = GetOpenFileName(&ofn); - if (r) - { - pclog("GetOpenFileName return true\n"); - return 0; - } - pclog("GetOpenFileName return false\n"); - err = CommDlgExtendedError(); - pclog("CommDlgExtendedError return %04X\n", err); - return 1; -} - -int getsfile(HWND hwnd, char *f, char *fn) -{ - OPENFILENAME ofn; // common dialog box structure - BOOL r; - DWORD err; - - // Initialize OPENFILENAME - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFile = openfilestring; - // - // Set lpstrFile[0] to '\0' so that GetOpenFileName does not - // use the contents of szFile to initialize itself. - // -// ofn.lpstrFile[0] = '\0'; - strcpy(ofn.lpstrFile,fn); - ofn.nMaxFile = sizeof(openfilestring); - ofn.lpstrFilter = f;//"All\0*.*\0Text\0*.TXT\0"; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - - // Display the Open dialog box. - - pclog("GetSaveFileName - lpstrFile = %s\n", ofn.lpstrFile); - r = GetSaveFileName(&ofn); - if (r) - { - pclog("GetSaveFileName return true\n"); - return 0; - } - pclog("GetSaveFileName return false\n"); - err = CommDlgExtendedError(); - pclog("CommDlgExtendedError return %04X\n", err); - return 1; -} - - - - HHOOK hKeyboardHook; +int hook_enabled = 0; LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) { BOOL bControlKeyDown; KBDLLHOOKSTRUCT* p; - // if (nCode < 0 || nCode != HC_ACTION || (!mousecapture && !video_fullscreen)) if (nCode < 0 || nCode != HC_ACTION) return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); p = (KBDLLHOOKSTRUCT*)lParam; - if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; //disable alt-tab - if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; //disable alt-tab - if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1;//disable windows keys - if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1;//disable alt-escape - bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1);//checks ctrl key pressed - if (p->vkCode == VK_ESCAPE && bControlKeyDown) return 1; //disable ctrl-escape - + if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ + if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ + if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1; /* disable windows keys */ + if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-escape */ + bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); /* checks ctrl key pressed */ + if (p->vkCode == VK_ESCAPE && bControlKeyDown) return 1; /* disable ctrl-escape */ + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); } @@ -1113,15 +1459,13 @@ void cdrom_close(uint8_t id) } } -char *floppy_image_extensions = "All floppy images (*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.001;*.002;*.003;*.004;*.005;*.006;*.007;*.008;*.009;*.010;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0"; - int ide_ter_set_irq(HMENU hmenu, int irq, int id) { if (ide_irq[2] == irq) { return 0; } - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) + if (msgbox_reset_yn(ghwnd) != IDYES) { return 0; } @@ -1147,7 +1491,7 @@ int ide_qua_set_irq(HMENU hmenu, int irq, int id) { return 0; } - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) + if (msgbox_reset_yn(ghwnd) != IDYES) { return 0; } @@ -1177,7 +1521,7 @@ void video_toggle_option(HMENU hmenu, int *val, int id) void win_cdrom_eject(uint8_t id) { HMENU hmenu; - hmenu=GetMenu(ghwnd); + hmenu = GetSubMenu(smenu, id + 4); if (cdrom_drives[id].host_drive == 0) { /* Switch from empty to empty. Do nothing. */ @@ -1191,18 +1535,26 @@ void win_cdrom_eject(uint8_t id) /* Signal disc change to the emulated machine. */ cdrom_insert(id); } - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (id * 1000) + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (id * 1000), MF_UNCHECKED); + if (cdrom_drives[id].host_drive == 200) + { + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_UNCHECKED); + } + else + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); + } cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; cdrom_drives[id].host_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (id * 1000), MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); + update_status_bar_icon_state(0x10 | id, get_cd_state(id)); + update_tip(0x10 | id); saveconfig(); } void win_cdrom_reload(uint8_t id) { HMENU hmenu; - hmenu=GetMenu(ghwnd); + hmenu = GetSubMenu(smenu, id + 4); int new_cdrom_drive; if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) { @@ -1218,10 +1570,9 @@ void win_cdrom_reload(uint8_t id) /* Signal disc change to the emulated machine. */ cdrom_insert(id); } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (id * 1000), MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (id * 1000), MF_CHECKED); - saveconfig(); + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_CHECKED); } else { @@ -1232,30 +1583,46 @@ void win_cdrom_reload(uint8_t id) /* Signal disc change to the emulated machine. */ cdrom_insert(id); } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (id * 1000), MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (id * 1000) + cdrom_drives[id].host_drive, MF_CHECKED); - saveconfig(); + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); } + update_status_bar_icon_state(0x10 | id, get_cd_state(id)); + update_tip(0x10 | id); + saveconfig(); } -int convert_cdrom_id(int original_id) +static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { - int i = 0; + HWND h; - if (original_id >= (CDROM_NUM * 1000)) - { - return 0; + switch (message) + { + case WM_INITDIALOG: + pause = 1; + h = GetDlgItem(hdlg, IDC_ABOUT_ICON); + SendMessage(h, STM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) LoadIconBig((PCTSTR) 100)); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + default: + break; + } + break; } - for (i = 0; i < CDROM_NUM; i++) - { - if (original_id == (i * 1000)) - { - return i; - } - } - return 0; + return FALSE; +} + +void about_open(HWND hwnd) +{ + DialogBox(hinstance, (LPCSTR) ABOUTDLG, hwnd, about_dlgproc); } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -1263,33 +1630,21 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM HMENU hmenu; RECT rect; uint32_t ri_size = 0; - char temp_iso_path[1024]; - int new_cdrom_drive; - int cdrom_id = 0; - int menu_sub_param = 0; -// pclog("Message %i %08X\n",message,message); + int edgex, edgey; + int sb_borders[3]; + switch (message) { case WM_CREATE: SetTimer(hwnd, TIMER_1SEC, 1000, NULL); hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; break; case WM_COMMAND: -// pclog("WM_COMMAND %i\n",LOWORD(wParam)); hmenu=GetMenu(hwnd); switch (LOWORD(wParam)) { -#if 0 - case IDM_FILE_RESET: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpc(); - pause=0; - break; -#endif case IDM_FILE_HRESET: pause=1; Sleep(100); @@ -1309,68 +1664,12 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_FILE_EXIT: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; - case IDM_DISC_1: - case IDM_DISC_1_WP: - if (!getfile(hwnd, floppy_image_extensions, discfns[0])) - { - disc_close(0); - ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, openfilestring); - saveconfig(); - } - break; - case IDM_DISC_2: - case IDM_DISC_2_WP: - if (!getfile(hwnd, floppy_image_extensions, discfns[1])) - { - disc_close(1); - ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, openfilestring); - saveconfig(); - } - break; - case IDM_DISC_3: - case IDM_DISC_3_WP: - if (!getfile(hwnd, floppy_image_extensions, discfns[2])) - { - disc_close(2); - ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, openfilestring); - saveconfig(); - } - break; - case IDM_DISC_4: - case IDM_DISC_4_WP: - if (!getfile(hwnd, floppy_image_extensions, discfns[3])) - { - disc_close(3); - ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, openfilestring); - saveconfig(); - } - break; - case IDM_EJECT_1: - disc_close(0); - saveconfig(); - break; - case IDM_EJECT_2: - disc_close(1); - saveconfig(); - break; - case IDM_EJECT_3: - disc_close(2); - saveconfig(); - break; - case IDM_EJECT_4: - disc_close(3); - saveconfig(); - break; - case IDM_HDCONF: - hdconf_open(hwnd); - break; case IDM_CONFIG: - config_open(hwnd); + win_settings_open(hwnd); break; + case IDM_ABOUT: + about_open(hwnd); + break; case IDM_STATUS: status_open(hwnd); break; @@ -1383,6 +1682,19 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + GetWindowRect(hwndStatus,&rect); + SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + if (vid_resize) + { + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + } + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + win_doresize = 1; saveconfig(); break; case IDM_VID_REMEMBER: @@ -1406,7 +1718,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM vid_apis[0][vid_api].close(); vid_api = LOWORD(wParam) - IDM_VID_DDRAW; CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - vid_apis[0][vid_api].init(ghwnd); + vid_apis[0][vid_api].init(hwndRender); endblit(); saveconfig(); device_force_redraw(); @@ -1416,7 +1728,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (video_fullscreen_first) { video_fullscreen_first = 0; - MessageBox(hwnd, "Use CTRL + ALT + PAGE DOWN to return to windowed mode", "86Box", MB_OK); + msgbox_info(ghwnd, 2193); } startblit(); video_wait_for_blit(); @@ -1450,20 +1762,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM saveconfig(); break; - case IDM_USE_NUKEDOPL: - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - opl3_type ^= 1; - CheckMenuItem(hmenu, IDM_USE_NUKEDOPL, opl3_type ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - case IDM_VID_FORCE43: video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); break; @@ -1474,6 +1772,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_VID_OVERSCAN: video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); + update_overscan = 1; break; case IDM_VID_FLASH: @@ -1536,9 +1835,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_LOAD: pause = 1; - if (!getfile(hwnd, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "")) + if (!file_dlg_st(hwnd, 2174, "", 0)) { - if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) == IDOK) + if (msgbox_reset_yn(ghwnd) == IDYES) { loadconfig(openfilestring); config_save(config_file_default); @@ -1552,314 +1851,10 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_SAVE: pause = 1; - if (!getsfile(hwnd, "Configuration (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0", "")) + if (!file_dlg_st(hwnd, 2174, "", 1)) config_save(openfilestring); pause = 0; - break; - - case IDM_CDROM_1_ENABLED: - case IDM_CDROM_2_ENABLED: - case IDM_CDROM_3_ENABLED: - case IDM_CDROM_4_ENABLED: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_ENABLED); - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - cdrom_drives[cdrom_id].enabled ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_ENABLED + (cdrom_id * 1000), cdrom_drives[cdrom_id].enabled ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_CDROM_1_SOUND_ON: - case IDM_CDROM_2_SOUND_ON: - case IDM_CDROM_3_SOUND_ON: - case IDM_CDROM_4_SOUND_ON: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_SOUND_ON); - Sleep(100); - cdrom_drives[cdrom_id].sound_on ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_SOUND_ON + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_1_SCSI: - case IDM_CDROM_2_SCSI: - case IDM_CDROM_3_SCSI: - case IDM_CDROM_4_SCSI: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_SCSI); - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - cdrom_drives[cdrom_id].bus_type ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_SCSI + (cdrom_id * 1000), cdrom_drives[cdrom_id].bus_type ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_CDROM_1_DMA: - case IDM_CDROM_2_DMA: - case IDM_CDROM_3_DMA: - case IDM_CDROM_4_DMA: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_DMA); - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - cdrom_drives[cdrom_id].atapi_dma ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_DMA + (cdrom_id * 1000), cdrom_drives[cdrom_id].atapi_dma ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_CDROM_1_C ... IDM_CDROM_1_H: - case IDM_CDROM_2_C ... IDM_CDROM_2_H: - case IDM_CDROM_3_C ... IDM_CDROM_3_H: - case IDM_CDROM_4_C ... IDM_CDROM_4_H: - menu_sub_param = LOWORD(wParam) % 100; - cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_C); - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - CheckMenuItem(hmenu, IDM_CDROM_1_C + (cdrom_id * 1000) + cdrom_drives[cdrom_id].ide_channel, MF_UNCHECKED); - cdrom_drives[cdrom_id].ide_channel = menu_sub_param; - CheckMenuItem(hmenu, IDM_CDROM_1_C + (cdrom_id * 1000) + cdrom_drives[cdrom_id].ide_channel, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_CDROM_1_0 ... IDM_CDROM_1_15: - case IDM_CDROM_2_0 ... IDM_CDROM_2_15: - case IDM_CDROM_3_0 ... IDM_CDROM_3_15: - case IDM_CDROM_4_0 ... IDM_CDROM_4_15: - menu_sub_param = LOWORD(wParam) % 100; - cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_0); - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - CheckMenuItem(hmenu, IDM_CDROM_1_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_id, MF_UNCHECKED); - cdrom_drives[cdrom_id].scsi_device_id = menu_sub_param; - CheckMenuItem(hmenu, IDM_CDROM_1_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_CDROM_1_LUN_0 ... IDM_CDROM_1_LUN_7: - case IDM_CDROM_2_LUN_0 ... IDM_CDROM_2_LUN_7: - case IDM_CDROM_3_LUN_0 ... IDM_CDROM_3_LUN_7: - case IDM_CDROM_4_LUN_0 ... IDM_CDROM_4_LUN_7: - menu_sub_param = LOWORD(wParam) % 100; - cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_LUN_0); - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - CheckMenuItem(hmenu, IDM_CDROM_1_LUN_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_lun, MF_UNCHECKED); - cdrom_drives[cdrom_id].scsi_device_lun = menu_sub_param; - CheckMenuItem(hmenu, IDM_CDROM_1_LUN_0 + (cdrom_id * 1000) + cdrom_drives[cdrom_id].scsi_device_lun, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_IDE_TER_ENABLED: - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - ide_enable[2] ^= 1; - CheckMenuItem(hmenu, IDM_IDE_TER_ENABLED, ide_enable[2] ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_IDE_TER_IRQ9: - ide_ter_set_irq(hmenu, 9, IDM_IDE_TER_IRQ9); - break; - - case IDM_IDE_TER_IRQ10: - ide_ter_set_irq(hmenu, 10, IDM_IDE_TER_IRQ10); - break; - - case IDM_IDE_TER_IRQ11: - ide_ter_set_irq(hmenu, 11, IDM_IDE_TER_IRQ11); - break; - - case IDM_IDE_TER_IRQ12: - ide_ter_set_irq(hmenu, 12, IDM_IDE_TER_IRQ12); - break; - - case IDM_IDE_TER_IRQ14: - ide_ter_set_irq(hmenu, 14, IDM_IDE_TER_IRQ14); - break; - - case IDM_IDE_TER_IRQ15: - ide_ter_set_irq(hmenu, 15, IDM_IDE_TER_IRQ15); - break; - - case IDM_IDE_QUA_ENABLED: - if (MessageBox(NULL,"This will reset 86Box!\nOkay to continue?","86Box",MB_OKCANCEL) != IDOK) - { - break; - } - pause = 1; - Sleep(100); - ide_enable[3] ^= 1; - CheckMenuItem(hmenu, IDM_IDE_QUA_ENABLED, ide_enable[3] ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); - resetpchard(); - pause = 0; - break; - - case IDM_IDE_QUA_IRQ9: - ide_qua_set_irq(hmenu, 9, IDM_IDE_QUA_IRQ9); - break; - - case IDM_IDE_QUA_IRQ10: - ide_qua_set_irq(hmenu, 10, IDM_IDE_QUA_IRQ10); - break; - - case IDM_IDE_QUA_IRQ11: - ide_qua_set_irq(hmenu, 11, IDM_IDE_QUA_IRQ11); - break; - - case IDM_IDE_QUA_IRQ12: - ide_qua_set_irq(hmenu, 12, IDM_IDE_QUA_IRQ12); - break; - - case IDM_IDE_QUA_IRQ14: - ide_qua_set_irq(hmenu, 14, IDM_IDE_QUA_IRQ14); - break; - - case IDM_IDE_QUA_IRQ15: - ide_qua_set_irq(hmenu, 15, IDM_IDE_QUA_IRQ15); - break; - - case IDM_CDROM_1_EMPTY: - case IDM_CDROM_2_EMPTY: - case IDM_CDROM_3_EMPTY: - case IDM_CDROM_4_EMPTY: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_EMPTY); - win_cdrom_eject(cdrom_id); -#if 0 - if (cdrom_drive == 0) - { - /* Switch from empty to empty. Do nothing. */ - break; - } - cdrom->exit(); - cdrom_close(); - cdrom_null_open(0); - if (cdrom_enabled) - { - /* Signal disc change to the emulated machine. */ - SCSICDROM_Insert(); - } - CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - old_cdrom_drive = cdrom_drive; - cdrom_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED); - saveconfig(); -#endif - break; - - case IDM_CDROM_1_RELOAD: - case IDM_CDROM_2_RELOAD: - case IDM_CDROM_3_RELOAD: - case IDM_CDROM_4_RELOAD: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_RELOAD); - win_cdrom_reload(cdrom_id); - break; - - case IDM_CDROM_1_ISO: - case IDM_CDROM_2_ISO: - case IDM_CDROM_3_ISO: - case IDM_CDROM_4_ISO: - cdrom_id = convert_cdrom_id(LOWORD(wParam) - IDM_CDROM_1_ISO); - if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",cdrom_iso[cdrom_id].iso_path)) - { - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - strcpy(temp_iso_path, openfilestring); - if ((strcmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) - { - /* Switching from ISO to the same ISO. Do nothing. */ - break; - } - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - iso_open(cdrom_id, temp_iso_path); - if (cdrom_drives[cdrom_id].enabled) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (cdrom_id * 1000), MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (cdrom_id * 1000) + cdrom_drives[cdrom_id].host_drive, MF_UNCHECKED); - } - cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (cdrom_id * 1000), MF_CHECKED); - saveconfig(); - } - break; - - default: - menu_sub_param = LOWORD(wParam) % 100; - cdrom_id = convert_cdrom_id(LOWORD(wParam) - menu_sub_param - IDM_CDROM_1_REAL); - if ((LOWORD(wParam) > IDM_CDROM_1_REAL + (cdrom_id * 1000)) && (LOWORD(wParam) < (IDM_CDROM_1_REAL + (cdrom_id * 1000) + 100))) - { - new_cdrom_drive = menu_sub_param; - if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) - { - /* Switching to the same drive. Do nothing. */ - break; - } - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - ioctl_open(cdrom_id, new_cdrom_drive); - if (cdrom_drives[cdrom_id].enabled) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + (cdrom_id * 1000), MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (cdrom_id * 1000) + cdrom_drives[cdrom_id].host_drive, MF_UNCHECKED); - } - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + (cdrom_id * 1000), MF_UNCHECKED); - cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + (cdrom_id * 1000) + cdrom_drives[cdrom_id].host_drive, MF_CHECKED); - saveconfig(); - } - break; + break; } return 0; @@ -1894,12 +1889,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM const RAWKEYBOARD rawKB = raw->data.keyboard; USHORT scancode = rawKB.MakeCode; - // pclog("Keyboard input received: S:%X VK:%X F:%X\n", c, d, e); - /* If it's not a scan code that starts with 0xE1 */ if (!(rawKB.Flags & RI_KEY_E1)) { - // pclog("Non-E1 triggered, make code is %04X\n", rawKB.MakeCode); if (rawKB.Flags & RI_KEY_E0) scancode |= (0xE0 << 8); @@ -1921,7 +1913,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } else { - // pclog("E1 triggered, make code is %04X\n", rawKB.MakeCode); if (rawKB.MakeCode == 0x1D) scancode = 0xFF; if (!(scancode & 0xf00)) @@ -1938,9 +1929,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case WM_SETFOCUS: infocus=1; - // QueryPerformanceCounter(&counter_posold); -// pclog("Set focus!\n"); + if (!hook_enabled) + { + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + } break; + case WM_KILLFOCUS: infocus=0; if (mousecapture) @@ -1949,10 +1944,14 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM ShowCursor(TRUE); mousecapture=0; } -// pclog("Lost focus!\n"); memset(rawinputkey, 0, sizeof(rawinputkey)); if (video_fullscreen) leave_fullscreen_flag = 1; + if (hook_enabled) + { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } break; case WM_LBUTTONUP: @@ -1968,7 +1967,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; ClipCursor(&pcclip); mousecapture = 1; -// ShowCursor(FALSE); while (1) { if (ShowCursor(FALSE) < 0) break; @@ -1982,12 +1980,16 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_ENTERMENULOOP: -// if (key[KEY_ALT] || key[KEY_ALTGR]) return 0; break; case WM_SIZE: - winsizex=lParam&0xFFFF; - winsizey=lParam>>16; + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); if (vid_apis[video_fullscreen][vid_api].resize) { @@ -1997,6 +1999,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM endblit(); } + MoveWindow(hwndStatus, 0, winsizey + 6, + winsizex, + 17, + TRUE); + if (mousecapture) { RECT pcclip; @@ -2060,11 +2067,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case WM_SYSKEYDOWN: case WM_KEYUP: case WM_SYSKEYUP: -// if (mousecapture) return 0; -// return DefWindowProc (hwnd, message, wParam, lParam); - case WM_DESTROY: UnhookWindowsHookEx( hKeyboardHook ); KillTimer(hwnd, TIMER_1SEC); @@ -2072,13 +2076,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_SYSCOMMAND: - // if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0 && (video_fullscreen || mousecapture)) /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) return 0; /*disable ALT key for menu*/ default: -// pclog("Def %08X %i\n",message,message); return DefWindowProc (hwnd, message, wParam, lParam); } return 0; @@ -2093,3 +2095,241 @@ LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR } return 0; } + +VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) +{ + HMENU pmenu; + int menu_id = -1; + if (id >= (sb_parts - 1)) + { + return; + } + pt.x = id * sb_icon_width; /* Justify to the left. */ + pt.y = 0; /* Justify to the top. */ + ClientToScreen(hwnd, (LPPOINT) &pt); + if ((sb_part_meanings[id] & 0x30) == 0x00) + { + menu_id = sb_part_meanings[id] & 0xf; + } + else if ((sb_part_meanings[id] & 0x30) == 0x10) + { + menu_id = (sb_part_meanings[id] & 0xf) + 4; + } + if (menu_id != -1) + { + pmenu = GetSubMenu(smenu, menu_id); + TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); + } +} + +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + POINT pt; + + char temp_iso_path[1024]; + int new_cdrom_drive; + int cdrom_id = 0; + int menu_sub_param = 0; + int menu_super_param = 0; + + HMENU hmenu; + + switch (message) + { + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDM_DISC_1: + case IDM_DISC_1_WP: + if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + { + disc_close(0); + ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; + disc_load(0, openfilestring); + update_status_bar_icon_state(0x00, 0); + update_tip(0x00); + saveconfig(); + } + break; + case IDM_DISC_2: + case IDM_DISC_2_WP: + if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + { + disc_close(1); + ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; + disc_load(1, openfilestring); + update_status_bar_icon_state(0x01, 0); + update_tip(0x01); + saveconfig(); + } + break; + case IDM_DISC_3: + case IDM_DISC_3_WP: + if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + { + disc_close(2); + ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; + disc_load(2, openfilestring); + update_status_bar_icon_state(0x02, 0); + update_tip(0x02); + saveconfig(); + } + break; + case IDM_DISC_4: + case IDM_DISC_4_WP: + if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + { + disc_close(3); + ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; + disc_load(3, openfilestring); + update_status_bar_icon_state(0x03, 0); + update_tip(0x03); + saveconfig(); + } + break; + case IDM_EJECT_1: + disc_close(0); + update_status_bar_icon_state(0x00, 1); + update_tip(0x00); + saveconfig(); + break; + case IDM_EJECT_2: + disc_close(1); + update_status_bar_icon_state(0x01, 1); + update_tip(0x01); + saveconfig(); + break; + case IDM_EJECT_3: + disc_close(2); + update_status_bar_icon_state(0x02, 1); + update_tip(0x02); + saveconfig(); + break; + case IDM_EJECT_4: + disc_close(3); + update_status_bar_icon_state(0x03, 1); + update_tip(0x03); + saveconfig(); + break; + + case IDM_CDROM_1_MUTE: + case IDM_CDROM_2_MUTE: + case IDM_CDROM_3_MUTE: + case IDM_CDROM_4_MUTE: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + Sleep(100); + cdrom_drives[cdrom_id].sound_on ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); + saveconfig(); + sound_cd_thread_reset(); + break; + + case IDM_CDROM_1_EMPTY: + case IDM_CDROM_2_EMPTY: + case IDM_CDROM_3_EMPTY: + case IDM_CDROM_4_EMPTY: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + win_cdrom_eject(cdrom_id); + break; + + case IDM_CDROM_1_RELOAD: + case IDM_CDROM_2_RELOAD: + case IDM_CDROM_3_RELOAD: + case IDM_CDROM_4_RELOAD: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + win_cdrom_reload(cdrom_id); + break; + + case IDM_CDROM_1_ISO: + case IDM_CDROM_2_ISO: + case IDM_CDROM_3_ISO: + case IDM_CDROM_4_ISO: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + if (!file_dlg_st(hwnd, 2175, cdrom_iso[cdrom_id].iso_path, 0)) + { + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + strcpy(temp_iso_path, openfilestring); + if ((strcmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + { + /* Switching from ISO to the same ISO. Do nothing. */ + break; + } + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + iso_open(cdrom_id, temp_iso_path); + if (cdrom_drives[cdrom_id].enabled) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(cdrom_id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); + } + cdrom_drives[cdrom_id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_CHECKED); + update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); + update_tip(0x10 | cdrom_id); + saveconfig(); + } + break; + + default: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; + /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ + if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) + { + new_cdrom_drive = menu_sub_param; + if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) + { + /* Switching to the same drive. Do nothing. */ + break; + } + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + ioctl_open(cdrom_id, new_cdrom_drive); + if (cdrom_drives[cdrom_id].enabled) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(cdrom_id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); + } + CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_UNCHECKED); + cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); + update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); + update_tip(0x10 | cdrom_id); + saveconfig(); + } + break; + } + return 0; + + case WM_LBUTTONDOWN: + GetClientRect(hwnd, (LPRECT)& rc); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + if (PtInRect((LPRECT) &rc, pt)) + { + HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); + } + break; + + default: + return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); + } + return 0; +} diff --git a/src/win.h b/src/win.h index 5807bb2e9..17316c27a 100644 --- a/src/win.h +++ b/src/win.h @@ -11,6 +11,7 @@ extern "C" { #define szClassName "86BoxMainWnd" #define szSubClassName "86BoxSubWnd" +#define szStatusBarClassName "86BoxStatusBar" void leave_fullscreen(); @@ -23,10 +24,6 @@ void status_open(HWND hwnd); extern HWND status_hwnd; extern int status_is_open; -void hdconf_open(HWND hwnd); - -void config_open(HWND hwnd); - void deviceconfig_open(HWND hwnd, struct device_t *device); void joystickconfig_open(HWND hwnd, int joy_nr, int type); @@ -35,4 +32,19 @@ extern char openfilestring[260]; int getfile(HWND hwnd, char *f, char *fn); int getsfile(HWND hwnd, char *f, char *fn); +void get_executable_name(char *s, int size); +void set_window_title(char *s); + +void startblit(); +void endblit(); + extern int pause; + +void win_settings_open(HWND hwnd); +void win_menu_update(); + +void update_status_bar_panes(HWND hwnds); + +int fdd_type_to_icon(int type); + +extern HWND hwndStatus; diff --git a/src/x86_flags.h b/src/x86_flags.h index f1a394e61..dab54dbf6 100644 --- a/src/x86_flags.h +++ b/src/x86_flags.h @@ -35,10 +35,10 @@ enum FLAGS_DEC8, FLAGS_DEC16, - FLAGS_DEC32, + FLAGS_DEC32 }; -static inline int ZF_SET() +static __inline int ZF_SET() { switch (cpu_state.flags_op) { @@ -70,10 +70,13 @@ static inline int ZF_SET() case FLAGS_UNKNOWN: return flags & Z_FLAG; + + default: + return 0; } } -static inline int NF_SET() +static __inline int NF_SET() { switch (cpu_state.flags_op) { @@ -109,10 +112,13 @@ static inline int NF_SET() case FLAGS_UNKNOWN: return flags & N_FLAG; + + default: + return 0; } } -static inline int PF_SET() +static __inline int PF_SET() { switch (cpu_state.flags_op) { @@ -144,10 +150,13 @@ static inline int PF_SET() case FLAGS_UNKNOWN: return flags & P_FLAG; + + default: + return 0; } } -static inline int VF_SET() +static __inline int VF_SET() { switch (cpu_state.flags_op) { @@ -195,10 +204,13 @@ static inline int VF_SET() case FLAGS_UNKNOWN: return flags & V_FLAG; + + default: + return 0; } } -static inline int AF_SET() +static __inline int AF_SET() { switch (cpu_state.flags_op) { @@ -234,10 +246,13 @@ static inline int AF_SET() case FLAGS_UNKNOWN: return flags & A_FLAG; + + default: + return 0; } } -static inline int CF_SET() +static __inline int CF_SET() { switch (cpu_state.flags_op) { @@ -285,17 +300,13 @@ static inline int CF_SET() case FLAGS_INC32: case FLAGS_UNKNOWN: return flags & C_FLAG; + + default: + return 0; } } -//#define ZF_SET() (flags & Z_FLAG) -//#define NF_SET() (flags & N_FLAG) -//#define PF_SET() (flags & P_FLAG) -//#define VF_SET() (flags & V_FLAG) -//#define CF_SET() (flags & C_FLAG) -//#define AF_SET() (flags & A_FLAG) - -static inline void flags_rebuild() +static __inline void flags_rebuild() { if (cpu_state.flags_op != FLAGS_UNKNOWN) { @@ -311,12 +322,12 @@ static inline void flags_rebuild() } } -static inline void flags_extract() +static __inline void flags_extract() { cpu_state.flags_op = FLAGS_UNKNOWN; } -static inline void flags_rebuild_c() +static __inline void flags_rebuild_c() { if (cpu_state.flags_op != FLAGS_UNKNOWN) { @@ -327,17 +338,17 @@ static inline void flags_rebuild_c() } } -static inline void setznp8(uint8_t val) +static __inline void setznp8(uint8_t val) { cpu_state.flags_op = FLAGS_ZN8; cpu_state.flags_res = val; } -static inline void setznp16(uint16_t val) +static __inline void setznp16(uint16_t val) { cpu_state.flags_op = FLAGS_ZN16; cpu_state.flags_res = val; } -static inline void setznp32(uint32_t val) +static __inline void setznp32(uint32_t val) { cpu_state.flags_op = FLAGS_ZN32; cpu_state.flags_res = val; @@ -349,28 +360,28 @@ static inline void setznp32(uint32_t val) cpu_state.flags_op1 = orig; \ cpu_state.flags_op2 = shift; -static inline void setadd8(uint8_t a, uint8_t b) +static __inline void setadd8(uint8_t a, uint8_t b) { cpu_state.flags_op1 = a; cpu_state.flags_op2 = b; cpu_state.flags_res = (a + b) & 0xff; cpu_state.flags_op = FLAGS_ADD8; } -static inline void setadd16(uint16_t a, uint16_t b) +static __inline void setadd16(uint16_t a, uint16_t b) { cpu_state.flags_op1 = a; cpu_state.flags_op2 = b; cpu_state.flags_res = (a + b) & 0xffff; cpu_state.flags_op = FLAGS_ADD16; } -static inline void setadd32(uint32_t a, uint32_t b) +static __inline void setadd32(uint32_t a, uint32_t b) { cpu_state.flags_op1 = a; cpu_state.flags_op2 = b; cpu_state.flags_res = a + b; cpu_state.flags_op = FLAGS_ADD32; } -static inline void setadd8nc(uint8_t a, uint8_t b) +static __inline void setadd8nc(uint8_t a, uint8_t b) { flags_rebuild_c(); cpu_state.flags_op1 = a; @@ -378,7 +389,7 @@ static inline void setadd8nc(uint8_t a, uint8_t b) cpu_state.flags_res = (a + b) & 0xff; cpu_state.flags_op = FLAGS_INC8; } -static inline void setadd16nc(uint16_t a, uint16_t b) +static __inline void setadd16nc(uint16_t a, uint16_t b) { flags_rebuild_c(); cpu_state.flags_op1 = a; @@ -386,7 +397,7 @@ static inline void setadd16nc(uint16_t a, uint16_t b) cpu_state.flags_res = (a + b) & 0xffff; cpu_state.flags_op = FLAGS_INC16; } -static inline void setadd32nc(uint32_t a, uint32_t b) +static __inline void setadd32nc(uint32_t a, uint32_t b) { flags_rebuild_c(); cpu_state.flags_op1 = a; @@ -395,21 +406,21 @@ static inline void setadd32nc(uint32_t a, uint32_t b) cpu_state.flags_op = FLAGS_INC32; } -static inline void setsub8(uint8_t a, uint8_t b) +static __inline void setsub8(uint8_t a, uint8_t b) { cpu_state.flags_op1 = a; cpu_state.flags_op2 = b; cpu_state.flags_res = (a - b) & 0xff; cpu_state.flags_op = FLAGS_SUB8; } -static inline void setsub16(uint16_t a, uint16_t b) +static __inline void setsub16(uint16_t a, uint16_t b) { cpu_state.flags_op1 = a; cpu_state.flags_op2 = b; cpu_state.flags_res = (a - b) & 0xffff; cpu_state.flags_op = FLAGS_SUB16; } -static inline void setsub32(uint32_t a, uint32_t b) +static __inline void setsub32(uint32_t a, uint32_t b) { cpu_state.flags_op1 = a; cpu_state.flags_op2 = b; @@ -417,7 +428,7 @@ static inline void setsub32(uint32_t a, uint32_t b) cpu_state.flags_op = FLAGS_SUB32; } -static inline void setsub8nc(uint8_t a, uint8_t b) +static __inline void setsub8nc(uint8_t a, uint8_t b) { flags_rebuild_c(); cpu_state.flags_op1 = a; @@ -425,7 +436,7 @@ static inline void setsub8nc(uint8_t a, uint8_t b) cpu_state.flags_res = (a - b) & 0xff; cpu_state.flags_op = FLAGS_DEC8; } -static inline void setsub16nc(uint16_t a, uint16_t b) +static __inline void setsub16nc(uint16_t a, uint16_t b) { flags_rebuild_c(); cpu_state.flags_op1 = a; @@ -433,7 +444,7 @@ static inline void setsub16nc(uint16_t a, uint16_t b) cpu_state.flags_res = (a - b) & 0xffff; cpu_state.flags_op = FLAGS_DEC16; } -static inline void setsub32nc(uint32_t a, uint32_t b) +static __inline void setsub32nc(uint32_t a, uint32_t b) { flags_rebuild_c(); cpu_state.flags_op1 = a; @@ -442,7 +453,7 @@ static inline void setsub32nc(uint32_t a, uint32_t b) cpu_state.flags_op = FLAGS_DEC32; } -static inline void setadc8(uint8_t a, uint8_t b) +static __inline void setadc8(uint8_t a, uint8_t b) { uint16_t c=(uint16_t)a+(uint16_t)b+tempc; cpu_state.flags_op = FLAGS_UNKNOWN; @@ -452,7 +463,7 @@ static inline void setadc8(uint8_t a, uint8_t b) if (!((a^b)&0x80)&&((a^c)&0x80)) flags|=V_FLAG; if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; } -static inline void setadc16(uint16_t a, uint16_t b) +static __inline void setadc16(uint16_t a, uint16_t b) { uint32_t c=(uint32_t)a+(uint32_t)b+tempc; cpu_state.flags_op = FLAGS_UNKNOWN; @@ -463,7 +474,7 @@ static inline void setadc16(uint16_t a, uint16_t b) if (((a&0xF)+(b&0xF))&0x10) flags|=A_FLAG; } -static inline void setsbc8(uint8_t a, uint8_t b) +static __inline void setsbc8(uint8_t a, uint8_t b) { uint16_t c=(uint16_t)a-(((uint16_t)b)+tempc); cpu_state.flags_op = FLAGS_UNKNOWN; @@ -473,7 +484,7 @@ static inline void setsbc8(uint8_t a, uint8_t b) if ((a^b)&(a^c)&0x80) flags|=V_FLAG; if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; } -static inline void setsbc16(uint16_t a, uint16_t b) +static __inline void setsbc16(uint16_t a, uint16_t b) { uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); cpu_state.flags_op = FLAGS_UNKNOWN; @@ -485,7 +496,7 @@ static inline void setsbc16(uint16_t a, uint16_t b) if (((a&0xF)-(b&0xF))&0x10) flags|=A_FLAG; } -static inline void setadc32(uint32_t a, uint32_t b) +static __inline void setadc32(uint32_t a, uint32_t b) { uint32_t c=(uint32_t)a+(uint32_t)b+tempc; cpu_state.flags_op = FLAGS_UNKNOWN; @@ -496,7 +507,7 @@ static inline void setadc32(uint32_t a, uint32_t b) if (!((a^b)&0x80000000)&&((a^c)&0x80000000)) flags|=V_FLAG; if (((a&0xF)+(b&0xF)+tempc)&0x10) flags|=A_FLAG; } -static inline void setsbc32(uint32_t a, uint32_t b) +static __inline void setsbc32(uint32_t a, uint32_t b) { uint32_t c=(uint32_t)a-(((uint32_t)b)+tempc); cpu_state.flags_op = FLAGS_UNKNOWN; diff --git a/src/x86_ops_arith.h b/src/x86_ops_arith.h index 3a9f96953..3c6b67fa6 100644 --- a/src/x86_ops_arith.h +++ b/src/x86_ops_arith.h @@ -1,12 +1,14 @@ #define OP_ARITH(name, operation, setflags, flagops, gettempc) \ static int op ## name ## _b_rmw_a16(uint32_t fetchdat) \ { \ + uint8_t dst; \ + uint8_t src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ if (cpu_mod == 3) \ { \ - uint8_t dst = getr8(cpu_rm); \ - uint8_t src = getr8(cpu_reg); \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ setflags ## 8 flagops; \ setr8(cpu_rm, operation); \ CLOCK_CYCLES(timing_rr); \ @@ -14,8 +16,8 @@ } \ else \ { \ - uint8_t dst = geteab(); if (cpu_state.abrt) return 1; \ - uint8_t src = getr8(cpu_reg); \ + dst = geteab(); if (cpu_state.abrt) return 1; \ + src = getr8(cpu_reg); \ seteab(operation); if (cpu_state.abrt) return 1; \ setflags ## 8 flagops; \ CLOCK_CYCLES(timing_mr); \ @@ -25,12 +27,14 @@ } \ static int op ## name ## _b_rmw_a32(uint32_t fetchdat) \ { \ + uint8_t dst; \ + uint8_t src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ if (cpu_mod == 3) \ { \ - uint8_t dst = getr8(cpu_rm); \ - uint8_t src = getr8(cpu_reg); \ + dst = getr8(cpu_rm); \ + src = getr8(cpu_reg); \ setflags ## 8 flagops; \ setr8(cpu_rm, operation); \ CLOCK_CYCLES(timing_rr); \ @@ -38,8 +42,8 @@ } \ else \ { \ - uint8_t dst = geteab(); if (cpu_state.abrt) return 1; \ - uint8_t src = getr8(cpu_reg); \ + dst = geteab(); if (cpu_state.abrt) return 1; \ + src = getr8(cpu_reg); \ seteab(operation); if (cpu_state.abrt) return 1; \ setflags ## 8 flagops; \ CLOCK_CYCLES(timing_mr); \ @@ -50,12 +54,14 @@ \ static int op ## name ## _w_rmw_a16(uint32_t fetchdat) \ { \ + uint16_t dst; \ + uint16_t src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ if (cpu_mod == 3) \ { \ - uint16_t dst = cpu_state.regs[cpu_rm].w; \ - uint16_t src = cpu_state.regs[cpu_reg].w; \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ setflags ## 16 flagops; \ cpu_state.regs[cpu_rm].w = operation; \ CLOCK_CYCLES(timing_rr); \ @@ -63,8 +69,8 @@ } \ else \ { \ - uint16_t dst = geteaw(); if (cpu_state.abrt) return 1; \ - uint16_t src = cpu_state.regs[cpu_reg].w; \ + dst = geteaw(); if (cpu_state.abrt) return 1; \ + src = cpu_state.regs[cpu_reg].w; \ seteaw(operation); if (cpu_state.abrt) return 1; \ setflags ## 16 flagops; \ CLOCK_CYCLES(timing_mr); \ @@ -74,12 +80,14 @@ } \ static int op ## name ## _w_rmw_a32(uint32_t fetchdat) \ { \ + uint16_t dst; \ + uint16_t src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ if (cpu_mod == 3) \ { \ - uint16_t dst = cpu_state.regs[cpu_rm].w; \ - uint16_t src = cpu_state.regs[cpu_reg].w; \ + dst = cpu_state.regs[cpu_rm].w; \ + src = cpu_state.regs[cpu_reg].w; \ setflags ## 16 flagops; \ cpu_state.regs[cpu_rm].w = operation; \ CLOCK_CYCLES(timing_rr); \ @@ -87,8 +95,8 @@ } \ else \ { \ - uint16_t dst = geteaw(); if (cpu_state.abrt) return 1; \ - uint16_t src = cpu_state.regs[cpu_reg].w; \ + dst = geteaw(); if (cpu_state.abrt) return 1; \ + src = cpu_state.regs[cpu_reg].w; \ seteaw(operation); if (cpu_state.abrt) return 1; \ setflags ## 16 flagops; \ CLOCK_CYCLES(timing_mr); \ @@ -99,12 +107,14 @@ \ static int op ## name ## _l_rmw_a16(uint32_t fetchdat) \ { \ + uint32_t dst; \ + uint32_t src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_16(fetchdat); \ if (cpu_mod == 3) \ { \ - uint32_t dst = cpu_state.regs[cpu_rm].l; \ - uint32_t src = cpu_state.regs[cpu_reg].l; \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ setflags ## 32 flagops; \ cpu_state.regs[cpu_rm].l = operation; \ CLOCK_CYCLES(timing_rr); \ @@ -112,8 +122,8 @@ } \ else \ { \ - uint32_t dst = geteal(); if (cpu_state.abrt) return 1; \ - uint32_t src = cpu_state.regs[cpu_reg].l; \ + dst = geteal(); if (cpu_state.abrt) return 1; \ + src = cpu_state.regs[cpu_reg].l; \ seteal(operation); if (cpu_state.abrt) return 1; \ setflags ## 32 flagops; \ CLOCK_CYCLES(timing_mr); \ @@ -123,12 +133,14 @@ } \ static int op ## name ## _l_rmw_a32(uint32_t fetchdat) \ { \ + uint32_t dst; \ + uint32_t src; \ if (gettempc) tempc = CF_SET() ? 1 : 0; \ fetch_ea_32(fetchdat); \ if (cpu_mod == 3) \ { \ - uint32_t dst = cpu_state.regs[cpu_rm].l; \ - uint32_t src = cpu_state.regs[cpu_reg].l; \ + dst = cpu_state.regs[cpu_rm].l; \ + src = cpu_state.regs[cpu_reg].l; \ setflags ## 32 flagops; \ cpu_state.regs[cpu_rm].l = operation; \ CLOCK_CYCLES(timing_rr); \ @@ -136,8 +148,8 @@ } \ else \ { \ - uint32_t dst = geteal(); if (cpu_state.abrt) return 1; \ - uint32_t src = cpu_state.regs[cpu_reg].l; \ + dst = geteal(); if (cpu_state.abrt) return 1; \ + src = cpu_state.regs[cpu_reg].l; \ seteal(operation); if (cpu_state.abrt) return 1; \ setflags ## 32 flagops; \ CLOCK_CYCLES(timing_mr); \ diff --git a/src/x86_ops_bitscan.h b/src/x86_ops_bitscan.h index 834211128..9252b4b87 100644 --- a/src/x86_ops_bitscan.h +++ b/src/x86_ops_bitscan.h @@ -1,5 +1,6 @@ #define BS_common(start, end, dir, dest, time) \ flags_rebuild(); \ + instr_cycles = 0; \ if (temp) \ { \ int c; \ @@ -21,7 +22,7 @@ static int opBSF_w_a16(uint32_t fetchdat) { uint16_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_16(fetchdat); temp = geteaw(); if (cpu_state.abrt) return 1; @@ -36,7 +37,7 @@ static int opBSF_w_a16(uint32_t fetchdat) static int opBSF_w_a32(uint32_t fetchdat) { uint16_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_32(fetchdat); temp = geteaw(); if (cpu_state.abrt) return 1; @@ -51,7 +52,7 @@ static int opBSF_w_a32(uint32_t fetchdat) static int opBSF_l_a16(uint32_t fetchdat) { uint32_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_16(fetchdat); temp = geteal(); if (cpu_state.abrt) return 1; @@ -66,7 +67,7 @@ static int opBSF_l_a16(uint32_t fetchdat) static int opBSF_l_a32(uint32_t fetchdat) { uint32_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_32(fetchdat); temp = geteal(); if (cpu_state.abrt) return 1; @@ -82,7 +83,7 @@ static int opBSF_l_a32(uint32_t fetchdat) static int opBSR_w_a16(uint32_t fetchdat) { uint16_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_16(fetchdat); temp = geteaw(); if (cpu_state.abrt) return 1; @@ -97,7 +98,7 @@ static int opBSR_w_a16(uint32_t fetchdat) static int opBSR_w_a32(uint32_t fetchdat) { uint16_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_32(fetchdat); temp = geteaw(); if (cpu_state.abrt) return 1; @@ -112,7 +113,7 @@ static int opBSR_w_a32(uint32_t fetchdat) static int opBSR_l_a16(uint32_t fetchdat) { uint32_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_16(fetchdat); temp = geteal(); if (cpu_state.abrt) return 1; @@ -127,7 +128,7 @@ static int opBSR_l_a16(uint32_t fetchdat) static int opBSR_l_a32(uint32_t fetchdat) { uint32_t temp; - int instr_cycles; + int instr_cycles = 0; fetch_ea_32(fetchdat); temp = geteal(); if (cpu_state.abrt) return 1; diff --git a/src/x86_ops_call.h b/src/x86_ops_call.h index 40d90a09e..6d27373f4 100644 --- a/src/x86_ops_call.h +++ b/src/x86_ops_call.h @@ -163,7 +163,6 @@ static int opFF_w_a16(uint32_t fetchdat) break; default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; @@ -240,7 +239,6 @@ static int opFF_w_a32(uint32_t fetchdat) break; default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; @@ -318,7 +316,6 @@ static int opFF_l_a16(uint32_t fetchdat) break; default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; @@ -394,7 +391,6 @@ static int opFF_l_a32(uint32_t fetchdat) break; default: -// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; diff --git a/src/x86_ops_i686.h b/src/x86_ops_i686.h index 0b6bec4de..b684e1195 100644 --- a/src/x86_ops_i686.h +++ b/src/x86_ops_i686.h @@ -150,7 +150,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) uint8_t fxinst = 0; uint16_t twd = x87_gettag(); uint16_t old_eaaddr = 0; - int old_ismmx = cpu_state.ismmx; uint8_t ftwb = 0; uint16_t rec_ftw = 0; uint16_t fpus = 0; @@ -172,9 +171,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) if ((fxinst > 1) || (cpu_mod == 3)) { - // if (fxinst > 1) pclog("FX instruction is: %02X\n", fxinst); - // if (cpu_mod == 3) pclog("MOD is 3\n"); - x86illegal(); return cpu_state.abrt; } @@ -186,8 +182,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) if (fxinst == 1) { /* FXRSTOR */ - // pclog("FXRSTOR issued\n"); - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; @@ -251,10 +245,10 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.ismmx = 0; /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times something like this is needed*/ - if (cpu_state.MM[0].w[4] == 0xffff && cpu_state.MM[1].w[4] == 0xffff && cpu_state.MM[2].w[4] == 0xffff && cpu_state.MM[3].w[4] == 0xffff && - cpu_state.MM[4].w[4] == 0xffff && cpu_state.MM[5].w[4] == 0xffff && cpu_state.MM[6].w[4] == 0xffff && cpu_state.MM[7].w[4] == 0xffff && - !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) - cpu_state.ismmx = old_ismmx; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && + cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && + !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) + cpu_state.ismmx = 1; x87_settag(rec_ftw); @@ -265,8 +259,6 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) else { /* FXSAVE */ - // pclog("FXSAVE issued\n"); - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; @@ -333,7 +325,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) uint8_t fxinst = 0; uint16_t twd = x87_gettag(); uint32_t old_eaaddr = 0; - int old_ismmx = cpu_state.ismmx; uint8_t ftwb = 0; uint16_t rec_ftw = 0; uint16_t fpus = 0; @@ -355,9 +346,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) if ((fxinst > 1) || (cpu_mod == 3)) { - // if (fxinst > 1) pclog("FX instruction is: %02X\n", fxinst); - // if (cpu_mod == 3) pclog("MOD is 3\n"); - x86illegal(); return cpu_state.abrt; } @@ -369,8 +357,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) if (fxinst == 1) { /* FXRSTOR */ - // pclog("FXRSTOR issued\n"); - cpu_state.npxc = readmemw(easeg, cpu_state.eaaddr); fpus = readmemw(easeg, cpu_state.eaaddr + 2); cpu_state.npxc = (cpu_state.npxc & ~FPU_CW_Reserved_Bits) | 0x0040; @@ -434,10 +420,10 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.ismmx = 0; /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times something like this is needed*/ - if (cpu_state.MM[0].w[4] == 0xffff && cpu_state.MM[1].w[4] == 0xffff && cpu_state.MM[2].w[4] == 0xffff && cpu_state.MM[3].w[4] == 0xffff && - cpu_state.MM[4].w[4] == 0xffff && cpu_state.MM[5].w[4] == 0xffff && cpu_state.MM[6].w[4] == 0xffff && cpu_state.MM[7].w[4] == 0xffff && - !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) - cpu_state.ismmx = old_ismmx; + if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && + cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && + !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) + cpu_state.ismmx = 1; x87_settag(rec_ftw); @@ -448,8 +434,6 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) else { /* FXSAVE */ - // pclog("FXSAVE issued\n"); - if ((twd & 0x0003) == 0x0003) ftwb |= 0x01; if ((twd & 0x000C) == 0x000C) ftwb |= 0x02; if ((twd & 0x0030) == 0x0030) ftwb |= 0x04; diff --git a/src/x86_ops_int.h b/src/x86_ops_int.h index 139389160..dafb1dde5 100644 --- a/src/x86_ops_int.h +++ b/src/x86_ops_int.h @@ -12,6 +12,20 @@ static int opINT3(uint32_t fetchdat) return 1; } +static int opINT1(uint32_t fetchdat) +{ + int cycles_old = cycles; + if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) + { + x86gpf(NULL,0); + return 1; + } + x86_int_sw(1); + CLOCK_CYCLES((is486) ? 44 : 59); + PREFETCH_RUN(cycles_old-cycles, 1, -1, 0,0,0,0, 0); + return 1; +} + static int opINT(uint32_t fetchdat) { int cycles_old = cycles; @@ -24,38 +38,6 @@ static int opINT(uint32_t fetchdat) return 1; } temp = getbytef(); -// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc); -// if (CS == 0x0028 && pc == 0xC03813C0) -// output = 3; -/* if (pc == 0x8028009A) - output = 3; - if (pc == 0x80282B6F) - { - __times++; - if (__times == 2) - fatal("WRONG\n"); - } - if (pc == 0x802809CE) - fatal("RIGHT\n");*/ -// if (CS == 0x0028 && pc == 0x80037FE9) -// output = 3; -//if (CS == 0x9087 && pc == 0x3763) -// fatal("Here\n"); -//if (CS==0x9087 && pc == 0x0850) -// output = 1; - -/* if (output && pc == 0x80033008) - { - __times++; - if (__times == 2) - fatal("WRONG\n"); - }*/ -/* if (output && pc == 0x80D8) - { - __times++; - if (__times == 2) - fatal("RIGHT\n"); - }*/ x86_int_sw(temp); PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); diff --git a/src/x86_ops_io.h b/src/x86_ops_io.h index 8f190cea0..7d42299cc 100644 --- a/src/x86_ops_io.h +++ b/src/x86_ops_io.h @@ -103,7 +103,6 @@ static int opOUT_AL_DX(uint32_t fetchdat) } static int opOUT_AX_DX(uint32_t fetchdat) { - //pclog("OUT_AX_DX %04X %04X\n", DX, AX); check_io_perm(DX); check_io_perm(DX + 1); outw(DX, AX); diff --git a/src/x86_ops_jump.h b/src/x86_ops_jump.h index 93987633e..63ca65ea0 100644 --- a/src/x86_ops_jump.h +++ b/src/x86_ops_jump.h @@ -246,9 +246,11 @@ static int opJMP_r32(uint32_t fetchdat) static int opJMP_far_a16(uint32_t fetchdat) { - uint16_t addr = getwordf(); - uint16_t seg = getword(); if (cpu_state.abrt) return 1; - uint32_t oxpc = cpu_state.pc; + uint16_t addr, seg; + uint32_t oxpc; + addr = getwordf(); + seg = getword(); if (cpu_state.abrt) return 1; + oxpc = cpu_state.pc; cpu_state.pc = addr; loadcsjmp(seg, oxpc); CPU_BLOCK_END(); @@ -258,9 +260,11 @@ static int opJMP_far_a16(uint32_t fetchdat) } static int opJMP_far_a32(uint32_t fetchdat) { - uint32_t addr = getlong(); - uint16_t seg = getword(); if (cpu_state.abrt) return 1; - uint32_t oxpc = cpu_state.pc; + uint16_t seg; + uint32_t addr, oxpc; + addr = getlong(); + seg = getword(); if (cpu_state.abrt) return 1; + oxpc = cpu_state.pc; cpu_state.pc = addr; loadcsjmp(seg, oxpc); CPU_BLOCK_END(); @@ -321,8 +325,8 @@ static int opRET_l(uint32_t fetchdat) static int opRET_w_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); uint16_t ret; + uint16_t offset = getwordf(); ret = POP_W(); if (cpu_state.abrt) return 1; if (stack32) ESP += offset; @@ -337,8 +341,8 @@ static int opRET_w_imm(uint32_t fetchdat) } static int opRET_l_imm(uint32_t fetchdat) { - uint16_t offset = getwordf(); uint32_t ret; + uint16_t offset = getwordf(); ret = POP_L(); if (cpu_state.abrt) return 1; if (stack32) ESP += offset; diff --git a/src/x86_ops_misc.h b/src/x86_ops_misc.h index ddf727f32..a2b4f6f31 100644 --- a/src/x86_ops_misc.h +++ b/src/x86_ops_misc.h @@ -56,6 +56,7 @@ static int opF6_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*TEST b,#8*/ + case 0x08: src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; setznp8(src & dst); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -127,7 +128,6 @@ static int opF6_a16(uint32_t fetchdat) } else { -// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); x86_int(0); return 1; } @@ -153,6 +153,7 @@ static int opF6_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*TEST b,#8*/ + case 0x08: src = readmemb(cs, cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; setznp8(src & dst); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -224,7 +225,6 @@ static int opF6_a32(uint32_t fetchdat) } else { -// pclog("IDIVb exception - %X / %08X = %X\n", tempws, dst, tempws2); x86_int(0); return 1; } @@ -253,6 +253,7 @@ static int opF7_w_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*TEST w*/ + case 0x08: src = getword(); if (cpu_state.abrt) return 1; setznp16(src & dst); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -301,7 +302,6 @@ static int opF7_w_a16(uint32_t fetchdat) } else { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); x86_int(0); return 1; } @@ -320,7 +320,6 @@ static int opF7_w_a16(uint32_t fetchdat) } else { -// pclog("IDIVw exception - %X / %08X = %X\n",tempws, dst, tempws2); x86_int(0); return 1; } @@ -346,6 +345,7 @@ static int opF7_w_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*TEST w*/ + case 0x08: src = getword(); if (cpu_state.abrt) return 1; setznp16(src & dst); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -394,7 +394,6 @@ static int opF7_w_a32(uint32_t fetchdat) } else { -// fatal("DIVw BY 0 %04X:%04X %i\n",cs>>4,pc,ins); x86_int(0); return 1; } @@ -413,7 +412,6 @@ static int opF7_w_a32(uint32_t fetchdat) } else { -// pclog("IDIVw exception - %X / %08X = %X\n", tempws, dst, tempws2); x86_int(0); return 1; } @@ -439,6 +437,7 @@ static int opF7_l_a16(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*TEST l*/ + case 0x08: src = getlong(); if (cpu_state.abrt) return 1; setznp32(src & dst); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -508,6 +507,7 @@ static int opF7_l_a32(uint32_t fetchdat) switch (rmdat & 0x38) { case 0x00: /*TEST l*/ + case 0x08: src = getlong(); if (cpu_state.abrt) return 1; setznp32(src & dst); if (is486) CLOCK_CYCLES((cpu_mod == 3) ? 1 : 2); @@ -721,13 +721,19 @@ static int opWBINVD(uint32_t fetchdat) return 0; } - - static int opLOADALL(uint32_t fetchdat) { + if (CPL && (cr0&1)) + { + x86gpf(NULL,0); + return 1; + } + msw = (msw & 1) | readmemw(0, 0x806); flags = (readmemw(0, 0x818) & 0xffd5) | 2; flags_extract(); + tr.seg = readmemw(0, 0x816); cpu_state.pc = readmemw(0, 0x81A); + ldt.seg = readmemw(0, 0x81C); DS = readmemw(0, 0x81E); SS = readmemw(0, 0x820); CS = readmemw(0, 0x822); @@ -741,14 +747,33 @@ static int opLOADALL(uint32_t fetchdat) CX = readmemw(0, 0x832); AX = readmemw(0, 0x834); es = readmemw(0, 0x836) | (readmemb(0, 0x838) << 16); + _es.access = readmemb(0, 0x839); + _es.limit = readmemw(0, 0x83A); cs = readmemw(0, 0x83C) | (readmemb(0, 0x83E) << 16); + _cs.access = readmemb(0, 0x83F); + _cs.limit = readmemw(0, 0x840); ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); + _ss.access = readmemb(0, 0x845); + _ss.limit = readmemw(0, 0x846); ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); + _ds.access = readmemb(0, 0x84B); + _ds.limit = readmemw(0, 0x84C); + gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); + gdt.limit = readmemw(0, 0x852); + ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); + ldt.access = readmemb(0, 0x857); + ldt.limit = readmemw(0, 0x858); + idt.base = readmemw(0, 0x85A) | (readmemb(0, 0x85C) << 16); + idt.limit = readmemw(0, 0x85E); + tr.base = readmemw(0, 0x860) | (readmemb(0, 0x862) << 16); + tr.access = readmemb(0, 0x863); + tr.limit = readmemw(0, 0x864); CLOCK_CYCLES(195); + PREFETCH_RUN(195, 1, -1, 51,0,0,0, 0); return 0; } -static int set_segment_limit(x86seg *s, uint8_t segdat3) +static void set_segment_limit(x86seg *s, uint8_t segdat3) { if ((s->access & 0x18) != 0x10 || !(s->access & (1 << 2))) /*expand-down*/ { @@ -762,7 +787,7 @@ static int set_segment_limit(x86seg *s, uint8_t segdat3) } } -static int loadall_load_segment(uint32_t addr, x86seg *s) +static void loadall_load_segment(uint32_t addr, x86seg *s) { uint32_t attrib = readmeml(0, addr); uint32_t segdat3 = (attrib >> 16) & 0xff; diff --git a/src/x86_ops_mov.h b/src/x86_ops_mov.h index a9ba431c2..bf82c3d66 100644 --- a/src/x86_ops_mov.h +++ b/src/x86_ops_mov.h @@ -181,6 +181,7 @@ static int opMOV_b_imm_a16(uint32_t fetchdat) { uint8_t temp; fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); temp = readmemb(cs,cpu_state.pc); cpu_state.pc++; if (cpu_state.abrt) return 1; CHECK_WRITE(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr); seteab(temp); @@ -192,6 +193,7 @@ static int opMOV_b_imm_a32(uint32_t fetchdat) { uint8_t temp; fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); temp = getbyte(); if (cpu_state.abrt) return 1; seteab(temp); CLOCK_CYCLES(timing_rr); @@ -203,6 +205,7 @@ static int opMOV_w_imm_a16(uint32_t fetchdat) { uint16_t temp; fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); temp = getword(); if (cpu_state.abrt) return 1; seteaw(temp); CLOCK_CYCLES(timing_rr); @@ -213,6 +216,7 @@ static int opMOV_w_imm_a32(uint32_t fetchdat) { uint16_t temp; fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); temp = getword(); if (cpu_state.abrt) return 1; seteaw(temp); CLOCK_CYCLES(timing_rr); @@ -223,6 +227,7 @@ static int opMOV_l_imm_a16(uint32_t fetchdat) { uint32_t temp; fetch_ea_16(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); temp = getlong(); if (cpu_state.abrt) return 1; seteal(temp); CLOCK_CYCLES(timing_rr); @@ -233,6 +238,7 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) { uint32_t temp; fetch_ea_32(fetchdat); + ILLEGAL_ON((rmdat & 0x38) != 0); temp = getlong(); if (cpu_state.abrt) return 1; seteal(temp); CLOCK_CYCLES(timing_rr); @@ -243,8 +249,9 @@ static int opMOV_l_imm_a32(uint32_t fetchdat) static int opMOV_AL_a16(uint32_t fetchdat) { + uint8_t temp; uint16_t addr = getwordf(); - uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AL = temp; CLOCK_CYCLES((is486) ? 1 : 4); PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); @@ -252,8 +259,9 @@ static int opMOV_AL_a16(uint32_t fetchdat) } static int opMOV_AL_a32(uint32_t fetchdat) { + uint8_t temp; uint32_t addr = getlong(); - uint8_t temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + temp = readmemb(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AL = temp; CLOCK_CYCLES((is486) ? 1 : 4); PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); @@ -261,8 +269,9 @@ static int opMOV_AL_a32(uint32_t fetchdat) } static int opMOV_AX_a16(uint32_t fetchdat) { + uint16_t temp; uint16_t addr = getwordf(); - uint16_t temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AX = temp; CLOCK_CYCLES((is486) ? 1 : 4); PREFETCH_RUN(4, 3, -1, 1,0,0,0, 0); @@ -270,8 +279,9 @@ static int opMOV_AX_a16(uint32_t fetchdat) } static int opMOV_AX_a32(uint32_t fetchdat) { + uint16_t temp; uint32_t addr = getlong(); - uint16_t temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + temp = readmemw(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; AX = temp; CLOCK_CYCLES((is486) ? 1 : 4); PREFETCH_RUN(4, 5, -1, 1,0,0,0, 1); @@ -279,8 +289,9 @@ static int opMOV_AX_a32(uint32_t fetchdat) } static int opMOV_EAX_a16(uint32_t fetchdat) { + uint32_t temp; uint16_t addr = getwordf(); - uint32_t temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; EAX = temp; CLOCK_CYCLES((is486) ? 1 : 4); PREFETCH_RUN(4, 3, -1, 0,1,0,0, 0); @@ -288,8 +299,9 @@ static int opMOV_EAX_a16(uint32_t fetchdat) } static int opMOV_EAX_a32(uint32_t fetchdat) { + uint32_t temp; uint32_t addr = getlong(); - uint32_t temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; + temp = readmeml(cpu_state.ea_seg->base, addr); if (cpu_state.abrt) return 1; EAX = temp; CLOCK_CYCLES((is486) ? 1 : 4); PREFETCH_RUN(4, 5, -1, 0,1,0,0, 1); @@ -349,7 +361,7 @@ static int opMOV_a32_EAX(uint32_t fetchdat) static int opLEA_w_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - // ILLEGAL_ON(cpu_mod == 3); + /* ILLEGAL_ON(cpu_mod == 3); */ cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr; CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); @@ -358,7 +370,7 @@ static int opLEA_w_a16(uint32_t fetchdat) static int opLEA_w_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - // ILLEGAL_ON(cpu_mod == 3); + /* ILLEGAL_ON(cpu_mod == 3); */ cpu_state.regs[cpu_reg].w = (cpu_mod == 3) ? (cpu_state.last_ea & 0xffff) : cpu_state.eaaddr; CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); @@ -368,7 +380,7 @@ static int opLEA_w_a32(uint32_t fetchdat) static int opLEA_l_a16(uint32_t fetchdat) { fetch_ea_16(fetchdat); - // ILLEGAL_ON(cpu_mod == 3); + /* ILLEGAL_ON(cpu_mod == 3); */ cpu_state.regs[cpu_reg].l = ((cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr) & 0xffff; CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); @@ -377,7 +389,7 @@ static int opLEA_l_a16(uint32_t fetchdat) static int opLEA_l_a32(uint32_t fetchdat) { fetch_ea_32(fetchdat); - // ILLEGAL_ON(cpu_mod == 3); + /* ILLEGAL_ON(cpu_mod == 3); */ cpu_state.regs[cpu_reg].l = (cpu_mod == 3) ? cpu_state.last_ea : cpu_state.eaaddr; CLOCK_CYCLES(timing_rr); PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 1); diff --git a/src/x86_ops_pmode.h b/src/x86_ops_pmode.h index 1f30fbfa7..85f028dbd 100644 --- a/src/x86_ops_pmode.h +++ b/src/x86_ops_pmode.h @@ -4,7 +4,7 @@ static int opARPL_a16(uint32_t fetchdat) NOTRM fetch_ea_16(fetchdat); - pclog("ARPL_a16\n"); + /* pclog("ARPL_a16\n"); */ temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -27,7 +27,7 @@ static int opARPL_a32(uint32_t fetchdat) NOTRM fetch_ea_32(fetchdat); - pclog("ARPL_a32\n"); + /* pclog("ARPL_a32\n"); */ temp_seg = geteaw(); if (cpu_state.abrt) return 1; flags_rebuild(); @@ -49,7 +49,7 @@ static int opARPL_a32(uint32_t fetchdat) static int opLAR_ ## name(uint32_t fetchdat) \ { \ int valid; \ - uint16_t sel, desc; \ + uint16_t sel, desc = 0; \ \ NOTRM \ fetch_ea(fetchdat); \ @@ -99,7 +99,7 @@ opLAR(l_a32, fetch_ea_32, 1, 1) static int opLSL_ ## name(uint32_t fetchdat) \ { \ int valid; \ - uint16_t sel, desc; \ + uint16_t sel, desc = 0; \ \ NOTRM \ fetch_ea(fetchdat); \ @@ -159,7 +159,7 @@ static int op0F00_common(uint32_t fetchdat, int ea32) uint16_t desc, sel; uint8_t access; -// pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); + /* pclog("op0F00 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ switch (rmdat & 0x38) { case 0x00: /*SLDT*/ @@ -293,12 +293,12 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) { uint32_t base; uint16_t limit, tempw; -// pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); + /* pclog("op0F01 %02X %04X:%04X\n", rmdat & 0x38, CS, pc); */ switch (rmdat & 0x38) { case 0x00: /*SGDT*/ seteaw(gdt.limit); - base = gdt.base; //is32 ? gdt.base : (gdt.base & 0xffffff); + base = gdt.base; /* is32 ? gdt.base : (gdt.base & 0xffffff); */ if (is286) base |= 0xff000000; writememl(easeg, cpu_state.eaaddr + 2, base); @@ -321,10 +321,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) x86gpf(NULL,0); break; } -// pclog("LGDT %08X:%08X\n", easeg, eaaddr); + /* pclog("LGDT %08X:%08X\n", easeg, eaaddr); */ limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; -// pclog(" %08X %04X\n", base, limit); + /* pclog(" %08X %04X\n", base, limit); */ gdt.limit = limit; gdt.base = base; if (!is32) gdt.base &= 0xffffff; @@ -338,10 +338,10 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) x86gpf(NULL,0); break; } -// pclog("LIDT %08X:%08X\n", easeg, eaaddr); + /* pclog("LIDT %08X:%08X\n", easeg, eaaddr); */ limit = geteaw(); base = readmeml(0, easeg + cpu_state.eaaddr + 2); if (cpu_state.abrt) return 1; -// pclog(" %08X %04X\n", base, limit); + /* pclog(" %08X %04X\n", base, limit); */ idt.limit = limit; idt.base = base; if (!is32) idt.base &= 0xffffff; @@ -350,8 +350,9 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) break; case 0x20: /*SMSW*/ - if (is486) seteaw(msw); - else seteaw(msw | 0xFF00); + if (is486) seteaw(msw); + else if (is386) seteaw(msw | 0xFF00); + else seteaw(msw | 0xFFF0); CLOCK_CYCLES(2); PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; @@ -364,6 +365,7 @@ static int op0F01_common(uint32_t fetchdat, int is32, int is286, int ea32) } tempw = geteaw(); if (cpu_state.abrt) return 1; if (msw & 1) tempw |= 1; + if (!is386) tempw &= 0xF; msw = tempw; PREFETCH_RUN(2, 2, rmdat, 0,0,(cpu_mod == 3) ? 0:1,0, ea32); break; diff --git a/src/x86_ops_shift.h b/src/x86_ops_shift.h index 495a1bf47..0c5a31f06 100644 --- a/src/x86_ops_shift.h +++ b/src/x86_ops_shift.h @@ -497,9 +497,11 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHLD_w() \ if (count) \ { \ + int tempc; \ + uint32_t templ; \ uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - int tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ - uint32_t templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ + tempc = ((tempw << (count - 1)) & (1 << 15)) ? 1 : 0; \ + templ = (tempw << 16) | cpu_state.regs[cpu_reg].w; \ if (count <= 16) tempw = templ >> (16 - count); \ else tempw = (templ << count) >> 16; \ seteaw(tempw); if (cpu_state.abrt) return 1; \ @@ -511,8 +513,9 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHLD_l() \ if (count) \ { \ + int tempc; \ uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - int tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ + tempc = ((templ << (count - 1)) & (1 << 31)) ? 1 : 0; \ templ = (templ << count) | (cpu_state.regs[cpu_reg].l >> (32 - count)); \ seteal(templ); if (cpu_state.abrt) return 1; \ setznp32(templ); \ @@ -523,10 +526,12 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHRD_w() \ if (count) \ - { \ + { \ + int tempc; \ + uint32_t templ; \ uint16_t tempw = geteaw(); if (cpu_state.abrt) return 1; \ - int tempc = (tempw >> (count - 1)) & 1; \ - uint32_t templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ + tempc = (tempw >> (count - 1)) & 1; \ + templ = tempw | (cpu_state.regs[cpu_reg].w << 16); \ tempw = templ >> count; \ seteaw(tempw); if (cpu_state.abrt) return 1; \ setznp16(tempw); \ @@ -537,8 +542,9 @@ static int opD3_l_a32(uint32_t fetchdat) #define SHRD_l() \ if (count) \ { \ + int tempc; \ uint32_t templ = geteal(); if (cpu_state.abrt) return 1; \ - int tempc = (templ >> (count - 1)) & 1; \ + tempc = (templ >> (count - 1)) & 1; \ templ = (templ >> count) | (cpu_state.regs[cpu_reg].l << (32 - count)); \ seteal(templ); if (cpu_state.abrt) return 1; \ setznp32(templ); \ @@ -553,7 +559,7 @@ static int opD3_l_a32(uint32_t fetchdat) \ fetch_ea_16(fetchdat); \ count = getbyte() & 31; \ - operation(); \ + operation() \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ @@ -565,7 +571,7 @@ static int opD3_l_a32(uint32_t fetchdat) \ fetch_ea_16(fetchdat); \ count = CL & 31; \ - operation(); \ + operation() \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 0); \ @@ -577,7 +583,7 @@ static int opD3_l_a32(uint32_t fetchdat) \ fetch_ea_32(fetchdat); \ count = getbyte() & 31; \ - operation(); \ + operation() \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ @@ -589,7 +595,7 @@ static int opD3_l_a32(uint32_t fetchdat) \ fetch_ea_32(fetchdat); \ count = CL & 31; \ - operation(); \ + operation() \ \ CLOCK_CYCLES(3); \ PREFETCH_RUN(3, 3, rmdat, 0,(cpu_mod == 3) ? 0:1,0,(cpu_mod == 3) ? 0:1, 1); \ diff --git a/src/x86_ops_stack.h b/src/x86_ops_stack.h index 86daf52aa..621f602b3 100644 --- a/src/x86_ops_stack.h +++ b/src/x86_ops_stack.h @@ -310,10 +310,16 @@ static int opPOPL_a32(uint32_t fetchdat) static int opENTER_w(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; int reads = 0, writes = 1, instr_cycles = 0; + uint16_t tempw; + + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; cpu_state.pc++; + tempEBP = EBP; + tempESP = ESP; PUSH_W(BP); if (cpu_state.abrt) return 1; frame_ptr = ESP; @@ -322,8 +328,6 @@ static int opENTER_w(uint32_t fetchdat) { while (--count) { - uint16_t tempw; - BP -= 2; tempw = readmemw(ss, BP); if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } @@ -348,10 +352,15 @@ static int opENTER_w(uint32_t fetchdat) } static int opENTER_l(uint32_t fetchdat) { - uint16_t offset = getwordf(); - int count = (fetchdat >> 16) & 0xff; cpu_state.pc++; - uint32_t tempEBP = EBP, tempESP = ESP, frame_ptr; + uint16_t offset; + int count; + uint32_t tempEBP, tempESP, frame_ptr; int reads = 0, writes = 1, instr_cycles = 0; + uint32_t templ; + + offset = getwordf(); + count = (fetchdat >> 16) & 0xff; cpu_state.pc++; + tempEBP = EBP; tempESP = ESP; PUSH_L(EBP); if (cpu_state.abrt) return 1; frame_ptr = ESP; @@ -360,8 +369,6 @@ static int opENTER_l(uint32_t fetchdat) { while (--count) { - uint32_t templ; - EBP -= 4; templ = readmeml(ss, EBP); if (cpu_state.abrt) { ESP = tempESP; EBP = tempEBP; return 1; } @@ -455,17 +462,17 @@ static int opLEAVE_l(uint32_t fetchdat) } -PUSH_SEG_OPS(CS); -PUSH_SEG_OPS(DS); -PUSH_SEG_OPS(ES); -PUSH_SEG_OPS(FS); -PUSH_SEG_OPS(GS); -PUSH_SEG_OPS(SS); +PUSH_SEG_OPS(CS) +PUSH_SEG_OPS(DS) +PUSH_SEG_OPS(ES) +PUSH_SEG_OPS(FS) +PUSH_SEG_OPS(GS) +PUSH_SEG_OPS(SS) -POP_SEG_OPS(DS, &_ds); -POP_SEG_OPS(ES, &_es); -POP_SEG_OPS(FS, &_fs); -POP_SEG_OPS(GS, &_gs); +POP_SEG_OPS(DS, &_ds) +POP_SEG_OPS(ES, &_es) +POP_SEG_OPS(FS, &_fs) +POP_SEG_OPS(GS, &_gs) static int opPOP_SS_w(uint32_t fetchdat) diff --git a/src/x86seg.c b/src/x86seg.c index e19775b24..1042712ae 100644 --- a/src/x86seg.c +++ b/src/x86seg.c @@ -1,14 +1,17 @@ /* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ -//#if 0 #include #include #include #include "ibm.h" #include "mem.h" +#include "nvr.h" #include "x86.h" #include "386.h" +#include "386_common.h" +#undef readmemb +#define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) #include "cpu.h" /*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ @@ -73,19 +76,9 @@ void x86seg_reset() void x86_doabrt(int x86_abrt) { -// ingpf = 1; CS = oldcs; cpu_state.pc = cpu_state.oldpc; _cs.access = (oldcpl << 5) | 0x80; -// pclog("x86_doabrt - %02X %08X %04X:%08X %i\n", x86_abrt, abrt_error, CS, pc, ins); - -/* if (CS == 0x3433 && cpu_state.pc == 0x000006B0) - { - // pclog("Quit it\n"); - dumpregs(); - exit(-1); - }*/ -// pclog("GPF! - error %04X %04X(%08X):%08X %02X %02X %i %04X %i %i\n",error,CS,cs,cpu_state.pc,opcode,opcode2,ins,flags&I_FLAG,IOPL, dtimes); if (msw & 1) pmodeint(x86_abrt, 0); @@ -143,30 +136,24 @@ void x86_doabrt(int x86_abrt) SP-=4; } } -// ingpf = 0; -// cpu_state.abrt = gpf = 1; } void x86gpf(char *s, uint16_t error) { - // pclog("GPF %04X : %s\n", error, s); cpu_state.abrt = ABRT_GPF; abrt_error = error; } void x86ss(char *s, uint16_t error) { - // pclog("SS %04X\n", error); cpu_state.abrt = ABRT_SS; abrt_error = error; } void x86ts(char *s, uint16_t error) { - // pclog("TS %04X\n", error); cpu_state.abrt = ABRT_TS; abrt_error = error; } void x86np(char *s, uint16_t error) { - // pclog("NP %04X : %s\n", error, s); cpu_state.abrt = ABRT_NP; abrt_error = error; } @@ -192,7 +179,6 @@ void do_seg_load(x86seg *s, uint16_t *segdat) s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; s->limit_low = s->limit + 1; } -// if (output) pclog("SEG : base=%08x limit=%08x low=%08x high=%08x\n", s->base, s->limit, s->limit_low, s->limit_high); } static void do_seg_v86_init(x86seg *s) @@ -212,7 +198,6 @@ static void check_seg_valid(x86seg *s) { if ((s->seg & ~7) >= ldt.limit) { -// pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n", s->seg, ldt.limit, opcode, opcode2, rmdat); valid = 0; } } @@ -220,7 +205,6 @@ static void check_seg_valid(x86seg *s) { if ((s->seg & ~7) >= gdt.limit) { -// pclog("Bigger than GDT limit %04X %04X\n", s->seg, gdt.limit); valid = 0; } } @@ -232,7 +216,6 @@ static void check_seg_valid(x86seg *s) case 0x1A: case 0x1B: /*Readable non-conforming code*/ if ((s->seg & 3) > dpl || (CPL) > dpl) { -// pclog("Data seg fail - %04X:%08X %04X %i\n", CS, cpu_state.pc, s->seg, dpl); valid = 0; break; } @@ -258,36 +241,23 @@ void loadseg(uint16_t seg, x86seg *s) if (msw&1 && !(eflags&VM_FLAG)) { -// intcount++; if (!(seg&~3)) { if (s==&_ss) { - // pclog("SS selector = NULL!\n"); x86ss(NULL,0); return; -// dumpregs(); -// exit(-1); } -// if (s->base!=-1) pclog("NEW! "); s->seg=0; - // s->access = 0; s->access = 0x80; s->base=-1; -// pclog("NULL selector %s%s%s%s %04X(%06X):%06X\n",(s==&_ds)?"DS":"",(s==&_es)?"ES":"",(s==&_fs)?"FS":"",(s==&_gs)?"GS":"",CS,cs,cpu_state.pc); return; } -// if (s==&_ss) pclog("Load SS %04X\n",seg); -// pclog("Protected mode seg load!\n"); addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X %02X %02X %02X\n",seg,ldt.limit, opcode, opcode2, rmdat); -// dumppic(); -// dumpregs(); -// exit(-1); x86gpf("loadseg(): Bigger than LDT limit",seg&~3); return; } @@ -297,9 +267,6 @@ void loadseg(uint16_t seg, x86seg *s) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X 1\n",seg,gdt.limit); -// dumpregs(); -// exit(-1); x86gpf("loadseg(): Bigger than GDT limit",seg&~3); return; } @@ -315,15 +282,12 @@ void loadseg(uint16_t seg, x86seg *s) { if (!(seg&~3)) { - // pclog("Load SS null selector\n"); x86gpf(NULL,seg&~3); return; } if ((seg&3)!=CPL || dpl!=CPL) { - // pclog("Invalid SS permiss\n"); x86gpf(NULL,seg&~3); -// x86abort("Invalid SS permiss for %04X!\n",seg&0xFFFC); return; } switch ((segdat[2]>>8)&0x1F) @@ -331,19 +295,15 @@ void loadseg(uint16_t seg, x86seg *s) case 0x12: case 0x13: case 0x16: case 0x17: /*r/w*/ break; default: - // pclog("Invalid SS type\n"); x86gpf(NULL,seg&~3); -// x86abort("Invalid SS segment type for %04X!\n",seg&0xFFFC); return; } if (!(segdat[2]&0x8000)) { - // pclog("Load SS not present!\n"); x86ss(NULL,seg&~3); return; } stack32 = (segdat[3] & 0x40) ? 1 : 0; -// pclog("Load SS %04x %04x %04x %04x\n", segdat[0], segdat[1], segdat[2], segdat[3]); } else if (s!=&_cs) { @@ -354,19 +314,15 @@ void loadseg(uint16_t seg, x86seg *s) case 0x10: case 0x11: case 0x12: case 0x13: /*Data segments*/ case 0x14: case 0x15: case 0x16: case 0x17: case 0x1A: case 0x1B: /*Readable non-conforming code*/ -// pclog("Load seg %04X %i %i %04X:%08X\n",seg,dpl,CS&3,CS,cpu_state.pc); if ((seg&3)>dpl || (CPL)>dpl) { - // pclog("Data seg fail - %04X:%08X %04X %i %04X\n",CS,cpu_state.pc,seg,dpl,segdat[2]); x86gpf(NULL,seg&~3); -// x86abort("Data segment load - level too low!\n",seg&0xFFFC); return; } break; case 0x1E: case 0x1F: /*Readable conforming code*/ break; default: - // pclog("Invalid segment type for %04X! %04X\n",seg&0xFFFC,segdat[2]); x86gpf(NULL,seg&~3); return; } @@ -416,24 +372,16 @@ void loadcs(uint16_t seg) if (output) pclog("Load CS %04X\n",seg); if (msw&1 && !(eflags&VM_FLAG)) { -// intcount++; -// flushmmucache(); -// pclog("Load CS %04X\n",seg); if (!(seg&~3)) { - // pclog("Trying to load CS with NULL selector! lcs\n"); -// dumpregs(); -// exit(-1); x86gpf(NULL,0); return; } -// pclog("Protected mode CS load! %04X\n",seg); addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit); x86gpf(NULL,seg&~3); return; } @@ -443,7 +391,6 @@ void loadcs(uint16_t seg) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -454,9 +401,6 @@ void loadcs(uint16_t seg) segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; - // if (optype==JMP) pclog("Code seg - %04X - %04X %04X %04X %04X\n",seg,segdat[0],segdat[1],segdat[2],segdat[3]); -// if (!(segdat[2]&0x8000)) x86abort("Code segment not present!\n"); -// if (output) pclog("Segdat2 %04X\n",segdat[2]); if (segdat[2]&0x1000) /*Normal code segment*/ { if (!(segdat[2]&0x400)) /*Not conforming*/ @@ -464,7 +408,6 @@ void loadcs(uint16_t seg) if ((seg&3)>CPL) { x86gpf(NULL,seg&~3); - // pclog("loadcs RPL > CPL %04X %04X %i %02X\n",segdat[2],seg,CPL,opcode); return; } if (CPL != DPL) @@ -495,8 +438,6 @@ void loadcs(uint16_t seg) writememw(0, addr+4, segdat[2] | 0x100); /*Set accessed bit*/ cpl_override = 0; #endif -// if (output) pclog("Load CS %08X\n",_cs.base); -// CS=(CS&0xFFFC)|((_cs.access>>5)&3); } else /*System segment*/ { @@ -508,14 +449,10 @@ void loadcs(uint16_t seg) switch (segdat[2]&0xF00) { default: - // pclog("Bad CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg); x86gpf(NULL,seg&~3); return; } } -// pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); -// dumpregs(); -// exit(-1); } else { @@ -534,26 +471,20 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { uint16_t segdat[4]; uint32_t addr; - int count; uint16_t type,seg2; uint32_t newpc; -// pclog("Load CS JMP %04X\n",seg); if (msw&1 && !(eflags&VM_FLAG)) { if (!(seg&~3)) { - // pclog("Trying to load CS with NULL selector! lcsjmp\n"); x86gpf(NULL,0); return; -// dumpregs(); -// exit(-1); } addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X CS\n",seg,ldt.limit); x86gpf(NULL,seg&~3); return; } @@ -563,7 +494,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X CS\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -577,7 +507,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) if (output) pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); if (segdat[2]&0x1000) /*Normal code segment*/ { -// pclog("Normal CS\n"); if (!(segdat[2]&0x400)) /*Not conforming*/ { if ((seg&3)>CPL) @@ -620,10 +549,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) } else /*System segment*/ { -// pclog("System CS\n"); if (!(segdat[2]&0x8000)) { - // x86np("Load CS JMP system selector not present\n", seg & 0xfffc); return; } type=segdat[2]&0xF00; @@ -633,12 +560,10 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { case 0x400: /*Call gate*/ case 0xC00: -// pclog("Call gate\n"); cgate32=(type&0x800); cgate16=!cgate32; oldcs=CS; cpu_state.oldpc=cpu_state.pc; - count=segdat[2]&31; #if 0 if ((DPL < CPL) || (DPL < (seg&3))) { @@ -665,18 +590,14 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) if (!(seg2&~3)) { - // pclog("Trying to load CS with NULL selector! lcsjmpcg\n"); x86gpf(NULL,0); return; -// dumpregs(); -// exit(-1); } addr=seg2&~7; if (seg2&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X CSJ\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -686,7 +607,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X CSJ\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -715,7 +635,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ if (DPL > CPL) { - // pclog("Call gate DPL > CPL"); x86gpf(NULL,seg2&~3); return; } @@ -734,7 +653,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) break; default: - // pclog("JMP Call gate bad segment type\n"); x86gpf(NULL,seg2&~3); return; } @@ -743,28 +661,18 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) case 0x900: /*386 Task gate*/ -// pclog("Task gate\n"); cpu_state.pc=oxpc; cpl_override=1; taskswitch286(seg,segdat,segdat[2]&0x800); flags &= ~NT_FLAG; cpl_override=0; -// case 0xB00: /*386 Busy task gate*/ -// if (optype==JMP) pclog("Task switch!\n"); -// taskswitch386(seg,segdat); return; default: - // pclog("Bad JMP CS %02X %02X %i special descriptor %03X %04X\n",opcode,rmdat,optype,segdat[2]&0xF00,seg); x86gpf(NULL,0); return; -// dumpregs(); -// exit(-1); } } -// pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); -// dumpregs(); -// exit(-1); } else { @@ -782,7 +690,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) void PUSHW(uint16_t v) { -// if (output==3) pclog("PUSHW %04X to %08X\n",v,ESP-4); if (stack32) { writememw(ss,ESP-2,v); @@ -791,7 +698,6 @@ void PUSHW(uint16_t v) } else { -// pclog("Write %04X to %08X\n", v, ss+((SP-2)&0xFFFF)); writememw(ss,((SP-2)&0xFFFF),v); if (cpu_state.abrt) return; SP-=2; @@ -799,7 +705,6 @@ void PUSHW(uint16_t v) } void PUSHL(uint32_t v) { -// if (output==3) pclog("PUSHL %08X to %08X\n",v,ESP-4); if (stack32) { writememl(ss,ESP-4,v); @@ -855,8 +760,7 @@ void loadcscall(uint16_t seg) uint32_t addr,oldssbase=ss, oaddr; uint32_t newpc; int count; - uint16_t oldcs=CPL; - uint32_t oldss,oldsp,newsp,oldpc, oldsp2; + uint32_t oldss,oldsp,newsp, oldsp2; int type; uint16_t tempw; @@ -864,22 +768,17 @@ void loadcscall(uint16_t seg) if (msw&1 && !(eflags&VM_FLAG)) { - //flushmmucache(); if (csout) pclog("Protected mode CS load! %04X\n",seg); if (!(seg&~3)) { - // pclog("Trying to load CS with NULL selector! lcscall\n"); x86gpf(NULL,0); return; -// dumpregs(); -// exit(-1); } addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X CSC\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -889,7 +788,6 @@ void loadcscall(uint16_t seg) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X CSC\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -911,26 +809,22 @@ void loadcscall(uint16_t seg) { if ((seg&3)>CPL) { - /* if (csout) */ // pclog("Not conforming, RPL > CPL\n"); x86gpf("loadcscall(): segment > CPL",seg&~3); return; } if (CPL != DPL) { - /* if (csout) */ // pclog("Not conforming, CPL != DPL (%i %i)\n",CPL,DPL); x86gpf(NULL,seg&~3); return; } } if (CPL < DPL) { - /* if (csout) */ // pclog("CPL < DPL\n"); x86gpf(NULL,seg&~3); return; } if (!(segdat[2]&0x8000)) { - /* if (csout) */ // pclog("Not present\n"); x86np("Load CS call not present", seg & 0xfffc); return; } @@ -970,15 +864,7 @@ void loadcscall(uint16_t seg) cgate32=(type&0x800); cgate16=!cgate32; oldcs=CS; - oldpc=cpu_state.pc; count=segdat[2]&31; -#if 0 - if ((DPL < CPL) || (DPL < (seg&3))) - { - x86gpf("",seg&~3); - return; - } -#endif if ((DPL < CPL)) { x86gpf("loadcscall(): ex DPL < CPL",seg&~3); @@ -1001,18 +887,14 @@ void loadcscall(uint16_t seg) if (!(seg2&~3)) { - // pclog("Trying to load CS with NULL selector! lcscallcg\n"); x86gpf(NULL,0); return; -// dumpregs(); -// exit(-1); } addr=seg2&~7; if (seg2&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X CSC\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -1022,7 +904,6 @@ void loadcscall(uint16_t seg) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X CSC\n",seg2,gdt.limit); x86gpf(NULL,seg2&~3); return; } @@ -1076,7 +957,6 @@ void loadcscall(uint16_t seg) if (output) pclog("New stack %04X:%08X\n",newss,newsp); if (!(newss&~3)) { - // pclog("Call gate loading null SS\n"); x86ts(NULL,newss&~3); return; } @@ -1110,21 +990,16 @@ void loadcscall(uint16_t seg) if (output) pclog("Read stack seg done!\n"); if (((newss & 3) != DPL) || (DPL2 != DPL)) { - // pclog("Call gate loading SS with wrong permissions %04X %04X %i %i %04X %04X\n", newss, seg2, DPL, DPL2, segdat[2], segdat2[2]); -// dumpregs(); -// exit(-1); x86ts(NULL,newss&~3); return; } if ((segdat2[2]&0x1A00)!=0x1200) { - // pclog("Call gate loading SS wrong type\n"); x86ts(NULL,newss&~3); return; } if (!(segdat2[2]&0x8000)) { - // pclog("Call gate loading SS not present\n"); x86np("Call gate loading SS not present\n", newss & 0xfffc); return; } @@ -1165,12 +1040,10 @@ void loadcscall(uint16_t seg) PUSHL(oldsp2); if (cpu_state.abrt) { - // pclog("ABRT PUSHL\n"); SS = oldss; ESP = oldsp2; return; } -// if (output) pclog("Stack now %04X:%08X\n",SS,ESP); if (count) { while (count) @@ -1179,16 +1052,12 @@ void loadcscall(uint16_t seg) PUSHL(readmeml(oldssbase,oldsp+(count*4))); if (cpu_state.abrt) { - // pclog("ABRT COPYL\n"); SS = oldss; ESP = oldsp2; return; } } } -// x86abort("Call gate with count %i\n",count); -// PUSHL(oldcs); -// PUSHL(oldpc); if (cpu_state.abrt) return; } else { @@ -1198,14 +1067,11 @@ void loadcscall(uint16_t seg) PUSHW(oldsp2); if (cpu_state.abrt) { - // pclog("ABRT PUSHW\n"); SS = oldss; ESP = oldsp2; return; } if (output) pclog("Write SP to %04X:%04X\n",SS,SP); -// if (output) pclog("Stack %04X %i %04X:%04X\n",SP,count,oldssbase,oldsp); -// if (output) pclog("PUSH %04X %04X %i %i now %04X:%08X\n",oldss,oldsp,count,stack32,SS,ESP); if (count) { while (count) @@ -1216,38 +1082,22 @@ void loadcscall(uint16_t seg) PUSHW(tempw); if (cpu_state.abrt) { - // pclog("ABRT COPYW\n"); SS = oldss; ESP = oldsp2; return; } } } -// if (output) pclog("Stack %04X\n",SP); -// if (count) x86abort("Call gate with count\n"); -// PUSHW(oldcs); -// PUSHW(oldpc); if (cpu_state.abrt) return; } cycles -= timing_call_pm_gate_inner; break; } else if (DPL > CPL) { - // pclog("Call gate DPL > CPL"); x86gpf(NULL,seg2&~3); return; } case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ -/* if (type==0xC00) - { - PUSHL(oldcs); - PUSHL(oldpc); if (cpu_state.abrt) return; - } - else - { - PUSHW(oldcs); - PUSHW(oldpc); if (cpu_state.abrt) return; - }*/ CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); @@ -1263,30 +1113,16 @@ void loadcscall(uint16_t seg) break; default: - // pclog("Call gate bad segment type\n"); x86gpf(NULL,seg2&~3); return; } break; -// case 0x900: /*386 Task gate*/ -// case 0xB00: /*386 Busy task gate*/ -// if (optype==JMP) pclog("Task switch!\n"); -// taskswitch386(seg,segdat); -// return; - - default: - // pclog("Bad CALL special descriptor %03X\n",segdat[2]&0xF00); x86gpf(NULL,seg&~3); return; -// dumpregs(); -// exit(-1); } } -// pclog("CS = %04X base=%06X limit=%04X access=%02X %04X\n",CS,cs,_cs.limit,_cs.access,addr); -// dumpregs(); -// exit(-1); } else { @@ -1324,20 +1160,12 @@ void pmoderetf(int is32, uint16_t off) if (output) pclog("Return to %04X:%08X\n",seg,newpc); if ((seg&3)=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X RETF\n",seg,ldt.limit); x86gpf(NULL,seg&~3); return; } @@ -1356,10 +1183,7 @@ void pmoderetf(int is32, uint16_t off) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X RETF\n",seg,gdt.limit); x86gpf(NULL,seg&~3); -// dumpregs(); -// exit(-1); return; } addr+=gdt.base; @@ -1384,7 +1208,6 @@ void pmoderetf(int is32, uint16_t off) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if (CPL != DPL) { - // pclog("RETF non-conforming CPL != DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; @@ -1393,20 +1216,17 @@ void pmoderetf(int is32, uint16_t off) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if (CPL < DPL) { - // pclog("RETF non-conforming CPL < DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; } break; default: - // pclog("RETF CS not code segment\n"); x86gpf(NULL,seg&~3); return; } if (!(segdat[2]&0x8000)) { - // pclog("RETF CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); ESP=oldsp; x86np("RETF CS not present\n", seg & 0xfffc); return; @@ -1427,7 +1247,6 @@ void pmoderetf(int is32, uint16_t off) if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); use32=(segdat[3]&0x40)?0x300:0; -// pclog("CPL=RPL return to %04X:%08X\n",CS,cpu_state.pc); cycles -= timing_retf_pm; } else @@ -1437,7 +1256,6 @@ void pmoderetf(int is32, uint16_t off) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if ((seg&3) != DPL) { - // pclog("RETF non-conforming RPL != DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; @@ -1447,7 +1265,6 @@ void pmoderetf(int is32, uint16_t off) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if ((seg&3) < DPL) { - // pclog("RETF non-conforming RPL < DPL\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; @@ -1455,15 +1272,12 @@ void pmoderetf(int is32, uint16_t off) if (output) pclog("RETF conforming, %i %i\n",seg&3, DPL); break; default: - // pclog("RETF CS not code segment\n"); ESP=oldsp; x86gpf(NULL,seg&~3); return; } if (!(segdat[2]&0x8000)) { - // pclog("RETF CS not present! %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); - ESP=oldsp; x86np("RETF CS not present\n", seg & 0xfffc); return; @@ -1472,7 +1286,6 @@ void pmoderetf(int is32, uint16_t off) { newsp=POPL(); newss=POPL(); if (cpu_state.abrt) return; -// pclog("is32 new stack %04X:%04X\n",newss,newsp); } else { @@ -1480,12 +1293,10 @@ void pmoderetf(int is32, uint16_t off) newsp=POPW(); if (output) pclog("SS read from %04X:%04X\n",SS,SP); newss=POPW(); if (cpu_state.abrt) return; -// pclog("!is32 new stack %04X:%04X\n",newss,newsp); } if (output) pclog("Read new stack : %04X:%04X (%08X)\n", newss, newsp, ldt.base); if (!(newss&~3)) { - // pclog("RETF loading null SS\n"); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1495,7 +1306,6 @@ void pmoderetf(int is32, uint16_t off) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X RETF SS\n",newss,gdt.limit); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1506,7 +1316,6 @@ void pmoderetf(int is32, uint16_t off) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X RETF SS\n",newss,gdt.limit); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1519,36 +1328,26 @@ void pmoderetf(int is32, uint16_t off) segdat2[2]=readmemw(0,addr+4); segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP=oldsp; return; } if (output) pclog("Segment data %04X %04X %04X %04X\n", segdat2[0], segdat2[1], segdat2[2], segdat2[3]); -// if (((newss & 3) != DPL) || (DPL2 != DPL)) if ((newss & 3) != (seg & 3)) { - // pclog("RETF loading SS with wrong permissions %i %i %04X %04X\n", newss & 3, seg & 3, newss, seg); ESP=oldsp; -// output = 3; -// dumpregs(); -// exit(-1); x86gpf(NULL,newss&~3); return; } if ((segdat2[2]&0x1A00)!=0x1200) { - // pclog("RETF loading SS wrong type\n"); ESP=oldsp; -// dumpregs(); -// exit(-1); x86gpf(NULL,newss&~3); return; } if (!(segdat2[2]&0x8000)) { - // pclog("RETF loading SS not present\n"); ESP=oldsp; x86np("RETF loading SS not present\n", newss & 0xfffc); return; } if (DPL2 != (seg & 3)) { - // pclog("RETF loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); ESP=oldsp; x86gpf(NULL,newss&~3); return; @@ -1585,7 +1384,6 @@ void pmoderetf(int is32, uint16_t off) check_seg_valid(&_es); check_seg_valid(&_fs); check_seg_valid(&_gs); -// pclog("CPL=idt.limit) @@ -1624,19 +1416,15 @@ void pmodeint(int num, int soft) if (num==8) { /*Triple fault - reset!*/ - // pclog("Triple fault!\n"); -// output=1; softresetx86(); cpu_set_edx(); } else if (num==0xD) { - // pclog("Double fault!\n"); pmodeint(8,0); } else { - // pclog("INT out of range\n"); x86gpf(NULL,(num*8)+2+((soft)?0:1)); } if (output) pclog("addr >= IDT.limit\n"); @@ -1653,39 +1441,32 @@ void pmodeint(int num, int soft) if (output) pclog("Addr %08X seg %04X %04X %04X %04X\n",addr,segdat[0],segdat[1],segdat[2],segdat[3]); if (!(segdat[2]&0x1F00)) { - // pclog("No seg\n"); x86gpf(NULL,(num*8)+2); return; } if (DPL=0x800)?32:16; -// if (output) pclog("Int gate %04X %i oldpc %04X pc %04X\n",type,intgatesize,oldpc,cpu_state.pc); if (!(segdat[2]&0x8000)) { - // pclog("Int gate not present\n"); x86np("Int gate not present\n", (num << 3) | 2); return; } seg=segdat[1]; new_cpl = seg & 3; -// pclog("Interrupt gate : %04X:%04X%04X\n",seg,segdat[3],segdat[0]); addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -1695,18 +1476,11 @@ void pmodeint(int num, int soft) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins); x86gpf(NULL,seg&~3); return; } addr+=gdt.base; } -/* if ((seg&3) < CPL) - { - // pclog("INT to higher level\n"); - x86gpf(NULL,seg&~3); - return; - }*/ cpl_override=1; segdat2[0]=readmemw(0,addr); segdat2[1]=readmemw(0,addr+2); @@ -1716,26 +1490,21 @@ void pmodeint(int num, int soft) if (DPL2 > CPL) { - // pclog("INT to higher level 2\n"); x86gpf(NULL,seg&~3); return; } - //pclog("Type %04X\n",segdat2[2]); switch (segdat2[2]&0x1F00) { case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if (DPL2=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X PMODEINT SS\n",newss,gdt.limit); x86ss(NULL,newss&~3); return; } @@ -1777,7 +1544,6 @@ void pmodeint(int num, int soft) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X CSC\n",newss,gdt.limit); x86ss(NULL,newss&~3); return; } @@ -1790,19 +1556,16 @@ void pmodeint(int num, int soft) segdat3[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) return; if (((newss & 3) != DPL2) || (DPL3 != DPL2)) { - // pclog("Int gate loading SS with wrong permissions\n"); x86ss(NULL,newss&~3); return; } if ((segdat3[2]&0x1A00)!=0x1200) { - // pclog("Int gate loading SS wrong type\n"); x86ss(NULL,newss&~3); return; } if (!(segdat3[2]&0x8000)) { - // pclog("Int gate loading SS not present\n"); x86np("Int gate loading SS not present\n", newss & 0xfffc); return; } @@ -1822,7 +1585,6 @@ void pmodeint(int num, int soft) cpl_override=1; if (type>=0x800) { -// if (output) pclog("Push 32 %i\n",eflags&VM_FLAG); if (eflags & VM_FLAG) { PUSHL(GS); @@ -1837,82 +1599,63 @@ void pmodeint(int num, int soft) PUSHL(oldss); PUSHL(oldsp); PUSHL(flags|(eflags<<16)); -// if (soft) pclog("Pushl CS %08X\n", CS); PUSHL(CS); -// if (soft) pclog("Pushl PC %08X\n", cpu_state.pc); PUSHL(cpu_state.pc); if (cpu_state.abrt) return; -// if (output) pclog("32Stack %04X:%08X\n",SS,ESP); } else { -// if (output) pclog("Push 16\n"); PUSHW(oldss); PUSHW(oldsp); PUSHW(flags); -// if (soft) pclog("Pushw CS %04X\n", CS); PUSHW(CS); -// if (soft) pclog("Pushw pc %04X\n", cpu_state.pc); PUSHW(cpu_state.pc); if (cpu_state.abrt) return; -// if (output) pclog("16Stack %04X:%08X\n",SS,ESP); } cpl_override=0; _cs.access=0 | 0x80; cycles -= timing_int_pm_outer - timing_int_pm; -// pclog("Non-confirming int gate, CS = %04X\n"); break; } else if (DPL2!=CPL) { - // pclog("Non-conforming int gate DPL != CPL\n"); x86gpf(NULL,seg&~3); return; } case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if (!(segdat2[2]&0x8000)) { - // pclog("Int gate CS not present\n"); x86np("Int gate CS not present\n", segdat[1] & 0xfffc); return; } if ((eflags & VM_FLAG) && DPL20x800) { PUSHL(flags|(eflags<<16)); -// if (soft) pclog("Pushlc CS %08X\n", CS); PUSHL(CS); -// if (soft) pclog("Pushlc PC %08X\n", cpu_state.pc); PUSHL(cpu_state.pc); if (cpu_state.abrt) return; } else { PUSHW(flags); -// if (soft) pclog("Pushwc CS %04X\n", CS); PUSHW(CS); -// if (soft) pclog("Pushwc PC %04X\n", cpu_state.pc); PUSHW(cpu_state.pc); if (cpu_state.abrt) return; } new_cpl = CS & 3; break; default: - // pclog("Int gate CS not code segment - %04X %04X %04X %04X\n",segdat2[0],segdat2[1],segdat2[2],segdat2[3]); x86gpf(NULL,seg&~3); return; } do_seg_load(&_cs, segdat2); CS = (seg & ~3) | new_cpl; _cs.access = (_cs.access & ~(3 << 5)) | (new_cpl << 5); -// pclog("New CS = %04X\n",CS); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; use32=(segdat2[3]&0x40)?0x300:0; -// pclog("Int gate done!\n"); #ifdef CS_ACCESSED cpl_override = 1; @@ -1924,22 +1667,18 @@ void pmodeint(int num, int soft) if (!(type&0x100)) { flags&=~I_FLAG; -// pclog("INT %02X disabling interrupts %i\n",num,soft); } flags&=~(T_FLAG|NT_FLAG); -// if (output) pclog("Final Stack %04X:%08X\n",SS,ESP); cycles -= timing_int_pm; break; case 0x500: /*Task gate*/ -// pclog("Task gate\n"); seg=segdat[1]; addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X INT\n",seg,gdt.limit); x86gpf(NULL,seg&~3); return; } @@ -1949,7 +1688,6 @@ void pmodeint(int num, int soft) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X INT %i\n",seg,gdt.limit,ins); x86gpf(NULL,seg&~3); return; } @@ -1963,7 +1701,6 @@ void pmodeint(int num, int soft) cpl_override=0; if (cpu_state.abrt) return; if (!(segdat2[2]&0x8000)) { - // pclog("Int task gate not present\n"); x86np("Int task gate not present\n", segdat[1] & 0xfffc); return; } @@ -1974,7 +1711,6 @@ void pmodeint(int num, int soft) break; default: - // pclog("Bad int gate type %04X %04X %04X %04X %04X\n",segdat[2]&0x1F00,segdat[0],segdat[1],segdat[2],segdat[3]); x86gpf(NULL,seg&~3); return; } @@ -1993,10 +1729,8 @@ void pmodeiret(int is32) uint32_t oldsp=ESP; if (is386 && (eflags&VM_FLAG)) { -// if (output) pclog("V86 IRET\n"); if (IOPL!=3) { - // pclog("V86 IRET! IOPL!=3\n"); x86gpf(NULL,0); return; } @@ -2025,13 +1759,8 @@ void pmodeiret(int is32) return; } -// pclog("IRET %i\n",is32); - //flushmmucache(); -// if (output) pclog("Pmode IRET %04X:%04X ",CS,cpu_state.pc); - if (flags&NT_FLAG) { -// pclog("NT IRET\n"); seg=readmemw(tr.base,0); addr=seg&~7; if (seg&4) @@ -2044,7 +1773,6 @@ void pmodeiret(int is32) { if (addr>=gdt.limit) { - // pclog("TS Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); x86ts(NULL,seg&~3); return; } @@ -2063,25 +1791,19 @@ void pmodeiret(int is32) flagmask=0xFFFF; if (CPL) flagmask&=~0x3000; if (IOPL>16)&VM_FLAG)) { -// pclog("IRETD to V86\n"); - newsp=POPL(); newss=POPL(); segs[0]=POPL(); segs[1]=POPL(); segs[2]=POPL(); segs[3]=POPL(); if (cpu_state.abrt) { ESP = oldsp; return; } -// pclog("Pop stack %04X:%04X\n",newss,newsp); eflags=tempflags>>16; loadseg(segs[0],&_es); do_seg_v86_init(&_es); @@ -2092,9 +1814,6 @@ void pmodeiret(int is32) loadseg(segs[3],&_gs); do_seg_v86_init(&_gs); -// pclog("V86 IRET %04X:%08X\n",SS,ESP); -// output=3; - cpu_state.pc=newpc; _cs.base=seg<<4; _cs.limit=0xFFFF; @@ -2110,12 +1829,6 @@ void pmodeiret(int is32) use32=0; flags=(tempflags&0xFFD5)|2; cycles -= timing_iret_v86; -// pclog("V86 IRET to %04X:%04X %04X:%04X %04X %04X %04X %04X %i\n",CS,cpu_state.pc,SS,SP,DS,ES,FS,GS,cpu_state.abrt); - // if (CS==0xFFFF && pc==0xFFFFFFFF) timetolive=12; -/* { - dumpregs(); - exit(-1); - }*/ return; } } @@ -2125,25 +1838,18 @@ void pmodeiret(int is32) seg=POPW(); tempflags=POPW(); if (cpu_state.abrt) { ESP = oldsp; return; } } -// if (!is386) tempflags&=0xFFF; -// pclog("Returned to %04X:%08X %04X %04X %i\n",seg,newpc,flags,tempflags, ins); if (!(seg&~3)) { - // pclog("IRET CS=0\n"); ESP = oldsp; -// dumpregs(); -// exit(-1); x86gpf(NULL,0); return; } -// if (output) pclog("IRET %04X:%08X\n",seg,newpc); addr=seg&~7; if (seg&4) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X IRET\n",seg,gdt.limit); ESP = oldsp; x86gpf(NULL,seg&~3); return; @@ -2154,7 +1860,6 @@ void pmodeiret(int is32) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X IRET\n",seg,gdt.limit); ESP = oldsp; x86gpf(NULL,seg&~3); return; @@ -2163,7 +1868,6 @@ void pmodeiret(int is32) } if ((seg&3) < CPL) { - // pclog("IRET to lower level\n"); ESP = oldsp; x86gpf(NULL,seg&~3); return; @@ -2173,17 +1877,13 @@ void pmodeiret(int is32) segdat[1]=readmemw(0,addr+2); segdat[2]=readmemw(0,addr+4); segdat[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } -// pclog("Seg type %04X %04X\n",segdat[2]&0x1F00,segdat[2]); switch (segdat[2]&0x1F00) { case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming code*/ if ((seg&3) != DPL) { - // pclog("IRET NC DPL %04X %04X %04X %04X %04X\n", seg, segdat[0], segdat[1], segdat[2], segdat[3]); ESP = oldsp; -// dumpregs(); -// exit(-1); x86gpf(NULL,seg&~3); return; } @@ -2191,31 +1891,24 @@ void pmodeiret(int is32) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming code*/ if ((seg&3) < DPL) { - // pclog("IRET C DPL\n"); ESP = oldsp; x86gpf(NULL,seg&~3); return; } break; default: - // pclog("IRET CS != code seg\n"); ESP = oldsp; x86gpf(NULL,seg&~3); -// dumpregs(); -// exit(-1); return; } if (!(segdat[2]&0x8000)) { - // pclog("IRET CS not present %i %04X %04X %04X\n",ins, segdat[0], segdat[1], segdat[2]); ESP = oldsp; x86np("IRET CS not present\n", seg & 0xfffc); return; } -// pclog("Seg %04X CPL %04X\n",seg,CPL); if ((seg&3) == CPL) { -// pclog("Same level\n"); CS=seg; do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); @@ -2248,7 +1941,6 @@ void pmodeiret(int is32) if (!(newss&~3)) { - // pclog("IRET loading null SS\n"); ESP = oldsp; x86gpf(NULL,newss&~3); return; @@ -2258,7 +1950,6 @@ void pmodeiret(int is32) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X PMODEIRET SS\n",newss,gdt.limit); ESP = oldsp; x86gpf(NULL,newss&~3); return; @@ -2269,7 +1960,6 @@ void pmodeiret(int is32) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X PMODEIRET\n",newss,gdt.limit); ESP = oldsp; x86gpf(NULL,newss&~3); return; @@ -2281,34 +1971,26 @@ void pmodeiret(int is32) segdat2[1]=readmemw(0,addr+2); segdat2[2]=readmemw(0,addr+4); segdat2[3]=readmemw(0,addr+6); cpl_override=0; if (cpu_state.abrt) { ESP = oldsp; return; } -// pclog("IRET SS sd2 %04X\n",segdat2[2]); -// if (((newss & 3) != DPL) || (DPL2 != DPL)) if ((newss & 3) != (seg & 3)) { - // pclog("IRET loading SS with wrong permissions %04X %04X\n", newss, seg); ESP = oldsp; -// dumpregs(); -// exit(-1); x86gpf(NULL,newss&~3); return; } if ((segdat2[2]&0x1A00)!=0x1200) { - // pclog("IRET loading SS wrong type\n"); ESP = oldsp; x86gpf(NULL,newss&~3); return; } if (DPL2 != (seg & 3)) { - // pclog("IRET loading SS with wrong permissions2 %i %i %04X %04X\n", DPL2, seg & 3, newss, seg); ESP = oldsp; x86gpf(NULL,newss&~3); return; } if (!(segdat2[2]&0x8000)) { - // pclog("IRET loading SS not present\n"); ESP = oldsp; x86np("IRET loading SS not present\n", newss & 0xfffc); return; @@ -2347,7 +2029,6 @@ void pmodeiret(int is32) cpu_state.pc=newpc; flags=(flags&~flagmask)|(tempflags&flagmask&0xFFD5)|2; if (is32) eflags=tempflags>>16; -// pclog("done\n"); } void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) @@ -2367,17 +2048,11 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) uint16_t segdat2[4]; -//output=3; base=segdat[1]|((segdat[2]&0xFF)<<16)|((segdat[3]>>8)<<24); limit=segdat[0]|((segdat[3]&0xF)<<16); -// pclog("286 Task switch! %04X:%04X\n",CS,cpu_state.pc); -/// pclog("TSS %04X base %08X limit %04X old TSS %04X %08X %i\n",seg,base,limit,tr.seg,tr.base,ins); -// / pclog("%04X %04X %04X %04X\n",segdat[0],segdat[1],segdat[2],segdat[3]); if (is386) { -// if (output) pclog("32-bit TSS\n"); - new_cr3=readmeml(base,0x1C); new_pc=readmeml(base,0x20); new_flags=readmeml(base,0x24); @@ -2392,7 +2067,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) new_edi=readmeml(base,0x44); new_es=readmemw(base,0x48); -// if (output) pclog("Read CS from %08X\n",base+0x4C); new_cs=readmemw(base,0x4C); new_ss=readmemw(base,0x50); new_ds=readmemw(base,0x54); @@ -2413,7 +2087,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) if (optype==IRET) flags&=~NT_FLAG; -// if (output) pclog("Write PC %08X %08X\n",tr.base,cpu_state.pc); cpu_386_flags_rebuild(); writememl(tr.base,0x1C,cr3); writememl(tr.base,0x20,cpu_state.pc); @@ -2429,7 +2102,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) writememl(tr.base,0x44,EDI); writememl(tr.base,0x48,ES); -// if (output) pclog("Write CS %04X to %08X\n",CS,tr.base+0x4C); writememl(tr.base,0x4C,CS); writememl(tr.base,0x50,SS); writememl(tr.base,0x54,DS); @@ -2456,21 +2128,15 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) cr3=new_cr3; -// pclog("TS New CR3 %08X\n",cr3); flushmmucache(); - - - + cpu_state.pc=new_pc; -// if (output) pclog("New pc %08X\n",new_pc); flags=new_flags; eflags=new_flags>>16; cpu_386_flags_extract(); -// if (output) pclog("Load LDT %04X\n",new_ldt); ldt.seg=new_ldt; templ=(ldt.seg&~7)+gdt.base; -// if (output) pclog("Load from %08X %08X\n",templ,gdt.base); ldt.limit=readmemw(0,templ); if (readmemb(templ+6)&0x80) { @@ -2478,19 +2144,15 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ldt.limit|=0xFFF; } ldt.base=(readmemw(0,templ+2))|(readmemb(templ+4)<<16)|(readmemb(templ+7)<<24); -// if (output) pclog("Limit %04X Base %08X\n",ldt.limit,ldt.base); - if (eflags&VM_FLAG) { - // pclog("Task switch V86!\n"); x86gpf(NULL,0); return; } if (!(new_cs&~3)) { - // pclog("TS loading null CS\n"); x86gpf(NULL,0); return; } @@ -2499,7 +2161,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { if (addr>=ldt.limit) { - // pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr); x86gpf(NULL,0); return; } @@ -2509,7 +2170,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) { if (addr>=gdt.limit) { - // pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); x86gpf(NULL,0); return; } @@ -2521,7 +2181,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) segdat2[3]=readmemw(0,addr+6); if (!(segdat2[2]&0x8000)) { - // pclog("TS loading CS not present\n"); x86np("TS loading CS not present\n", new_cs & 0xfffc); return; } @@ -2530,7 +2189,6 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ if ((new_cs&3) != DPL2) { - // pclog("TS load CS non-conforming RPL != DPL"); x86gpf(NULL,new_cs&~3); return; } @@ -2538,18 +2196,15 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ if ((new_cs&3) < DPL2) { - // pclog("TS load CS non-conforming RPL < DPL"); x86gpf(NULL,new_cs&~3); return; } break; default: - // pclog("TS load CS not code segment\n"); x86gpf(NULL,new_cs&~3); return; } -// if (output) pclog("new_cs %04X\n",new_cs); CS=new_cs; do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); @@ -2579,9 +2234,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } else { - // pclog("16-bit TSS\n"); resetx86(); - //exit(-1); } diff --git a/src/x87.c b/src/x87.c index 547e56091..a729a14c4 100644 --- a/src/x87.c +++ b/src/x87.c @@ -1,13 +1,3 @@ -//Quake timedemo demo1 - 8.1FPS - -//11A00 - D_SCAlloc -//11C1C - D_CacheSurface - -//36174 - SCR_CalcRefdef - -//SCR_CalcRefdef -//Calls R_SetVrect and R_ViewChanged - #define fplog 0 #include diff --git a/src/x87.h b/src/x87.h index 6a0c532b1..5e3db1960 100644 --- a/src/x87.h +++ b/src/x87.h @@ -1,9 +1,6 @@ uint32_t x87_pc_off,x87_op_off; uint16_t x87_pc_seg,x87_op_seg; -static inline void x87_set_mmx(); -static inline void x87_emms(); - uint16_t x87_gettag(); void x87_settag(uint16_t new_tag); diff --git a/src/x87_ops.h b/src/x87_ops.h index 2121e0b0b..e212c6ccb 100644 --- a/src/x87_ops.h +++ b/src/x87_ops.h @@ -32,31 +32,31 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ dst = src1 / (double)src2; \ } while (0) -static inline void x87_set_mmx() +static __inline void x87_set_mmx() { cpu_state.TOP = 0; *(uint64_t *)cpu_state.tag = 0; cpu_state.ismmx = 1; } -static inline void x87_emms() +static __inline void x87_emms() { *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; cpu_state.ismmx = 0; } -static inline void x87_checkexceptions() +static __inline void x87_checkexceptions() { } -static inline void x87_push(double i) +static __inline void x87_push(double i) { cpu_state.TOP=(cpu_state.TOP-1)&7; cpu_state.ST[cpu_state.TOP] = i; cpu_state.tag[cpu_state.TOP&7] = (i == 0.0) ? 1 : 0; } -static inline double x87_pop() +static __inline double x87_pop() { double t = cpu_state.ST[cpu_state.TOP]; cpu_state.tag[cpu_state.TOP&7] = 3; @@ -64,7 +64,7 @@ static inline double x87_pop() return t; } -static inline int64_t x87_fround(double b) +static __inline int64_t x87_fround(double b) { int64_t a, c; @@ -85,13 +85,20 @@ static inline int64_t x87_fround(double b) return (int64_t)ceil(b); case 3: /*Chop*/ return (int64_t)b; + default: + return (int64_t)0; } } #define BIAS80 16383 #define BIAS64 1023 -static inline double x87_ld80() +static __inline double x87_ld80() { + int64_t exp64; + int64_t blah; + int64_t exp64final; + int64_t mant64; + int64_t sign; struct { int16_t begin; union @@ -104,12 +111,12 @@ static inline double x87_ld80() test.eind.ll |= (uint64_t)readmeml(easeg,cpu_state.eaaddr+4)<<32; test.begin = readmemw(easeg,cpu_state.eaaddr+8); - int64_t exp64 = (((test.begin&0x7fff) - BIAS80)); - int64_t blah = ((exp64 >0)?exp64:-exp64)&0x3ff; - int64_t exp64final = ((exp64 >0)?blah:-blah) +BIAS64; + exp64 = (((test.begin&0x7fff) - BIAS80)); + blah = ((exp64 >0)?exp64:-exp64)&0x3ff; + exp64final = ((exp64 >0)?blah:-blah) +BIAS64; - int64_t mant64 = (test.eind.ll >> 11) & (0xfffffffffffff); - int64_t sign = (test.begin&0x8000)?1:0; + mant64 = (test.eind.ll >> 11) & (0xfffffffffffffll); + sign = (test.begin&0x8000)?1:0; if ((test.begin & 0x7fff) == 0x7fff) exp64final = 0x7ff; @@ -123,8 +130,14 @@ static inline double x87_ld80() return test.eind.d; } -static inline void x87_st80(double d) +static __inline void x87_st80(double d) { + int64_t sign80; + int64_t exp80; + int64_t exp80final; + int64_t mant80; + int64_t mant80final; + struct { int16_t begin; union @@ -136,21 +149,21 @@ static inline void x87_st80(double d) test.eind.d=d; - int64_t sign80 = (test.eind.ll&(0x8000000000000000))?1:0; - int64_t exp80 = test.eind.ll&(0x7ff0000000000000); - int64_t exp80final = (exp80>>52); - int64_t mant80 = test.eind.ll&(0x000fffffffffffff); - int64_t mant80final = (mant80 << 11); + sign80 = (test.eind.ll&(0x8000000000000000ll))?1:0; + exp80 = test.eind.ll&(0x7ff0000000000000ll); + exp80final = (exp80>>52); + mant80 = test.eind.ll&(0x000fffffffffffffll); + mant80final = (mant80 << 11); if (exp80final == 0x7ff) /*Infinity / Nan*/ { exp80final = 0x7fff; - mant80final |= (0x8000000000000000); + mant80final |= (0x8000000000000000ll); } - else if (d != 0){ //Zero is a special case - // Elvira wants the 8 and tcalc doesn't - mant80final |= (0x8000000000000000); - //Ca-cyber doesn't like this when result is zero. + else if (d != 0){ /* Zero is a special case */ + /* Elvira wants the 8 and tcalc doesn't */ + mant80final |= (0x8000000000000000ll); + /* Ca-cyber doesn't like this when result is zero. */ exp80final += (BIAS80 - BIAS64); } test.begin = (((int16_t)sign80)<<15)| (int16_t)exp80final; @@ -161,7 +174,7 @@ static inline void x87_st80(double d) writememw(easeg,cpu_state.eaaddr+8,test.begin); } -static inline void x87_st_fsave(int reg) +static __inline void x87_st_fsave(int reg) { reg = (cpu_state.TOP + reg) & 7; @@ -175,7 +188,7 @@ static inline void x87_st_fsave(int reg) x87_st80(cpu_state.ST[reg]); } -static inline void x87_ld_frstor(int reg) +static __inline void x87_ld_frstor(int reg) { reg = (cpu_state.TOP + reg) & 7; @@ -191,21 +204,21 @@ static inline void x87_ld_frstor(int reg) cpu_state.ST[reg] = x87_ld80(); } -static inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) +static __inline void x87_ldmmx(MMX_REG *r, uint16_t *w4) { r->l[0] = readmeml(easeg, cpu_state.eaaddr); r->l[1] = readmeml(easeg, cpu_state.eaaddr + 4); *w4 = readmemw(easeg, cpu_state.eaaddr + 8); } -static inline void x87_stmmx(MMX_REG r) +static __inline void x87_stmmx(MMX_REG r) { writememl(easeg, cpu_state.eaaddr, r.l[0]); writememl(easeg, cpu_state.eaaddr + 4, r.l[1]); writememw(easeg, cpu_state.eaaddr + 8, 0xffff); } -static inline uint16_t x87_compare(double a, double b) +static __inline uint16_t x87_compare(double a, double b) { #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 uint32_t out; @@ -214,11 +227,11 @@ static inline uint16_t x87_compare(double a, double b) { if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) { - // pclog("Comparing infinity\n"); + /* pclog("Comparing infinity\n"); */ - asm volatile ("" : : : "memory"); + __asm volatile ("" : : : "memory"); - asm( + __asm( "fldl %2\n" "fldl %1\n" "fclex\n" @@ -234,9 +247,9 @@ static inline uint16_t x87_compare(double a, double b) /* Memory barrier, to force GCC to write to the input parameters * before the compare rather than after */ - asm volatile ("" : : : "memory"); + __asm volatile ("" : : : "memory"); - asm( + __asm( "fldl %2\n" "fldl %1\n" "fclex\n" @@ -254,7 +267,7 @@ static inline uint16_t x87_compare(double a, double b) if (is386) { - if ((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY)) + if (((a == INFINITY) || (a == -INFINITY)) && ((b == INFINITY) || (b == -INFINITY))) { out |= C3; return out; @@ -277,16 +290,16 @@ static inline uint16_t x87_compare(double a, double b) #endif } -static inline uint16_t x87_ucompare(double a, double b) +static __inline uint16_t x87_ucompare(double a, double b) { #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 uint32_t out; /* Memory barrier, to force GCC to write to the input parameters * before the compare rather than after */ - asm volatile ("" : : : "memory"); + __asm volatile ("" : : : "memory"); - asm( + __asm( "fldl %2\n" "fldl %1\n" "fclex\n" @@ -345,7 +358,10 @@ static int op_nofpu_a16(uint32_t fetchdat) return 1; } else + { fetch_ea_16(fetchdat); + return 0; + } } static int op_nofpu_a32(uint32_t fetchdat) { @@ -355,9 +371,31 @@ static int op_nofpu_a32(uint32_t fetchdat) return 1; } else + { fetch_ea_32(fetchdat); + return 0; + } } +static int FPU_ILLEGAL_a16(uint32_t fetchdat) +{ + fetch_ea_16(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); + return 0; +} + +static int FPU_ILLEGAL_a32(uint32_t fetchdat) +{ + fetch_ea_32(fetchdat); + CLOCK_CYCLES(timing_rr); + PREFETCH_RUN(timing_rr, 2, rmdat, 0,0,0,0, 0); + return 0; +} + +#define ILLEGAL_a16 FPU_ILLEGAL_a16 +#define ILLEGAL_a32 FPU_ILLEGAL_a32 + OpFn OP_TABLE(fpu_d8_a16)[32] = { opFADDs_a16, opFMULs_a16, opFCOMs_a16, opFCOMPs_a16, opFSUBs_a16, opFSUBRs_a16, opFDIVs_a16, opFDIVRs_a16, @@ -376,7 +414,7 @@ OpFn OP_TABLE(fpu_d8_a32)[32] = OpFn OP_TABLE(fpu_287_d9_a16)[256] = { opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, @@ -385,7 +423,7 @@ OpFn OP_TABLE(fpu_287_d9_a16)[256] = opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, @@ -394,7 +432,7 @@ OpFn OP_TABLE(fpu_287_d9_a16)[256] = opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, @@ -402,20 +440,20 @@ OpFn OP_TABLE(fpu_287_d9_a16)[256] = opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*Invalid*/ - opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS }; OpFn OP_TABLE(fpu_287_d9_a32)[256] = { opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, @@ -424,7 +462,7 @@ OpFn OP_TABLE(fpu_287_d9_a32)[256] = opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, @@ -433,7 +471,7 @@ OpFn OP_TABLE(fpu_287_d9_a32)[256] = opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, @@ -441,20 +479,20 @@ OpFn OP_TABLE(fpu_287_d9_a32)[256] = opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, /*Invalid*/ - opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS }; OpFn OP_TABLE(fpu_d9_a16)[256] = { opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, @@ -463,7 +501,7 @@ OpFn OP_TABLE(fpu_d9_a16)[256] = opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, @@ -472,7 +510,7 @@ OpFn OP_TABLE(fpu_d9_a16)[256] = opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, opFLDs_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFSTPs_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, opFLDENV_a16, @@ -480,20 +518,20 @@ OpFn OP_TABLE(fpu_d9_a16)[256] = opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTENV_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, opFSTCW_a16, - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ - opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a16, ILLEGAL_a16, opFTST, opFXAM, ILLEGAL_a16, ILLEGAL_a16, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a16, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a16, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS }; OpFn OP_TABLE(fpu_d9_a32)[256] = { opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, @@ -502,7 +540,7 @@ OpFn OP_TABLE(fpu_d9_a32)[256] = opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, @@ -511,7 +549,7 @@ OpFn OP_TABLE(fpu_d9_a32)[256] = opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, opFLDs_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFSTPs_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, opFLDENV_a32, @@ -519,14 +557,14 @@ OpFn OP_TABLE(fpu_d9_a32)[256] = opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTENV_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, opFSTCW_a32, - opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, - opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, - opFNOP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ - opFCHS, opFABS, ILLEGAL, ILLEGAL, opFTST, opFXAM, ILLEGAL, ILLEGAL, - opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL, - opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL, opFPREM1, opFDECSTP, opFINCSTP, - opFPREM, opFYL2XP1,opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS + opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, opFLD, + opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, + opFNOP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, /*Invalid*/ + opFCHS, opFABS, ILLEGAL_a32, ILLEGAL_a32, opFTST, opFXAM, ILLEGAL_a32, ILLEGAL_a32, + opFLD1, opFLDL2T, opFLDL2E, opFLDPI, opFLDEG2, opFLDLN2, opFLDZ, ILLEGAL_a32, + opF2XM1, opFYL2X, opFPTAN, opFPATAN, ILLEGAL_a32, opFPREM1, opFDECSTP, opFINCSTP, + opFPREM, opFYL2XP1, opFSQRT, opFSINCOS, opFRNDINT, opFSCALE, opFSIN, opFCOS }; OpFn OP_TABLE(fpu_287_da_a16)[256] = @@ -558,14 +596,14 @@ OpFn OP_TABLE(fpu_287_da_a16)[256] = opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_287_da_a32)[256] = { @@ -596,14 +634,14 @@ OpFn OP_TABLE(fpu_287_da_a32)[256] = opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_da_a16)[256] = @@ -635,14 +673,14 @@ OpFn OP_TABLE(fpu_da_a16)[256] = opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, opFDIVRil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_da_a32)[256] = { @@ -673,14 +711,14 @@ OpFn OP_TABLE(fpu_da_a32)[256] = opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, opFDIVRil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_686_da_a16)[256] = @@ -716,10 +754,10 @@ OpFn OP_TABLE(fpu_686_da_a16)[256] = opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFUCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_686_da_a32)[256] = { @@ -754,241 +792,241 @@ OpFn OP_TABLE(fpu_686_da_a32)[256] = opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVBE, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, opFCMOVU, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFUCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFUCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_287_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_287_db_a32)[256] = { opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_db_a32)[256] = { opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_686_db_a16)[256] = { opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, opFILDil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, opFISTPil_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, opFLDe_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFSTPe_a16, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a16, ILLEGAL_a16, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_686_db_a32)[256] = { opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, opFILDil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, opFISTPil_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, opFLDe_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFSTPe_a32, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNB, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNBE, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, opFCMOVNU, - opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL, ILLEGAL, + opFNOP, opFNOP, opFCLEX, opFINIT, opFNOP, opFNOP, ILLEGAL_a32, ILLEGAL_a32, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFUCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, opFCOMI, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_287_dc_a16)[32] = @@ -996,14 +1034,14 @@ OpFn OP_TABLE(fpu_287_dc_a16)[32] = opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, opFADDd_a16, opFMULd_a16, opFCOMd_a16, opFCOMPd_a16, opFSUBd_a16, opFSUBRd_a16, opFDIVd_a16, opFDIVRd_a16, - opFADDr, opFMULr, ILLEGAL, ILLEGAL, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + opFADDr, opFMULr, ILLEGAL_a16, ILLEGAL_a16, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr }; OpFn OP_TABLE(fpu_287_dc_a32)[32] = { opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, opFADDd_a32, opFMULd_a32, opFCOMd_a32, opFCOMPd_a32, opFSUBd_a32, opFSUBRd_a32, opFDIVd_a32, opFDIVRd_a32, - opFADDr, opFMULr, ILLEGAL, ILLEGAL, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr + opFADDr, opFMULr, ILLEGAL_a32, ILLEGAL_a32, opFSUBRr, opFSUBr, opFDIVRr, opFDIVr }; OpFn OP_TABLE(fpu_dc_a16)[32] = @@ -1024,106 +1062,106 @@ OpFn OP_TABLE(fpu_dc_a32)[32] = OpFn OP_TABLE(fpu_287_dd_a16)[256] = { opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_287_dd_a32)[256] = { opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, opFFREE, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFST, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_dd_a16)[256] = { opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, opFLDd_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTPd_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, opFSTOR_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSAVE_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, opFSTSW_a16, @@ -1133,35 +1171,35 @@ OpFn OP_TABLE(fpu_dd_a16)[256] = opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_dd_a32)[256] = { opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, opFLDd_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTPd_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, opFSTOR_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSAVE_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, opFSTSW_a32, @@ -1171,8 +1209,8 @@ OpFn OP_TABLE(fpu_dd_a32)[256] = opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOM, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, opFUCOMP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_287_de_a16)[256] = @@ -1206,8 +1244,8 @@ OpFn OP_TABLE(fpu_287_de_a16)[256] = opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, @@ -1245,8 +1283,8 @@ OpFn OP_TABLE(fpu_287_de_a32)[256] = opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, @@ -1285,7 +1323,7 @@ OpFn OP_TABLE(fpu_de_a16)[256] = opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, - ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, opFCOMPP, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, @@ -1324,7 +1362,7 @@ OpFn OP_TABLE(fpu_de_a32)[256] = opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFADDP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFMULP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, opFCOMP, - ILLEGAL, opFCOMPP, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, opFCOMPP, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBRP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFSUBP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, opFDIVRP, @@ -1334,105 +1372,105 @@ OpFn OP_TABLE(fpu_de_a32)[256] = OpFn OP_TABLE(fpu_287_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_287_df_a32)[256] = { opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, opFFREEP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -1441,36 +1479,36 @@ OpFn OP_TABLE(fpu_df_a16)[256] = opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_df_a32)[256] = { opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -1479,37 +1517,37 @@ OpFn OP_TABLE(fpu_df_a32)[256] = opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(fpu_686_df_a16)[256] = { opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, opFILDiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, opFISTPiw_a16, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, opFILDiq_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FBSTP_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, FISTPiq_a16, @@ -1518,36 +1556,36 @@ OpFn OP_TABLE(fpu_686_df_a16)[256] = opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, ILLEGAL_a16, }; OpFn OP_TABLE(fpu_686_df_a32)[256] = { opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, opFILDiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, opFISTPiw_a32, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, opFILDiq_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FBSTP_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, FISTPiq_a32, @@ -1556,10 +1594,10 @@ OpFn OP_TABLE(fpu_686_df_a32)[256] = opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFXCH, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, opFSTP, - opFSTSW_AX, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + opFSTSW_AX, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFUCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, opFCOMIP, - ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, ILLEGAL_a32, }; OpFn OP_TABLE(nofpu_a16)[256] = diff --git a/src/xtide.c b/src/xtide.c index fc3b70f75..587f1de02 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,3 +1,5 @@ +#include + #include "ibm.h" #include "device.h" @@ -59,6 +61,9 @@ static uint8_t xtide_read(uint16_t port, void *p) case 0xe: return readide(0, 0x3f6); + + default: + return 0xff; } } @@ -92,6 +97,20 @@ static void *xtide_ps2_init() xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); + rom_init(&xtide->bios_rom, "roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + ide_init(); + ide_pri_disable(); + ide_sec_disable(); + io_sethandler(0x0360, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); + + return xtide; +} + +static void *xtide_at_ps2_init() +{ + xtide_t *xtide = malloc(sizeof(xtide_t)); + memset(xtide, 0, sizeof(xtide_t)); + rom_init(&xtide->bios_rom, "roms/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); @@ -116,6 +135,11 @@ static int xtide_at_available() } static int xtide_ps2_available() +{ + return rom_present("roms/SIDE1V12.BIN"); +} + +static int xtide_at_ps2_available() { return rom_present("roms/ide_at_1_1_5.bin"); } @@ -148,7 +172,7 @@ device_t xtide_at_device = device_t xtide_ps2_device = { "XTIDE (PS/2)", - DEVICE_AT, + DEVICE_PS2, xtide_ps2_init, xtide_close, xtide_ps2_available, @@ -157,3 +181,16 @@ device_t xtide_ps2_device = NULL, NULL }; + +device_t xtide_at_ps2_device = +{ + "XTIDE (AT) (PS/2)", + DEVICE_PS2, + xtide_at_ps2_init, + xtide_close, + xtide_at_ps2_available, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/xtide.h b/src/xtide.h index d74dc76c2..666783629 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -1,3 +1,4 @@ extern device_t xtide_device; extern device_t xtide_at_device; extern device_t xtide_ps2_device; +extern device_t xtide_at_ps2_device; From 0d95147bb4da222161406a0fae90d05d84d5552a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 01:54:21 +0200 Subject: [PATCH 151/392] Fixed a compile-breaking mistake in win-joystickconfig.c . --- src/win-joystickconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win-joystickconfig.c b/src/win-joystickconfig.c index cabb75358..1432379ff 100644 --- a/src/win-joystickconfig.c +++ b/src/win-joystickconfig.c @@ -11,7 +11,7 @@ #include "device.h" #include "gameport.h" #include "plat-joystick.h" -#include "resources.h" +#include "resource.h" #include "win.h" static int joystick_nr; From 2262ad3ba08825400f8843969d7c311b9cbbbc48 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 02:15:28 +0200 Subject: [PATCH 152/392] Fixed compile-breaking mistakes in nv_riva128.c (just in case someone wants to compile it); Removed Cirrus and NVidia stuff from the makefile. --- src/Makefile.mingw | 3 --- src/Makefile.mingw64 | 3 --- src/vid_nv_riva128.c | 6 +++--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index c7850ce4a..a41ace019 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -113,13 +113,10 @@ VIDOBJ = video.o \ vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_ati_mach64.o \ vid_ics2595.o \ - vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o \ - vid_bt485_ramdac.o \ vid_sdac_ramdac.o \ vid_stg_ramdac.o \ vid_unk_ramdac.o \ vid_wy700.o \ - vid_nv_riva128.o \ vid_voodoo.o \ vid_pcjr.o vid_ps1_svga.o \ vid_olivetti_m24.o \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index c880ecaac..19d33a53b 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -113,13 +113,10 @@ VIDOBJ = video.o \ vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ vid_ati68860_ramdac.o vid_ati_mach64.o \ vid_ics2595.o \ - vid_cl_gd.o vid_cl_gd_blit.o vid_cl_ramdac.o \ - vid_bt485_ramdac.o \ vid_sdac_ramdac.o \ vid_stg_ramdac.o \ vid_unk_ramdac.o \ vid_wy700.o \ - vid_nv_riva128.o \ vid_voodoo.o \ vid_pcjr.o vid_ps1_svga.o \ vid_olivetti_m24.o \ diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 5fdcfc2b0..06c08f5c0 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -3335,7 +3335,7 @@ static void rivatnt2_add_status_info(char *s, int max_len, void *p) static device_config_t rivatnt2_config[] = { { - "model", "Card model", CONFIG_SELECTION, 0, + "model", "Card model", CONFIG_SELECTION, "", 0, { { "Vanilla TNT2", 0, @@ -3349,7 +3349,7 @@ static device_config_t rivatnt2_config[] = }, }, { - "memory", "Memory size", CONFIG_SELECTION, 32, + "memory", "Memory size", CONFIG_SELECTION, "", 32, { { "4 MB", 4 @@ -3407,7 +3407,7 @@ static device_config_t rivatnt2_config[] = }, }, { - -1 + "", "", -1 } }; From 55be17348586484bf8099f3e174a4ee5488a622e Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 02:35:21 +0200 Subject: [PATCH 153/392] Fixed a bug in the makefile - strip 86Box.exe should now be executed. --- src/Makefile.mingw | 2 +- src/Makefile.mingw64 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index a41ace019..d6cd7da4d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -169,7 +169,7 @@ $(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(LIBS) all: $(PROG).exe -ifeq ($(DEBUG), y) +ifneq ($(DEBUG), y) strip $(PROG).exe endif diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 19d33a53b..c40cd2464 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -169,7 +169,7 @@ $(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(LIBS) all: $(PROG).exe -ifeq ($(DEBUG), y) +ifneq ($(DEBUG), y) strip $(PROG).exe endif From 7610dbe2095406d3bb9cf08e1e093122e9604077 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 02:43:34 +0200 Subject: [PATCH 154/392] Fixed the makefiles again, hopefully this time properly; Single-sided floppy drives are actually single-sided now; Temporarily re-enabled floppy logs for bugfixing purposes. --- src/Makefile.mingw | 4 ++-- src/Makefile.mingw64 | 4 ++-- src/disc_86f.c | 5 +++++ src/fdc.c | 6 +++--- src/fdd.c | 5 +++++ src/fdd.h | 1 + 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d6cd7da4d..57a504121 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -167,12 +167,12 @@ $(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(OBJ) \ $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ $(LIBS) - -all: $(PROG).exe ifneq ($(DEBUG), y) strip $(PROG).exe endif +all: $(PROG).exe + clean: rm *.o rm *.exe diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index c40cd2464..ef7d0ac13 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -167,12 +167,12 @@ $(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) $(OBJ) \ $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ $(LIBS) - -all: $(PROG).exe ifneq ($(DEBUG), y) strip $(PROG).exe endif +all: $(PROG).exe + clean: rm *.o rm *.exe diff --git a/src/disc_86f.c b/src/disc_86f.c index c1567a1d5..83df71198 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1972,6 +1972,11 @@ void d86f_poll(int drive) int mfm = 1; side = fdd_get_head(drive); + if (!fdd_is_double_sided(drive)) + { + side = 0; + } + mfm = fdc_is_mfm(); if ((d86f[drive].state & 0xF8) == 0xE8) diff --git a/src/fdc.c b/src/fdc.c index 0174778f5..40f1c11f8 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -142,11 +142,11 @@ int discrate[4]; int discint; -int fdc_do_log = 0; +int fdc_do_log = 1; void fdc_log(const char *format, ...) { -#ifdef ENABLE_FDC_LOG +// #ifdef ENABLE_FDC_LOG if (fdc_do_log) { va_list ap; @@ -155,7 +155,7 @@ void fdc_log(const char *format, ...) va_end(ap); fflush(stdout); } -#endif +// #endif } void fdc_reset() diff --git a/src/fdd.c b/src/fdd.c index 1ecc6eebd..d876552f6 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -276,6 +276,11 @@ int fdd_is_ed(int drive) return drive_types[fdd[drive].type].flags & FLAG_HOLE2; } +int fdd_is_double_sided(int drive) +{ + return drive_types[fdd[drive].type].flags & FLAG_DS; +} + void fdd_set_head(int drive, int head) { drive = real_drive(drive); diff --git a/src/fdd.h b/src/fdd.h index f9481148f..11d9dee89 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -11,6 +11,7 @@ int fdd_can_read_medium(int drive); int fdd_doublestep_40(int drive); int fdd_is_525(int drive); int fdd_is_ed(int drive); +int fdd_is_double_sided(int drive); void fdd_set_head(int drive, int head); int fdd_get_head(int drive); From 38efeeae357fcfbc21ada8a2afc3b18f06de3be4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 02:58:42 +0200 Subject: [PATCH 155/392] Fixed the makefiles (hopefully) to not build non-optimized builds for Haswell. --- src/Makefile.mingw | 5 ++++- src/Makefile.mingw64 | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 57a504121..cefbc5bdc 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -44,8 +44,11 @@ OPTS = -DWIN32 $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) DFLAGS = -march=i686 -Og -ggdb -DDEBUG else +ifeq ($(OPTIMIZED), y) DFLAGS = -march=native -mtune=native -O6 -UFLAGS = -march=i686 -O3 +else +DFLAGS = -march=i686 -O3 +endif endif AFLAGS = -msse -msse2 -mfpmath=sse CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index ef7d0ac13..7dfc840ac 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -44,8 +44,11 @@ OPTS = -DWIN32 $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) DFLAGS = -march=i686 -Og -ggdb -DDEBUG else +ifeq ($(OPTIMIZED), y) DFLAGS = -march=native -mtune=native -O6 -UFLAGS = -O3 +else +DFLAGS = -O3 +endif endif AFLAGS = -msse -msse2 -mfpmath=sse CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ From ba8eeeb2af66c761450c566d9cb8780607a8cf43 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Thu, 4 May 2017 20:13:22 -0500 Subject: [PATCH 156/392] Fixed RIVA 128 compilation --- src/vid_nv_riva128.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 06c08f5c0..9f47a6c41 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -2839,7 +2839,7 @@ static void riva128_add_status_info(char *s, int max_len, void *p) static device_config_t riva128_config[] = { { - "memory", "Memory size", CONFIG_SELECTION, 4, + "memory", "Memory size", CONFIG_SELECTION, "", 4, { { "1 MB", 1 @@ -3124,7 +3124,7 @@ static void rivatnt_add_status_info(char *s, int max_len, void *p) static device_config_t rivatnt_config[] = { { - "memory", "Memory size", CONFIG_SELECTION, 16, + "memory", "Memory size", CONFIG_SELECTION, "", 16, { { "4 MB", 4 From b024f174a3d0c6048559c2c69a6cb973188c9977 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 04:32:05 +0200 Subject: [PATCH 157/392] DD floppy drives now correctly ignore DENSEL when reading DD floppies; Ne2000 now uses the correct vendor ID for the MAC address, per information from waltje; File name text box in Add hard disk dialog is now correctly disabled; Floppy drive types are now stored as readable string in the configuration file. --- src/86Box.rc | 4 ++-- src/disc_86f.c | 12 ++++++++++++ src/fdc.c | 12 +++++++++--- src/fdd.c | 5 +++++ src/fdd.h | 4 ++++ src/ne2000.c | 4 ++-- src/pc.c | 9 +++++++-- src/win-settings.c | 2 ++ 8 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/86Box.rc b/src/86Box.rc index 07282d465..997b7cf1b 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -189,8 +189,8 @@ FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,55,89,50,14 PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14 - EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,188,12 - PUSHBUTTON "...",IDC_CFILE,195,16,16,12 + EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,153,12 + PUSHBUTTON "&Specify...",IDC_CFILE,167,16,44,12 EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12 EDITTEXT IDC_EDIT_HD_HPC,112,34,28,12 EDITTEXT IDC_EDIT_HD_CYL,42,34,28,12 diff --git a/src/disc_86f.c b/src/disc_86f.c index 83df71198..a939e9fe6 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -724,6 +724,10 @@ int d86f_wrong_densel(int drive) { case 0: default: + if (fdd_is_dd(drive)) + { + return 0; + } if (fdd_get_densel(drive)) { return 1; @@ -734,6 +738,10 @@ int d86f_wrong_densel(int drive) } break; case 1: + if (fdd_is_dd(drive)) + { + return 1; + } if (fdd_get_densel(drive)) { return 0; @@ -751,6 +759,10 @@ int d86f_wrong_densel(int drive) } break; case 2: + if (fdd_is_dd(drive) || !fdd_is_ed(drive)) + { + return 1; + } if (fdd_get_densel(drive)) { return 0; diff --git a/src/fdc.c b/src/fdc.c index 40f1c11f8..9e5b66cce 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -142,11 +142,11 @@ int discrate[4]; int discint; -int fdc_do_log = 1; +int fdc_do_log = 0; void fdc_log(const char *format, ...) { -// #ifdef ENABLE_FDC_LOG +#ifdef ENABLE_FDC_LOG if (fdc_do_log) { va_list ap; @@ -155,7 +155,7 @@ void fdc_log(const char *format, ...) va_end(ap); fflush(stdout); } -// #endif +#endif } void fdc_reset() @@ -429,6 +429,7 @@ int fdc_get_rwc(int drive) void fdc_update_rwc(int drive, int rwc) { + fdc_log("FDD %c: New RWC is %i\n", 0x41 + drive, rwc); fdc.rwc[drive] = rwc; fdc_rate(drive); } @@ -445,6 +446,7 @@ void fdc_update_boot_drive(int boot_drive) void fdc_update_densel_polarity(int densel_polarity) { + fdc_log("FDC: New DENSEL polarity is %i\n", densel_polarity); fdc.densel_polarity = densel_polarity; fdc_update_rates(); } @@ -456,12 +458,14 @@ uint8_t fdc_get_densel_polarity() void fdc_update_densel_force(int densel_force) { + fdc_log("FDC: New DENSEL force is %i\n", densel_force); fdc.densel_force = densel_force; fdc_update_rates(); } void fdc_update_drvrate(int drive, int drvrate) { + fdc_log("FDD %c: New drive rate is %i\n", 0x41 + drive, drvrate); fdc.drvrate[drive] = drvrate; fdc_rate(drive); } @@ -588,6 +592,7 @@ static void fdc_rate(int drive) { fdc_update_rate(drive); disc_set_rate(drive, fdc.drvrate[drive], fdc.rate); + fdc_log("FDD %c: Setting rate: %i, %i, %i (%i, %i)\n", 0x41 + drive, fdc.drvrate[drive], fdc.rate, fdc_get_densel(drive), fdc.rwc[drive], fdc.densel_force); fdd_set_densel(fdc_get_densel(drive)); } @@ -1822,6 +1827,7 @@ void fdc_error(int st5, int st6) fdc.res[4]=0x40|(fdd_get_head(real_drive(fdc.drive))?4:0)|fdc.rw_drive; fdc.res[5]=st5; fdc.res[6]=st6; + fdc_log("FDC Error: %02X %02X %02X\n", fdc.res[4], fdc.res[5], fdc.res[6]); switch(discint) { case 0x02: diff --git a/src/fdd.c b/src/fdd.c index d876552f6..35a2b6865 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -271,6 +271,11 @@ int fdd_is_525(int drive) return drive_types[fdd[drive].type].flags & FLAG_525; } +int fdd_is_dd(int drive) +{ + return (drive_types[fdd[drive].type].flags & 0x70) == 0x10; +} + int fdd_is_ed(int drive) { return drive_types[fdd[drive].type].flags & FLAG_HOLE2; diff --git a/src/fdd.h b/src/fdd.h index 11d9dee89..c4a18afbe 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -10,6 +10,7 @@ void fdd_set_densel(int densel); int fdd_can_read_medium(int drive); int fdd_doublestep_40(int drive); int fdd_is_525(int drive); +int fdd_is_dd(int drive); int fdd_is_ed(int drive); int fdd_is_double_sided(int drive); void fdd_set_head(int drive, int head); @@ -28,3 +29,6 @@ int fdd_get_densel(int drive); void fdd_setswap(int swap); char *fdd_getname(int type); + +char *fdd_get_internal_name(int type); +int fdd_get_from_internal_name(char *s); diff --git a/src/ne2000.c b/src/ne2000.c index 9bcad3036..f67b3f0d4 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -257,9 +257,9 @@ static uint8_t *ne2000_mac() void ne2000_generate_maclocal(int mac) { - maclocal[0] = 0x00; /* 00:00:1B (NE2000 ISA vendor prefix). */ + maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ maclocal[1] = 0x00; - maclocal[2] = 0x1B; + maclocal[2] = 0xD8; if (mac & 0xff000000) { diff --git a/src/pc.c b/src/pc.c index 2c9f891ad..a3a09c04f 100644 --- a/src/pc.c +++ b/src/pc.c @@ -769,7 +769,12 @@ void loadconfig(char *fn) for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - fdd_set_type(c, config_get_int(NULL, temps, (c < 2) ? 2 : 0)); + p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); + if (p) + fdd_set_type(c, fdd_get_from_internal_name(p)); + else + fdd_set_type(c, (c < 2) ? 2 : 0); + sprintf(temps, "fdd_%02i_fn", c + 1); p = (char *)config_get_string(NULL, temps, ""); if (p) strcpy(discfns[c], p); @@ -965,7 +970,7 @@ void saveconfig() for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - config_set_int(NULL, temps, fdd_get_type(c)); + config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); sprintf(temps, "fdd_%02i_fn", c + 1); config_set_string(NULL, temps, discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); diff --git a/src/win-settings.c b/src/win-settings.c index 4790ce717..ff3f87c7a 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -2125,6 +2125,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W SendMessage(h, CB_SETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + EnableWindow(h, FALSE); no_update = 0; return TRUE; From cee82642ef6493cb399d5007f6a90a340825d087 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 5 May 2017 22:36:10 +0200 Subject: [PATCH 158/392] Made the emulator even more Unicode then before - configuration files are now Unicode, and floppy images, CD/DVD .ISO images, and hard disk images can now be in paths with non-Latin characters; Fixed a few minor UI bugs; Brought IDE IDENTIFY command behavior back in line with Mainline PCEM, in hopes to reduce bugs. --- src/86Box.rc | 6 +- src/86box.h | 1 + src/cdrom-iso.c | 28 ++++---- src/cdrom-iso.h | 2 +- src/cdrom.h | 2 +- src/config.c | 118 ++++++++++++++++++++++++++------- src/config.h | 3 + src/disc.c | 83 +++++++++++++----------- src/disc.h | 2 +- src/disc_86f.c | 55 ++++++++++------ src/disc_86f.h | 2 +- src/disc_fdi.c | 11 +++- src/disc_fdi.h | 2 +- src/disc_imd.c | 14 +++- src/disc_imd.h | 2 +- src/disc_img.c | 27 ++++---- src/disc_img.h | 2 +- src/disc_td0.c | 9 ++- src/disc_td0.h | 2 +- src/hdd_esdi.c | 6 +- src/ibm.h | 10 +-- src/ide.c | 33 ++++++---- src/mfm_at.c | 7 +- src/mfm_xebec.c | 6 +- src/nethandler.c | 8 ++- src/pc.c | 57 +++++++++------- src/scsi.h | 1 + src/scsi_hd.c | 10 +-- src/win-d3d-fs.cc | 10 ++- src/win-d3d.cc | 6 +- src/win-ddraw-fs.cc | 1 + src/win-ddraw-screenshot.cc | 11 ++-- src/win-ddraw.cc | 1 + src/win-language.c | 36 ++++++++--- src/win-language.h | 12 ++++ src/win-settings.c | 48 +++++++------- src/win.c | 126 ++++++++++++++++++++---------------- src/win.h | 9 +-- 38 files changed, 487 insertions(+), 282 deletions(-) diff --git a/src/86Box.rc b/src/86Box.rc index 997b7cf1b..c72678d63 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -751,8 +751,8 @@ BEGIN 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" 2177 "Microsoft InPort mouse" 2178 "Genius Bus mouse" - 2179 "Floppy %i (%s): %s" - 2180 "CD-ROM %i: %s" + 2179 "Floppy %i (%s): %ws" + 2180 "CD-ROM %i: %ws" 2181 "Removable disk %i: %s" 2182 "MFM hard disk" 2183 "IDE hard disk" @@ -766,7 +766,7 @@ BEGIN 2191 "ATAPI (PIO-only) (%01i:%01i)" 2192 "ATAPI (PIO and DMA) (%01i:%01i)" 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2194 "" + 2194 "Unable to create bitmap file: %s" 2195 "English (United States)" END diff --git a/src/86box.h b/src/86box.h index 09f0a8a15..ef0a45e15 100644 --- a/src/86box.h +++ b/src/86box.h @@ -2,3 +2,4 @@ see COPYING for more details */ #define emulator_version "1.20" +#define emulator_version_w L"1.20" diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c index 7fc01b246..2247baccb 100644 --- a/src/cdrom-iso.c +++ b/src/cdrom-iso.c @@ -13,7 +13,7 @@ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE -#include +#include static CDROM iso_cdrom; @@ -48,7 +48,7 @@ void iso_audio_stop(uint8_t id) static int iso_ready(uint8_t id) { - if (strlen(cdrom_iso[id].iso_path) == 0) + if (wcslen(cdrom_iso[id].iso_path) == 0) { return 0; } @@ -68,7 +68,7 @@ static int iso_ready(uint8_t id) static int iso_medium_changed(uint8_t id) { - if (strlen(cdrom_iso[id].iso_path) == 0) + if (wcslen(cdrom_iso[id].iso_path) == 0) { return 0; } @@ -100,7 +100,7 @@ static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) { int pos=0; int32_t temp; - if (strlen(cdrom_iso[id].iso_path) == 0) + if (wcslen(cdrom_iso[id].iso_path) == 0) { return 0; } @@ -157,7 +157,7 @@ static void iso_readsector(uint8_t id, uint8_t *b, int sector) } file_pos <<= 11; memset(b, 0, 2856); - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); fclose(cdrom_iso[id].iso_image); @@ -527,7 +527,7 @@ static uint32_t iso_size(uint8_t id) { uint64_t iso_size; - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); fseeko64(cdrom_iso[id].iso_image, 0, SEEK_END); iso_size = ftello64(cdrom_iso[id].iso_image); iso_size >>= 11; @@ -547,11 +547,11 @@ void iso_reset(uint8_t id) { } -int iso_open(uint8_t id, char *fn) +int iso_open(uint8_t id, wchar_t *fn) { - struct stat64 st; + FILE *f; - if (strcmp(fn, cdrom_iso[id].iso_path) != 0) + if (wcscmp(fn, cdrom_iso[id].iso_path) != 0) { cdrom_iso[id].iso_changed = 1; } @@ -559,9 +559,9 @@ int iso_open(uint8_t id, char *fn) if (!cdrom_iso[id].iso_inited && (cdrom_drives[id].host_drive != 200)) cdrom_iso[id].iso_changed = 0; if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) { - sprintf(cdrom_iso[id].iso_path, "%s", fn); + _swprintf(cdrom_iso[id].iso_path, L"%ws", fn); } - cdrom_iso[id].iso_image = fopen(cdrom_iso[id].iso_path, "rb"); + cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); cdrom_drives[id].handler = &iso_cdrom; if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) { @@ -569,8 +569,10 @@ int iso_open(uint8_t id, char *fn) fclose(cdrom_iso[id].iso_image); } - stat64(cdrom_iso[id].iso_path, &st); - cdrom_iso[id].image_size = st.st_size; + f = _wfopen(cdrom_iso[id].iso_path, L"rb"); + fseeko64(f, 0, SEEK_END); + cdrom_iso[id].image_size = ftello64(f); + fclose(f); return 0; } diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h index c16ea0ebb..fa7b734fa 100644 --- a/src/cdrom-iso.h +++ b/src/cdrom-iso.h @@ -7,7 +7,7 @@ /* this header file lists the functions provided by various platform specific cdrom-ioctl files */ -extern int iso_open(uint8_t id, char *fn); +extern int iso_open(uint8_t id, wchar_t *fn); extern void iso_reset(uint8_t id); extern void iso_close(uint8_t id); diff --git a/src/cdrom.h b/src/cdrom.h index eb5e4066e..85f03a4b0 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -173,7 +173,7 @@ typedef struct uint32_t last_block; uint64_t image_size; int iso_inited; - char iso_path[1024]; + wchar_t iso_path[1024]; FILE* iso_image; int iso_changed; diff --git a/src/config.c b/src/config.c index 1e22f6415..20f40e197 100644 --- a/src/config.c +++ b/src/config.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "config.h" #include "ibm.h" @@ -33,6 +34,7 @@ typedef struct entry_t char name[256]; char data[256]; + wchar_t wdata[256]; } entry_t; #define list_add(new, head) \ @@ -100,7 +102,7 @@ void config_free() void config_load(char *fn) { - FILE *f = fopen(fn, "rt"); + FILE *f = fopen(fn, "rt, ccs=UNICODE"); section_t *current_section; memset(&config_head, 0, sizeof(list_t)); @@ -115,32 +117,34 @@ void config_load(char *fn) while (1) { int c; - char buffer[256]; + wchar_t buffer[1024]; + int org_pos; - fgets(buffer, 255, f); + memset(buffer, 0, 2048); + fgetws(buffer, 255, f); if (feof(f)) break; c = 0; - while (buffer[c] == ' ') + while (buffer[c] == L' ') c++; - if (!buffer[c]) continue; + if (buffer[c] == L'\0') continue; - if (buffer[c] == '#') /*Comment*/ + if (buffer[c] == L'#') /*Comment*/ continue; - if (buffer[c] == '[') /*Section*/ + if (buffer[c] == L'[') /*Section*/ { section_t *new_section; char name[256]; int d = 0; c++; - while (buffer[c] != ']' && buffer[c]) - name[d++] = buffer[c++]; + while (buffer[c] != L']' && buffer[c]) + wctomb(&(name[d++]), buffer[c++]); - if (buffer[c] != ']') + if (buffer[c] != L']') continue; name[d] = 0; @@ -157,13 +161,13 @@ void config_load(char *fn) char name[256]; int d = 0, data_pos; - while (buffer[c] != '=' && buffer[c] != ' ' && buffer[c]) - name[d++] = buffer[c++]; + while (buffer[c] != L'=' && buffer[c] != L' ' && buffer[c]) + wctomb(&(name[d++]), buffer[c++]); - if (!buffer[c]) continue; + if (buffer[c] == L'\0') continue; name[d] = 0; - while ((buffer[c] == '=' || buffer[c] == ' ') && buffer[c]) + while ((buffer[c] == L'=' || buffer[c] == L' ') && buffer[c]) c++; if (!buffer[c]) continue; @@ -171,15 +175,18 @@ void config_load(char *fn) data_pos = c; while (buffer[c]) { - if (buffer[c] == '\n') - buffer[c] = 0; + if (buffer[c] == L'\n') + buffer[c] = L'\0'; c++; } new_entry = malloc(sizeof(entry_t)); memset(new_entry, 0, sizeof(entry_t)); strncpy(new_entry->name, name, 256); - strncpy(new_entry->data, &buffer[data_pos], 256); + memcpy(new_entry->wdata, &buffer[data_pos], 512); + new_entry->wdata[255] = L'\0'; + wcstombs(new_entry->data, new_entry->wdata, 512); + new_entry->data[255] = '\0'; list_add(&new_entry->list, ¤t_section->entry_head); } } @@ -193,7 +200,7 @@ void config_load(char *fn) void config_new() { - FILE *f = fopen(config_file, "wt"); + FILE *f = fopen(config_file, "wt, ccs=UNICODE"); fclose(f); } @@ -292,6 +299,24 @@ char *config_get_string(char *head, char *name, char *def) return entry->data; } +wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + return entry->wdata; +} + void config_set_int(char *head, char *name, int val) { section_t *section; @@ -308,6 +333,7 @@ void config_set_int(char *head, char *name, int val) entry = create_entry(section, name); sprintf(entry->data, "%i", val); + mbstowcs(entry->wdata, entry->data, 512); } void config_set_string(char *head, char *name, char *val) @@ -326,6 +352,25 @@ void config_set_string(char *head, char *name, char *val) entry = create_entry(section, name); strncpy(entry->data, val, 256); + mbstowcs(entry->wdata, entry->data, 256); +} + +void config_set_wstring(char *head, char *name, wchar_t *val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + memcpy(entry->wdata, val, 512); } @@ -336,7 +381,7 @@ char *get_filename(char *s) { if (s[c] == '/' || s[c] == '\\') return &s[c+1]; - c--; + c--; } return s; } @@ -369,9 +414,27 @@ char *get_extension(char *s) return &s[c+1]; } +wchar_t *get_extension_w(wchar_t *s) +{ + int c = wcslen(s) - 1; + + if (c <= 0) + return s; + + while (c && s[c] != L'.') + c--; + + if (!c) + return &s[wcslen(s)]; + + return &s[c+1]; +} + +static wchar_t wname[512]; + void config_save(char *fn) { - FILE *f = fopen(fn, "wt"); + FILE *f = fopen(fn, "wt, ccs=UNICODE"); section_t *current_section; current_section = (section_t *)config_head.next; @@ -381,13 +444,24 @@ void config_save(char *fn) entry_t *current_entry; if (current_section->name[0]) - fprintf(f, "\n[%s]\n", current_section->name); + { + mbstowcs(wname, current_section->name, strlen(current_section->name) + 1); + _fwprintf_p(f, L"\n[%ws]\n", wname); + } current_entry = (entry_t *)current_section->entry_head.next; while (current_entry) { - fprintf(f, "%s = %s\n", current_entry->name, current_entry->data); + mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); + if (current_entry->wdata[0] == L'\0') + { + _fwprintf_p(f, L"%ws = \n", wname); + } + else + { + _fwprintf_p(f, L"%ws = %ws\n", wname, current_entry->wdata); + } current_entry = (entry_t *)current_entry->list.next; } diff --git a/src/config.h b/src/config.h index 55e091e52..6fb3c8a2f 100644 --- a/src/config.h +++ b/src/config.h @@ -3,13 +3,16 @@ */ int config_get_int(char *head, char *name, int def); char *config_get_string(char *head, char *name, char *def); +wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); void config_set_int(char *head, char *name, int val); void config_set_string(char *head, char *name, char *val); +void config_set_wstring(char *head, char *name, wchar_t *val); char *get_filename(char *s); void append_filename(char *dest, char *s1, char *s2, int size); void put_backslash(char *s); char *get_extension(char *s); +wchar_t *get_extension_w(wchar_t *s); void config_load(char *fn); void config_save(char *fn); diff --git a/src/disc.c b/src/disc.c index 70141de15..e858474ce 100644 --- a/src/disc.c +++ b/src/disc.c @@ -1,6 +1,9 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +#define UNICODE +#include + #include "ibm.h" #include "config.h" @@ -56,68 +59,68 @@ void (*fdc_indexpulse)();*/ static struct { - char *ext; - void (*load)(int drive, char *fn); + wchar_t *ext; + void (*load)(int drive, wchar_t *fn); 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}, - {"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}, - {"TD0", td0_load, td0_close, -1}, - {"VFD", img_load, img_close, -1}, - {"XDF", img_load, img_close, -1}, + {L"001", img_load, img_close, -1}, + {L"002", img_load, img_close, -1}, + {L"003", img_load, img_close, -1}, + {L"004", img_load, img_close, -1}, + {L"005", img_load, img_close, -1}, + {L"006", img_load, img_close, -1}, + {L"007", img_load, img_close, -1}, + {L"008", img_load, img_close, -1}, + {L"009", img_load, img_close, -1}, + {L"010", img_load, img_close, -1}, + {L"12", img_load, img_close, -1}, + {L"144", img_load, img_close, -1}, + {L"360", img_load, img_close, -1}, + {L"720", img_load, img_close, -1}, + {L"86F", d86f_load, d86f_close, -1}, + {L"BIN", img_load, img_close, -1}, + {L"CQ", img_load, img_close, -1}, + {L"CQM", img_load, img_close, -1}, + {L"DSK", img_load, img_close, -1}, + {L"FDI", fdi_load, fdi_close, -1}, + {L"FDF", img_load, img_close, -1}, + {L"FLP", img_load, img_close, -1}, + {L"HDM", img_load, img_close, -1}, + {L"IMA", img_load, img_close, -1}, + {L"IMD", imd_load, imd_close, -1}, + {L"IMG", img_load, img_close, -1}, + {L"TD0", td0_load, td0_close, -1}, + {L"VFD", img_load, img_close, -1}, + {L"XDF", img_load, img_close, -1}, {0,0,0} }; static int driveloaders[4]; -void disc_load(int drive, char *fn) +void disc_load(int drive, wchar_t *fn) { int c = 0, size; - char *p; + wchar_t *p; FILE *f; if (!fn) return; - p = get_extension(fn); + p = get_extension_w(fn); if (!p) return; - f = fopen(fn, "rb"); + f = _wfopen(fn, L"rb"); if (!f) return; fseek(f, -1, SEEK_END); size = ftell(f) + 1; fclose(f); while (loaders[c].ext) { - if (!strcasecmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) + if (!_wcsicmp(p, loaders[c].ext) && (size == loaders[c].size || loaders[c].size == -1)) { driveloaders[drive] = c; loaders[c].load(drive, fn); drive_empty[drive] = 0; - strcpy(discfns[drive], fn); + memcpy(discfns[drive], fn, (wcslen(fn) << 1) + 2); fdd_forced_seek(real_drive(drive), 0); disc_changed[drive] = 1; return; @@ -127,7 +130,8 @@ void disc_load(int drive, char *fn) pclog("Couldn't load %s %s\n",fn,p); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); - discfns[drive][0] = 0; + discfns[drive][0] = L'\0'; + update_status_bar_icon_state(drive, 1); } void disc_close(int drive) @@ -135,7 +139,7 @@ void disc_close(int drive) if (loaders[driveloaders[drive]].close) loaders[driveloaders[drive]].close(drive); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); - discfns[drive][0] = 0; + discfns[drive][0] = L'\0'; drives[drive].hole = NULL; drives[drive].poll = NULL; drives[drive].seek = NULL; @@ -146,6 +150,7 @@ void disc_close(int drive) drives[drive].format = NULL; drives[drive].byteperiod = NULL; drives[drive].stop = NULL; + update_status_bar_icon_state(drive, 1); } int disc_notfound=0; diff --git a/src/disc.h b/src/disc.h index 32bb601a0..4bf7a96cb 100644 --- a/src/disc.h +++ b/src/disc.h @@ -21,7 +21,7 @@ extern DRIVE drives[FDD_NUM]; extern int curdrive; -void disc_load(int drive, char *fn); +void disc_load(int drive, wchar_t *fn); void disc_new(int drive, char *fn); void disc_close(int drive); void disc_init(); diff --git a/src/disc_86f.c b/src/disc_86f.c index a939e9fe6..892696304 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "lzf/lzf.h" @@ -229,7 +230,7 @@ struct __attribute__((__packed__)) uint32_t error_condition; int is_compressed; int id_found; - char original_file_name[2048]; + wchar_t original_file_name[2048]; uint8_t *filebuf; uint8_t *outbuf; uint32_t dma_over; @@ -2738,7 +2739,7 @@ void d86f_writeback(int drive) /* The image is compressed. */ /* Open the original, compressed file. */ - cf = fopen(d86f[drive].original_file_name, "wb"); + cf = _wfopen(d86f[drive].original_file_name, L"wb"); /* Write the header to the original file. */ fwrite(header, 1, header_size, cf); @@ -3018,11 +3019,11 @@ void d86f_common_handlers(int drive) drives[drive].stop = d86f_stop; } -void d86f_load(int drive, char *fn) +void d86f_load(int drive, wchar_t *fn) { uint32_t magic = 0; uint32_t len = 0; - char temp_file_name[2048]; + wchar_t temp_file_name[2048]; uint16_t temp = 0; int i = 0; FILE *tf; @@ -3030,12 +3031,15 @@ void d86f_load(int drive, char *fn) d86f_unregister(drive); writeprot[drive] = 0; - d86f[drive].f = fopen(fn, "rb+"); + d86f[drive].f = _wfopen(fn, L"rb+"); if (!d86f[drive].f) { - d86f[drive].f = fopen(fn, "rb"); + d86f[drive].f = _wfopen(fn, L"rb"); if (!d86f[drive].f) + { + update_status_bar_icon_state(drive, 1); return; + } writeprot[drive] = 1; } if (ui_writeprot[drive]) @@ -3054,6 +3058,7 @@ void d86f_load(int drive, char *fn) { /* File is WAY too small, abort. */ fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3062,6 +3067,7 @@ void d86f_load(int drive, char *fn) /* File is not of the valid format, abort. */ d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3083,6 +3089,7 @@ void d86f_load(int drive, char *fn) d86f_log("86F: Unrecognized file version: %i.%02i\n", d86f[drive].version >> 8, d86f[drive].version & 0xFF); } fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -3098,6 +3105,7 @@ void d86f_load(int drive, char *fn) { /* File too small, abort. */ fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3119,26 +3127,27 @@ void d86f_load(int drive, char *fn) { d86f_log("86F: CRC64 error\n"); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } #endif if (d86f[drive].is_compressed) { - append_filename(temp_file_name, pcempath, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 511); - memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 13); - memcpy(d86f[drive].original_file_name, fn, strlen(fn) + 1); + memcpy(temp_file_name, drive ? L"TEMP$$$1.$$$" : L"TEMP$$$0.$$$", 256); + memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2); fclose(d86f[drive].f); - d86f[drive].f = fopen(temp_file_name, "wb"); + d86f[drive].f = _wfopen(temp_file_name, L"wb"); if (!d86f[drive].f) { d86f_log("86F: Unable to create temporary decompressed file\n"); + update_status_bar_icon_state(drive, 1); return; } - tf = fopen(fn, "rb"); + tf = _wfopen(fn, L"rb"); for (i = 0; i < 8; i++) { @@ -3163,11 +3172,12 @@ void d86f_load(int drive, char *fn) if (!temp) { d86f_log("86F: Error decompressing file\n"); - remove(temp_file_name); + _wremove(temp_file_name); + update_status_bar_icon_state(drive, 1); return; } - d86f[drive].f = fopen(temp_file_name, "rb+"); + d86f[drive].f = _wfopen(temp_file_name, L"rb+"); } if (d86f[drive].disk_flags & 0x100) @@ -3177,8 +3187,9 @@ void d86f_load(int drive, char *fn) fclose(d86f[drive].f); if (d86f[drive].is_compressed) { - remove(temp_file_name); + _wremove(temp_file_name); } + update_status_bar_icon_state(drive, 1); return; } @@ -3189,8 +3200,9 @@ void d86f_load(int drive, char *fn) fclose(d86f[drive].f); if (d86f[drive].is_compressed) { - remove(temp_file_name); + _wremove(temp_file_name); } + update_status_bar_icon_state(drive, 1); return; } @@ -3206,11 +3218,11 @@ void d86f_load(int drive, char *fn) if (d86f[drive].is_compressed) { - d86f[drive].f = fopen(temp_file_name, "rb"); + d86f[drive].f = _wfopen(temp_file_name, L"rb"); } else { - d86f[drive].f = fopen(fn, "rb"); + d86f[drive].f = _wfopen(fn, L"rb"); } } @@ -3223,6 +3235,7 @@ void d86f_load(int drive, char *fn) /* File has no track 0 side 0, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3231,6 +3244,7 @@ void d86f_load(int drive, char *fn) /* File is 2-sided but has no track 0 side 1, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -3306,14 +3320,13 @@ void d86f_init() void d86f_close(int drive) { - char temp_file_name[2048]; + wchar_t temp_file_name[2048]; - append_filename(temp_file_name, pcempath, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 511); - memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 13); + memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 26); if (d86f[drive].f) fclose(d86f[drive].f); if (d86f[drive].is_compressed) - remove(temp_file_name); + _wremove(temp_file_name); d86f[drive].f = NULL; } diff --git a/src/disc_86f.h b/src/disc_86f.h index 45c5838d2..7efc9b3f5 100644 --- a/src/disc_86f.h +++ b/src/disc_86f.h @@ -2,7 +2,7 @@ see COPYING for more details */ void d86f_init(); -void d86f_load(int drive, char *fn); +void d86f_load(int drive, wchar_t *fn); void d86f_close(int drive); void d86f_seek(int drive, int track); int d86f_hole(int drive); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index 091524b20..b7aae9819 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -3,6 +3,7 @@ */ #include #include +#include #include "ibm.h" #include "disc.h" #include "disc_img.h" @@ -239,13 +240,17 @@ void d86f_register_fdi(int drive) d86f_handler[drive].check_crc = 1; } -void fdi_load(int drive, char *fn) +void fdi_load(int drive, wchar_t *fn) { char header[26]; writeprot[drive] = fwriteprot[drive] = 1; - fdi[drive].f = fopen(fn, "rb"); - if (!fdi[drive].f) return; + fdi[drive].f = _wfopen(fn, L"rb"); + if (!fdi[drive].f) + { + update_status_bar_icon_state(drive, 1); + return; + } d86f_unregister(drive); diff --git a/src/disc_fdi.h b/src/disc_fdi.h index d26340fd0..781efac23 100644 --- a/src/disc_fdi.h +++ b/src/disc_fdi.h @@ -2,7 +2,7 @@ see COPYING for more details */ void fdi_init(); -void fdi_load(int drive, char *fn); +void fdi_load(int drive, wchar_t *fn); void fdi_close(int drive); void fdi_seek(int drive, int track); void fdi_readsector(int drive, int sector, int track, int side, int density, int sector_size); diff --git a/src/disc_imd.c b/src/disc_imd.c index c69a0b674..e583335e0 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -8,6 +8,7 @@ #include "fdd.h" #include +#include typedef struct { @@ -49,7 +50,7 @@ void imd_init() void d86f_register_imd(int drive); -void imd_load(int drive, char *fn) +void imd_load(int drive, wchar_t *fn) { uint32_t magic = 0; uint32_t fsize = 0; @@ -73,12 +74,15 @@ void imd_load(int drive, char *fn) d86f_unregister(drive); writeprot[drive] = 0; - imd[drive].f = fopen(fn, "rb+"); + imd[drive].f = _wfopen(fn, L"rb+"); if (!imd[drive].f) { - imd[drive].f = fopen(fn, "rb"); + imd[drive].f = _wfopen(fn, L"rb"); if (!imd[drive].f) + { + update_status_bar_icon_state(drive, 1); return; + } writeprot[drive] = 1; } if (ui_writeprot[drive]) @@ -93,6 +97,7 @@ void imd_load(int drive, char *fn) { pclog("IMD: Not a valid ImageDisk image\n"); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -113,6 +118,7 @@ void imd_load(int drive, char *fn) { pclog("IMD: No ASCII EOF character\n"); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -125,6 +131,7 @@ void imd_load(int drive, char *fn) { pclog("IMD: File ends after ASCII EOF character\n"); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -243,6 +250,7 @@ void imd_load(int drive, char *fn) /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); fclose(imd[drive].f); + update_status_bar_icon_state(drive, 1); return; } } diff --git a/src/disc_imd.h b/src/disc_imd.h index 03628b031..a132605d9 100644 --- a/src/disc_imd.h +++ b/src/disc_imd.h @@ -2,6 +2,6 @@ see COPYING for more details */ void imd_init(); -void imd_load(int drive, char *fn); +void imd_load(int drive, wchar_t *fn); void imd_close(int drive); void imd_seek(int drive, int track); diff --git a/src/disc_img.c b/src/disc_img.c index a9e60c880..e5020353d 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -2,8 +2,10 @@ see COPYING for more details */ #include +#include #include "ibm.h" +#include "config.h" #include "disc.h" #include "disc_img.h" #include "fdc.h" @@ -296,14 +298,14 @@ int first_byte_is_valid(uint8_t first_byte) double bit_rate_300; -char ext[4]; +wchar_t *ext; uint8_t first_byte, second_byte, third_byte, fourth_byte; /* This is hard-coded to 0 - if you really need to read those NT 3.1 Beta floppy images, change this to 1 and recompile the emulator. */ uint8_t fdf_suppress_final_byte = 0; -void img_load(int drive, char *fn) +void img_load(int drive, wchar_t *fn) { int size; uint16_t bpb_bps; @@ -324,20 +326,20 @@ void img_load(int drive, char *fn) uint16_t track_bytes = 0; uint8_t *literal; - ext[0] = fn[strlen(fn) - 3] | 0x60; - ext[1] = fn[strlen(fn) - 2] | 0x60; - ext[2] = fn[strlen(fn) - 1] | 0x60; - ext[3] = 0; + ext = get_extension_w(fn); d86f_unregister(drive); writeprot[drive] = 0; - img[drive].f = fopen(fn, "rb+"); + img[drive].f = _wfopen(fn, L"rb+"); if (!img[drive].f) { - img[drive].f = fopen(fn, "rb"); + img[drive].f = _wfopen(fn, L"rb"); if (!img[drive].f) + { + update_status_bar_icon_state(drive, 1); return; + } writeprot[drive] = 1; } if (ui_writeprot[drive]) @@ -350,7 +352,7 @@ void img_load(int drive, char *fn) img[drive].interleave = img[drive].skew = 0; - if (strcmp(ext, "fdi") == 0) + if (_wcsicmp(ext, L"FDI") == 0) { /* This is a Japanese FDI image, so let's read the header */ pclog("img_load(): File is a Japanese FDI image...\n"); @@ -395,7 +397,7 @@ void img_load(int drive, char *fn) pclog("img_load(): File is a FDF image...\n"); fwriteprot[drive] = writeprot[drive] = 1; fclose(img[drive].f); - img[drive].f = fopen(fn, "rb"); + img[drive].f = _wfopen(fn, L"rb"); fdf = 1; @@ -580,7 +582,7 @@ void img_load(int drive, char *fn) pclog("img_load(): File is a CopyQM image...\n"); fwriteprot[drive] = writeprot[drive] = 1; fclose(img[drive].f); - img[drive].f = fopen(fn, "rb"); + img[drive].f = _wfopen(fn, L"rb"); fseek(img[drive].f, 0x03, SEEK_SET); fread(&bpb_bps, 1, 2, img[drive].f); @@ -734,6 +736,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); + update_status_bar_icon_state(drive, 1); return; } } @@ -795,6 +798,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); + update_status_bar_icon_state(drive, 1); return; } @@ -811,6 +815,7 @@ jump_if_fdf: { pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); fclose(img[drive].f); + update_status_bar_icon_state(drive, 1); return; } diff --git a/src/disc_img.h b/src/disc_img.h index a98ba1a98..4cb82ea1f 100644 --- a/src/disc_img.h +++ b/src/disc_img.h @@ -2,6 +2,6 @@ see COPYING for more details */ void img_init(); -void img_load(int drive, char *fn); +void img_load(int drive, wchar_t *fn); void img_close(int drive); void img_seek(int drive, int track); diff --git a/src/disc_td0.c b/src/disc_td0.c index 5905527b9..ab3511a32 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -14,6 +14,8 @@ * Edited and translated to English by Kenji RIKITAKE */ +#include + #include "ibm.h" #include "disc.h" #include "disc_td0.h" @@ -499,16 +501,17 @@ uint8_t imagebuf[4*1024*1024]; uint8_t processed_buf[5*1024*1024]; uint8_t header[12]; -void td0_load(int drive, char *fn) +void td0_load(int drive, wchar_t *fn) { int ret = 0; d86f_unregister(drive); writeprot[drive] = 1; - td0[drive].f = fopen(fn, "rb"); + td0[drive].f = _wfopen(fn, L"rb"); if (!td0[drive].f) { + update_status_bar_icon_state(drive, 1); return; } fwriteprot[drive] = writeprot[drive]; @@ -518,6 +521,7 @@ void td0_load(int drive, char *fn) { pclog("TD0: Not a valid Teledisk image\n"); fclose(td0[drive].f); + update_status_bar_icon_state(drive, 1); return; } else @@ -532,6 +536,7 @@ void td0_load(int drive, char *fn) { pclog("TD0: Failed to initialize\n"); fclose(td0[drive].f); + update_status_bar_icon_state(drive, 1); return; } else diff --git a/src/disc_td0.h b/src/disc_td0.h index 48226d77a..306c7be20 100644 --- a/src/disc_td0.h +++ b/src/disc_td0.h @@ -2,6 +2,6 @@ see COPYING for more details */ void td0_init(); -void td0_load(int drive, char *fn); +void td0_load(int drive, wchar_t *fn); void td0_close(int drive); void td0_seek(int drive, int track); diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 4dfc0b4b6..5afe4ff10 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -796,14 +796,14 @@ static void esdi_mca_write(int port, uint8_t val, void *p) } } -static void loadhd(esdi_t *esdi, int d, const char *fn) +static void loadhd(esdi_t *esdi, int d, const wchar_t *fn) { esdi_drive_t *drive = &esdi->drives[d]; if (drive->hdfile == NULL) { /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "rb+"); + drive->hdfile = _wfopen(fn, L"rb+"); if (drive->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -811,7 +811,7 @@ static void loadhd(esdi_t *esdi, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - drive->hdfile = fopen64(fn, "wb+"); + drive->hdfile = _wfopen(fn, L"wb+"); if (drive->hdfile == NULL) { pclog("Cannot create file '%s': %s", diff --git a/src/ibm.h b/src/ibm.h index ffbc18593..9d06e631b 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -4,6 +4,7 @@ #include #include #include +#include #define printf pclog /*Memory*/ @@ -350,7 +351,7 @@ extern int pic_intpending; int disctime; -char discfns[4][256]; +wchar_t discfns[4][256]; int driveempty[4]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset=ROM_IBMAT)) @@ -637,10 +638,10 @@ FILE *shdf[HDC_NUM]; uint64_t hdt[128][3]; uint64_t hdt_mfm[128][3]; -extern char hdd_fn[HDC_NUM][512]; +extern wchar_t hdd_fn[HDC_NUM][512]; -int image_is_hdi(const char *s); -int image_is_hdx(const char *s, int check_signature); +int image_is_hdi(const wchar_t *s); +int image_is_hdx(const wchar_t *s, int check_signature); /*Keyboard*/ int keybsenddelay; @@ -779,6 +780,7 @@ void softresetx86(); void speedchanged(); void trc_reset(uint8_t val); void update_status_bar_icon(int tag, int active); +void update_status_bar_icon_state(int tag, int state); void x86_int_sw(int num); void x86gpf(char *s, uint16_t error); void x86np(char *s, uint16_t error); diff --git a/src/ide.c b/src/ide.c index 525534189..aa8855eba 100644 --- a/src/ide.c +++ b/src/ide.c @@ -13,6 +13,7 @@ #include #include +#include #include "86box.h" #include "cdrom.h" @@ -95,7 +96,7 @@ IDE ide_drives[IDE_NUM]; IDE *ext_ide; -char hdd_fn[HDC_NUM][512]; +wchar_t hdd_fn[HDC_NUM][512]; int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); @@ -142,16 +143,19 @@ int ide_drive_is_cdrom(IDE *ide) } } -int image_is_hdi(const char *s) +static char as[512]; + +int image_is_hdi(const wchar_t *s) { int i, len; char ext[5] = { 0, 0, 0, 0, 0 }; - len = strlen(s); - if ((len < 4) || (s[0] == '.')) + wcstombs(as, s, (wcslen(s) << 1) + 2); + len = strlen(as); + if ((len < 4) || (as[0] == '.')) { return 0; } - memcpy(ext, s + len - 4, 4); + memcpy(ext, as + len - 4, 4); for (i = 0; i < 4; i++) { ext[i] = toupper(ext[i]); @@ -166,19 +170,20 @@ int image_is_hdi(const char *s) } } -int image_is_hdx(const char *s, int check_signature) +int image_is_hdx(const wchar_t *s, int check_signature) { int i, len; FILE *f; uint64_t filelen; uint64_t signature; char ext[5] = { 0, 0, 0, 0, 0 }; - len = strlen(s); - if ((len < 4) || (s[0] == '.')) + wcstombs(as, s, (wcslen(s) << 1) + 2); + len = strlen(as); + if ((len < 4) || (as[0] == '.')) { return 0; } - memcpy(ext, s + len - 4, 4); + memcpy(ext, as + len - 4, 4); for (i = 0; i < 4; i++) { ext[i] = toupper(ext[i]); @@ -187,7 +192,7 @@ int image_is_hdx(const char *s, int check_signature) { if (check_signature) { - f = fopen(s, "rb"); + f = _wfopen(s, L"rb"); if (!f) { return 0; @@ -392,6 +397,7 @@ static void ide_identify(IDE *ide) ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ ide->buffer[52] = 2 << 8; /*DMA timing mode*/ +#if 0 ide->buffer[53] = 1; ide->buffer[55] = ide->hpc; ide->buffer[56] = ide->spt; @@ -406,6 +412,7 @@ static void ide_identify(IDE *ide) full_size = ((uint64_t) ide->hpc) * ((uint64_t) ide->spt) * ((uint64_t) ide->buffer[54]); ide->buffer[57] = full_size & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[58] = (full_size >> 16) & 0x0FFF; +#endif ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if (ide->buffer[49] & (1 << 9)) { @@ -494,7 +501,7 @@ static void ide_next_sector(IDE *ide) } } -static void loadhd(IDE *ide, int d, const char *fn) +static void loadhd(IDE *ide, int d, const wchar_t *fn) { uint32_t sector_size = 512; uint32_t zero = 0; @@ -511,7 +518,7 @@ static void loadhd(IDE *ide, int d, const char *fn) ide->type = IDE_NONE; return; } - ide->hdfile = fopen64(fn, "rb+"); + ide->hdfile = _wfopen(fn, L"rb+"); if (ide->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -519,7 +526,7 @@ static void loadhd(IDE *ide, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - ide->hdfile = fopen64(fn, "wb+"); + ide->hdfile = _wfopen(fn, L"wb+"); if (ide->hdfile == NULL) { ide->type = IDE_NONE; diff --git a/src/mfm_at.c b/src/mfm_at.c index ebbcde2a9..c4c1be484 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -8,6 +8,7 @@ #include #include +#include #include "ibm.h" #include "device.h" @@ -159,14 +160,14 @@ static void mfm_next_sector(mfm_t *mfm) } } -static void loadhd(mfm_t *mfm, int c, int d, const char *fn) +static void loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) { mfm_drive_t *drive = &mfm->drives[c]; if (drive->hdfile == NULL) { /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "rb+"); + drive->hdfile = _wfopen(fn, L"rb+"); if (drive->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -174,7 +175,7 @@ static void loadhd(mfm_t *mfm, int c, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - drive->hdfile = fopen64(fn, "wb+"); + drive->hdfile = _wfopen(fn, L"wb+"); if (drive->hdfile == NULL) { pclog("Cannot create file '%s': %s", diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index eac421b0a..5459a75a7 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -763,14 +763,14 @@ static void xebec_callback(void *p) } } -static void loadhd(xebec_t *xebec, int d, const char *fn) +static void loadhd(xebec_t *xebec, int d, const wchar_t *fn) { mfm_drive_t *drive = &xebec->drives[d]; if (drive->hdfile == NULL) { /* Try to open existing hard disk image */ - drive->hdfile = fopen64(fn, "rb+"); + drive->hdfile = _wfopen(fn, L"rb+"); if (drive->hdfile == NULL) { /* Failed to open existing hard disk image */ @@ -778,7 +778,7 @@ static void loadhd(xebec_t *xebec, int d, const char *fn) { /* Failed because it does not exist, so try to create new file */ - drive->hdfile = fopen64(fn, "wb+"); + drive->hdfile = _wfopen(fn, L"wb+"); if (drive->hdfile == NULL) { pclog("Cannot create file '%s': %s", diff --git a/src/nethandler.c b/src/nethandler.c index c399964c6..ddf1677af 100644 --- a/src/nethandler.c +++ b/src/nethandler.c @@ -1,12 +1,9 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -#include -#include #include #include #include -#include #include "nethandler.h" #include "ibm.h" @@ -83,6 +80,11 @@ void network_card_init() if (network_cards[network_card_current].device) device_add(network_cards[network_card_current].device); network_card_last = network_card_current; + + if (network_card_current != 0) + { + vlan_reset(); /* NETWORK */ + } } static struct diff --git a/src/pc.c b/src/pc.c index a3a09c04f..d13a402e7 100644 --- a/src/pc.c +++ b/src/pc.c @@ -10,6 +10,7 @@ #include "device.h" #ifndef __unix +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP @@ -357,7 +358,7 @@ void initpc(int argc, char *argv[]) { if (cdrom_drives[i].host_drive == 200) { - ff = fopen(cdrom_iso[i].iso_path, "rb"); + ff = _wfopen(cdrom_iso[i].iso_path, L"rb"); if (ff) { fclose(ff); @@ -486,12 +487,8 @@ void resetpchard() ide_qua_init(); } - if (network_card_current != 0) - { - vlan_reset(); /* NETWORK */ - } - network_card_init(network_card_current); - + network_card_init(); + for (i = 0; i < CDROM_NUM; i++) { if (cdrom_drives[i].bus_type) @@ -503,7 +500,7 @@ void resetpchard() resetide(); scsi_card_init(); - sound_card_init(sound_card_current); + sound_card_init(); if (GUS) device_add(&gus_device); if (GAMEBLASTER) @@ -559,9 +556,12 @@ int serial_fifo_read, serial_fifo_write; int emu_fps = 0; +static WCHAR wmodel[2048]; +static WCHAR wcpu[2048]; + void runpc() { - char s[200]; + wchar_t s[200]; int done=0; startblit(); @@ -637,7 +637,9 @@ void runpc() if (win_title_update) { win_title_update=0; - sprintf(s, "86Box v%s - %i%% - %s - %s - %s", emulator_version, fps, model_getname(), models[model].cpu[cpu_manufacturer].cpus[cpu].name, (!mousecapture) ? "Click to capture mouse" : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? "Press F12-F8 to release mouse" : "Press F12-F8 or middle button to release mouse")); + mbstowcs(wmodel, model_getname(), strlen(model_getname()) + 1); + mbstowcs(wcpu, models[model].cpu[cpu_manufacturer].cpus[cpu].name, strlen(models[model].cpu[cpu_manufacturer].cpus[cpu].name) + 1); + _swprintf(s, L"86Box v%s - %i%% - %s - %s - %s", emulator_version_w, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); set_window_title(s); } done++; @@ -703,6 +705,7 @@ void loadconfig(char *fn) int c, d; char s[512]; char *p; + WCHAR *wp; char temps[512]; if (!fn) @@ -776,9 +779,13 @@ void loadconfig(char *fn) fdd_set_type(c, (c < 2) ? 2 : 0); sprintf(temps, "fdd_%02i_fn", c + 1); - p = (char *)config_get_string(NULL, temps, ""); - if (p) strcpy(discfns[c], p); - else strcpy(discfns[c], ""); + wp = (WCHAR *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(discfns[c], wp, 512); + else { + memcpy(discfns[c], L"", 2); + discfns[c][0] = L'\0'; + } + printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); ui_writeprot[c] = config_get_int(NULL, temps, 0); } @@ -818,9 +825,12 @@ void loadconfig(char *fn) sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); hdc[c].scsi_lun = config_get_int(NULL, temps, 0); sprintf(temps, "hdd_%02i_fn", c + 1); - p = (char *)config_get_string(NULL, temps, ""); - if (p) strcpy(hdd_fn[c], p); - else strcpy(hdd_fn[c], ""); + wp = (WCHAR *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(hdd_fn[c], wp, 512); + else { + memcpy(hdd_fn[c], L"", 2); + hdd_fn[c][0] = L'\0'; + } } memset(temps, 0, 512); @@ -845,9 +855,12 @@ void loadconfig(char *fn) cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); sprintf(temps, "cdrom_%02i_iso_path", c + 1); - p = (char *)config_get_string(NULL, temps, ""); - if (p) strcpy(cdrom_iso[c].iso_path, p); - else strcpy(cdrom_iso[c].iso_path, ""); + wp = (WCHAR *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(cdrom_iso[c].iso_path, wp, 512); + else { + memcpy(cdrom_iso[c].iso_path, L"", 2); + cdrom_iso[c].iso_path[0] = L'\0'; + } } vid_resize = config_get_int(NULL, "vid_resize", 0); @@ -972,7 +985,7 @@ void saveconfig() sprintf(temps, "fdd_%02i_type", c + 1); config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_string(NULL, temps, discfns[c]); + config_set_wstring(NULL, temps, discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); config_set_int(NULL, temps, ui_writeprot[c]); } @@ -1008,7 +1021,7 @@ void saveconfig() sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); config_set_int(NULL, temps, hdc[c].scsi_lun); sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_string(NULL, temps, hdd_fn[c]); + config_set_wstring(NULL, temps, hdd_fn[c]); } memset(temps, 0, 512); @@ -1032,7 +1045,7 @@ void saveconfig() config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); sprintf(temps, "cdrom_%02i_iso_path", c + 1); - config_set_string(NULL, temps, cdrom_iso[c].iso_path); + config_set_wstring(NULL, temps, cdrom_iso[c].iso_path); } config_set_int(NULL, "vid_resize", vid_resize); diff --git a/src/scsi.h b/src/scsi.h index ba0334f57..61c8f1bf5 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -12,6 +12,7 @@ #define GPCMD_TEST_UNIT_READY 0x00 #define GPCMD_REZERO_UNIT 0x01 #define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_FORMAT_UNIT 0x04 #define GPCMD_READ_6 0x08 #define GPCMD_WRITE_6 0x0a #define GPCMD_SEEK_6 0x0b diff --git a/src/scsi_hd.c b/src/scsi_hd.c index 1f2bd2788..e0b7f09a2 100644 --- a/src/scsi_hd.c +++ b/src/scsi_hd.c @@ -65,7 +65,8 @@ uint8_t scsi_hd_command_flags[0x100] = IMPLEMENTED | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x01 */ 0, IMPLEMENTED | ALLOW_UA, /* 0x03 */ - 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY | ALLOW_UA | NONDATA | SCSI_ONLY, /* 0x04 */ + 0, 0, 0, IMPLEMENTED | CHECK_READY, /* 0x08 */ 0, IMPLEMENTED | CHECK_READY, /* 0x0A */ @@ -189,7 +190,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) uint64_t signature = 0xD778A82044445459ll; uint64_t full_size = 0; int c; - char *fn = hdd_fn[id]; + wchar_t *fn = hdd_fn[id]; shdc[id].base = 0; @@ -205,7 +206,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) scsi_hard_disks[scsi_id][scsi_lun] = 0xff; return; } - shdf[id] = fopen64(fn, "rb+"); + shdf[id] = _wfopen(fn, L"rb+"); if (shdf[id] == NULL) { /* Failed to open existing hard disk image */ @@ -213,7 +214,7 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) { /* Failed because it does not exist, so try to create new file */ - shdf[id] = fopen64(fn, "wb+"); + shdf[id] = _wfopen(fn, L"wb+"); if (shdf[id] == NULL) { scsi_hard_disks[scsi_id][scsi_lun] = 0xff; @@ -764,6 +765,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) switch (cdb[0]) { case GPCMD_TEST_UNIT_READY: + case GPCMD_FORMAT_UNIT: case GPCMD_VERIFY_6: case GPCMD_VERIFY_10: case GPCMD_VERIFY_12: diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index b3378e1e6..b44097898 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -3,6 +3,7 @@ */ #include #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP @@ -133,7 +134,7 @@ void cgapal_rebuild() int d3d_fs_init(HWND h) { HRESULT hr; - char emulator_title[200]; + WCHAR emulator_title[200]; d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); @@ -142,7 +143,7 @@ int d3d_fs_init(HWND h) d3d_hwnd = h; - sprintf(emulator_title, "86Box v%s", emulator_version); + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); d3d_device_window = CreateWindowEx ( 0, szSubClassName, @@ -572,12 +573,15 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) void d3d_fs_take_screenshot(char *fn) { + WCHAR wfn[512]; LPDIRECT3DSURFACE9 d3dSurface = NULL; if (!d3dTexture) return; + mbstowcs(wfn, fn, strlen(fn) + 1); + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + D3DXSaveSurfaceToFile(wfn, D3DXIFF_PNG, d3dSurface, NULL, NULL); d3dSurface->Release(); d3dSurface = NULL; diff --git a/src/win-d3d.cc b/src/win-d3d.cc index 561873c58..a30fe1795 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -2,6 +2,7 @@ see COPYING for more details */ #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP @@ -382,12 +383,15 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) void d3d_take_screenshot(char *fn) { + WCHAR wfn[512]; LPDIRECT3DSURFACE9 d3dSurface = NULL; if (!d3dTexture) return; + mbstowcs(wfn, fn, strlen(fn) + 1); + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + D3DXSaveSurfaceToFile(wfn, D3DXIFF_PNG, d3dSurface, NULL, NULL); d3dSurface->Release(); d3dSurface = NULL; diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index 9c7bedbb0..811c69f37 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -2,6 +2,7 @@ see COPYING for more details */ #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc index 55c2ff730..c49c6170d 100644 --- a/src/win-ddraw-screenshot.cc +++ b/src/win-ddraw-screenshot.cc @@ -3,10 +3,13 @@ */ #include #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP +#include "win.h" #include "win-ddraw-screenshot.h" +#include "win-language.h" #include "video.h" extern "C" void fatal(const char *format, ...); @@ -64,6 +67,8 @@ void DoubleLines(uint8_t *dst, uint8_t *src) } } +static WCHAR szMessage[2048]; + void SaveBitmap(char *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; @@ -73,8 +78,6 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) BITMAPINFO bmpInfo; BITMAPFILEHEADER bmpFileHeader; - char szMessage[2048]; - do{ hdc=GetDC(NULL); @@ -105,8 +108,8 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) if((fp = fopen(szFilename,"wb"))==NULL) { - sprintf(szMessage, "Unable to Create Bitmap File %s", szFilename); - MessageBox( NULL, szMessage, "Error", MB_OK|MB_ICONERROR); + _swprintf(szMessage, win_language_get_string_from_id(2194), szFilename); + msgbox_error_wstr(ghwnd, szMessage); break; } diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 347c6a752..7842f16b6 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -3,6 +3,7 @@ */ #include #include +#define UNICODE #define BITMAP WINDOWS_BITMAP #include #undef BITMAP diff --git a/src/win-language.c b/src/win-language.c index 353fb1302..51f3e6c86 100644 --- a/src/win-language.c +++ b/src/win-language.c @@ -26,6 +26,7 @@ uint32_t dwLangID, dwSubLangID; WCHAR lpResourceString[STRINGS_NUM][512]; char openfilestring[260]; +WCHAR wopenfilestring[260]; void win_language_set() { @@ -94,11 +95,21 @@ void msgbox_info(HWND hwndParent, int i) MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); } +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + void msgbox_error(HWND hwndParent, int i) { MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); } +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); +} + void msgbox_critical(HWND hwndParent, int i) { MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR); @@ -116,27 +127,22 @@ void msgbox_fatal(HWND hwndParent, char *string) free(lptsTemp); } -int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) +int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save) { OPENFILENAME ofn; /* common dialog box structure */ BOOL r; DWORD err; - WCHAR ufn[260]; - WCHAR uofs[260]; - - /* Convert file name to Unicode */ - mbstowcs(ufn, fn, strlen(fn) + 1); /* Initialize OPENFILENAME */ ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; - ofn.lpstrFile = uofs; + ofn.lpstrFile = wopenfilestring; /* Set lpstrFile[0] to '\0' so that GetOpenFileName does not use the contents of szFile to initialize itself. */ - memcpy(ofn.lpstrFile, ufn, (wcslen(ufn) << 1) + 2); + memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); ofn.nMaxFile = 259; ofn.lpstrFilter = f; ofn.nFilterIndex = 1; @@ -163,7 +169,7 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) } if (r) { - wcstombs(openfilestring, uofs, 520); + wcstombs(openfilestring, wopenfilestring, 520); pclog("File dialog return true\n"); return 0; } @@ -173,6 +179,18 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) return 1; } +int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) +{ + WCHAR ufn[512]; + mbstowcs(ufn, fn, strlen(fn) + 1); + return file_dlg_w(hwnd, f, ufn, save); +} + +int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save) +{ + file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); +} + int file_dlg_st(HWND hwnd, int i, char *fn, int save) { file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); diff --git a/src/win-language.h b/src/win-language.h index 47fde8df8..113c16f44 100644 --- a/src/win-language.h +++ b/src/win-language.h @@ -1,12 +1,20 @@ +#ifdef __cplusplus +extern "C" { +#endif + int msgbox_reset(HWND hwndParent); int msgbox_reset_yn(HWND hwndParent); int msgbox_question(HWND hwndParent, int i); void msgbox_info(HWND hwndParent, int i); +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr); void msgbox_error(HWND hwndParent, int i); +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr); void msgbox_fatal(HWND hwndParent, char *string); void msgbox_critical(HWND hwndParent, int i); +int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save); int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save); +int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save); int file_dlg_st(HWND hwnd, int i, char *fn, int save); void win_language_load_common_strings(); @@ -17,3 +25,7 @@ void win_language_check(); LPTSTR win_language_get_string_from_id(int i); LPTSTR win_language_get_string_from_string(char *str); + +#ifdef __cplusplus +} +#endif diff --git a/src/win-settings.c b/src/win-settings.c index ff3f87c7a..58229df82 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -57,7 +57,7 @@ char temp_hdc_name[16]; /* Hard disks category */ hard_disk_t temp_hdc[HDC_NUM]; -char temp_hdd_fn[HDC_NUM][512]; +wchar_t temp_hdd_fn[HDC_NUM][512]; /* Removable devices category */ int temp_fdd_types[FDD_NUM]; @@ -124,7 +124,7 @@ static void win_settings_init() memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memcpy(temp_hdd_fn[i], hdd_fn[i], 512); + memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); } /* Removable devices category */ @@ -183,7 +183,7 @@ static int win_settings_changed() i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); for (j = 0; j < HDC_NUM; j++) { - i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 512); + i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); } /* Removable devices category */ @@ -274,7 +274,7 @@ static void win_settings_save() memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memcpy(hdd_fn[i], temp_hdd_fn[i], 512); + memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); } /* Removable devices category */ @@ -1474,17 +1474,18 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) int next_free_id = 0; +wchar_t ifn[HDC_NUM][512]; + static void normalize_hd_list() { hard_disk_t ihdc[HDC_NUM]; - char ifn[HDC_NUM][512]; int i, j; j = 0; memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memset(ifn[i], 0, 512); + memset(ifn[i], 0, 1024); } for (i = 0; i < HDC_NUM; i++) { @@ -1496,7 +1497,7 @@ static void normalize_hd_list() if (temp_hdc[i].bus > 0) { memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); - memcpy(ifn[j], temp_hdd_fn[i], 512); + memcpy(ifn[j], temp_hdd_fn[i], 1024); j++; } } @@ -1504,7 +1505,7 @@ static void normalize_hd_list() memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); for (i = 0; i < HDC_NUM; i++) { - memcpy(temp_hdd_fn[i], ifn[i], 512); + memcpy(temp_hdd_fn[i], ifn[i], 1024); } } @@ -1786,8 +1787,7 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column } else if (column == 1) { - mbstowcs(szText, temp_hdd_fn[i], strlen(temp_hdd_fn[i]) + 1); - lvI.pszText = szText; + lvI.pszText = temp_hdd_fn[i]; lvI.iImage = 0; } else if (column == 2) @@ -1864,8 +1864,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 1; - mbstowcs(szText, temp_hdd_fn[i], strlen(temp_hdd_fn[i]) + 1); - lvI.pszText = szText; + lvI.pszText = temp_hdd_fn[i]; lvI.iItem = j; lvI.iImage = 0; @@ -2020,7 +2019,7 @@ int existing = 0; uint64_t selection = 127; uint64_t spt, hpc, tracks, size; -char hd_file_name[512]; +wchar_t hd_file_name[512]; static int hdconf_initialize_hdt_combo(HWND hdlg) { @@ -2134,7 +2133,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W switch (LOWORD(wParam)) { case IDOK: - if (strlen(hd_file_name) == 0) + if (wcslen(hd_file_name) == 0) { msgbox_error(hwndParentDialog, 2056); return TRUE; @@ -2153,14 +2152,14 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - memset(temp_hdd_fn[next_free_id], 0, 512); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, strlen(hd_file_name) + 1); + memset(temp_hdd_fn[next_free_id], 0, 1024); + memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); sector_size = 512; - if (!existing && (strlen(hd_file_name) > 0)) + if (!existing && (wcslen(hd_file_name) > 0)) { - f = fopen(hd_file_name, "wb"); + f = _wfopen(hd_file_name, L"wb"); if (image_is_hdi(hd_file_name)) { @@ -2225,9 +2224,9 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W return TRUE; case IDC_CFILE: - if (!file_dlg(hdlg, win_language_get_string_from_id(2172), "", !existing)) + if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) { - f = fopen(openfilestring, existing ? "rb" : "wb"); + f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); if (f == NULL) { msgbox_error(hwndParentDialog, existing ? 2060 : 2057); @@ -2235,7 +2234,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } if (existing) { - if (image_is_hdi(openfilestring) || image_is_hdx(openfilestring, 1)) + if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) { fseeko64(f, 0x10, SEEK_SET); fread(§or_size, 1, 4, f); @@ -2312,9 +2311,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - mbstowcs(szText, openfilestring, strlen(openfilestring) + 1); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) szText); - memcpy(hd_file_name, openfilestring, strlen(openfilestring) + 1); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); + memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); return TRUE; @@ -2632,7 +2630,7 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA return FALSE; case IDC_BUTTON_HDD_REMOVE: - strncpy(temp_hdd_fn[hdlv_current_sel], "", strlen("") + 1); + memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ ignore_change = 1; diff --git a/src/win.c b/src/win.c index 9c6695efa..75c798ded 100644 --- a/src/win.c +++ b/src/win.c @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +#define UNICODE #define _WIN32_WINNT 0x0501 #define BITMAP WINDOWS_BITMAP #include @@ -397,7 +398,7 @@ static void initmenu(void) { int i, c; HMENU m; - char s[32]; + WCHAR s[64]; for (i = 0; i < CDROM_NUM; i++) { @@ -407,10 +408,10 @@ static void initmenu(void) it's a CDROM */ for (c='A';c<='Z';c++) { - sprintf(s,"%c:\\",c); + _swprintf(s,L"%c:\\",c); if (GetDriveType(s)==DRIVE_CDROM) { - sprintf(s, "Host CD/DVD Drive (%c:)", c); + _swprintf(s, win_language_get_string_from_id(2076), c); AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); } } @@ -419,10 +420,12 @@ static void initmenu(void) void get_executable_name(char *s, int size) { - GetModuleFileName(hinstance, s, size); + WCHAR ws[512]; + GetModuleFileName(hinstance, ws, size); + wcstombs(s, ws, (wcslen(ws) << 1) + 2); } -void set_window_title(char *s) +void set_window_title(WCHAR *s) { if (video_fullscreen) return; @@ -478,8 +481,8 @@ UINT16 convert_scan_code(UINT16 scan_code) void get_registry_key_map() { - char *keyName = "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - char *valueName = "Scancode Map"; + WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + WCHAR *valueName = L"Scancode Map"; unsigned char buf[32768]; DWORD bufSize; HKEY hKey; @@ -528,11 +531,13 @@ static char *argbuf; static void process_command_line() { - char *cmdline; + WCHAR *wcmdline; + char cmdline[2048]; int argc_max; int i, q; - cmdline = GetCommandLine(); + wcmdline = GetCommandLine(); + wcstombs(cmdline, wcmdline, (wcslen(wcmdline) << 1) + 2); i = strlen(cmdline) + 1; argbuf = malloc(i); memcpy(argbuf, cmdline, i); @@ -753,6 +758,20 @@ void update_status_bar_icon_state(int tag, int state) if (found != -1) { + if (state) + { + switch(tag & 0xf0) + { + case 0x00: + default: + discfns[tag & 0x0f][0] = L'\0'; + break; + case 0x10: + cdrom_iso[tag & 0x0f].iso_path[0] = L'\0'; + break; + } + } + sb_icon_flags[found] &= ~256; sb_icon_flags[found] |= state ? 256 : 0; @@ -765,59 +784,53 @@ void update_status_bar_icon_state(int tag, int state) } } -char sbTips[24][512]; +WCHAR sbTips[24][512]; void create_floppy_tip(int part) { WCHAR *szText; - char ansi_text[2][512]; + WCHAR wtext[512]; int drive = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2179); - wcstombs(ansi_text[0], szText, (wcslen(szText) << 1) + 2); - szText = (WCHAR *) win_language_get_string_from_id(2185); - wcstombs(ansi_text[1], szText, (wcslen(szText) << 1) + 2); - if (strlen(discfns[drive]) == 0) + + mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); + if (wcslen(discfns[drive]) == 0) { - sprintf(sbTips[part], ansi_text[0], drive + 1, fdd_getname(fdd_get_type(drive)), ansi_text[1]); + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); } else { - sprintf(sbTips[part], ansi_text[0], drive + 1, fdd_getname(fdd_get_type(drive)), discfns[drive]); + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); } } void create_cdrom_tip(int part) { WCHAR *szText; - char ansi_text[4][512]; + char ansi_text[3][512]; + WCHAR wtext[512]; int drive = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2180); - wcstombs(ansi_text[0], szText, (wcslen(szText) << 1) + 2); - szText = (WCHAR *) win_language_get_string_from_id(2185); - wcstombs(ansi_text[1], szText, (wcslen(szText) << 1) + 2); - szText = (WCHAR *) win_language_get_string_from_id(2186); - wcstombs(ansi_text[2], szText, (wcslen(szText) << 1) + 2); + if (cdrom_drives[drive].host_drive == 200) { - if (strlen(cdrom_iso[drive].iso_path) == 0) + if (wcslen(cdrom_iso[drive].iso_path) == 0) { - sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[1]); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - sprintf(sbTips[part], ansi_text[0], drive + 1, cdrom_iso[drive].iso_path); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_iso[drive].iso_path); } } else if (cdrom_drives[drive].host_drive < 0x41) { - sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[1]); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - sprintf(ansi_text[3], ansi_text[2], cdrom_drives[drive].host_drive & ~0x20); - sprintf(sbTips[part], ansi_text[0], drive + 1, ansi_text[3]); + _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); } } @@ -827,7 +840,7 @@ void create_hd_tip(int part) int bus = sb_part_meanings[part] & 0xf; szText = (WCHAR *) win_language_get_string_from_id(2182 + bus); - wcstombs(sbTips[part], szText, (wcslen(szText) << 1) + 2); + memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); } void update_tip(int meaning) @@ -866,7 +879,7 @@ void update_tip(int meaning) static int get_floppy_state(int id) { - return (strlen(discfns[id]) == 0) ? 1 : 0; + return (wcslen(discfns[id]) == 0) ? 1 : 0; } static int get_cd_state(int id) @@ -879,7 +892,7 @@ static int get_cd_state(int id) { if (cdrom_drives[id].host_drive == 0x200) { - return (strlen(cdrom_iso[id].iso_path) == 0) ? 1 : 0; + return (wcslen(cdrom_iso[id].iso_path) == 0) ? 1 : 0; } else { @@ -962,7 +975,7 @@ void update_status_bar_panes(HWND hwnds) { case 0x00: /* Floppy */ - sb_icon_flags[i] = (strlen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; create_floppy_tip(i); break; @@ -977,7 +990,7 @@ void update_status_bar_panes(HWND hwnds) { if (cdrom_drives[id].host_drive == 0x200) { - sb_icon_flags[i] = (strlen(cdrom_iso[id].iso_path) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(cdrom_iso[id].iso_path) == 0) ? 256 : 0; } else { @@ -1002,7 +1015,7 @@ void update_status_bar_panes(HWND hwnds) break; case 0x30: /* Status text */ - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) "Hello from 86Box UX lab! :p"); + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); sb_part_icons[i] = -1; break; } @@ -1088,7 +1101,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, MSG messages; /* Here messages to the application are saved */ WNDCLASSEX wincl; /* Data structure for the windowclass */ int c, d, e, bRet; - char emulator_title[200]; + WCHAR emulator_title[200]; LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ @@ -1105,8 +1118,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, wincl.cbSize = sizeof (WNDCLASSEX); /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(hinstance, (LPCSTR) 100); - wincl.hIconSm = LoadIcon(hinstance, (LPCSTR) 100); + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); wincl.hCursor = NULL; wincl.lpszMenuName = NULL; /* No menu */ wincl.cbClsExtra = 0; /* No extra bytes after the window class */ @@ -1126,7 +1139,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - sprintf(emulator_title, "86Box v%s", emulator_version); + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( @@ -1148,7 +1161,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, ShowWindow (hwnd, nFunsterStil); /* Load the accelerator table */ - haccel = LoadAccelerators(hinstAcc, "MainAccel"); + haccel = LoadAccelerators(hinstAcc, L"MainAccel"); if (haccel == NULL) fatal("haccel is null\n"); @@ -1169,7 +1182,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, initpc(argc, argv); - hwndRender = CreateWindow("STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); @@ -1622,7 +1635,7 @@ static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA void about_open(HWND hwnd) { - DialogBox(hinstance, (LPCSTR) ABOUTDLG, hwnd, about_dlgproc); + DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -2127,7 +2140,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR RECT rc; POINT pt; - char temp_iso_path[1024]; + WCHAR temp_iso_path[1024]; int new_cdrom_drive; int cdrom_id = 0; int menu_sub_param = 0; @@ -2142,11 +2155,12 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { case IDM_DISC_1: case IDM_DISC_1_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[0], 0)) { disc_close(0); ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, openfilestring); + msgbox_info_wstr(ghwnd, wopenfilestring); + disc_load(0, wopenfilestring); update_status_bar_icon_state(0x00, 0); update_tip(0x00); saveconfig(); @@ -2154,11 +2168,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_2: case IDM_DISC_2_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[1], 0)) { disc_close(1); ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, openfilestring); + disc_load(1, wopenfilestring); update_status_bar_icon_state(0x01, 0); update_tip(0x01); saveconfig(); @@ -2166,11 +2180,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_3: case IDM_DISC_3_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[2], 0)) { disc_close(2); ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, openfilestring); + disc_load(2, wopenfilestring); update_status_bar_icon_state(0x02, 0); update_tip(0x02); saveconfig(); @@ -2178,11 +2192,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_4: case IDM_DISC_4_WP: - if (!file_dlg_st(hwnd, 2173, discfns[0], 0)) + if (!file_dlg_w_st(hwnd, 2173, discfns[3], 0)) { disc_close(3); ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, openfilestring); + disc_load(3, wopenfilestring); update_status_bar_icon_state(0x03, 0); update_tip(0x03); saveconfig(); @@ -2250,11 +2264,11 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR case IDM_CDROM_4_ISO: cdrom_id = LOWORD(wParam) & 3; hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_st(hwnd, 2175, cdrom_iso[cdrom_id].iso_path, 0)) + if (!file_dlg_w_st(hwnd, 2175, cdrom_iso[cdrom_id].iso_path, 0)) { cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - strcpy(temp_iso_path, openfilestring); - if ((strcmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + wcscpy(temp_iso_path, wopenfilestring); + if ((wcscmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) { /* Switching from ISO to the same ISO. Do nothing. */ break; diff --git a/src/win.h b/src/win.h index 17316c27a..d49689a15 100644 --- a/src/win.h +++ b/src/win.h @@ -9,9 +9,9 @@ extern int mousecapture; extern "C" { #endif -#define szClassName "86BoxMainWnd" -#define szSubClassName "86BoxSubWnd" -#define szStatusBarClassName "86BoxStatusBar" +#define szClassName L"86BoxMainWnd" +#define szSubClassName L"86BoxSubWnd" +#define szStatusBarClassName L"86BoxStatusBar" void leave_fullscreen(); @@ -28,12 +28,13 @@ void deviceconfig_open(HWND hwnd, struct device_t *device); void joystickconfig_open(HWND hwnd, int joy_nr, int type); extern char openfilestring[260]; +extern WCHAR wopenfilestring[260]; int getfile(HWND hwnd, char *f, char *fn); int getsfile(HWND hwnd, char *f, char *fn); void get_executable_name(char *s, int size); -void set_window_title(char *s); +void set_window_title(WCHAR *s); void startblit(); void endblit(); From c403855a94b79f6c2d38864d81aff9aba5b5fa63 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 May 2017 04:02:03 +0200 Subject: [PATCH 159/392] The emulator is now almost completely Unicode - this means all paths and file names used can now use non-Latin characters; Fixed several NVR- and ROM-related bugs in the process of doing the above. --- src/config.c | 38 ++++-- src/config.h | 9 +- src/disc_86f.c | 4 +- src/hdd_esdi.c | 4 +- src/ibm.h | 11 +- src/intel_flash.c | 64 ++++------ src/mem.c | 275 ++++++++++++++++-------------------------- src/mem.h | 2 - src/mfm_xebec.c | 8 +- src/ne2000.c | 6 +- src/nvr.c | 242 +++++++++++++++++-------------------- src/pc.c | 71 ++++++----- src/ps1.c | 8 +- src/ps2_nvr.c | 6 +- src/rom.c | 46 ++++--- src/rom.h | 9 +- src/scsi_aha154x.c | 10 +- src/sound_adlibgold.c | 4 +- src/sound_emu8k.c | 2 +- src/sound_sb.c | 2 +- src/tandy_eeprom.c | 10 +- src/tandy_rom.c | 5 +- src/vid_ati18800.c | 6 +- src/vid_ati28800.c | 18 +-- src/vid_ati_eeprom.c | 10 +- src/vid_ati_eeprom.h | 4 +- src/vid_ati_mach64.c | 12 +- src/vid_cl_gd.c | 38 +++--- src/vid_ega.c | 12 +- src/vid_et4000.c | 4 +- src/vid_et4000w32.c | 4 +- src/vid_genius.c | 3 +- src/vid_nv_riva128.c | 16 +-- src/vid_oti067.c | 42 +------ src/vid_paradise.c | 36 +----- src/vid_pc1640.c | 2 +- src/vid_s3.c | 30 ++--- src/vid_s3_virge.c | 12 +- src/vid_tgui9440.c | 4 +- src/vid_tvga.c | 4 +- src/vid_vga.c | 45 +------ src/vid_voodoo.c | 5 +- src/vid_wy700.c | 1 - src/video.c | 4 +- src/video.h | 2 +- src/win.c | 36 +++--- src/win.h | 2 +- src/xtide.c | 16 +-- 48 files changed, 524 insertions(+), 680 deletions(-) diff --git a/src/config.c b/src/config.c index 20f40e197..55b4fec72 100644 --- a/src/config.c +++ b/src/config.c @@ -8,9 +8,9 @@ #include "config.h" #include "ibm.h" -char config_file_default[256]; +wchar_t config_file_default[256]; -static char config_file[256]; +static wchar_t config_file[256]; typedef struct list_t { @@ -100,9 +100,9 @@ void config_free() } } -void config_load(char *fn) +void config_load(wchar_t *fn) { - FILE *f = fopen(fn, "rt, ccs=UNICODE"); + FILE *f = _wfopen(fn, L"rt, ccs=UNICODE"); section_t *current_section; memset(&config_head, 0, sizeof(list_t)); @@ -200,7 +200,7 @@ void config_load(char *fn) void config_new() { - FILE *f = fopen(config_file, "wt, ccs=UNICODE"); + FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); fclose(f); } @@ -386,11 +386,28 @@ char *get_filename(char *s) return s; } +wchar_t *get_filename_w(wchar_t *s) +{ + int c = wcslen(s) - 1; + while (c > 0) + { + if (s[c] == L'/' || s[c] == L'\\') + return &s[c+1]; + c--; + } + return s; +} + void append_filename(char *dest, char *s1, char *s2, int size) { sprintf(dest, "%s%s", s1, s2); } +void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size) +{ + _swprintf(dest, L"%s%s", s1, s2); +} + void put_backslash(char *s) { int c = strlen(s) - 1; @@ -398,6 +415,13 @@ void put_backslash(char *s) s[c] = '/'; } +void put_backslash_w(wchar_t *s) +{ + int c = wcslen(s) - 1; + if (s[c] != L'/' && s[c] != L'\\') + s[c] = L'/'; +} + char *get_extension(char *s) { int c = strlen(s) - 1; @@ -432,9 +456,9 @@ wchar_t *get_extension_w(wchar_t *s) static wchar_t wname[512]; -void config_save(char *fn) +void config_save(wchar_t *fn) { - FILE *f = fopen(fn, "wt, ccs=UNICODE"); + FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); section_t *current_section; current_section = (section_t *)config_head.next; diff --git a/src/config.h b/src/config.h index 6fb3c8a2f..b51585b52 100644 --- a/src/config.h +++ b/src/config.h @@ -9,14 +9,17 @@ void config_set_string(char *head, char *name, char *val); void config_set_wstring(char *head, char *name, wchar_t *val); char *get_filename(char *s); +wchar_t *get_filename_w(wchar_t *s); void append_filename(char *dest, char *s1, char *s2, int size); +void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); void put_backslash(char *s); +void put_backslash_w(wchar_t *s); char *get_extension(char *s); wchar_t *get_extension_w(wchar_t *s); -void config_load(char *fn); -void config_save(char *fn); +void config_load(wchar_t *fn); +void config_save(wchar_t *fn); void config_dump(); void config_free(); -extern char config_file_default[256]; +extern wchar_t config_file_default[256]; diff --git a/src/disc_86f.c b/src/disc_86f.c index 892696304..10f4ff486 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -3134,7 +3134,7 @@ void d86f_load(int drive, wchar_t *fn) if (d86f[drive].is_compressed) { - memcpy(temp_file_name, drive ? L"TEMP$$$1.$$$" : L"TEMP$$$0.$$$", 256); + memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 256); memcpy(d86f[drive].original_file_name, fn, (wcslen(fn) << 1) + 2); fclose(d86f[drive].f); @@ -3322,7 +3322,7 @@ void d86f_close(int drive) { wchar_t temp_file_name[2048]; - memcpy(temp_file_name, drive ? "TEMP$$$1.$$$" : "TEMP$$$0.$$$", 26); + memcpy(temp_file_name, drive ? nvr_concat(L"TEMP$$$1.$$$") : nvr_concat(L"TEMP$$$0.$$$"), 26); if (d86f[drive].f) fclose(d86f[drive].f); diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 5afe4ff10..707e0d1b6 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -842,7 +842,7 @@ static void *esdi_init() esdi_t *esdi = malloc(sizeof(esdi_t)); memset(esdi, 0, sizeof(esdi_t)); - rom_init_interleaved(&esdi->bios_rom, "roms/90x8970.bin", "roms/90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init_interleaved(&esdi->bios_rom, L"roms/90x8970.bin", L"roms/90x8969.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); mem_mapping_disable(&esdi->bios_rom.mapping); for (i = 0; i < HDC_NUM; i++) @@ -882,7 +882,7 @@ static void esdi_close(void *p) static int esdi_available() { - return rom_present("roms/90x8969.bin") && rom_present("roms/90x8970.bin"); + return rom_present(L"roms/90x8969.bin") && rom_present(L"roms/90x8970.bin"); } device_t hdd_esdi_device = diff --git a/src/ibm.h b/src/ibm.h index 9d06e631b..5898a8b2d 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -52,7 +52,6 @@ void outw(uint16_t port, uint16_t val); uint32_t inl(uint16_t port); void outl(uint16_t port, uint32_t val); -FILE *romfopen(char *fn, char *mode); extern int shadowbios,shadowbios_write; extern int mem_size; extern int readlnum,writelnum; @@ -552,7 +551,7 @@ int gated,speakval,speakon; #define SND_WSS 9 /*Windows Sound System*/ #define SND_PAS16 10 /*Pro Audio Spectrum 16*/ -char pcempath[512]; +wchar_t pcempath[512]; /*Hard disc*/ @@ -676,7 +675,7 @@ uint64_t timer_read(); extern uint64_t timer_freq; -void loadconfig(char *fn); +void loadconfig(wchar_t *fn); extern int infocus; @@ -701,10 +700,10 @@ extern uint64_t star; #define FPU_CW_Reserved_Bits (0xe0c0) -extern char nvr_path[1024]; +extern wchar_t nvr_path[1024]; extern int path_len; -char *nvr_concat(char *to_concat); +wchar_t *nvr_concat(wchar_t *to_concat); int mem_a20_state; @@ -758,7 +757,7 @@ void execx86(int cycs); void flushmmucache(); void flushmmucache_cr3(); int idivl(int32_t val); -void initpc(int argc, char *argv[]); +void initpc(int argc, wchar_t *argv[]); void loadcscall(uint16_t seg); void loadcsjmp(uint16_t seg, uint32_t oxpc); void mmu_invalidate(uint32_t addr); diff --git a/src/intel_flash.c b/src/intel_flash.c index 39d40ec7d..dae940086 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -2,6 +2,7 @@ #include "ibm.h" #include "device.h" #include "mem.h" +#include "rom.h" #define FLASH_IS_BXB 2 #define FLASH_INVERT 1 @@ -34,7 +35,7 @@ typedef struct flash_t uint8_t array[131072]; } flash_t; -static char flash_path[1024]; +static wchar_t flash_path[1024]; static uint8_t flash_read(uint32_t addr, void *p) { @@ -150,7 +151,6 @@ static void intel_flash_add_mappings_inverted(flash_t *flash) void *intel_flash_init(uint8_t type) { FILE *f; - char fpath[1024]; int i; flash_t *flash; flash = malloc(sizeof(flash_t)); @@ -159,74 +159,64 @@ void *intel_flash_init(uint8_t type) switch(romset) { case ROM_REVENGE: - strcpy(flash_path, "roms/revenge/"); + wcscpy(flash_path, nvr_concat(L"revenge.bin")); break; case ROM_586MC1: - strcpy(flash_path, "roms/586mc1/"); + wcscpy(flash_path, nvr_concat(L"586mc1.bin")); break; case ROM_PLATO: - strcpy(flash_path, "roms/plato/"); + wcscpy(flash_path, nvr_concat(L"plato.bin")); break; case ROM_ENDEAVOR: - strcpy(flash_path, "roms/endeavor/"); + wcscpy(flash_path, nvr_concat(L"endeavor.bin")); break; case ROM_MB500N: - strcpy(flash_path, "roms/mb500n/"); + wcscpy(flash_path, nvr_concat(L"mb500n.bin")); break; -#if 0 - case ROM_POWERMATE_V: - strcpy(flash_path, "roms/powermate_v/"); - break; -#endif case ROM_P54TP4XE: - strcpy(flash_path, "roms/p54tp4xe/"); + wcscpy(flash_path, nvr_concat(L"p54tp4xe.bin")); break; case ROM_AP53: - strcpy(flash_path, "roms/ap53/"); + wcscpy(flash_path, nvr_concat(L"ap53.bin")); break; case ROM_P55T2S: - strcpy(flash_path, "roms/p55t2s/"); + wcscpy(flash_path, nvr_concat(L"p55t2s.bin")); break; case ROM_ACERM3A: - strcpy(flash_path, "roms/acerm3a/"); + wcscpy(flash_path, nvr_concat(L"acerm3a.bin")); break; case ROM_ACERV35N: - strcpy(flash_path, "roms/acerv35n/"); + wcscpy(flash_path, nvr_concat(L"acerv35n.bin")); break; case ROM_430VX: - strcpy(flash_path, "roms/430vx/"); + wcscpy(flash_path, nvr_concat(L"430vx.bin")); break; case ROM_P55VA: - strcpy(flash_path, "roms/p55va/"); + wcscpy(flash_path, nvr_concat(L"p55va.bin")); break; case ROM_P55T2P4: - strcpy(flash_path, "roms/p55t2p4/"); + wcscpy(flash_path, nvr_concat(L"p55t2p4.bin")); break; case ROM_P55TVP4: - strcpy(flash_path, "roms/p55tvp4/"); + wcscpy(flash_path, nvr_concat(L"p55tvp4.bin")); break; case ROM_440FX: - strcpy(flash_path, "roms/440fx/"); + wcscpy(flash_path, nvr_concat(L"440fx.bin")); break; -#if 0 - case ROM_MARL: - strcpy(flash_path, "roms/marl/"); - break; -#endif case ROM_THOR: - strcpy(flash_path, "roms/thor/"); + wcscpy(flash_path, nvr_concat(L"thor.bin")); break; case ROM_MRTHOR: - strcpy(flash_path, "roms/mrthor/"); + wcscpy(flash_path, nvr_concat(L"mrthor.bin")); break; case ROM_ZAPPA: - strcpy(flash_path, "roms/zappa/"); + wcscpy(flash_path, nvr_concat(L"zappa.bin")); break; case ROM_S1668: - strcpy(flash_path, "roms/tpatx/"); + wcscpy(flash_path, nvr_concat(L"tpatx.bin")); break; default: - fatal("intel_flash_init on unsupported ROM set %i\n", romset); + fatal("intel_flash_init on unsupported ROM set %i\n", romset); } flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; @@ -289,9 +279,7 @@ void *intel_flash_init(uint8_t type) flash->command = CMD_READ_ARRAY; flash->status = 0; - strcpy(fpath, flash_path); - strcat(fpath, "flash.bin"); - f = romfopen(fpath, "rb"); + f = nvrfopen(flash_path, L"rb"); if (f) { fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); @@ -331,11 +319,7 @@ void intel_flash_close(void *p) FILE *f; flash_t *flash = (flash_t *)p; - char fpath[1024]; - - strcpy(fpath, flash_path); - strcat(fpath, "flash.bin"); - f = romfopen(fpath, "wb"); + f = nvrfopen(flash_path, L"wb"); fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); fwrite(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); fwrite(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); diff --git a/src/mem.c b/src/mem.c index a48b6217d..59b94136e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -68,7 +68,7 @@ uint32_t ram_mapped_addr[64]; static void mem_load_atide115_bios() { FILE *f; - f=romfopen("roms/ide_at_1_1_5.bin","rb"); + f=romfopen(L"roms/ide_at_1_1_5.bin",L"rb"); if (f) { @@ -83,8 +83,8 @@ int loadbios() FILE *f=NULL,*ff=NULL; int c; - loadfont("roms/mda.rom", 0); - loadfont("roms/wy700.rom", 3); + loadfont(L"roms/mda.rom", 0); + loadfont(L"roms/wy700.rom", 3); biosmask = 0xffff; @@ -98,8 +98,8 @@ int loadbios() switch (romset) { case ROM_PC1512: - f=romfopen("roms/pc1512/40043.v1","rb"); - ff=romfopen("roms/pc1512/40044.v1","rb"); + f=romfopen(L"roms/pc1512/40043.v1",L"rb"); + ff=romfopen(L"roms/pc1512/40044.v1",L"rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -108,11 +108,11 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("roms/pc1512/40078.ic127", 2); + loadfont(L"roms/pc1512/40078.ic127", 2); return 1; case ROM_PC1640: - f=romfopen("roms/pc1640/40044.v3","rb"); - ff=romfopen("roms/pc1640/40043.v3","rb"); + f=romfopen(L"roms/pc1640/40044.v3",L"rb"); + ff=romfopen(L"roms/pc1640/40043.v3",L"rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -121,13 +121,13 @@ int loadbios() } fclose(ff); fclose(f); - f=romfopen("roms/pc1640/40100","rb"); + f=romfopen(L"roms/pc1640/40100",L"rb"); if (!f) break; fclose(f); return 1; case ROM_PC200: - f=romfopen("roms/pc200/pc20v2.1","rb"); - ff=romfopen("roms/pc200/pc20v2.0","rb"); + f=romfopen(L"roms/pc200/pc20v2.1",L"rb"); + ff=romfopen(L"roms/pc200/pc20v2.0",L"rb"); if (!f || !ff) break; for (c=0xC000;c<0x10000;c+=2) { @@ -136,24 +136,24 @@ int loadbios() } fclose(ff); fclose(f); - loadfont("roms/pc200/40109.bin", 1); + loadfont(L"roms/pc200/40109.bin", 1); return 1; case ROM_TANDY: - f=romfopen("roms/tandy/tandy1t1.020","rb"); + f=romfopen(L"roms/tandy/tandy1t1.020",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_TANDY1000HX: - f = romfopen("roms/tandy1000hx/v020000.u12", "rb"); + f = romfopen(L"roms/tandy1000hx/v020000.u12", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; case ROM_TANDY1000SL2: - f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); - ff = romfopen("roms/tandy1000sl2/8079048.hu2","rb"); + f = romfopen(L"roms/tandy1000sl2/8079047.hu1" ,L"rb"); + ff = romfopen(L"roms/tandy1000sl2/8079048.hu2",L"rb"); if (!f || !ff) break; fseek(f, 0x30000/2, SEEK_SET); fseek(ff, 0x30000/2, SEEK_SET); @@ -165,20 +165,12 @@ int loadbios() fclose(ff); fclose(f); return 1; -/* case ROM_IBMPCJR: - f=fopen("pcjr/bios.rom","rb"); - fread(rom+0xE000,8192,1,f); - fclose(f); - f=fopen("pcjr/basic.rom","rb"); - fread(rom+0x6000,32768,1,f); - fclose(f); - break;*/ case ROM_IBMXT: - f=romfopen("roms/ibmxt/xt.rom","rb"); + f=romfopen(L"roms/ibmxt/xt.rom",L"rb"); if (!f) { - f = romfopen("roms/ibmxt/5000027.u19", "rb"); - ff = romfopen("roms/ibmxt/1501512.u18","rb"); + f = romfopen(L"roms/ibmxt/5000027.u19", L"rb"); + ff = romfopen(L"roms/ibmxt/1501512.u18", L"rb"); if (!f || !ff) break; fread(rom, 0x8000, 1, f); fread(rom + 0x8000, 0x8000, 1, ff); @@ -195,22 +187,22 @@ int loadbios() break; case ROM_IBMPCJR: - f = romfopen("roms/ibmpcjr/bios.rom","rb"); + f = romfopen(L"roms/ibmpcjr/bios.rom", L"rb"); if (!f) break; fread(rom, 0x10000, 1, f); fclose(f); return 1; case ROM_PORTABLE: - f=romfopen("roms/portable/Compaq Portable Plus 100666-001 Rev C u47.bin","rb"); + f=romfopen(L"roms/portable/Compaq Portable Plus 100666-001 Rev C u47.bin",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_PORTABLEII: - f = romfopen("roms/portableii/62x0820.u27", "rb"); - ff =romfopen("roms/portableii/62x0821.u47", "rb"); + f = romfopen(L"roms/portableii/62x0820.u27", L"rb"); + ff =romfopen(L"roms/portableii/62x0821.u47", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -222,9 +214,9 @@ int loadbios() return 1; case ROM_PORTABLEIII: - case ROM_PORTABLEIII386: - f = romfopen("roms/portableiii/62x0820.u27", "rb"); - ff =romfopen("roms/portableiii/62x0821.u47", "rb"); + case ROM_PORTABLEIII386: + f = romfopen(L"roms/portableiii/62x0820.u27", L"rb"); + ff =romfopen(L"roms/portableiii/62x0821.u47", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -236,20 +228,20 @@ int loadbios() return 1; case ROM_GENXT: - f=romfopen("roms/genxt/pcxt.rom","rb"); + f=romfopen(L"roms/genxt/pcxt.rom",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_DTKXT: - f=romfopen("roms/dtk/DTK_ERSO_2.42_2764.bin","rb"); + f=romfopen(L"roms/dtk/DTK_ERSO_2.42_2764.bin",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); return 1; case ROM_OLIM24: - f = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,"rb"); - ff = romfopen("roms/olivetti_m24/olivetti_m24_version_1.43_high.bin","rb"); + f = romfopen(L"roms/olivetti_m24/olivetti_m24_version_1.43_low.bin" ,L"rb"); + ff = romfopen(L"roms/olivetti_m24/olivetti_m24_version_1.43_high.bin",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x4000; c += 2) { @@ -261,8 +253,8 @@ int loadbios() return 1; case ROM_PC2086: - f = romfopen("roms/pc2086/40179.ic129" ,"rb"); - ff = romfopen("roms/pc2086/40180.ic132","rb"); + f = romfopen(L"roms/pc2086/40179.ic129" ,L"rb"); + ff = romfopen(L"roms/pc2086/40180.ic132",L"rb"); if (!f || !ff) break; pclog("Loading BIOS\n"); for (c = 0x0000; c < 0x4000; c += 2) @@ -273,32 +265,26 @@ int loadbios() pclog("%02X %02X %02X\n", rom[0xfff0], rom[0xfff1], rom[0xfff2]); fclose(ff); fclose(f); - f = romfopen("roms/pc2086/40186.ic171", "rb"); + f = romfopen(L"roms/pc2086/40186.ic171", L"rb"); if (!f) break; fclose(f); biosmask = 0x3fff; return 1; case ROM_PC3086: - f = romfopen("roms/pc3086/fc00.bin" ,"rb"); + f = romfopen(L"roms/pc3086/fc00.bin", L"rb"); if (!f) break; fread(rom, 0x4000, 1, f); fclose(f); - f = romfopen("roms/pc3086/c000.bin", "rb"); + f = romfopen(L"roms/pc3086/c000.bin", L"rb"); if (!f) break; fclose(f); biosmask = 0x3fff; return 1; case ROM_IBMAT: -/* f=romfopen("roms/AMIC206.BIN","rb"); - if (!f) break; - fread(rom,65536,1,f); - fclose(f); - return 1;*/ - case ROM_IBMAT386: - f = romfopen("roms/ibmat/62x0820.u27", "rb"); - ff =romfopen("roms/ibmat/62x0821.u47", "rb"); + f = romfopen(L"roms/ibmat/62x0820.u27", L"rb"); + ff =romfopen(L"roms/ibmat/62x0821.u47", L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -309,8 +295,8 @@ int loadbios() fclose(f); return 1; case ROM_CMDPC30: - f = romfopen("roms/cmdpc30/commodore pc 30 iii even.bin", "rb"); - ff = romfopen("roms/cmdpc30/commodore pc 30 iii odd.bin", "rb"); + f = romfopen(L"roms/cmdpc30/commodore pc 30 iii even.bin", L"rb"); + ff = romfopen(L"roms/cmdpc30/commodore pc 30 iii odd.bin", L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x8000; c += 2) { @@ -321,24 +307,9 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; -#if 0 - case ROM_CMDPC60: - f = romfopen("roms/cmdpc60/cbm-pc60c-bios-lo-v1.36-390473-07.bin", "rb"); - ff = romfopen("roms/cmdpc60/cbm-pc60c-bios-hi-v1.36-390474-07.bin", "rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x20000; c += 2) - { - rom[c] = getc(f); - rom[c + 1] = getc(ff); - } - fclose(ff); - fclose(f); - biosmask = 0x1ffff; - return 1; -#endif case ROM_DELL200: - f=romfopen("roms/dells200/dell0.bin","rb"); - ff=romfopen("roms/dells200/dell1.bin","rb"); + f=romfopen(L"roms/dells200/dell0.bin",L"rb"); + ff=romfopen(L"roms/dells200/dell1.bin",L"rb"); if (!f || !ff) break; for (c=0x0000;c<0x10000;c+=2) { @@ -348,85 +319,65 @@ int loadbios() fclose(ff); fclose(f); return 1; -/* case ROM_IBMAT386: - f=romfopen("roms/at386/at386.bin","rb"); - if (!f) break; - fread(rom,65536,1,f); - fclose(f); - return 1;*/ case ROM_AMI386SX: - f=romfopen("roms/ami386/ami386.bin","rb"); + f=romfopen(L"roms/ami386/ami386.bin",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_AMI386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f=romfopen("roms/ami386dx/OPT495SX.AMI","rb"); + f=romfopen(L"roms/ami386dx/OPT495SX.AMI",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_MR386DX_OPTI495: /*This uses the OPTi 82C495 chipset*/ - f=romfopen("roms/mr386dx/OPT495SX.MR","rb"); + f=romfopen(L"roms/mr386dx/OPT495SX.MR",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; -#if 0 - case ROM_ACER386: - f=romfopen("roms/acer386/acer386.bin","rb"); - if (!f) break; - fread(rom,65536,1,f); - fclose(f); - rom[0xB0]=0xB0-0x51; - rom[0x40d4]=0x51; /*PUSH CX*/ - f=romfopen("roms/acer386/oti067.bin","rb"); - if (!f) break; - fclose(f); - return 1; -#endif - case ROM_AMI286: - f=romfopen("roms/ami286/amic206.bin","rb"); + f=romfopen(L"roms/ami286/amic206.bin",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_AWARD286: - f=romfopen("roms/award286/award.bin","rb"); + f=romfopen(L"roms/award286/award.bin",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; - case ROM_EUROPC: - f=romfopen("roms/europc/50145","rb"); + case ROM_EUROPC: + f=romfopen(L"roms/europc/50145",L"rb"); if (!f) break; fread(rom+0x8000,32768,1,f); fclose(f); return 1; case ROM_IBMPC: - f=romfopen("roms/ibmpc/pc102782.bin","rb"); + f=romfopen(L"roms/ibmpc/pc102782.bin",L"rb"); if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.f6","rb"); + f=romfopen(L"roms/ibmpc/basicc11.f6",L"rb"); if (!f) return 1; /*I don't really care if BASIC is there or not*/ fread(rom+0x6000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.f8","rb"); + f=romfopen(L"roms/ibmpc/basicc11.f8",L"rb"); if (!f) break; /*But if some of it is there, then all of it must be*/ fread(rom+0x8000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.fa","rb"); + f=romfopen(L"roms/ibmpc/basicc11.fa",L"rb"); if (!f) break; fread(rom+0xA000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.fc","rb"); + f=romfopen(L"roms/ibmpc/basicc11.fc",L"rb"); if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); @@ -434,8 +385,8 @@ int loadbios() case ROM_MEGAPC: case ROM_MEGAPCDX: - f = romfopen("roms/megapc/41651-bios lo.u18", "rb"); - ff = romfopen("roms/megapc/211253-bios hi.u19", "rb"); + f = romfopen(L"roms/megapc/41651-bios lo.u18", L"rb"); + ff = romfopen(L"roms/megapc/211253-bios hi.u19", L"rb"); if (!f || !ff) break; fseek(f, 0x8000, SEEK_SET); fseek(ff, 0x8000, SEEK_SET); @@ -449,22 +400,21 @@ int loadbios() return 1; case ROM_AMI486: - f=romfopen("roms/ami486/ami486.BIN","rb"); + f=romfopen(L"roms/ami486/ami486.BIN",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_WIN486: - f=romfopen("roms/win486/ALI1429G.AMW","rb"); + f=romfopen(L"roms/win486/ALI1429G.AMW",L"rb"); if (!f) break; fread(rom,65536,1,f); fclose(f); return 1; case ROM_SIS496: - /* f = romfopen("roms/sis496/SIS496-1.AWA", "rb"); */ - f = romfopen("roms/sis496/SIS496_3.AWA", "rb"); + f = romfopen(L"roms/sis496/SIS496_3.AWA", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -473,7 +423,7 @@ int loadbios() return 1; case ROM_430VX: - f = romfopen("roms/430vx/55XWUQ0E.BIN", "rb"); + f = romfopen(L"roms/430vx/55XWUQ0E.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -481,12 +431,12 @@ int loadbios() return 1; case ROM_REVENGE: - f = romfopen("roms/revenge/1009AF2_.BIO", "rb"); + f = romfopen(L"roms/revenge/1009AF2_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/revenge/1009AF2_.BI1", "rb"); + f = romfopen(L"roms/revenge/1009AF2_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xc000, 1, f); @@ -494,12 +444,12 @@ int loadbios() biosmask = 0x1ffff; return 1; case ROM_ENDEAVOR: - f = romfopen("roms/endeavor/1006CB0_.BIO", "rb"); + f = romfopen(L"roms/endeavor/1006CB0_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/endeavor/1006CB0_.BI1", "rb"); + f = romfopen(L"roms/endeavor/1006CB0_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xd000, 1, f); @@ -508,7 +458,7 @@ int loadbios() return 1; case ROM_IBMPS1_2011: - f = romfopen("roms/ibmps1es/f80000.bin", "rb"); + f = romfopen(L"roms/ibmps1es/f80000.bin", L"rb"); if (!f) break; fseek(f, 0x60000, SEEK_SET); fread(rom, 0x20000, 1, f); @@ -518,7 +468,7 @@ int loadbios() case ROM_IBMPS1_2121: case ROM_IBMPS1_2121_ISA: - f = romfopen("roms/ibmps1_2121/fc0000.bin", "rb"); + f = romfopen(L"roms/ibmps1_2121/fc0000.bin", L"rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); fread(rom, 0x20000, 1, f); @@ -531,8 +481,8 @@ int loadbios() return 1; case ROM_DESKPRO_386: - f=romfopen("roms/deskpro386/109592-005.U11.bin","rb"); - ff=romfopen("roms/deskpro386/109591-005.U13.bin","rb"); + f=romfopen(L"roms/deskpro386/109592-005.U11.bin",L"rb"); + ff=romfopen(L"roms/deskpro386/109591-005.U13.bin",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x8000; c += 2) { @@ -545,78 +495,63 @@ int loadbios() return 1; case ROM_AMIXT: - f = romfopen("roms/amixt/AMI_8088_BIOS_31JAN89.BIN", "rb"); + f = romfopen(L"roms/amixt/AMI_8088_BIOS_31JAN89.BIN", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_LTXT: - f = romfopen("roms/ltxt/27C64.bin", "rb"); + f = romfopen(L"roms/ltxt/27C64.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_LXT3: - f = romfopen("roms/lxt3/27C64D.bin", "rb"); + f = romfopen(L"roms/lxt3/27C64D.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_SPC4200P: /*Samsung SPC-4200P*/ - f = romfopen("roms/spc4200p/U8.01", "rb"); + f = romfopen(L"roms/spc4200p/U8.01", L"rb"); if (!f) break; fread(rom, 65536, 1, f); fclose(f); return 1; case ROM_SUPER286TR: /*Hyundai Super-286TR*/ - f = romfopen("roms/super286tr/hyundai_award286.bin", "rb"); + f = romfopen(L"roms/super286tr/hyundai_award286.bin", L"rb"); if (!f) break; fread(rom, 65536, 1, f); fclose(f); return 1; -#if 0 - case ROM_PX386: /*Phoenix 80386 BIOS*/ - f=romfopen("roms/px386/3iip001l.bin","rb"); - ff=romfopen("roms/px386/3iip001h.bin","rb"); - if (!f || !ff) break; - for (c = 0x0000; c < 0x10000; c += 2) - { - rom[c] = getc(f); - rom[c+1] = getc(ff); - } - fclose(ff); - fclose(f); - return 1; -#endif - case ROM_DTK386: /*Uses NEAT chipset*/ - f = romfopen("roms/dtk386/3cto001.bin", "rb"); + f = romfopen(L"roms/dtk386/3cto001.bin", L"rb"); if (!f) break; fread(rom, 65536, 1, f); fclose(f); return 1; case ROM_PXXT: - f = romfopen("roms/pxxt/000p001.bin", "rb"); + f = romfopen(L"roms/pxxt/000p001.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_JUKOPC: - f = romfopen("roms/jukopc/000o001.bin", "rb"); + f = romfopen(L"roms/jukopc/000o001.bin", L"rb"); if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); return 1; case ROM_IBMPS2_M30_286: - f = romfopen("roms/ibmps2_m30_286/33f5381a.bin", "rb"); + f = romfopen(L"roms/ibmps2_m30_286/33f5381a.bin", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -628,14 +563,14 @@ int loadbios() return 1; case ROM_DTK486: - f = romfopen("roms/dtk486/4siw005.bin", "rb"); + f = romfopen(L"roms/dtk486/4siw005.bin", L"rb"); if (!f) break; fread(rom, 0x10000, 1, f); fclose(f); return 1; case ROM_R418: - f = romfopen("roms/r418/r418i.bin", "rb"); + f = romfopen(L"roms/r418/r418i.bin", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -644,7 +579,7 @@ int loadbios() return 1; case ROM_586MC1: - f = romfopen("roms/586mc1/IS.34", "rb"); + f = romfopen(L"roms/586mc1/IS.34", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -652,12 +587,12 @@ int loadbios() return 1; case ROM_PLATO: - f = romfopen("roms/plato/1016AX1_.BIO", "rb"); + f = romfopen(L"roms/plato/1016AX1_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/plato/1016AX1_.BI1", "rb"); + f = romfopen(L"roms/plato/1016AX1_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0xd000, 1, f); @@ -666,7 +601,7 @@ int loadbios() return 1; case ROM_MB500N: - f = romfopen("roms/mb500n/031396S.BIN", "rb"); /* Works */ + f = romfopen(L"roms/mb500n/031396S.BIN", L"rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -674,7 +609,7 @@ int loadbios() return 1; case ROM_AP53: - f = romfopen("roms/ap53/AP53R2C0.ROM", "rb"); /* Works */ + f = romfopen(L"roms/ap53/AP53R2C0.ROM", L"rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -682,7 +617,7 @@ int loadbios() return 1; case ROM_P55T2S: - f = romfopen("roms/p55t2s/S6Y08T.ROM", "rb"); /* Works */ + f = romfopen(L"roms/p55t2s/S6Y08T.ROM", L"rb"); /* Works */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -690,7 +625,7 @@ int loadbios() return 1; case ROM_P54TP4XE: - f = romfopen("roms/p54tp4xe/T15I0302.AWD", "rb"); + f = romfopen(L"roms/p54tp4xe/T15I0302.AWD", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -698,7 +633,7 @@ int loadbios() return 1; case ROM_ACERM3A: - f = romfopen("roms/acerm3a/r01-b3.bin", "rb"); + f = romfopen(L"roms/acerm3a/r01-b3.bin", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -706,7 +641,7 @@ int loadbios() return 1; case ROM_ACERV35N: - f = romfopen("roms/acerv35n/V35ND1S1.BIN", "rb"); + f = romfopen(L"roms/acerv35n/V35ND1S1.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -714,7 +649,7 @@ int loadbios() return 1; case ROM_P55VA: - f = romfopen("roms/p55va/VA021297.BIN", "rb"); + f = romfopen(L"roms/p55va/VA021297.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -722,7 +657,7 @@ int loadbios() return 1; case ROM_P55T2P4: - f = romfopen("roms/p55t2p4/0207_J2.BIN", "rb"); + f = romfopen(L"roms/p55t2p4/0207_J2.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -730,7 +665,7 @@ int loadbios() return 1; case ROM_P55TVP4: - f = romfopen("roms/p55tvp4/TV5I0204.AWD", "rb"); + f = romfopen(L"roms/p55tvp4/TV5I0204.AWD", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -738,7 +673,7 @@ int loadbios() return 1; case ROM_440FX: - f = romfopen("roms/440fx/NTMAW501.BIN", "rb"); /* Working Tyan BIOS. */ + f = romfopen(L"roms/440fx/NTMAW501.BIN", L"rb"); /* Working Tyan BIOS. */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -746,7 +681,7 @@ int loadbios() return 1; case ROM_S1668: - f = romfopen("roms/tpatx/S1668P.ROM", "rb"); /* Working Tyan BIOS. */ + f = romfopen(L"roms/tpatx/S1668P.ROM", L"rb"); /* Working Tyan BIOS. */ if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -754,12 +689,12 @@ int loadbios() return 1; case ROM_THOR: - f = romfopen("roms/thor/1006CN0_.BIO", "rb"); + f = romfopen(L"roms/thor/1006CN0_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/thor/1006CN0_.BI1", "rb"); + f = romfopen(L"roms/thor/1006CN0_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0x10000, 1, f); @@ -768,7 +703,7 @@ int loadbios() return 1; case ROM_MRTHOR: - f = romfopen("roms/mrthor/MR_ATX.BIO", "rb"); + f = romfopen(L"roms/mrthor/MR_ATX.BIO", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); @@ -776,12 +711,12 @@ int loadbios() return 1; case ROM_ZAPPA: - f = romfopen("roms/zappa/1006BS0_.BIO", "rb"); + f = romfopen(L"roms/zappa/1006BS0_.BIO", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom + 0x10000, 0x10000, 1, f); fclose(f); - f = romfopen("roms/zappa/1006BS0_.BI1", "rb"); + f = romfopen(L"roms/zappa/1006BS0_.BI1", L"rb"); if (!f) break; fseek(f, 0x80, SEEK_SET); fread(rom, 0x10000, 1, f); @@ -790,8 +725,8 @@ int loadbios() return 1; case ROM_IBMPS2_M50: - f=romfopen("roms/i8550021/90x7423.zm14","rb"); - ff=romfopen("roms/i8550021/90x7426.zm16","rb"); + f=romfopen(L"roms/i8550021/90x7423.zm14",L"rb"); + ff=romfopen(L"roms/i8550021/90x7426.zm16",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x10000; c += 2) { @@ -800,8 +735,8 @@ int loadbios() } fclose(ff); fclose(f); - f=romfopen("roms/i8550021/90x7420.zm13","rb"); - ff=romfopen("roms/i8550021/90x7429.zm18","rb"); + f=romfopen(L"roms/i8550021/90x7420.zm13",L"rb"); + ff=romfopen(L"roms/i8550021/90x7429.zm18",L"rb"); if (!f || !ff) break; for (c = 0x10000; c < 0x20000; c += 2) { @@ -814,8 +749,8 @@ int loadbios() return 1; case ROM_IBMPS2_M55SX: - f=romfopen("roms/i8555081/33f8146.zm41","rb"); - ff=romfopen("roms/i8555081/33f8145.zm40","rb"); + f=romfopen(L"roms/i8555081/33f8146.zm41",L"rb"); + ff=romfopen(L"roms/i8555081/33f8145.zm40",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x20000; c += 2) { @@ -828,8 +763,8 @@ int loadbios() return 1; case ROM_IBMPS2_M80: - f=romfopen("roms/i8580111/15f6637.bin","rb"); - ff=romfopen("roms/i8580111/15f6639.bin","rb"); + f=romfopen(L"roms/i8580111/15f6637.bin",L"rb"); + ff=romfopen(L"roms/i8580111/15f6639.bin",L"rb"); if (!f || !ff) break; for (c = 0x0000; c < 0x20000; c += 2) { diff --git a/src/mem.h b/src/mem.h index 7e888e207..f4cef2a31 100644 --- a/src/mem.h +++ b/src/mem.h @@ -107,8 +107,6 @@ void mem_write_null(uint32_t addr, uint8_t val, void *p); void mem_write_nullw(uint32_t addr, uint16_t val, void *p); void mem_write_nulll(uint32_t addr, uint32_t val, void *p); -FILE *romfopen(char *fn, char *mode); - mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index 5459a75a7..fde48c45d 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -858,7 +858,7 @@ static void *xebec_init() xebec_set_switches(xebec); - rom_init(&xebec->bios_rom, "roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, L"roms/ibm_xebec_62x0822_1985.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); @@ -885,7 +885,7 @@ static void xebec_close(void *p) static int xebec_available() { - return rom_present("roms/ibm_xebec_62x0822_1985.bin"); + return rom_present(L"roms/ibm_xebec_62x0822_1985.bin"); } device_t mfm_xebec_device = @@ -923,7 +923,7 @@ static void *dtc_5150x_init() xebec->drives[1].cfg_cyl = xebec->drives[1].tracks; xebec->drives[1].cfg_hpc = xebec->drives[1].hpc; - rom_init(&xebec->bios_rom, "roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xebec->bios_rom, L"roms/dtc_cxd21a.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x0320, 0x0004, xebec_read, NULL, NULL, xebec_write, NULL, NULL, xebec); @@ -933,7 +933,7 @@ static void *dtc_5150x_init() } static int dtc_5150x_available() { - return rom_present("roms/dtc_cxd21a.bin"); + return rom_present(L"roms/dtc_cxd21a.bin"); } device_t dtc_5150x_device = diff --git a/src/ne2000.c b/src/ne2000.c index f67b3f0d4..a88f8ee45 100644 --- a/src/ne2000.c +++ b/src/ne2000.c @@ -1955,9 +1955,9 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p) } } -void ne2000_rom_init(ne2000_t *ne2000, char *s) +void ne2000_rom_init(ne2000_t *ne2000, wchar_t *s) { - FILE *f = fopen(s, "rb"); + FILE *f = romfopen(s, "rb"); uint32_t temp; if(!f) { @@ -2048,7 +2048,7 @@ void *ne2000_init() if (!disable_netbios) { - ne2000_rom_init(ne2000, "roms/ne2000.rom"); + ne2000_rom_init(ne2000, is_rtl8029as ? L"roms/rtl8029as.rom" : L"roms/ne2000.rom"); if (is_rtl8029as) { diff --git a/src/nvr.c b/src/nvr.c index 76c42e7d0..acfa6c4d7 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -1,8 +1,10 @@ #include #include "ibm.h" #include "io.h" +#include "mem.h" #include "nvr.h" #include "pic.h" +#include "rom.h" #include "timer.h" #include "rtc.h" @@ -190,72 +192,60 @@ void loadnvr() oldromset=romset; switch (romset) { - case ROM_PC1512: f = romfopen(nvr_concat("pc1512.nvr"), "rb"); break; - case ROM_PC1640: f = romfopen(nvr_concat("pc1640.nvr"), "rb"); break; - case ROM_PC200: f = romfopen(nvr_concat("pc200.nvr"), "rb"); break; - case ROM_PC2086: f = romfopen(nvr_concat("pc2086.nvr"), "rb"); break; - case ROM_PC3086: f = romfopen(nvr_concat("pc3086.nvr"), "rb"); break; - case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "rb"); break; - case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "rb"); break; - case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "rb"); break; - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "rb"); break; - case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "rb"); nvrmask = 127; break; - case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "rb"); break; - case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "rb"); break; - case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; - case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; - case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "rb"); nvrmask = 127; break; - case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "rb"); nvrmask = 127; break; - case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; - case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; - case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; - case ROM_PORTABLEIII386: f = romfopen(nvr_concat("portableiii386.nvr"), "rb"); break; - /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "rb"); nvrmask = 127; break; */ - case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "rb"); nvrmask = 127; break; - case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "rb"); nvrmask = 127; break; - case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "rb"); nvrmask = 127; break; - case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "rb"); nvrmask = 127; break; - case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "rb"); nvrmask = 127; break; - case ROM_PCI486: f = romfopen(nvr_concat("hot-433.nvr"), "rb"); nvrmask = 127; break; - case ROM_SIS496: f = romfopen(nvr_concat("sis496.nvr"), "rb"); nvrmask = 127; break; - case ROM_430VX: f = romfopen(nvr_concat("430vx.nvr"), "rb"); nvrmask = 127; break; - case ROM_REVENGE: f = romfopen(nvr_concat("revenge.nvr"), "rb"); nvrmask = 127; break; - case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "rb"); nvrmask = 127; break; - /* case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "rb"); nvrmask = 127; break; */ - case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "rb"); nvrmask = 127; break; - case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "rb"); nvrmask = 127; break; - case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "rb"); nvrmask = 127; break; - case ROM_DTK486: f = romfopen(nvr_concat("dtk486.nvr"), "rb"); nvrmask = 127; break; - case ROM_R418: f = romfopen(nvr_concat("r418.nvr"), "rb"); nvrmask = 127; break; - case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "rb"); nvrmask = 127; break; - case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "rb"); nvrmask = 127; break; - case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "rb"); nvrmask = 127; break; -#if 0 - case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "rb"); nvrmask = 127; break; -#endif - case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "rb"); nvrmask = 127; break; - case ROM_AP53: f = romfopen(nvr_concat("ap53.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55T2S: f = romfopen(nvr_concat("p55t2s.nvr"), "rb"); nvrmask = 127; break; - case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "rb"); nvrmask = 127; break; - case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "rb"); nvrmask = 127; break; - case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "rb"); nvrmask = 127; break; - case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "rb"); nvrmask = 127; break; -#if 0 - case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "rb"); nvrmask = 127; break; -#endif - case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "rb"); nvrmask = 127; break; - case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "rb"); nvrmask = 127; break; - case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "rb"); nvrmask = 127; break; -#if 0 - case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "rb"); nvrmask = 127; break; -#endif - case ROM_S1668: f = romfopen(nvr_concat("tpatx.nvr"), "rb"); nvrmask = 127; break; + case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"rb"); break; + case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"rb"); break; + case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"rb"); break; + case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"rb"); break; + case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"rb"); break; + case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"rb"); break; + case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"rb"); break; + case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"rb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"rb"); break; + case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"rb"); nvrmask = 127; break; + case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"rb"); break; + case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"rb"); break; + case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"rb"); nvrmask = 127; break; + case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"rb"); nvrmask = 127; break; + case ROM_DELL200: f = nvrfopen(L"dell200.nvr", L"rb"); nvrmask = 127; break; + case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"rb"); nvrmask = 127; break; + case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"rb"); nvrmask = 127; break; + case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"rb"); break; + case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"rb"); break; + case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"rb"); nvrmask = 127; break; + case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"rb"); nvrmask = 127; break; + case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"rb"); nvrmask = 127; break; + case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"rb"); nvrmask = 127; break; + case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"rb"); nvrmask = 127; break; + case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"rb"); nvrmask = 127; break; + case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"rb"); nvrmask = 127; break; + case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"rb"); nvrmask = 127; break; + case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"rb"); nvrmask = 127; break; + case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"rb"); nvrmask = 127; break; + case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"rb"); nvrmask = 127; break; + case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"rb"); nvrmask = 127; break; + case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"rb"); nvrmask = 127; break; + case ROM_R418: f = nvrfopen(L"r418.nvr", L"rb"); nvrmask = 127; break; + case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"rb"); nvrmask = 127; break; + case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"rb"); nvrmask = 127; break; + case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"rb"); nvrmask = 127; break; + case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"rb"); nvrmask = 127; break; + case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"rb"); nvrmask = 127; break; + case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"rb"); nvrmask = 127; break; + case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"rb"); nvrmask = 127; break; + case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"rb"); nvrmask = 127; break; + case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"rb"); nvrmask = 127; break; + case ROM_THOR: f = nvrfopen(L"thor.nvr", L"rb"); nvrmask = 127; break; + case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"rb"); nvrmask = 127; break; + case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"rb"); nvrmask = 127; break; + case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"rb"); nvrmask = 127; break; default: return; } if (!f) @@ -287,72 +277,60 @@ void savenvr() FILE *f; switch (oldromset) { - case ROM_PC1512: f = romfopen(nvr_concat("pc1512.nvr"), "wb"); break; - case ROM_PC1640: f = romfopen(nvr_concat("pc1640.nvr"), "wb"); break; - case ROM_PC200: f = romfopen(nvr_concat("pc200.nvr"), "wb"); break; - case ROM_PC2086: f = romfopen(nvr_concat("pc2086.nvr"), "wb"); break; - case ROM_PC3086: f = romfopen(nvr_concat("pc3086.nvr"), "wb"); break; - case ROM_IBMAT: f = romfopen(nvr_concat("at.nvr"), "wb"); break; - case ROM_IBMPS1_2011: f = romfopen(nvr_concat("ibmps1_2011.nvr"), "wb"); break; - case ROM_IBMPS1_2121: f = romfopen(nvr_concat("ibmps1_2121.nvr"), "wb"); break; - case ROM_IBMPS1_2121_ISA: f = romfopen(nvr_concat("ibmps1_2121_isa.nvr"), "wb"); break; - case ROM_IBMPS2_M30_286: f = romfopen(nvr_concat("ibmps2_m30_286.nvr"), "wb"); break; - case ROM_IBMPS2_M50: f = romfopen("nvr/ibmps2_m50.nvr", "wb"); break; - case ROM_IBMPS2_M55SX: f = romfopen("nvr/ibmps2_m55sx.nvr", "wb"); break; - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80.nvr", "wb"); break; - case ROM_CMDPC30: f = romfopen(nvr_concat("cmdpc30.nvr"), "wb"); break; - case ROM_PORTABLEII: f = romfopen(nvr_concat("portableii.nvr"), "wb"); break; - case ROM_PORTABLEIII: f = romfopen(nvr_concat("portableiii.nvr"), "wb"); break; - case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; - case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; - case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "wb"); break; - case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "wb"); break; - case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; - case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; - case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; - case ROM_PORTABLEIII386: f = romfopen(nvr_concat("portableiii386.nvr"), "wb"); break; - /* case ROM_ACER386: f = romfopen(nvr_concat("acer386.nvr"), "wb"); break; */ - case ROM_MEGAPC: f = romfopen(nvr_concat("megapc.nvr"), "wb"); break; - case ROM_MEGAPCDX: f = romfopen(nvr_concat("megapcdx.nvr"), "wb"); break; - case ROM_AMI386SX: f = romfopen(nvr_concat("ami386.nvr"), "wb"); break; - case ROM_AMI486: f = romfopen(nvr_concat("ami486.nvr"), "wb"); break; - case ROM_WIN486: f = romfopen(nvr_concat("win486.nvr"), "wb"); break; - case ROM_PCI486: f = romfopen(nvr_concat("hot-433.nvr"), "wb"); break; - case ROM_SIS496: f = romfopen(nvr_concat("sis496.nvr"), "wb"); break; - case ROM_430VX: f = romfopen(nvr_concat("430vx.nvr"), "wb"); break; - case ROM_REVENGE: f = romfopen(nvr_concat("revenge.nvr"), "wb"); break; - case ROM_ENDEAVOR: f = romfopen(nvr_concat("endeavor.nvr"), "wb"); break; - /* case ROM_PX386: f = romfopen(nvr_concat("px386.nvr"), "wb"); break; */ - case ROM_DTK386: f = romfopen(nvr_concat("dtk386.nvr"), "wb"); break; - case ROM_MR386DX_OPTI495: f = romfopen(nvr_concat("mr386dx_opti495.nvr"), "wb"); break; - case ROM_AMI386DX_OPTI495: f = romfopen(nvr_concat("ami386dx_opti495.nvr"), "wb"); break; - case ROM_DTK486: f = romfopen(nvr_concat("dtk486.nvr"), "wb"); break; - case ROM_R418: f = romfopen(nvr_concat("r418.nvr"), "wb"); break; - case ROM_586MC1: f = romfopen(nvr_concat("586mc1.nvr"), "wb"); break; - case ROM_PLATO: f = romfopen(nvr_concat("plato.nvr"), "wb"); break; - case ROM_MB500N: f = romfopen(nvr_concat("mb500n.nvr"), "wb"); break; -#if 0 - case ROM_POWERMATE_V: f = romfopen(nvr_concat("powermate_v.nvr"), "wb"); break; -#endif - case ROM_P54TP4XE: f = romfopen(nvr_concat("p54tp4xe.nvr"), "wb"); break; - case ROM_AP53: f = romfopen(nvr_concat("ap53.nvr"), "wb"); break; - case ROM_P55T2S: f = romfopen(nvr_concat("p55t2s.nvr"), "wb"); break; - case ROM_ACERM3A: f = romfopen(nvr_concat("acerm3a.nvr"), "wb"); break; - case ROM_ACERV35N: f = romfopen(nvr_concat("acerv35n.nvr"), "wb"); break; - case ROM_P55VA: f = romfopen(nvr_concat("p55va.nvr"), "wb"); break; - case ROM_P55T2P4: f = romfopen(nvr_concat("p55t2p4.nvr"), "wb"); break; - case ROM_P55TVP4: f = romfopen(nvr_concat("p55tvp4.nvr"), "wb"); break; - case ROM_440FX: f = romfopen(nvr_concat("440fx.nvr"), "wb"); break; -#if 0 - case ROM_MARL: f = romfopen(nvr_concat("marl.nvr"), "wb"); break; -#endif - case ROM_THOR: f = romfopen(nvr_concat("thor.nvr"), "wb"); break; - case ROM_MRTHOR: f = romfopen(nvr_concat("mrthor.nvr"), "wb"); break; - case ROM_ZAPPA: f = romfopen(nvr_concat("zappa.nvr"), "wb"); break; -#if 0 - case ROM_CMDPC60: f = romfopen(nvr_concat("cmdpc60.nvr"), "wb"); break; -#endif - case ROM_S1668: f = romfopen(nvr_concat("tpatx.nvr"), "wb"); break; + case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"wb"); break; + case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"wb"); break; + case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"wb"); break; + case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"wb"); break; + case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"wb"); break; + case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"wb"); break; + case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"wb"); break; + case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"wb"); break; + case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"wb"); break; + case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"wb"); break; + case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"wb"); break; + case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"wb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"wb"); break; + case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"wb"); break; + case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"wb"); break; + case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"wb"); break; + case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"wb"); break; + case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"wb"); break; + case ROM_DELL200: f = nvrfopen(L"dell200.nvr", L"wb"); break; + case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"wb"); break; + case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"wb"); break; + case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"wb"); break; + case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"wb"); break; + case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"wb"); break; + case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"wb"); break; + case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"wb"); break; + case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"wb"); break; + case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"wb"); break; + case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"wb"); break; + case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"wb"); break; + case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"wb"); break; + case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"wb"); break; + case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"wb"); break; + case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"wb"); break; + case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"wb"); break; + case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"wb"); break; + case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"wb"); break; + case ROM_R418: f = nvrfopen(L"r418.nvr", L"wb"); break; + case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"wb"); break; + case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"wb"); break; + case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"wb"); break; + case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"wb"); break; + case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"wb"); break; + case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"wb"); break; + case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"wb"); break; + case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"wb"); break; + case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"wb"); break; + case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"wb"); break; + case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"wb"); break; + case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"wb"); break; + case ROM_THOR: f = nvrfopen(L"thor.nvr", L"wb"); break; + case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"wb"); break; + case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"wb"); break; + case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/pc.c b/src/pc.c index d13a402e7..4f49e367d 100644 --- a/src/pc.c +++ b/src/pc.c @@ -76,7 +76,7 @@ uint8_t ethif; int inum; -char nvr_path[1024]; +wchar_t nvr_path[1024]; int path_len; int window_w, window_h, window_x, window_y, window_remember; @@ -261,21 +261,21 @@ void pc_reset() ali1429_reset(); } #undef printf -void initpc(int argc, char *argv[]) +void initpc(int argc, wchar_t *argv[]) { - char *p; - char *config_file = NULL; + wchar_t *p; + wchar_t *config_file = NULL; int c, i; FILE *ff; - get_executable_name(pcempath,511); - pclog("executable_name = %s\n", pcempath); - p=get_filename(pcempath); - *p=0; - pclog("path = %s\n", pcempath); + get_executable_name(pcempath, 511); + pclog("executable_name = %ws\n", pcempath); + p=get_filename_w(pcempath); + *p=L'\0'; + pclog("path = %ws\n", pcempath); for (c = 1; c < argc; c++) { - if (!strcasecmp(argv[c], "--help")) + if (!_wcsicmp(argv[c], L"--help")) { printf("PCem command line options :\n\n"); printf("--config file.cfg - use given config file as initial configuration\n"); @@ -283,22 +283,22 @@ void initpc(int argc, char *argv[]) printf("--fullscreen - start in fullscreen mode\n"); exit(-1); } - else if (!strcasecmp(argv[c], "--config")) + else if (!_wcsicmp(argv[c], L"--config")) { if ((c+1) == argc) break; config_file = argv[c+1]; c++; } - else if (!strcasecmp(argv[c], "--dump")) + else if (!_wcsicmp(argv[c], L"--dump")) { dump_on_exit = 1; } - else if (!strcasecmp(argv[c], "--fullscreen")) + else if (!_wcsicmp(argv[c], L"--fullscreen")) { start_in_fullscreen = 1; } - else if (!strcasecmp(argv[c], "--test")) + else if (!_wcsicmp(argv[c], L"--test")) { /* some (undocumented) test function here.. */ @@ -313,11 +313,11 @@ void initpc(int argc, char *argv[]) if (config_file == NULL) { - append_filename(config_file_default, pcempath, "86box.cfg", 511); + append_filename_w(config_file_default, pcempath, L"86box.cfg", 511); } else { - append_filename(config_file_default, pcempath, config_file, 511); + append_filename_w(config_file_default, pcempath, config_file, 511); } disc_random_init(); @@ -700,12 +700,12 @@ void closepc() END_OF_MAIN();*/ -void loadconfig(char *fn) +void loadconfig(wchar_t *fn) { int c, d; char s[512]; char *p; - WCHAR *wp; + WCHAR *wp, *wq; char temps[512]; if (!fn) @@ -919,20 +919,27 @@ void loadconfig(char *fn) } } - memset(nvr_path, 0, 1024); - p = (char *)config_get_string(NULL, "nvr_path", "nvr"); - if (p) { - if (strlen(p) <= 992) strcpy(nvr_path, p); - else strcpy(nvr_path, "nvr"); + memset(nvr_path, 0, 2048); + wp = (char *)config_get_wstring(NULL, "nvr_path", "nvr"); + if (wp) { + if (strlen(wp) <= 992) wcscpy(nvr_path, wp); + else + { + append_filename_w(nvr_path, pcempath, L"nvr", 511); + } } - else strcpy(nvr_path, "nvr"); + else append_filename_w(nvr_path, pcempath, L"nvr", 511); - if (nvr_path[strlen(nvr_path)] != '/') + if (nvr_path[wcslen(nvr_path) - 1] != L'/') { - nvr_path[strlen(nvr_path)] = '/'; + if (nvr_path[wcslen(nvr_path) - 1] != L'\\') + { + nvr_path[wcslen(nvr_path)] = L'/'; + nvr_path[wcslen(nvr_path) + 1] = L'\0'; + } } - path_len = strlen(nvr_path); + path_len = wcslen(nvr_path); serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); @@ -940,10 +947,14 @@ void loadconfig(char *fn) bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); } -char *nvr_concat(char *to_concat) +wchar_t *nvr_concat(wchar_t *to_concat) { - memset(nvr_path + path_len, 0, 1024 - path_len); - strcpy(nvr_path + path_len, to_concat); + char *p = (char *) nvr_path; + p += (path_len * 2); + wchar_t *wp = (wchar_t *) p; + + memset(wp, 0, (1024 - path_len) * 2); + wcscpy(wp, to_concat); return nvr_path; } diff --git a/src/ps1.c b/src/ps1.c index a9f068bfd..bfb98318c 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -134,7 +134,7 @@ void ps1mb_init() if (!enable_xtide) { rom_init(&ps1_high_rom, - "roms/ibmps1es/f80000_shell.bin", + L"roms/ibmps1es/f80000_shell.bin", 0xf80000, 0x80000, 0x7ffff, @@ -142,8 +142,8 @@ void ps1mb_init() MEM_MAPPING_EXTERNAL); } /* rom_init_interleaved(&ps1_high_rom, - "roms/ibmps1es/ibm_1057757_24-05-90.bin", - "roms/ibmps1es/ibm_1057757_29-15-90.bin", + L"roms/ibmps1es/ibm_1057757_24-05-90.bin", + L"roms/ibmps1es/ibm_1057757_29-15-90.bin", 0xfc0000, 0x40000, 0x3ffff, @@ -287,7 +287,7 @@ void ps1mb_m2121_init() io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); rom_init(&ps1_high_rom, - "roms/ibmps1_2121/fc0000_shell.bin", + L"roms/ibmps1_2121/fc0000_shell.bin", 0xfc0000, 0x40000, 0x3ffff, diff --git a/src/ps2_nvr.c b/src/ps2_nvr.c index 917b0e786..33661c813 100644 --- a/src/ps2_nvr.c +++ b/src/ps2_nvr.c @@ -2,6 +2,8 @@ #include "ibm.h" #include "device.h" #include "io.h" +#include "mem.h" +#include "rom.h" #include "ps2_nvr.h" typedef struct ps2_nvr_t @@ -56,7 +58,7 @@ static void *ps2_nvr_init() switch (romset) { - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "rb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80_sec.nvr", L"rb"); break; } if (f) { @@ -76,7 +78,7 @@ static void ps2_nvr_close(void *p) switch (romset) { - case ROM_IBMPS2_M80: f = romfopen("nvr/ibmps2_m80_sec.nvr", "wb"); break; + case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80_sec.nvr", L"wb"); break; } if (f) { diff --git a/src/rom.c b/src/rom.c index 60475aac8..82299602d 100644 --- a/src/rom.c +++ b/src/rom.c @@ -9,25 +9,31 @@ #include "rom.h" -FILE *romfopen(char *fn, char *mode) +FILE *romfopen(wchar_t *fn, wchar_t *mode) { - char s[512]; - strcpy(s, pcempath); - put_backslash(s); - strcat(s, fn); - return fopen(s, mode); + wchar_t s[512]; + wcscpy(s, pcempath); + put_backslash_w(s); + wcscat(s, fn); + return _wfopen(s, mode); } -int rom_present(char *fn) +FILE *nvrfopen(wchar_t *fn, wchar_t *mode) +{ + return _wfopen(nvr_concat(fn), mode); +} + + +int rom_present(wchar_t *fn) { FILE *f; - char s[512]; + wchar_t s[512]; - strcpy(s, pcempath); - put_backslash(s); - strcat(s, fn); - f = fopen(s, "rb"); + wcscpy(s, pcempath); + put_backslash_w(s); + wcscat(s, fn); + f = _wfopen(s, L"rb"); if (f) { fclose(f); @@ -70,13 +76,13 @@ uint32_t rom_readl(uint32_t addr, void *p) } -int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) +int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { - FILE *f = romfopen(fn, "rb"); + FILE *f = romfopen(fn, L"rb"); if (!f) { - pclog("ROM image not found : %s\n", fn); + pclog("ROM image not found : %ws\n", fn); return -1; } @@ -101,20 +107,20 @@ int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int fil } -int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) +int rom_init_interleaved(rom_t *rom, wchar_t *fn_low, wchar_t *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags) { - FILE *f_low = romfopen(fn_low, "rb"); - FILE *f_high = romfopen(fn_high, "rb"); + FILE *f_low = romfopen(fn_low, L"rb"); + FILE *f_high = romfopen(fn_high, L"rb"); int c; if (!f_low || !f_high) { if (!f_low) - pclog("ROM image not found : %s\n", fn_low); + pclog("ROM image not found : %ws\n", fn_low); else fclose(f_low); if (!f_high) - pclog("ROM image not found : %s\n", fn_high); + pclog("ROM image not found : %ws\n", fn_high); else fclose(f_high); return -1; diff --git a/src/rom.h b/src/rom.h index d548ee8be..c4cea8f7c 100644 --- a/src/rom.h +++ b/src/rom.h @@ -1,8 +1,9 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -FILE *romfopen(char *fn, char *mode); -int rom_present(char *fn); +FILE *romfopen(wchar_t *fn, wchar_t *mode); +FILE *nvrfopen(wchar_t *fn, wchar_t *mode); +int rom_present(wchar_t *fn); typedef struct rom_t { @@ -11,5 +12,5 @@ typedef struct rom_t mem_mapping_t mapping; } rom_t; -int rom_init(rom_t *rom, char *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); -int rom_init_interleaved(rom_t *rom, char *fn_low, char *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +int rom_init(rom_t *rom, wchar_t *fn, uint32_t address, int size, int mask, int file_offset, uint32_t flags); +int rom_init_interleaved(rom_t *rom, wchar_t *fn_low, wchar_t *fn_high, uint32_t address, int size, int mask, int file_offset, uint32_t flags); diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index fd89a1cc5..99fcd8cb9 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -34,12 +34,12 @@ #if AHA == AHA154xB -# define ROMFILE "roms/adaptec/aha1540b310.bin" +# define ROMFILE L"roms/adaptec/aha1540b310.bin" # define AHA_BID 'A' /* AHA-154x B */ #endif #if AHA == AHA154xC -# define ROMFILE "roms/adaptec/aha1542c101.bin" +# define ROMFILE L"roms/adaptec/aha1542c101.bin" # define AHA_BID 'D' /* AHA-154x C */ # define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ # define ROM_SHRAM 0x3F80 /* shadow RAM address base */ @@ -49,7 +49,7 @@ #endif #if AHA == AHA154xCF -# define ROMFILE "roms/adaptec/aha1542cf201.bin" +# define ROMFILE L"roms/adaptec/aha1542cf201.bin" # define AHA_BID 'E' /* AHA-154x CF */ # define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ # define ROM_SHRAM 0x3F80 /* shadow RAM address base */ @@ -59,7 +59,7 @@ #endif #if AHA == AHA154xCP -# define ROMFILE "roms/adaptec/aha1542cp102.bin" +# define ROMFILE L"roms/adaptec/aha1542cp102.bin" # define AHA_BID 'F' /* AHA-154x CP */ # define ROM_FWHIGH 0x0055 /* firmware version (hi/lo) */ # define ROM_SHRAM 0x3F80 /* shadow RAM address base */ @@ -208,7 +208,7 @@ aha154x_init(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) pclog("AHA154x: loading BIOS from '%s'\n", bios_path); /* Open the BIOS image file and make sure it exists. */ - if ((f = fopen(bios_path, "rb")) == NULL) { + if ((f = romfopen(bios_path, L"rb")) == NULL) { pclog("AHA154x: BIOS ROM not found!\n"); return; } diff --git a/src/sound_adlibgold.c b/src/sound_adlibgold.c index 398ed139c..0a4f1aaa4 100644 --- a/src/sound_adlibgold.c +++ b/src/sound_adlibgold.c @@ -772,7 +772,7 @@ void *adgold_init() for (; c >= 0; c--) attenuation[c] = 0; - f = romfopen("nvr/adgold.bin", "rb"); + f = nvrfopen(L"adgold.bin", L"rb"); if (f) { fread(adgold->adgold_eeprom, 0x18, 1, f); @@ -812,7 +812,7 @@ void adgold_close(void *p) FILE *f; adgold_t *adgold = (adgold_t *)p; - f = romfopen("nvr/adgold.bin", "wb"); + f = nvrfopen(L"adgold.bin", L"wb"); if (f) { fwrite(adgold->adgold_eeprom, 0x18, 1, f); diff --git a/src/sound_emu8k.c b/src/sound_emu8k.c index 1d82385f1..d9cddbdab 100644 --- a/src/sound_emu8k.c +++ b/src/sound_emu8k.c @@ -671,7 +671,7 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram) int c; double out; - f = romfopen("roms/awe32.raw", "rb"); + f = romfopen(L"roms/awe32.raw", L"rb"); if (!f) fatal("ROMS/AWE32.RAW not found\n"); diff --git a/src/sound_sb.c b/src/sound_sb.c index d29f5028e..cd7b456f3 100644 --- a/src/sound_sb.c +++ b/src/sound_sb.c @@ -655,7 +655,7 @@ void *sb_16_init() int sb_awe32_available() { - return rom_present("roms/awe32.raw"); + return rom_present(L"roms/awe32.raw"); } void *sb_awe32_init() diff --git a/src/tandy_eeprom.c b/src/tandy_eeprom.c index 391b9c12f..8d1a9eff2 100644 --- a/src/tandy_eeprom.c +++ b/src/tandy_eeprom.c @@ -4,7 +4,9 @@ #include #include "ibm.h" #include "device.h" +#include "mem.h" #include "io.h" +#include "rom.h" #include "tandy_eeprom.h" typedef struct @@ -124,10 +126,10 @@ void *tandy_eeprom_init() switch (romset) { case ROM_TANDY1000HX: - f = romfopen(nvr_concat("tandy1000hx.bin"), "rb"); + f = nvrfopen(L"tandy1000hx.bin", L"rb"); break; case ROM_TANDY1000SL2: - f = romfopen(nvr_concat("tandy1000sl2.bin"), "rb"); + f = nvrfopen(L"tandy1000sl2.bin", L"rb"); break; } if (f) @@ -151,10 +153,10 @@ void tandy_eeprom_close(void *p) switch (eeprom->romset) { case ROM_TANDY1000HX: - f = romfopen(nvr_concat("tandy1000hx.bin"), "wb"); + f = nvrfopen(L"tandy1000hx.bin", L"wb"); break; case ROM_TANDY1000SL2: - f = romfopen(nvr_concat("tandy1000sl2.bin"), "wb"); + f = nvrfopen(L"tandy1000sl2.bin", L"wb"); break; } fwrite(eeprom->store, 128, 1, f); diff --git a/src/tandy_rom.c b/src/tandy_rom.c index fb4c6bdfd..a3b912c5f 100644 --- a/src/tandy_rom.c +++ b/src/tandy_rom.c @@ -6,6 +6,7 @@ #include "device.h" #include "io.h" #include "mem.h" +#include "rom.h" #include "tandy_rom.h" static uint8_t *tandy_rom; @@ -52,8 +53,8 @@ void *tandy_rom_init() tandy_rom = malloc(0x80000); - f = romfopen("roms/tandy1000sl2/8079047.hu1" ,"rb"); - ff = romfopen("roms/tandy1000sl2/8079048.hu2","rb"); + f = romfopen(L"roms/tandy1000sl2/8079047.hu1", L"rb"); + ff = romfopen(L"roms/tandy1000sl2/8079048.hu2", L"rb"); for (c = 0x0000; c < 0x80000; c += 2) { tandy_rom[c] = getc(f); diff --git a/src/vid_ati18800.c b/src/vid_ati18800.c index 068d2bcd5..bb30b4f1c 100644 --- a/src/vid_ati18800.c +++ b/src/vid_ati18800.c @@ -162,7 +162,7 @@ void *ati18800_init() ati18800_t *ati18800 = malloc(sizeof(ati18800_t)); memset(ati18800, 0, sizeof(ati18800_t)); - rom_init(&ati18800->bios_rom, "roms/vga88.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati18800->bios_rom, L"roms/vga88.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati18800->svga, ati18800, 1 << 19, /*512kb*/ NULL, @@ -175,14 +175,14 @@ void *ati18800_init() ati18800->svga.miscout = 1; - ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0); + ati_eeprom_load(&ati18800->eeprom, L"ati18800.nvr", 0); return ati18800; } static int ati18800_available() { - return rom_present("roms/vga88.BIN"); + return rom_present(L"roms/vga88.BIN"); } void ati18800_close(void *p) diff --git a/src/vid_ati28800.c b/src/vid_ati28800.c index 821185883..54269a9de 100644 --- a/src/vid_ati28800.c +++ b/src/vid_ati28800.c @@ -361,19 +361,19 @@ void *ati28800_init() if (gfxcard == GFX_VGAWONDERXL) { rom_init_interleaved(&ati28800->bios_rom, - "roms/XLEVEN.BIN", - "roms/XLODD.BIN", + L"roms/XLEVEN.BIN", + L"roms/XLODD.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); } else if (gfxcard == GFX_VGAWONDERXL24) { rom_init_interleaved(&ati28800->bios_rom, - "roms/112-14318-102.bin", - "roms/112-14319-102.bin", + L"roms/112-14318-102.bin", + L"roms/112-14319-102.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); } else - rom_init(&ati28800->bios_rom, "roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ati28800->bios_rom, L"roms/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&ati28800->svga, ati28800, memory, /*512kb*/ ati28800_recalctimings, @@ -386,24 +386,24 @@ void *ati28800_init() ati28800->svga.miscout = 1; - ati_eeprom_load(&ati28800->eeprom, "ati28800.nvr", 0); + ati_eeprom_load(&ati28800->eeprom, L"ati28800.nvr", 0); return ati28800; } static int ati28800_available() { - return rom_present("roms/bios.bin"); + return rom_present(L"roms/bios.bin"); } static int compaq_ati28800_available() { - return (rom_present("roms/XLEVEN.bin") && rom_present("roms/XLODD.bin")); + return (rom_present(L"roms/XLEVEN.bin") && rom_present(L"roms/XLODD.bin")); } static int ati28800_wonderxl24_available() { - return (rom_present("roms/112-14318-102.bin") && rom_present("roms/112-14319-102.bin")); + return (rom_present(L"roms/112-14318-102.bin") && rom_present(L"roms/112-14319-102.bin")); } void ati28800_close(void *p) diff --git a/src/vid_ati_eeprom.c b/src/vid_ati_eeprom.c index ffc2a04d8..bc7a56079 100644 --- a/src/vid_ati_eeprom.c +++ b/src/vid_ati_eeprom.c @@ -2,6 +2,8 @@ see COPYING for more details */ #include "ibm.h" +#include "mem.h" +#include "rom.h" #include "vid_ati_eeprom.h" enum @@ -31,12 +33,12 @@ enum EEPROM_OP_EWEN = 3 }; -void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) +void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type) { FILE *f; eeprom->type = type; - strcpy(eeprom->fn, fn); - f = romfopen(eeprom->fn, "rb"); + wcscpy(eeprom->fn, fn); + f = nvrfopen(eeprom->fn, L"rb"); if (!f) { memset(eeprom->data, 0, eeprom->type ? 512 : 128); @@ -48,7 +50,7 @@ void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) void ati_eeprom_save(ati_eeprom_t *eeprom) { - FILE *f = romfopen(eeprom->fn, "wb"); + FILE *f = nvrfopen(eeprom->fn, L"wb"); if (!f) return; fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); fclose(f); diff --git a/src/vid_ati_eeprom.h b/src/vid_ati_eeprom.h index 540f2c3f9..786ae0c8b 100644 --- a/src/vid_ati_eeprom.h +++ b/src/vid_ati_eeprom.h @@ -11,9 +11,9 @@ typedef struct ati_eeprom_t uint32_t dat; int type; - char fn[256]; + wchar_t fn[256]; } ati_eeprom_t; -void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); +void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type); void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/src/vid_ati_mach64.c b/src/vid_ati_mach64.c index 46d7f53a7..4a2744c59 100644 --- a/src/vid_ati_mach64.c +++ b/src/vid_ati_mach64.c @@ -3293,9 +3293,9 @@ static void *mach64gx_init() else mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - ati_eeprom_load(&mach64->eeprom, "mach64.nvr", 1); + ati_eeprom_load(&mach64->eeprom, L"mach64.nvr", 1); - rom_init(&mach64->bios_rom, "roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, L"roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return mach64; } @@ -3310,9 +3310,9 @@ static void *mach64vt2_init() mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ mach64->config_stat0 = 4; - ati_eeprom_load(&mach64->eeprom, "mach64vt.nvr", 1); + ati_eeprom_load(&mach64->eeprom, L"mach64vt.nvr", 1); - rom_init(&mach64->bios_rom, "roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&mach64->bios_rom, L"roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga->vblank_start = mach64_vblank_start; @@ -3321,12 +3321,12 @@ static void *mach64vt2_init() int mach64gx_available() { - return rom_present("roms/mach64gx/bios.bin"); + return rom_present(L"roms/mach64gx/bios.bin"); } int mach64vt2_available() { - return rom_present("roms/atimach64vt2pci.bin"); + return rom_present(L"roms/atimach64vt2pci.bin"); } void mach64_close(void *p) diff --git a/src/vid_cl_gd.c b/src/vid_cl_gd.c index 7c0899a95..b932992bb 100644 --- a/src/vid_cl_gd.c +++ b/src/vid_cl_gd.c @@ -806,7 +806,7 @@ uint8_t cirrus_read(uint32_t addr, void *p) return ret; } -void *clgd_common_init(char *romfn, uint8_t id) +void *clgd_common_init(wchar_t *romfn, uint8_t id) { clgd = malloc(sizeof(clgd_t)); svga_t *svga = &clgd->svga; @@ -880,92 +880,92 @@ void *clgd_common_init(char *romfn, uint8_t id) void *gd6235_init() { - return clgd_common_init("roms/vga6235.rom", CIRRUS_ID_CLGD6235); + return clgd_common_init(L"roms/vga6235.rom", CIRRUS_ID_CLGD6235); } void *gd5422_init() { - return clgd_common_init("roms/CL5422.ROM", CIRRUS_ID_CLGD5422); + return clgd_common_init(L"roms/CL5422.ROM", CIRRUS_ID_CLGD5422); } void *gd5429_init() { - return clgd_common_init("roms/5429.vbi", CIRRUS_ID_CLGD5429); + return clgd_common_init(L"roms/5429.vbi", CIRRUS_ID_CLGD5429); } void *gd5430_init() { - return clgd_common_init("roms/pci.BIN", CIRRUS_ID_CLGD5430); + return clgd_common_init(L"roms/pci.BIN", CIRRUS_ID_CLGD5430); } void *dia5430_init() { - return clgd_common_init("roms/diamondvlbus.BIN", CIRRUS_ID_CLGD5430); + return clgd_common_init(L"roms/diamondvlbus.BIN", CIRRUS_ID_CLGD5430); } void *gd5434_init() { - return clgd_common_init("roms/japan.BIN", CIRRUS_ID_CLGD5434); + return clgd_common_init(L"roms/japan.BIN", CIRRUS_ID_CLGD5434); } void *gd5436_init() { - return clgd_common_init("roms/5436.VBI", CIRRUS_ID_CLGD5436); + return clgd_common_init(L"roms/5436.VBI", CIRRUS_ID_CLGD5436); } void *gd5440_init() { - return clgd_common_init("roms/5440BIOS.BIN", CIRRUS_ID_CLGD5440); + return clgd_common_init(L"roms/5440BIOS.BIN", CIRRUS_ID_CLGD5440); } void *gd5446_init() { - return clgd_common_init("roms/5446BV.VBI", CIRRUS_ID_CLGD5446); + return clgd_common_init(L"roms/5446BV.VBI", CIRRUS_ID_CLGD5446); } static int gd5422_available() { - return rom_present("roms/CL5422.ROM"); + return rom_present(L"roms/CL5422.ROM"); } static int gd5429_available() { - return rom_present("roms/5429.vbi"); + return rom_present(L"roms/5429.vbi"); } static int gd5430_available() { - return rom_present("roms/pci.BIN"); + return rom_present(L"roms/pci.BIN"); } static int dia5430_available() { - return rom_present("roms/diamondvlbus.BIN"); + return rom_present(L"roms/diamondvlbus.BIN"); } static int gd5434_available() { - return rom_present("roms/japan.BIN"); + return rom_present(L"roms/japan.BIN"); } static int gd5436_available() { - return rom_present("roms/5436.VBI"); + return rom_present(L"roms/5436.VBI"); } static int gd5440_available() { - return rom_present("roms/5440BIOS.BIN"); + return rom_present(L"roms/5440BIOS.BIN"); } static int gd5446_available() { - return rom_present("roms/5446BV.VBI"); + return rom_present(L"roms/5446BV.VBI"); } static int gd6235_available() { - return rom_present("roms/vga6235.rom"); + return rom_present(L"roms/vga6235.rom"); } void clgd_close(void *p) diff --git a/src/vid_ega.c b/src/vid_ega.c index 2e98235d3..42062b5b8 100644 --- a/src/vid_ega.c +++ b/src/vid_ega.c @@ -900,7 +900,7 @@ void *ega_standalone_init() overscan_x = 16; overscan_y = 28; - rom_init(&ega->bios_rom, "roms/ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, L"roms/ibm_6277356_ega_card_u44_27128.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { @@ -938,7 +938,7 @@ void *cpqega_standalone_init() overscan_x = 16; overscan_y = 28; - rom_init(&ega->bios_rom, "roms/108281-001.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, L"roms/108281-001.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { @@ -974,7 +974,7 @@ void *sega_standalone_init() overscan_x = 16; overscan_y = 28; - rom_init(&ega->bios_rom, "roms/lega.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&ega->bios_rom, L"roms/lega.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (ega->bios_rom.rom[0x3ffe] == 0xaa && ega->bios_rom.rom[0x3fff] == 0x55) { @@ -1004,17 +1004,17 @@ void *sega_standalone_init() static int ega_standalone_available() { - return rom_present("roms/ibm_6277356_ega_card_u44_27128.bin"); + return rom_present(L"roms/ibm_6277356_ega_card_u44_27128.bin"); } static int cpqega_standalone_available() { - return rom_present("roms/108281-001.bin"); + return rom_present(L"roms/108281-001.bin"); } static int sega_standalone_available() { - return rom_present("roms/lega.vbi"); + return rom_present(L"roms/lega.vbi"); } void ega_close(void *p) diff --git a/src/vid_et4000.c b/src/vid_et4000.c index ca845982b..77831c446 100644 --- a/src/vid_et4000.c +++ b/src/vid_et4000.c @@ -144,7 +144,7 @@ void *et4000_init() et4000_t *et4000 = malloc(sizeof(et4000_t)); memset(et4000, 0, sizeof(et4000_t)); - rom_init(&et4000->bios_rom, "roms/et4000.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, L"roms/et4000.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); io_sethandler(0x03c0, 0x0020, et4000_in, NULL, NULL, et4000_out, NULL, NULL, et4000); @@ -159,7 +159,7 @@ void *et4000_init() static int et4000_available() { - return rom_present("roms/et4000.BIN"); + return rom_present(L"roms/et4000.BIN"); } void et4000_close(void *p) diff --git a/src/vid_et4000w32.c b/src/vid_et4000w32.c index bac8c5fa7..7f63f946a 100644 --- a/src/vid_et4000w32.c +++ b/src/vid_et4000w32.c @@ -1160,7 +1160,7 @@ void *et4000w32p_init() et4000w32p_hwcursor_draw, NULL); - rom_init(&et4000->bios_rom, "roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&et4000->bios_rom, L"roms/et4000w32.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&et4000->bios_rom.mapping); @@ -1195,7 +1195,7 @@ void *et4000w32p_init() int et4000w32p_available() { - return rom_present("roms/et4000w32.bin"); + return rom_present(L"roms/et4000w32.bin"); } void et4000w32p_close(void *p) diff --git a/src/vid_genius.c b/src/vid_genius.c index bc9ca6e1c..477d845d4 100644 --- a/src/vid_genius.c +++ b/src/vid_genius.c @@ -13,7 +13,6 @@ #define GENIUS_YSIZE 1008 void updatewindowsize(int x, int y); -void loadfont(char *s, int format); extern uint8_t fontdat8x12[256][16]; @@ -606,7 +605,7 @@ void genius_close(void *p) static int genius_available() { - return rom_present("roms/8x12.bin"); + return rom_present(L"roms/8x12.bin"); } void genius_speed_changed(void *p) diff --git a/src/vid_nv_riva128.c b/src/vid_nv_riva128.c index 9f47a6c41..ce8ff697c 100644 --- a/src/vid_nv_riva128.c +++ b/src/vid_nv_riva128.c @@ -2715,7 +2715,7 @@ static void *riva128_init() riva128_in, riva128_out, NULL, NULL); - rom_init(&riva128->bios_rom, "roms/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/Diamond_V330_rev-e.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&riva128->bios_rom.mapping); @@ -2812,7 +2812,7 @@ static void riva128_close(void *p) static int riva128_available() { - return rom_present("roms/Diamond_V330_rev-e.vbi"); + return rom_present(L"roms/Diamond_V330_rev-e.vbi"); } static void riva128_speed_changed(void *p) @@ -3016,7 +3016,7 @@ static void *rivatnt_init() riva128_in, riva128_out, NULL, NULL); - rom_init(&riva128->bios_rom, "roms/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/NV4_diamond_revB.rom", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&riva128->bios_rom.mapping); @@ -3097,7 +3097,7 @@ static void rivatnt_close(void *p) static int rivatnt_available() { - return rom_present("roms/NV4_diamond_revB.rom"); + return rom_present(L"roms/NV4_diamond_revB.rom"); } static void rivatnt_speed_changed(void *p) @@ -3219,13 +3219,13 @@ static void *rivatnt2_init() switch(model) { case 0: - rom_init(&riva128->bios_rom, "roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/NV5diamond.bin", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; case 1: - rom_init(&riva128->bios_rom, "roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/inno3d64bit.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; case 2: - rom_init(&riva128->bios_rom, "roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&riva128->bios_rom, L"roms/creative.BIN", 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL); break; } if (PCI) @@ -3308,7 +3308,7 @@ static void rivatnt2_close(void *p) static int rivatnt2_available() { - return rom_present("roms/NV5diamond.bin") || rom_present("roms/inno3d64bit.BIN") || rom_present("roms/creative.BIN"); + return rom_present(L"roms/NV5diamond.bin") || rom_present(L"roms/inno3d64bit.BIN") || rom_present(L"roms/creative.BIN"); } static void rivatnt2_speed_changed(void *p) diff --git a/src/vid_oti067.c b/src/vid_oti067.c index c1f0f0b0c..dc3d94e6c 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -157,7 +157,7 @@ void oti067_recalctimings(svga_t *svga) } } -void *oti067_common_init(char *bios_fn, int vram_size, int chip_id) +void *oti067_common_init(wchar_t *bios_fn, int vram_size, int chip_id) { oti067_t *oti067 = malloc(sizeof(oti067_t)); memset(oti067, 0, sizeof(oti067_t)); @@ -182,47 +182,26 @@ void *oti067_common_init(char *bios_fn, int vram_size, int chip_id) return oti067; } -/* void *oti037_init() -{ - int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/hyundai_oti037c.bin", vram_size, 0); -} */ - void *oti067_init() { int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/oti067/bios.bin", vram_size, 2); + return oti067_common_init(L"roms/oti067/bios.bin", vram_size, 2); } void *oti077_init() { int vram_size = device_get_config_int("memory"); - return oti067_common_init("roms/oti077.vbi", vram_size, 5); + return oti067_common_init(L"roms/oti077.vbi", vram_size, 5); } -void *oti067_acer386_init() -{ - oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512, 2); - - /* if (oti067) - oti067->bios_rom.rom[0x5d] = 0x74; */ - - return oti067; -} - -/* static int oti037_available() -{ - return rom_present("roms/hyundai_oti037c.bin"); -} */ - static int oti067_available() { - return rom_present("roms/oti067/bios.bin"); + return rom_present(L"roms/oti067/bios.bin"); } static int oti077_available() { - return rom_present("roms/oti077.vbi"); + return rom_present(L"roms/oti077.vbi"); } void oti067_close(void *p) @@ -312,17 +291,6 @@ device_t oti067_device = oti067_add_status_info, oti067_config }; -device_t oti067_acer386_device = -{ - "Oak OTI-067 (Acermate 386SX/25N)", - 0, - oti067_acer386_init, - oti067_close, - oti067_available, - oti067_speed_changed, - oti067_force_redraw, - oti067_add_status_info -}; device_t oti077_device = { "Oak OTI-077", diff --git a/src/vid_paradise.c b/src/vid_paradise.c index 859695459..6a385611a 100644 --- a/src/vid_paradise.c +++ b/src/vid_paradise.c @@ -323,7 +323,7 @@ static void *paradise_pvga1a_pc2086_init() paradise_t *paradise = paradise_pvga1a_init(); if (paradise) - rom_init(¶dise->bios_rom, "roms/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(¶dise->bios_rom, L"roms/pc2086/40186.ic171", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; } @@ -332,7 +332,7 @@ static void *paradise_pvga1a_pc3086_init() paradise_t *paradise = paradise_pvga1a_init(); if (paradise) - rom_init(¶dise->bios_rom, "roms/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(¶dise->bios_rom, L"roms/pc3086/c000.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; } @@ -343,8 +343,8 @@ static void *paradise_wd90c11_megapc_init() if (paradise) rom_init_interleaved(¶dise->bios_rom, - "roms/megapc/41651-bios lo.u18", - "roms/megapc/211253-bios hi.u19", + L"roms/megapc/41651-bios lo.u18", + L"roms/megapc/211253-bios hi.u19", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); return paradise; @@ -352,24 +352,9 @@ static void *paradise_wd90c11_megapc_init() static int paradise_wd90c11_standalone_available() { - return rom_present("roms/megapc/41651-bios lo.u18") && rom_present("roms/megapc/211253-bios hi.u19"); + return rom_present(L"roms/megapc/41651-bios lo.u18") && rom_present(L"roms/megapc/211253-bios hi.u19"); } -/* static void *cpqvga_init() -{ - paradise_t *paradise = paradise_pvga1a_init(); - - if (paradise) - rom_init(¶dise->bios_rom, "roms/1988-05-18.rom", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - - return paradise; -} - -static int cpqvga_standalone_available() -{ - return rom_present("roms/1988-05-18.rom"); -} */ - void paradise_close(void *p) { paradise_t *paradise = (paradise_t *)p; @@ -444,14 +429,3 @@ device_t paradise_wd90c11_device = paradise_force_redraw, paradise_add_status_info }; -/* device_t cpqvga_device = -{ - "Compaq/Paradise VGA", - 0, - cpqvga_init, - paradise_close, - cpqvga_standalone_available, - paradise_speed_changed, - paradise_force_redraw, - paradise_add_status_info -}; */ diff --git a/src/vid_pc1640.c b/src/vid_pc1640.c index 610f322c0..68a2117a0 100644 --- a/src/vid_pc1640.c +++ b/src/vid_pc1640.c @@ -125,7 +125,7 @@ void *pc1640_init() ega_t *ega = &pc1640->ega; memset(pc1640, 0, sizeof(pc1640_t)); - rom_init(&pc1640->bios_rom, "roms/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); + rom_init(&pc1640->bios_rom, L"roms/pc1640/40100", 0xc0000, 0x8000, 0x7fff, 0, 0); ega_init(&pc1640->ega); pc1640->cga.vram = pc1640->ega.vram; diff --git a/src/vid_s3.c b/src/vid_s3.c index 3c0a3371b..cf2621698 100644 --- a/src/vid_s3.c +++ b/src/vid_s3.c @@ -2063,7 +2063,7 @@ static int vram_sizes[] = 3 /*8 MB*/ }; -static void *s3_init(char *bios_fn, int chip) +static void *s3_init(wchar_t *bios_fn, int chip) { s3_t *s3 = malloc(sizeof(s3_t)); svga_t *svga = &s3->svga; @@ -2124,7 +2124,7 @@ static void *s3_init(char *bios_fn, int chip) return s3; } -void *s3_vision864_init(char *bios_fn) +void *s3_vision864_init(wchar_t *bios_fn) { s3_t *s3 = s3_init(bios_fn, S3_VISION864); @@ -2140,29 +2140,29 @@ void *s3_vision864_init(char *bios_fn) void *s3_bahamas64_init() { - s3_t *s3 = s3_vision864_init("roms/bahamas64.BIN"); + s3_t *s3 = s3_vision864_init(L"roms/bahamas64.BIN"); return s3; } void *s3_phoenix_vision864_init() { - s3_t *s3 = s3_vision864_init("roms/86c864p.bin"); + s3_t *s3 = s3_vision864_init(L"roms/86c864p.bin"); return s3; } int s3_bahamas64_available() { - return rom_present("roms/bahamas64.BIN"); + return rom_present(L"roms/bahamas64.BIN"); } int s3_phoenix_vision864_available() { - return rom_present("roms/86c864p.bin"); + return rom_present(L"roms/86c864p.bin"); } void *s3_phoenix_trio32_init() { - s3_t *s3 = s3_init("roms/86C732P.bin", S3_TRIO32); + s3_t *s3 = s3_init(L"roms/86C732P.bin", S3_TRIO32); s3->id = 0xe1; /*Trio32*/ s3->id_ext = 0x10; @@ -2177,10 +2177,10 @@ void *s3_phoenix_trio32_init() int s3_phoenix_trio32_available() { - return rom_present("roms/86C732P.bin"); + return rom_present(L"roms/86C732P.bin"); } -void *s3_trio64_init(char *bios_fn) +void *s3_trio64_init(wchar_t *bios_fn) { int card_id = 0; s3_t *s3 = s3_init(bios_fn, S3_TRIO64); @@ -2206,35 +2206,35 @@ void *s3_trio64_init(char *bios_fn) void *s3_9fx_init() { - s3_t *s3 = s3_trio64_init("roms/s3_764.bin"); + s3_t *s3 = s3_trio64_init(L"roms/s3_764.bin"); return s3; } void *s3_phoenix_trio64_init() { - s3_t *s3 = s3_trio64_init("roms/86C764X1.bin"); + s3_t *s3 = s3_trio64_init(L"roms/86C764X1.bin"); return s3; } void *s3_diamond_stealth64_init() { - s3_t *s3 = s3_trio64_init("roms/STEALT64.BIN"); + s3_t *s3 = s3_trio64_init(L"roms/STEALT64.BIN"); return s3; } int s3_9fx_available() { - return rom_present("roms/s3_764.bin"); + return rom_present(L"roms/s3_764.bin"); } int s3_phoenix_trio64_available() { - return rom_present("roms/86C764X1.bin"); + return rom_present(L"roms/86C764X1.bin"); } int s3_diamond_stealth64_available() { - return rom_present("roms/STEALT64.BIN"); + return rom_present(L"roms/STEALT64.BIN"); } void s3_close(void *p) diff --git a/src/vid_s3_virge.c b/src/vid_s3_virge.c index cecdcb427..e11f1c7d0 100644 --- a/src/vid_s3_virge.c +++ b/src/vid_s3_virge.c @@ -3707,7 +3707,7 @@ static void *s3_virge_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, L"roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -3802,7 +3802,7 @@ static void *s3_virge_988_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "roms/diamondstealth3000.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, L"roms/diamondstealth3000.VBI", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -3897,7 +3897,7 @@ static void *s3_virge_375_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, "roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, L"roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -4003,17 +4003,17 @@ static void s3_virge_close(void *p) static int s3_virge_available() { - return rom_present("roms/s3virge.bin"); + return rom_present(L"roms/s3virge.bin"); } static int s3_virge_988_available() { - return rom_present("roms/diamondstealth3000.VBI"); + return rom_present(L"roms/diamondstealth3000.VBI"); } static int s3_virge_375_available() { - return rom_present("roms/86c375_1.bin"); + return rom_present(L"roms/86c375_1.bin"); } static void s3_virge_speed_changed(void *p) diff --git a/src/vid_tgui9440.c b/src/vid_tgui9440.c index f369c8370..384f76a81 100644 --- a/src/vid_tgui9440.c +++ b/src/vid_tgui9440.c @@ -510,7 +510,7 @@ void *tgui9440_init() tgui->vram_size = device_get_config_int("memory") << 20; tgui->vram_mask = tgui->vram_size - 1; - rom_init(&tgui->bios_rom, "roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tgui->bios_rom, L"roms/9440.vbi", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tgui->svga, tgui, tgui->vram_size, tgui_recalctimings, @@ -536,7 +536,7 @@ void *tgui9440_init() static int tgui9440_available() { - return rom_present("roms/9440.vbi"); + return rom_present(L"roms/9440.vbi"); } void tgui_close(void *p) diff --git a/src/vid_tvga.c b/src/vid_tvga.c index 3e70422cb..bbbf9d1ca 100644 --- a/src/vid_tvga.c +++ b/src/vid_tvga.c @@ -285,7 +285,7 @@ void *tvga8900d_init() tvga->vram_size = device_get_config_int("memory") << 10; tvga->vram_mask = tvga->vram_size - 1; - rom_init(&tvga->bios_rom, "roms/TRIDENT.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&tvga->bios_rom, L"roms/TRIDENT.BIN", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); svga_init(&tvga->svga, tvga, tvga->vram_size, tvga_recalctimings, @@ -300,7 +300,7 @@ void *tvga8900d_init() static int tvga8900d_available() { - return rom_present("roms/TRIDENT.BIN"); + return rom_present(L"roms/TRIDENT.BIN"); } void tvga_close(void *p) diff --git a/src/vid_vga.c b/src/vid_vga.c index f5ff18ed6..a69b6f60c 100644 --- a/src/vid_vga.c +++ b/src/vid_vga.c @@ -84,7 +84,7 @@ void *vga_init() vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); - rom_init(&vga->bios_rom, "roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + rom_init(&vga->bios_rom, L"roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ NULL, @@ -100,36 +100,13 @@ void *vga_init() return vga; } -#if 0 -void *vga_chips_init() -{ - vga_t *vga = malloc(sizeof(vga_t)); - memset(vga, 0, sizeof(vga_t)); - - rom_init(&vga->bios_rom, "roms/SD620.04M", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); - - svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ - NULL, - vga_in, vga_out, - NULL, - NULL); - - io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga); - - vga->svga.bpp = 8; - vga->svga.miscout = 1; - - return vga; -} -#endif - #ifdef DEV_BRANCH void *trigem_unk_init() { vga_t *vga = malloc(sizeof(vga_t)); memset(vga, 0, sizeof(vga_t)); - rom_init(&vga->bios_rom, "roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); + rom_init(&vga->bios_rom, L"roms/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL); svga_init(&vga->svga, vga, 1 << 18, /*256kb*/ NULL, @@ -172,14 +149,9 @@ void *ps1vga_init() static int vga_available() { - return rom_present("roms/ibm_vga.bin"); + return rom_present(L"roms/ibm_vga.bin"); } -/* static int vga_chips_available() -{ - return rom_present("roms/SD620.04M"); -} */ - void vga_close(void *p) { vga_t *vga = (vga_t *)p; @@ -221,17 +193,6 @@ device_t vga_device = vga_force_redraw, vga_add_status_info }; -/* device_t vga_chips_device = -{ - "Chips VGA", - 0, - vga_chips_init, - vga_close, - vga_chips_available, - vga_speed_changed, - vga_force_redraw, - vga_add_status_info -}; */ #ifdef DEV_BRANCH device_t trigem_unk_device = { diff --git a/src/vid_voodoo.c b/src/vid_voodoo.c index a1a5e93e7..eef3df1e8 100644 --- a/src/vid_voodoo.c +++ b/src/vid_voodoo.c @@ -4,6 +4,7 @@ #include "device.h" #include "mem.h" #include "pci.h" +#include "rom.h" #include "thread.h" #include "timer.h" #include "video.h" @@ -7040,12 +7041,12 @@ void voodoo_close(void *p) int c; #ifndef RELEASE_BUILD - f = romfopen("texram.dmp", "wb"); + f = romfopen(L"texram.dmp", L"wb"); fwrite(voodoo->tex_mem[0], voodoo->texture_size*1024*1024, 1, f); fclose(f); if (voodoo->dual_tmus) { - f = romfopen("texram2.dmp", "wb"); + f = romfopen(L"texram2.dmp", L"wb"); fwrite(voodoo->tex_mem[1], voodoo->texture_size*1024*1024, 1, f); fclose(f); } diff --git a/src/vid_wy700.c b/src/vid_wy700.c index 80def235f..4519a293e 100644 --- a/src/vid_wy700.c +++ b/src/vid_wy700.c @@ -12,7 +12,6 @@ #define WY700_YSIZE 800 void updatewindowsize(int x, int y); -void loadfont(char *s, int format); /* The Wyse 700 is an unusual video card. Though it has an MC6845 CRTC, this diff --git a/src/video.c b/src/video.c index 1176824ee..798981c71 100644 --- a/src/video.c +++ b/src/video.c @@ -358,9 +358,9 @@ int xsize=1,ysize=1; PALETTE cgapal; -void loadfont(char *s, int format) +void loadfont(wchar_t *s, int format) { - FILE *f=romfopen(s,"rb"); + FILE *f=romfopen(s,L"rb"); int c,d; if (!f) { diff --git a/src/video.h b/src/video.h index 33aed0400..234bb81ad 100644 --- a/src/video.h +++ b/src/video.h @@ -113,7 +113,7 @@ void ddraw_fs_take_screenshot(char *fn); extern int cga_palette; -void loadfont(char *s, int format); +void loadfont(wchar_t *s, int format); void initvideo(); void video_init(); void closevideo(); diff --git a/src/win.c b/src/win.c index 75c798ded..ac112aed4 100644 --- a/src/win.c +++ b/src/win.c @@ -418,11 +418,9 @@ static void initmenu(void) } } -void get_executable_name(char *s, int size) +void get_executable_name(WCHAR *s, int size) { - WCHAR ws[512]; - GetModuleFileName(hinstance, ws, size); - wcstombs(s, ws, (wcslen(ws) << 1) + 2); + GetModuleFileName(hinstance, s, size); } void set_window_title(WCHAR *s) @@ -525,26 +523,24 @@ void get_registry_key_map() } } -static char **argv; +static wchar_t **argv; static int argc; -static char *argbuf; +static wchar_t *argbuf; static void process_command_line() { - WCHAR *wcmdline; - char cmdline[2048]; + WCHAR *cmdline; int argc_max; int i, q; - wcmdline = GetCommandLine(); - wcstombs(cmdline, wcmdline, (wcslen(wcmdline) << 1) + 2); - i = strlen(cmdline) + 1; - argbuf = malloc(i); - memcpy(argbuf, cmdline, i); + cmdline = GetCommandLine(); + i = wcslen(cmdline) + 1; + argbuf = malloc(i * 2); + memcpy(argbuf, cmdline, i * 2); argc = 0; argc_max = 64; - argv = malloc(sizeof(char *) * argc_max); + argv = malloc(sizeof(wchar_t *) * argc_max); if (!argv) { free(argbuf); @@ -556,12 +552,12 @@ static void process_command_line() /* parse commandline into argc/argv format */ while (argbuf[i]) { - while (argbuf[i] == ' ') + while (argbuf[i] == L' ') i++; if (argbuf[i]) { - if ((argbuf[i] == '\'') || (argbuf[i] == '"')) + if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) { q = argbuf[i++]; if (!argbuf[i]) @@ -575,7 +571,7 @@ static void process_command_line() if (argc >= argc_max) { argc_max += 64; - argv = realloc(argv, sizeof(char *) * argc_max); + argv = realloc(argv, sizeof(wchar_t *) * argc_max); if (!argv) { free(argbuf); @@ -583,7 +579,7 @@ static void process_command_line() } } - while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != ' '))) + while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != L' '))) i++; if (argbuf[i]) @@ -1852,8 +1848,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { if (msgbox_reset_yn(ghwnd) == IDYES) { - loadconfig(openfilestring); config_save(config_file_default); + loadconfig(wopenfilestring); mem_resize(); loadbios(); resetpchard(); @@ -1865,7 +1861,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_SAVE: pause = 1; if (!file_dlg_st(hwnd, 2174, "", 1)) - config_save(openfilestring); + config_save(wopenfilestring); pause = 0; break; } diff --git a/src/win.h b/src/win.h index d49689a15..0e09db88f 100644 --- a/src/win.h +++ b/src/win.h @@ -33,7 +33,7 @@ extern WCHAR wopenfilestring[260]; int getfile(HWND hwnd, char *f, char *fn); int getsfile(HWND hwnd, char *f, char *fn); -void get_executable_name(char *s, int size); +void get_executable_name(WCHAR *s, int size); void set_window_title(WCHAR *s); void startblit(); diff --git a/src/xtide.c b/src/xtide.c index 587f1de02..db6f1dca3 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -72,7 +72,7 @@ static void *xtide_init() xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); ide_pri_disable(); ide_sec_disable(); @@ -86,7 +86,7 @@ static void *xtide_at_init() xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; @@ -97,7 +97,7 @@ static void *xtide_ps2_init() xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); ide_pri_disable(); ide_sec_disable(); @@ -111,7 +111,7 @@ static void *xtide_at_ps2_init() xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, "roms/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, L"roms/ide_at_1_1_5.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; @@ -126,22 +126,22 @@ static void xtide_close(void *p) static int xtide_available() { - return rom_present("roms/ide_xt.bin"); + return rom_present(L"roms/ide_xt.bin"); } static int xtide_at_available() { - return rom_present("roms/ide_at.bin"); + return rom_present(L"roms/ide_at.bin"); } static int xtide_ps2_available() { - return rom_present("roms/SIDE1V12.BIN"); + return rom_present(L"roms/SIDE1V12.BIN"); } static int xtide_at_ps2_available() { - return rom_present("roms/ide_at_1_1_5.bin"); + return rom_present(L"roms/ide_at_1_1_5.bin"); } device_t xtide_device = From e2a717deae210b17e753828d3e37c642ada0c514 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 May 2017 14:15:16 +0200 Subject: [PATCH 160/392] Fixed the setting of nvr_path, NVR's with CMOS settings now get saved again; Added pclog_w which is the Unicode version of pclog, used in disc.c for logging when a floppy image could not be loaded. --- src/disc.c | 2 +- src/ibm.h | 1 + src/pc.c | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/disc.c b/src/disc.c index e858474ce..ad7459fe2 100644 --- a/src/disc.c +++ b/src/disc.c @@ -127,7 +127,7 @@ void disc_load(int drive, wchar_t *fn) } c++; } - pclog("Couldn't load %s %s\n",fn,p); + pclog_w(L"Couldn't load %s %s\n",fn,p); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); discfns[drive][0] = L'\0'; diff --git a/src/ibm.h b/src/ibm.h index 5898a8b2d..c163e5f15 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -664,6 +664,7 @@ extern uint32_t SCSIGetCDChannel(int channel); extern int ui_writeprot[4]; void pclog(const char *format, ...); +void pclog_w(const wchar_t *format, ...); extern int nmi; extern int nmi_auto_clear; diff --git a/src/pc.c b/src/pc.c index 4f49e367d..abfb59c38 100644 --- a/src/pc.c +++ b/src/pc.c @@ -115,6 +115,17 @@ void pclog(const char *format, ...) #endif } +void pclog_w(const wchar_t *format, ...) +{ +#ifndef RELEASE_BUILD + va_list ap; + va_start(ap, format); + _vwprintf_p(format, ap); + va_end(ap); + fflush(stdout); +#endif +} + #ifndef __unix #ifndef _LIBC # define __builtin_expect(expr, val) (expr) @@ -705,7 +716,7 @@ void loadconfig(wchar_t *fn) int c, d; char s[512]; char *p; - WCHAR *wp, *wq; + wchar_t *wp, *wq; char temps[512]; if (!fn) @@ -920,9 +931,9 @@ void loadconfig(wchar_t *fn) } memset(nvr_path, 0, 2048); - wp = (char *)config_get_wstring(NULL, "nvr_path", "nvr"); + wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L"nvr"); if (wp) { - if (strlen(wp) <= 992) wcscpy(nvr_path, wp); + if (wcslen(wp) <= 992) wcscpy(nvr_path, wp); else { append_filename_w(nvr_path, pcempath, L"nvr", 511); From f6612fb33bd28302c813eca4d734c1c9a9e58af0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 May 2017 17:48:33 +0200 Subject: [PATCH 161/392] Fixed bugs that were preventing NVR and Flash files from behind saved; A lot of clean ups from waltje; Start of a directory structure for the code, thanks to waltje. --- src/86Box.rc | 16 +- src/CMakeModules/FindD3D9.cmake | 53 -- src/CMakeModules/FindDirectDraw.cmake | 53 -- src/CMakeModules/FindDirectInput.cmake | 53 -- src/{ => CPU}/386.c | 14 +- src/{ => CPU}/386.h | 0 src/{ => CPU}/386_common.h | 0 src/{ => CPU}/386_dynarec.c | 14 +- src/{ => CPU}/386_dynarec_ops.c | 6 +- src/{ => CPU}/386_ops.h | 0 src/{ => CPU}/808x.c | 16 +- src/{ => CPU}/codegen.c | 4 +- src/{ => CPU}/codegen.h | 0 src/{ => CPU}/codegen_ops.c | 3 +- src/{ => CPU}/codegen_ops.h | 0 src/{ => CPU}/codegen_ops_arith.h | 0 src/{ => CPU}/codegen_ops_fpu.h | 0 src/{ => CPU}/codegen_ops_jump.h | 0 src/{ => CPU}/codegen_ops_logic.h | 0 src/{ => CPU}/codegen_ops_misc.h | 0 src/{ => CPU}/codegen_ops_mmx.h | 0 src/{ => CPU}/codegen_ops_mov.h | 0 src/{ => CPU}/codegen_ops_shift.h | 0 src/{ => CPU}/codegen_ops_stack.h | 0 src/{ => CPU}/codegen_ops_x86-64.h | 0 src/{ => CPU}/codegen_ops_x86.h | 0 src/{ => CPU}/codegen_ops_xchg.h | 0 src/{ => CPU}/codegen_timing_486.c | 4 +- src/{ => CPU}/codegen_timing_686.c | 5 +- src/{ => CPU}/codegen_timing_pentium.c | 5 +- src/{ => CPU}/codegen_timing_winchip.c | 4 +- src/{ => CPU}/codegen_x86-64.c | 0 src/{ => CPU}/codegen_x86-64.h | 0 src/{ => CPU}/codegen_x86.c | 5 +- src/{ => CPU}/codegen_x86.h | 0 src/{ => CPU}/cpu.c | 10 +- src/{ => CPU}/cpu.h | 0 src/{ => CPU}/x86.h | 0 src/{ => CPU}/x86_flags.h | 0 src/{ => CPU}/x86_ops.h | 0 src/{ => CPU}/x86_ops_arith.h | 0 src/{ => CPU}/x86_ops_atomic.h | 0 src/{ => CPU}/x86_ops_bcd.h | 0 src/{ => CPU}/x86_ops_bit.h | 0 src/{ => CPU}/x86_ops_bitscan.h | 0 src/{ => CPU}/x86_ops_call.h | 0 src/{ => CPU}/x86_ops_flag.h | 0 src/{ => CPU}/x86_ops_fpu.h | 0 src/{ => CPU}/x86_ops_i686.h | 0 src/{ => CPU}/x86_ops_inc_dec.h | 0 src/{ => CPU}/x86_ops_int.h | 0 src/{ => CPU}/x86_ops_io.h | 0 src/{ => CPU}/x86_ops_jump.h | 0 src/{ => CPU}/x86_ops_misc.h | 0 src/{ => CPU}/x86_ops_mmx.h | 0 src/{ => CPU}/x86_ops_mmx_arith.h | 0 src/{ => CPU}/x86_ops_mmx_cmp.h | 0 src/{ => CPU}/x86_ops_mmx_logic.h | 0 src/{ => CPU}/x86_ops_mmx_mov.h | 0 src/{ => CPU}/x86_ops_mmx_pack.h | 0 src/{ => CPU}/x86_ops_mmx_shift.h | 0 src/{ => CPU}/x86_ops_mov.h | 0 src/{ => CPU}/x86_ops_mov_ctrl.h | 0 src/{ => CPU}/x86_ops_mov_seg.h | 0 src/{ => CPU}/x86_ops_movx.h | 0 src/{ => CPU}/x86_ops_msr.h | 0 src/{ => CPU}/x86_ops_mul.h | 0 src/{ => CPU}/x86_ops_pmode.h | 0 src/{ => CPU}/x86_ops_prefix.h | 0 src/{ => CPU}/x86_ops_rep.h | 0 src/{ => CPU}/x86_ops_ret.h | 0 src/{ => CPU}/x86_ops_set.h | 0 src/{ => CPU}/x86_ops_shift.h | 0 src/{ => CPU}/x86_ops_stack.h | 0 src/{ => CPU}/x86_ops_string.h | 0 src/{ => CPU}/x86_ops_xchg.h | 0 src/{ => CPU}/x86seg.c | 6 +- src/{ => CPU}/x86seg.h | 0 src/{ => CPU}/x87.c | 6 +- src/{ => CPU}/x87.h | 0 src/{ => CPU}/x87_ops.h | 0 src/{ => CPU}/x87_ops_arith.h | 0 src/{ => CPU}/x87_ops_loadstore.h | 0 src/{ => CPU}/x87_ops_misc.h | 0 src/Makefile.mingw | 90 +- src/Makefile.mingw64 | 172 +--- src/{dosbox => SOUND}/dbopl.cpp | 0 src/{dosbox => SOUND}/dbopl.h | 0 src/{ => SOUND}/filters.h | 0 src/{dosbox => SOUND}/nukedopl.cpp | 0 src/{dosbox => SOUND}/nukedopl.h | 0 src/{soundopenal.c => SOUND/openal.c} | 16 +- src/{ => SOUND}/resid-fp/AUTHORS | 0 src/{ => SOUND}/resid-fp/COPYING | 0 src/{ => SOUND}/resid-fp/ChangeLog | 0 src/{ => SOUND}/resid-fp/INSTALL | 0 src/{ => SOUND}/resid-fp/Makefile.am | 0 src/{ => SOUND}/resid-fp/Makefile.in | 0 src/{ => SOUND}/resid-fp/NEWS | 0 src/{ => SOUND}/resid-fp/README | 0 src/{ => SOUND}/resid-fp/README.VICE | 0 src/{ => SOUND}/resid-fp/aclocal.m4 | 0 src/{ => SOUND}/resid-fp/configure | 0 src/{ => SOUND}/resid-fp/configure.in | 0 src/{ => SOUND}/resid-fp/convolve-sse.cc | 0 src/{ => SOUND}/resid-fp/convolve.cc | 0 src/{ => SOUND}/resid-fp/envelope.cc | 0 src/{ => SOUND}/resid-fp/envelope.h | 0 src/{ => SOUND}/resid-fp/extfilt.cc | 0 src/{ => SOUND}/resid-fp/extfilt.h | 0 src/{ => SOUND}/resid-fp/filter.cc | 0 src/{ => SOUND}/resid-fp/filter.h | 0 src/{ => SOUND}/resid-fp/pot.cc | 0 src/{ => SOUND}/resid-fp/pot.h | 0 src/{ => SOUND}/resid-fp/samp2src.pl | 0 src/{ => SOUND}/resid-fp/sid.cc | 0 src/{ => SOUND}/resid-fp/sid.h | 0 src/{ => SOUND}/resid-fp/siddefs-fp.h | 0 src/{ => SOUND}/resid-fp/siddefs-fp.h.in | 0 src/{ => SOUND}/resid-fp/version.cc | 0 src/{ => SOUND}/resid-fp/voice.cc | 0 src/{ => SOUND}/resid-fp/voice.h | 0 src/{ => SOUND}/resid-fp/wave.cc | 0 src/{ => SOUND}/resid-fp/wave.h | 0 src/{ => SOUND}/resid-fp/wave6581_PST.cc | 0 src/{ => SOUND}/resid-fp/wave6581_PST.dat | Bin src/{ => SOUND}/resid-fp/wave6581_PS_.cc | 0 src/{ => SOUND}/resid-fp/wave6581_PS_.dat | Bin src/{ => SOUND}/resid-fp/wave6581_P_T.cc | 0 src/{ => SOUND}/resid-fp/wave6581_P_T.dat | Bin src/{ => SOUND}/resid-fp/wave6581__ST.cc | 0 src/{ => SOUND}/resid-fp/wave6581__ST.dat | Bin src/{ => SOUND}/resid-fp/wave8580_PST.cc | 0 src/{ => SOUND}/resid-fp/wave8580_PST.dat | Bin src/{ => SOUND}/resid-fp/wave8580_PS_.cc | 0 src/{ => SOUND}/resid-fp/wave8580_PS_.dat | Bin src/{ => SOUND}/resid-fp/wave8580_P_T.cc | 0 src/{ => SOUND}/resid-fp/wave8580_P_T.dat | Bin src/{ => SOUND}/resid-fp/wave8580__ST.cc | 0 src/{ => SOUND}/resid-fp/wave8580__ST.dat | Bin src/{sound_ad1848.c => SOUND/snd_ad1848.c} | 12 +- src/{sound_ad1848.h => SOUND/snd_ad1848.h} | 2 - src/{sound_adlib.c => SOUND/snd_adlib.c} | 13 +- src/{sound_adlib.h => SOUND/snd_adlib.h} | 0 .../snd_adlibgold.c} | 23 +- .../snd_adlibgold.h} | 0 src/{sound_cms.c => SOUND/snd_cms.c} | 11 +- src/{sound_cms.h => SOUND/snd_cms.h} | 0 src/{sound_dbopl.cc => SOUND/snd_dbopl.cc} | 8 +- src/{sound_dbopl.h => SOUND/snd_dbopl.h} | 0 src/{sound_emu8k.c => SOUND/snd_emu8k.c} | 13 +- src/{sound_emu8k.h => SOUND/snd_emu8k.h} | 0 src/{sound_gus.c => SOUND/snd_gus.c} | 16 +- src/{sound_gus.h => SOUND/snd_gus.h} | 0 .../snd_mpu401_uart.c} | 10 +- .../snd_mpu401_uart.h} | 0 src/{sound_opl.c => SOUND/snd_opl.c} | 10 +- src/{sound_opl.h => SOUND/snd_opl.h} | 0 src/{sound_pas16.c => SOUND/snd_pas16.c} | 24 +- src/{sound_pas16.h => SOUND/snd_pas16.h} | 0 src/{sound_ps1.c => SOUND/snd_ps1.c} | 14 +- src/{sound_ps1.h => SOUND/snd_ps1.h} | 0 src/{sound_pssj.c => SOUND/snd_pssj.c} | 16 +- src/{sound_pssj.h => SOUND/snd_pssj.h} | 0 src/{sound_resid.cc => SOUND/snd_resid.cc} | 7 +- src/{sound_resid.h => SOUND/snd_resid.h} | 0 src/{sound_sb.c => SOUND/snd_sb.c} | 24 +- src/{sound_sb.h => SOUND/snd_sb.h} | 0 src/{sound_sb_dsp.c => SOUND/snd_sb_dsp.c} | 17 +- src/{sound_sb_dsp.h => SOUND/snd_sb_dsp.h} | 0 src/{sound_sn76489.c => SOUND/snd_sn76489.c} | 10 +- src/{sound_sn76489.h => SOUND/snd_sn76489.h} | 0 src/{sound_speaker.c => SOUND/snd_speaker.c} | 20 +- src/{sound_speaker.h => SOUND/snd_speaker.h} | 0 src/{sound_ssi2001.c => SOUND/snd_ssi2001.c} | 10 +- src/{sound_ssi2001.h => SOUND/snd_ssi2001.h} | 0 src/{sound_wss.c => SOUND/snd_wss.c} | 21 +- src/{sound_wss.h => SOUND/snd_wss.h} | 0 src/{sound_ym7128.c => SOUND/snd_ym7128.c} | 6 +- src/{sound_ym7128.h => SOUND/snd_ym7128.h} | 0 src/{ => SOUND}/sound.c | 32 +- src/{ => SOUND}/sound.h | 2 - src/{ => VIDEO}/vid_ati18800.c | 11 +- src/{ => VIDEO}/vid_ati18800.h | 0 src/{ => VIDEO}/vid_ati28800.c | 13 +- src/{ => VIDEO}/vid_ati28800.h | 0 src/{ => VIDEO}/vid_ati68860_ramdac.c | 5 +- src/{ => VIDEO}/vid_ati68860_ramdac.h | 0 src/{ => VIDEO}/vid_ati_eeprom.c | 7 +- src/{ => VIDEO}/vid_ati_eeprom.h | 0 src/{ => VIDEO}/vid_ati_mach64.c | 15 +- src/{ => VIDEO}/vid_ati_mach64.h | 0 src/{ => VIDEO}/vid_bt485_ramdac.c | 5 +- src/{ => VIDEO}/vid_bt485_ramdac.h | 0 src/{ => VIDEO}/vid_cga.c | 15 +- src/{ => VIDEO}/vid_cga.h | 0 src/{dosbox => VIDEO}/vid_cga_comp.c | 4 +- src/{dosbox => VIDEO}/vid_cga_comp.h | 0 src/{ => VIDEO}/vid_cl5429.h | 0 src/{ => VIDEO}/vid_cl_gd.c | 13 +- src/{ => VIDEO}/vid_cl_gd.h | 0 src/{ => VIDEO}/vid_cl_gd_blit.c | 11 +- src/{ => VIDEO}/vid_cl_gd_blit.h | 0 src/{ => VIDEO}/vid_cl_gd_vga_rop.h | 0 src/{ => VIDEO}/vid_cl_gd_vga_rop2.h | 0 src/{ => VIDEO}/vid_cl_ramdac.c | 11 +- src/{ => VIDEO}/vid_cl_ramdac.h | 0 src/{ => VIDEO}/vid_colorplus.c | 13 +- src/{ => VIDEO}/vid_colorplus.h | 0 src/{ => VIDEO}/vid_ega.c | 13 +- src/{ => VIDEO}/vid_ega.h | 0 src/{ => VIDEO}/vid_et4000.c | 12 +- src/{ => VIDEO}/vid_et4000.h | 0 src/{ => VIDEO}/vid_et4000w32.c | 15 +- src/{ => VIDEO}/vid_et4000w32.h | 0 src/{ => VIDEO}/vid_et4000w32i.c | 0 src/{ => VIDEO}/vid_genius.c | 14 +- src/{ => VIDEO}/vid_genius.h | 0 src/{ => VIDEO}/vid_hercules.c | 13 +- src/{ => VIDEO}/vid_hercules.h | 0 src/{ => VIDEO}/vid_herculesplus.c | 10 +- src/{ => VIDEO}/vid_herculesplus.h | 0 src/{ => VIDEO}/vid_icd2061.c | 3 +- src/{ => VIDEO}/vid_icd2061.h | 0 src/{ => VIDEO}/vid_ics2595.c | 6 +- src/{ => VIDEO}/vid_ics2595.h | 0 src/{ => VIDEO}/vid_incolor.c | 11 +- src/{ => VIDEO}/vid_incolor.h | 0 src/{ => VIDEO}/vid_mda.c | 13 +- src/{ => VIDEO}/vid_mda.h | 0 src/{ => VIDEO}/vid_nv_riva128.c | 19 +- src/{ => VIDEO}/vid_nv_riva128.h | 0 src/{ => VIDEO}/vid_olivetti_m24.c | 11 +- src/{ => VIDEO}/vid_olivetti_m24.h | 0 src/{ => VIDEO}/vid_oti067.c | 11 +- src/{ => VIDEO}/vid_oti067.h | 0 src/{ => VIDEO}/vid_paradise.c | 11 +- src/{ => VIDEO}/vid_paradise.h | 0 src/{ => VIDEO}/vid_pc1512.c | 11 +- src/{ => VIDEO}/vid_pc1512.h | 0 src/{ => VIDEO}/vid_pc1640.c | 13 +- src/{ => VIDEO}/vid_pc1640.h | 0 src/{ => VIDEO}/vid_pc200.c | 11 +- src/{ => VIDEO}/vid_pc200.h | 0 src/{ => VIDEO}/vid_pcjr.c | 16 +- src/{ => VIDEO}/vid_pcjr.h | 0 src/{ => VIDEO}/vid_ps1_svga.c | 11 +- src/{ => VIDEO}/vid_ps1_svga.h | 0 src/{ => VIDEO}/vid_s3.c | 15 +- src/{ => VIDEO}/vid_s3.h | 0 src/{ => VIDEO}/vid_s3_virge.c | 15 +- src/{ => VIDEO}/vid_s3_virge.h | 0 src/{ => VIDEO}/vid_sdac_ramdac.c | 5 +- src/{ => VIDEO}/vid_sdac_ramdac.h | 0 src/{ => VIDEO}/vid_stg_ramdac.c | 6 +- src/{ => VIDEO}/vid_stg_ramdac.h | 0 src/{ => VIDEO}/vid_svga.c | 12 +- src/{ => VIDEO}/vid_svga.h | 0 src/{ => VIDEO}/vid_svga_render.c | 8 +- src/{ => VIDEO}/vid_svga_render.h | 0 src/{ => VIDEO}/vid_tandy.c | 14 +- src/{ => VIDEO}/vid_tandy.h | 0 src/{ => VIDEO}/vid_tandysl.c | 11 +- src/{ => VIDEO}/vid_tandysl.h | 0 src/{ => VIDEO}/vid_tgui9440.c | 15 +- src/{ => VIDEO}/vid_tgui9440.h | 0 src/{ => VIDEO}/vid_tkd8001_ramdac.c | 5 +- src/{ => VIDEO}/vid_tkd8001_ramdac.h | 0 src/{ => VIDEO}/vid_tvga.c | 11 +- src/{ => VIDEO}/vid_tvga.h | 0 src/{ => VIDEO}/vid_unk_ramdac.c | 5 +- src/{ => VIDEO}/vid_unk_ramdac.h | 0 src/{ => VIDEO}/vid_vga.c | 11 +- src/{ => VIDEO}/vid_vga.h | 0 src/{ => VIDEO}/vid_voodoo.c | 16 +- src/{ => VIDEO}/vid_voodoo.h | 0 src/{ => VIDEO}/vid_voodoo_codegen_x86-64.h | 0 src/{ => VIDEO}/vid_voodoo_codegen_x86.h | 0 src/{ => VIDEO}/vid_voodoo_dither.h | 0 src/{ => VIDEO}/vid_wy700.c | 12 +- src/{ => VIDEO}/vid_wy700.h | 0 src/{ => VIDEO}/video.c | 32 +- src/{ => VIDEO}/video.h | 8 +- src/acer386sx.c | 5 +- src/ali1429.c | 2 +- src/buslogic.h | 27 - src/cdrom.c | 16 +- src/config.c | 6 +- src/config.h | 4 +- src/device.c | 5 +- src/dma.c | 25 +- src/dma.h | 24 +- src/gameport.c | 6 +- src/headland.c | 2 +- src/intel.c | 4 +- src/intel_flash.c | 38 +- src/io.c | 5 +- src/keyboard_amstrad.c | 6 +- src/keyboard_at.c | 11 +- src/keyboard_olim24.c | 9 +- src/keyboard_pcjr.c | 11 +- src/keyboard_xt.c | 12 +- src/mem.c | 13 +- src/model.c | 19 +- src/mouse.c | 57 +- src/mouse.h | 13 +- src/mouse_bus.c | 203 +++-- src/mouse_serial.c | 14 +- src/ne2000.h | 10 - src/{ne2000.c => net_ne2000.c} | 41 +- src/net_ne2000.h | 19 + src/nethandler.c | 139 --- src/nethandler.h | 20 - src/network.c | 154 ++++ src/network.h | 31 + src/opti495.c | 2 +- src/pc.c | 115 ++- src/pit.c | 11 +- src/ps2_mca.c | 11 +- src/resource.h | 56 +- src/scsi.c | 4 +- src/scsi.h | 4 +- src/scsi_aha154x.c | 48 +- src/scsi_buslogic.c | 6 +- src/scsi_buslogic.h | 4 +- src/{scsi_hd.c => scsi_disk.c} | 0 src/serial.c | 848 ++++++++++++------ src/serial.h | 79 +- src/sio.c | 3 +- src/timer.h | 1 - src/win-d3d-fs.cc | 31 +- src/win-d3d.cc | 27 +- src/win-ddraw-fs.cc | 13 +- src/win-ddraw-screenshot.cc | 13 +- src/win-ddraw-screenshot.h | 2 +- src/win-ddraw.cc | 13 +- src/win-keyboard.cc | 60 -- src/{serial_bh.c => win-serial.c} | 4 +- src/{serial_bh.h => win-serial.h} | 2 +- src/win-settings.c | 61 +- src/win-status.c | 10 +- src/win-video.c | 4 +- src/win.c | 39 +- src/xtide.c | 35 +- 344 files changed, 2011 insertions(+), 1870 deletions(-) delete mode 100644 src/CMakeModules/FindD3D9.cmake delete mode 100644 src/CMakeModules/FindDirectDraw.cmake delete mode 100644 src/CMakeModules/FindDirectInput.cmake rename src/{ => CPU}/386.c (99%) rename src/{ => CPU}/386.h (100%) rename src/{ => CPU}/386_common.h (100%) rename src/{ => CPU}/386_dynarec.c (99%) rename src/{ => CPU}/386_dynarec_ops.c (97%) rename src/{ => CPU}/386_ops.h (100%) rename src/{ => CPU}/808x.c (99%) rename src/{ => CPU}/codegen.c (94%) rename src/{ => CPU}/codegen.h (100%) rename src/{ => CPU}/codegen_ops.c (99%) rename src/{ => CPU}/codegen_ops.h (100%) rename src/{ => CPU}/codegen_ops_arith.h (100%) rename src/{ => CPU}/codegen_ops_fpu.h (100%) rename src/{ => CPU}/codegen_ops_jump.h (100%) rename src/{ => CPU}/codegen_ops_logic.h (100%) rename src/{ => CPU}/codegen_ops_misc.h (100%) rename src/{ => CPU}/codegen_ops_mmx.h (100%) rename src/{ => CPU}/codegen_ops_mov.h (100%) rename src/{ => CPU}/codegen_ops_shift.h (100%) rename src/{ => CPU}/codegen_ops_stack.h (100%) rename src/{ => CPU}/codegen_ops_x86-64.h (100%) rename src/{ => CPU}/codegen_ops_x86.h (100%) rename src/{ => CPU}/codegen_ops_xchg.h (100%) rename src/{ => CPU}/codegen_timing_486.c (99%) rename src/{ => CPU}/codegen_timing_686.c (99%) rename src/{ => CPU}/codegen_timing_pentium.c (99%) rename src/{ => CPU}/codegen_timing_winchip.c (99%) rename src/{ => CPU}/codegen_x86-64.c (100%) rename src/{ => CPU}/codegen_x86-64.h (100%) rename src/{ => CPU}/codegen_x86.c (99%) rename src/{ => CPU}/codegen_x86.h (100%) rename src/{ => CPU}/cpu.c (99%) rename src/{ => CPU}/cpu.h (100%) rename src/{ => CPU}/x86.h (100%) rename src/{ => CPU}/x86_flags.h (100%) rename src/{ => CPU}/x86_ops.h (100%) rename src/{ => CPU}/x86_ops_arith.h (100%) rename src/{ => CPU}/x86_ops_atomic.h (100%) rename src/{ => CPU}/x86_ops_bcd.h (100%) rename src/{ => CPU}/x86_ops_bit.h (100%) rename src/{ => CPU}/x86_ops_bitscan.h (100%) rename src/{ => CPU}/x86_ops_call.h (100%) rename src/{ => CPU}/x86_ops_flag.h (100%) rename src/{ => CPU}/x86_ops_fpu.h (100%) rename src/{ => CPU}/x86_ops_i686.h (100%) rename src/{ => CPU}/x86_ops_inc_dec.h (100%) rename src/{ => CPU}/x86_ops_int.h (100%) rename src/{ => CPU}/x86_ops_io.h (100%) rename src/{ => CPU}/x86_ops_jump.h (100%) rename src/{ => CPU}/x86_ops_misc.h (100%) rename src/{ => CPU}/x86_ops_mmx.h (100%) rename src/{ => CPU}/x86_ops_mmx_arith.h (100%) rename src/{ => CPU}/x86_ops_mmx_cmp.h (100%) rename src/{ => CPU}/x86_ops_mmx_logic.h (100%) rename src/{ => CPU}/x86_ops_mmx_mov.h (100%) rename src/{ => CPU}/x86_ops_mmx_pack.h (100%) rename src/{ => CPU}/x86_ops_mmx_shift.h (100%) rename src/{ => CPU}/x86_ops_mov.h (100%) rename src/{ => CPU}/x86_ops_mov_ctrl.h (100%) rename src/{ => CPU}/x86_ops_mov_seg.h (100%) rename src/{ => CPU}/x86_ops_movx.h (100%) rename src/{ => CPU}/x86_ops_msr.h (100%) rename src/{ => CPU}/x86_ops_mul.h (100%) rename src/{ => CPU}/x86_ops_pmode.h (100%) rename src/{ => CPU}/x86_ops_prefix.h (100%) rename src/{ => CPU}/x86_ops_rep.h (100%) rename src/{ => CPU}/x86_ops_ret.h (100%) rename src/{ => CPU}/x86_ops_set.h (100%) rename src/{ => CPU}/x86_ops_shift.h (100%) rename src/{ => CPU}/x86_ops_stack.h (100%) rename src/{ => CPU}/x86_ops_string.h (100%) rename src/{ => CPU}/x86_ops_xchg.h (100%) rename src/{ => CPU}/x86seg.c (99%) rename src/{ => CPU}/x86seg.h (100%) rename src/{ => CPU}/x87.c (98%) rename src/{ => CPU}/x87.h (100%) rename src/{ => CPU}/x87_ops.h (100%) rename src/{ => CPU}/x87_ops_arith.h (100%) rename src/{ => CPU}/x87_ops_loadstore.h (100%) rename src/{ => CPU}/x87_ops_misc.h (100%) rename src/{dosbox => SOUND}/dbopl.cpp (100%) rename src/{dosbox => SOUND}/dbopl.h (100%) rename src/{ => SOUND}/filters.h (100%) rename src/{dosbox => SOUND}/nukedopl.cpp (100%) rename src/{dosbox => SOUND}/nukedopl.h (100%) rename src/{soundopenal.c => SOUND/openal.c} (96%) rename src/{ => SOUND}/resid-fp/AUTHORS (100%) rename src/{ => SOUND}/resid-fp/COPYING (100%) rename src/{ => SOUND}/resid-fp/ChangeLog (100%) rename src/{ => SOUND}/resid-fp/INSTALL (100%) rename src/{ => SOUND}/resid-fp/Makefile.am (100%) rename src/{ => SOUND}/resid-fp/Makefile.in (100%) rename src/{ => SOUND}/resid-fp/NEWS (100%) rename src/{ => SOUND}/resid-fp/README (100%) rename src/{ => SOUND}/resid-fp/README.VICE (100%) rename src/{ => SOUND}/resid-fp/aclocal.m4 (100%) rename src/{ => SOUND}/resid-fp/configure (100%) rename src/{ => SOUND}/resid-fp/configure.in (100%) rename src/{ => SOUND}/resid-fp/convolve-sse.cc (100%) rename src/{ => SOUND}/resid-fp/convolve.cc (100%) rename src/{ => SOUND}/resid-fp/envelope.cc (100%) rename src/{ => SOUND}/resid-fp/envelope.h (100%) rename src/{ => SOUND}/resid-fp/extfilt.cc (100%) rename src/{ => SOUND}/resid-fp/extfilt.h (100%) rename src/{ => SOUND}/resid-fp/filter.cc (100%) rename src/{ => SOUND}/resid-fp/filter.h (100%) rename src/{ => SOUND}/resid-fp/pot.cc (100%) rename src/{ => SOUND}/resid-fp/pot.h (100%) rename src/{ => SOUND}/resid-fp/samp2src.pl (100%) rename src/{ => SOUND}/resid-fp/sid.cc (100%) rename src/{ => SOUND}/resid-fp/sid.h (100%) rename src/{ => SOUND}/resid-fp/siddefs-fp.h (100%) rename src/{ => SOUND}/resid-fp/siddefs-fp.h.in (100%) rename src/{ => SOUND}/resid-fp/version.cc (100%) rename src/{ => SOUND}/resid-fp/voice.cc (100%) rename src/{ => SOUND}/resid-fp/voice.h (100%) rename src/{ => SOUND}/resid-fp/wave.cc (100%) rename src/{ => SOUND}/resid-fp/wave.h (100%) rename src/{ => SOUND}/resid-fp/wave6581_PST.cc (100%) rename src/{ => SOUND}/resid-fp/wave6581_PST.dat (100%) rename src/{ => SOUND}/resid-fp/wave6581_PS_.cc (100%) rename src/{ => SOUND}/resid-fp/wave6581_PS_.dat (100%) rename src/{ => SOUND}/resid-fp/wave6581_P_T.cc (100%) rename src/{ => SOUND}/resid-fp/wave6581_P_T.dat (100%) rename src/{ => SOUND}/resid-fp/wave6581__ST.cc (100%) rename src/{ => SOUND}/resid-fp/wave6581__ST.dat (100%) rename src/{ => SOUND}/resid-fp/wave8580_PST.cc (100%) rename src/{ => SOUND}/resid-fp/wave8580_PST.dat (100%) rename src/{ => SOUND}/resid-fp/wave8580_PS_.cc (100%) rename src/{ => SOUND}/resid-fp/wave8580_PS_.dat (100%) rename src/{ => SOUND}/resid-fp/wave8580_P_T.cc (100%) rename src/{ => SOUND}/resid-fp/wave8580_P_T.dat (100%) rename src/{ => SOUND}/resid-fp/wave8580__ST.cc (100%) rename src/{ => SOUND}/resid-fp/wave8580__ST.dat (100%) rename src/{sound_ad1848.c => SOUND/snd_ad1848.c} (98%) rename src/{sound_ad1848.h => SOUND/snd_ad1848.h} (97%) rename src/{sound_adlib.c => SOUND/snd_adlib.c} (95%) rename src/{sound_adlib.h => SOUND/snd_adlib.h} (100%) rename src/{sound_adlibgold.c => SOUND/snd_adlibgold.c} (99%) rename src/{sound_adlibgold.h => SOUND/snd_adlibgold.h} (100%) rename src/{sound_cms.c => SOUND/snd_cms.c} (98%) rename src/{sound_cms.h => SOUND/snd_cms.h} (100%) rename src/{sound_dbopl.cc => SOUND/snd_dbopl.cc} (98%) rename src/{sound_dbopl.h => SOUND/snd_dbopl.h} (100%) rename src/{sound_emu8k.c => SOUND/snd_emu8k.c} (99%) rename src/{sound_emu8k.h => SOUND/snd_emu8k.h} (100%) rename src/{sound_gus.c => SOUND/snd_gus.c} (99%) rename src/{sound_gus.h => SOUND/snd_gus.h} (100%) rename src/{sound_mpu401_uart.c => SOUND/snd_mpu401_uart.c} (93%) rename src/{sound_mpu401_uart.h => SOUND/snd_mpu401_uart.h} (100%) rename src/{sound_opl.c => SOUND/snd_opl.c} (97%) rename src/{sound_opl.h => SOUND/snd_opl.h} (100%) rename src/{sound_pas16.c => SOUND/snd_pas16.c} (99%) rename src/{sound_pas16.h => SOUND/snd_pas16.h} (100%) rename src/{sound_ps1.c => SOUND/snd_ps1.c} (96%) rename src/{sound_ps1.h => SOUND/snd_ps1.h} (100%) rename src/{sound_pssj.c => SOUND/snd_pssj.c} (97%) rename src/{sound_pssj.h => SOUND/snd_pssj.h} (100%) rename src/{sound_resid.cc => SOUND/snd_resid.cc} (98%) rename src/{sound_resid.h => SOUND/snd_resid.h} (100%) rename src/{sound_sb.c => SOUND/snd_sb.c} (99%) rename src/{sound_sb.h => SOUND/snd_sb.h} (100%) rename src/{sound_sb_dsp.c => SOUND/snd_sb_dsp.c} (99%) rename src/{sound_sb_dsp.h => SOUND/snd_sb_dsp.h} (100%) rename src/{sound_sn76489.c => SOUND/snd_sn76489.c} (99%) rename src/{sound_sn76489.h => SOUND/snd_sn76489.h} (100%) rename src/{sound_speaker.c => SOUND/snd_speaker.c} (93%) rename src/{sound_speaker.h => SOUND/snd_speaker.h} (100%) rename src/{sound_ssi2001.c => SOUND/snd_ssi2001.c} (94%) rename src/{sound_ssi2001.h => SOUND/snd_ssi2001.h} (100%) rename src/{sound_wss.c => SOUND/snd_wss.c} (93%) rename src/{sound_wss.h => SOUND/snd_wss.h} (100%) rename src/{sound_ym7128.c => SOUND/snd_ym7128.c} (99%) rename src/{sound_ym7128.h => SOUND/snd_ym7128.h} (100%) rename src/{ => SOUND}/sound.c (96%) rename src/{ => SOUND}/sound.h (97%) rename src/{ => VIDEO}/vid_ati18800.c (98%) rename src/{ => VIDEO}/vid_ati18800.h (100%) rename src/{ => VIDEO}/vid_ati28800.c (99%) rename src/{ => VIDEO}/vid_ati28800.h (100%) rename src/{ => VIDEO}/vid_ati68860_ramdac.c (99%) rename src/{ => VIDEO}/vid_ati68860_ramdac.h (100%) rename src/{ => VIDEO}/vid_ati_eeprom.c (99%) rename src/{ => VIDEO}/vid_ati_eeprom.h (100%) rename src/{ => VIDEO}/vid_ati_mach64.c (99%) rename src/{ => VIDEO}/vid_ati_mach64.h (100%) rename src/{ => VIDEO}/vid_bt485_ramdac.c (99%) rename src/{ => VIDEO}/vid_bt485_ramdac.h (100%) rename src/{ => VIDEO}/vid_cga.c (99%) rename src/{ => VIDEO}/vid_cga.h (100%) rename src/{dosbox => VIDEO}/vid_cga_comp.c (99%) rename src/{dosbox => VIDEO}/vid_cga_comp.h (100%) rename src/{ => VIDEO}/vid_cl5429.h (100%) rename src/{ => VIDEO}/vid_cl_gd.c (99%) rename src/{ => VIDEO}/vid_cl_gd.h (100%) rename src/{ => VIDEO}/vid_cl_gd_blit.c (99%) rename src/{ => VIDEO}/vid_cl_gd_blit.h (100%) rename src/{ => VIDEO}/vid_cl_gd_vga_rop.h (100%) rename src/{ => VIDEO}/vid_cl_gd_vga_rop2.h (100%) rename src/{ => VIDEO}/vid_cl_ramdac.c (97%) rename src/{ => VIDEO}/vid_cl_ramdac.h (100%) rename src/{ => VIDEO}/vid_colorplus.c (99%) rename src/{ => VIDEO}/vid_colorplus.h (100%) rename src/{ => VIDEO}/vid_ega.c (99%) rename src/{ => VIDEO}/vid_ega.h (100%) rename src/{ => VIDEO}/vid_et4000.c (98%) rename src/{ => VIDEO}/vid_et4000.h (100%) rename src/{ => VIDEO}/vid_et4000w32.c (99%) rename src/{ => VIDEO}/vid_et4000w32.h (100%) rename src/{ => VIDEO}/vid_et4000w32i.c (100%) rename src/{ => VIDEO}/vid_genius.c (99%) rename src/{ => VIDEO}/vid_genius.h (100%) rename src/{ => VIDEO}/vid_hercules.c (99%) rename src/{ => VIDEO}/vid_hercules.h (100%) rename src/{ => VIDEO}/vid_herculesplus.c (99%) rename src/{ => VIDEO}/vid_herculesplus.h (100%) rename src/{ => VIDEO}/vid_icd2061.c (99%) rename src/{ => VIDEO}/vid_icd2061.h (100%) rename src/{ => VIDEO}/vid_ics2595.c (98%) rename src/{ => VIDEO}/vid_ics2595.h (100%) rename src/{ => VIDEO}/vid_incolor.c (99%) rename src/{ => VIDEO}/vid_incolor.h (100%) rename src/{ => VIDEO}/vid_mda.c (98%) rename src/{ => VIDEO}/vid_mda.h (100%) rename src/{ => VIDEO}/vid_nv_riva128.c (99%) rename src/{ => VIDEO}/vid_nv_riva128.h (100%) rename src/{ => VIDEO}/vid_olivetti_m24.c (99%) rename src/{ => VIDEO}/vid_olivetti_m24.h (100%) rename src/{ => VIDEO}/vid_oti067.c (98%) rename src/{ => VIDEO}/vid_oti067.h (100%) rename src/{ => VIDEO}/vid_paradise.c (99%) rename src/{ => VIDEO}/vid_paradise.h (100%) rename src/{ => VIDEO}/vid_pc1512.c (99%) rename src/{ => VIDEO}/vid_pc1512.h (100%) rename src/{ => VIDEO}/vid_pc1640.c (97%) rename src/{ => VIDEO}/vid_pc1640.h (100%) rename src/{ => VIDEO}/vid_pc200.c (97%) rename src/{ => VIDEO}/vid_pc200.h (100%) rename src/{ => VIDEO}/vid_pcjr.c (99%) rename src/{ => VIDEO}/vid_pcjr.h (100%) rename src/{ => VIDEO}/vid_ps1_svga.c (98%) rename src/{ => VIDEO}/vid_ps1_svga.h (100%) rename src/{ => VIDEO}/vid_s3.c (99%) rename src/{ => VIDEO}/vid_s3.h (100%) rename src/{ => VIDEO}/vid_s3_virge.c (99%) rename src/{ => VIDEO}/vid_s3_virge.h (100%) rename src/{ => VIDEO}/vid_sdac_ramdac.c (99%) rename src/{ => VIDEO}/vid_sdac_ramdac.h (100%) rename src/{ => VIDEO}/vid_stg_ramdac.c (99%) rename src/{ => VIDEO}/vid_stg_ramdac.h (100%) rename src/{ => VIDEO}/vid_svga.c (99%) rename src/{ => VIDEO}/vid_svga.h (100%) rename src/{ => VIDEO}/vid_svga_render.c (99%) rename src/{ => VIDEO}/vid_svga_render.h (100%) rename src/{ => VIDEO}/vid_tandy.c (99%) rename src/{ => VIDEO}/vid_tandy.h (100%) rename src/{ => VIDEO}/vid_tandysl.c (99%) rename src/{ => VIDEO}/vid_tandysl.h (100%) rename src/{ => VIDEO}/vid_tgui9440.c (99%) rename src/{ => VIDEO}/vid_tgui9440.h (100%) rename src/{ => VIDEO}/vid_tkd8001_ramdac.c (97%) rename src/{ => VIDEO}/vid_tkd8001_ramdac.h (100%) rename src/{ => VIDEO}/vid_tvga.c (99%) rename src/{ => VIDEO}/vid_tvga.h (100%) rename src/{ => VIDEO}/vid_unk_ramdac.c (98%) rename src/{ => VIDEO}/vid_unk_ramdac.h (100%) rename src/{ => VIDEO}/vid_vga.c (98%) rename src/{ => VIDEO}/vid_vga.h (100%) rename src/{ => VIDEO}/vid_voodoo.c (99%) rename src/{ => VIDEO}/vid_voodoo.h (100%) rename src/{ => VIDEO}/vid_voodoo_codegen_x86-64.h (100%) rename src/{ => VIDEO}/vid_voodoo_codegen_x86.h (100%) rename src/{ => VIDEO}/vid_voodoo_dither.h (100%) rename src/{ => VIDEO}/vid_wy700.c (99%) rename src/{ => VIDEO}/vid_wy700.h (100%) rename src/{ => VIDEO}/video.c (97%) rename src/{ => VIDEO}/video.h (93%) delete mode 100644 src/buslogic.h delete mode 100644 src/ne2000.h rename src/{ne2000.c => net_ne2000.c} (99%) create mode 100644 src/net_ne2000.h delete mode 100644 src/nethandler.c delete mode 100644 src/nethandler.h create mode 100644 src/network.c create mode 100644 src/network.h rename src/{scsi_hd.c => scsi_disk.c} (100%) delete mode 100644 src/win-keyboard.cc rename src/{serial_bh.c => win-serial.c} (99%) rename src/{serial_bh.h => win-serial.h} (96%) diff --git a/src/86Box.rc b/src/86Box.rc index c72678d63..a36f17ca4 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -708,10 +708,10 @@ BEGIN 2137 "Mid VLB/PCI" 2138 "Fast VLB/PCI" 2139 "Microsoft 2-button mouse (serial)" - 2140 "2-button mouse (PS/2)" - 2141 "Microsoft Intellimouse (PS/2)" - 2142 "Amstrad mouse" - 2143 "Olivetti M24 mouse" + 2140 "Mouse Systems mouse (serial)" + 2141 "2-button mouse (PS/2)" + 2142 "Microsoft Intellimouse (PS/2)" + 2143 "Bus mouse" END STRINGTABLE DISCARDABLE @@ -733,8 +733,8 @@ BEGIN 2158 "SCSI (%02i:%02i)" 2159 "IDE (PIO-only)" 2160 "%" PRIu64 - 2161 "Microsoft Bus mouse" - 2162 "Mouse Systems mouse" + 2161 "Genius Bus mouse" + 2162 "Amstrad mouse" 2163 "Attempting to create a spuriously large hard disk image" 2164 "Invalid number of sectors (valid values are between 1 and 99)" 2165 "Invalid number of cylinders (valid values are between 1 and 1023)" @@ -749,8 +749,8 @@ BEGIN 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" 2175 "CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0" 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2177 "Microsoft InPort mouse" - 2178 "Genius Bus mouse" + 2177 "Olivetti M24 mouse" + 2178 "" 2179 "Floppy %i (%s): %ws" 2180 "CD-ROM %i: %ws" 2181 "Removable disk %i: %s" diff --git a/src/CMakeModules/FindD3D9.cmake b/src/CMakeModules/FindD3D9.cmake deleted file mode 100644 index 6e7ed3237..000000000 --- a/src/CMakeModules/FindD3D9.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# Locate directdraw -# This module defines -# D3D9_LIBRARIES -# D3D9_FOUND, if false, do not try to link to directinput -# D3D9_INCLUDE_DIR, where to find the headers -# -# $D3D9_DIR is an environment variable that would -# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow) -# -# Created by Cedric Pinson. -# - -SET( D3D9_FOUND FALSE ) - -IF( WIN32 ) - FIND_PATH( D3D9_ROOT_DIR Include/D3D9.h - PATHS - $ENV{PATH} - $ENV{PROGRAMFILES} - ) - - FIND_PATH( D3D9_INCLUDE_DIR d3d9.h - PATHS - ${D3D9_ROOT_DIR}/Include - ) - - FIND_LIBRARY( D3D9_LIBRARY d3d9.lib d3dx9 - PATHS - ${D3D9_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( D3D9_GUID_LIBRARY dxguid.lib - PATHS - ${D3D9_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( D3D9_ERR_LIBRARY dxerr.lib - PATHS - ${D3D9_ROOT_DIR}/lib/x86 - ) - - SET( D3D9_LIBRARIES - ${D3D9_LIBRARY} - ${D3D9_GUID_LIBRARY} - ${D3D9_ERR_LIBRARY} - ) - - IF ( D3D9_INCLUDE_DIR AND D3D9_LIBRARIES ) - SET( D3D9_FOUND TRUE ) - ENDIF ( D3D9_INCLUDE_DIR AND D3D9_LIBRARIES ) -ENDIF( WIN32 ) - -MARK_AS_ADVANCED( D3D9_FOUND ) \ No newline at end of file diff --git a/src/CMakeModules/FindDirectDraw.cmake b/src/CMakeModules/FindDirectDraw.cmake deleted file mode 100644 index c5f995313..000000000 --- a/src/CMakeModules/FindDirectDraw.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# Locate directdraw -# This module defines -# DDRAW_LIBRARIES -# DDRAW_FOUND, if false, do not try to link to directinput -# DDRAW_INCLUDE_DIR, where to find the headers -# -# $DDRAW_DIR is an environment variable that would -# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow) -# -# Created by Cedric Pinson. -# - -SET( DDRAW_FOUND FALSE ) - -IF( WIN32 ) - FIND_PATH( DDRAW_ROOT_DIR Include/D3D10.h - PATHS - $ENV{PATH} - $ENV{PROGRAMFILES} - ) - - FIND_PATH( DDRAW_INCLUDE_DIR ddraw.h - PATHS - ${DDRAW_ROOT_DIR}/Include - ) - - FIND_LIBRARY( DDRAW_LIBRARY ddraw.lib - PATHS - ${DDRAW_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DDRAW_GUID_LIBRARY dxguid.lib - PATHS - ${DDRAW_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DDRAW_ERR_LIBRARY dxerr.lib - PATHS - ${DDRAW_ROOT_DIR}/lib/x86 - ) - - SET( DDRAW_LIBRARIES - ${DDRAW_LIBRARY} - ${DDRAW_GUID_LIBRARY} - ${DDRAW_ERR_LIBRARY} - ) - - IF ( DDRAW_INCLUDE_DIR AND DDRAW_LIBRARIES ) - SET( DDRAW_FOUND TRUE ) - ENDIF ( DDRAW_INCLUDE_DIR AND DDRAW_LIBRARIES ) -ENDIF( WIN32 ) - -MARK_AS_ADVANCED( DDRAW_FOUND ) \ No newline at end of file diff --git a/src/CMakeModules/FindDirectInput.cmake b/src/CMakeModules/FindDirectInput.cmake deleted file mode 100644 index b7b457527..000000000 --- a/src/CMakeModules/FindDirectInput.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# Locate directinput -# This module defines -# DIRECTINPUT_LIBRARIES -# DIRECTINPUT_FOUND, if false, do not try to link to directinput -# DIRECTINPUT_INCLUDE_DIR, where to find the headers -# -# $DIRECTINPUT_DIR is an environment variable that would -# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow) -# -# Created by Cedric Pinson. -# - -SET( DIRECTINPUT_FOUND FALSE ) - -IF( WIN32 ) - FIND_PATH( DIRECTINPUT_ROOT_DIR Include/D3D10.h - PATHS - $ENV{PATH} - $ENV{PROGRAMFILES} - ) - - FIND_PATH( DIRECTINPUT_INCLUDE_DIR dinput.h - PATHS - ${DIRECTINPUT_ROOT_DIR}/Include - ) - - FIND_LIBRARY( DIRECTINPUT_LIBRARY dinput7.lib dinput8.lib - PATHS - ${DIRECTINPUT_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DIRECTINPUT_GUID_LIBRARY dxguid.lib - PATHS - ${DIRECTINPUT_ROOT_DIR}/lib/x86 - ) - - FIND_LIBRARY( DIRECTINPUT_ERR_LIBRARY dxerr.lib - PATHS - ${DIRECTINPUT_ROOT_DIR}/lib/x86 - ) - - SET( DIRECTINPUT_LIBRARIES - ${DIRECTINPUT_LIBRARY} - ${DIRECTINPUT_GUID_LIBRARY} - ${DIRECTINPUT_ERR_LIBRARY} - ) - - IF ( DIRECTINPUT_INCLUDE_DIR AND DIRECTINPUT_LIBRARIES ) - SET( DIRECTINPUT_FOUND TRUE ) - ENDIF ( DIRECTINPUT_INCLUDE_DIR AND DIRECTINPUT_LIBRARIES ) -ENDIF( WIN32 ) - -MARK_AS_ADVANCED( DIRECTINPUT_FOUND ) \ No newline at end of file diff --git a/src/386.c b/src/CPU/386.c similarity index 99% rename from src/386.c rename to src/CPU/386.c index 256a1ce88..6bd69af85 100644 --- a/src/386.c +++ b/src/CPU/386.c @@ -5,15 +5,15 @@ #include #include #include -#include "ibm.h" +#include "../ibm.h" +#include "cpu.h" #include "x86.h" #include "x87.h" -#include "mem.h" -#include "cpu.h" -#include "disc.h" -#include "fdc.h" -#include "pic.h" -#include "timer.h" +#include "../mem.h" +#include "../disc.h" +#include "../fdc.h" +#include "../pic.h" +#include "../timer.h" #include "386_common.h" diff --git a/src/386.h b/src/CPU/386.h similarity index 100% rename from src/386.h rename to src/CPU/386.h diff --git a/src/386_common.h b/src/CPU/386_common.h similarity index 100% rename from src/386_common.h rename to src/CPU/386_common.h diff --git a/src/386_dynarec.c b/src/CPU/386_dynarec.c similarity index 99% rename from src/386_dynarec.c rename to src/CPU/386_dynarec.c index 69a3df8a8..06066223f 100644 --- a/src/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -5,17 +5,17 @@ #include #include #include -#include "ibm.h" +#include "../ibm.h" +#include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" +#include "../mem.h" #include "codegen.h" -#include "cpu.h" -#include "disc.h" -#include "fdc.h" -#include "pic.h" -#include "timer.h" +#include "../disc.h" +#include "../fdc.h" +#include "../pic.h" +#include "../timer.h" #include "386_common.h" diff --git a/src/386_dynarec_ops.c b/src/CPU/386_dynarec_ops.c similarity index 97% rename from src/386_dynarec_ops.c rename to src/CPU/386_dynarec_ops.c index 7b5a5c7f5..e0e018872 100644 --- a/src/386_dynarec_ops.c +++ b/src/CPU/386_dynarec_ops.c @@ -2,15 +2,15 @@ #ifndef INFINITY # define INFINITY (__builtin_inff()) #endif -#include "ibm.h" +#include "../ibm.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" #include "x86_flags.h" -#include "mem.h" +#include "../mem.h" #include "codegen.h" -#include "pic.h" +#include "../pic.h" #define CPU_BLOCK_END() cpu_block_end = 1 diff --git a/src/386_ops.h b/src/CPU/386_ops.h similarity index 100% rename from src/386_ops.h rename to src/CPU/386_ops.h diff --git a/src/808x.c b/src/CPU/808x.c similarity index 99% rename from src/808x.c rename to src/CPU/808x.c index 6f72fb613..297782386 100644 --- a/src/808x.c +++ b/src/CPU/808x.c @@ -12,16 +12,14 @@ 2 clocks - fetch opcode 2 etc*/ #include #include - -#include "ibm.h" - +#include "../ibm.h" #include "cpu.h" -#include "keyboard.h" -#include "mem.h" -#include "nmi.h" -#include "pic.h" -#include "timer.h" #include "x86.h" +#include "../keyboard.h" +#include "../mem.h" +#include "../nmi.h" +#include "../pic.h" +#include "../timer.h" int xt_cpu_multi; int nmi = 0; @@ -481,7 +479,7 @@ void dumpregs(int force) #ifndef RELEASE_BUILD indump = 1; output=0; - chdir(pcempath); + _wchdir(pcempath); nopageerrors=1; f=fopen("ram.dmp","wb"); fwrite(ram,mem_size*1024,1,f); diff --git a/src/codegen.c b/src/CPU/codegen.c similarity index 94% rename from src/codegen.c rename to src/CPU/codegen.c index 5667c9bad..afe795601 100644 --- a/src/codegen.c +++ b/src/CPU/codegen.c @@ -1,6 +1,6 @@ -#include "ibm.h" +#include "../ibm.h" #include "x86_ops.h" -#include "mem.h" +#include "../mem.h" #include "codegen.h" void (*codegen_timing_start)(); diff --git a/src/codegen.h b/src/CPU/codegen.h similarity index 100% rename from src/codegen.h rename to src/CPU/codegen.h diff --git a/src/codegen_ops.c b/src/CPU/codegen_ops.c similarity index 99% rename from src/codegen_ops.c rename to src/CPU/codegen_ops.c index a1f846a52..2bd6550e2 100644 --- a/src/codegen_ops.c +++ b/src/CPU/codegen_ops.c @@ -1,4 +1,5 @@ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "x86.h" #include "x86_ops.h" #include "x86_flags.h" diff --git a/src/codegen_ops.h b/src/CPU/codegen_ops.h similarity index 100% rename from src/codegen_ops.h rename to src/CPU/codegen_ops.h diff --git a/src/codegen_ops_arith.h b/src/CPU/codegen_ops_arith.h similarity index 100% rename from src/codegen_ops_arith.h rename to src/CPU/codegen_ops_arith.h diff --git a/src/codegen_ops_fpu.h b/src/CPU/codegen_ops_fpu.h similarity index 100% rename from src/codegen_ops_fpu.h rename to src/CPU/codegen_ops_fpu.h diff --git a/src/codegen_ops_jump.h b/src/CPU/codegen_ops_jump.h similarity index 100% rename from src/codegen_ops_jump.h rename to src/CPU/codegen_ops_jump.h diff --git a/src/codegen_ops_logic.h b/src/CPU/codegen_ops_logic.h similarity index 100% rename from src/codegen_ops_logic.h rename to src/CPU/codegen_ops_logic.h diff --git a/src/codegen_ops_misc.h b/src/CPU/codegen_ops_misc.h similarity index 100% rename from src/codegen_ops_misc.h rename to src/CPU/codegen_ops_misc.h diff --git a/src/codegen_ops_mmx.h b/src/CPU/codegen_ops_mmx.h similarity index 100% rename from src/codegen_ops_mmx.h rename to src/CPU/codegen_ops_mmx.h diff --git a/src/codegen_ops_mov.h b/src/CPU/codegen_ops_mov.h similarity index 100% rename from src/codegen_ops_mov.h rename to src/CPU/codegen_ops_mov.h diff --git a/src/codegen_ops_shift.h b/src/CPU/codegen_ops_shift.h similarity index 100% rename from src/codegen_ops_shift.h rename to src/CPU/codegen_ops_shift.h diff --git a/src/codegen_ops_stack.h b/src/CPU/codegen_ops_stack.h similarity index 100% rename from src/codegen_ops_stack.h rename to src/CPU/codegen_ops_stack.h diff --git a/src/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h similarity index 100% rename from src/codegen_ops_x86-64.h rename to src/CPU/codegen_ops_x86-64.h diff --git a/src/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h similarity index 100% rename from src/codegen_ops_x86.h rename to src/CPU/codegen_ops_x86.h diff --git a/src/codegen_ops_xchg.h b/src/CPU/codegen_ops_xchg.h similarity index 100% rename from src/codegen_ops_xchg.h rename to src/CPU/codegen_ops_xchg.h diff --git a/src/codegen_timing_486.c b/src/CPU/codegen_timing_486.c similarity index 99% rename from src/codegen_timing_486.c rename to src/CPU/codegen_timing_486.c index 19b958931..ddcbc260c 100644 --- a/src/codegen_timing_486.c +++ b/src/CPU/codegen_timing_486.c @@ -1,9 +1,9 @@ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" #define CYCLES(c) (int *)c diff --git a/src/codegen_timing_686.c b/src/CPU/codegen_timing_686.c similarity index 99% rename from src/codegen_timing_686.c rename to src/CPU/codegen_timing_686.c index c4b4cc456..eab10357b 100644 --- a/src/codegen_timing_686.c +++ b/src/CPU/codegen_timing_686.c @@ -7,13 +7,12 @@ - FPU queue - Out of order execution (beyond most simplistic approximation) */ - -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ diff --git a/src/codegen_timing_pentium.c b/src/CPU/codegen_timing_pentium.c similarity index 99% rename from src/codegen_timing_pentium.c rename to src/CPU/codegen_timing_pentium.c index 6d678915e..2812e63ae 100644 --- a/src/codegen_timing_pentium.c +++ b/src/CPU/codegen_timing_pentium.c @@ -8,13 +8,12 @@ - FPU latencies - MMX latencies */ - -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ diff --git a/src/codegen_timing_winchip.c b/src/CPU/codegen_timing_winchip.c similarity index 99% rename from src/codegen_timing_winchip.c rename to src/CPU/codegen_timing_winchip.c index 5d1a26bf3..a76a08e7a 100644 --- a/src/codegen_timing_winchip.c +++ b/src/CPU/codegen_timing_winchip.c @@ -1,9 +1,9 @@ -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "codegen.h" #define CYCLES(c) (int *)c diff --git a/src/codegen_x86-64.c b/src/CPU/codegen_x86-64.c similarity index 100% rename from src/codegen_x86-64.c rename to src/CPU/codegen_x86-64.c diff --git a/src/codegen_x86-64.h b/src/CPU/codegen_x86-64.h similarity index 100% rename from src/codegen_x86-64.h rename to src/CPU/codegen_x86-64.h diff --git a/src/codegen_x86.c b/src/CPU/codegen_x86.c similarity index 99% rename from src/codegen_x86.c rename to src/CPU/codegen_x86.c index e7971c383..a42b32104 100644 --- a/src/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1,13 +1,12 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 - #include -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" #include "386_common.h" diff --git a/src/codegen_x86.h b/src/CPU/codegen_x86.h similarity index 100% rename from src/codegen_x86.h rename to src/CPU/codegen_x86.h diff --git a/src/cpu.c b/src/CPU/cpu.c similarity index 99% rename from src/cpu.c rename to src/CPU/cpu.c index d2e1b26f7..453e8626a 100644 --- a/src/cpu.c +++ b/src/CPU/cpu.c @@ -1,13 +1,13 @@ /* Copyright holders: Sarah Walker, Tenshi, leilei see COPYING for more details */ -#include "ibm.h" +#include "../ibm.h" #include "cpu.h" -#include "model.h" -#include "io.h" +#include "../model.h" +#include "../io.h" #include "x86_ops.h" -#include "mem.h" -#include "pci.h" +#include "../mem.h" +#include "../pci.h" #include "codegen.h" int isa_cycles; diff --git a/src/cpu.h b/src/CPU/cpu.h similarity index 100% rename from src/cpu.h rename to src/CPU/cpu.h diff --git a/src/x86.h b/src/CPU/x86.h similarity index 100% rename from src/x86.h rename to src/CPU/x86.h diff --git a/src/x86_flags.h b/src/CPU/x86_flags.h similarity index 100% rename from src/x86_flags.h rename to src/CPU/x86_flags.h diff --git a/src/x86_ops.h b/src/CPU/x86_ops.h similarity index 100% rename from src/x86_ops.h rename to src/CPU/x86_ops.h diff --git a/src/x86_ops_arith.h b/src/CPU/x86_ops_arith.h similarity index 100% rename from src/x86_ops_arith.h rename to src/CPU/x86_ops_arith.h diff --git a/src/x86_ops_atomic.h b/src/CPU/x86_ops_atomic.h similarity index 100% rename from src/x86_ops_atomic.h rename to src/CPU/x86_ops_atomic.h diff --git a/src/x86_ops_bcd.h b/src/CPU/x86_ops_bcd.h similarity index 100% rename from src/x86_ops_bcd.h rename to src/CPU/x86_ops_bcd.h diff --git a/src/x86_ops_bit.h b/src/CPU/x86_ops_bit.h similarity index 100% rename from src/x86_ops_bit.h rename to src/CPU/x86_ops_bit.h diff --git a/src/x86_ops_bitscan.h b/src/CPU/x86_ops_bitscan.h similarity index 100% rename from src/x86_ops_bitscan.h rename to src/CPU/x86_ops_bitscan.h diff --git a/src/x86_ops_call.h b/src/CPU/x86_ops_call.h similarity index 100% rename from src/x86_ops_call.h rename to src/CPU/x86_ops_call.h diff --git a/src/x86_ops_flag.h b/src/CPU/x86_ops_flag.h similarity index 100% rename from src/x86_ops_flag.h rename to src/CPU/x86_ops_flag.h diff --git a/src/x86_ops_fpu.h b/src/CPU/x86_ops_fpu.h similarity index 100% rename from src/x86_ops_fpu.h rename to src/CPU/x86_ops_fpu.h diff --git a/src/x86_ops_i686.h b/src/CPU/x86_ops_i686.h similarity index 100% rename from src/x86_ops_i686.h rename to src/CPU/x86_ops_i686.h diff --git a/src/x86_ops_inc_dec.h b/src/CPU/x86_ops_inc_dec.h similarity index 100% rename from src/x86_ops_inc_dec.h rename to src/CPU/x86_ops_inc_dec.h diff --git a/src/x86_ops_int.h b/src/CPU/x86_ops_int.h similarity index 100% rename from src/x86_ops_int.h rename to src/CPU/x86_ops_int.h diff --git a/src/x86_ops_io.h b/src/CPU/x86_ops_io.h similarity index 100% rename from src/x86_ops_io.h rename to src/CPU/x86_ops_io.h diff --git a/src/x86_ops_jump.h b/src/CPU/x86_ops_jump.h similarity index 100% rename from src/x86_ops_jump.h rename to src/CPU/x86_ops_jump.h diff --git a/src/x86_ops_misc.h b/src/CPU/x86_ops_misc.h similarity index 100% rename from src/x86_ops_misc.h rename to src/CPU/x86_ops_misc.h diff --git a/src/x86_ops_mmx.h b/src/CPU/x86_ops_mmx.h similarity index 100% rename from src/x86_ops_mmx.h rename to src/CPU/x86_ops_mmx.h diff --git a/src/x86_ops_mmx_arith.h b/src/CPU/x86_ops_mmx_arith.h similarity index 100% rename from src/x86_ops_mmx_arith.h rename to src/CPU/x86_ops_mmx_arith.h diff --git a/src/x86_ops_mmx_cmp.h b/src/CPU/x86_ops_mmx_cmp.h similarity index 100% rename from src/x86_ops_mmx_cmp.h rename to src/CPU/x86_ops_mmx_cmp.h diff --git a/src/x86_ops_mmx_logic.h b/src/CPU/x86_ops_mmx_logic.h similarity index 100% rename from src/x86_ops_mmx_logic.h rename to src/CPU/x86_ops_mmx_logic.h diff --git a/src/x86_ops_mmx_mov.h b/src/CPU/x86_ops_mmx_mov.h similarity index 100% rename from src/x86_ops_mmx_mov.h rename to src/CPU/x86_ops_mmx_mov.h diff --git a/src/x86_ops_mmx_pack.h b/src/CPU/x86_ops_mmx_pack.h similarity index 100% rename from src/x86_ops_mmx_pack.h rename to src/CPU/x86_ops_mmx_pack.h diff --git a/src/x86_ops_mmx_shift.h b/src/CPU/x86_ops_mmx_shift.h similarity index 100% rename from src/x86_ops_mmx_shift.h rename to src/CPU/x86_ops_mmx_shift.h diff --git a/src/x86_ops_mov.h b/src/CPU/x86_ops_mov.h similarity index 100% rename from src/x86_ops_mov.h rename to src/CPU/x86_ops_mov.h diff --git a/src/x86_ops_mov_ctrl.h b/src/CPU/x86_ops_mov_ctrl.h similarity index 100% rename from src/x86_ops_mov_ctrl.h rename to src/CPU/x86_ops_mov_ctrl.h diff --git a/src/x86_ops_mov_seg.h b/src/CPU/x86_ops_mov_seg.h similarity index 100% rename from src/x86_ops_mov_seg.h rename to src/CPU/x86_ops_mov_seg.h diff --git a/src/x86_ops_movx.h b/src/CPU/x86_ops_movx.h similarity index 100% rename from src/x86_ops_movx.h rename to src/CPU/x86_ops_movx.h diff --git a/src/x86_ops_msr.h b/src/CPU/x86_ops_msr.h similarity index 100% rename from src/x86_ops_msr.h rename to src/CPU/x86_ops_msr.h diff --git a/src/x86_ops_mul.h b/src/CPU/x86_ops_mul.h similarity index 100% rename from src/x86_ops_mul.h rename to src/CPU/x86_ops_mul.h diff --git a/src/x86_ops_pmode.h b/src/CPU/x86_ops_pmode.h similarity index 100% rename from src/x86_ops_pmode.h rename to src/CPU/x86_ops_pmode.h diff --git a/src/x86_ops_prefix.h b/src/CPU/x86_ops_prefix.h similarity index 100% rename from src/x86_ops_prefix.h rename to src/CPU/x86_ops_prefix.h diff --git a/src/x86_ops_rep.h b/src/CPU/x86_ops_rep.h similarity index 100% rename from src/x86_ops_rep.h rename to src/CPU/x86_ops_rep.h diff --git a/src/x86_ops_ret.h b/src/CPU/x86_ops_ret.h similarity index 100% rename from src/x86_ops_ret.h rename to src/CPU/x86_ops_ret.h diff --git a/src/x86_ops_set.h b/src/CPU/x86_ops_set.h similarity index 100% rename from src/x86_ops_set.h rename to src/CPU/x86_ops_set.h diff --git a/src/x86_ops_shift.h b/src/CPU/x86_ops_shift.h similarity index 100% rename from src/x86_ops_shift.h rename to src/CPU/x86_ops_shift.h diff --git a/src/x86_ops_stack.h b/src/CPU/x86_ops_stack.h similarity index 100% rename from src/x86_ops_stack.h rename to src/CPU/x86_ops_stack.h diff --git a/src/x86_ops_string.h b/src/CPU/x86_ops_string.h similarity index 100% rename from src/x86_ops_string.h rename to src/CPU/x86_ops_string.h diff --git a/src/x86_ops_xchg.h b/src/CPU/x86_ops_xchg.h similarity index 100% rename from src/x86_ops_xchg.h rename to src/CPU/x86_ops_xchg.h diff --git a/src/x86seg.c b/src/CPU/x86seg.c similarity index 99% rename from src/x86seg.c rename to src/CPU/x86seg.c index 1042712ae..71fe5ccef 100644 --- a/src/x86seg.c +++ b/src/CPU/x86seg.c @@ -4,9 +4,9 @@ #include #include #include -#include "ibm.h" -#include "mem.h" -#include "nvr.h" +#include "../ibm.h" +#include "../mem.h" +#include "../nvr.h" #include "x86.h" #include "386.h" #include "386_common.h" diff --git a/src/x86seg.h b/src/CPU/x86seg.h similarity index 100% rename from src/x86seg.h rename to src/CPU/x86seg.h diff --git a/src/x87.c b/src/CPU/x87.c similarity index 98% rename from src/x87.c rename to src/CPU/x87.c index a729a14c4..a241130fb 100644 --- a/src/x87.c +++ b/src/CPU/x87.c @@ -1,14 +1,14 @@ #define fplog 0 - #include -#include "ibm.h" -#include "pic.h" +#include "../ibm.h" +#include "../pic.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" #include "386_common.h" + uint16_t x87_gettag() { uint16_t ret = 0; diff --git a/src/x87.h b/src/CPU/x87.h similarity index 100% rename from src/x87.h rename to src/CPU/x87.h diff --git a/src/x87_ops.h b/src/CPU/x87_ops.h similarity index 100% rename from src/x87_ops.h rename to src/CPU/x87_ops.h diff --git a/src/x87_ops_arith.h b/src/CPU/x87_ops_arith.h similarity index 100% rename from src/x87_ops_arith.h rename to src/CPU/x87_ops_arith.h diff --git a/src/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h similarity index 100% rename from src/x87_ops_loadstore.h rename to src/CPU/x87_ops_loadstore.h diff --git a/src/x87_ops_misc.h b/src/CPU/x87_ops_misc.h similarity index 100% rename from src/x87_ops_misc.h rename to src/CPU/x87_ops_misc.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index cefbc5bdc..783447992 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.5 2017/05/05 +# Version: @(#)Makefile.mingw 1.0.6 2017/05/06 # # Authors: Kotori, # Fred N. van Kempen, @@ -30,31 +30,52 @@ EXTRAS = # Do we want a debugging build? DEBUG = n +OPTIM = n +X64 = n ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . dosbox lzf resid-fp slirp +VPATH = . cpu sound sound/resid-fp video lzf slirp CPP = g++.exe CC = gcc.exe WINDRES = windres.exe OPTS = -DWIN32 $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) -DFLAGS = -march=i686 -Og -ggdb -DDEBUG +DFLAGS = -march=i686 -ggdb -DDEBUG +COPTIM = -Og else -ifeq ($(OPTIMIZED), y) -DFLAGS = -march=native -mtune=native -O6 +ifeq ($(OPTIM), y) +DFLAGS = -march=native +COPTIM = -O6 else -DFLAGS = -march=i686 -O3 +ifeq ($(X64), y) +DFLAGS = +else +DFLAGS = -march=i686 +endif +COPTIM = -O3 endif endif -AFLAGS = -msse -msse2 -mfpmath=sse -CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ +ifeq ($(OPTIM), y) +AOPTIM = -mtune=native +else +AOPTIM = +endif +AFLAGS = -msse -msse2 \ + -mfpmath=sse +CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ -fomit-frame-pointer -mstackrealign RFLAGS = --input-format=rc -O coff +ifeq ($(X64), y) +PLATCG = codegen_x86-64.o +else +PLATCG = codegen_x86.o +endif + MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ @@ -63,7 +84,7 @@ CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ codegen.o \ codegen_ops.o codegen_timing_486.o \ codegen_timing_686.o codegen_timing_pentium.o \ - codegen_timing_winchip.o codegen_x86.o \ + codegen_timing_winchip.o $(PLATCG) \ x86seg.o x87.o SYSOBJ = model.o \ headland.o \ @@ -88,22 +109,31 @@ DEVOBJ = bugger.o lpt.o serial.o \ mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ fdd.o fdc.o \ fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ - hdd.o hdd_esdi.o mfm_at.o mfm_xebec.o ide.o xtide.o piix.o scsi_hd.o \ + hdd.o \ + mfm_at.o mfm_xebec.o hdd_esdi.o ide.o xtide.o piix.o \ disc.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o USBOBJ = usb.o -NETOBJ = ne2000.o nethandler.o -SCSIOBJ = scsi.o scsi_buslogic.o scsi_aha154x.o -SNDOBJ = sound.o sound_speaker.o dac.o sound_ps1.o sound_pssj.o \ - sound_adlib.o sound_adlibgold.o sound_ad1848.o sound_sb.o \ - sound_sb_dsp.o sound_cms.o sound_dbopl.o sound_emu8k.o \ - sound_gus.o sound_opl.o sound_mpu401_uart.o sound_pas16.o \ - sound_resid.o sound_sn76489.o sound_ssi2001.o sound_wss.o \ - sound_ym7128.o soundopenal.o +NETOBJ = network.o net_ne2000.o +SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o +SNDOBJ = sound.o \ + convolve.o convolve-sse.o envelope.o extfilt.o \ + filter.o pot.o sid.o voice.o wave6581__ST.o \ + wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ + wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o \ + dbopl.o nukedopl.o openal.o \ + snd_speaker.o dac.o snd_ps1.o snd_pssj.o \ + snd_adlib.o snd_adlibgold.o snd_ad1848.o \ + snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ + snd_emu8k.o snd_gus.o snd_opl.o \ + snd_mpu401_uart.o snd_pas16.o snd_resid.o \ + snd_sn76489.o snd_ssi2001.o snd_wss.o \ + snd_ym7128.o VIDOBJ = video.o \ - vid_mda.o vid_cga.o vid_ega.o \ + vid_cga.o vid_cga_comp.o vid_mda.o vid_ega.o \ vid_vga.o vid_svga.o vid_svga_render.o \ vid_hercules.o vid_herculesplus.o vid_incolor.o \ vid_colorplus.o \ @@ -128,22 +158,18 @@ VIDOBJ = video.o \ WINOBJ = win.o \ win-d3d.o win-d3d-fs.o \ win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o win-video.o \ - win-keyboard.o win-mouse.o win-joystick.o win-midi.o \ + win-language.o win-status.o \ + win-video.o win-serial.o win-mouse.o \ + win-joystick.o win-midi.o \ win-settings.o win-deviceconfig.o win-joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) -DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o LZFOBJ = lzf_c.o lzf_d.o -SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o \ - sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o \ - wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o -SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o \ - queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o \ - udp.o if.o mbuf.o slirp.o tcp_subr.o +SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ + ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o \ + sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ @@ -164,12 +190,10 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ @echo $< @$(CPP) $(CFLAGS) -c $< -$(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) +$(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. @$(CC) -o $(PROG).exe \ - $(OBJ) \ - $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ - $(LIBS) + $(OBJ) $(LZFOBJ) $(SLIRPOBJ) $(LIBS) ifneq ($(DEBUG), y) strip $(PROG).exe endif diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index 7dfc840ac..2f0f9b408 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -6,9 +6,9 @@ # # This file is part of the 86Box distribution. # -# Modified Makefile for Win32 MinGW 32-bit environment. +# Modified Makefile for Win64 MinGW 64-bit environment. # -# Version: @(#)Makefile.mingw64 1.0.0 2017/05/05 +# Version: @(#)Makefile.mingw64 1.0.2 2017/05/06 # # Authors: Kotori, # Fred N. van Kempen, @@ -16,174 +16,18 @@ # Richard G., # +# Include the default Makefile. +include Makefile.mingw + # Name of the executable. PROG = 86Box64 # Various compile-time options. -# -DROM_TRACE=0xcd800 traces ROM access from segment C800 -# -DIO_TACE=0x66 traces I/O on port 0x66 STUFF = - -# Add feature selections here. -# -DBUGGER adds the ISA BusBugger emulation. EXTRAS = - -# Do we want a debugging build? DEBUG = n +OPTIM = n +X64 = y -######################################################################### -# Nothing should need changing from here on.. # -######################################################################### -VPATH = . dosbox lzf resid-fp slirp -CPP = g++.exe -CC = gcc.exe -WINDRES = windres.exe - -OPTS = -DWIN32 $(EXTRAS) $(STUFF) -ifeq ($(DEBUG), y) -DFLAGS = -march=i686 -Og -ggdb -DDEBUG -else -ifeq ($(OPTIMIZED), y) -DFLAGS = -march=native -mtune=native -O6 -else -DFLAGS = -O3 -endif -endif -AFLAGS = -msse -msse2 -mfpmath=sse -CFLAGS = $(OPTS) $(DFLAGS) $(AFLAGS) \ - -fomit-frame-pointer -mstackrealign -RFLAGS = --input-format=rc -O coff - - -MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ - mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ - memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o -CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ - codegen.o \ - codegen_ops.o codegen_timing_486.o \ - codegen_timing_686.o codegen_timing_pentium.o \ - codegen_timing_winchip.o codegen_x86-64.o \ - x86seg.o x87.o -SYSOBJ = model.o \ - headland.o \ - i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ - neat.o \ - ali1429.o \ - opti495.o \ - scat.o \ - sis496.o \ - wd76c10.o \ - acer386sx.o acerm3a.o amstrad.o \ - compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ - tandy_eeprom.o tandy_rom.o -DEVOBJ = bugger.o lpt.o serial.o \ - um8669f.o pc87306.o sis85c471.o w83877f.o \ - keyboard.o \ - keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ - keyboard_amstrad.o keyboard_olim24.o \ - gameport.o \ - joystick_standard.o joystick_ch_flightstick_pro.o \ - joystick_sw_pad.o joystick_tm_fcs.o \ - mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ - fdd.o fdc.o \ - fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ - hdd.o hdd_esdi.o mfm_at.o mfm_xebec.o ide.o xtide.o piix.o scsi_hd.o \ - disc.o \ - disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ - disc_random.o disc_td0.o \ - cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o -USBOBJ = usb.o -NETOBJ = ne2000.o nethandler.o -SCSIOBJ = scsi.o scsi_buslogic.o scsi_aha154x.o -SNDOBJ = sound.o sound_speaker.o dac.o sound_ps1.o sound_pssj.o \ - sound_adlib.o sound_adlibgold.o sound_ad1848.o sound_sb.o \ - sound_sb_dsp.o sound_cms.o sound_dbopl.o sound_emu8k.o \ - sound_gus.o sound_opl.o sound_mpu401_uart.o sound_pas16.o \ - sound_resid.o sound_sn76489.o sound_ssi2001.o sound_wss.o \ - sound_ym7128.o soundopenal.o -VIDOBJ = video.o \ - vid_mda.o vid_cga.o vid_ega.o \ - vid_vga.o vid_svga.o vid_svga_render.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_s3.o vid_s3_virge.o \ - vid_et4000.o vid_et4000w32.o vid_icd2061.o \ - vid_oti067.o \ - vid_paradise.o \ - vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ - vid_ati68860_ramdac.o vid_ati_mach64.o \ - vid_ics2595.o \ - vid_sdac_ramdac.o \ - vid_stg_ramdac.o \ - vid_unk_ramdac.o \ - vid_wy700.o \ - vid_voodoo.o \ - vid_pcjr.o vid_ps1_svga.o \ - vid_olivetti_m24.o \ - vid_pc1512.o vid_pc1640.o vid_pc200.o \ - vid_tandy.o vid_tandysl.o -WINOBJ = win.o \ - win-d3d.o win-d3d-fs.o \ - win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o win-video.o \ - win-keyboard.o win-mouse.o win-joystick.o win-midi.o \ - win-settings.o win-deviceconfig.o win-joystickconfig.o \ - 86Box.res -OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ - $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) - -DBOBJ = dbopl.o nukedopl.o vid_cga_comp.o -LZFOBJ = lzf_c.o lzf_d.o -SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o \ - sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o \ - wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o -SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o ip_input.o \ - queue.o tcp_input.o tftp.o debug.o ip_output.o sbuf.o tcp_output.o \ - udp.o if.o mbuf.o slirp.o tcp_subr.o - -LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ - -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ - -lstdc++ -lpsapi -static-libstdc++ -static-libgcc \ - -static -L. -lwpcapdelay - - -# Build rules. -%.o: %.c - @echo $< - $(CC) $(CFLAGS) -c $< - -%.o: %.cc - @echo $< - @$(CPP) $(CFLAGS) -c $< - -%.o: %.cpp - @echo $< - @$(CPP) $(CFLAGS) -c $< - -$(PROG).exe: $(OBJ) $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) - @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe \ - $(OBJ) \ - $(DBOBJ) $(LZFOBJ) $(SIDOBJ) $(SLIRPOBJ) \ - $(LIBS) -ifneq ($(DEBUG), y) - strip $(PROG).exe -endif - -all: $(PROG).exe - -clean: - rm *.o - rm *.exe - rm *.res - -86Box.res: 86Box.rc - @echo Processing $< - @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res - - -# End of Makefile.mingw. +# End of Makefile.mingw64. diff --git a/src/dosbox/dbopl.cpp b/src/SOUND/dbopl.cpp similarity index 100% rename from src/dosbox/dbopl.cpp rename to src/SOUND/dbopl.cpp diff --git a/src/dosbox/dbopl.h b/src/SOUND/dbopl.h similarity index 100% rename from src/dosbox/dbopl.h rename to src/SOUND/dbopl.h diff --git a/src/filters.h b/src/SOUND/filters.h similarity index 100% rename from src/filters.h rename to src/SOUND/filters.h diff --git a/src/dosbox/nukedopl.cpp b/src/SOUND/nukedopl.cpp similarity index 100% rename from src/dosbox/nukedopl.cpp rename to src/SOUND/nukedopl.cpp diff --git a/src/dosbox/nukedopl.h b/src/SOUND/nukedopl.h similarity index 100% rename from src/dosbox/nukedopl.h rename to src/SOUND/nukedopl.h diff --git a/src/soundopenal.c b/src/SOUND/openal.c similarity index 96% rename from src/soundopenal.c rename to src/SOUND/openal.c index 8cb065fbd..9f20b57de 100644 --- a/src/soundopenal.c +++ b/src/SOUND/openal.c @@ -3,13 +3,14 @@ #include #include #ifdef USE_OPENAL -#include -#include -#include +# include +# include +# include #endif -#include "ibm.h" +#include "../ibm.h" #include "sound.h" + FILE *allog; #ifdef USE_OPENAL ALuint buffers[4]; /* front and back buffers */ @@ -19,7 +20,8 @@ static ALuint source[2]; /* audio source */ #define FREQ 48000 #define BUFLEN SOUNDBUFLEN -void closeal(); + +void closeal(ALvoid); ALvoid alutInit(ALint *argc,ALbyte **argv) { ALCcontext *Context; @@ -60,14 +62,14 @@ void initalmain(int argc, char *argv[]) #endif } -void closeal() +void closeal(ALvoid) { #ifdef USE_OPENAL alutExit(); #endif } -void inital() +void inital(ALvoid) { #ifdef USE_OPENAL int c; diff --git a/src/resid-fp/AUTHORS b/src/SOUND/resid-fp/AUTHORS similarity index 100% rename from src/resid-fp/AUTHORS rename to src/SOUND/resid-fp/AUTHORS diff --git a/src/resid-fp/COPYING b/src/SOUND/resid-fp/COPYING similarity index 100% rename from src/resid-fp/COPYING rename to src/SOUND/resid-fp/COPYING diff --git a/src/resid-fp/ChangeLog b/src/SOUND/resid-fp/ChangeLog similarity index 100% rename from src/resid-fp/ChangeLog rename to src/SOUND/resid-fp/ChangeLog diff --git a/src/resid-fp/INSTALL b/src/SOUND/resid-fp/INSTALL similarity index 100% rename from src/resid-fp/INSTALL rename to src/SOUND/resid-fp/INSTALL diff --git a/src/resid-fp/Makefile.am b/src/SOUND/resid-fp/Makefile.am similarity index 100% rename from src/resid-fp/Makefile.am rename to src/SOUND/resid-fp/Makefile.am diff --git a/src/resid-fp/Makefile.in b/src/SOUND/resid-fp/Makefile.in similarity index 100% rename from src/resid-fp/Makefile.in rename to src/SOUND/resid-fp/Makefile.in diff --git a/src/resid-fp/NEWS b/src/SOUND/resid-fp/NEWS similarity index 100% rename from src/resid-fp/NEWS rename to src/SOUND/resid-fp/NEWS diff --git a/src/resid-fp/README b/src/SOUND/resid-fp/README similarity index 100% rename from src/resid-fp/README rename to src/SOUND/resid-fp/README diff --git a/src/resid-fp/README.VICE b/src/SOUND/resid-fp/README.VICE similarity index 100% rename from src/resid-fp/README.VICE rename to src/SOUND/resid-fp/README.VICE diff --git a/src/resid-fp/aclocal.m4 b/src/SOUND/resid-fp/aclocal.m4 similarity index 100% rename from src/resid-fp/aclocal.m4 rename to src/SOUND/resid-fp/aclocal.m4 diff --git a/src/resid-fp/configure b/src/SOUND/resid-fp/configure similarity index 100% rename from src/resid-fp/configure rename to src/SOUND/resid-fp/configure diff --git a/src/resid-fp/configure.in b/src/SOUND/resid-fp/configure.in similarity index 100% rename from src/resid-fp/configure.in rename to src/SOUND/resid-fp/configure.in diff --git a/src/resid-fp/convolve-sse.cc b/src/SOUND/resid-fp/convolve-sse.cc similarity index 100% rename from src/resid-fp/convolve-sse.cc rename to src/SOUND/resid-fp/convolve-sse.cc diff --git a/src/resid-fp/convolve.cc b/src/SOUND/resid-fp/convolve.cc similarity index 100% rename from src/resid-fp/convolve.cc rename to src/SOUND/resid-fp/convolve.cc diff --git a/src/resid-fp/envelope.cc b/src/SOUND/resid-fp/envelope.cc similarity index 100% rename from src/resid-fp/envelope.cc rename to src/SOUND/resid-fp/envelope.cc diff --git a/src/resid-fp/envelope.h b/src/SOUND/resid-fp/envelope.h similarity index 100% rename from src/resid-fp/envelope.h rename to src/SOUND/resid-fp/envelope.h diff --git a/src/resid-fp/extfilt.cc b/src/SOUND/resid-fp/extfilt.cc similarity index 100% rename from src/resid-fp/extfilt.cc rename to src/SOUND/resid-fp/extfilt.cc diff --git a/src/resid-fp/extfilt.h b/src/SOUND/resid-fp/extfilt.h similarity index 100% rename from src/resid-fp/extfilt.h rename to src/SOUND/resid-fp/extfilt.h diff --git a/src/resid-fp/filter.cc b/src/SOUND/resid-fp/filter.cc similarity index 100% rename from src/resid-fp/filter.cc rename to src/SOUND/resid-fp/filter.cc diff --git a/src/resid-fp/filter.h b/src/SOUND/resid-fp/filter.h similarity index 100% rename from src/resid-fp/filter.h rename to src/SOUND/resid-fp/filter.h diff --git a/src/resid-fp/pot.cc b/src/SOUND/resid-fp/pot.cc similarity index 100% rename from src/resid-fp/pot.cc rename to src/SOUND/resid-fp/pot.cc diff --git a/src/resid-fp/pot.h b/src/SOUND/resid-fp/pot.h similarity index 100% rename from src/resid-fp/pot.h rename to src/SOUND/resid-fp/pot.h diff --git a/src/resid-fp/samp2src.pl b/src/SOUND/resid-fp/samp2src.pl similarity index 100% rename from src/resid-fp/samp2src.pl rename to src/SOUND/resid-fp/samp2src.pl diff --git a/src/resid-fp/sid.cc b/src/SOUND/resid-fp/sid.cc similarity index 100% rename from src/resid-fp/sid.cc rename to src/SOUND/resid-fp/sid.cc diff --git a/src/resid-fp/sid.h b/src/SOUND/resid-fp/sid.h similarity index 100% rename from src/resid-fp/sid.h rename to src/SOUND/resid-fp/sid.h diff --git a/src/resid-fp/siddefs-fp.h b/src/SOUND/resid-fp/siddefs-fp.h similarity index 100% rename from src/resid-fp/siddefs-fp.h rename to src/SOUND/resid-fp/siddefs-fp.h diff --git a/src/resid-fp/siddefs-fp.h.in b/src/SOUND/resid-fp/siddefs-fp.h.in similarity index 100% rename from src/resid-fp/siddefs-fp.h.in rename to src/SOUND/resid-fp/siddefs-fp.h.in diff --git a/src/resid-fp/version.cc b/src/SOUND/resid-fp/version.cc similarity index 100% rename from src/resid-fp/version.cc rename to src/SOUND/resid-fp/version.cc diff --git a/src/resid-fp/voice.cc b/src/SOUND/resid-fp/voice.cc similarity index 100% rename from src/resid-fp/voice.cc rename to src/SOUND/resid-fp/voice.cc diff --git a/src/resid-fp/voice.h b/src/SOUND/resid-fp/voice.h similarity index 100% rename from src/resid-fp/voice.h rename to src/SOUND/resid-fp/voice.h diff --git a/src/resid-fp/wave.cc b/src/SOUND/resid-fp/wave.cc similarity index 100% rename from src/resid-fp/wave.cc rename to src/SOUND/resid-fp/wave.cc diff --git a/src/resid-fp/wave.h b/src/SOUND/resid-fp/wave.h similarity index 100% rename from src/resid-fp/wave.h rename to src/SOUND/resid-fp/wave.h diff --git a/src/resid-fp/wave6581_PST.cc b/src/SOUND/resid-fp/wave6581_PST.cc similarity index 100% rename from src/resid-fp/wave6581_PST.cc rename to src/SOUND/resid-fp/wave6581_PST.cc diff --git a/src/resid-fp/wave6581_PST.dat b/src/SOUND/resid-fp/wave6581_PST.dat similarity index 100% rename from src/resid-fp/wave6581_PST.dat rename to src/SOUND/resid-fp/wave6581_PST.dat diff --git a/src/resid-fp/wave6581_PS_.cc b/src/SOUND/resid-fp/wave6581_PS_.cc similarity index 100% rename from src/resid-fp/wave6581_PS_.cc rename to src/SOUND/resid-fp/wave6581_PS_.cc diff --git a/src/resid-fp/wave6581_PS_.dat b/src/SOUND/resid-fp/wave6581_PS_.dat similarity index 100% rename from src/resid-fp/wave6581_PS_.dat rename to src/SOUND/resid-fp/wave6581_PS_.dat diff --git a/src/resid-fp/wave6581_P_T.cc b/src/SOUND/resid-fp/wave6581_P_T.cc similarity index 100% rename from src/resid-fp/wave6581_P_T.cc rename to src/SOUND/resid-fp/wave6581_P_T.cc diff --git a/src/resid-fp/wave6581_P_T.dat b/src/SOUND/resid-fp/wave6581_P_T.dat similarity index 100% rename from src/resid-fp/wave6581_P_T.dat rename to src/SOUND/resid-fp/wave6581_P_T.dat diff --git a/src/resid-fp/wave6581__ST.cc b/src/SOUND/resid-fp/wave6581__ST.cc similarity index 100% rename from src/resid-fp/wave6581__ST.cc rename to src/SOUND/resid-fp/wave6581__ST.cc diff --git a/src/resid-fp/wave6581__ST.dat b/src/SOUND/resid-fp/wave6581__ST.dat similarity index 100% rename from src/resid-fp/wave6581__ST.dat rename to src/SOUND/resid-fp/wave6581__ST.dat diff --git a/src/resid-fp/wave8580_PST.cc b/src/SOUND/resid-fp/wave8580_PST.cc similarity index 100% rename from src/resid-fp/wave8580_PST.cc rename to src/SOUND/resid-fp/wave8580_PST.cc diff --git a/src/resid-fp/wave8580_PST.dat b/src/SOUND/resid-fp/wave8580_PST.dat similarity index 100% rename from src/resid-fp/wave8580_PST.dat rename to src/SOUND/resid-fp/wave8580_PST.dat diff --git a/src/resid-fp/wave8580_PS_.cc b/src/SOUND/resid-fp/wave8580_PS_.cc similarity index 100% rename from src/resid-fp/wave8580_PS_.cc rename to src/SOUND/resid-fp/wave8580_PS_.cc diff --git a/src/resid-fp/wave8580_PS_.dat b/src/SOUND/resid-fp/wave8580_PS_.dat similarity index 100% rename from src/resid-fp/wave8580_PS_.dat rename to src/SOUND/resid-fp/wave8580_PS_.dat diff --git a/src/resid-fp/wave8580_P_T.cc b/src/SOUND/resid-fp/wave8580_P_T.cc similarity index 100% rename from src/resid-fp/wave8580_P_T.cc rename to src/SOUND/resid-fp/wave8580_P_T.cc diff --git a/src/resid-fp/wave8580_P_T.dat b/src/SOUND/resid-fp/wave8580_P_T.dat similarity index 100% rename from src/resid-fp/wave8580_P_T.dat rename to src/SOUND/resid-fp/wave8580_P_T.dat diff --git a/src/resid-fp/wave8580__ST.cc b/src/SOUND/resid-fp/wave8580__ST.cc similarity index 100% rename from src/resid-fp/wave8580__ST.cc rename to src/SOUND/resid-fp/wave8580__ST.cc diff --git a/src/resid-fp/wave8580__ST.dat b/src/SOUND/resid-fp/wave8580__ST.dat similarity index 100% rename from src/resid-fp/wave8580__ST.dat rename to src/SOUND/resid-fp/wave8580__ST.dat diff --git a/src/sound_ad1848.c b/src/SOUND/snd_ad1848.c similarity index 98% rename from src/sound_ad1848.c rename to src/SOUND/snd_ad1848.c index c97a6d518..10ff8b2b3 100644 --- a/src/sound_ad1848.c +++ b/src/SOUND/snd_ad1848.c @@ -3,15 +3,17 @@ AD1848 CODEC emulation (Windows Sound System compatible)*/ #include - -#include "ibm.h" -#include "dma.h" -#include "pic.h" +#include "../ibm.h" +#include "../dma.h" +#include "../pic.h" +#include "../timer.h" #include "sound.h" -#include "sound_ad1848.h" +#include "snd_ad1848.h" + static int ad1848_vols[64]; + void ad1848_setirq(ad1848_t *ad1848, int irq) { ad1848->irq = irq; diff --git a/src/sound_ad1848.h b/src/SOUND/snd_ad1848.h similarity index 97% rename from src/sound_ad1848.h rename to src/SOUND/snd_ad1848.h index 6c5e02c55..3a0dd4e46 100644 --- a/src/sound_ad1848.h +++ b/src/SOUND/snd_ad1848.h @@ -1,5 +1,3 @@ -#include "timer.h" - typedef struct ad1848_t { int index; diff --git a/src/sound_adlib.c b/src/SOUND/snd_adlib.c similarity index 95% rename from src/sound_adlib.c rename to src/SOUND/snd_adlib.c index 70ed47b7a..e131d04c3 100644 --- a/src/sound_adlib.c +++ b/src/SOUND/snd_adlib.c @@ -1,12 +1,12 @@ #include -#include "ibm.h" -#include "io.h" -#include "device.h" +#include "../ibm.h" +#include "../io.h" +#include "../mca.h" +#include "../device.h" #include "sound.h" -#include "mca.h" +#include "snd_adlib.h" +#include "snd_opl.h" -#include "sound_adlib.h" -#include "sound_opl.h" typedef struct adlib_t { @@ -15,6 +15,7 @@ typedef struct adlib_t uint8_t pos_regs[8]; } adlib_t; + static void adlib_get_buffer(int32_t *buffer, int len, void *p) { adlib_t *adlib = (adlib_t *)p; diff --git a/src/sound_adlib.h b/src/SOUND/snd_adlib.h similarity index 100% rename from src/sound_adlib.h rename to src/SOUND/snd_adlib.h diff --git a/src/sound_adlibgold.c b/src/SOUND/snd_adlibgold.c similarity index 99% rename from src/sound_adlibgold.c rename to src/SOUND/snd_adlibgold.c index 0a4f1aaa4..e03a9cf9b 100644 --- a/src/sound_adlibgold.c +++ b/src/SOUND/snd_adlibgold.c @@ -1,18 +1,19 @@ #include #include -#include "ibm.h" -#include "device.h" - -#include "sound_opl.h" -#include "sound_ym7128.h" -#include "dma.h" -#include "io.h" -#include "pic.h" -#include "pit.h" +#include "../ibm.h" +#include "../io.h" +#include "../dma.h" +#include "../pic.h" +#include "../pit.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "timer.h" - #include "filters.h" +#include "snd_opl.h" +#include "snd_ym7128.h" + typedef struct adgold_t { diff --git a/src/sound_adlibgold.h b/src/SOUND/snd_adlibgold.h similarity index 100% rename from src/sound_adlibgold.h rename to src/SOUND/snd_adlibgold.h diff --git a/src/sound_cms.c b/src/SOUND/snd_cms.c similarity index 98% rename from src/sound_cms.c rename to src/SOUND/snd_cms.c index 93a2aab1f..1cbf723b2 100644 --- a/src/sound_cms.c +++ b/src/SOUND/snd_cms.c @@ -1,14 +1,15 @@ #include #include -#include "ibm.h" - -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../device.h" #include "sound.h" -#include "sound_cms.h" +#include "snd_cms.h" + #define MASTER_CLOCK 7159090 + typedef struct cms_t { int addrs[2]; diff --git a/src/sound_cms.h b/src/SOUND/snd_cms.h similarity index 100% rename from src/sound_cms.h rename to src/SOUND/snd_cms.h diff --git a/src/sound_dbopl.cc b/src/SOUND/snd_dbopl.cc similarity index 98% rename from src/sound_dbopl.cc rename to src/SOUND/snd_dbopl.cc index 8f7463357..bf3260b84 100644 --- a/src/sound_dbopl.cc +++ b/src/SOUND/snd_dbopl.cc @@ -1,12 +1,14 @@ /* Copyright holders: The DOSBox Team, SA1988 see COPYING for more details */ -#include "dosbox/dbopl.h" -#include "dosbox/nukedopl.h" -#include "sound_dbopl.h" +#include "dbopl.h" +#include "nukedopl.h" +#include "snd_dbopl.h" + int opl3_type = 0; + static struct { DBOPL::Chip chip; diff --git a/src/sound_dbopl.h b/src/SOUND/snd_dbopl.h similarity index 100% rename from src/sound_dbopl.h rename to src/SOUND/snd_dbopl.h diff --git a/src/sound_emu8k.c b/src/SOUND/snd_emu8k.c similarity index 99% rename from src/sound_emu8k.c rename to src/SOUND/snd_emu8k.c index d9cddbdab..670e057a1 100644 --- a/src/sound_emu8k.c +++ b/src/SOUND/snd_emu8k.c @@ -5,12 +5,15 @@ highest (10.72 Hz) = 2^12 steps = 4096*/ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_emu8k.h" -#include "timer.h" +#include "snd_emu8k.h" + enum { diff --git a/src/sound_emu8k.h b/src/SOUND/snd_emu8k.h similarity index 100% rename from src/sound_emu8k.h rename to src/SOUND/snd_emu8k.h diff --git a/src/sound_gus.c b/src/SOUND/snd_gus.c similarity index 99% rename from src/sound_gus.c rename to src/SOUND/snd_gus.c index 34b0416e4..2735d77fd 100644 --- a/src/sound_gus.c +++ b/src/SOUND/snd_gus.c @@ -1,15 +1,15 @@ #include #include #include -#include "ibm.h" - -#include "device.h" -#include "dma.h" -#include "io.h" -#include "pic.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../dma.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_gus.h" -#include "timer.h" +#include "snd_gus.h" + typedef struct gus_t { diff --git a/src/sound_gus.h b/src/SOUND/snd_gus.h similarity index 100% rename from src/sound_gus.h rename to src/SOUND/snd_gus.h diff --git a/src/sound_mpu401_uart.c b/src/SOUND/snd_mpu401_uart.c similarity index 93% rename from src/sound_mpu401_uart.c rename to src/SOUND/snd_mpu401_uart.c index 5d70b5427..ac145f49f 100644 --- a/src/sound_mpu401_uart.c +++ b/src/SOUND/snd_mpu401_uart.c @@ -1,7 +1,8 @@ -#include "ibm.h" -#include "io.h" -#include "plat-midi.h" -#include "sound_mpu401_uart.h" +#include "../ibm.h" +#include "../io.h" +#include "../plat-midi.h" +#include "snd_mpu401_uart.h" + enum { @@ -9,6 +10,7 @@ enum STATUS_INPUT_NOT_READY = 0x80 }; + static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) { mpu401_uart_t *mpu = (mpu401_uart_t *)p; diff --git a/src/sound_mpu401_uart.h b/src/SOUND/snd_mpu401_uart.h similarity index 100% rename from src/sound_mpu401_uart.h rename to src/SOUND/snd_mpu401_uart.h diff --git a/src/sound_opl.c b/src/SOUND/snd_opl.c similarity index 97% rename from src/sound_opl.c rename to src/SOUND/snd_opl.c index 28647f6dc..d04b7be9a 100644 --- a/src/sound_opl.c +++ b/src/SOUND/snd_opl.c @@ -3,11 +3,13 @@ */ #include #include -#include "ibm.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../timer.h" #include "sound.h" -#include "sound_opl.h" -#include "sound_dbopl.h" +#include "snd_opl.h" +#include "snd_dbopl.h" + /*Interfaces between PCem and the actual OPL emulator*/ diff --git a/src/sound_opl.h b/src/SOUND/snd_opl.h similarity index 100% rename from src/sound_opl.h rename to src/SOUND/snd_opl.h diff --git a/src/sound_pas16.c b/src/SOUND/snd_pas16.c similarity index 99% rename from src/sound_pas16.c rename to src/SOUND/snd_pas16.c index 69c245f5e..e91b7a09a 100644 --- a/src/sound_pas16.c +++ b/src/SOUND/snd_pas16.c @@ -1,17 +1,17 @@ #include -#include "ibm.h" - -#include "device.h" -#include "dma.h" -#include "filters.h" -#include "io.h" -#include "pic.h" -#include "pit.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../pit.h" +#include "../dma.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_opl.h" -#include "sound_pas16.h" -#include "sound_sb_dsp.h" -#include "timer.h" +#include "snd_opl.h" +#include "snd_pas16.h" +#include "snd_sb_dsp.h" +#include "filters.h" + /* Original PAS uses 2 x OPL2 diff --git a/src/sound_pas16.h b/src/SOUND/snd_pas16.h similarity index 100% rename from src/sound_pas16.h rename to src/SOUND/snd_pas16.h diff --git a/src/sound_ps1.c b/src/SOUND/snd_ps1.c similarity index 96% rename from src/sound_ps1.c rename to src/SOUND/snd_ps1.c index 6c2498e7e..85334101a 100644 --- a/src/sound_ps1.c +++ b/src/SOUND/snd_ps1.c @@ -1,11 +1,13 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "pic.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_ps1.h" -#include "sound_sn76489.h" +#include "snd_ps1.h" +#include "snd_sn76489.h" + typedef struct ps1_audio_t { diff --git a/src/sound_ps1.h b/src/SOUND/snd_ps1.h similarity index 100% rename from src/sound_ps1.h rename to src/SOUND/snd_ps1.h diff --git a/src/sound_pssj.c b/src/SOUND/snd_pssj.c similarity index 97% rename from src/sound_pssj.c rename to src/SOUND/snd_pssj.c index bda1442fd..dc52aee46 100644 --- a/src/sound_pssj.c +++ b/src/SOUND/snd_pssj.c @@ -1,14 +1,14 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../dma.h" +#include "../pic.h" +#include "../timer.h" +#include "../device.h" #include "sound.h" -#include "sound_pssj.h" -#include "sound_sn76489.h" +#include "snd_pssj.h" +#include "snd_sn76489.h" -#include "dma.h" -#include "pic.h" -#include "timer.h" typedef struct pssj_t { diff --git a/src/sound_pssj.h b/src/SOUND/snd_pssj.h similarity index 100% rename from src/sound_pssj.h rename to src/SOUND/snd_pssj.h diff --git a/src/sound_resid.cc b/src/SOUND/snd_resid.cc similarity index 98% rename from src/sound_resid.cc rename to src/SOUND/snd_resid.cc index 8185b6046..ef1d32854 100644 --- a/src/sound_resid.cc +++ b/src/SOUND/snd_resid.cc @@ -3,7 +3,8 @@ #include #include #include "resid-fp/sid.h" -#include "sound_resid.h" +#include "snd_resid.h" + typedef struct psid_t { @@ -12,9 +13,11 @@ typedef struct psid_t int16_t last_sample; } psid_t; + psid_t *psid; -void *sid_init() + +void *sid_init(void) { // psid_t *psid; int c; diff --git a/src/sound_resid.h b/src/SOUND/snd_resid.h similarity index 100% rename from src/sound_resid.h rename to src/SOUND/snd_resid.h diff --git a/src/sound_sb.c b/src/SOUND/snd_sb.c similarity index 99% rename from src/sound_sb.c rename to src/SOUND/snd_sb.c index cd7b456f3..32f3fbc34 100644 --- a/src/sound_sb.c +++ b/src/SOUND/snd_sb.c @@ -1,19 +1,19 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mca.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mca.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "sound.h" -#include "sound_emu8k.h" -#include "sound_mpu401_uart.h" -#include "sound_opl.h" -#include "sound_sb.h" -#include "sound_sb_dsp.h" - +#include "snd_emu8k.h" +#include "snd_mpu401_uart.h" +#include "snd_opl.h" +#include "snd_sb.h" +#include "snd_sb_dsp.h" #include "filters.h" + typedef struct sb_mixer_t { int master_l, master_r; diff --git a/src/sound_sb.h b/src/SOUND/snd_sb.h similarity index 100% rename from src/sound_sb.h rename to src/SOUND/snd_sb.h diff --git a/src/sound_sb_dsp.c b/src/SOUND/snd_sb_dsp.c similarity index 99% rename from src/sound_sb_dsp.c rename to src/SOUND/snd_sb_dsp.c index 13298d446..16215d05e 100644 --- a/src/sound_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -3,24 +3,21 @@ 486-33 - 20kHz 486-50 - 32kHz Pentium - 45kHz*/ - #include #include -#include "ibm.h" - - -#include "dma.h" -#include "io.h" -#include "pic.h" +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../dma.h" +#include "../timer.h" #include "sound.h" -#include "sound_sb_dsp.h" -#include "timer.h" +#include "snd_sb_dsp.h" + void pollsb(void *p); void sb_poll_i(void *p); - static int sbe2dat[4][9] = { { 0x01, -0x02, -0x04, 0x08, -0x10, 0x20, 0x40, -0x80, -106 }, { -0x01, 0x02, -0x04, 0x08, 0x10, -0x20, 0x40, -0x80, 165 }, diff --git a/src/sound_sb_dsp.h b/src/SOUND/snd_sb_dsp.h similarity index 100% rename from src/sound_sb_dsp.h rename to src/SOUND/snd_sb_dsp.h diff --git a/src/sound_sn76489.c b/src/SOUND/snd_sn76489.c similarity index 99% rename from src/sound_sn76489.c rename to src/SOUND/snd_sn76489.c index 7d6fe80a1..574769322 100644 --- a/src/sound_sn76489.c +++ b/src/SOUND/snd_sn76489.c @@ -1,13 +1,15 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../device.h" #include "sound.h" -#include "sound_sn76489.h" +#include "snd_sn76489.h" + int sn76489_mute; + static float volslog[16]= { 0.00000f,0.59715f,0.75180f,0.94650f, diff --git a/src/sound_sn76489.h b/src/SOUND/snd_sn76489.h similarity index 100% rename from src/sound_sn76489.h rename to src/SOUND/snd_sn76489.h diff --git a/src/sound_speaker.c b/src/SOUND/snd_speaker.c similarity index 93% rename from src/sound_speaker.c rename to src/SOUND/snd_speaker.c index f4bc7086d..25344d922 100644 --- a/src/sound_speaker.c +++ b/src/SOUND/snd_speaker.c @@ -1,17 +1,18 @@ -#include "ibm.h" +#include "../ibm.h" #include "sound.h" -#include "sound_speaker.h" +#include "snd_speaker.h" + int speaker_mute = 0; - -static int16_t speaker_buffer[SOUNDBUFLEN]; - -static int speaker_pos = 0; - int speaker_gated = 0; int speaker_enable = 0, was_speaker_enable = 0; -void speaker_update() + +static int16_t speaker_buffer[SOUNDBUFLEN]; +static int speaker_pos = 0; + + +void speaker_update(void) { int16_t val; @@ -51,7 +52,8 @@ static void speaker_get_buffer(int32_t *buffer, int len, void *p) speaker_pos = 0; } -void speaker_init() + +void speaker_init(void) { sound_add_handler(speaker_get_buffer, NULL); speaker_mute = 0; diff --git a/src/sound_speaker.h b/src/SOUND/snd_speaker.h similarity index 100% rename from src/sound_speaker.h rename to src/SOUND/snd_speaker.h diff --git a/src/sound_ssi2001.c b/src/SOUND/snd_ssi2001.c similarity index 94% rename from src/sound_ssi2001.c rename to src/SOUND/snd_ssi2001.c index d0a7e2136..d42898b9d 100644 --- a/src/sound_ssi2001.c +++ b/src/SOUND/snd_ssi2001.c @@ -1,11 +1,11 @@ #include -#include "ibm.h" -#include "device.h" -#include "io.h" +#include "../ibm.h" +#include "../io.h" +#include "../device.h" #include "sound.h" +#include "snd_resid.h" +#include "snd_ssi2001.h" -#include "sound_resid.h" -#include "sound_ssi2001.h" typedef struct ssi2001_t { diff --git a/src/sound_ssi2001.h b/src/SOUND/snd_ssi2001.h similarity index 100% rename from src/sound_ssi2001.h rename to src/SOUND/snd_ssi2001.h diff --git a/src/sound_wss.c b/src/SOUND/snd_wss.c similarity index 93% rename from src/sound_wss.c rename to src/SOUND/snd_wss.c index f8a5bcbd6..a58bc0b64 100644 --- a/src/sound_wss.c +++ b/src/SOUND/snd_wss.c @@ -2,18 +2,18 @@ Windows Sound System emulation*/ -#include #include -#include "ibm.h" - -#include "device.h" -#include "dma.h" -#include "io.h" -#include "pic.h" +#include +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../dma.h" +#include "../device.h" #include "sound.h" -#include "sound_ad1848.h" -#include "sound_opl.h" -#include "sound_wss.h" +#include "snd_ad1848.h" +#include "snd_opl.h" +#include "snd_wss.h" + /*530, 11, 3 - 530=23*/ /*530, 11, 1 - 530=22*/ @@ -29,6 +29,7 @@ static int wss_dma[4] = {0, 0, 1, 3}; static int wss_irq[8] = {5, 7, 9, 10, 11, 12, 14, 15}; /*W95 only uses 7-9, others may be wrong*/ + typedef struct wss_t { uint8_t config; diff --git a/src/sound_wss.h b/src/SOUND/snd_wss.h similarity index 100% rename from src/sound_wss.h rename to src/SOUND/snd_wss.h diff --git a/src/sound_ym7128.c b/src/SOUND/snd_ym7128.c similarity index 99% rename from src/sound_ym7128.c rename to src/SOUND/snd_ym7128.c index be0b3946c..4bea44f53 100644 --- a/src/sound_ym7128.c +++ b/src/SOUND/snd_ym7128.c @@ -1,9 +1,11 @@ -#include "ibm.h" -#include "sound_ym7128.h" +#include "../ibm.h" +#include "snd_ym7128.h" + static int attenuation[32]; static int tap_position[32]; + void ym7128_init(ym7128_t *ym7128) { int c; diff --git a/src/sound_ym7128.h b/src/SOUND/snd_ym7128.h similarity index 100% rename from src/sound_ym7128.h rename to src/SOUND/snd_ym7128.h diff --git a/src/sound.c b/src/SOUND/sound.c similarity index 96% rename from src/sound.c rename to src/SOUND/sound.c index a00f7f9ca..1b60e3068 100644 --- a/src/sound.c +++ b/src/SOUND/sound.c @@ -1,30 +1,26 @@ #include #include #include - -#include "cdrom.h" -#include "ibm.h" - -#include "device.h" - +#include "../ibm.h" +#include "../device.h" +#include "../timer.h" +#include "../thread.h" +#include "../cdrom.h" +#include "sound.h" +#include "snd_opl.h" +#include "snd_adlib.h" +#include "snd_adlibgold.h" +#include "snd_pas16.h" +#include "snd_sb.h" +#include "snd_sb_dsp.h" +#include "snd_wss.h" #include "filters.h" -#include "sound_opl.h" - -#include "sound.h" -#include "sound_adlib.h" -#include "sound_adlibgold.h" -#include "sound_pas16.h" -#include "sound_sb.h" -#include "sound_sb_dsp.h" -#include "sound_wss.h" - -#include "timer.h" -#include "thread.h" int sound_card_current = 0; static int sound_card_last = 0; + typedef struct { char name[64]; diff --git a/src/sound.h b/src/SOUND/sound.h similarity index 97% rename from src/sound.h rename to src/SOUND/sound.h index 23eea439e..ffa9d87af 100644 --- a/src/sound.h +++ b/src/SOUND/sound.h @@ -1,5 +1,3 @@ -#include "timer.h" - void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p); extern int sound_card_current; diff --git a/src/vid_ati18800.c b/src/VIDEO/vid_ati18800.c similarity index 98% rename from src/vid_ati18800.c rename to src/VIDEO/vid_ati18800.c index bb30b4f1c..ecbb4fe40 100644 --- a/src/vid_ati18800.c +++ b/src/VIDEO/vid_ati18800.c @@ -3,16 +3,17 @@ */ /*ATI 18800 emulation (VGA Edge-16)*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_ati18800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" + typedef struct ati18800_t { svga_t svga; diff --git a/src/vid_ati18800.h b/src/VIDEO/vid_ati18800.h similarity index 100% rename from src/vid_ati18800.h rename to src/VIDEO/vid_ati18800.h diff --git a/src/vid_ati28800.c b/src/VIDEO/vid_ati28800.c similarity index 99% rename from src/vid_ati28800.c rename to src/VIDEO/vid_ati28800.c index 54269a9de..84d8ec8e4 100644 --- a/src/vid_ati28800.c +++ b/src/VIDEO/vid_ati28800.c @@ -3,17 +3,18 @@ */ /*ATI 28800 emulation (VGA Charger)*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" +#include "../timer.h" #include "video.h" #include "vid_ati28800.h" #include "vid_ati_eeprom.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "timer.h" + typedef struct ati28800_t { diff --git a/src/vid_ati28800.h b/src/VIDEO/vid_ati28800.h similarity index 100% rename from src/vid_ati28800.h rename to src/VIDEO/vid_ati28800.h diff --git a/src/vid_ati68860_ramdac.c b/src/VIDEO/vid_ati68860_ramdac.c similarity index 99% rename from src/vid_ati68860_ramdac.c rename to src/VIDEO/vid_ati68860_ramdac.c index a8c2f132d..f1d1d6b84 100644 --- a/src/vid_ati68860_ramdac.c +++ b/src/VIDEO/vid_ati68860_ramdac.c @@ -21,13 +21,14 @@ bit 0 Controls 6/8bit DAC. 0: 8bit DAC/LUT, 1: 6bit DAC/LUT 5-6 Always set ? 7 If set can remove "snow" in some cases (A860_Delay_L ?) ?? */ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_ati68860_ramdac.h" #include "vid_svga_render.h" + void ati68860_ramdac_out(uint16_t addr, uint8_t val, ati68860_ramdac_t *ramdac, svga_t *svga) { switch (addr) diff --git a/src/vid_ati68860_ramdac.h b/src/VIDEO/vid_ati68860_ramdac.h similarity index 100% rename from src/vid_ati68860_ramdac.h rename to src/VIDEO/vid_ati68860_ramdac.h diff --git a/src/vid_ati_eeprom.c b/src/VIDEO/vid_ati_eeprom.c similarity index 99% rename from src/vid_ati_eeprom.c rename to src/VIDEO/vid_ati_eeprom.c index bc7a56079..198575a60 100644 --- a/src/vid_ati_eeprom.c +++ b/src/VIDEO/vid_ati_eeprom.c @@ -1,11 +1,12 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#include "ibm.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../mem.h" +#include "../rom.h" #include "vid_ati_eeprom.h" + enum { EEPROM_IDLE, diff --git a/src/vid_ati_eeprom.h b/src/VIDEO/vid_ati_eeprom.h similarity index 100% rename from src/vid_ati_eeprom.h rename to src/VIDEO/vid_ati_eeprom.h diff --git a/src/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c similarity index 99% rename from src/vid_ati_mach64.c rename to src/VIDEO/vid_ati_mach64.c index 4a2744c59..12bbf2383 100644 --- a/src/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -1,12 +1,12 @@ /*ATI Mach64 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../thread.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -14,6 +14,7 @@ #include "vid_ati_eeprom.h" #include "vid_ics2595.h" + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) diff --git a/src/vid_ati_mach64.h b/src/VIDEO/vid_ati_mach64.h similarity index 100% rename from src/vid_ati_mach64.h rename to src/VIDEO/vid_ati_mach64.h diff --git a/src/vid_bt485_ramdac.c b/src/VIDEO/vid_bt485_ramdac.c similarity index 99% rename from src/vid_bt485_ramdac.c rename to src/VIDEO/vid_bt485_ramdac.c index 57848a128..e11f69132 100644 --- a/src/vid_bt485_ramdac.c +++ b/src/VIDEO/vid_bt485_ramdac.c @@ -3,12 +3,13 @@ */ /*Brooktree BT485 true colour RAMDAC emulation*/ /*Currently only a dummy stub for logging and passing output to the generic SVGA handler*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_bt485_ramdac.h" + int bt485_get_clock_divider(bt485_ramdac_t *ramdac) { return 1; /* Will be implemented later. */ diff --git a/src/vid_bt485_ramdac.h b/src/VIDEO/vid_bt485_ramdac.h similarity index 100% rename from src/vid_bt485_ramdac.h rename to src/VIDEO/vid_bt485_ramdac.h diff --git a/src/vid_cga.c b/src/VIDEO/vid_cga.c similarity index 99% rename from src/vid_cga.c rename to src/VIDEO/vid_cga.c index a665e45d9..646ba51e9 100644 --- a/src/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -4,18 +4,19 @@ /*CGA emulation*/ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + #define CGA_RGB 0 #define CGA_COMPOSITE 1 diff --git a/src/vid_cga.h b/src/VIDEO/vid_cga.h similarity index 100% rename from src/vid_cga.h rename to src/VIDEO/vid_cga.h diff --git a/src/dosbox/vid_cga_comp.c b/src/VIDEO/vid_cga_comp.c similarity index 99% rename from src/dosbox/vid_cga_comp.c rename to src/VIDEO/vid_cga_comp.c index 63e54cdad..a63d69f2e 100644 --- a/src/dosbox/vid_cga_comp.c +++ b/src/VIDEO/vid_cga_comp.c @@ -8,11 +8,13 @@ #include "../ibm.h" #include "../device.h" #include "../mem.h" -#include "../vid_cga.h" +#include "vid_cga.h" #include "vid_cga_comp.h" + int CGA_Composite_Table[1024]; + static double brightness = 0; static double contrast = 100; static double saturation = 100; diff --git a/src/dosbox/vid_cga_comp.h b/src/VIDEO/vid_cga_comp.h similarity index 100% rename from src/dosbox/vid_cga_comp.h rename to src/VIDEO/vid_cga_comp.h diff --git a/src/vid_cl5429.h b/src/VIDEO/vid_cl5429.h similarity index 100% rename from src/vid_cl5429.h rename to src/VIDEO/vid_cl5429.h diff --git a/src/vid_cl_gd.c b/src/VIDEO/vid_cl_gd.c similarity index 99% rename from src/vid_cl_gd.c rename to src/VIDEO/vid_cl_gd.c index b932992bb..89d9d3c77 100644 --- a/src/vid_cl_gd.c +++ b/src/VIDEO/vid_cl_gd.c @@ -1,10 +1,10 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -12,6 +12,7 @@ #include "vid_cl_gd.h" #include "vid_cl_gd_blit.h" + void cirrus_update_bank_ptr(clgd_t *clgd, uint8_t bank_index); void clgd_recalctimings(svga_t *svga); @@ -1113,4 +1114,4 @@ device_t gd6235_device = clgd_speed_changed, clgd_force_redraw, clgd_add_status_info -}; \ No newline at end of file +}; diff --git a/src/vid_cl_gd.h b/src/VIDEO/vid_cl_gd.h similarity index 100% rename from src/vid_cl_gd.h rename to src/VIDEO/vid_cl_gd.h diff --git a/src/vid_cl_gd_blit.c b/src/VIDEO/vid_cl_gd_blit.c similarity index 99% rename from src/vid_cl_gd_blit.c rename to src/VIDEO/vid_cl_gd_blit.c index b312f0012..18d6642f3 100644 --- a/src/vid_cl_gd_blit.c +++ b/src/VIDEO/vid_cl_gd_blit.c @@ -1,10 +1,10 @@ /*This is the CL-GD 5446 blitter, directly from QEMU*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -12,6 +12,7 @@ #include "vid_cl_gd.h" #include "vid_cl_gd_blit.h" + // Same for all the svga->vrammask which are -s>cirrus_addr_mask in the original. // Eventually this needs to be configurable diff --git a/src/vid_cl_gd_blit.h b/src/VIDEO/vid_cl_gd_blit.h similarity index 100% rename from src/vid_cl_gd_blit.h rename to src/VIDEO/vid_cl_gd_blit.h diff --git a/src/vid_cl_gd_vga_rop.h b/src/VIDEO/vid_cl_gd_vga_rop.h similarity index 100% rename from src/vid_cl_gd_vga_rop.h rename to src/VIDEO/vid_cl_gd_vga_rop.h diff --git a/src/vid_cl_gd_vga_rop2.h b/src/VIDEO/vid_cl_gd_vga_rop2.h similarity index 100% rename from src/vid_cl_gd_vga_rop2.h rename to src/VIDEO/vid_cl_gd_vga_rop2.h diff --git a/src/vid_cl_ramdac.c b/src/VIDEO/vid_cl_ramdac.c similarity index 97% rename from src/vid_cl_ramdac.c rename to src/VIDEO/vid_cl_ramdac.c index 2520038ea..340d27c88 100644 --- a/src/vid_cl_ramdac.c +++ b/src/VIDEO/vid_cl_ramdac.c @@ -1,13 +1,14 @@ -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_cl_ramdac.h" #include "vid_cl_gd.h" #include "vid_cl_gd_blit.h" + void cl_ramdac_out(uint16_t addr, uint8_t val, cl_ramdac_t *ramdac, void *clgd, svga_t *svga) { clgd_t *real_clgd = (clgd_t *) clgd; @@ -97,4 +98,4 @@ uint8_t cl_ramdac_in(uint16_t addr, cl_ramdac_t *ramdac, void *clgd, svga_t *svg break; } return svga_in(addr, svga); -} \ No newline at end of file +} diff --git a/src/vid_cl_ramdac.h b/src/VIDEO/vid_cl_ramdac.h similarity index 100% rename from src/vid_cl_ramdac.h rename to src/VIDEO/vid_cl_ramdac.h diff --git a/src/vid_colorplus.c b/src/VIDEO/vid_colorplus.c similarity index 99% rename from src/vid_colorplus.c rename to src/VIDEO/vid_colorplus.c index 13a661b04..25ceb71dc 100644 --- a/src/vid_colorplus.c +++ b/src/VIDEO/vid_colorplus.c @@ -1,15 +1,16 @@ /*Plantronics ColorPlus emulation*/ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" #include "vid_colorplus.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" + /* Bits in the colorplus control register: */ #define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */ diff --git a/src/vid_colorplus.h b/src/VIDEO/vid_colorplus.h similarity index 100% rename from src/vid_colorplus.h rename to src/VIDEO/vid_colorplus.h diff --git a/src/vid_ega.c b/src/VIDEO/vid_ega.c similarity index 99% rename from src/vid_ega.c rename to src/VIDEO/vid_ega.c index 42062b5b8..9243c825f 100644 --- a/src/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -1,14 +1,15 @@ /*EGA emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_ega.h" + extern uint8_t edatlookup[4][4]; static uint8_t ega_rotate[8][256]; diff --git a/src/vid_ega.h b/src/VIDEO/vid_ega.h similarity index 100% rename from src/vid_ega.h rename to src/VIDEO/vid_ega.h diff --git a/src/vid_et4000.c b/src/VIDEO/vid_et4000.c similarity index 98% rename from src/vid_et4000.c rename to src/VIDEO/vid_et4000.c index 77831c446..9ee0255a6 100644 --- a/src/vid_et4000.c +++ b/src/VIDEO/vid_et4000.c @@ -3,17 +3,17 @@ */ /*ET4000 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_unk_ramdac.h" - #include "vid_et4000.h" + typedef struct et4000_t { svga_t svga; diff --git a/src/vid_et4000.h b/src/VIDEO/vid_et4000.h similarity index 100% rename from src/vid_et4000.h rename to src/VIDEO/vid_et4000.h diff --git a/src/vid_et4000w32.c b/src/VIDEO/vid_et4000w32.c similarity index 99% rename from src/vid_et4000w32.c rename to src/VIDEO/vid_et4000w32.c index 7f63f946a..69b21af50 100644 --- a/src/vid_et4000w32.c +++ b/src/VIDEO/vid_et4000w32.c @@ -4,18 +4,19 @@ - Accelerator doesn't work in planar modes */ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../device.h" +#include "../thread.h" #include "video.h" #include "vid_svga.h" #include "vid_icd2061.h" #include "vid_stg_ramdac.h" + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) diff --git a/src/vid_et4000w32.h b/src/VIDEO/vid_et4000w32.h similarity index 100% rename from src/vid_et4000w32.h rename to src/VIDEO/vid_et4000w32.h diff --git a/src/vid_et4000w32i.c b/src/VIDEO/vid_et4000w32i.c similarity index 100% rename from src/vid_et4000w32i.c rename to src/VIDEO/vid_et4000w32i.c diff --git a/src/vid_genius.c b/src/VIDEO/vid_genius.c similarity index 99% rename from src/vid_genius.c rename to src/VIDEO/vid_genius.c index 477d845d4..a0053cc93 100644 --- a/src/vid_genius.c +++ b/src/VIDEO/vid_genius.c @@ -1,17 +1,19 @@ /* MDSI Genius VHR emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_genius.h" + #define GENIUS_XSIZE 728 #define GENIUS_YSIZE 1008 + void updatewindowsize(int x, int y); extern uint8_t fontdat8x12[256][16]; diff --git a/src/vid_genius.h b/src/VIDEO/vid_genius.h similarity index 100% rename from src/vid_genius.h rename to src/VIDEO/vid_genius.h diff --git a/src/vid_hercules.c b/src/VIDEO/vid_hercules.c similarity index 99% rename from src/vid_hercules.c rename to src/VIDEO/vid_hercules.c index 4a9606b32..8eefb409f 100644 --- a/src/vid_hercules.c +++ b/src/VIDEO/vid_hercules.c @@ -3,17 +3,18 @@ */ /*Hercules emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../mem.h" +#include "../io.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_hercules.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + typedef struct hercules_t { mem_mapping_t mapping; diff --git a/src/vid_hercules.h b/src/VIDEO/vid_hercules.h similarity index 100% rename from src/vid_hercules.h rename to src/VIDEO/vid_hercules.h diff --git a/src/vid_herculesplus.c b/src/VIDEO/vid_herculesplus.c similarity index 99% rename from src/vid_herculesplus.c rename to src/VIDEO/vid_herculesplus.c index 7af5d4a9c..a2a004312 100644 --- a/src/vid_herculesplus.c +++ b/src/VIDEO/vid_herculesplus.c @@ -4,11 +4,11 @@ /*Hercules InColor emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_herculesplus.h" diff --git a/src/vid_herculesplus.h b/src/VIDEO/vid_herculesplus.h similarity index 100% rename from src/vid_herculesplus.h rename to src/VIDEO/vid_herculesplus.h diff --git a/src/vid_icd2061.c b/src/VIDEO/vid_icd2061.c similarity index 99% rename from src/vid_icd2061.c rename to src/VIDEO/vid_icd2061.c index bc75d4999..04c2db166 100644 --- a/src/vid_icd2061.c +++ b/src/VIDEO/vid_icd2061.c @@ -5,9 +5,10 @@ ICD2061 clock generator emulation Used by ET4000w32/p (Diamond Stealth 32)*/ -#include "ibm.h" +#include "../ibm.h" #include "vid_icd2061.h" + void icd2061_write(icd2061_t *icd2061, int val) { int q, p, m, a; diff --git a/src/vid_icd2061.h b/src/VIDEO/vid_icd2061.h similarity index 100% rename from src/vid_icd2061.h rename to src/VIDEO/vid_icd2061.h diff --git a/src/vid_ics2595.c b/src/VIDEO/vid_ics2595.c similarity index 98% rename from src/vid_ics2595.c rename to src/VIDEO/vid_ics2595.c index 15c397729..ffe6f504c 100644 --- a/src/vid_ics2595.c +++ b/src/VIDEO/vid_ics2595.c @@ -3,10 +3,10 @@ */ /*ICS2595 clock chip emulation Used by ATI Mach64*/ - -#include "ibm.h" +#include "../ibm.h" #include "vid_ics2595.h" + enum { ICS2595_IDLE = 0, @@ -14,8 +14,10 @@ enum ICS2595_READ }; + static int ics2595_div[4] = {8, 4, 2, 1}; + void ics2595_write(ics2595_t *ics2595, int strobe, int dat) { if (strobe) diff --git a/src/vid_ics2595.h b/src/VIDEO/vid_ics2595.h similarity index 100% rename from src/vid_ics2595.h rename to src/VIDEO/vid_ics2595.h diff --git a/src/vid_incolor.c b/src/VIDEO/vid_incolor.c similarity index 99% rename from src/vid_incolor.c rename to src/VIDEO/vid_incolor.c index 4185978b0..45cf15d41 100644 --- a/src/vid_incolor.c +++ b/src/VIDEO/vid_incolor.c @@ -2,13 +2,12 @@ see COPYING for more details */ /*Hercules InColor emulation*/ - #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_incolor.h" diff --git a/src/vid_incolor.h b/src/VIDEO/vid_incolor.h similarity index 100% rename from src/vid_incolor.h rename to src/VIDEO/vid_incolor.h diff --git a/src/vid_mda.c b/src/VIDEO/vid_mda.c similarity index 98% rename from src/vid_mda.c rename to src/VIDEO/vid_mda.c index 4b45debc3..689cc56ab 100644 --- a/src/vid_mda.c +++ b/src/VIDEO/vid_mda.c @@ -3,17 +3,18 @@ */ /*MDA emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_mda.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + typedef struct mda_t { mem_mapping_t mapping; diff --git a/src/vid_mda.h b/src/VIDEO/vid_mda.h similarity index 100% rename from src/vid_mda.h rename to src/VIDEO/vid_mda.h diff --git a/src/vid_nv_riva128.c b/src/VIDEO/vid_nv_riva128.c similarity index 99% rename from src/vid_nv_riva128.c rename to src/VIDEO/vid_nv_riva128.c index ce8ff697c..d6bcd839b 100644 --- a/src/vid_nv_riva128.c +++ b/src/VIDEO/vid_nv_riva128.c @@ -3,20 +3,21 @@ */ /*nVidia RIVA 128 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "pic.h" -#include "rom.h" -#include "thread.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../pic.h" +#include "../rom.h" +#include "../thread.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_nv_riva128.h" #include "vid_svga.h" #include "vid_svga_render.h" + typedef struct riva128_t { mem_mapping_t linear_mapping; diff --git a/src/vid_nv_riva128.h b/src/VIDEO/vid_nv_riva128.h similarity index 100% rename from src/vid_nv_riva128.h rename to src/VIDEO/vid_nv_riva128.h diff --git a/src/vid_olivetti_m24.c b/src/VIDEO/vid_olivetti_m24.c similarity index 99% rename from src/vid_olivetti_m24.c rename to src/VIDEO/vid_olivetti_m24.c index 8b6e62983..f130c69fb 100644 --- a/src/vid_olivetti_m24.c +++ b/src/VIDEO/vid_olivetti_m24.c @@ -4,14 +4,15 @@ /*Olivetti M24 video emulation Essentially double-res CGA*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_olivetti_m24.h" + typedef struct m24_t { mem_mapping_t mapping; diff --git a/src/vid_olivetti_m24.h b/src/VIDEO/vid_olivetti_m24.h similarity index 100% rename from src/vid_olivetti_m24.h rename to src/VIDEO/vid_olivetti_m24.h diff --git a/src/vid_oti067.c b/src/VIDEO/vid_oti067.c similarity index 98% rename from src/vid_oti067.c rename to src/VIDEO/vid_oti067.c index dc3d94e6c..c04a43778 100644 --- a/src/vid_oti067.c +++ b/src/VIDEO/vid_oti067.c @@ -3,15 +3,16 @@ */ /*Oak OTI067 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_oti067.h" #include "vid_svga.h" + typedef struct oti067_t { svga_t svga; diff --git a/src/vid_oti067.h b/src/VIDEO/vid_oti067.h similarity index 100% rename from src/vid_oti067.h rename to src/VIDEO/vid_oti067.h diff --git a/src/vid_paradise.c b/src/VIDEO/vid_paradise.c similarity index 99% rename from src/vid_paradise.c rename to src/VIDEO/vid_paradise.c index 6a385611a..4527619fe 100644 --- a/src/vid_paradise.c +++ b/src/VIDEO/vid_paradise.c @@ -7,17 +7,18 @@ MegaPC uses W90C11A */ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_paradise.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_unk_ramdac.h" + typedef struct paradise_t { svga_t svga; diff --git a/src/vid_paradise.h b/src/VIDEO/vid_paradise.h similarity index 100% rename from src/vid_paradise.h rename to src/VIDEO/vid_paradise.h diff --git a/src/vid_pc1512.c b/src/VIDEO/vid_pc1512.c similarity index 99% rename from src/vid_pc1512.c rename to src/VIDEO/vid_pc1512.c index 466db6f8f..832bde2ea 100644 --- a/src/vid_pc1512.c +++ b/src/VIDEO/vid_pc1512.c @@ -10,14 +10,15 @@ The Technical Reference Manual lists the video waitstate time as between 12 and 46 cycles. PCem currently always uses the lower number.*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_pc1512.h" + typedef struct pc1512_t { mem_mapping_t mapping; diff --git a/src/vid_pc1512.h b/src/VIDEO/vid_pc1512.h similarity index 100% rename from src/vid_pc1512.h rename to src/VIDEO/vid_pc1512.h diff --git a/src/vid_pc1640.c b/src/VIDEO/vid_pc1640.c similarity index 97% rename from src/vid_pc1640.c rename to src/VIDEO/vid_pc1640.c index 68a2117a0..3db12e57d 100644 --- a/src/vid_pc1640.c +++ b/src/VIDEO/vid_pc1640.c @@ -4,17 +4,18 @@ /*PC1640 video emulation. Mostly standard EGA, but with CGA & Hercules emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" #include "vid_ega.h" #include "vid_pc1640.h" + typedef struct pc1640_t { mem_mapping_t cga_mapping; diff --git a/src/vid_pc1640.h b/src/VIDEO/vid_pc1640.h similarity index 100% rename from src/vid_pc1640.h rename to src/VIDEO/vid_pc1640.h diff --git a/src/vid_pc200.c b/src/VIDEO/vid_pc200.c similarity index 97% rename from src/vid_pc200.c rename to src/VIDEO/vid_pc200.c index 99eeb3171..eef181c33 100644 --- a/src/vid_pc200.c +++ b/src/VIDEO/vid_pc200.c @@ -5,15 +5,16 @@ CGA with some NMI stuff. But we don't need that as it's only used for TV and LCD displays, and we're emulating a CRT*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_cga.h" #include "vid_pc200.h" + typedef struct pc200_t { mem_mapping_t mapping; diff --git a/src/vid_pc200.h b/src/VIDEO/vid_pc200.h similarity index 100% rename from src/vid_pc200.h rename to src/VIDEO/vid_pc200.h diff --git a/src/vid_pcjr.c b/src/VIDEO/vid_pcjr.c similarity index 99% rename from src/vid_pcjr.c rename to src/VIDEO/vid_pcjr.c index b10cb475c..0557967d9 100644 --- a/src/vid_pcjr.c +++ b/src/VIDEO/vid_pcjr.c @@ -1,18 +1,20 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pic.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pic.h" +#include "../timer.h" +#include "../device.h" #include "video.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" #include "vid_pcjr.h" + #define PCJR_RGB 0 #define PCJR_COMPOSITE 1 + typedef struct pcjr_t { mem_mapping_t mapping; diff --git a/src/vid_pcjr.h b/src/VIDEO/vid_pcjr.h similarity index 100% rename from src/vid_pcjr.h rename to src/VIDEO/vid_pcjr.h diff --git a/src/vid_ps1_svga.c b/src/VIDEO/vid_ps1_svga.c similarity index 98% rename from src/vid_ps1_svga.c rename to src/VIDEO/vid_ps1_svga.c index 86b10c8ec..9bb6acafc 100644 --- a/src/vid_ps1_svga.c +++ b/src/VIDEO/vid_ps1_svga.c @@ -8,15 +8,16 @@ it's just a VGA for now. */ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_vga.h" + typedef struct ps1_m2121_svga_t { svga_t svga; diff --git a/src/vid_ps1_svga.h b/src/VIDEO/vid_ps1_svga.h similarity index 100% rename from src/vid_ps1_svga.h rename to src/VIDEO/vid_ps1_svga.h diff --git a/src/vid_s3.c b/src/VIDEO/vid_s3.c similarity index 99% rename from src/vid_s3.c rename to src/VIDEO/vid_s3.c index cf2621698..9feac48de 100644 --- a/src/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1,18 +1,19 @@ /*S3 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../thread.h" +#include "../device.h" #include "video.h" #include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" + enum { S3_VISION864, diff --git a/src/vid_s3.h b/src/VIDEO/vid_s3.h similarity index 100% rename from src/vid_s3.h rename to src/VIDEO/vid_s3.h diff --git a/src/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c similarity index 99% rename from src/vid_s3_virge.c rename to src/VIDEO/vid_s3_virge.c index e11f1c7d0..21723de42 100644 --- a/src/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -3,18 +3,19 @@ */ /*S3 ViRGE emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../device.h" +#include "../thread.h" #include "video.h" #include "vid_s3_virge.h" #include "vid_svga.h" #include "vid_svga_render.h" + static uint64_t virge_time = 0; static uint64_t status_time = 0; static int reg_writes = 0, reg_reads = 0; diff --git a/src/vid_s3_virge.h b/src/VIDEO/vid_s3_virge.h similarity index 100% rename from src/vid_s3_virge.h rename to src/VIDEO/vid_s3_virge.h diff --git a/src/vid_sdac_ramdac.c b/src/VIDEO/vid_sdac_ramdac.c similarity index 99% rename from src/vid_sdac_ramdac.c rename to src/VIDEO/vid_sdac_ramdac.c index c1dad85d2..3bff85104 100644 --- a/src/vid_sdac_ramdac.c +++ b/src/VIDEO/vid_sdac_ramdac.c @@ -3,12 +3,13 @@ */ /*87C716 'SDAC' true colour RAMDAC emulation*/ /*Misidentifies as AT&T 21C504*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_sdac_ramdac.h" + /* Returning divider * 2 */ int sdac_get_clock_divider(sdac_ramdac_t *ramdac) { diff --git a/src/vid_sdac_ramdac.h b/src/VIDEO/vid_sdac_ramdac.h similarity index 100% rename from src/vid_sdac_ramdac.h rename to src/VIDEO/vid_sdac_ramdac.h diff --git a/src/vid_stg_ramdac.c b/src/VIDEO/vid_stg_ramdac.c similarity index 99% rename from src/vid_stg_ramdac.c rename to src/VIDEO/vid_stg_ramdac.c index 2aa3fee19..2881fff91 100644 --- a/src/vid_stg_ramdac.c +++ b/src/VIDEO/vid_stg_ramdac.c @@ -2,15 +2,17 @@ see COPYING for more details */ /*STG1702 true colour RAMDAC emulation*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_stg_ramdac.h" + static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}}; static int stg_state_write[8] = {0,0,0,0,0,6,7,7}; + void stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac) { if (ramdac->command & 0x8) diff --git a/src/vid_stg_ramdac.h b/src/VIDEO/vid_stg_ramdac.h similarity index 100% rename from src/vid_stg_ramdac.h rename to src/VIDEO/vid_stg_ramdac.h diff --git a/src/vid_svga.c b/src/VIDEO/vid_svga.c similarity index 99% rename from src/vid_svga.c rename to src/VIDEO/vid_svga.c index 9db83a709..bb54d1498 100644 --- a/src/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -5,16 +5,18 @@ /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/ #include #include -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include "io.h" -#include "timer.h" + #define svga_output 0 + void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga); extern uint8_t edatlookup[4][4]; @@ -1842,4 +1844,4 @@ void svga_add_status_info(char *s, int max_len, void *p) sprintf(temps, "SVGA DAC in %i-bit mode\n", (svga->attrregs[0x10] & 0x80) ? 8 : 6); strncat(s, temps, max_len); -} \ No newline at end of file +} diff --git a/src/vid_svga.h b/src/VIDEO/vid_svga.h similarity index 100% rename from src/vid_svga.h rename to src/VIDEO/vid_svga.h diff --git a/src/vid_svga_render.c b/src/VIDEO/vid_svga_render.c similarity index 99% rename from src/vid_svga_render.c rename to src/VIDEO/vid_svga_render.c index cf6caac68..fb8845a75 100644 --- a/src/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -1,15 +1,17 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#include "ibm.h" -#include "mem.h" +#include +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" -#include + int invert_display = 0; + uint32_t svga_color_transform(uint32_t color) { uint32_t temp = 0; diff --git a/src/vid_svga_render.h b/src/VIDEO/vid_svga_render.h similarity index 100% rename from src/vid_svga_render.h rename to src/VIDEO/vid_svga_render.h diff --git a/src/vid_tandy.c b/src/VIDEO/vid_tandy.c similarity index 99% rename from src/vid_tandy.c rename to src/VIDEO/vid_tandy.c index e9deb6798..d6151e44e 100644 --- a/src/vid_tandy.c +++ b/src/VIDEO/vid_tandy.c @@ -1,17 +1,19 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_tandy.h" -#include "dosbox/vid_cga_comp.h" +#include "vid_cga_comp.h" + #define TANDY_RGB 0 #define TANDY_COMPOSITE 1 + typedef struct tandy_t { mem_mapping_t mapping; diff --git a/src/vid_tandy.h b/src/VIDEO/vid_tandy.h similarity index 100% rename from src/vid_tandy.h rename to src/VIDEO/vid_tandy.h diff --git a/src/vid_tandysl.c b/src/VIDEO/vid_tandysl.c similarity index 99% rename from src/vid_tandysl.c rename to src/VIDEO/vid_tandysl.c index 0ad656aaf..0c4225525 100644 --- a/src/vid_tandysl.c +++ b/src/VIDEO/vid_tandysl.c @@ -3,14 +3,15 @@ */ #include #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_tandysl.h" + typedef struct tandysl_t { mem_mapping_t mapping; diff --git a/src/vid_tandysl.h b/src/VIDEO/vid_tandysl.h similarity index 100% rename from src/vid_tandysl.h rename to src/VIDEO/vid_tandysl.h diff --git a/src/vid_tgui9440.c b/src/VIDEO/vid_tgui9440.c similarity index 99% rename from src/vid_tgui9440.c rename to src/VIDEO/vid_tgui9440.c index 384f76a81..e365ed4ac 100644 --- a/src/vid_tgui9440.c +++ b/src/VIDEO/vid_tgui9440.c @@ -3,19 +3,20 @@ */ /*Trident TGUI9440 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../pci.h" +#include "../rom.h" +#include "../device.h" +#include "../thread.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_tkd8001_ramdac.h" #include "vid_tgui9440.h" + #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) #define FIFO_ENTRY_SIZE (1 << 31) diff --git a/src/vid_tgui9440.h b/src/VIDEO/vid_tgui9440.h similarity index 100% rename from src/vid_tgui9440.h rename to src/VIDEO/vid_tgui9440.h diff --git a/src/vid_tkd8001_ramdac.c b/src/VIDEO/vid_tkd8001_ramdac.c similarity index 97% rename from src/vid_tkd8001_ramdac.c rename to src/VIDEO/vid_tkd8001_ramdac.c index 3d22d987c..553bc489f 100644 --- a/src/vid_tkd8001_ramdac.c +++ b/src/VIDEO/vid_tkd8001_ramdac.c @@ -2,12 +2,13 @@ see COPYING for more details */ /*Trident TKD8001 RAMDAC emulation*/ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_tkd8001_ramdac.h" + void tkd8001_ramdac_out(uint16_t addr, uint8_t val, tkd8001_ramdac_t *ramdac, svga_t *svga) { switch (addr) diff --git a/src/vid_tkd8001_ramdac.h b/src/VIDEO/vid_tkd8001_ramdac.h similarity index 100% rename from src/vid_tkd8001_ramdac.h rename to src/VIDEO/vid_tkd8001_ramdac.h diff --git a/src/vid_tvga.c b/src/VIDEO/vid_tvga.c similarity index 99% rename from src/vid_tvga.c rename to src/VIDEO/vid_tvga.c index bbbf9d1ca..7c6c7f255 100644 --- a/src/vid_tvga.c +++ b/src/VIDEO/vid_tvga.c @@ -3,17 +3,18 @@ */ /*Trident TVGA (8900D) emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_tkd8001_ramdac.h" #include "vid_tvga.h" + typedef struct tvga_t { mem_mapping_t linear_mapping; diff --git a/src/vid_tvga.h b/src/VIDEO/vid_tvga.h similarity index 100% rename from src/vid_tvga.h rename to src/VIDEO/vid_tvga.h diff --git a/src/vid_unk_ramdac.c b/src/VIDEO/vid_unk_ramdac.c similarity index 98% rename from src/vid_unk_ramdac.c rename to src/VIDEO/vid_unk_ramdac.c index 0b6fc6aea..c2fb35bae 100644 --- a/src/vid_unk_ramdac.c +++ b/src/VIDEO/vid_unk_ramdac.c @@ -5,12 +5,13 @@ It is possibly a Sierra 1502x It's addressed by the TLIVESA1 driver for ET4000*/ /* Note by Tenshi: Not possibly, this *IS* a Sierra 1502x. */ -#include "ibm.h" -#include "mem.h" +#include "../ibm.h" +#include "../mem.h" #include "video.h" #include "vid_svga.h" #include "vid_unk_ramdac.h" + void unk_ramdac_out(uint16_t addr, uint8_t val, unk_ramdac_t *ramdac, svga_t *svga) { int oldbpp = 0; diff --git a/src/vid_unk_ramdac.h b/src/VIDEO/vid_unk_ramdac.h similarity index 100% rename from src/vid_unk_ramdac.h rename to src/VIDEO/vid_unk_ramdac.h diff --git a/src/vid_vga.c b/src/VIDEO/vid_vga.c similarity index 98% rename from src/vid_vga.c rename to src/VIDEO/vid_vga.c index a69b6f60c..e1570b3c4 100644 --- a/src/vid_vga.c +++ b/src/VIDEO/vid_vga.c @@ -3,15 +3,16 @@ */ /*IBM VGA emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "io.h" -#include "mem.h" -#include "rom.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_vga.h" + typedef struct vga_t { svga_t svga; diff --git a/src/vid_vga.h b/src/VIDEO/vid_vga.h similarity index 100% rename from src/vid_vga.h rename to src/VIDEO/vid_vga.h diff --git a/src/vid_voodoo.c b/src/VIDEO/vid_voodoo.c similarity index 99% rename from src/vid_voodoo.c rename to src/VIDEO/vid_voodoo.c index eef3df1e8..815d071a6 100644 --- a/src/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -1,17 +1,19 @@ #include #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "pci.h" -#include "rom.h" -#include "thread.h" -#include "timer.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../mem.h" +#include "../rom.h" +#include "../pci.h" +#include "../thread.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_voodoo.h" #include "vid_voodoo_dither.h" + #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define CLAMP(x) (((x) < 0) ? 0 : (((x) > 0xff) ? 0xff : (x))) diff --git a/src/vid_voodoo.h b/src/VIDEO/vid_voodoo.h similarity index 100% rename from src/vid_voodoo.h rename to src/VIDEO/vid_voodoo.h diff --git a/src/vid_voodoo_codegen_x86-64.h b/src/VIDEO/vid_voodoo_codegen_x86-64.h similarity index 100% rename from src/vid_voodoo_codegen_x86-64.h rename to src/VIDEO/vid_voodoo_codegen_x86-64.h diff --git a/src/vid_voodoo_codegen_x86.h b/src/VIDEO/vid_voodoo_codegen_x86.h similarity index 100% rename from src/vid_voodoo_codegen_x86.h rename to src/VIDEO/vid_voodoo_codegen_x86.h diff --git a/src/vid_voodoo_dither.h b/src/VIDEO/vid_voodoo_dither.h similarity index 100% rename from src/vid_voodoo_dither.h rename to src/VIDEO/vid_voodoo_dither.h diff --git a/src/vid_wy700.c b/src/VIDEO/vid_wy700.c similarity index 99% rename from src/vid_wy700.c rename to src/VIDEO/vid_wy700.c index 4519a293e..a7b612e09 100644 --- a/src/vid_wy700.c +++ b/src/VIDEO/vid_wy700.c @@ -1,16 +1,18 @@ /* Wyse-700 emulation*/ #include -#include "ibm.h" -#include "device.h" -#include "mem.h" -#include "io.h" -#include "timer.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../timer.h" +#include "../device.h" #include "video.h" #include "vid_wy700.h" + #define WY700_XSIZE 1280 #define WY700_YSIZE 800 + void updatewindowsize(int x, int y); diff --git a/src/vid_wy700.h b/src/VIDEO/vid_wy700.h similarity index 100% rename from src/vid_wy700.h rename to src/VIDEO/vid_wy700.h diff --git a/src/video.c b/src/VIDEO/video.c similarity index 97% rename from src/video.c rename to src/VIDEO/video.c index 798981c71..20352cdb5 100644 --- a/src/video.c +++ b/src/VIDEO/video.c @@ -5,21 +5,22 @@ #include #include #include -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "mem.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../config.h" +#include "../device.h" +#include "../thread.h" +#include "../timer.h" #include "video.h" #include "vid_svga.h" -#include "io.h" -#include "cpu.h" -#include "rom.h" -#include "thread.h" -#include "timer.h" #ifndef __unix -#include "win-cgapal.h" +#include "../win-cgapal.h" #endif + #include "vid_ati18800.h" #include "vid_ati28800.h" #include "vid_ati_mach64.h" @@ -57,6 +58,7 @@ #include "vid_vga.h" #include "vid_wy700.h" + int cga_palette = 0; typedef struct @@ -686,20 +688,20 @@ void take_screenshot() #else time_t now; struct tm *info; -char screenshot_fn_partial[2048]; -char screenshot_fn[4096]; +wchar_t screenshot_fn_partial[2048]; +wchar_t screenshot_fn[4096]; void take_screenshot() { if ((vid_api < 0) || (vid_api > 1)) return; time(&now); info = localtime(&now); - memset(screenshot_fn, 0, 4096); - memset(screenshot_fn_partial, 0, 2048); + memset(screenshot_fn, 0, 8192); + memset(screenshot_fn_partial, 0, 4096); pclog("Video API is: %i\n", vid_api); if (vid_api == 1) { - strftime(screenshot_fn_partial, 2048, "screenshots\\%Y%m%d_%H%M%S.png", info); + wcsftime(screenshot_fn_partial, 2048, L"screenshots\\%Y%m%d_%H%M%S.png", info); append_filename(screenshot_fn, pcempath, screenshot_fn_partial, 4095); if (video_fullscreen) { diff --git a/src/video.h b/src/VIDEO/video.h similarity index 93% rename from src/video.h rename to src/VIDEO/video.h index 234bb81ad..83e50bc1d 100644 --- a/src/video.h +++ b/src/VIDEO/video.h @@ -103,10 +103,10 @@ extern "C" { #endif void take_screenshot(); -void d3d_take_screenshot(char *fn); -void d3d_fs_take_screenshot(char *fn); -void ddraw_take_screenshot(char *fn); -void ddraw_fs_take_screenshot(char *fn); +void d3d_take_screenshot(wchar_t *fn); +void d3d_fs_take_screenshot(wchar_t *fn); +void ddraw_take_screenshot(wchar_t *fn); +void ddraw_fs_take_screenshot(wchar_t *fn); #ifdef __cplusplus } #endif diff --git a/src/acer386sx.c b/src/acer386sx.c index ea3bfe74d..4f6ce5eed 100644 --- a/src/acer386sx.c +++ b/src/acer386sx.c @@ -2,14 +2,15 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" -#include "cpu.h" - #include "acer386sx.h" + static int acer_index = 0; static uint8_t acer_regs[256]; + void acer386sx_write(uint16_t addr, uint8_t val, void *priv) { if (addr & 1) diff --git a/src/ali1429.c b/src/ali1429.c index f1fa8fa3f..e0c348829 100644 --- a/src/ali1429.c +++ b/src/ali1429.c @@ -3,9 +3,9 @@ */ #include #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" -#include "cpu.h" #include "ali1429.h" diff --git a/src/buslogic.h b/src/buslogic.h deleted file mode 100644 index c4b6805f0..000000000 --- a/src/buslogic.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef BUSLOGIC_H -# define BUSLOGIC_H - - -typedef struct { - uint8_t flags; /* local flags */ - uint8_t bid; /* board ID */ - char fwl, fwh; /* firmware info */ -} aha_info; -#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ - - -extern device_t aha1540b_device; -extern device_t aha1542cf_device; -extern device_t buslogic_device; -extern device_t buslogic_pci_device; - - -extern int buslogic_dev_present(uint8_t id, uint8_t lun); - -extern void aha154x_init(uint16_t, uint32_t, aha_info *); -extern uint8_t aha154x_shram(uint8_t); -extern uint8_t aha154x_eeprom(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t *); -extern uint8_t aha154x_memory(uint8_t); - - -#endif /*BUSLOGIC_H*/ diff --git a/src/cdrom.c b/src/cdrom.c index 8cf6e3174..09f55ac4d 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -978,16 +978,16 @@ void cdrom_mode_sense_load(uint8_t id) switch(id) { case 0: - f = fopen(nvr_concat("cdrom_1_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_1_mode_sense.bin"), L"rb"); break; case 1: - f = fopen(nvr_concat("cdrom_2_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_2_mode_sense.bin"), L"rb"); break; case 2: - f = fopen(nvr_concat("cdrom_3_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_3_mode_sense.bin"), L"rb"); break; case 3: - f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "rb"); + f = _wfopen(nvr_concat(L"cdrom_4_mode_sense.bin"), L"rb"); break; default: return; @@ -1006,16 +1006,16 @@ void cdrom_mode_sense_save(uint8_t id) switch(id) { case 0: - f = fopen(nvr_concat("cdrom_1_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_1_mode_sense.bin"), L"wb"); break; case 1: - f = fopen(nvr_concat("cdrom_2_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_2_mode_sense.bin"), L"wb"); break; case 2: - f = fopen(nvr_concat("cdrom_3_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_3_mode_sense.bin"), L"wb"); break; case 3: - f = fopen(nvr_concat("cdrom_4_mode_sense.bin"), "wb"); + f = _wfopen(nvr_concat(L"cdrom_4_mode_sense.bin"), L"wb"); break; default: return; diff --git a/src/config.c b/src/config.c index 55b4fec72..c72de4da8 100644 --- a/src/config.c +++ b/src/config.c @@ -470,7 +470,7 @@ void config_save(wchar_t *fn) if (current_section->name[0]) { mbstowcs(wname, current_section->name, strlen(current_section->name) + 1); - _fwprintf_p(f, L"\n[%ws]\n", wname); + fwprintf(f, L"\n[%ws]\n", wname); } current_entry = (entry_t *)current_section->entry_head.next; @@ -480,11 +480,11 @@ void config_save(wchar_t *fn) mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); if (current_entry->wdata[0] == L'\0') { - _fwprintf_p(f, L"%ws = \n", wname); + fwprintf(f, L"%ws = \n", wname); } else { - _fwprintf_p(f, L"%ws = %ws\n", wname, current_entry->wdata); + fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); } current_entry = (entry_t *)current_entry->list.next; diff --git a/src/config.h b/src/config.h index b51585b52..feab20d60 100644 --- a/src/config.h +++ b/src/config.h @@ -19,7 +19,7 @@ wchar_t *get_extension_w(wchar_t *s); void config_load(wchar_t *fn); void config_save(wchar_t *fn); -void config_dump(); -void config_free(); +void config_dump(void); +void config_free(void); extern wchar_t config_file_default[256]; diff --git a/src/device.c b/src/device.c index 39a4c0c32..ec63744d5 100644 --- a/src/device.c +++ b/src/device.c @@ -1,9 +1,10 @@ #include "ibm.h" +#include "cpu/cpu.h" #include "config.h" -#include "cpu.h" #include "device.h" #include "model.h" -#include "sound.h" +#include "sound/sound.h" + static void *device_priv[256]; static device_t *devices[256]; diff --git a/src/dma.c b/src/dma.c index c1c039ffa..259401dee 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,16 +1,19 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ #include "ibm.h" - -#include "dma.h" -#include "io.h" +#include "cpu/x86.h" #include "mem.h" -#include "video.h" -#include "x86.h" +#include "io.h" +#include "dma.h" + static uint8_t dmaregs[16]; static uint8_t dma16regs[16]; static uint8_t dmapages[16]; -void dma_reset() + +void dma_reset(void) { int c; dma.wp = 0; @@ -447,30 +450,30 @@ uint8_t dma_page_read(uint16_t addr, void *priv) return dmapages[addr & 0xf]; } -void dma_init() +void dma_init(void) { io_sethandler(0x0000, 0x0010, dma_read, NULL, NULL, dma_write, NULL, NULL, NULL); io_sethandler(0x0080, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); dma.is_ps2 = 0; } -void dma16_init() +void dma16_init(void) { io_sethandler(0x00C0, 0x0020, dma16_read, NULL, NULL, dma16_write, NULL, NULL, NULL); io_sethandler(0x0088, 0x0008, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void dma_alias_set() +void dma_alias_set(void) { io_sethandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void dma_alias_remove() +void dma_alias_remove(void) { io_removehandler(0x0090, 0x0010, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void dma_alias_remove_piix() +void dma_alias_remove_piix(void) { io_removehandler(0x0090, 0x0001, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); io_removehandler(0x0094, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); diff --git a/src/dma.h b/src/dma.h index 3cf611ea2..515f02f87 100644 --- a/src/dma.h +++ b/src/dma.h @@ -1,29 +1,29 @@ /* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ -void dma_init(); -void dma16_init(); -void ps2_dma_init(); -void dma_reset(); +void dma_init(void); +void dma16_init(void); +void ps2_dma_init(void); +void dma_reset(void); int dma_mode(int channel); #define DMA_NODATA -1 #define DMA_OVER 0x10000 #define DMA_VERIFY 0x20000 -void readdma0(); -int readdma1(); -uint8_t readdma2(); -int readdma3(); +void readdma0(void); +int readdma1(void); +uint8_t readdma2(void); +int readdma3(void); void writedma2(uint8_t temp); int dma_channel_read(int channel); int dma_channel_write(int channel, uint16_t val); -void dma_alias_set(); -void dma_alias_remove(); -void dma_alias_remove_piix(); +void dma_alias_set(void); +void dma_alias_remove(void); +void dma_alias_remove_piix(void); void DMAPageRead(uint32_t PhysAddress, char *DataRead, uint32_t TotalSize); -void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); \ No newline at end of file +void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); diff --git a/src/gameport.c b/src/gameport.c index 45e2cb8d8..b75e9f6ce 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -4,19 +4,21 @@ #include #include #include "ibm.h" +#include "cpu/cpu.h" #include "device.h" #include "io.h" -#include "plat-joystick.h" #include "timer.h" - +#include "plat-joystick.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" #include "joystick_sw_pad.h" #include "joystick_tm_fcs.h" + int joystick_type; + joystick_if_t joystick_none = { "No joystick", diff --git a/src/headland.c b/src/headland.c index b100b85c8..62e6dd076 100644 --- a/src/headland.c +++ b/src/headland.c @@ -2,9 +2,9 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" -#include "cpu.h" #include "headland.h" diff --git a/src/intel.c b/src/intel.c index 2eb47939b..01560852f 100644 --- a/src/intel.c +++ b/src/intel.c @@ -2,14 +2,14 @@ see COPYING for more details */ #include "ibm.h" -#include "cpu.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "pit.h" #include "timer.h" - #include "intel.h" + uint8_t batman_brdconfig(uint16_t port, void *p) { switch (port) diff --git a/src/intel_flash.c b/src/intel_flash.c index dae940086..1ccb225a9 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -159,61 +159,61 @@ void *intel_flash_init(uint8_t type) switch(romset) { case ROM_REVENGE: - wcscpy(flash_path, nvr_concat(L"revenge.bin")); + wcscpy(flash_path, L"revenge.bin"); break; case ROM_586MC1: - wcscpy(flash_path, nvr_concat(L"586mc1.bin")); + wcscpy(flash_path, L"586mc1.bin"); break; case ROM_PLATO: - wcscpy(flash_path, nvr_concat(L"plato.bin")); + wcscpy(flash_path, L"plato.bin"); break; case ROM_ENDEAVOR: - wcscpy(flash_path, nvr_concat(L"endeavor.bin")); + wcscpy(flash_path, L"endeavor.bin"); break; case ROM_MB500N: - wcscpy(flash_path, nvr_concat(L"mb500n.bin")); + wcscpy(flash_path, L"mb500n.bin"); break; case ROM_P54TP4XE: - wcscpy(flash_path, nvr_concat(L"p54tp4xe.bin")); + wcscpy(flash_path, L"p54tp4xe.bin"); break; case ROM_AP53: - wcscpy(flash_path, nvr_concat(L"ap53.bin")); + wcscpy(flash_path, L"ap53.bin"); break; case ROM_P55T2S: - wcscpy(flash_path, nvr_concat(L"p55t2s.bin")); + wcscpy(flash_path, L"p55t2s.bin"); break; case ROM_ACERM3A: - wcscpy(flash_path, nvr_concat(L"acerm3a.bin")); + wcscpy(flash_path, L"acerm3a.bin"); break; case ROM_ACERV35N: - wcscpy(flash_path, nvr_concat(L"acerv35n.bin")); + wcscpy(flash_path, L"acerv35n.bin"); break; case ROM_430VX: - wcscpy(flash_path, nvr_concat(L"430vx.bin")); + wcscpy(flash_path, L"430vx.bin"); break; case ROM_P55VA: - wcscpy(flash_path, nvr_concat(L"p55va.bin")); + wcscpy(flash_path, L"p55va.bin"); break; case ROM_P55T2P4: - wcscpy(flash_path, nvr_concat(L"p55t2p4.bin")); + wcscpy(flash_path, L"p55t2p4.bin"); break; case ROM_P55TVP4: - wcscpy(flash_path, nvr_concat(L"p55tvp4.bin")); + wcscpy(flash_path, L"p55tvp4.bin"); break; case ROM_440FX: - wcscpy(flash_path, nvr_concat(L"440fx.bin")); + wcscpy(flash_path, L"440fx.bin"); break; case ROM_THOR: - wcscpy(flash_path, nvr_concat(L"thor.bin")); + wcscpy(flash_path, L"thor.bin"); break; case ROM_MRTHOR: - wcscpy(flash_path, nvr_concat(L"mrthor.bin")); + wcscpy(flash_path, L"mrthor.bin"); break; case ROM_ZAPPA: - wcscpy(flash_path, nvr_concat(L"zappa.bin")); + wcscpy(flash_path, L"zappa.bin"); break; case ROM_S1668: - wcscpy(flash_path, nvr_concat(L"tpatx.bin")); + wcscpy(flash_path, L"tpatx.bin"); break; default: fatal("intel_flash_init on unsupported ROM set %i\n", romset); diff --git a/src/io.c b/src/io.c index da9e3318a..ca9259e75 100644 --- a/src/io.c +++ b/src/io.c @@ -2,10 +2,8 @@ see COPYING for more details */ #include "ibm.h" -#include "ide.h" #include "io.h" -#include "video.h" -#include "cpu.h" + uint8_t (*port_inb[0x10000][2])(uint16_t addr, void *priv); uint16_t (*port_inw[0x10000][2])(uint16_t addr, void *priv); @@ -17,6 +15,7 @@ void (*port_outl[0x10000][2])(uint16_t addr, uint32_t val, void *priv); void *port_priv[0x10000][2]; + void io_init() { int c; diff --git a/src/keyboard_amstrad.c b/src/keyboard_amstrad.c index 6ec66001f..3765b43ca 100644 --- a/src/keyboard_amstrad.c +++ b/src/keyboard_amstrad.c @@ -7,13 +7,13 @@ #include "mem.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" #include "timer.h" - +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_amstrad.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4cf084829..4e6c7f7e9 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -2,21 +2,20 @@ see COPYING for more details */ #include - #include "ibm.h" -#include "disc.h" -#include "fdc.h" #include "io.h" #include "mem.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" #include "timer.h" - +#include "disc.h" +#include "fdc.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_at.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index 498640777..e031bafad 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -2,16 +2,16 @@ #include "ibm.h" #include "io.h" #include "mem.h" -#include "mouse.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" #include "timer.h" - +#include "mouse.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_olim24.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -21,6 +21,7 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 + struct { int wantirq; diff --git a/src/keyboard_pcjr.c b/src/keyboard_pcjr.c index 38142dd14..a7005d77b 100644 --- a/src/keyboard_pcjr.c +++ b/src/keyboard_pcjr.c @@ -2,22 +2,21 @@ see COPYING for more details */ #include - #include "ibm.h" -#include "device.h" #include "io.h" #include "mem.h" #include "nmi.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_sn76489.h" -#include "sound_speaker.h" #include "timer.h" - +#include "device.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" +#include "sound/snd_sn76489.h" #include "keyboard.h" #include "keyboard_pcjr.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 0541b2692..c4497f9b9 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -2,21 +2,20 @@ see COPYING for more details */ #include - #include "ibm.h" -#include "device.h" #include "io.h" #include "mem.h" #include "pic.h" #include "pit.h" -#include "sound.h" -#include "sound_speaker.h" -#include "tandy_eeprom.h" #include "timer.h" - +#include "device.h" +#include "tandy_eeprom.h" +#include "sound/sound.h" +#include "sound/snd_speaker.h" #include "keyboard.h" #include "keyboard_xt.h" + #define STAT_PARITY 0x80 #define STAT_RTIMEOUT 0x40 #define STAT_TTIMEOUT 0x20 @@ -26,6 +25,7 @@ #define STAT_IFULL 0x02 #define STAT_OFULL 0x01 + struct { int blocked; diff --git a/src/mem.c b/src/mem.c index 59b94136e..2e087651f 100644 --- a/src/mem.c +++ b/src/mem.c @@ -7,20 +7,19 @@ - pc2386 video BIOS is underdumped (16k instead of 24k) - c386sx16 BIOS fails checksum */ - #include #include #include "ibm.h" - +#include "cpu/cpu.h" +#include "cpu/x86_ops.h" +#include "cpu/x86.h" #include "config.h" #include "io.h" #include "mem.h" -#include "video.h" -#include "x86.h" -#include "cpu.h" #include "rom.h" -#include "x86_ops.h" -#include "codegen.h" +#include "cpu/codegen.h" +#include "video/video.h" + page_t *pages; page_t **page_lookup; diff --git a/src/model.c b/src/model.c index f92f0ea92..6410737d9 100644 --- a/src/model.c +++ b/src/model.c @@ -3,16 +3,15 @@ */ #include #include - #include "ibm.h" -#include "cdrom.h" -#include "cpu.h" +#include "cpu/cpu.h" +#include "io.h" #include "mem.h" +#include "rom.h" #include "model.h" #include "mouse.h" #include "mouse_ps2.h" -#include "io.h" -#include "rom.h" +#include "cdrom.h" #include "acerm3a.h" #include "ali1429.h" @@ -64,14 +63,14 @@ #include "sis496.h" #include "sis85c471.h" #include "sio.h" -#include "sound_ps1.h" -#include "sound_pssj.h" -#include "sound_sn76489.h" +#include "sound/snd_ps1.h" +#include "sound/snd_pssj.h" +#include "sound/snd_sn76489.h" #include "tandy_eeprom.h" #include "tandy_rom.h" #include "um8669f.h" -#include "vid_pcjr.h" -#include "vid_tandy.h" +#include "video/vid_pcjr.h" +#include "video/vid_tandy.h" #include "w83877f.h" #include "wd76c10.h" #include "xtide.h" diff --git a/src/mouse.c b/src/mouse.c index 9fb10ccf2..3e11903dc 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,40 +1,22 @@ #include "ibm.h" #include "mouse.h" #include "mouse_serial.h" -#ifdef INPORT_MOUSE -# include "mouse_inport.h" -#endif #include "mouse_ps2.h" #include "mouse_bus.h" #include "amstrad.h" #include "keyboard_olim24.h" -#ifndef INPORTMOUSE -static mouse_t mouse_notimp = { - "Microsoft InPort Mouse", - "msinport", - MOUSE_TYPE_INPORT, - NULL, NULL, NULL -}; -#endif - - static mouse_t *mouse_list[] = { &mouse_serial_microsoft, /* 0 Microsoft Serial Mouse */ -#ifdef INPORTMOUSE - &mouse_inport, /* 1 Microsoft InPort Bus Mouse */ -#else - &mouse_notimp, /* 1 (not implemented) */ -#endif - &mouse_ps2_2_button, /* 2 PS/2 Mouse 2-button */ + &mouse_ps2_2_button, /* 1 PS/2 Mouse 2-button */ + &mouse_intellimouse, /* 2 PS/2 Intellimouse 3-button */ &mouse_bus, /* 3 Logitech Bus Mouse 2-button */ - &mouse_intellimouse, /* 4 PS/2 Intellimouse 3-button */ - &mouse_amstrad, /* 5 Amstrad PC System Mouse */ - &mouse_olim24, /* 6 Olivetti M24 System Mouse */ + &mouse_amstrad, /* 4 Amstrad PC System Mouse */ + &mouse_olim24, /* 5 Olivetti M24 System Mouse */ #if 0 - &mouse_msystems, /* 7 Mouse Systems */ - &mouse_genius, /* 8 Genius Bus Mouse */ + &mouse_msystems, /* 6 Mouse Systems */ + &mouse_genius, /* 7 Genius Bus Mouse */ #endif NULL }; @@ -44,14 +26,16 @@ static void *mouse_p; int mouse_type = 0; -void mouse_emu_init(void) +void +mouse_emu_init(void) { cur_mouse = mouse_list[mouse_type]; mouse_p = cur_mouse->init(); } -void mouse_emu_close(void) +void +mouse_emu_close(void) { if (cur_mouse) cur_mouse->close(mouse_p); @@ -59,14 +43,16 @@ void mouse_emu_close(void) } -void mouse_poll(int x, int y, int z, int b) +void +mouse_poll(int x, int y, int z, int b) { if (cur_mouse) cur_mouse->poll(x, y, z, b, mouse_p); } -char *mouse_get_name(int mouse) +char * +mouse_get_name(int mouse) { if (!mouse_list[mouse]) return(NULL); @@ -74,18 +60,19 @@ char *mouse_get_name(int mouse) } -char *mouse_get_internal_name(int mouse) +char * +mouse_get_internal_name(int mouse) { return(mouse_list[mouse]->internal_name); } -int mouse_get_from_internal_name(char *s) +int +mouse_get_from_internal_name(char *s) { int c = 0; - while (mouse_list[c] != NULL) - { + while (mouse_list[c] != NULL) { if (!strcmp(mouse_list[c]->internal_name, s)) return(c); c++; @@ -95,14 +82,16 @@ int mouse_get_from_internal_name(char *s) } -int mouse_get_type(int mouse) +int +mouse_get_type(int mouse) { return(mouse_list[mouse]->type); } /* Return number of MOUSE types we know about. */ -int mouse_get_ndev(void) +int +mouse_get_ndev(void) { return(sizeof(mouse_list)/sizeof(mouse_t *) - 1); } diff --git a/src/mouse.h b/src/mouse.h index 701d5de9a..4ae2d8d76 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -3,14 +3,13 @@ #define MOUSE_TYPE_SERIAL 0 /* Serial Mouse */ -#define MOUSE_TYPE_INPORT 1 /* Microsoft InPort Bus Mouse */ -#define MOUSE_TYPE_PS2 2 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_PS2 1 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_PS2_MS 2 /* Microsoft Intellimouse PS/2 */ #define MOUSE_TYPE_BUS 3 /* Logitech/ATI Bus Mouse */ -#define MOUSE_TYPE_PS2_MS 4 -#define MOUSE_TYPE_AMSTRAD 5 /* Amstrad PC system mouse */ -#define MOUSE_TYPE_OLIM24 6 /* Olivetti M24 system mouse */ -#define MOUSE_TYPE_MSYSTEMS 7 /* Mouse Systems mouse */ -#define MOUSE_TYPE_GENIUS 8 /* Genius Bus Mouse */ +#define MOUSE_TYPE_AMSTRAD 4 /* Amstrad PC system mouse */ +#define MOUSE_TYPE_OLIM24 5 /* Olivetti M24 system mouse */ +#define MOUSE_TYPE_MSYSTEMS 6 /* Mouse Systems mouse */ +#define MOUSE_TYPE_GENIUS 7 /* Genius Bus Mouse */ #define MOUSE_TYPE_MASK 0x0f #define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */ diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 19ddb98cb..9112e2c3e 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -8,16 +8,19 @@ * * Implementation of Bus Mouse devices. * - * These mice devices were made by both Microsoft (InPort) and - * Logitech. Sadly, they did not use the same I/O protocol, but - * they were close enough to fit into a single implementation. + * These devices were made by both Microsoft and Logitech. At + * first, Microsoft used the same protocol as Logitech, but did + * switch to their new protocol for their InPort interface. So, + * although alike enough to be handled in the same driver, they + * are not the same. * - * Although the Minix driver blindly took IRQ5, the board seems - * to be able to tell the driver what IRQ it is set for. When - * testing on MS-DOS (6.22), the 'mouse.exe' driver did not want - * to start, and only after disassembling it and inspecting the - * code it was discovered that driver actually does use the IRQ - * reporting feature. In a really, really weird way, too: it + * This code is based on my Minix driver for the Logitech(-mode) + * interface. Although that driver blindly took IRQ5, the board + * seems to be able to tell the driver what IRQ it is set for. + * When testing on MS-DOS (6.22), the 'mouse.exe' driver did not + * want to start, and only after disassembling it and inspecting + * the code it was discovered that driver actually does use the + * IRQ reporting feature. In a really, really weird way, too: it * sets up the board, and then reads the CTRL register which is * supposed to return that IRQ value. Depending on whether or * not the FREEZE bit is set, it has to return either the two's @@ -29,10 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * NOTE: Still have to add the code for the MS InPort mouse, which - * is very similar. Almost done, but not ready for release. - * - * Version: @(#)mouse_bus.c 1.0.3 2017/04/22 + * Version: @(#)mouse_bus.c 1.0.4 2017/05/01 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -50,13 +50,11 @@ #define ENABLE_3BTN 1 /* enable 3-button mode */ -/* Register definitions (based on Logitech info.) */ +/* Register definitions for Logitech mode. */ #define LTMOUSE_DATA 0 /* DATA register */ #define LTMOUSE_MAGIC 1 /* signature magic register */ # define MAGIC_BYTE1 0xa5 /* most drivers use this */ # define MAGIC_BYTE2 0x5a /* some drivers use this */ -# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ -# define MAGIC_MSBYTE2 0xad #define LTMOUSE_CTRL 2 /* CTRL register */ # define CTRL_FREEZE 0x80 /* do not sample when set */ # define CTRL_RD_Y_HI 0x60 /* plus FREEZE */ @@ -64,15 +62,25 @@ # define CTRL_RD_X_HI 0x20 /* plus FREEZE */ # define CTRL_RD_X_LO 0x00 /* plus FREEZE */ # define CTRL_RD_MASK 0x60 -# define CTRL_IDISABLE 0x10 -# define CTRL_IENABLE 0x00 -# define CTRL_DFLT (CTRL_IDISABLE) +# define CTRL_IDIS 0x10 +# define CTRL_IENB 0x00 +# define CTRL_DFLT (CTRL_IDIS) #define LTMOUSE_CONFIG 3 /* CONFIG register */ # define CONFIG_DFLT 0x91 /* 8255 controller config */ +/* Register definitions for Microsoft mode. */ #define MSMOUSE_CTRL 0 /* CTRL register */ +# define MSCTRL_RESET 0x80 +# define MSCTRL_MODE 0x07 +# define MSCTRL_RD_Y 0x02 +# define MSCTRL_RD_X 0x01 +# define MSCTRL_RD_BUT 0x00 #define MSMOUSE_DATA 1 /* DATA register */ +# define MSDATA_BASE 0x10 +# define MSDATA_IRQ 0x01 #define MSMOUSE_MAGIC 2 /* MAGIC register */ +# define MAGIC_MSBYTE1 0xde /* indicates MS InPort */ +# define MAGIC_MSBYTE2 0xad #define MSMOUSE_CONFIG 3 /* CONFIG register */ @@ -92,47 +100,62 @@ typedef struct { uint8_t but; } mouse_bus_t; #define MOUSE_ENABLED 0x80 /* device is enabled for use */ -#define MOUSE_LOGITECH 0x40 /* running as Logitech mode */ -#define MOUSE_CMDFLAG 0x01 /* next wr is a command (MS) */ +#define MOUSE_LOGITECH 0x40 /* running in Logitech mode */ +#define MOUSE_MICROSOFT 0x20 /* running in Microsoft mode */ -/* Handle a write to the control register. */ +/* Handle a WRITE to a Microsoft-mode register. */ static void -wctrl(mouse_bus_t *ms, uint8_t val) +ms_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { - uint8_t b = (ms->r_ctrl ^ val); +#if 1 + pclog("BUSMOUSE: ms_write(%d,%02x)\n", port, val); +#endif - if (b & CTRL_FREEZE) { - /* Hold the sampling while we do something. */ - if (! (val & CTRL_FREEZE)) { - /* Reset current state. */ - ms->x = ms->y = 0; - if (ms->but) /* allow one more POLL for button-release */ - ms->but = 0x80; - } + switch (port) { + case MSMOUSE_CTRL: /* [00] control register */ + if (val & MSCTRL_RESET) { + /* Reset the interface. */ + ms->r_magic = MAGIC_MSBYTE1; + ms->r_conf = 0x00; + } + + /* Save new register value. */ + ms->r_ctrl = val; + break; + + case MSMOUSE_DATA: /* [01] data register */ + if (ms->r_ctrl == MSCTRL_MODE) { + ms->r_conf = val; + } + break; + + case MSMOUSE_MAGIC: /* [02] magic data register */ + break; + + case MSMOUSE_CONFIG: /* [03] config register */ + ms->r_conf = val; + ms->flags &= ~MOUSE_MICROSOFT; + ms->flags |= MOUSE_LOGITECH; + break; + + default: + break; } - - if (b & CTRL_IDISABLE) { - /* Disable or enable interrupts. */ - /* (we don't do anything for that here..) */ - } - - /* Save new register value. */ - ms->r_ctrl = val; } -/* Handle a WRITE operation to one of our registers. */ +/* Handle a WRITE to a LOGITECH-mode register. */ static void -busmouse_write(uint16_t port, uint8_t val, void *priv) +lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { - mouse_bus_t *ms = (mouse_bus_t *)priv; + uint8_t b = (ms->r_ctrl ^ val); -#if 0 - pclog("BUSMOUSE: write(%d,%02x)\n", port-ms->port, val); +#if 1 + pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val); #endif - switch (port-ms->port) { + switch (port) { case LTMOUSE_DATA: /* [00] data register */ break; @@ -144,7 +167,24 @@ busmouse_write(uint16_t port, uint8_t val, void *priv) break; case LTMOUSE_CTRL: /* [02] control register */ - wctrl(ms, val); + if (b & CTRL_FREEZE) { + /* Hold the sampling while we do something. */ + if (! (val & CTRL_FREEZE)) { + /* Reset current state. */ + ms->x = ms->y = 0; + if (ms->but) + /* One more POLL for button-release. */ + ms->but = 0x80; + } + } + + if (b & CTRL_IDIS) { + /* Disable or enable interrupts. */ + /* (we don't do anything for that here..) */ + } + + /* Save new register value. */ + ms->r_ctrl = val; break; case LTMOUSE_CONFIG: /* [03] config register */ @@ -157,6 +197,20 @@ busmouse_write(uint16_t port, uint8_t val, void *priv) } +/* Handle a WRITE operation to one of our registers. */ +static void +bm_write(uint16_t port, uint8_t val, void *priv) +{ + mouse_bus_t *ms = (mouse_bus_t *)priv; + + if (ms->flags & MOUSE_LOGITECH) + lt_write(ms, port - ms->port, val); + + if (ms->flags & MOUSE_MICROSOFT) + ms_write(ms, port - ms->port, val); +} + + /* Handle a READ from a Microsoft-mode register. */ static uint8_t ms_read(mouse_bus_t *ms, uint16_t port) @@ -194,8 +248,8 @@ ms_read(mouse_bus_t *ms, uint16_t port) break; } -#if 0 - pclog("BUSMOUSE: msread(%d): %02x\n", port, r); +#if 1 + pclog("BUSMOUSE: ms_read(%d): %02x\n", port, r); #endif return(r); @@ -285,7 +339,7 @@ lt_read(mouse_bus_t *ms, uint16_t port) * first value is assumed to be the 2's complement of the * actual IRQ value. * Next, it does this a second time, but now with the - * IDISABLE bit clear (so, interrupts enabled), which is + * IDIS bit clear (so, interrupts enabled), which is * our cue to return the regular (not complemented) value * to them. * @@ -297,10 +351,10 @@ lt_read(mouse_bus_t *ms, uint16_t port) */ if (ms->r_intr++ < 250) /* Still settling, return invalid data. */ - r = (ms->r_ctrl&CTRL_IDISABLE)?0xff:0x00; + r = (ms->r_ctrl&CTRL_IDIS)?0xff:0x00; else { /* OK, all good, return correct data. */ - r = (ms->r_ctrl&CTRL_IDISABLE)?-ms->irq:ms->irq; + r = (ms->r_ctrl&CTRL_IDIS)?-ms->irq:ms->irq; ms->r_intr = 0; } break; @@ -313,8 +367,8 @@ lt_read(mouse_bus_t *ms, uint16_t port) break; } -#if 0 - pclog("BUSMOUSE: ltread(%d): %02x\n", port, r); +#if 1 + pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r); #endif return(r); @@ -323,14 +377,15 @@ lt_read(mouse_bus_t *ms, uint16_t port) /* Handle a READ operation from one of our registers. */ static uint8_t -busmouse_read(uint16_t port, void *priv) +bm_read(uint16_t port, void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; uint8_t r; if (ms->flags & MOUSE_LOGITECH) r = lt_read(ms, port - ms->port); - else + + if (ms->flags & MOUSE_MICROSOFT) r = ms_read(ms, port - ms->port); return(r); @@ -339,14 +394,10 @@ busmouse_read(uint16_t port, void *priv) /* The emulator calls us with an update on the host mouse device. */ static uint8_t -busmouse_poll(int x, int y, int z, int b, void *priv) +bm_poll(int x, int y, int z, int b, void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; -#if 0 - pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b); -#endif - /* Return early if nothing to do. */ if (!x && !y && !z && (ms->but == b)) return(1); @@ -354,6 +405,10 @@ busmouse_poll(int x, int y, int z, int b, void *priv) if (!(ms->flags & MOUSE_ENABLED) || (ms->r_ctrl & CTRL_FREEZE)) return(0); +#if 0 + pclog("BUSMOUSE: poll(%d,%d,%d, %02x)\n", x, y, z, b); +#endif + /* Add the delta to our state. */ x += ms->x; if (x > 127) @@ -372,7 +427,7 @@ busmouse_poll(int x, int y, int z, int b, void *priv) ms->but = b; /* All set, generate an interrupt. */ - if (! (ms->r_ctrl & CTRL_IDISABLE)) + if (! (ms->r_ctrl & CTRL_IDIS)) picint(1 << ms->irq); return(0); @@ -381,14 +436,13 @@ busmouse_poll(int x, int y, int z, int b, void *priv) /* Release all resources held by the device. */ static void -busmouse_close(void *priv) +bm_close(void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; /* Release our I/O range. */ io_removehandler(ms->port, ms->portlen, - busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, - ms); + bm_read, NULL, NULL, bm_write, NULL, NULL, ms); free(ms); } @@ -396,7 +450,7 @@ busmouse_close(void *priv) /* Initialize the device for use by the user. */ static void * -busmouse_init(void) +bm_init(void) { mouse_bus_t *ms; @@ -417,17 +471,12 @@ busmouse_init(void) ms->r_conf = CONFIG_DFLT; ms->r_ctrl = CTRL_DFLT; - /* - * Technically this is not possible, but we fake that we - * did a power-up initialization with default config as - * set in the "conf" register. Emulators rock! --FvK - */ - ms->flags = MOUSE_ENABLED; + /* Initialize with Microsoft-mode being default. */ + ms->flags = (MOUSE_ENABLED | MOUSE_MICROSOFT); /* Request an I/O range. */ io_sethandler(ms->port, ms->portlen, - busmouse_read, NULL, NULL, busmouse_write, NULL, NULL, - ms); + bm_read, NULL, NULL, bm_write, NULL, NULL, ms); /* Return our private data to the I/O layer. */ return(ms); @@ -438,7 +487,7 @@ mouse_t mouse_bus = { "Bus Mouse", "msbus", MOUSE_TYPE_BUS, - busmouse_init, - busmouse_close, - busmouse_poll + bm_init, + bm_close, + bm_poll }; diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 84e85a673..46ebbbb1e 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -85,9 +85,13 @@ sermouse_init(void) memset(ms, 0x00, sizeof(mouse_serial_t)); /* Attach a serial port to the mouse. */ - ms->serial = &serial1; - serial1.rcr_callback = sermouse_rcr; - serial1.rcr_callback_p = ms; +#if 1 + ms->serial = serial_attach(0, sermouse_rcr, ms); +#else + ms->serial = &serial1; + serial1.rcr_callback = sermouse_rcr; + serial1.rcr_callback_p = ms; +#endif timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); @@ -101,7 +105,11 @@ sermouse_close(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; /* Detach serial port from the mouse. */ +#if 1 + serial_attach(0, NULL, NULL); +#else serial1.rcr_callback = NULL; +#endif free(ms); } diff --git a/src/ne2000.h b/src/ne2000.h deleted file mode 100644 index 218685e88..000000000 --- a/src/ne2000.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright holders: SA1988 - see COPYING for more details -*/ -void ne2000_generate_maclocal(int mac); -void ne2000_generate_maclocal_pci(int mac); -int net2000_get_maclocal(); -int net2000_get_maclocal_pci(); - -extern device_t ne2000_device; -extern device_t rtl8029as_device; diff --git a/src/ne2000.c b/src/net_ne2000.c similarity index 99% rename from src/ne2000.c rename to src/net_ne2000.c index a88f8ee45..30a1553bd 100644 --- a/src/ne2000.c +++ b/src/net_ne2000.c @@ -21,27 +21,22 @@ #include #include #include - +#include #include "slirp/slirp.h" #include "slirp/queue.h" -#include - #include "ibm.h" -#include "device.h" -#include "disc_random.h" - -#include "config.h" -#include "nethandler.h" - #include "io.h" #include "mem.h" -#include "nethandler.h" #include "rom.h" - -#include "ne2000.h" #include "pci.h" #include "pic.h" #include "timer.h" +#include "device.h" +#include "config.h" +#include "disc_random.h" +#include "network.h" +#include "net_ne2000.h" + /* THIS IS THE DEFAULT MAC ADDRESS .... so it wont place nice with multiple VMs. YET. */ uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; @@ -229,6 +224,7 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len); int ne2000_do_log = 0; + void ne2000_log(const char *format, ...) { #ifdef ENABLE_NE2000_LOG @@ -243,7 +239,7 @@ void ne2000_log(const char *format, ...) #endif } -static uint8_t *ne2000_mac() +static uint8_t *ne2000_mac(void) { if (network_card_current == 2) { @@ -255,7 +251,7 @@ static uint8_t *ne2000_mac() } } -void ne2000_generate_maclocal(int mac) +void ne2000_generate_maclocal(uint32_t mac) { maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ maclocal[1] = 0x00; @@ -276,7 +272,7 @@ void ne2000_generate_maclocal(int mac) } } -void ne2000_generate_maclocal_pci(int mac) +void ne2000_generate_maclocal_pci(uint32_t mac) { maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ maclocal_pci[1] = 0x20; @@ -297,18 +293,18 @@ void ne2000_generate_maclocal_pci(int mac) } } -int net2000_get_maclocal() +uint32_t net2000_get_maclocal() { - int temp; + uint32_t temp; temp = (((int) maclocal[3]) << 16); temp |= (((int) maclocal[4]) << 8); temp |= ((int) maclocal[5]); return temp; } -int net2000_get_maclocal_pci() +uint32_t net2000_get_maclocal_pci() { - int temp; + uint32_t temp; temp = (((int) maclocal_pci[3]) << 16); temp |= (((int) maclocal_pci[4]) << 8); temp |= ((int) maclocal_pci[5]); @@ -1957,7 +1953,7 @@ void ne2000_pci_write(int func, int addr, uint8_t val, void *p) void ne2000_rom_init(ne2000_t *ne2000, wchar_t *s) { - FILE *f = romfopen(s, "rb"); + FILE *f = romfopen(s, L"rb"); uint32_t temp; if(!f) { @@ -1989,7 +1985,8 @@ void ne2000_rom_init(ne2000_t *ne2000, wchar_t *s) static char errbuf[32768]; -void *ne2000_init() + +void *ne2000_init(void) { int rc; int config_net_type; @@ -2093,7 +2090,7 @@ void *ne2000_init() } ne2000_reset(ne2000, BX_RESET_HARDWARE); - vlan_handler(ne2000_poller, ne2000); + network_add_handler(ne2000_poller, ne2000); ne2000_log("ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n",is_rtl8029as ? "pci" : "isa",ne2000->base_address,device_get_config_int("irq"),net_is_pcap); diff --git a/src/net_ne2000.h b/src/net_ne2000.h new file mode 100644 index 000000000..550219dac --- /dev/null +++ b/src/net_ne2000.h @@ -0,0 +1,19 @@ +/* Copyright holders: SA1988 + see COPYING for more details +*/ +#ifndef NET_NE2000_H +# define NET_NE2000_H + + +extern device_t ne2000_device; +extern device_t rtl8029as_device; + + +extern void ne2000_generate_maclocal(uint32_t mac); +extern uint32_t net2000_get_maclocal(void); + +extern void ne2000_generate_maclocal_pci(uint32_t mac); +extern uint32_t net2000_get_maclocal_pci(void); + + +#endif /*NET_NE2000_H*/ diff --git a/src/nethandler.c b/src/nethandler.c deleted file mode 100644 index ddf1677af..000000000 --- a/src/nethandler.c +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#include -#include "nethandler.h" - -#include "ibm.h" -#include "device.h" - -#include "ne2000.h" -#include "timer.h" -#include "thread.h" - -int network_card_current = 0; -static int network_card_last = 0; - -typedef struct -{ - char name[64]; - char internal_name[32]; - device_t *device; -} NETWORK_CARD; - -static NETWORK_CARD network_cards[] = -{ - {"None", "none", NULL}, - {"Novell NE2000", "ne2k", &ne2000_device}, - {"Realtek RTL8029AS", "ne2kpci", &rtl8029as_device}, - {"", "", NULL} -}; - -int network_card_available(int card) -{ - if (network_cards[card].device) - return device_available(network_cards[card].device); - - return 1; -} - -char *network_card_getname(int card) -{ - return network_cards[card].name; -} - -device_t *network_card_getdevice(int card) -{ - return network_cards[card].device; -} - -int network_card_has_config(int card) -{ - if (!network_cards[card].device) - return 0; - return network_cards[card].device->config ? 1 : 0; -} - -char *network_card_get_internal_name(int card) -{ - return network_cards[card].internal_name; -} - -int network_card_get_from_internal_name(char *s) -{ - int c = 0; - - while (strlen(network_cards[c].internal_name)) - { - if (!strcmp(network_cards[c].internal_name, s)) - return c; - c++; - } - - return 0; -} - -void network_card_init() -{ - if (network_cards[network_card_current].device) - device_add(network_cards[network_card_current].device); - network_card_last = network_card_current; - - if (network_card_current != 0) - { - vlan_reset(); /* NETWORK */ - } -} - -static struct -{ - void (*poller)(void *p); - void *priv; -} vlan_handlers[8]; - -static int vlan_handlers_num; - -static int vlan_poller_time = 0; - -void vlan_handler(void (*poller)(void *p), void *p) -{ - vlan_handlers[vlan_handlers_num].poller = poller; - vlan_handlers[vlan_handlers_num].priv = p; - vlan_handlers_num++; -} - -static void network_thread(void *param) -{ - int c; - - for (c = 0; c < vlan_handlers_num; c++) - { - vlan_handlers[c].poller(vlan_handlers[c].priv); - } -} - -void vlan_poller(void *priv) -{ - vlan_poller_time += (int)((double)TIMER_USEC * (1000000.0 / 8.0 / 3000.0)); - - if (vlan_handlers_num) - { - network_thread(priv); - } -} - -void vlan_reset() -{ - pclog("vlan_reset()\n"); - - if (network_card_current) - { - pclog("Adding timer...\n"); - - timer_add(vlan_poller, &vlan_poller_time, TIMER_ALWAYS_ENABLED, NULL); - } - - vlan_handlers_num = 0; -} diff --git a/src/nethandler.h b/src/nethandler.h deleted file mode 100644 index 623dec93b..000000000 --- a/src/nethandler.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include - -void vlan_handler(void (*poller)(void *p), void *p); - -extern int network_card_current; - -int network_card_available(int card); -char *network_card_getname(int card); -struct device_t *network_card_getdevice(int card); -int network_card_has_config(int card); -char *network_card_get_internal_name(int card); -int network_card_get_from_internal_name(char *s); -void network_card_init(); -void vlan_reset(); - -void initpcap(); -void closepcap(); diff --git a/src/network.c b/src/network.c new file mode 100644 index 000000000..5f4a3f95e --- /dev/null +++ b/src/network.c @@ -0,0 +1,154 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#include +#include +#include +#include "ibm.h" +#include "device.h" +#include "network.h" +#include "timer.h" +#include "thread.h" + +#include "net_ne2000.h" + + +typedef struct { + char name[64]; + char internal_name[32]; + device_t *device; +} NETCARD; + +typedef struct { + void (*poller)(void *p); + void *priv; +} NETPOLL; + + +static int net_handlers_num; +static int net_card_last = 0; +static uint32_t net_poll_time = 0; +static NETPOLL net_handlers[8]; +static NETCARD net_cards[] = { + { "None", "none", NULL }, + { "Novell NE2000", "ne2k", &ne2000_device }, + { "Realtek RTL8029AS", "ne2kpci", &rtl8029as_device }, + { "", "", NULL } +}; + +int network_card_current = 0; + + +static void +net_poll(void *priv) +{ + int c; + + /* Reset the poll timer. */ + net_poll_time += (uint32_t)((double)TIMER_USEC * (1000000.0/8.0/3000.0)); + + /* If we have active cards.. */ + if (net_handlers_num) { + /* .. poll each of them. */ + for (c=0; cconfig ? 1 : 0); +} + + +char * +network_card_get_internal_name(int card) +{ + return(net_cards[card].internal_name); +} + + +int +network_card_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(net_cards[c].internal_name)) { + if (! strcmp(net_cards[c].internal_name, s)) + return(c); + c++; + } + + return(0); +} diff --git a/src/network.h b/src/network.h new file mode 100644 index 000000000..59c379a64 --- /dev/null +++ b/src/network.h @@ -0,0 +1,31 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifndef NETWORK_H +# define NETWORK_H +# include + + +#define NE2000 1 +#define RTL8029AS 2 + + +extern int network_card_current; + + +extern void network_init(void); +extern void network_reset(void); +extern void network_add_handler(void (*poller)(void *p), void *p); + +extern int network_card_available(int card); +extern char *network_card_getname(int card); +extern int network_card_has_config(int card); +extern char *network_card_get_internal_name(int card); +extern int network_card_get_from_internal_name(char *s); +extern struct device_t *network_card_getdevice(int card); + +extern void initpcap(void); +extern void closepcap(void); + + +#endif /*NETWORK_H*/ diff --git a/src/opti495.c b/src/opti495.c index 2567782bd..9bf55d854 100644 --- a/src/opti495.c +++ b/src/opti495.c @@ -1,7 +1,7 @@ /*OPTi 82C495 emulation This is the chipset used in the AMI386 model*/ #include "ibm.h" -#include "cpu.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" diff --git a/src/pc.c b/src/pc.c index abfb59c38..b4bf2b942 100644 --- a/src/pc.c +++ b/src/pc.c @@ -4,11 +4,62 @@ #include #include #include - #include "86box.h" #include "ibm.h" +#include "mem.h" +#include "cpu/cpu.h" +#include "cpu/x86_ops.h" +#include "cpu/codegen.h" +#include "dma.h" +#include "nvr.h" +#include "pic.h" +#include "pit.h" +#include "timer.h" #include "device.h" +#include "ali1429.h" +#include "cdrom.h" +#include "cdrom-ioctl.h" +#include "disc.h" +#include "disc_86f.h" +#include "disc_fdi.h" +#include "disc_imd.h" +#include "disc_img.h" +#include "disc_td0.h" +#include "disc_random.h" +#include "config.h" +#include "fdc.h" +#include "fdd.h" +#include "gameport.h" +#include "plat-joystick.h" +#include "plat-midi.h" +#include "hdd.h" +#include "ide.h" +#include "cdrom.h" +#include "cdrom-iso.h" +#include "cdrom-null.h" +#include "scsi.h" +#include "keyboard.h" +#include "plat-keyboard.h" +#include "keyboard_at.h" +#include "model.h" +#include "mouse.h" +#include "plat-mouse.h" +#include "network.h" +#include "net_ne2000.h" +#include "serial.h" +#include "sound/sound.h" +#include "sound/snd_cms.h" +#include "sound/snd_dbopl.h" +#include "sound/snd_opl.h" +#include "sound/snd_gus.h" +#include "sound/snd_sb.h" +#include "sound/snd_speaker.h" +#include "sound/snd_ssi2001.h" +#include "video/video.h" +#include "video/vid_voodoo.h" +#include "amstrad.h" + #ifndef __unix #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -18,61 +69,7 @@ #include "win-language.h" #endif -#include "ali1429.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" -#include "disc.h" -#include "disc_86f.h" -#include "disc_fdi.h" -#include "disc_imd.h" -#include "disc_img.h" -#include "disc_random.h" -#include "disc_td0.h" -#include "mem.h" -#include "x86_ops.h" -#include "codegen.h" -#include "cdrom-iso.h" -#include "cdrom-null.h" -#include "config.h" -#include "cpu.h" -#include "dma.h" -#include "fdc.h" -#include "fdd.h" -#include "gameport.h" -#include "sound_gus.h" -#include "ide.h" -#include "cdrom.h" -#include "scsi.h" -#include "keyboard.h" -#include "keyboard_at.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "ne2000.h" -#include "nethandler.h" -#include "nvr.h" -#include "pic.h" -#include "pit.h" -#include "plat-joystick.h" -#include "plat-midi.h" -#include "plat-mouse.h" -#include "plat-keyboard.h" -#include "serial.h" -#include "sound.h" -#include "sound_cms.h" -#include "sound_dbopl.h" -#include "sound_opl.h" -#include "sound_sb.h" -#include "sound_speaker.h" -#include "sound_ssi2001.h" -#include "timer.h" -#include "vid_voodoo.h" -#include "video.h" -#include "amstrad.h" -#include "hdd.h" -#include "nethandler.h" -#define NE2000 1 -#define RTL8029AS 2 + uint8_t ethif; int inum; @@ -318,7 +315,6 @@ void initpc(int argc, wchar_t *argv[]) } } - keyboard_init(); mouse_init(); midi_init(); @@ -498,8 +494,8 @@ void resetpchard() ide_qua_init(); } - network_card_init(); - + network_init(); + for (i = 0; i < CDROM_NUM; i++) { if (cdrom_drives[i].bus_type) @@ -594,7 +590,6 @@ void runpc() execx86(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100); } - keyboard_poll_host(); keyboard_process(); pollmouse(); if (joystick_type != 7) joystick_poll(); diff --git a/src/pit.c b/src/pit.c index e9e4cb090..b735656a5 100644 --- a/src/pit.c +++ b/src/pit.c @@ -5,17 +5,18 @@ #include #include "ibm.h" - -#include "cpu.h" -#include "device.h" +#include "cpu/cpu.h" #include "dma.h" #include "io.h" #include "pic.h" #include "pit.h" -#include "sound_speaker.h" +#include "device.h" #include "timer.h" -#include "video.h" #include "model.h" +#include "sound/snd_speaker.h" +#include "video/video.h" + + /*B0 to 40, two writes to 43, then two reads - value does not change!*/ /*B4 to 40, two writes to 43, then two reads - value _does_ change!*/ int displine; diff --git a/src/ps2_mca.c b/src/ps2_mca.c index fd3201ac3..74183a8ed 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -1,15 +1,16 @@ #include "ibm.h" -#include "cpu.h" -#include "device.h" +#include "cpu/cpu.h" +#include "cpu/x86.h" #include "io.h" -#include "lpt.h" #include "mca.h" #include "mem.h" +#include "rom.h" +#include "device.h" +#include "lpt.h" #include "ps2_mca.h" #include "ps2_nvr.h" -#include "rom.h" #include "serial.h" -#include "x86.h" + static struct { diff --git a/src/resource.h b/src/resource.h index 9bfe518b4..fec4d83b9 100644 --- a/src/resource.h +++ b/src/resource.h @@ -1,10 +1,9 @@ /* Copyright holders: Tenshi see COPYING for more details */ - /* {{NO_DEPENDENCIES}} Microsoft Developer Studio generated include file. - Used by pc_new2.rc + Used by 86Box.rc */ #define IDHDCONFIG 3 #define IDCDCONFIG 4 @@ -195,27 +194,27 @@ #define IDM_IDE_QUA_IRQ15 44035 #ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG -#define IDM_LOG_BUSLOGIC 51200 -#endif -#ifdef ENABLE_CDROM_LOG -#define IDM_LOG_CDROM 51201 -#endif -#ifdef ENABLE_D86F_LOG -#define IDM_LOG_D86F 51202 -#endif -#ifdef ENABLE_FDC_LOG -#define IDM_LOG_FDC 51203 -#endif -#ifdef ENABLE_IDE_LOG -#define IDM_LOG_IDE 51204 -#endif -#ifdef ENABLE_NE2000_LOG -#define IDM_LOG_NE2000 51205 -#endif +# ifdef ENABLE_BUSLOGIC_LOG +# define IDM_LOG_BUSLOGIC 51200 +# endif +# ifdef ENABLE_CDROM_LOG +# define IDM_LOG_CDROM 51201 +# endif +# ifdef ENABLE_D86F_LOG +# define IDM_LOG_D86F 51202 +# endif +# ifdef ENABLE_FDC_LOG +# define IDM_LOG_FDC 51203 +# endif +# ifdef ENABLE_IDE_LOG +# define IDM_LOG_IDE 51204 +# endif +# ifdef ENABLE_NE2000_LOG +# define IDM_LOG_NE2000 51205 +# endif #endif #ifdef ENABLE_LOG_BREAKPOINT -#define IDM_LOG_BREAKPOINT 51206 +# define IDM_LOG_BREAKPOINT 51206 #endif #define IDC_COMBO1 1000 @@ -413,13 +412,12 @@ #define IDC_STATIC 1792 /* Next default values for new objects */ - #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 110 -#define _APS_NEXT_COMMAND_VALUE 40002 -#define _APS_NEXT_CONTROL_VALUE 1055 -#define _APS_NEXT_SYMED_VALUE 101 -#endif +# ifndef APSTUDIO_READONLY_SYMBOLS +# define _APS_NO_MFC 1 +# define _APS_NEXT_RESOURCE_VALUE 110 +# define _APS_NEXT_COMMAND_VALUE 40002 +# define _APS_NEXT_CONTROL_VALUE 1055 +# define _APS_NEXT_SYMED_VALUE 101 +# endif #endif diff --git a/src/scsi.c b/src/scsi.c index 3dbefdf37..3b88ed36b 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -6,10 +6,10 @@ #include #include "86box.h" #include "ibm.h" +#include "timer.h" #include "device.h" #include "cdrom.h" #include "scsi.h" -#include "timer.h" #include "scsi_buslogic.h" @@ -106,7 +106,7 @@ void SCSIReset(uint8_t id, uint8_t lun) if (hdc_id != 0xff) { scsi_hd_reset(cdrom_id); - SCSIDevices[id][lun].LunType = SCSI_HDD; + SCSIDevices[id][lun].LunType = SCSI_DISK; } else { if (cdrom_id != 0xff) { diff --git a/src/scsi.h b/src/scsi.h index 61c8f1bf5..788dcb7f3 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -208,7 +208,7 @@ extern int cd_status; extern int prev_status; #define SCSI_NONE 0 -#define SCSI_HDD 1 +#define SCSI_DISK 1 #define SCSI_CDROM 2 #define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) @@ -266,4 +266,4 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l void scsi_hd_command(uint8_t id, uint8_t *cdb); void scsi_hd_callback(uint8_t id); -#endif \ No newline at end of file +#endif diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 99fcd8cb9..2161fa934 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -8,10 +8,10 @@ * * Implementation of several low-level support functions for * the AHA-154x series of ISA Host Adapters made by Adaptec. - * These functions implement the support needed by the ROM BIOS - * of these cards. + * These functions implement the support needed by the ROM + * BIOS of these cards. * - * Version: @(#)aha154x.c 1.0.4 2017/04/21 + * Version: @(#)scsi_aha154x.c 1.0.5 2017/05/05 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -40,35 +40,35 @@ #if AHA == AHA154xC # define ROMFILE L"roms/adaptec/aha1542c101.bin" -# define AHA_BID 'D' /* AHA-154x C */ -# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ -# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ -# define ROM_SHRAMSZ 128 /* size of shadow RAM */ -# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ -# define EEP_SIZE 32 /* 32 bytes of storage */ +# define AHA_BID 'D' /* AHA-154x C */ +# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ #endif #if AHA == AHA154xCF # define ROMFILE L"roms/adaptec/aha1542cf201.bin" -# define AHA_BID 'E' /* AHA-154x CF */ -# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ -# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ -# define ROM_SHRAMSZ 128 /* size of shadow RAM */ -# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ -# define EEP_SIZE 32 /* 32 bytes of storage */ +# define AHA_BID 'E' /* AHA-154x CF */ +# define ROM_FWHIGH 0x0022 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ #endif #if AHA == AHA154xCP # define ROMFILE L"roms/adaptec/aha1542cp102.bin" -# define AHA_BID 'F' /* AHA-154x CP */ -# define ROM_FWHIGH 0x0055 /* firmware version (hi/lo) */ -# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ -# define ROM_SHRAMSZ 128 /* size of shadow RAM */ -# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ -# define EEP_SIZE 32 /* 32 bytes of storage */ +# define AHA_BID 'F' /* AHA-154x CP */ +# define ROM_FWHIGH 0x0055 /* firmware version (hi/lo) */ +# define ROM_SHRAM 0x3F80 /* shadow RAM address base */ +# define ROM_SHRAMSZ 128 /* size of shadow RAM */ +# define ROM_IOADDR 0x3F7E /* [2:0] idx into addr table */ +# define EEP_SIZE 32 /* 32 bytes of storage */ #endif -#define ROM_SIZE 16384 /* one ROM is 16K */ +#define ROM_SIZE 16384 /* one ROM is 16K */ /* EEPROM map and bit definitions. */ @@ -198,14 +198,14 @@ aha154x_init(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) uint32_t bios_size; uint32_t bios_addr; uint32_t bios_mask; - char *bios_path; + wchar_t *bios_path; uint32_t temp; FILE *f; /* Set BIOS load address. */ bios_addr = memaddr; bios_path = ROMFILE; - pclog("AHA154x: loading BIOS from '%s'\n", bios_path); + pclog_w(L"AHA154x: loading BIOS from '%s'\n", bios_path); /* Open the BIOS image file and make sure it exists. */ if ((f = romfopen(bios_path, L"rb")) == NULL) { diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 9675cfe88..39da63367 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -2055,7 +2055,7 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbo req->CmdBlock.common.ControlByte); } - BuslogicInOperation = (SCSIDevices[Id][Lun].LunType == SCSI_HDD) ? 0x11 : 1; + BuslogicInOperation = (SCSIDevices[Id][Lun].LunType == SCSI_DISK) ? 0x11 : 1; pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType); } } @@ -2424,7 +2424,7 @@ void *AdaptecInit(int has_bios, int chip) { if (scsi_hard_disks[i][j] != 0xff) { - SCSIDevices[i][j].LunType = SCSI_HDD; + SCSIDevices[i][j].LunType = SCSI_DISK; } } } @@ -2509,7 +2509,7 @@ void *BuslogicInit(int chip) { if (scsi_hard_disks[i][j] != 0xff) { - SCSIDevices[i][j].LunType = SCSI_HDD; + SCSIDevices[i][j].LunType = SCSI_DISK; } } } diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h index c4b6805f0..46ec9bf3b 100644 --- a/src/scsi_buslogic.h +++ b/src/scsi_buslogic.h @@ -14,8 +14,8 @@ extern device_t aha1540b_device; extern device_t aha1542cf_device; extern device_t buslogic_device; extern device_t buslogic_pci_device; - - + + extern int buslogic_dev_present(uint8_t id, uint8_t lun); extern void aha154x_init(uint16_t, uint32_t, aha_info *); diff --git a/src/scsi_hd.c b/src/scsi_disk.c similarity index 100% rename from src/scsi_hd.c rename to src/scsi_disk.c diff --git a/src/serial.c b/src/serial.c index 4eb78e821..a80912ddf 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,295 +1,639 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of NS8250-series UART devices. + * + * The original IBM-PC design did not have any serial ports of + * any kind. Rather, these were offered as add-on devices, most + * likely because a) most people did not need one at the time, + * and, b) this way, IBM could make more money off them. + * + * So, for the PC, the offerings were for an IBM Asynchronous + * Communications Adapter, and, later, a model for synchronous + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. + * + * Of course, many system builders came up with similar boards, + * and even more boards were designed where several I/O functions + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. + * + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. + * + * Based on the 86Box serial port driver as a framework. + * + * Version: @(#)serial.c 1.0.2 2017/05/05 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ #include "ibm.h" #include "io.h" #include "mouse.h" #include "pic.h" #include "serial.h" #include "timer.h" +#include "win-serial.h" -enum -{ - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8 + +enum { + SERINT_LSR = 1, + SERINT_RECEIVE = 2, + SERINT_TRANSMIT = 4, + SERINT_MSR = 8 }; -SERIAL serial1, serial2; -void serial_reset() -{ - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; - serial2.fifo_read = serial2.fifo_write = 0; -} +/* IER register bits. */ +#define IER_RDAIE (0x01) +#define IER_THREIE (0x02) +#define IER_RXLSIE (0x04) +#define IER_MSIE (0x08) +#define IER_SLEEP (0x10) /* NS16750 */ +#define IER_LOWPOWER (0x20) /* NS16750 */ +#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ -void serial_update_ints(SERIAL *serial) +/* IIR register bits. */ +#define IIR_IP (0x01) +#define IIR_IID (0x0e) +# define IID_IDMDM (0x00) +# define IID_IDTX (0x02) +# define IID_IDRX (0x04) +# define IID_IDERR (0x06) +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) +# define IIR_FIFO64 (0x20) +# define IIR_FIFOBAD (0x80) /* 16550 */ +# define IIR_FIFOENB (0xc0) + +/* FCR register bits. */ +#define FCR_FCRFE (0x01) +#define FCR_RFR (0x02) +#define FCR_TFR (0x04) +#define FCR_SELDMA1 (0x08) +#define FCR_FENB64 (0x20) /* 16750 */ +#define FCR_RTLS (0xc0) +# define FCR_RTLS1 (0x00) +# define FCR_RTLS4 (0x40) +# define FCR_RTLS8 (0x80) +# define FCR_RTLS14 (0xc0) + +/* LCR register bits. */ +#define LCR_WLS (0x03) +# define WLS_BITS5 (0x00) +# define WLS_BITS6 (0x01) +# define WLS_BITS7 (0x02) +# define WLS_BITS8 (0x03) +#define LCR_SBS (0x04) +#define LCR_PE (0x08) +#define LCR_EP (0x10) +#define LCR_PS (0x20) +# define PAR_NONE (0x00) +# define PAR_EVEN (LCR_PE | LCR_EP) +# define PAR_ODD (LCR_PE) +# define PAR_MARK (LCR_PE | LCR_PS) +# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) +#define LCR_BC (0x40) +#define LCR_DLAB (0x80) + +/* MCR register bits. */ +#define MCR_DTR (0x01) +#define MCR_RTS (0x02) +#define MCR_OUT1 (0x04) /* 8250 */ +#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ +#define MCR_LMS (0x10) +#define MCR_AUTOFLOW (0x20) /* 16750 + +/* LSR register bits. */ +#define LSR_DR (0x01) +#define LSR_OE (0x02) +#define LSR_PE (0x04) +#define LSR_FE (0x08) +#define LSR_BI (0x10) +#define LSR_THRE (0x20) +#define LSR_TEMT (0x40) +#define LSR_RXFE (0x80) + +/* MSR register bits. */ +#define MSR_DCTS (0x01) +#define MSR_DDSR (0x02) +#define MSR_TERI (0x04) +#define MSR_DDCD (0x08) +#define MSR_CTS (0x10) +#define MSR_DSR (0x20) +#define MSR_RI (0x40) +#define MSR_DCD (0x80) +#define MSR_MASK (0x0f) + + +static uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; +static int serial_irq[2] = { 4, 3 }; +static SERIAL serial1, serial2; + + +static void +update_ints(SERIAL *sp) { - int stat = 0; + int stat = 0; - serial->iir = 1; + sp->iir = IIR_IP; + if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { + /* Line Status interrupt. */ + stat = 1; + sp->iir = IID_IDERR; + } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { + /* Received Data available. */ + stat = 1; + sp->iir = IID_IDRX; + } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { + /* Transmit Data empty. */ + stat = 1; + sp->iir = IID_IDTX; + } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { + /* Modem Status interrupt. */ + stat = 1; + sp->iir = IID_IDMDM; + } - if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ - { - stat = 1; - serial->iir = 6; - } - else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ - { - stat = 1; - serial->iir = 4; - } - else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ - { - stat = 1; - serial->iir = 2; - } - else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ - { - stat = 1; - serial->iir = 0; - } - - if (stat && ((serial->mctrl & 8) || PCJR)) - picintlevel(1 << serial->irq); - else - picintc(1 << serial->irq); + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); } -void serial_write_fifo(SERIAL *serial, uint8_t dat) + +/* Write data to the (input) FIFO. Used by MOUSE driver. */ +void +serial_write_fifo(SERIAL *sp, uint8_t dat) { - serial->fifo[serial->fifo_write] = dat; - serial->fifo_write = (serial->fifo_write + 1) & 0xFF; - if (!(serial->lsr & 1)) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + /* Stuff data into FIFO. */ + sp->fifo[sp->fifo_write] = dat; + sp->fifo_write = (sp->fifo_write + 1) & 0xFF; + + if (! (sp->lsr & LSR_DR)) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } } -uint8_t serial_read_fifo(SERIAL *serial) + +static uint8_t +read_fifo(SERIAL *sp) { - if (serial->fifo_read != serial->fifo_write) - { - serial->dat = serial->fifo[serial->fifo_read]; - serial->fifo_read = (serial->fifo_read + 1) & 0xFF; - } - return serial->dat; + if (sp->fifo_read != sp->fifo_write) { + sp->dat = sp->fifo[sp->fifo_read]; + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; + } + + return(sp->dat); } -void serial_write(uint16_t addr, uint8_t val, void *p) + +/* BHTTY WRITE COMPLETE handler. */ +static void +serial_wr_done(void *arg) { - SERIAL *serial = (SERIAL *)p; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - serial->dlab1 = val; - return; - } - serial->thr = val; - serial->lsr |= 0x20; - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - if (serial->mctrl & 0x10) - { - serial_write_fifo(serial, val); - } - break; - case 1: - if (serial->lcr & 0x80) - { - serial->dlab2 = val; - return; - } - serial->ier = val & 0xf; - serial_update_ints(serial); - break; - case 2: - serial->fcr = val; - break; - case 3: - serial->lcr = val; - break; - case 4: - if ((val & 2) && !(serial->mctrl & 2)) - { - if (serial->rcr_callback) - serial->rcr_callback(serial, serial->rcr_callback_p); - } - serial->mctrl = val; - if (val & 0x10) - { - uint8_t new_msr; - - new_msr = (val & 0x0c) << 4; - new_msr |= (val & 0x02) ? 0x10: 0; - new_msr |= (val & 0x01) ? 0x20: 0; - - if ((serial->msr ^ new_msr) & 0x10) - new_msr |= 0x01; - if ((serial->msr ^ new_msr) & 0x20) - new_msr |= 0x02; - if ((serial->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((serial->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - serial->msr = new_msr; - } - break; - case 5: - serial->lsr = val; - if (serial->lsr & 0x01) - serial->int_status |= SERIAL_INT_RECEIVE; - if (serial->lsr & 0x1e) - serial->int_status |= SERIAL_INT_LSR; - if (serial->lsr & 0x20) - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - break; - case 6: - serial->msr = val; - if (serial->msr & 0x0f) - serial->int_status |= SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - serial->scratch = val; - break; - } + SERIAL *sp = (SERIAL *)arg; + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); } -uint8_t serial_read(uint16_t addr, void *p) + +/* Handle a WRITE operation to one of our registers. */ +static void +serial_write(uint16_t addr, uint8_t val, void *priv) { - SERIAL *serial = (SERIAL *)p; - uint8_t temp = 0; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - temp = serial->dlab1; - break; - } + SERIAL *sp = (SERIAL *)priv; + uint8_t wl, sb, pa; + uint16_t baud; + long speed; - serial->lsr &= ~1; - serial->int_status &= ~SERIAL_INT_RECEIVE; - serial_update_ints(serial); - temp = serial_read_fifo(serial); - if (serial->fifo_read != serial->fifo_write) - serial->recieve_delay = 1000 * TIMER_USEC; - break; - case 1: - if (serial->lcr & 0x80) - temp = serial->dlab2; - else - temp = serial->ier; - break; - case 2: - temp = serial->iir; - if ((temp & 0xe) == 2) - { - serial->int_status &= ~SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - } - if (serial->fcr & 1) - temp |= 0xc0; - break; - case 3: - temp = serial->lcr; - break; - case 4: - temp = serial->mctrl; - break; - case 5: - if (serial->lsr & 0x20) - serial->lsr |= 0x40; - serial->lsr |= 0x20; - temp = serial->lsr; - if (serial->lsr & 0x1f) - serial->lsr &= ~0x1e; - serial->int_status &= ~SERIAL_INT_LSR; - serial_update_ints(serial); - break; - case 6: - temp = serial->msr; - serial->msr &= ~0x0f; - serial->int_status &= ~SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - temp = serial->scratch; - break; - } - return temp; + switch (addr & 0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab1 = val; + return; + } + sp->thr = val; +#if 0 + bhtty_write((BHTTY *)sp->bh, sp->thr, serial_wrdone, sp); +#else + bhtty_write((BHTTY *)sp->bh, sp->thr); + serial_wr_done(sp); +#endif + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val); + } + break; + + case 1: /* IER / DLAB2 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab2 = val; + return; + } + sp->ier = (val & IER_MASK); + update_ints(sp); + break; + + case 2: /* FCR */ + sp->fcr = val; + break; + + case 3: /* LCR */ + if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { + /* We dropped DLAB, so handle baudrate. */ + baud = ((sp->dlab2 << 8) | sp->dlab1); + speed = 115200UL/baud; +#if 1 + pclog("Serial: new divisor %u, baudrate %ld\n", + baud, speed); +#endif + bhtty_speed((BHTTY *)sp->bh, speed); + } + wl = (val & LCR_WLS) + 5; /* databits */ + sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ + pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; +#if 1 + pclog("Serial: WL=%d SB=%d PA=%d\n", wl, sb, pa); +#endif + bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; + break; + + case 4: + if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { + /* + * This is old code for use by the Serial Mouse + * driver. If the user toggles RTS, any serial + * mouse is expected to send an 'M' character, + * to inform any enumerator there 'is' something. + */ + if (sp->rcr_callback) { + sp->rcr_callback(sp, sp->rcr_callback_p); +#if 0 + pclog("RTS raised; sending M\n"); +#endif + } + } + + if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { + /* Start up reading from the real port. */ + (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); + } + sp->mctrl = val; + if (val & MCR_LMS) { /* loopback mode */ + uint8_t new_msr; + + /*FIXME: WTF does this do?? --FvK */ + new_msr = (val & 0x0c) << 4; + new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; + new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; + + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + sp->msr = new_msr; + } + break; + + case 5: + sp->lsr = val; + if (sp->lsr & LSR_DR) + sp->int_status |= SERINT_RECEIVE; + if (sp->lsr & 0x1e) + sp->int_status |= SERINT_LSR; + if (sp->lsr & LSR_THRE) + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + break; + + case 6: + sp->msr = val; + if (sp->msr & MSR_MASK) + sp->int_status |= SERINT_MSR; + update_ints(sp); + break; + + case 7: + sp->scratch = val; + break; + } } -void serial_recieve_callback(void *p) + +/* BHTTY READ COMPLETE handler. */ +static void +serial_rd_done(void *arg, int num) { - SERIAL *serial = (SERIAL *)p; - - serial->recieve_delay = 0; - - if (serial->fifo_read != serial->fifo_write) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + SERIAL *sp = (SERIAL *)arg; +//pclog("%04x: %d bytes available: %02x (%c)\n",sp->port,num,sp->hold,sp->hold); + + /* Stuff the byte in the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + + /* Start up the next read from the real port. */ + (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); +} + + +/* Handle a READ operation from one of our registers. */ +static uint8_t +serial_read(uint16_t addr, void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + uint8_t ret = 0x00; + + switch (addr&0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + ret = sp->dlab1; + break; + } + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); +#if 0 + if (sp->fifo_read != sp->fifo_write) + sp->receive_delay = 1000 * TIMER_USEC; +#endif + break; + + case 1: /* LCR / DLAB2 */ + if (sp->lcr & LCR_DLAB) + ret = sp->dlab2; + else + ret = sp->ier; + break; + + case 2: /* IIR */ + ret = sp->iir; + if ((ret & IIR_IID) == IID_IDTX) { + sp->int_status &= ~SERINT_TRANSMIT; + update_ints(sp); + } + if (sp->fcr & 1) + { + ret |= 0xc0; + } + break; + + case 3: /* LCR */ + ret = sp->lcr; + break; + + case 4: /* MCR */ + ret = sp->mctrl; + break; + + case 5: /* LSR */ + if (sp->lsr & LSR_THRE) + sp->lsr |= LSR_TEMT; + sp->lsr |= LSR_THRE; + ret = sp->lsr; + if (sp->lsr & 0x1f) + sp->lsr &= ~0x1e; +#if 0 + sp->lsr |= (LSR_THRE | LSR_TEMT); +#endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); + break; + + case 6: + ret = sp->msr; + sp->msr &= ~0x0f; + sp->int_status &= ~SERINT_MSR; + update_ints(sp); + break; + + case 7: + ret = sp->scratch; + break; + } + + return(ret); } -uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; -int serial_irq[2] = { 4, 3 }; /*Tandy might need COM1 at 2f8*/ -void serial1_init(uint16_t addr, int irq) +void +serial1_init(uint16_t addr, int irq) { - memset(&serial1, 0, sizeof(serial1)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial1.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); - serial_addr[0] = addr; - serial_irq[0] = irq; -} -void serial1_set(uint16_t addr, int irq) -{ - serial1_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial_addr[0] = addr; - serial_irq[0] = irq; -} -void serial1_remove() -{ - io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + BHTTY *bh; + + memset(&serial1, 0x00, sizeof(serial1)); + + pclog("Serial1, I/O=%04x, IRQ=%d, host ", addr, irq); + + /* Request a port from the host system. */ + bh = bhtty_open(BHTTY_PORT1, 0); /*FIXME: from config! --FvK */ + if (bh == NULL) { + return; + } + serial1.bh = bh; + serial1.port = addr; + serial1.irq = irq; + serial1.rcr_callback = NULL; + pclog("'%s'\n", bh->name); + + /* Set up bottom-half I/O callback info. */ + bh->rd_done = serial_rd_done; + bh->rd_arg = &serial1; + + /* Request an I/O range. */ + io_sethandler(addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + +#if 0 + timer_add(serial_receive_callback, + &serial1.receive_delay, &serial1.receive_delay, &serial1); +#endif + + serial_addr[0] = addr; + serial_irq[0] = irq; } -void serial2_init(uint16_t addr, int irq) + +/* Release all resources held by the device. */ +void +serial1_remove(void) { - memset(&serial2, 0, sizeof(serial2)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial2.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); - serial_addr[1] = addr; - serial_irq[1] = irq; + /* Close the host device. */ + if (serial1.bh != NULL) + bhtty_close((BHTTY *)serial1.bh); + + /* Release our I/O range. */ + io_removehandler(serial_addr[0], 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } -void serial2_set(uint16_t addr, int irq) + + +void +serial1_set(uint16_t addr, int irq) { - serial2_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial_addr[1] = addr; - serial_irq[1] = irq; + void *temp; + +#if 0 + pclog("serial1_set(%04X, %02X)\n", addr, irq); +#endif + temp = serial1.bh; + serial1.bh = NULL; + serial1_remove(); + serial1.bh = temp; + serial1.port = addr; + serial1.irq = irq; + + io_sethandler(addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial_addr[0] = addr; + serial_irq[0] = irq; } -void serial2_remove() + + +void +serial2_init(uint16_t addr, int irq) { - io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + BHTTY *bh; + + memset(&serial2, 0x00, sizeof(serial2)); + + pclog("Serial2, I/O=%04x, IRQ=%d, host ", addr, irq); + + /* Request a port from the host system. */ + bh = bhtty_open(BHTTY_PORT2, 0); /*FIXME: from config! --FvK */ + if (bh == NULL) { + return; + } + serial2.bh = bh; + serial2.port = addr; + serial2.irq = irq; + serial2.rcr_callback = NULL; + pclog("'%s'\n", bh->name); + + /* Set up bottom-half I/O callback info. */ + bh->rd_done = serial_rd_done; + bh->rd_arg = &serial2; + + /* Request an I/O range. */ + io_sethandler(addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + + serial_addr[1] = addr; + serial_irq[1] = irq; +} + + +/* Release all resources held by the device. */ +void +serial2_remove(void) +{ + /* Close the host device. */ + if (serial2.bh != NULL) + bhtty_close((BHTTY *)serial2.bh); + + /* Release our I/O range. */ + io_removehandler(serial_addr[1], 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); +} + + +void +serial2_set(uint16_t addr, int irq) +{ + void *temp; + +#if 0 + pclog("serial2_set(%04X, %02X)\n", addr, irq); +#endif + temp = serial2.bh; + serial2.bh = NULL; + serial2_remove(); + serial2.bh = temp; + serial2.port = addr; + serial2.irq = irq; + + io_sethandler(addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + + serial_addr[1] = addr; + serial_irq[1] = irq; +} + + +/* + * Reset the serial ports. + * + * This should be a per-port function. + */ +void +serial_reset(void) +{ + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; + serial1.fifo_read = serial1.fifo_write = 0; + + serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; + serial2.fifo_read = serial2.fifo_write = 0; +} + + +/* Fake interrupt generator, needed for Serial Mouse. */ +static void +serial_timer(void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + + sp->receive_delay = 0; + + if (sp->fifo_read != sp->fifo_write) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } +} + + +/* Attach another device (MOUSE) to a serial port. */ +SERIAL * +serial_attach(int port, void *func, void *arg) +{ + SERIAL *sp; + + if (port == 0) + sp = &serial1; + else + sp = &serial2; + + /* Set up callback info. */ + sp->rcr_callback = func; + sp->rcr_callback_p = arg; + + /* Create a timer to fake RX interrupts for mouse data. */ + timer_add(serial_timer, + &sp->receive_delay, &sp->receive_delay, sp); + + return(sp); } diff --git a/src/serial.h b/src/serial.h index 96104068e..05a5c7ff5 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,35 +1,56 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void serial1_init(uint16_t addr, int irq); -void serial2_init(uint16_t addr, int irq); -void serial1_set(uint16_t addr, int irq); -void serial2_set(uint16_t addr, int irq); -void serial1_remove(); -void serial2_remove(); -void serial_reset(); +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the SERIAL card. + * + * Version: @(#)serial.h 1.0.1 2017/04/14 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef SERIAL_H +# define SERIAL_H -struct SERIAL; -typedef struct -{ - uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; - uint8_t dlab1,dlab2; - uint8_t dat; - uint8_t int_status; - uint8_t scratch; - uint8_t fcr; - - int irq; +typedef struct _serial_ { + uint16_t port; + int16_t irq; - void (*rcr_callback)(struct SERIAL *serial, void *p); - void *rcr_callback_p; - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int recieve_delay; + uint8_t lsr, thr, mctrl, rcr, iir, ier, lcr, msr; + uint8_t dlab1, dlab2; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + + void (*rcr_callback)(struct _serial_ *, void *); + void *rcr_callback_p; + + uint8_t hold; + uint8_t fifo[256]; + int fifo_read, fifo_write; + + int receive_delay; + + void *bh; } SERIAL; -extern SERIAL serial1, serial2; -void serial_write_fifo(SERIAL *serial, uint8_t dat); +extern void serial1_init(uint16_t addr, int irq); +extern void serial2_init(uint16_t addr, int irq); +extern void serial1_set(uint16_t addr, int irq); +extern void serial2_set(uint16_t addr, int irq); +extern void serial1_remove(); +extern void serial2_remove(); + +extern void serial_reset(); +extern SERIAL *serial_attach(int, void *, void *); +extern void serial_write_fifo(SERIAL *, uint8_t); + + +#endif /*SERIAL_H*/ diff --git a/src/sio.c b/src/sio.c index a5303935e..9092e0c2e 100644 --- a/src/sio.c +++ b/src/sio.c @@ -7,10 +7,9 @@ word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer */ #include - #include "ibm.h" +#include "cpu/cpu.h" #include "cdrom.h" -#include "cpu.h" #include "disc.h" #include "dma.h" #include "fdc.h" diff --git a/src/timer.h b/src/timer.h index 50c83e55c..b2e7fec93 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,7 +1,6 @@ #ifndef _TIMER_H_ #define _TIMER_H_ -#include "cpu.h" extern int timer_start; diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index b44097898..9c0c7f557 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -9,23 +9,25 @@ #undef BITMAP #include #include "86box.h" -#include "resource.h" -#include "video.h" +#include "video/video.h" #include "win-d3d-fs.h" #include "win.h" #include "win-cgapal.h" +#include "resource.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); -static void d3d_fs_init_objects(); -static void d3d_fs_close_objects(); +static void d3d_fs_init_objects(void); +static void d3d_fs_close_objects(void); static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h); -extern "C" void video_blit_complete(); +extern "C" void video_blit_complete(void); + static LPDIRECT3D9 d3d = NULL; static LPDIRECT3DDEVICE9 d3ddev = NULL; @@ -108,7 +110,7 @@ static CUSTOMVERTEX d3d_verts[] = {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; -void cgapal_rebuild() +void cgapal_rebuild(void) { int c; for (c = 0; c < 256; c++) @@ -195,7 +197,7 @@ int d3d_fs_init(HWND h) return 1; } -static void d3d_fs_close_objects() +static void d3d_fs_close_objects(void) { if (d3dTexture) { @@ -209,7 +211,7 @@ static void d3d_fs_close_objects() } } -static void d3d_fs_init_objects() +static void d3d_fs_init_objects(void) { D3DLOCKED_RECT dr; RECT r; @@ -256,7 +258,7 @@ static void d3d_fs_init_objects() d3d_reset(); }*/ -void d3d_fs_reset() +void d3d_fs_reset(void) { HRESULT hr; @@ -291,7 +293,7 @@ void d3d_fs_reset() device_force_redraw(); } -void d3d_fs_close() +void d3d_fs_close(void) { if (d3dTexture) { @@ -571,17 +573,14 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) PostMessage(ghwnd, WM_RESETD3D, 0, 0); } -void d3d_fs_take_screenshot(char *fn) +void d3d_fs_take_screenshot(wchar_t *fn) { - WCHAR wfn[512]; LPDIRECT3DSURFACE9 d3dSurface = NULL; if (!d3dTexture) return; - mbstowcs(wfn, fn, strlen(fn) + 1); - d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(wfn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); d3dSurface->Release(); d3dSurface = NULL; diff --git a/src/win-d3d.cc b/src/win-d3d.cc index a30fe1795..abfce0bfb 100644 --- a/src/win-d3d.cc +++ b/src/win-d3d.cc @@ -9,17 +9,19 @@ #include #include "resource.h" #include "win-d3d.h" -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); -extern "C" void video_blit_complete(); +extern "C" void device_force_redraw(void); +extern "C" void video_blit_complete(void); -void d3d_init_objects(); -void d3d_close_objects(); + +void d3d_init_objects(void); +void d3d_close_objects(void); void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); void d3d_blit_memtoscreen_8(int x, int y, int w, int h); @@ -92,7 +94,7 @@ int d3d_init(HWND h) return 1; } -void d3d_close_objects() +void d3d_close_objects(void) { if (d3dTexture) { @@ -106,7 +108,7 @@ void d3d_close_objects() } } -void d3d_init_objects() +void d3d_init_objects(void) { D3DLOCKED_RECT dr; RECT r; @@ -150,7 +152,7 @@ void d3d_resize(int x, int y) d3d_reset(); } -void d3d_reset() +void d3d_reset(void) { HRESULT hr; @@ -185,7 +187,7 @@ void d3d_reset() device_force_redraw(); } -void d3d_close() +void d3d_close(void) { if (d3dTexture) { @@ -381,17 +383,14 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); } -void d3d_take_screenshot(char *fn) +void d3d_take_screenshot(wchar_t *fn) { - WCHAR wfn[512]; LPDIRECT3DSURFACE9 d3dSurface = NULL; if (!d3dTexture) return; - mbstowcs(wfn, fn, strlen(fn) + 1); - d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(wfn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); d3dSurface->Release(); d3dSurface = NULL; diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index 811c69f37..ed458af7a 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -8,18 +8,19 @@ #undef BITMAP #include "win-ddraw-fs.h" #include "win-ddraw-screenshot.h" -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); extern "C" int ddraw_fs_init(HWND h); -extern "C" void ddraw_fs_close(); +extern "C" void ddraw_fs_close(void); -extern "C" void video_blit_complete(); +extern "C" void video_blit_complete(void); static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); @@ -91,7 +92,7 @@ int ddraw_fs_init(HWND h) return 1; } -void ddraw_fs_close() +void ddraw_fs_close(void) { if (lpdds_back2) { @@ -331,7 +332,7 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); } -void ddraw_fs_take_screenshot(char *fn) +void ddraw_fs_take_screenshot(wchar_t *fn) { ddraw_common_take_screenshot(fn, lpdds_back2); } diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc index c49c6170d..e8a891fe9 100644 --- a/src/win-ddraw-screenshot.cc +++ b/src/win-ddraw-screenshot.cc @@ -10,15 +10,16 @@ #include "win.h" #include "win-ddraw-screenshot.h" #include "win-language.h" -#include "video.h" +#include "video/video.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); extern "C" void ddraw_init(HWND h); -extern "C" void ddraw_close(); +extern "C" void ddraw_close(void); HBITMAP hbitmap; @@ -69,7 +70,7 @@ void DoubleLines(uint8_t *dst, uint8_t *src) static WCHAR szMessage[2048]; -void SaveBitmap(char *szFilename,HBITMAP hBitmap) +void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap) { HDC hdc=NULL; FILE* fp=NULL; @@ -106,7 +107,7 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS); - if((fp = fopen(szFilename,"wb"))==NULL) + if((fp = _wfopen(szFilename,L"wb"))==NULL) { _swprintf(szMessage, win_language_get_string_from_id(2194), szFilename); msgbox_error_wstr(ghwnd, szMessage); @@ -154,7 +155,7 @@ void SaveBitmap(char *szFilename,HBITMAP hBitmap) if(fp) fclose(fp); } -void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface7 *pDDSurface) +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface) { xs = xsize; ys = ys2 = ysize; diff --git a/src/win-ddraw-screenshot.h b/src/win-ddraw-screenshot.h index 7c56e5f96..4739174a1 100644 --- a/src/win-ddraw-screenshot.h +++ b/src/win-ddraw-screenshot.h @@ -1,4 +1,4 @@ /* Copyright holders: Tenshi see COPYING for more details */ -void ddraw_common_take_screenshot(char *fn, IDirectDrawSurface7 *pDDSurface); +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc index 7842f16b6..509124205 100644 --- a/src/win-ddraw.cc +++ b/src/win-ddraw.cc @@ -9,18 +9,19 @@ #undef BITMAP #include "win-ddraw.h" #include "win-ddraw-screenshot.h" -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(); +extern "C" void device_force_redraw(void); extern "C" int ddraw_init(HWND h); -extern "C" void ddraw_close(); +extern "C" void ddraw_close(void); -extern "C" void video_blit_complete(); +extern "C" void video_blit_complete(void); static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h); @@ -96,7 +97,7 @@ int ddraw_init(HWND h) return 1; } -void ddraw_close() +void ddraw_close(void) { if (lpdds_back2) { @@ -311,7 +312,7 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) } } -void ddraw_take_screenshot(char *fn) +void ddraw_take_screenshot(wchar_t *fn) { ddraw_common_take_screenshot(fn, lpdds_back2); } diff --git a/src/win-keyboard.cc b/src/win-keyboard.cc deleted file mode 100644 index 16381cd4c..000000000 --- a/src/win-keyboard.cc +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define UNICODE -#include -#include -#include -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "plat-keyboard.h" -#include "win.h" -#include "video.h" - -extern "C" int recv_key[272]; - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void keyboard_init(); -extern "C" void keyboard_close(); -extern "C" void keyboard_poll(); - -int recv_key[272]; - -void keyboard_init() -{ - atexit(keyboard_close); - - memset(recv_key, 0, sizeof(recv_key)); - pclog("Keyboard initialized!\n"); -} - -void keyboard_close() -{ -} - -void keyboard_poll_host() -{ -#if 0 - int c; - - for (c = 0; c < 272; c++) - recv_key[c] = rawinputkey[c]; - - if ((rawinputkey[0x1D] || rawinputkey[0x9D]) && - (rawinputkey[0x38] || rawinputkey[0xB8]) && - (rawinputkey[0x51] || rawinputkey[0xD1]) && - video_fullscreen) - leave_fullscreen(); - - if ((rawinputkey[0x1D] || rawinputkey[0x9D]) && -// (rawinputkey[0x38] || rawinputkey[0xB8]) && - (rawinputkey[0x57] || rawinputkey[0x57])) - { - pclog("Taking screenshot...\n"); - take_screenshot(); - } -#endif -} diff --git a/src/serial_bh.c b/src/win-serial.c similarity index 99% rename from src/serial_bh.c rename to src/win-serial.c index 23ec556e8..e49ebc09f 100644 --- a/src/serial_bh.c +++ b/src/win-serial.c @@ -12,7 +12,7 @@ * Windows and UNIX systems, with support for FTDI and Prolific * USB ports. Support for these has been removed. * - * Version: @(#)serial_bh.c 1.0.1 2017/04/14 + * Version: @(#)win-serial.c 1.0.2 2017/05/05 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -22,7 +22,7 @@ #include #include #define BHTTY_C -#include "serial_bh.h" +#include "win-serial.h" extern void pclog(char *__fmt, ...); diff --git a/src/serial_bh.h b/src/win-serial.h similarity index 96% rename from src/serial_bh.h rename to src/win-serial.h index a3f42a1ba..6c77fbe75 100644 --- a/src/serial_bh.h +++ b/src/win-serial.h @@ -8,7 +8,7 @@ * * Definitions for the Bottom Half of the SERIAL card. * - * Version: @(#)serial_bh.h 1.0.1 2017/04/14 + * Version: @(#)win-serial.h 1.0.2 2017/05/05 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. diff --git a/src/win-settings.c b/src/win-settings.c index 58229df82..035a554d5 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -8,35 +8,35 @@ #undef BITMAP #include - #include - -#include "nethandler.h" #include "ibm.h" -#include "ide.h" -#include "cdrom.h" -#include "cpu.h" +#include "mem.h" +#include "cpu/cpu.h" +#include "nvr.h" +#include "model.h" #include "device.h" -#include "scsi_buslogic.h" +#include "cdrom.h" #include "disc.h" #include "fdd.h" -#include "gameport.h" #include "hdd.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "nvr.h" -#include "resource.h" +#include "ide.h" #include "scsi.h" -#include "sound.h" -#include "sound_dbopl.h" -#include "video.h" -#include "vid_voodoo.h" +#include "scsi_buslogic.h" +#include "network.h" +#include "sound/sound.h" +#include "sound/snd_dbopl.h" +#include "video/video.h" +#include "video/vid_voodoo.h" +#include "gameport.h" +#include "mouse.h" #include "win.h" #include "win-language.h" +#include "resource.h" + #define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + /* Machine category */ int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; @@ -825,29 +825,26 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa default: str_id = 2139; break; - case 1: /* MS InPort Bus */ - str_id = 2177; - break; - case 2: /* PS2 2b */ - str_id = 2140; - break; - case 3: /* MS/logi bus 2b */ - str_id = 2161; - break; - case 4: /* PS2 intelli 3b */ + case 1: /* PS2 2b */ str_id = 2141; break; - case 5: /* Amstrad */ + case 2: /* PS2 intelli 3b */ str_id = 2142; break; - case 6: /* Olivetti M24 */ + case 3: /* MS/logi bus 2b */ str_id = 2143; break; - case 7: /* MouseSystems */ + case 4: /* Amstrad */ str_id = 2162; break; - case 8: /* Genius Bus */ - str_id = 2178; + case 5: /* Olivetti M24 */ + str_id = 2177; + break; + case 6: /* MouseSystems */ + str_id = 2140; + break; + case 7: /* Genius Bus */ + str_id = 2161; break; } diff --git a/src/win-status.c b/src/win-status.c index b907d6942..858a3646c 100644 --- a/src/win-status.c +++ b/src/win-status.c @@ -7,22 +7,24 @@ #undef BITMAP #include "ibm.h" +#include "mem.h" +#include "cpu/x86_ops.h" +#include "cpu/codegen.h" #include "device.h" -#include "video.h" #include "resource.h" #include "win.h" -#include "x86_ops.h" -#include "mem.h" -#include "codegen.h" + HWND status_hwnd; int status_is_open = 0; + extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; extern uint64_t main_time; static uint64_t status_time; + static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { char device_s[4096]; diff --git a/src/win-video.c b/src/win-video.c index dd6b3788f..15aec3785 100644 --- a/src/win-video.c +++ b/src/win-video.c @@ -4,11 +4,13 @@ #include #include #include -#include "video.h" +#include "video/video.h" #include "win-cgapal.h" + BITMAP *screen; + void hline(BITMAP *b, int x1, int y, int x2, uint32_t col) { if (y < 0 || y >= buffer->h) diff --git a/src/win.c b/src/win.c index ac112aed4..ee792c5d8 100644 --- a/src/win.c +++ b/src/win.c @@ -10,9 +10,7 @@ #include #include - #include - #include #include #include @@ -24,29 +22,26 @@ #include "fdd.h" #include "hdd.h" #include "ibm.h" +#include "cpu/cpu.h" +#include "mem.h" +#include "rom.h" +#include "nvr.h" +#include "thread.h" +#include "config.h" +#include "model.h" #include "ide.h" +#include "cdrom.h" #include "cdrom-null.h" #include "cdrom-ioctl.h" #include "cdrom-iso.h" -#include "config.h" -#include "video.h" -#include "resource.h" -#include "cpu.h" -#include "cdrom.h" -#include "mem.h" -#include "model.h" -#include "mouse.h" -#include "nethandler.h" -#include "nvr.h" -#include "sound.h" -#include "sound_dbopl.h" -#include "thread.h" -#include "rom.h" -#include "vid_ega.h" - +#include "video/video.h" +#include "video/vid_ega.h" +#include "plat-keyboard.h" #include "plat-mouse.h" #include "plat-midi.h" -#include "plat-keyboard.h" +#include "mouse.h" +#include "sound/sound.h" +#include "sound/snd_dbopl.h" #include "win.h" #include "win-ddraw.h" @@ -54,6 +49,8 @@ #include "win-d3d.h" #include "win-d3d-fs.h" #include "win-language.h" +#include "resource.h" + #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 @@ -1087,6 +1084,8 @@ void win_menu_update() #endif } +int recv_key[272]; + int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, @@ -1101,6 +1100,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, LARGE_INTEGER qpc_freq; HACCEL haccel; /* Handle to accelerator table */ + memset(recv_key, 0, sizeof(recv_key)); + process_command_line(); win_language_load_common_strings(); diff --git a/src/xtide.c b/src/xtide.c index db6f1dca3..ce827151b 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,20 +1,20 @@ #include - #include "ibm.h" - -#include "device.h" #include "io.h" -#include "ide.h" #include "mem.h" #include "rom.h" +#include "device.h" +#include "ide.h" #include "xtide.h" + typedef struct xtide_t { uint8_t data_high; rom_t bios_rom; } xtide_t; + static void xtide_write(uint16_t port, uint8_t val, void *p) { xtide_t *xtide = (xtide_t *)p; @@ -40,6 +40,7 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) } } + static uint8_t xtide_read(uint16_t port, void *p) { xtide_t *xtide = (xtide_t *)p; @@ -67,7 +68,8 @@ static uint8_t xtide_read(uint16_t port, void *p) } } -static void *xtide_init() + +static void *xtide_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); @@ -81,7 +83,8 @@ static void *xtide_init() return xtide; } -static void *xtide_at_init() + +static void *xtide_at_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); @@ -92,7 +95,8 @@ static void *xtide_at_init() return xtide; } -static void *xtide_ps2_init() + +static void *xtide_ps2_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); @@ -106,7 +110,8 @@ static void *xtide_ps2_init() return xtide; } -static void *xtide_at_ps2_init() + +static void *xtide_at_ps2_init(void) { xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); @@ -117,6 +122,7 @@ static void *xtide_at_ps2_init() return xtide; } + static void xtide_close(void *p) { xtide_t *xtide = (xtide_t *)p; @@ -124,26 +130,31 @@ static void xtide_close(void *p) free(xtide); } -static int xtide_available() + +static int xtide_available(void) { return rom_present(L"roms/ide_xt.bin"); } -static int xtide_at_available() + +static int xtide_at_available(void) { return rom_present(L"roms/ide_at.bin"); } -static int xtide_ps2_available() + +static int xtide_ps2_available(void) { return rom_present(L"roms/SIDE1V12.BIN"); } -static int xtide_at_ps2_available() + +static int xtide_at_ps2_available(void) { return rom_present(L"roms/ide_at_1_1_5.bin"); } + device_t xtide_device = { "XTIDE", From 9f99dbcfae8a020942456d85f53e3df16a254084 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 May 2017 22:27:23 +0200 Subject: [PATCH 162/392] Applied a typo-fixing mainline PCem commit to 808x.c; Temporarily reverted serial port and serial mouse code back to the old one until the new code is fixed; Fixed nvr_path handling - the NVR path no longer gets messed up at hard reset. --- src/CPU/808x.c | 2 +- src/disc_86f.c | 1 - src/disc_fdi.c | 1 - src/disc_imd.c | 1 - src/disc_img.c | 2 - src/disc_td0.c | 1 - src/mouse_serial.c | 14 +- src/pc.c | 12 +- src/serial.c | 850 ++++++++++++++------------------------------- src/serial.h | 79 ++--- src/win.c | 1 - 11 files changed, 295 insertions(+), 669 deletions(-) diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 297782386..1f6f67cca 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -1998,7 +1998,7 @@ void execx86(int cycs) case 0xA1: /*MOV AX,(w)*/ addr=getword(); AX=readmemw(ds,addr); - cycles-=!4; + cycles-=14; break; case 0xA2: /*MOV (w),AL*/ addr=getword(); diff --git a/src/disc_86f.c b/src/disc_86f.c index 10f4ff486..5a7614e32 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -3328,5 +3328,4 @@ void d86f_close(int drive) fclose(d86f[drive].f); if (d86f[drive].is_compressed) _wremove(temp_file_name); - d86f[drive].f = NULL; } diff --git a/src/disc_fdi.c b/src/disc_fdi.c index b7aae9819..bf8410e91 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -286,7 +286,6 @@ void fdi_close(int drive) fdi2raw_header_free(fdi[drive].h); if (fdi[drive].f) fclose(fdi[drive].f); - fdi[drive].f = NULL; } void fdi_seek(int drive, int track) diff --git a/src/disc_imd.c b/src/disc_imd.c index e583335e0..fcbed568d 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -289,7 +289,6 @@ void imd_close(int drive) } fclose(imd[drive].f); } - imd[drive].f = NULL; } int imd_track_is_xdf(int drive, int side, int track) diff --git a/src/disc_img.c b/src/disc_img.c index e5020353d..0391820d0 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -850,8 +850,6 @@ void img_close(int drive) fclose(img[drive].f); if (img[drive].disk_data) free(img[drive].disk_data); - img[drive].f = NULL; - img[drive].disk_data = NULL; } #define xdf_img_sector xdf_img_layout[current_xdft][!is_t0][sector] diff --git a/src/disc_td0.c b/src/disc_td0.c index ab3511a32..c63a62dc5 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -584,7 +584,6 @@ void td0_close(int drive) if (td0[drive].f) fclose(td0[drive].f); - td0[drive].f = NULL; } uint32_t td0_get_raw_tsize(int side_flags, int slower_rpm) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 46ebbbb1e..84e85a673 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -85,13 +85,9 @@ sermouse_init(void) memset(ms, 0x00, sizeof(mouse_serial_t)); /* Attach a serial port to the mouse. */ -#if 1 - ms->serial = serial_attach(0, sermouse_rcr, ms); -#else - ms->serial = &serial1; - serial1.rcr_callback = sermouse_rcr; - serial1.rcr_callback_p = ms; -#endif + ms->serial = &serial1; + serial1.rcr_callback = sermouse_rcr; + serial1.rcr_callback_p = ms; timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); @@ -105,11 +101,7 @@ sermouse_close(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; /* Detach serial port from the mouse. */ -#if 1 - serial_attach(0, NULL, NULL); -#else serial1.rcr_callback = NULL; -#endif free(ms); } diff --git a/src/pc.c b/src/pc.c index b4bf2b942..bf8036f52 100644 --- a/src/pc.c +++ b/src/pc.c @@ -953,15 +953,21 @@ void loadconfig(wchar_t *fn) bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); } +wchar_t temp_nvr_path[1024]; + wchar_t *nvr_concat(wchar_t *to_concat) { - char *p = (char *) nvr_path; + char *p; + + memset(temp_nvr_path, 0, 2048); + wcscpy(temp_nvr_path, nvr_path); + + p = (char *) temp_nvr_path; p += (path_len * 2); wchar_t *wp = (wchar_t *) p; - memset(wp, 0, (1024 - path_len) * 2); wcscpy(wp, to_concat); - return nvr_path; + return temp_nvr_path; } void saveconfig() diff --git a/src/serial.c b/src/serial.c index a80912ddf..4eb78e821 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,639 +1,295 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of NS8250-series UART devices. - * - * The original IBM-PC design did not have any serial ports of - * any kind. Rather, these were offered as add-on devices, most - * likely because a) most people did not need one at the time, - * and, b) this way, IBM could make more money off them. - * - * So, for the PC, the offerings were for an IBM Asynchronous - * Communications Adapter, and, later, a model for synchronous - * communications. - * - * The "Async Adapter" was based on the NS8250 UART chip, and - * is what we now call the "serial" or "com" port of the PC. - * - * Of course, many system builders came up with similar boards, - * and even more boards were designed where several I/O functions - * were combined into a single board: the Multi-I/O adapters. - * Initially, these had all the chips as-is, but later many of - * these functions were integrated into a single MIO chip. - * - * This file implements the standard NS8250 series of chips, with - * support for the later (16450 and 16550) FIFO additions. On the - * lower half of the driver, we interface to the host system's - * serial ports for real-world access. - * - * Based on the 86Box serial port driver as a framework. - * - * Version: @(#)serial.c 1.0.2 2017/05/05 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ #include "ibm.h" #include "io.h" #include "mouse.h" #include "pic.h" #include "serial.h" #include "timer.h" -#include "win-serial.h" - -enum { - SERINT_LSR = 1, - SERINT_RECEIVE = 2, - SERINT_TRANSMIT = 4, - SERINT_MSR = 8 +enum +{ + SERIAL_INT_LSR = 1, + SERIAL_INT_RECEIVE = 2, + SERIAL_INT_TRANSMIT = 4, + SERIAL_INT_MSR = 8 }; +SERIAL serial1, serial2; -/* IER register bits. */ -#define IER_RDAIE (0x01) -#define IER_THREIE (0x02) -#define IER_RXLSIE (0x04) -#define IER_MSIE (0x08) -#define IER_SLEEP (0x10) /* NS16750 */ -#define IER_LOWPOWER (0x20) /* NS16750 */ -#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ - -/* IIR register bits. */ -#define IIR_IP (0x01) -#define IIR_IID (0x0e) -# define IID_IDMDM (0x00) -# define IID_IDTX (0x02) -# define IID_IDRX (0x04) -# define IID_IDERR (0x06) -# define IID_IDTMO (0x0c) -#define IIR_IIRFE (0xc0) -# define IIR_FIFO64 (0x20) -# define IIR_FIFOBAD (0x80) /* 16550 */ -# define IIR_FIFOENB (0xc0) - -/* FCR register bits. */ -#define FCR_FCRFE (0x01) -#define FCR_RFR (0x02) -#define FCR_TFR (0x04) -#define FCR_SELDMA1 (0x08) -#define FCR_FENB64 (0x20) /* 16750 */ -#define FCR_RTLS (0xc0) -# define FCR_RTLS1 (0x00) -# define FCR_RTLS4 (0x40) -# define FCR_RTLS8 (0x80) -# define FCR_RTLS14 (0xc0) - -/* LCR register bits. */ -#define LCR_WLS (0x03) -# define WLS_BITS5 (0x00) -# define WLS_BITS6 (0x01) -# define WLS_BITS7 (0x02) -# define WLS_BITS8 (0x03) -#define LCR_SBS (0x04) -#define LCR_PE (0x08) -#define LCR_EP (0x10) -#define LCR_PS (0x20) -# define PAR_NONE (0x00) -# define PAR_EVEN (LCR_PE | LCR_EP) -# define PAR_ODD (LCR_PE) -# define PAR_MARK (LCR_PE | LCR_PS) -# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) -#define LCR_BC (0x40) -#define LCR_DLAB (0x80) - -/* MCR register bits. */ -#define MCR_DTR (0x01) -#define MCR_RTS (0x02) -#define MCR_OUT1 (0x04) /* 8250 */ -#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ -#define MCR_LMS (0x10) -#define MCR_AUTOFLOW (0x20) /* 16750 - -/* LSR register bits. */ -#define LSR_DR (0x01) -#define LSR_OE (0x02) -#define LSR_PE (0x04) -#define LSR_FE (0x08) -#define LSR_BI (0x10) -#define LSR_THRE (0x20) -#define LSR_TEMT (0x40) -#define LSR_RXFE (0x80) - -/* MSR register bits. */ -#define MSR_DCTS (0x01) -#define MSR_DDSR (0x02) -#define MSR_TERI (0x04) -#define MSR_DDCD (0x08) -#define MSR_CTS (0x10) -#define MSR_DSR (0x20) -#define MSR_RI (0x40) -#define MSR_DCD (0x80) -#define MSR_MASK (0x0f) - - -static uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; -static int serial_irq[2] = { 4, 3 }; -static SERIAL serial1, serial2; - - -static void -update_ints(SERIAL *sp) +void serial_reset() { - int stat = 0; + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; + serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; + serial1.fifo_read = serial1.fifo_write = 0; + serial2.fifo_read = serial2.fifo_write = 0; +} + +void serial_update_ints(SERIAL *serial) +{ + int stat = 0; - sp->iir = IIR_IP; - if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { - /* Line Status interrupt. */ - stat = 1; - sp->iir = IID_IDERR; - } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { - /* Received Data available. */ - stat = 1; - sp->iir = IID_IDRX; - } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { - /* Transmit Data empty. */ - stat = 1; - sp->iir = IID_IDTX; - } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { - /* Modem Status interrupt. */ - stat = 1; - sp->iir = IID_IDMDM; - } + serial->iir = 1; - /* Raise or clear the level-based IRQ. */ - if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) - picintlevel(1 << sp->irq); - else - picintc(1 << sp->irq); + if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ + { + stat = 1; + serial->iir = 6; + } + else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ + { + stat = 1; + serial->iir = 4; + } + else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ + { + stat = 1; + serial->iir = 2; + } + else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ + { + stat = 1; + serial->iir = 0; + } + + if (stat && ((serial->mctrl & 8) || PCJR)) + picintlevel(1 << serial->irq); + else + picintc(1 << serial->irq); } - -/* Write data to the (input) FIFO. Used by MOUSE driver. */ -void -serial_write_fifo(SERIAL *sp, uint8_t dat) +void serial_write_fifo(SERIAL *serial, uint8_t dat) { - /* Stuff data into FIFO. */ - sp->fifo[sp->fifo_write] = dat; - sp->fifo_write = (sp->fifo_write + 1) & 0xFF; - - if (! (sp->lsr & LSR_DR)) { - sp->lsr |= LSR_DR; - sp->int_status |= SERINT_RECEIVE; - update_ints(sp); - } + serial->fifo[serial->fifo_write] = dat; + serial->fifo_write = (serial->fifo_write + 1) & 0xFF; + if (!(serial->lsr & 1)) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } } - -static uint8_t -read_fifo(SERIAL *sp) +uint8_t serial_read_fifo(SERIAL *serial) { - if (sp->fifo_read != sp->fifo_write) { - sp->dat = sp->fifo[sp->fifo_read]; - sp->fifo_read = (sp->fifo_read + 1) & 0xFF; - } - - return(sp->dat); + if (serial->fifo_read != serial->fifo_write) + { + serial->dat = serial->fifo[serial->fifo_read]; + serial->fifo_read = (serial->fifo_read + 1) & 0xFF; + } + return serial->dat; } - -/* BHTTY WRITE COMPLETE handler. */ -static void -serial_wr_done(void *arg) +void serial_write(uint16_t addr, uint8_t val, void *p) { - SERIAL *sp = (SERIAL *)arg; - - /* The WRITE completed, we are ready for more. */ - sp->lsr |= LSR_THRE; - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); + SERIAL *serial = (SERIAL *)p; + switch (addr&7) + { + case 0: + if (serial->lcr & 0x80) + { + serial->dlab1 = val; + return; + } + serial->thr = val; + serial->lsr |= 0x20; + serial->int_status |= SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + if (serial->mctrl & 0x10) + { + serial_write_fifo(serial, val); + } + break; + case 1: + if (serial->lcr & 0x80) + { + serial->dlab2 = val; + return; + } + serial->ier = val & 0xf; + serial_update_ints(serial); + break; + case 2: + serial->fcr = val; + break; + case 3: + serial->lcr = val; + break; + case 4: + if ((val & 2) && !(serial->mctrl & 2)) + { + if (serial->rcr_callback) + serial->rcr_callback(serial, serial->rcr_callback_p); + } + serial->mctrl = val; + if (val & 0x10) + { + uint8_t new_msr; + + new_msr = (val & 0x0c) << 4; + new_msr |= (val & 0x02) ? 0x10: 0; + new_msr |= (val & 0x01) ? 0x20: 0; + + if ((serial->msr ^ new_msr) & 0x10) + new_msr |= 0x01; + if ((serial->msr ^ new_msr) & 0x20) + new_msr |= 0x02; + if ((serial->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((serial->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + serial->msr = new_msr; + } + break; + case 5: + serial->lsr = val; + if (serial->lsr & 0x01) + serial->int_status |= SERIAL_INT_RECEIVE; + if (serial->lsr & 0x1e) + serial->int_status |= SERIAL_INT_LSR; + if (serial->lsr & 0x20) + serial->int_status |= SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + break; + case 6: + serial->msr = val; + if (serial->msr & 0x0f) + serial->int_status |= SERIAL_INT_MSR; + serial_update_ints(serial); + break; + case 7: + serial->scratch = val; + break; + } } - -/* Handle a WRITE operation to one of our registers. */ -static void -serial_write(uint16_t addr, uint8_t val, void *priv) +uint8_t serial_read(uint16_t addr, void *p) { - SERIAL *sp = (SERIAL *)priv; - uint8_t wl, sb, pa; - uint16_t baud; - long speed; + SERIAL *serial = (SERIAL *)p; + uint8_t temp = 0; + switch (addr&7) + { + case 0: + if (serial->lcr & 0x80) + { + temp = serial->dlab1; + break; + } - switch (addr & 0x07) { - case 0: /* DATA / DLAB1 */ - if (sp->lcr & LCR_DLAB) { - sp->dlab1 = val; - return; - } - sp->thr = val; -#if 0 - bhtty_write((BHTTY *)sp->bh, sp->thr, serial_wrdone, sp); -#else - bhtty_write((BHTTY *)sp->bh, sp->thr); - serial_wr_done(sp); -#endif - if (sp->mctrl & MCR_LMS) { - /* Echo data back to RX. */ - serial_write_fifo(sp, val); - } - break; - - case 1: /* IER / DLAB2 */ - if (sp->lcr & LCR_DLAB) { - sp->dlab2 = val; - return; - } - sp->ier = (val & IER_MASK); - update_ints(sp); - break; - - case 2: /* FCR */ - sp->fcr = val; - break; - - case 3: /* LCR */ - if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { - /* We dropped DLAB, so handle baudrate. */ - baud = ((sp->dlab2 << 8) | sp->dlab1); - speed = 115200UL/baud; -#if 1 - pclog("Serial: new divisor %u, baudrate %ld\n", - baud, speed); -#endif - bhtty_speed((BHTTY *)sp->bh, speed); - } - wl = (val & LCR_WLS) + 5; /* databits */ - sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ - pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; -#if 1 - pclog("Serial: WL=%d SB=%d PA=%d\n", wl, sb, pa); -#endif - bhtty_params((BHTTY *)sp->bh, wl, pa, sb); - sp->lcr = val; - break; - - case 4: - if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { - /* - * This is old code for use by the Serial Mouse - * driver. If the user toggles RTS, any serial - * mouse is expected to send an 'M' character, - * to inform any enumerator there 'is' something. - */ - if (sp->rcr_callback) { - sp->rcr_callback(sp, sp->rcr_callback_p); -#if 0 - pclog("RTS raised; sending M\n"); -#endif - } - } - - if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { - /* Start up reading from the real port. */ - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); - } - sp->mctrl = val; - if (val & MCR_LMS) { /* loopback mode */ - uint8_t new_msr; - - /*FIXME: WTF does this do?? --FvK */ - new_msr = (val & 0x0c) << 4; - new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; - new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; - - if ((sp->msr ^ new_msr) & 0x10) - new_msr |= MCR_DTR; - if ((sp->msr ^ new_msr) & 0x20) - new_msr |= MCR_RTS; - if ((sp->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((sp->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - sp->msr = new_msr; - } - break; - - case 5: - sp->lsr = val; - if (sp->lsr & LSR_DR) - sp->int_status |= SERINT_RECEIVE; - if (sp->lsr & 0x1e) - sp->int_status |= SERINT_LSR; - if (sp->lsr & LSR_THRE) - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); - break; - - case 6: - sp->msr = val; - if (sp->msr & MSR_MASK) - sp->int_status |= SERINT_MSR; - update_ints(sp); - break; - - case 7: - sp->scratch = val; - break; - } + serial->lsr &= ~1; + serial->int_status &= ~SERIAL_INT_RECEIVE; + serial_update_ints(serial); + temp = serial_read_fifo(serial); + if (serial->fifo_read != serial->fifo_write) + serial->recieve_delay = 1000 * TIMER_USEC; + break; + case 1: + if (serial->lcr & 0x80) + temp = serial->dlab2; + else + temp = serial->ier; + break; + case 2: + temp = serial->iir; + if ((temp & 0xe) == 2) + { + serial->int_status &= ~SERIAL_INT_TRANSMIT; + serial_update_ints(serial); + } + if (serial->fcr & 1) + temp |= 0xc0; + break; + case 3: + temp = serial->lcr; + break; + case 4: + temp = serial->mctrl; + break; + case 5: + if (serial->lsr & 0x20) + serial->lsr |= 0x40; + serial->lsr |= 0x20; + temp = serial->lsr; + if (serial->lsr & 0x1f) + serial->lsr &= ~0x1e; + serial->int_status &= ~SERIAL_INT_LSR; + serial_update_ints(serial); + break; + case 6: + temp = serial->msr; + serial->msr &= ~0x0f; + serial->int_status &= ~SERIAL_INT_MSR; + serial_update_ints(serial); + break; + case 7: + temp = serial->scratch; + break; + } + return temp; } - -/* BHTTY READ COMPLETE handler. */ -static void -serial_rd_done(void *arg, int num) +void serial_recieve_callback(void *p) { - SERIAL *sp = (SERIAL *)arg; -//pclog("%04x: %d bytes available: %02x (%c)\n",sp->port,num,sp->hold,sp->hold); - - /* Stuff the byte in the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); - - /* Start up the next read from the real port. */ - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -serial_read(uint16_t addr, void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - uint8_t ret = 0x00; - - switch (addr&0x07) { - case 0: /* DATA / DLAB1 */ - if (sp->lcr & LCR_DLAB) { - ret = sp->dlab1; - break; - } - sp->lsr &= ~LSR_DR; - sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); -#if 0 - if (sp->fifo_read != sp->fifo_write) - sp->receive_delay = 1000 * TIMER_USEC; -#endif - break; - - case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) - ret = sp->dlab2; - else - ret = sp->ier; - break; - - case 2: /* IIR */ - ret = sp->iir; - if ((ret & IIR_IID) == IID_IDTX) { - sp->int_status &= ~SERINT_TRANSMIT; - update_ints(sp); - } - if (sp->fcr & 1) - { - ret |= 0xc0; - } - break; - - case 3: /* LCR */ - ret = sp->lcr; - break; - - case 4: /* MCR */ - ret = sp->mctrl; - break; - - case 5: /* LSR */ - if (sp->lsr & LSR_THRE) - sp->lsr |= LSR_TEMT; - sp->lsr |= LSR_THRE; - ret = sp->lsr; - if (sp->lsr & 0x1f) - sp->lsr &= ~0x1e; -#if 0 - sp->lsr |= (LSR_THRE | LSR_TEMT); -#endif - sp->int_status &= ~SERINT_LSR; - update_ints(sp); - break; - - case 6: - ret = sp->msr; - sp->msr &= ~0x0f; - sp->int_status &= ~SERINT_MSR; - update_ints(sp); - break; - - case 7: - ret = sp->scratch; - break; - } - - return(ret); + SERIAL *serial = (SERIAL *)p; + + serial->recieve_delay = 0; + + if (serial->fifo_read != serial->fifo_write) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } } +uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; +int serial_irq[2] = { 4, 3 }; /*Tandy might need COM1 at 2f8*/ -void -serial1_init(uint16_t addr, int irq) +void serial1_init(uint16_t addr, int irq) { - BHTTY *bh; - - memset(&serial1, 0x00, sizeof(serial1)); - - pclog("Serial1, I/O=%04x, IRQ=%d, host ", addr, irq); - - /* Request a port from the host system. */ - bh = bhtty_open(BHTTY_PORT1, 0); /*FIXME: from config! --FvK */ - if (bh == NULL) { - return; - } - serial1.bh = bh; - serial1.port = addr; - serial1.irq = irq; - serial1.rcr_callback = NULL; - pclog("'%s'\n", bh->name); - - /* Set up bottom-half I/O callback info. */ - bh->rd_done = serial_rd_done; - bh->rd_arg = &serial1; - - /* Request an I/O range. */ - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - -#if 0 - timer_add(serial_receive_callback, - &serial1.receive_delay, &serial1.receive_delay, &serial1); -#endif - - serial_addr[0] = addr; - serial_irq[0] = irq; + memset(&serial1, 0, sizeof(serial1)); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = irq; + serial1.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); + serial_addr[0] = addr; + serial_irq[0] = irq; +} +void serial1_set(uint16_t addr, int irq) +{ + serial1_remove(); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + serial1.irq = irq; + serial_addr[0] = addr; + serial_irq[0] = irq; +} +void serial1_remove() +{ + io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); } - -/* Release all resources held by the device. */ -void -serial1_remove(void) +void serial2_init(uint16_t addr, int irq) { - /* Close the host device. */ - if (serial1.bh != NULL) - bhtty_close((BHTTY *)serial1.bh); - - /* Release our I/O range. */ - io_removehandler(serial_addr[0], 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + memset(&serial2, 0, sizeof(serial2)); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = irq; + serial2.rcr_callback = NULL; + timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); + serial_addr[1] = addr; + serial_irq[1] = irq; } - - -void -serial1_set(uint16_t addr, int irq) +void serial2_set(uint16_t addr, int irq) { - void *temp; - -#if 0 - pclog("serial1_set(%04X, %02X)\n", addr, irq); -#endif - temp = serial1.bh; - serial1.bh = NULL; - serial1_remove(); - serial1.bh = temp; - serial1.port = addr; - serial1.irq = irq; - - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial_addr[0] = addr; - serial_irq[0] = irq; + serial2_remove(); + io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + serial2.irq = irq; + serial_addr[1] = addr; + serial_irq[1] = irq; } - - -void -serial2_init(uint16_t addr, int irq) +void serial2_remove() { - BHTTY *bh; - - memset(&serial2, 0x00, sizeof(serial2)); - - pclog("Serial2, I/O=%04x, IRQ=%d, host ", addr, irq); - - /* Request a port from the host system. */ - bh = bhtty_open(BHTTY_PORT2, 0); /*FIXME: from config! --FvK */ - if (bh == NULL) { - return; - } - serial2.bh = bh; - serial2.port = addr; - serial2.irq = irq; - serial2.rcr_callback = NULL; - pclog("'%s'\n", bh->name); - - /* Set up bottom-half I/O callback info. */ - bh->rd_done = serial_rd_done; - bh->rd_arg = &serial2; - - /* Request an I/O range. */ - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - - serial_addr[1] = addr; - serial_irq[1] = irq; -} - - -/* Release all resources held by the device. */ -void -serial2_remove(void) -{ - /* Close the host device. */ - if (serial2.bh != NULL) - bhtty_close((BHTTY *)serial2.bh); - - /* Release our I/O range. */ - io_removehandler(serial_addr[1], 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); -} - - -void -serial2_set(uint16_t addr, int irq) -{ - void *temp; - -#if 0 - pclog("serial2_set(%04X, %02X)\n", addr, irq); -#endif - temp = serial2.bh; - serial2.bh = NULL; - serial2_remove(); - serial2.bh = temp; - serial2.port = addr; - serial2.irq = irq; - - io_sethandler(addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - - serial_addr[1] = addr; - serial_irq[1] = irq; -} - - -/* - * Reset the serial ports. - * - * This should be a per-port function. - */ -void -serial_reset(void) -{ - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; - - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial2.fifo_read = serial2.fifo_write = 0; -} - - -/* Fake interrupt generator, needed for Serial Mouse. */ -static void -serial_timer(void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - - sp->receive_delay = 0; - - if (sp->fifo_read != sp->fifo_write) { - sp->lsr |= LSR_DR; - sp->int_status |= SERINT_RECEIVE; - update_ints(sp); - } -} - - -/* Attach another device (MOUSE) to a serial port. */ -SERIAL * -serial_attach(int port, void *func, void *arg) -{ - SERIAL *sp; - - if (port == 0) - sp = &serial1; - else - sp = &serial2; - - /* Set up callback info. */ - sp->rcr_callback = func; - sp->rcr_callback_p = arg; - - /* Create a timer to fake RX interrupts for mouse data. */ - timer_add(serial_timer, - &sp->receive_delay, &sp->receive_delay, sp); - - return(sp); + io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); } diff --git a/src/serial.h b/src/serial.h index 05a5c7ff5..96104068e 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,56 +1,35 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the SERIAL card. - * - * Version: @(#)serial.h 1.0.1 2017/04/14 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef SERIAL_H -# define SERIAL_H +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +void serial1_init(uint16_t addr, int irq); +void serial2_init(uint16_t addr, int irq); +void serial1_set(uint16_t addr, int irq); +void serial2_set(uint16_t addr, int irq); +void serial1_remove(); +void serial2_remove(); +void serial_reset(); +struct SERIAL; -typedef struct _serial_ { - uint16_t port; - int16_t irq; +typedef struct +{ + uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; + uint8_t dlab1,dlab2; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + + int irq; - uint8_t lsr, thr, mctrl, rcr, iir, ier, lcr, msr; - uint8_t dlab1, dlab2; - uint8_t dat; - uint8_t int_status; - uint8_t scratch; - uint8_t fcr; - - void (*rcr_callback)(struct _serial_ *, void *); - void *rcr_callback_p; - - uint8_t hold; - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int receive_delay; - - void *bh; + void (*rcr_callback)(struct SERIAL *serial, void *p); + void *rcr_callback_p; + uint8_t fifo[256]; + int fifo_read, fifo_write; + + int recieve_delay; } SERIAL; +extern SERIAL serial1, serial2; -extern void serial1_init(uint16_t addr, int irq); -extern void serial2_init(uint16_t addr, int irq); -extern void serial1_set(uint16_t addr, int irq); -extern void serial2_set(uint16_t addr, int irq); -extern void serial1_remove(); -extern void serial2_remove(); - -extern void serial_reset(); -extern SERIAL *serial_attach(int, void *, void *); -extern void serial_write_fifo(SERIAL *, uint8_t); - - -#endif /*SERIAL_H*/ +void serial_write_fifo(SERIAL *serial, uint8_t dat); diff --git a/src/win.c b/src/win.c index ee792c5d8..9b85ac8ca 100644 --- a/src/win.c +++ b/src/win.c @@ -2156,7 +2156,6 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { disc_close(0); ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - msgbox_info_wstr(ghwnd, wopenfilestring); disc_load(0, wopenfilestring); update_status_bar_icon_state(0x00, 0); update_tip(0x00); From 1d93801019740d21a770d253ec904be7cdb52de8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 May 2017 22:44:45 +0200 Subject: [PATCH 163/392] Hopefully fixed the file name of the saved screenshots. --- src/VIDEO/video.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index 20352cdb5..c7c1a31b8 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -702,7 +702,7 @@ void take_screenshot() if (vid_api == 1) { wcsftime(screenshot_fn_partial, 2048, L"screenshots\\%Y%m%d_%H%M%S.png", info); - append_filename(screenshot_fn, pcempath, screenshot_fn_partial, 4095); + append_filename_w(screenshot_fn, pcempath, screenshot_fn_partial, 4095); if (video_fullscreen) { d3d_fs_take_screenshot(screenshot_fn); @@ -715,8 +715,8 @@ void take_screenshot() } else if (vid_api == 0) { - strftime(screenshot_fn_partial, 1024, "screenshots\\%Y%m%d_%H%M%S.bmp", info); - append_filename(screenshot_fn, pcempath, screenshot_fn_partial, 4095); + wcsftime(screenshot_fn_partial, 2048, L"screenshots\\%Y%m%d_%H%M%S.bmp", info); + append_filename_w(screenshot_fn, pcempath, screenshot_fn_partial, 4095); if (video_fullscreen) { ddraw_fs_take_screenshot(screenshot_fn); From 2dc5b2e48af6a0dab4937c8468850b544622f125 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 6 May 2017 23:20:32 +0200 Subject: [PATCH 164/392] Fixed generation of default NVR path, should fix the NVR path across configuration file loads. --- src/pc.c | 4 ++-- src/win.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pc.c b/src/pc.c index bf8036f52..86eb6e364 100644 --- a/src/pc.c +++ b/src/pc.c @@ -926,9 +926,9 @@ void loadconfig(wchar_t *fn) } memset(nvr_path, 0, 2048); - wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L"nvr"); + wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); if (wp) { - if (wcslen(wp) <= 992) wcscpy(nvr_path, wp); + if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); else { append_filename_w(nvr_path, pcempath, L"nvr", 511); diff --git a/src/win.c b/src/win.c index 9b85ac8ca..e601e2fb6 100644 --- a/src/win.c +++ b/src/win.c @@ -1851,6 +1851,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { config_save(config_file_default); loadconfig(wopenfilestring); + pclog_w(L"NVR path: %s\n", nvr_path); mem_resize(); loadbios(); resetpchard(); From 35352ff6af30ae80b4309454da8cb8b83fb97428 Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 6 May 2017 17:46:41 -0400 Subject: [PATCH 165/392] Testing GIT setup with harmless change. --- src/mouse_bus.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 9112e2c3e..c3817c98f 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -47,6 +47,9 @@ #include "plat-mouse.h" +/* commit test, pse ignore, will remove */ + + #define ENABLE_3BTN 1 /* enable 3-button mode */ From 3f3471ee7e0fcdeec4a03481d87b72af6ab9cb93 Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 6 May 2017 18:29:20 -0400 Subject: [PATCH 166/392] Undo test change. --- src/mouse_bus.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/mouse_bus.c b/src/mouse_bus.c index c3817c98f..ca2c4f80a 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -32,7 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * Version: @(#)mouse_bus.c 1.0.4 2017/05/01 + * Version: @(#)mouse_bus.c 1.0.4 2017/05/06 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -47,9 +47,6 @@ #include "plat-mouse.h" -/* commit test, pse ignore, will remove */ - - #define ENABLE_3BTN 1 /* enable 3-button mode */ From 885e2f0444734fdd9d4338f132a5d235f36e9336 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 7 May 2017 04:56:34 +0200 Subject: [PATCH 167/392] Added optional ability to dump (S)VGA Video RAM on demand (not enabled by default); Removed the unfinished (and largely unused) Disney Sound Source emulation. --- src/86Box.rc | 61 +++++++++++++++++++++++++++++++ src/Makefile.mingw | 18 ++++++++-- src/SOUND/sound.c | 14 -------- src/VIDEO/vid_s3.c | 2 +- src/VIDEO/vid_svga.c | 86 +++++++++++++++++++++++++++++++++++++++----- src/VIDEO/video.h | 4 +++ src/amstrad.c | 2 +- src/dac.c | 70 ------------------------------------ src/dac.h | 2 -- src/lpt.c | 9 ----- src/resource.h | 3 ++ src/win.c | 6 ++++ 12 files changed, 169 insertions(+), 108 deletions(-) delete mode 100644 src/dac.c delete mode 100644 src/dac.h diff --git a/src/86Box.rc b/src/86Box.rc index a36f17ca4..8bc4756d9 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -142,6 +142,41 @@ BEGIN MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END MENUITEM "S&tatus", IDM_STATUS +#ifdef ENABLE_LOG_TOGGLES +#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG + MENUITEM SEPARATOR +#endif +#ifdef ENABLE_BUSLOGIC_LOG + MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC +#endif +#ifdef ENABLE_CDROM_LOG + MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM +#endif +#ifdef ENABLE_D86F_LOG + MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F +#endif +#ifdef ENABLE_FDC_LOG + MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC +#endif +#ifdef ENABLE_IDE_LOG + MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE +#endif +#ifdef ENABLE_NE2000_LOG + MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + MENUITEM SEPARATOR + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +#ifdef ENABLE_VRAM_DUMP + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#else +#ifdef ENABLE_VRAM_DUMP + MENUITEM SEPARATOR + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#endif END POPUP "&Help" BEGIN @@ -157,6 +192,32 @@ END MAINACCEL ACCELERATORS MOVEABLE PURE BEGIN +#ifdef ENABLE_VRAM_DUMP + VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_CDROM_LOG + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_D86F_LOG + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_FDC_LOG + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_IDE_LOG + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_NE2000_LOG + VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY +#endif VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL END diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 783447992..c5cb7fbfb 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.6 2017/05/06 +# Version: @(#)Makefile.mingw 1.0.7 2017/05/07 # # Authors: Kotori, # Fred N. van Kempen, @@ -44,7 +44,11 @@ WINDRES = windres.exe OPTS = -DWIN32 $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) +ifeq ($(VRAMDUMP), y) +DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP +else DFLAGS = -march=i686 -ggdb -DDEBUG +endif COPTIM = -Og else ifeq ($(OPTIM), y) @@ -66,9 +70,19 @@ AOPTIM = endif AFLAGS = -msse -msse2 \ -mfpmath=sse +ifeq ($(RELEASE), y) +CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ + -fomit-frame-pointer -mstackrealign -DRELEASE_BUILD +RFLAGS = --input-format=rc -O coff -DRELEASE_BUILD +else CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ -fomit-frame-pointer -mstackrealign +ifeq ($(VRAMDUMP), y) +RFLAGS = --input-format=rc -O coff -DENABLE_VRAM_DUMP +else RFLAGS = --input-format=rc -O coff +endif +endif ifeq ($(X64), y) PLATCG = codegen_x86-64.o @@ -125,7 +139,7 @@ SNDOBJ = sound.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ dbopl.o nukedopl.o openal.o \ - snd_speaker.o dac.o snd_ps1.o snd_pssj.o \ + snd_speaker.o snd_ps1.o snd_pssj.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ snd_emu8k.o snd_gus.o snd_opl.o \ diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 1b60e3068..aa4c944bd 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -270,7 +270,6 @@ void sound_poll(void *priv) if (sound_pos_global == SOUNDBUFLEN) { int c; -/* int16_t buf16[SOUNDBUFLEN * 2 ];*/ memset(outbuffer, 0, SOUNDBUFLEN * 2 * sizeof(int32_t)); @@ -278,19 +277,6 @@ void sound_poll(void *priv) sound_handlers[c].get_buffer(outbuffer, SOUNDBUFLEN, sound_handlers[c].priv); -/* for (c=0;c 32767) - buf16[c] = 32767; - else - buf16[c] = outbuffer[c]; - } - - if (!soundf) soundf=fopen("sound.pcm","wb"); - fwrite(buf16,(SOUNDBUFLEN)*2*2,1,soundf);*/ - for (c = 0; c < SOUNDBUFLEN * 2; c++) { outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 9feac48de..a597cbad8 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -2391,7 +2391,7 @@ static device_config_t s3_phoenix_trio64_config[] = } }, { - "card_id", "Card ID", CONFIG_SELECTION, "", 1, + "card_id", "Card ID", CONFIG_SELECTION, "", 0, { { "S3 Trio64", 0 diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index bb54d1498..80d5983cc 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -8,6 +8,9 @@ #include "../ibm.h" #include "../io.h" #include "../mem.h" +#ifdef ENABLE_VRAM_DUMP +#include "../rom.h" +#endif #include "../timer.h" #include "video.h" #include "vid_svga.h" @@ -916,6 +919,11 @@ void svga_poll(void *p) } } +#ifdef ENABLE_VRAM_DUMP +uint8_t *ext_vram; +int ext_memsize; +#endif + int svga_init(svga_t *svga, void *p, int memsize, void (*recalctimings_ex)(struct svga_t *svga), uint8_t (*video_in) (uint16_t addr, void *p), @@ -950,6 +958,10 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->dispofftime = 1000 * (1 << TIMER_SHIFT); svga->bpp = 8; svga->vram = malloc(memsize); +#ifdef ENABLE_VRAM_DUMP + ext_vram = svga->vram; + ext_memsize = memsize; +#endif svga->vram_limit = memsize; svga->vrammask = memsize - 1; svga->changedvram = malloc(/*(memsize >> 12) << 1*/memsize >> 12); @@ -1008,21 +1020,38 @@ void svga_write(uint32_t addr, uint8_t val, void *p) if (!(svga->gdcreg[6] & 1)) svga->fullchange=2; if (svga->chain4 || svga->fb_only) { + /* + 00000 -> writemask 1, addr 0 -> vram addr 00000 + 00001 -> writemask 2, addr 0 -> vram addr 00001 + 00002 -> writemask 4, addr 0 -> vram addr 00002 + 00003 -> writemask 8, addr 0 -> vram addr 00003 + 00004 -> writemask 1, addr 4 -> vram addr 00004 + 00005 -> writemask 2, addr 4 -> vram addr 00005 + 00006 -> writemask 4, addr 4 -> vram addr 00006 + 00007 -> writemask 8, addr 4 -> vram addr 00007 + */ writemask2=1<<(addr&3); addr&=~3; } else if (svga->chain2_write) { - if ((svga->gdcreg[6] & 0xC) == 0x4) +#if 0 + if (svga->oddeven_page) { - writemask2 &= (svga->oddeven_page ? ~0xe : ~0xb); + /* Odd/Even page is 1, mask out plane 2 or 3, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 8 : 4; } else { - writemask2 &= ~0xa; + /* Odd/Even page is 2, mask out plane 0 or 1, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 2 : 1; } +#endif + + writemask2 &= ~0xa; if (addr & 1) - writemask2 <<= 1; + writemask2 <<= 1; + addr &= ~1; addr <<= 2; } @@ -1212,7 +1241,12 @@ uint8_t svga_read(uint32_t addr, void *p) } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); + readplane = addr & 1; + if (svga->oddeven_page) + { + readplane |= 2; + } + addr &= ~1; addr <<= 2; } @@ -1275,16 +1309,23 @@ void svga_write_linear(uint32_t addr, uint8_t val, void *p) } else if (svga->chain2_write) { - if ((svga->gdcreg[6] & 0xC) == 0x4) +#if 0 + if (svga->oddeven_page) { - writemask2 &= (svga->oddeven_page ? ~0xe : ~0xb); + /* Odd/Even page is 1, mask out plane 2 or 3, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 8 : 4; } else { - writemask2 &= ~0xa; + /* Odd/Even page is 2, mask out plane 0 or 1, according to bit 0 of the address. */ + writemask2 &= (addr & 1) ? 2 : 1; } +#endif + + writemask2 &= ~0xa; if (addr & 1) writemask2 <<= 1; + addr &= ~1; addr <<= 2; } @@ -1469,7 +1510,12 @@ uint8_t svga_read_linear(uint32_t addr, void *p) } else if (svga->chain2_read) { - readplane = (readplane & 2) | (addr & 1); + readplane = addr & 1; + if (svga->oddeven_page) + { + readplane |= 2; + } + addr &= ~1; addr <<= 2; } @@ -1816,6 +1862,28 @@ uint32_t svga_readl_linear(uint32_t addr, void *p) } +#ifdef ENABLE_VRAM_DUMP +void svga_dump_vram() +{ + FILE *f; + + if (ext_vram == NULL) + { + return; + } + + f = nvrfopen(L"svga_vram.dmp", L"wb"); + if (f == NULL) + { + return; + } + + fwrite(ext_vram, ext_memsize, 1, f); + + fclose(f); +} +#endif + void svga_add_status_info(char *s, int max_len, void *p) { svga_t *svga = (svga_t *)p; diff --git a/src/VIDEO/video.h b/src/VIDEO/video.h index 83e50bc1d..7054c33b3 100644 --- a/src/VIDEO/video.h +++ b/src/VIDEO/video.h @@ -121,3 +121,7 @@ void video_updatetiming(); void hline(BITMAP *b, int x1, int y, int x2, uint32_t col); void updatewindowsize(int x, int y); + +#ifdef ENABLE_VRAM_DUMP +void svga_dump_vram(); +#endif diff --git a/src/amstrad.c b/src/amstrad.c index c1f0ef763..a6dacab9c 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -15,7 +15,7 @@ uint8_t amstrad_read(uint16_t port, void *priv) switch (port) { case 0x379: - return 7 | readdacfifo(); + return 7; case 0x37a: if (romset == ROM_PC1512) return 0x20; if (romset == ROM_PC200) return 0x80; diff --git a/src/dac.c b/src/dac.c deleted file mode 100644 index 7aecf02f5..000000000 --- a/src/dac.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "dac.h" - -uint8_t dac,dac2; -uint8_t dacctrl; -int lptfifo; -uint8_t dssbuffer[16]; -int dssstart=0,dssend=0; -int dssmode=0; - -void writedac(uint16_t addr, uint8_t val) -{ - if (dssmode) dac2=val; - else dac=val; -} - -void writedacctrl(uint16_t addr, uint8_t val) -{ - if (dacctrl&8 && !(val&8) && (lptfifo!=16)) - { - dssbuffer[dssend++]=dac2; - dssend&=15; - lptfifo++; - } - dacctrl=val; -} - -uint8_t readdacfifo() -{ - if (lptfifo==16) return 0x40; - return 0; -} - -void pollss() -{ - if (lptfifo) - { - dac=dssbuffer[dssstart++]; - dssstart&=15; - lptfifo--; - } -} - -int16_t dacbuffer[SOUNDBUFLEN+20]; -int dacbufferpos=0; -void getdacsamp() -{ - if (dacbufferposSOUNDBUFLEN) dacbufferpos=SOUNDBUFLEN; - for (c=0;c Date: Sun, 7 May 2017 02:14:44 -0400 Subject: [PATCH 168/392] Removed ALLEGRO, per Kotori's OK. Fixed serial driver, re-worked API and updated other files accordingly. Fixed serial mouse driver for new serial port, prepared for Mouse Systems mode. --- src/Makefile.mingw | 2 +- src/allegro-gui-configure.c | 639 ------------------------- src/allegro-gui-deviceconfig.c | 306 ------------ src/allegro-gui-hdconf.c | 516 -------------------- src/allegro-gui.c | 229 --------- src/allegro-gui.h | 15 - src/allegro-joystick.c | 52 -- src/allegro-keyboard.c | 52 -- src/allegro-main.c | 172 ------- src/allegro-main.h | 22 - src/allegro-midi.c | 48 -- src/allegro-mouse.c | 34 -- src/allegro-video.c | 130 ----- src/allegro-video.h | 6 - src/fdc37c665.c | 30 +- src/fdc37c669.c | 32 +- src/fdc37c932fr.c | 12 +- src/model.c | 6 +- src/mouse_serial.c | 71 +-- src/mouse_serial.h | 28 +- src/pc.c | 48 +- src/pc87306.c | 56 +-- src/ps1.c | 16 +- src/ps2.c | 8 +- src/ps2_mca.c | 28 +- src/serial.c | 838 +++++++++++++++++++++++---------- src/serial.h | 87 ++-- src/sis85c471.c | 8 +- src/um8669f.c | 16 +- src/w83877f.c | 20 +- src/wd76c10.c | 16 +- src/win-serial.c | 2 +- src/win-serial.h | 53 --- 33 files changed, 858 insertions(+), 2740 deletions(-) delete mode 100644 src/allegro-gui-configure.c delete mode 100644 src/allegro-gui-deviceconfig.c delete mode 100644 src/allegro-gui-hdconf.c delete mode 100644 src/allegro-gui.c delete mode 100644 src/allegro-gui.h delete mode 100644 src/allegro-joystick.c delete mode 100644 src/allegro-keyboard.c delete mode 100644 src/allegro-main.c delete mode 100644 src/allegro-main.h delete mode 100644 src/allegro-midi.c delete mode 100644 src/allegro-mouse.c delete mode 100644 src/allegro-video.c delete mode 100644 src/allegro-video.h delete mode 100644 src/win-serial.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 783447992..d6b69b774 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -180,7 +180,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ # Build rules. %.o: %.c @echo $< - $(CC) $(CFLAGS) -c $< + @$(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< diff --git a/src/allegro-gui-configure.c b/src/allegro-gui-configure.c deleted file mode 100644 index dd7c50b2a..000000000 --- a/src/allegro-gui-configure.c +++ /dev/null @@ -1,639 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "cpu.h" -#include "fdd.h" -#include "gameport.h" -#include "model.h" -#include "sound.h" -#include "video.h" -#include "vid_voodoo.h" - -static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; -static int settings_sound_to_list[20], settings_list_to_sound[20]; - -typedef struct allegro_list_t -{ - char name[256]; - int num; -} allegro_list_t; - -static allegro_list_t model_list[ROM_MAX+1]; -static allegro_list_t video_list[GFX_MAX+1]; -static allegro_list_t sound_list[GFX_MAX+1]; -static allegro_list_t cpumanu_list[4]; -static allegro_list_t cpu_list[32]; -static allegro_list_t joystick_list[32]; - -static char mem_size_str[10], mem_size_units[3]; - -static allegro_list_t cache_list[] = -{ - {"A little", 0}, - {"A bit", 1}, - {"Some", 2}, - {"A lot", 3}, - {"Infinite", 4}, - {"", -1} -}; - -static allegro_list_t vidspeed_list[] = -{ - {"8-bit", 0}, - {"Slow 16-bit", 1}, - {"Fast 16-bit", 2}, - {"Slow VLB/PCI", 3}, - {"Mid VLB/PCI", 4}, - {"Fast VLB/PCI", 5}, - {"", -1} -}; - -static allegro_list_t fdd_list[] = -{ - {"None", 0}, - {"5.25\" 360k", 1}, - {"5.25\" 1.2M", 2}, - {"5.25\" 1.2M Dual RPM", 3}, - {"3.5\" 720k", 4}, - {"3.5\" 1.44M", 5}, - {"3.5\" 1.44M 3-Mode", 6}, - {"3.5\" 2.88M", 7}, - {"", -1} -}; - -static void reset_list(); - -static char *list_proc_model(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (model_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return model_list[index].name; -} - -static char *list_proc_video(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (video_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return video_list[index].name; -} - -static char *list_proc_cache(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (cache_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return cache_list[index].name; -} - -static char *list_proc_vidspeed(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (vidspeed_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return vidspeed_list[index].name; -} - -static char *list_proc_sound(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (sound_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return sound_list[index].name; -} - -static char *list_proc_cpumanu(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (cpumanu_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return cpumanu_list[index].name; -} - -static char *list_proc_cpu(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (cpu_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return cpu_list[index].name; -} - -static char *list_proc_fdd(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (fdd_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return fdd_list[index].name; -} - -static char *list_proc_joystick(int index, int *list_size) -{ - if (index < 0) - { - int c = 0; - - while (joystick_list[c].name[0]) - c++; - - *list_size = c; - return NULL; - } - - return joystick_list[index].name; -} - -static int voodoo_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - deviceconfig_open(&voodoo_device); - return D_O_K; - } - - return ret; -} - - -static int video_config_proc(int msg, DIALOG *d, int c); -static int sound_config_proc(int msg, DIALOG *d, int c); -static int list_proc(int msg, DIALOG *d, int c); - -static DIALOG configure_dialog[] = -{ - {d_shadow_box_proc, 0, 0, 568,352,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 226, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 296, 328, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {list_proc, 70*2, 12, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_model, 0, 0}, - - {list_proc, 70*2, 32, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_video, 0, 0}, - - {list_proc, 70*2, 52, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpumanu, 0, 0}, //5 - {list_proc, 70*2, 72, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cpu, 0, 0}, - {d_list_proc, 70*2, 112, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_cache, 0, 0}, - {d_list_proc, 70*2, 132, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_vidspeed, 0, 0}, - {list_proc, 70*2, 152, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_sound, 0, 0}, //9 - - {d_edit_proc, 70*2, 236, 32, 14, 0, 0xffffff, 0, 0, 3, 0, mem_size_str, 0, 0}, - - {d_text_proc, 98*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, mem_size_units, 0, 0}, - - {d_check_proc, 14*2, 252, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "CMS / Game Blaster", 0, 0}, - {d_check_proc, 14*2, 268, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Gravis Ultrasound", 0, 0}, - {d_check_proc, 14*2, 284, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Innovation SSI-2001", 0, 0}, - {d_check_proc, 14*2, 300, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Composite CGA", 0, 0}, - {d_check_proc, 14*2, 316, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Voodoo Graphics", 0, 0}, - - {d_text_proc, 16*2, 16, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Machine :", 0, 0}, - {d_text_proc, 16*2, 36, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video :", 0, 0}, - {d_text_proc, 16*2, 56, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU type :", 0, 0}, - {d_text_proc, 16*2, 76, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "CPU :", 0, 0}, - {d_text_proc, 16*2, 116, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Cache :", 0, 0}, - {d_text_proc, 16*2, 136, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Video speed :", 0, 0}, - {d_text_proc, 16*2, 156, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Soundcard :", 0, 0}, - {d_text_proc, 16*2, 236, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Memory :", 0, 0}, - - {d_check_proc, 14*2, 92, 118*2, 10, 0, 0xffffff, 0, 0, 0, 0, "Dynamic Recompiler", 0, 0}, - - {d_text_proc, 16*2, 176, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive A: :", 0, 0}, - {d_text_proc, 16*2, 196, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Drive B: :", 0, 0}, - {d_list_proc, 70*2, 172, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0}, - {d_list_proc, 70*2, 192, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_fdd, 0, 0}, - - {video_config_proc, 452, 32+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, //30 - {sound_config_proc, 452, 152+4, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - {voodoo_config_proc, 452, 316, 100, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Configure...", 0, 0}, - - {d_text_proc, 16*2, 216, 40, 10, 0, 0xffffff, 0, 0, 0, 0, "Joystick :", 0, 0}, - {d_list_proc, 70*2, 212, 152*2, 20, 0, 0xffffff, 0, 0, 0, 0, list_proc_joystick, 0, 0}, //34 - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int list_proc(int msg, DIALOG *d, int c) -{ - int old = d->d1; - int ret = d_list_proc(msg, d, c); - - if (d->d1 != old) - { - int new_model = model_list[configure_dialog[3].d1].num; - int new_cpu_m = configure_dialog[5].d1; - int new_cpu = configure_dialog[6].d1; - int new_dynarec = configure_dialog[25].flags & D_SELECTED; - int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num); - int new_mem_size; - int cpu_flags; - - reset_list(); - - if (models[new_model].fixed_gfxcard) - configure_dialog[4].flags |= D_DISABLED; - else - configure_dialog[4].flags &= ~D_DISABLED; - - cpu_flags = models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_flags; - configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && new_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - configure_dialog[25].flags |= D_DISABLED; - - sscanf(mem_size_str, "%i", &new_mem_size); - new_mem_size &= ~(models[new_model].ram_granularity - 1); - if (new_mem_size < models[new_model].min_ram) - new_mem_size = models[new_model].min_ram; - else if (new_mem_size > models[new_model].max_ram) - new_mem_size = models[new_model].max_ram; - sprintf(mem_size_str, "%i", new_mem_size); - - if (models[new_model].is_at) - sprintf(mem_size_units, "MB"); - else - sprintf(mem_size_units, "kB"); - - if (!video_card_has_config(new_gfxcard)) - configure_dialog[30].flags |= D_DISABLED; - else - configure_dialog[30].flags &= ~D_DISABLED; - - if (!sound_card_has_config(configure_dialog[9].d1)) - configure_dialog[31].flags |= D_DISABLED; - else - configure_dialog[31].flags &= ~D_DISABLED; - - return D_REDRAW; - } - - return ret; -} - -static int video_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - int new_gfxcard = video_old_to_new(video_list[configure_dialog[4].d1].num); - - deviceconfig_open(video_card_getdevice(new_gfxcard)); - return D_O_K; - } - - return ret; -} -static int sound_config_proc(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_CLOSE) - { - int new_sndcard = sound_list[configure_dialog[9].d1].num; - - deviceconfig_open(sound_card_getdevice(new_sndcard)); - return D_O_K; - } - - return ret; -} - -static void reset_list() -{ - int model = model_list[configure_dialog[3].d1].num; - int cpumanu = configure_dialog[5].d1; - int cpu = configure_dialog[6].d1; - int c; - - memset(cpumanu_list, 0, sizeof(cpumanu_list)); - memset(cpu_list, 0, sizeof(cpu_list)); - - c = 0; - while (models[model].cpu[c].cpus != NULL && c < 3) - { - strcpy(cpumanu_list[c].name, models[model].cpu[c].name); - cpumanu_list[c].num = c; - c++; - } - - if (cpumanu >= c) - cpumanu = configure_dialog[6].d1 = c-1; - - c = 0; - while (models[model].cpu[cpumanu].cpus[c].cpu_type != -1) - { - strcpy(cpu_list[c].name, models[model].cpu[cpumanu].cpus[c].name); - cpu_list[c].num = c; - c++; - } - - if (cpu >= c) - cpu = configure_dialog[7].d1 = c-1; -} - -int settings_configure() -{ - int c, d; - int cpu_flags; - - memset(model_list, 0, sizeof(model_list)); - memset(video_list, 0, sizeof(video_list)); - memset(sound_list, 0, sizeof(sound_list)); - - for (c = 0; c < ROM_MAX; c++) - romstolist[c] = 0; - c = d = 0; - while (models[c].id != -1) - { - pclog("INITDIALOG : %i %i %i\n",c,models[c].id,romspresent[models[c].id]); - if (romspresent[models[c].id]) - { - strcpy(model_list[d].name, models[c].name); - model_list[d].num = c; - if (c == model) - configure_dialog[3].d1 = d; - d++; - } - c++; - } - - if (models[model].fixed_gfxcard) - configure_dialog[4].flags |= D_DISABLED; - else - configure_dialog[4].flags &= ~D_DISABLED; - - c = d = 0; - while (1) - { - char *s = video_card_getname(c); - - if (!s[0]) - break; -pclog("video_card_available : %i\n", c); - if (video_card_available(c)) - { - strcpy(video_list[d].name, video_card_getname(c)); - video_list[d].num = video_new_to_old(c); - if (video_new_to_old(c) == gfxcard) - configure_dialog[4].d1 = d; - d++; - } - - c++; - } - - if (!video_card_has_config(video_old_to_new(gfxcard))) - configure_dialog[30].flags |= D_DISABLED; - else - configure_dialog[30].flags &= ~D_DISABLED; - - c = d = 0; - while (1) - { - char *s = sound_card_getname(c); - - if (!s[0]) - break; - - if (sound_card_available(c)) - { - strcpy(sound_list[d].name, sound_card_getname(c)); - sound_list[d].num = c; - if (c == sound_card_current) - configure_dialog[9].d1 = d; - d++; - } - - c++; - } - - c = 0; - while (joystick_get_name(c)) - { - strcpy(joystick_list[c].name, joystick_get_name(c)); - if (c == joystick_type) - configure_dialog[34].d1 = c; - - c++; - } - - if (!sound_card_has_config(configure_dialog[9].d1)) - configure_dialog[31].flags |= D_DISABLED; - else - configure_dialog[31].flags &= ~D_DISABLED; - - configure_dialog[5].d1 = cpu_manufacturer; - configure_dialog[6].d1 = cpu; - configure_dialog[7].d1 = cache; - configure_dialog[8].d1 = video_speed; - reset_list(); -// strcpy(cpumanu_str, models[romstomodel[romset]].cpu[cpu_manufacturer].name); -// strcpy(cpu_str, models[romstomodel[romset]].cpu[cpu_manufacturer].cpus[cpu].name); -// strcpy(cache_str, cache_str_list[cache]); -// strcpy(vidspeed_str, vidspeed_str_list[video_speed]); - -// strcpy(soundcard_str, sound_card_getname(sound_card_current)); - - if (GAMEBLASTER) - configure_dialog[12].flags |= D_SELECTED; - else - configure_dialog[12].flags &= ~D_SELECTED; - - if (GUS) - configure_dialog[13].flags |= D_SELECTED; - else - configure_dialog[13].flags &= ~D_SELECTED; - - if (SSI2001) - configure_dialog[14].flags |= D_SELECTED; - else - configure_dialog[14].flags &= ~D_SELECTED; - - if (cga_comp) - configure_dialog[15].flags |= D_SELECTED; - else - configure_dialog[15].flags &= ~D_SELECTED; - - if (voodoo_enabled) - configure_dialog[16].flags |= D_SELECTED; - else - configure_dialog[16].flags &= ~D_SELECTED; - - if (models[model].is_at) - sprintf(mem_size_str, "%i", mem_size / 1024); - else - sprintf(mem_size_str, "%i", mem_size); - - if (models[model].is_at) - sprintf(mem_size_units, "MB"); - else - sprintf(mem_size_units, "kB"); - - cpu_flags = models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_flags; - configure_dialog[25].flags = (((cpu_flags & CPU_SUPPORTS_DYNAREC) && cpu_use_dynarec) || (cpu_flags & CPU_REQUIRES_DYNAREC)) ? D_SELECTED : 0; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - configure_dialog[25].flags |= D_DISABLED; - - configure_dialog[28].d1 = fdd_get_type(0); - configure_dialog[29].d1 = fdd_get_type(1); - - while (1) - { - position_dialog(configure_dialog, SCREEN_W/2 - configure_dialog[0].w/2, SCREEN_H/2 - configure_dialog[0].h/2); - - c = popup_dialog(configure_dialog, 1); - - position_dialog(configure_dialog, -(SCREEN_W/2 - configure_dialog[0].w/2), -(SCREEN_H/2 - configure_dialog[0].h/2)); - - if (c == 1) - { - int new_model = model_list[configure_dialog[3].d1].num; - int new_gfxcard = video_list[configure_dialog[4].d1].num; - int new_sndcard = sound_list[configure_dialog[9].d1].num; - int new_cpu_m = configure_dialog[5].d1; - int new_cpu = configure_dialog[6].d1; - int new_mem_size; - int new_has_fpu = (models[new_model].cpu[new_cpu_m].cpus[new_cpu].cpu_type >= CPU_i486DX) ? 1 : 0; - int new_GAMEBLASTER = (configure_dialog[12].flags & D_SELECTED) ? 1 : 0; - int new_GUS = (configure_dialog[13].flags & D_SELECTED) ? 1 : 0; - int new_SSI2001 = (configure_dialog[14].flags & D_SELECTED) ? 1 : 0; - int new_voodoo = (configure_dialog[16].flags & D_SELECTED) ? 1 : 0; - int new_dynarec = (configure_dialog[25].flags & D_SELECTED) ? 1 : 0; - int new_fda = configure_dialog[28].d1; - int new_fdb = configure_dialog[29].d1; - - sscanf(mem_size_str, "%i", &new_mem_size); - new_mem_size &= ~(models[new_model].ram_granularity - 1); - if (new_mem_size < models[new_model].min_ram) - new_mem_size = models[new_model].min_ram; - else if (new_mem_size > models[new_model].max_ram) - new_mem_size = models[new_model].max_ram; - if (models[new_model].is_at) - new_mem_size *= 1024; - - if (new_model != model || new_gfxcard != gfxcard || new_mem_size != mem_size || - new_has_fpu != hasfpu || new_GAMEBLASTER != GAMEBLASTER || new_GUS != GUS || - new_SSI2001 != SSI2001 || new_sndcard != sound_card_current || new_voodoo != voodoo_enabled || - new_dynarec != cpu_use_dynarec || new_fda != fdd_get_type(0) || new_fdb != fdd_get_type(1)) - { - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1) - continue; - - model = new_model; - romset = model_getromset(); - gfxcard = new_gfxcard; - mem_size = new_mem_size; - cpu_manufacturer = new_cpu_m; - cpu = new_cpu; - GAMEBLASTER = new_GAMEBLASTER; - GUS = new_GUS; - SSI2001 = new_SSI2001; - sound_card_current = new_sndcard; - voodoo_enabled = new_voodoo; - cpu_use_dynarec = new_dynarec; - - mem_resize(); - loadbios(); - resetpchard(); - - fdd_set_type(0, new_fda); - fdd_set_type(1, new_fdb); - } - - video_speed = configure_dialog[8].d1; - - cga_comp = (configure_dialog[15].flags & D_SELECTED) ? 1 : 0; - - cpu_manufacturer = new_cpu_m; - cpu = new_cpu; - cpu_set(); - - cache = configure_dialog[7].d1; - mem_updatecache(); - - joystick_type = configure_dialog[34].d1; - gameport_update_joystick_type(); - - saveconfig(); - - speedchanged(); - - return D_O_K; - } - - if (c == 2) - return D_O_K; - } - - return D_O_K; -} - diff --git a/src/allegro-gui-deviceconfig.c b/src/allegro-gui-deviceconfig.c deleted file mode 100644 index 9dcbb5011..000000000 --- a/src/allegro-gui-deviceconfig.c +++ /dev/null @@ -1,306 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "config.h" - -static device_t *config_device; - -#define MAX_CONFIG_SIZE 64 -#define MAX_CONFIG_SELECTIONS 8 - -static device_config_selection_t *config_selections[MAX_CONFIG_SELECTIONS]; - -#define list_proc_device_func(i) \ - static char *list_proc_device_ ## i(int index, int *list_size) \ - { \ - device_config_selection_t *config = config_selections[i]; \ - \ - if (index < 0) \ - { \ - int c = 0; \ - \ - while (config[c].description[0]) \ - c++; \ - \ - *list_size = c; \ - return NULL; \ - } \ - \ - return config[index].description; \ - } - -list_proc_device_func(0) -list_proc_device_func(1) -list_proc_device_func(2) -list_proc_device_func(3) -list_proc_device_func(4) -list_proc_device_func(5) -list_proc_device_func(6) -list_proc_device_func(7) - -static DIALOG deviceconfig_dialog[MAX_CONFIG_SIZE] = -{ - {d_shadow_box_proc, 0, 0, 568,332,0,0xffffff,0,0, 0,0,0,0,0} // 0 -}; - -void deviceconfig_open(device_t *device) -{ - DIALOG *d; - device_config_t *config = device->config; - int y = 10; - int dialog_pos = 1; - int list_pos = 0; - int c; - int id_ok, id_cancel; - - memset((void *)((uintptr_t)deviceconfig_dialog) + sizeof(DIALOG), 0, sizeof(deviceconfig_dialog) - sizeof(DIALOG)); - deviceconfig_dialog[0].x = deviceconfig_dialog[0].y = 0; - - while (config->type != -1) - { - d = &deviceconfig_dialog[dialog_pos]; - - switch (config->type) - { - case CONFIG_BINARY: - d->x = 32; - d->y = y; - - d->w = 118*2; - d->h = 15; - - d->dp = config->description; - d->proc = d_check_proc; - - d->flags = config_get_int(device->name, config->name, config->default_int) ? D_SELECTED : 0; - d->bg = 0xffffff; - d->fg = 0; - - dialog_pos++; - - y += 20; - break; - - case CONFIG_SELECTION: - if (list_pos >= MAX_CONFIG_SELECTIONS) - break; - - d->x = 32; - d->y = y; - - d->w = 80; - d->h = 15; - - d->dp = config->description; - d->proc = d_text_proc; - - d->flags = 0; - d->bg = 0xffffff; - d->fg = 0; - - d++; - - d->x = 250; - d->y = y; - - d->w = 304; - d->h = 20; - - switch (list_pos) - { - case 0 : d->dp = list_proc_device_0; break; - case 1 : d->dp = list_proc_device_1; break; - case 2 : d->dp = list_proc_device_2; break; - case 3 : d->dp = list_proc_device_3; break; - case 4 : d->dp = list_proc_device_4; break; - case 5 : d->dp = list_proc_device_5; break; - case 6 : d->dp = list_proc_device_6; break; - case 7 : d->dp = list_proc_device_7; break; - } - d->proc = d_list_proc; - - d->flags = 0; - d->bg = 0xffffff; - d->fg = 0; - - config_selections[list_pos++] = config->selection; - - c = 0; - while (config->selection[c].description[0]) - { - if (config_get_int(device->name, config->name, config->default_int) == config->selection[c].value) - d->d1 = c; - c++; - } - - dialog_pos += 2; - - y += 20; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - d = &deviceconfig_dialog[dialog_pos]; - - id_ok = dialog_pos; - id_cancel = dialog_pos + 1; - - d->x = 226; - d->y = y+8; - - d->w = 50; - d->h = 16; - - d->dp = "OK"; - d->proc = d_button_proc; - - d->flags = D_EXIT; - d->bg = 0xffffff; - d->fg = 0; - - d++; - - d->x = 296; - d->y = y+8; - - d->w = 50; - d->h = 16; - - d->dp = "Cancel"; - d->proc = d_button_proc; - - d->flags = D_EXIT; - d->bg = 0xffffff; - d->fg = 0; - - deviceconfig_dialog[0].h = y + 28; - - config_device = device; - - while (1) - { - position_dialog(deviceconfig_dialog, SCREEN_W/2 - deviceconfig_dialog[0].w/2, SCREEN_H/2 - deviceconfig_dialog[0].h/2); - - c = popup_dialog(deviceconfig_dialog, 1); - - position_dialog(deviceconfig_dialog, -(SCREEN_W/2 - deviceconfig_dialog[0].w/2), -(SCREEN_H/2 - deviceconfig_dialog[0].h/2)); - - if (c == id_ok) - { - int changed = 0; - - dialog_pos = 1; - config = device->config; - - while (config->type != -1) - { - int val; - - d = &deviceconfig_dialog[dialog_pos]; - - switch (config->type) - { - case CONFIG_BINARY: - val = (d->flags & D_SELECTED) ? 1 : 0; - - if (val != config_get_int(device->name, config->name, config->default_int)) - changed = 1; - - dialog_pos++; - break; - - case CONFIG_SELECTION: - if (list_pos >= MAX_CONFIG_SELECTIONS) - break; - - d++; - - val = config->selection[d->d1].value; - - if (val != config_get_int(device->name, config->name, config->default_int)) - changed = 1; - - dialog_pos += 2; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - if (!changed) - return; - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) != 1) - continue; - - dialog_pos = 1; - config = device->config; - - while (config->type != -1) - { - int val; - - d = &deviceconfig_dialog[dialog_pos]; - - switch (config->type) - { - case CONFIG_BINARY: - val = (d->flags & D_SELECTED) ? 1 : 0; - - config_set_int(config_device->name, config->name, val); - - dialog_pos++; - break; - - case CONFIG_SELECTION: - if (list_pos >= MAX_CONFIG_SELECTIONS) - break; - - d++; - - val = config->selection[d->d1].value; - - config_set_int(config_device->name, config->name, val); - - dialog_pos += 2; - break; - - case CONFIG_MIDI: - break; - } - - config++; - - if (dialog_pos >= MAX_CONFIG_SIZE-3) - break; - } - - saveconfig(); - - resetpchard(); - - return; - } - - if (c == id_cancel) - break; - } -} diff --git a/src/allegro-gui-hdconf.c b/src/allegro-gui-hdconf.c deleted file mode 100644 index a493c319f..000000000 --- a/src/allegro-gui-hdconf.c +++ /dev/null @@ -1,516 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE - -#include -#include "ibm.h" -#include "device.h" -#include "ide.h" -#include "allegro-main.h" -#include "allegro-gui.h" - -static char hd_path[4][260]; -static char hd_sectors[4][10]; -static char hd_heads[4][10]; -static char hd_cylinders[4][10]; -static char hd_size[4][20]; - -static char hd_path_new[260]; -static char hd_sectors_new[10]; -static char hd_heads_new[10]; -static char hd_cylinders_new[10]; -static char hd_size_new[20]; - -static int new_cdrom_channel; - -static hard_disk_t hdc_new[4]; - -static DIALOG hdparams_dialog[]= -{ - {d_shadow_box_proc, 0, 0, 194*2,86,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 126, 66, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 196, 66, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_text_proc, 7*2, 6, 170, 10, 0, 0xffffff, 0, 0, 0, 0, "Initial settings are based on file size", 0, 0}, - - {d_text_proc, 7*2, 22, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 22, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 22, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_edit_proc, 44*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 2, 0, hd_sectors_new, 0, 0}, - {d_edit_proc, 92*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 3, 0, hd_heads_new, 0, 0}, - {d_edit_proc, 168*2, 22, 24*2, 12, 0, 0xffffff, 0, 0, 5, 0, hd_cylinders_new, 0, 0}, - {d_text_proc, 7*2, 54, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size_new, 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int hdconf_open(int msg, DIALOG *d, int c) -{ - int drv = d->d2; - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - char fn[260]; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - - strcpy(fn, hd_path[drv]); - ret = file_select_ex("Please choose a disc image", fn, "IMG", 260, xsize, ysize); - if (ret) - { - uint64_t sz; - FILE *f = fopen64(fn, "rb"); - if (!f) - { - return D_REDRAW; - } - fseeko64(f, -1, SEEK_END); - sz = ftello64(f) + 1; - fclose(f); - sprintf(hd_sectors_new, "63"); - sprintf(hd_heads_new, "16"); - sprintf(hd_cylinders_new, "%i", (int)((sz / 512) / 16) / 63); - - while (1) - { - position_dialog(hdparams_dialog, SCREEN_W/2 - 186, SCREEN_H/2 - 86/2); - - ret = popup_dialog(hdparams_dialog, 1); - - position_dialog(hdparams_dialog, -(SCREEN_W/2 - 186), -(SCREEN_H/2 - 86/2)); - - if (ret == 1) - { - int spt, hpc, cyl; - sscanf(hd_sectors_new, "%i", &spt); - sscanf(hd_heads_new, "%i", &hpc); - sscanf(hd_cylinders_new, "%i", &cyl); - - if (spt > 63) - { - alert("Drive has too many sectors (maximum is 63)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (hpc > 128) - { - alert("Drive has too many heads (maximum is 128)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (cyl > 16383) - { - alert("Drive has too many cylinders (maximum is 16383)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - - hdc_new[drv].spt = spt; - hdc_new[drv].hpc = hpc; - hdc_new[drv].tracks = cyl; - - strcpy(hd_path[drv], fn); - sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt); - sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc); - sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks); - sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024); - - return D_REDRAW; - } - - if (ret == 2) - break; - } - } - - return D_REDRAW; - } - - return ret; -} - -static int hdconf_new_file(int msg, DIALOG *d, int c) -{ - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - char fn[260]; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - - strcpy(fn, hd_path_new); - ret = file_select_ex("Please choose a disc image", fn, "IMG", 260, xsize, ysize); - if (ret) - strcpy(hd_path_new, fn); - - return D_REDRAW; - } - - return ret; -} - -static DIALOG hdnew_dialog[]= -{ - {d_shadow_box_proc, 0, 0, 194*2,86,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 126, 66, 50, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 196, 66, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_edit_proc, 7*2, 6, 136*2, 10, 0, 0xffffff, 0, 0, 0, 0, hd_path_new, 0, 0}, - {hdconf_new_file, 143*2, 6, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "...", 0, 0}, - - {d_text_proc, 7*2, 22, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 22, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 22, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_edit_proc, 44*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 2, 0, hd_sectors_new, 0, 0}, - {d_edit_proc, 92*2, 22, 16*2, 12, 0, 0xffffff, 0, 0, 3, 0, hd_heads_new, 0, 0}, - {d_edit_proc, 168*2, 22, 24*2, 12, 0, 0xffffff, 0, 0, 5, 0, hd_cylinders_new, 0, 0}, -// {d_text_proc, 7*2, 54, 136, 12, 0, -1, 0, 0, 0, 0, hd_size_new, 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static int create_hd(char *fn, int cyl, int hpc, int spt) -{ - int c; - int e; - uint8_t buf[512]; - FILE *f = fopen64(hd_path_new, "wb"); - e = errno; - if (!f) - { - alert("Can't open file for write", NULL, NULL, "OK", NULL, 0, 0); - return -1; - } - memset(buf, 0, 512); - for (c = 0; c < (cyl * hpc * spt); c++) - { - fwrite(buf, 512, 1, f); - } - fclose(f); -} - -static int hdconf_new(int msg, DIALOG *d, int c) -{ - int drv = d->d2; - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - sprintf(hd_sectors_new, "63"); - sprintf(hd_heads_new, "16"); - sprintf(hd_cylinders_new, "511"); - strcpy(hd_path_new, ""); - - while (1) - { - position_dialog(hdnew_dialog, SCREEN_W/2 - 186, SCREEN_H/2 - 86/2); - - ret = popup_dialog(hdnew_dialog, 1); - - position_dialog(hdnew_dialog, -(SCREEN_W/2 - 186), -(SCREEN_H/2 - 86/2)); - - if (ret == 1) - { - int spt, hpc, cyl; - int c, d; - FILE *f; - uint8_t *buf; - - sscanf(hd_sectors_new, "%i", &spt); - sscanf(hd_heads_new, "%i", &hpc); - sscanf(hd_cylinders_new, "%i", &cyl); - - if (spt > 63) - { - alert("Drive has too many sectors (maximum is 63)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (hpc > 128) - { - alert("Drive has too many heads (maximum is 128)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (cyl > 16383) - { - alert("Drive has too many cylinders (maximum is 16383)", NULL, NULL, "OK", NULL, 0, 0); - continue; - } - if (create_hd(hd_path_new, cyl, hpc, spt)) - return D_REDRAW; - - alert("Remember to partition and format the new drive", NULL, NULL, "OK", NULL, 0, 0); - - hdc_new[drv].spt = spt; - hdc_new[drv].hpc = hpc; - hdc_new[drv].tracks = cyl; - - strcpy(hd_path[drv], hd_path_new); - sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt); - sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc); - sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks); - sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024); - - return D_REDRAW; - } - - if (ret == 2) - break; - } - - return D_REDRAW; - } - - return ret; -} - -static int hdconf_eject(int msg, DIALOG *d, int c) -{ - int drv = d->d2; - int ret = d_button_proc(msg, d, c); - - if (ret == D_EXIT) - { - hdc_new[drv].spt = 0; - hdc_new[drv].hpc = 0; - hdc_new[drv].tracks = 0; - strcpy(hd_path[drv], ""); - sprintf(hd_sectors[drv], "%i", hdc_new[drv].spt); - sprintf(hd_heads[drv], "%i", hdc_new[drv].hpc); - sprintf(hd_cylinders[drv], "%i", hdc_new[drv].tracks); - sprintf(hd_size[drv], "Size : %imb", (((((uint64_t)hdc_new[drv].tracks*(uint64_t)hdc_new[drv].hpc)*(uint64_t)hdc_new[drv].spt)*512)/1024)/1024); - - return D_REDRAW; - } - - return ret; -} - -static int hdconf_radio_hd(int msg, DIALOG *d, int c); -static int hdconf_radio_cd(int msg, DIALOG *d, int c); - -static DIALOG hdconf_dialog[]= -{ - {d_shadow_box_proc, 0, 0, 210*2,354,0,0xffffff,0,0, 0,0,0,0,0}, // 0 - - {d_button_proc, 150, 334, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "OK", 0, 0}, // 1 - {d_button_proc, 220, 334, 50, 16, 0, 0xffffff, 0, D_EXIT, 0, 0, "Cancel", 0, 0}, // 2 - - {d_text_proc, 7*2, 6, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "C:", 0, 0}, - {hdconf_radio_hd, 7*2, 22, 96, 12, 0, 0xffffff, 0, D_EXIT, 0, 0, "Hard drive", 0, 0}, // 4 - {hdconf_radio_cd, 100*2, 22, 64, 12, 0, 0xffffff, 0, D_EXIT, 0, 0, "CD-ROM", 0, 0}, // 5 - {d_edit_proc, 7*2, 38, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[0], 0, 0}, - {hdconf_open, 143*2, 38, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "...", 0, 0}, - {hdconf_new, 159*2, 38, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "New", 0, 0}, - {hdconf_eject, 183*2, 38, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 0, "Eject", 0, 0}, - - {d_text_proc, 7*2, 54, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 54, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 54, 28, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_edit_proc, 44*2, 54, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[0], 0, 0}, - {d_edit_proc, 92*2, 54, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[0], 0, 0}, - {d_edit_proc, 168*2, 54, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[0], 0, 0}, - {d_text_proc, 7*2, 54, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[0], 0, 0}, - - {d_text_proc, 7*2, 76, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "D:", 0, 0}, - {hdconf_radio_hd, 7*2, 92, 96, 12, 0, 0xffffff, 0, D_EXIT, 1, 0, "Hard drive", 0, 0}, // 18 - {hdconf_radio_cd, 100*2, 92, 64, 12, 0, 0xffffff, 0, D_EXIT, 1, 0, "CD-ROM", 0, 0}, // 19 - {d_edit_proc, 7*2, 108, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[1], 0, 0}, - {hdconf_open, 143*2, 108, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "...", 0, 0}, - {hdconf_new, 159*2, 108, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "New", 0, 0}, - {hdconf_eject, 183*2, 108, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 1, "Eject", 0, 0}, - - {d_edit_proc, 44*2, 124, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[1], 0, 0}, - {d_edit_proc, 92*2, 124, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[1], 0, 0}, - {d_edit_proc, 168*2, 124, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[1], 0, 0}, - {d_text_proc, 7*2, 124, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 124, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 124, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_text_proc, 7*2, 140, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[1], 0, 0}, - - {d_text_proc, 7*2, 162, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "E:", 0, 0}, - {hdconf_radio_hd, 7*2, 178, 96, 12, 0, 0xffffff, 0, D_EXIT, 2, 0, "Hard drive", 0, 0}, // 32 - {hdconf_radio_cd, 100*2, 178, 64, 12, 0, 0xffffff, 0, D_EXIT, 2, 0, "CD-ROM", 0, 0}, // 33 - {d_edit_proc, 7*2, 194, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[2], 0, 0}, - {hdconf_open, 143*2, 194, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "...", 0, 0}, - {hdconf_new, 159*2, 194, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "New", 0, 0}, - {hdconf_eject, 183*2, 194, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 2, "Eject", 0, 0}, - - {d_edit_proc, 44*2, 210, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[2], 0, 0}, - {d_edit_proc, 92*2, 210, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[2], 0, 0}, - {d_edit_proc, 168*2, 210, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[2], 0, 0}, - {d_text_proc, 7*2, 210, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 210, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 210, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_text_proc, 7*2, 226, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[2], 0, 0}, - - {d_text_proc, 7*2, 248, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "F:", 0, 0}, - {hdconf_radio_hd, 7*2, 264, 96, 12, 0, 0xffffff, 0, D_EXIT, 3, 0, "Hard drive", 0, 0}, // 46 - {hdconf_radio_cd, 100*2, 264, 64, 12, 0, 0xffffff, 0, D_EXIT, 3, 0, "CD-ROM", 0, 0}, // 47 - {d_edit_proc, 7*2, 280, 136*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_path[3], 0, 0}, - {hdconf_open, 143*2, 280, 16*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "...", 0, 0}, - {hdconf_new, 159*2, 280, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "New", 0, 0}, - {hdconf_eject, 183*2, 280, 24*2, 14, 0, 0xffffff, 0, D_EXIT, 0, 3, "Eject", 0, 0}, - - {d_edit_proc, 44*2, 296, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_sectors[3], 0, 0}, - {d_edit_proc, 92*2, 296, 16*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_heads[3], 0, 0}, - {d_edit_proc, 168*2, 296, 24*2, 12, 0, 0xffffff, 0, D_DISABLED, 0, 0, hd_cylinders[3], 0, 0}, - {d_text_proc, 7*2, 296, 27, 10, 0, 0xffffff, 0, 0, 0, 0, "Sectors:", 0, 0}, - {d_text_proc, 63*2, 296, 29, 8, 0, 0xffffff, 0, 0, 0, 0, "Heads:", 0, 0}, - {d_text_proc, 120*2, 296, 32, 12, 0, 0xffffff, 0, 0, 0, 0, "Cylinders:", 0, 0}, - {d_text_proc, 7*2, 312, 136, 12, 0, 0xffffff, 0, 0, 0, 0, hd_size[3], 0, 0}, - - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -static void update_hdd_cdrom() -{ - if (new_cdrom_channel == 0) - { - hdconf_dialog[4].flags &= ~D_SELECTED; - hdconf_dialog[5].flags |= D_SELECTED; - } - else - { - hdconf_dialog[4].flags |= D_SELECTED; - hdconf_dialog[5].flags &= ~D_SELECTED; - } - if (new_cdrom_channel == 1) - { - hdconf_dialog[18].flags &= ~D_SELECTED; - hdconf_dialog[19].flags |= D_SELECTED; - } - else - { - hdconf_dialog[18].flags |= D_SELECTED; - hdconf_dialog[19].flags &= ~D_SELECTED; - } - if (new_cdrom_channel == 2) - { - hdconf_dialog[32].flags &= ~D_SELECTED; - hdconf_dialog[33].flags |= D_SELECTED; - } - else - { - hdconf_dialog[32].flags |= D_SELECTED; - hdconf_dialog[33].flags &= ~D_SELECTED; - } - if (new_cdrom_channel == 3) - { - hdconf_dialog[46].flags &= ~D_SELECTED; - hdconf_dialog[47].flags |= D_SELECTED; - } - else - { - hdconf_dialog[46].flags |= D_SELECTED; - hdconf_dialog[47].flags &= ~D_SELECTED; - } -} - -static int hdconf_radio_hd(int msg, DIALOG *d, int c) -{ - int ret = d_radio_proc(msg, d, c); - - if (ret == D_CLOSE) - { - if (new_cdrom_channel == d->d1) - { - new_cdrom_channel = -1; - update_hdd_cdrom(); - } - - return D_REDRAW; - } - - return ret; -} -static int hdconf_radio_cd(int msg, DIALOG *d, int c) -{ - int ret = d_radio_proc(msg, d, c); - - if (ret == D_CLOSE) - { - if (new_cdrom_channel != d->d1) - { - new_cdrom_channel = d->d1; - update_hdd_cdrom(); - } - - return D_REDRAW; - } - - return ret; -} - -int disc_hdconf() -{ - int c; - int changed=0; - - hdc_new[0] = hdc[0]; - hdc_new[1] = hdc[1]; - hdc_new[2] = hdc[2]; - hdc_new[3] = hdc[3]; - strcpy(hd_path[0], ide_fn[0]); - strcpy(hd_path[1], ide_fn[1]); - strcpy(hd_path[2], ide_fn[2]); - strcpy(hd_path[3], ide_fn[3]); - sprintf(hd_sectors[0], "%i", hdc[0].spt); - sprintf(hd_sectors[1], "%i", hdc[1].spt); - sprintf(hd_sectors[2], "%i", hdc[2].spt); - sprintf(hd_sectors[3], "%i", hdc[3].spt); - sprintf(hd_heads[0], "%i", hdc[0].hpc); - sprintf(hd_heads[1], "%i", hdc[1].hpc); - sprintf(hd_heads[2], "%i", hdc[2].hpc); - sprintf(hd_heads[3], "%i", hdc[3].hpc); - sprintf(hd_cylinders[0], "%i", hdc[0].tracks); - sprintf(hd_cylinders[1], "%i", hdc[1].tracks); - sprintf(hd_cylinders[2], "%i", hdc[2].tracks); - sprintf(hd_cylinders[3], "%i", hdc[3].tracks); - sprintf(hd_size[0], "Size : %imb", (((((uint64_t)hdc[0].tracks*(uint64_t)hdc[0].hpc)*(uint64_t)hdc[0].spt)*512)/1024)/1024); - sprintf(hd_size[1], "Size : %imb", (((((uint64_t)hdc[1].tracks*(uint64_t)hdc[1].hpc)*(uint64_t)hdc[1].spt)*512)/1024)/1024); - sprintf(hd_size[2], "Size : %imb", (((((uint64_t)hdc[2].tracks*(uint64_t)hdc[2].hpc)*(uint64_t)hdc[2].spt)*512)/1024)/1024); - sprintf(hd_size[3], "Size : %imb", (((((uint64_t)hdc[3].tracks*(uint64_t)hdc[3].hpc)*(uint64_t)hdc[3].spt)*512)/1024)/1024); - - new_cdrom_channel = cdrom_channel; - - update_hdd_cdrom(); - - while (1) - { - position_dialog(hdconf_dialog, SCREEN_W/2 - hdconf_dialog[0].w/2, SCREEN_H/2 - hdconf_dialog[0].h/2); - - c = popup_dialog(hdconf_dialog, 1); - - position_dialog(hdconf_dialog, -(SCREEN_W/2 - hdconf_dialog[0].w/2), -(SCREEN_H/2 - hdconf_dialog[0].h/2)); - - if (c == 1) - { - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - hdc[0] = hdc_new[0]; - hdc[1] = hdc_new[1]; - hdc[2] = hdc_new[2]; - hdc[3] = hdc_new[3]; - - strcpy(ide_fn[0], hd_path[0]); - strcpy(ide_fn[1], hd_path[1]); - strcpy(ide_fn[2], hd_path[2]); - strcpy(ide_fn[3], hd_path[3]); - - cdrom_channel = new_cdrom_channel; - - saveconfig(); - - resetpchard(); - - return D_O_K; - } - } - if (c == 2) - return D_O_K; - } - - return D_O_K; -} diff --git a/src/allegro-gui.c b/src/allegro-gui.c deleted file mode 100644 index 63b6ddef8..000000000 --- a/src/allegro-gui.c +++ /dev/null @@ -1,229 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "device.h" -#include "allegro-main.h" -#include "allegro-gui.h" -#include "disc.h" -#include "ide.h" - -static int file_return(void) -{ - return D_CLOSE; -} - -static int file_exit(void) -{ - quited = 1; - return D_CLOSE; -} - -static int file_reset(void) -{ - resetpchard(); - return D_CLOSE; -} - -static int file_cad(void) -{ - resetpc_cad(); - return D_CLOSE; -} - - -static MENU file_menu[]= -{ - {"&Return", file_return, NULL, 0, NULL}, - {"&Hard Reset", file_reset, NULL, 0, NULL}, - {"&Ctrl+Alt+Del", file_cad, NULL, 0, NULL}, - {"E&xit", file_exit, NULL, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static int disc_load_a() -{ - char fn[260]; - int ret; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - strcpy(fn, discfns[0]); - ret = file_select_ex("Please choose a disc image", fn, "IMG;IMA;FDI", 260, xsize, ysize); - if (ret) - { - disc_close(0); - disc_load(0, fn); - saveconfig(); - } - return D_O_K; -} - -static int disc_load_b() -{ - char fn[260]; - int ret; - int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - strcpy(fn, discfns[1]); - ret = file_select_ex("Please choose a disc image", fn, "IMG;IMA;FDI", 260, xsize, ysize); - if (ret) - { - disc_close(1); - disc_load(1, fn); - saveconfig(); - } - return D_O_K; -} - -static int disc_eject_a() -{ - disc_close(0); - saveconfig(); - - return D_O_K; -} - -static int disc_eject_b() -{ - disc_close(1); - saveconfig(); - - return D_O_K; -} - -static MENU disc_menu[]= -{ - {"Load drive &A:...", disc_load_a, NULL, 0, NULL}, - {"Load drive &B:...", disc_load_b, NULL, 0, NULL}, - {"&Eject drive &A:", disc_eject_a, NULL, 0, NULL}, - {"Eject drive &B:", disc_eject_b, NULL, 0, NULL}, - {"&Configure hard discs...", disc_hdconf, NULL, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static MENU cdrom_menu[]; - -static void cdrom_update() -{ - int c; - - for (c = 0; cdrom_menu[c].text; c++) - cdrom_menu[c].flags = 0; - - if (!cdrom_enabled) - cdrom_menu[0].flags = D_SELECTED; - else - cdrom_menu[1].flags = D_SELECTED; - - return D_O_K; -} - -static int cdrom_disabled() -{ - if (!cdrom_enabled) - return D_O_K; - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - atapi->exit(); - cdrom_enabled = 0; - saveconfig(); - resetpchard(); - cdrom_update(); - } - - return D_O_K; -} - -static int cdrom_empty() -{ - if (cdrom_enabled) - { - atapi->exit(); - cdrom_drive = -1; - cdrom_null_open(cdrom_drive); - return D_O_K; - } - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - cdrom_drive = -1; - cdrom_enabled = 1; - cdrom_null_open(cdrom_drive); - saveconfig(); - resetpchard(); - cdrom_update(); - } -} - -static int cdrom_dev() -{ - if (cdrom_enabled) - { - atapi->exit(); - cdrom_drive = 1; - ioctl_open(cdrom_drive); - return D_O_K; - } - - if (alert("This will reset 86Box!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) - { - cdrom_drive = 1; - cdrom_enabled = 1; - ioctl_open(cdrom_drive); - saveconfig(); - resetpchard(); - cdrom_update(); - } -} - -static MENU cdrom_menu[] = -{ - {"&Disabled", cdrom_disabled, NULL, 0, NULL}, - {"&Empty", cdrom_empty, NULL, 0, NULL}, - {"/dev/cdrom", cdrom_dev, NULL, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static MENU settings_menu[]= -{ - {"&Configure...", settings_configure, NULL, 0, NULL}, - {"CD-ROM", NULL, cdrom_menu, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static MENU main_menu[]= -{ - {"&File", NULL, file_menu, 0, NULL}, - {"&Disc", NULL, disc_menu, 0, NULL}, - {"&Settings", NULL, settings_menu, 0, NULL}, - {NULL,NULL,NULL,0,NULL} -}; - -static DIALOG main_windows_gui[]= -{ - {d_menu_proc, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, main_menu, NULL, NULL}, - {d_yield_proc, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, NULL, NULL, NULL}, - {0,0,0,0,0,0,0,0,0,0,0,NULL,NULL,NULL} -}; - -void gui_enter() -{ - DIALOG_PLAYER *dp; - int x = 1; - infocus = 0; - - dp = init_dialog(main_windows_gui, 0); - show_mouse(screen); - while (x && !(mouse_b & 2) && !key[KEY_ESC]) - { - x = update_dialog(dp); - } - show_mouse(NULL); - shutdown_dialog(dp); - - clear(screen); - clear_keybuf(); - - infocus = 1; - - device_force_redraw(); -} diff --git a/src/allegro-gui.h b/src/allegro-gui.h deleted file mode 100644 index 1ea830552..000000000 --- a/src/allegro-gui.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void gui_enter(); - -extern int quited; - -extern int romspresent[ROM_MAX]; -extern int gfx_present[GFX_MAX]; - -int disc_hdconf(); - -int settings_configure(); - -void deviceconfig_open(device_t *device); diff --git a/src/allegro-joystick.c b/src/allegro-joystick.c deleted file mode 100644 index ed03267f9..000000000 --- a/src/allegro-joystick.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "plat-joystick.h" -#include "device.h" -#include "gameport.h" - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; - -int joysticks_present; - -void joystick_init() -{ - install_joystick(JOY_TYPE_AUTODETECT); - joysticks_present = num_joysticks; -} -void joystick_close() -{ -} -void joystick_poll() -{ - int c, d; - - poll_joystick(); - - for (c = 0; c < num_joysticks; c++) - { - plat_joystick_state[c].a[0] = joy[c].stick[0].axis[0].pos * 256; - plat_joystick_state[c].a[1] = joy[c].stick[0].axis[1].pos * 256; - for (d = 0; d < MAX_JOYSTICK_BUTTONS; d++) - plat_joystick_state[c].b[d] = joy[c].button[d].b; - } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (c < num_joysticks) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = plat_joystick_state[c].a[d]; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[c].b[d]; - } - else - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - } - } -} diff --git a/src/allegro-keyboard.c b/src/allegro-keyboard.c deleted file mode 100644 index a3e3c3a51..000000000 --- a/src/allegro-keyboard.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "plat-keyboard.h" - -int recv_key[272]; -int rawinputkey[272]; - -static int key_convert[128] = -{ - -1, 0x1e, 0x30, 0x2e, 0x20, 0x12, 0x21, 0x22, /* , A, B, C, D, E, F, G*/ - 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18, /* H, I, J, K, L, M, N, O*/ - 0x19, 0x10, 0x13, 0x1f, 0x14, 0x16, 0x2f, 0x11, /* P, Q, R, S, T, U, V, W*/ - 0x2d, 0x15, 0x2c, 0x0b, 0x02, 0x03, 0x04, 0x05, /* X, Y, Z, 0, 1, 2, 3, 4*/ - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x52, 0x4f, 0x50, /* 5, 6, 7, 8, 9, p0, p1, p2*/ - 0x51, 0x4b, 0x4c, 0x4d, 0x47, 0x48, 0x49, 0x3b, /* p3, p4, p5, p6, p7, p8, p9, F1*/ - 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, /* F2, F3, F4, F5, F6, F7, F8, F9*/ - 0x44, 0x57, 0x58, 0x01, 0x29, 0x0c, 0x0d, 0x0e, /*F10, F11, F12, ESC, `ª, -_, =+, backspace*/ - 0x0f, 0x1a, 0x1b, 0x1c, 0x27, 0x28, 0x2b, 0x56, /*TAB, [{, ]}, ENT, ;:, '@, \|, #~*/ - 0x33, 0x34, 0x35, 0x39, 0xd2, 0xd3, 0xc7, 0xcf, /* ,<, .>, /?, SPC, INS, DEL, HOME, END*/ - 0xc9, 0xd1, 0xcb, 0xcd, 0xc8, 0xd0, 0xb5, 0x37, /*PGU, PGD, LFT, RHT, UP, DN, /, * */ - 0x4a, 0x4e, 0x53, 0x9c, 0xff, -1, -1, -1, /* p-, p+, pDL, pEN, psc, pse, abnt, yen*/ - -1, -1, -1, -1, -1, -1, -1, -1, /*kana, convert, noconvert, at, circumflex, colon2, kanji, pad equals*/ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 0x2a, 0x36, 0x1d, 0x9d, 0x38, /*, , lshift, rshift, lctrl, rctrl, alt*/ - 0xb8, 0xdb, 0xdc, 0xdd, 0x46, 0x45, 0x3a, -1 /*altgr, lwin, rwin, menu, scrlock, numlock, capslock*/ -}; - -void keyboard_init() -{ - install_keyboard(); -} - -void keyboard_close() -{ -} - -void keyboard_poll_host() -{ - int c; - - for (c = 0; c < 128; c++) - { - int key_idx = key_convert[c]; - if (key_idx == -1) - continue; - - if (key[c] != recv_key[key_idx]) - recv_key[key_idx] = key[c]; - } -} diff --git a/src/allegro-main.c b/src/allegro-main.c deleted file mode 100644 index 65bd43aea..000000000 --- a/src/allegro-main.c +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "ibm.h" -#include "cpu.h" -#include "model.h" -#include "nvr.h" -#include "video.h" - -#undef printf - -int mousecapture = 0; -int quited = 0; -int winsizex = -1, winsizey = -1; - -int romspresent[ROM_MAX]; -int gfx_present[GFX_MAX]; - -void updatewindowsize(int x, int y) -{ - if (x < 128) - x = 128; - if (y < 128) - y = 128; - if (winsizex != x || winsizey != y) - { - winsizex = x; - winsizey = y; - allegro_video_update_size(x, y); - } -} - -void startblit() -{ -} - -void endblit() -{ -} - -static int ticks = 0; -static void timer_rout() -{ - ticks++; -} - -uint64_t timer_freq; -uint64_t timer_read() -{ - return 0; -} - -int main(int argc, char *argv[]) -{ - int frames = 0; - int c, d; - allegro_init(); - allegro_video_init(); - install_timer(); - install_int_ex(timer_rout, BPS_TO_TIMER(100)); - install_int_ex(onesec, BPS_TO_TIMER(1)); - midi_init(); - - initpc(argc, argv); - - d = romset; - for (c = 0; c < ROM_MAX; c++) - { - romset = c; - romspresent[c] = loadbios(); - pclog("romset %i - %i\n", c, romspresent[c]); - } - - for (c = 0; c < ROM_MAX; c++) - { - if (romspresent[c]) - break; - } - if (c == ROM_MAX) - { - printf("No ROMs present!\nYou must have at least one romset to use 86Box."); - return 0; - } - - romset=d; - c=loadbios(); - - if (!c) - { - if (romset != -1) - printf("Configured romset not available.\nDefaulting to available romset."); - for (c = 0; c < ROM_MAX; c++) - { - if (romspresent[c]) - { - romset = c; - model = model_getmodel(romset); - saveconfig(); - resetpchard(); - break; - } - } - } - - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); - - if (!video_card_available(video_old_to_new(gfxcard))) - { - if (gfxcard) printf("Configured video BIOS not available.\nDefaulting to available romset."); - for (c = GFX_MAX-1; c >= 0; c--) - { - if (gfx_present[c]) - { - gfxcard = c; - saveconfig(); - resetpchard(); - break; - } - } - } - - resetpchard(); - - ticks = 0; - while (!quited) - { - if (ticks) - { - ticks--; - runpc(); - frames++; - if (frames >= 200 && nvr_dosave) - { - frames = 0; - nvr_dosave = 0; - savenvr(); - } - } - else - rest(1); - - if (ticks > 10) - ticks = 0; - - if ((mouse_b & 1) && !mousecapture) - mousecapture = 1; - - if (((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_END]) || (mouse_b & 4)) - mousecapture = 0; - - if ((key[KEY_LCONTROL] || key[KEY_RCONTROL]) && key[KEY_ALT] && key[KEY_PGDN]) - { - int old_winsizex = winsizex, old_winsizey = winsizey; - if (winsizex < 512 || winsizey < 350) - updatewindowsize(512, 350); - gui_enter(); - if (old_winsizex < 512 || old_winsizey < 350) - updatewindowsize(old_winsizex, old_winsizey); - ticks = 0; - } - } - - closepc(); - - midi_close(); - - return 0; -} - -END_OF_MAIN(); diff --git a/src/allegro-main.h b/src/allegro-main.h deleted file mode 100644 index 4498defd3..000000000 --- a/src/allegro-main.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define getr8 allegro_getr8 -#define setr8 allegro_setr8 -#define get_filename allegro_get_filename -#define append_filename allegro_append_filename -#define put_backslash allegro_put_backslash -#define get_extension allegro_get_extension -#define GFX_VGA allegro_GFX_VGA -#define MAX_JOYSTICKS allegro_MAX_JOYSTICKS - -#include - -#undef MAX_JOYSTICKS -#undef GFX_VGA -#undef getr8 -#undef setr8 -#undef get_filename -#undef append_filename -#undef put_backslash -#undef get_extension diff --git a/src/allegro-midi.c b/src/allegro-midi.c deleted file mode 100644 index 9178f9e35..000000000 --- a/src/allegro-midi.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "ibm.h" -#include "plat-midi.h" - -//#define USE_ALLEGRO_MIDI - -void midi_init() -{ -#ifdef USE_ALLEGRO_MIDI - install_sound(DIGI_NONE, MIDI_AUTODETECT, NULL); -#endif -} - -void midi_close() -{ -#ifdef USE_ALLEGRO_MIDI - remove_sound(); -#endif -} - -static int midi_cmd_pos, midi_len; -static uint8_t midi_command[3]; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 0}; - -void midi_write(uint8_t val) -{ - if (val & 0x80) - { - midi_cmd_pos = 0; - midi_len = midi_lengths[(val >> 4) & 7]; - midi_command[0] = midi_command[1] = midi_command[2] = 0; - } - - if (midi_len && midi_cmd_pos < 3) - { - midi_command[midi_cmd_pos] = val; - - midi_cmd_pos++; - -#ifdef USE_ALLEGRO_MIDI - if (midi_cmd_pos == midi_len) - midi_out(midi_command, midi_len); -#endif - } -} diff --git a/src/allegro-mouse.c b/src/allegro-mouse.c deleted file mode 100644 index 60f287361..000000000 --- a/src/allegro-mouse.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "plat-mouse.h" - -int mouse_buttons; - -void mouse_init() -{ - install_mouse(); -} - -void mouse_close() -{ -} - -void mouse_poll_host() -{ - //poll_mouse(); - mouse_buttons = mouse_b; -} - -void mouse_get_mickeys(int *x, int *y) -{ - if (mousecapture) - { - get_mouse_mickeys(x, y); -// position_mouse(64, 64); - } - else - *x = *y = 0; -} - diff --git a/src/allegro-video.c b/src/allegro-video.c deleted file mode 100644 index a4897ffc6..000000000 --- a/src/allegro-video.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "allegro-main.h" -#include "ibm.h" -#include "video.h" - -#include "allegro-video.h" - -static PALETTE cgapal= -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, - - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,63}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41}, - - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; - -static uint32_t pal_lookup[256]; - -static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void allegro_blit_memtoscreen_8(int x, int y, int w, int h); -static BITMAP *buffer32_vscale; -void allegro_video_init() -{ - int c; - - set_color_depth(32); - set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); - video_blit_memtoscreen = allegro_blit_memtoscreen; - video_blit_memtoscreen_8 = allegro_blit_memtoscreen_8; - - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); - - buffer32_vscale = create_bitmap(2048, 2048); -} - -void allegro_video_close() -{ - destroy_bitmap(buffer32_vscale); -} - -void allegro_video_update_size(int x, int y) -{ - if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, x, y, 0, 0)) - fatal("Failed to set gfx mode %i,%i : %s\n", x, y, allegro_error); -} - -static void allegro_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - if (h < winsizey) - { - int yy; - - for (yy = y+y1; yy < y+y2; yy++) - { - if (yy >= 0) - { - memcpy(&((uint32_t *)buffer32_vscale->line[yy*2])[x], &((uint32_t *)buffer32->line[yy])[x], w*4); - memcpy(&((uint32_t *)buffer32_vscale->line[(yy*2)+1])[x], &((uint32_t *)buffer32->line[yy])[x], w*4); - } - } - - blit(buffer32_vscale, screen, x, (y+y1)*2, 0, y1, w, (y2-y1)*2); - } - else - blit(buffer32, screen, x, y+y1, 0, y1, w, y2-y1); -} - -static void allegro_blit_memtoscreen_8(int x, int y, int w, int h) -{ - int xx, yy; - int line_double = (winsizey > h) ? 1 : 0; - - if (y < 0) - { - h += y; - y = 0; - } - - for (yy = y; yy < y+h; yy++) - { - int dy = line_double ? yy*2 : yy; - if (dy < buffer->h) - { - if (line_double) - { - for (xx = x; xx < x+w; xx++) - { - ((uint32_t *)buffer32->line[dy])[xx] = - ((uint32_t *)buffer32->line[dy + 1])[xx] = pal_lookup[buffer->line[yy][xx]]; - } - } - else - { - for (xx = x; xx < x+w; xx++) - ((uint32_t *)buffer32->line[dy])[xx] = pal_lookup[buffer->line[yy][xx]]; - } - } - } - - if (readflash) - { - if (line_double) - rectfill(buffer32, x+SCREEN_W-40, y*2+8, SCREEN_W-8, y*2+14, makecol(255, 255, 255)); - else - rectfill(buffer32, x+SCREEN_W-40, y+8, SCREEN_W-8, y+14, makecol(255, 255, 255)); - readflash = 0; - } - - if (line_double) - blit(buffer32, screen, x, y*2, 0, 0, w, h*2); - else - blit(buffer32, screen, x, y, 0, 0, w, h); -} diff --git a/src/allegro-video.h b/src/allegro-video.h deleted file mode 100644 index bcd05b28d..000000000 --- a/src/allegro-video.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void allegro_video_init(); -void allegro_video_close(); -void allegro_video_update_size(int x, int y); diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 53b4f6b24..1b6904a1a 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -86,19 +86,19 @@ void set_serial1_addr() switch (fdc37c665_regs[2] & 3) { case 0: - serial1_set(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); break; case 1: - serial1_set(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); break; case 2: - serial1_set(com3_addr, 4); + serial_setup(1, com3_addr, 4); break; case 3: - serial1_set(com4_addr, 3); + serial_setup(1, com4_addr, 3); break; } } @@ -111,19 +111,19 @@ void set_serial2_addr() switch (fdc37c665_regs[2] & 0x30) { case 0: - serial2_set(0x3f8, 4); + serial_setup(2, SERIAL1_ADDR, SERIAL1_IRQ); break; case 1: - serial2_set(0x2f8, 3); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); break; case 2: - serial2_set(com3_addr, 4); + serial_setup(2, com3_addr, 4); break; case 3: - serial2_set(com4_addr, 3); + serial_setup(2, com4_addr, 3); break; } } @@ -186,7 +186,7 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv) } if (valxor & 0x60) { - serial1_remove(); + serial_remove(1); set_com34_addr(); set_serial1_addr(); set_serial2_addr(); @@ -195,12 +195,12 @@ void fdc37c665_write(uint16_t port, uint8_t val, void *priv) case 2: if (valxor & 7) { - serial1_remove(); + serial_remove(1); set_serial1_addr(); } if (valxor & 0x70) { - serial2_remove(); + serial_remove(2); set_serial2_addr(); } break; @@ -254,11 +254,11 @@ void fdc37c665_reset(void) fdc_update_is_nsc(0); - serial1_remove(); - serial1_set(0x3f8, 4); + serial_remove(1); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - serial2_remove(); - serial2_set(0x2f8, 3); + serial_remove(2); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); lpt2_remove(); diff --git a/src/fdc37c669.c b/src/fdc37c669.c index 337b8cec1..605b79e17 100644 --- a/src/fdc37c669.c +++ b/src/fdc37c669.c @@ -170,13 +170,13 @@ process_value: case 2: if (valxor & 8) { - serial1_remove(); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + serial_remove(1); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); } if (valxor & 0x80) { - serial2_remove(); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + serial_remove(2); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF); } break; case 3: @@ -224,29 +224,29 @@ process_value: case 0x24: if (valxor & 0xfe) { - serial1_remove(); - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + serial_remove(1); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); } break; case 0x25: if (valxor & 0xfe) { - serial2_remove(); - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + serial_remove(2); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF); } break; case 0x28: if (valxor & 0xf) { - serial2_remove(); + serial_remove(2); if ((fdc37c669_regs[0x28] & 0xf) == 0) fdc37c669_regs[0x28] |= 0x3; - if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial2_set(make_port(0x25), fdc37c669_regs[0x28] & 0xF); + if ((fdc37c669_regs[2] & 0x80) && (fdc37c669_regs[0x25] & 0xc0)) serial_setup(2, make_port(0x25), fdc37c669_regs[0x28] & 0xF); } if (valxor & 0xf0) { - serial1_remove(); + serial_remove(1); if ((fdc37c669_regs[0x28] & 0xf0) == 0) fdc37c669_regs[0x28] |= 0x40; - if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial1_set(make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); + if ((fdc37c669_regs[2] & 8) && (fdc37c669_regs[0x24] & 0xc0)) serial_setup(1, make_port(0x24), (fdc37c669_regs[0x28] & 0xF0) >> 8); } break; } @@ -280,11 +280,11 @@ void fdc37c669_reset(void) fdc_update_is_nsc(0); - serial1_remove(); - serial1_set(0x3f8, 4); + serial_remove(1); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); - serial2_remove(); - serial2_set(0x2f8, 3); + serial_remove(2); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); lpt2_remove(); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 13b8371bd..96469ef5b 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -297,11 +297,11 @@ process_value: if (valxor) { if (!val) - serial1_remove(); + serial_remove(1); else { ld_port = make_port(4); - serial1_set(ld_port, fdc37c932fr_ld_regs[4][0x70]); + serial_setup(1, ld_port, fdc37c932fr_ld_regs[4][0x70]); } } break; @@ -311,7 +311,7 @@ process_value: if (valxor && fdc37c932fr_ld_regs[4][0x30]) { ld_port = make_port(4); - serial1_set(ld_port, fdc37c932fr_ld_regs[4][0x70]); + serial_setup(1, ld_port, fdc37c932fr_ld_regs[4][0x70]); } break; } @@ -325,11 +325,11 @@ process_value: if (valxor) { if (!val) - serial2_remove(); + serial_remove(2); else { ld_port = make_port(5); - serial2_set(ld_port, fdc37c932fr_ld_regs[5][0x70]); + serial_setup(2, ld_port, fdc37c932fr_ld_regs[5][0x70]); } } break; @@ -339,7 +339,7 @@ process_value: if (valxor && fdc37c932fr_ld_regs[5][0x30]) { ld_port = make_port(5); - serial2_set(ld_port, fdc37c932fr_ld_regs[5][0x70]); + serial_setup(2, ld_port, fdc37c932fr_ld_regs[5][0x70]); } break; } diff --git a/src/model.c b/src/model.c index 6410737d9..3b3b8f9b5 100644 --- a/src/model.c +++ b/src/model.c @@ -275,11 +275,11 @@ void common_init() pit_init(); if (serial_enabled[0]) { - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); } if (serial_enabled[1]) { - serial2_init(0x2f8, 3); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); } } @@ -306,7 +306,7 @@ void pcjr_init() pit_set_out_func(&pit, 0, pit_irq0_timer_pcjr); if (serial_enabled[0]) { - serial1_init(0x2f8, 3); + serial_setup(1, 0x2f8, 3); } keyboard_pcjr_init(); device_add(&sn76489_device); diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 84e85a673..e9e4338d5 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -1,12 +1,29 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Serial Mouse devices. + * + * Based on the 86Box Serial Mouse driver as a framework. + * + * Version: @(#)mouse_serial.c 1.0.2 2017/05/06 + * + * Author: Fred N. van Kempen, + */ #include #include "ibm.h" -#include "mouse.h" -#include "pic.h" -#include "serial.h" #include "timer.h" +#include "serial.h" +#include "mouse.h" +#include "mouse_serial.h" typedef struct mouse_serial_t { + int port; int pos, delay; int oldb; @@ -14,16 +31,19 @@ typedef struct mouse_serial_t { } mouse_serial_t; +/* Callback from serial driver: RTS was toggled. */ static void -sermouse_rcr(SERIAL *serial, void *priv) +sermouse_callback(SERIAL *serial, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - + + /* Start a timer to wake us up in a little while. */ ms->pos = -1; ms->delay = 5000 * (1 << TIMER_SHIFT); } +/* Callback timer expired, now send our "mouse ID" to the serial port. */ static void sermouse_timer(void *priv) { @@ -32,6 +52,8 @@ sermouse_timer(void *priv) ms->delay = 0; if (ms->pos == -1) { ms->pos = 0; + + /* This identifies a two-button Microsoft Serial mouse. */ serial_write_fifo(ms->serial, 'M'); } } @@ -41,10 +63,7 @@ static uint8_t sermouse_poll(int x, int y, int z, int b, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - SERIAL *sp = ms->serial; - uint8_t mousedat[3]; - - if (!(sp->ier & 1)) return(1); + uint8_t data[3]; if (!x && !y && b == ms->oldb) return(1); @@ -55,24 +74,21 @@ sermouse_poll(int x, int y, int z, int b, void *priv) if (y<-128) y = -128; /* Use Microsoft format. */ - mousedat[0] = 0x40; - mousedat[0] |= (((y>>6)&3)<<2); - mousedat[0] |= ((x>>6)&3); - if (b&1) mousedat[0] |= 0x20; - if (b&2) mousedat[0] |= 0x10; - mousedat[1] = x & 0x3F; - mousedat[2] = y & 0x3F; + data[0] = 0x40; + data[0] |= (((y>>6)&3)<<2); + data[0] |= ((x>>6)&3); + if (b&1) data[0] |= 0x20; + if (b&2) data[0] |= 0x10; + data[1] = x & 0x3F; + data[2] = y & 0x3F; - /* FIXME: we should check in serial_write_fifo, not here! --FvK */ - if (! (sp->mctrl & 0x10)) { + /* Send the packet to the bottom-half of the attached port. */ #if 0 - pclog("Serial data %02X %02X %02X\n", - mousedat[0], mousedat[1], mousedat[2]); + pclog("Mouse_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); #endif - serial_write_fifo(ms->serial, mousedat[0]); - serial_write_fifo(ms->serial, mousedat[1]); - serial_write_fifo(ms->serial, mousedat[2]); - } + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); return(0); } @@ -83,11 +99,10 @@ sermouse_init(void) { mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); memset(ms, 0x00, sizeof(mouse_serial_t)); + ms->port = SERMOUSE_PORT; /* Attach a serial port to the mouse. */ - ms->serial = &serial1; - serial1.rcr_callback = sermouse_rcr; - serial1.rcr_callback_p = ms; + ms->serial = serial_attach(ms->port, sermouse_callback, ms); timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); @@ -101,7 +116,7 @@ sermouse_close(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; /* Detach serial port from the mouse. */ - serial1.rcr_callback = NULL; + serial_attach(ms->port, NULL, NULL); free(ms); } diff --git a/src/mouse_serial.h b/src/mouse_serial.h index 94e744d44..f37b32da2 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -1 +1,27 @@ -extern mouse_t mouse_serial_microsoft; +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of Serial Mouse devices. + * + * Definitions for the Serial Mouse driver. + * + * Version: @(#)mouse_serial.h 1.0.2 2017/05/06 + * + * Author: Fred N. van Kempen, + */ +#ifndef MOUSE_SERIAL_H +# define MOUSE_SERIAL_H + + +#define SERMOUSE_PORT 1 /* attach to Serial1 */ + + +extern mouse_t mouse_serial_microsoft; + + +#endif /*MOUSE_SERIAL_H*/ diff --git a/src/pc.c b/src/pc.c index 86eb6e364..b2a2c7a82 100644 --- a/src/pc.c +++ b/src/pc.c @@ -101,6 +101,8 @@ int atfullspeed; void saveconfig(); int infocus; int mousecapture; + + void pclog(const char *format, ...) { #ifndef RELEASE_BUILD @@ -117,7 +119,7 @@ void pclog_w(const wchar_t *format, ...) #ifndef RELEASE_BUILD va_list ap; va_start(ap, format); - _vwprintf_p(format, ap); + vwprintf(format, ap); va_end(ap); fflush(stdout); #endif @@ -130,6 +132,7 @@ void pclog_w(const wchar_t *format, ...) #undef memmem + /* Return the first occurrence of NEEDLE in HAYSTACK. */ void *memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) { @@ -154,6 +157,7 @@ void *memmem (const void *haystack, size_t haystack_len, const void *needle, siz } #endif + void fatal(const char *format, ...) { char msg[1024]; @@ -184,8 +188,9 @@ void fatal(const char *format, ...) uint8_t cgastat; + int pollmouse_delay = 2; -void pollmouse() +void pollmouse(void) { int x, y, z; pollmouse_delay--; @@ -245,14 +250,14 @@ int updatestatus; int win_title_update=0; -void onesec() +void onesec(void) { fps=framecount; framecount=0; win_title_update=1; } -void pc_reset() +void pc_reset(void) { cpu_set(); resetx86(); @@ -268,6 +273,8 @@ void pc_reset() ali1429_reset(); } + + #undef printf void initpc(int argc, wchar_t *argv[]) { @@ -285,7 +292,7 @@ void initpc(int argc, wchar_t *argv[]) { if (!_wcsicmp(argv[c], L"--help")) { - printf("PCem command line options :\n\n"); + printf("Command line options :\n\n"); printf("--config file.cfg - use given config file as initial configuration\n"); printf("--dump - always dump memory on exit\n"); printf("--fullscreen - start in fullscreen mode\n"); @@ -317,6 +324,7 @@ void initpc(int argc, wchar_t *argv[]) mouse_init(); midi_init(); + serial_init(); if (config_file == NULL) { @@ -424,7 +432,7 @@ void initpc(int argc, wchar_t *argv[]) } } -void resetpc() +void resetpc(void) { pc_reset(); shadowbios=0; @@ -442,7 +450,7 @@ void pc_keyboard_send(uint8_t val) } } -void resetpc_cad() +void resetpc_cad(void) { pc_keyboard_send(29); /* Ctrl key pressed */ pc_keyboard_send(56); /* Alt key pressed */ @@ -454,7 +462,7 @@ void resetpc_cad() int suppress_overscan = 0; -void resetpchard() +void resetpchard(void) { int i = 0; @@ -475,7 +483,7 @@ void resetpchard() mem_resize(); fdc_init(); disc_reset(); - + model_init(); mouse_emu_init(); video_init(); @@ -566,7 +574,7 @@ int emu_fps = 0; static WCHAR wmodel[2048]; static WCHAR wcpu[2048]; -void runpc() +void runpc(void) { wchar_t s[200]; int done=0; @@ -651,7 +659,7 @@ void runpc() done++; } -void fullspeed() +void fullspeed(void) { cpuspeed2=cpuspeed; if (!atfullspeed) @@ -666,7 +674,7 @@ void fullspeed() nvr_recalc(); } -void speedchanged() +void speedchanged(void) { if (AT) setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); @@ -675,7 +683,7 @@ void speedchanged() nvr_recalc(); } -void closepc() +void closepc(void) { int i = 0; for (i = 0; i < CDROM_NUM; i++) @@ -693,18 +701,6 @@ void closepc() midi_close(); } -/*int main() -{ - initpc(); - while (!key[KEY_F11]) - { - runpc(); - } - closepc(); - return 0; -} - -END_OF_MAIN();*/ void loadconfig(wchar_t *fn) { @@ -970,7 +966,7 @@ wchar_t *nvr_concat(wchar_t *to_concat) return temp_nvr_path; } -void saveconfig() +void saveconfig(void) { int c, d; diff --git a/src/pc87306.c b/src/pc87306.c index b62ea642c..c0a6bb7d1 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -89,24 +89,24 @@ void serial1_handler() temp = (pc87306_regs[1] >> 2) & 3; switch (temp) { - case 0: serial1_set(0x3f8, uart1_int()); break; - case 1: serial1_set(0x2f8, uart1_int()); break; + case 0: serial_setup(1, SERIAL1_ADDR, uart1_int()); break; + case 1: serial_setup(1, SERIAL2_ADDR, uart1_int()); break; case 2: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial1_set(0x3e8, uart1_int()); break; - case 1: serial1_set(0x338, uart1_int()); break; - case 2: serial1_set(0x2e8, uart1_int()); break; - case 3: serial1_set(0x220, uart1_int()); break; + case 0: serial_setup(1, 0x3e8, uart1_int()); break; + case 1: serial_setup(1, 0x338, uart1_int()); break; + case 2: serial_setup(1, 0x2e8, uart1_int()); break; + case 3: serial_setup(1, 0x220, uart1_int()); break; } break; case 3: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial1_set(0x2e8, uart1_int()); break; - case 1: serial1_set(0x238, uart1_int()); break; - case 2: serial1_set(0x2e0, uart1_int()); break; - case 3: serial1_set(0x228, uart1_int()); break; + case 0: serial_setup(1, 0x2e8, uart1_int()); break; + case 1: serial_setup(1, 0x238, uart1_int()); break; + case 2: serial_setup(1, 0x2e0, uart1_int()); break; + case 3: serial_setup(1, 0x228, uart1_int()); break; } break; } @@ -118,24 +118,24 @@ void serial2_handler() temp = (pc87306_regs[1] >> 4) & 3; switch (temp) { - case 0: serial2_set(0x3f8, uart2_int()); break; - case 1: serial2_set(0x2f8, uart2_int()); break; + case 0: serial_setup(2, SERIAL1_ADDR, uart2_int()); break; + case 1: serial_setup(2, SERIAL2_ADDR, uart2_int()); break; case 2: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial2_set(0x3e8, uart2_int()); break; - case 1: serial2_set(0x338, uart2_int()); break; - case 2: serial2_set(0x2e8, uart2_int()); break; - case 3: serial2_set(0x220, uart2_int()); break; + case 0: serial_setup(2, 0x3e8, uart2_int()); break; + case 1: serial_setup(2, 0x338, uart2_int()); break; + case 2: serial_setup(2, 0x2e8, uart2_int()); break; + case 3: serial_setup(2, 0x220, uart2_int()); break; } break; case 3: switch ((pc87306_regs[1] >> 6) & 3) { - case 0: serial2_set(0x2e8, uart2_int()); break; - case 1: serial2_set(0x238, uart2_int()); break; - case 2: serial2_set(0x2e0, uart2_int()); break; - case 3: serial2_set(0x228, uart2_int()); break; + case 0: serial_setup(2, 0x2e8, uart2_int()); break; + case 1: serial_setup(2, 0x238, uart2_int()); break; + case 2: serial_setup(2, 0x2e0, uart2_int()); break; + case 3: serial_setup(2, 0x228, uart2_int()); break; } break; } @@ -206,7 +206,7 @@ process_value: if (valxor & 2) { - serial1_remove(); + serial_remove(1); if (val & 2) { serial1_handler(); @@ -214,7 +214,7 @@ process_value: } if (valxor & 4) { - serial2_remove(); + serial_remove(2); if (val & 4) { serial2_handler(); @@ -266,7 +266,7 @@ process_value: } else { - serial1_remove(); + serial_remove(1); } } @@ -278,7 +278,7 @@ process_value: } else { - serial2_remove(); + serial_remove(2); } } break; @@ -288,8 +288,8 @@ process_value: if (val & 1) { lpt1_remove(); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); fdc_remove(); } else @@ -448,8 +448,8 @@ void pc87306_reset(void) fdc_remove(); fdc_set_base(0x3f0, 0); fdd_swap = 0; - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); serial1_handler(); serial2_handler(); pc87306_gpio_init(); diff --git a/src/ps1.c b/src/ps1.c index bfb98318c..d54df75af 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -74,9 +74,9 @@ void ps1_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -155,8 +155,8 @@ void ps1mb_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); memset(&ps1_hd, 0, sizeof(ps1_hd)); } @@ -242,9 +242,9 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -299,8 +299,8 @@ void ps1mb_m2121_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); mem_remap_top_384k(); } diff --git a/src/ps2.c b/src/ps2.c index 1b5c4dc06..0f1e1a964 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -68,9 +68,9 @@ void ps2_write(uint16_t port, uint8_t val, void *p) case 0x102: lpt1_remove(); if (val & 0x04) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -131,8 +131,8 @@ void ps2board_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); memset(&ps2_hd, 0, sizeof(ps2_hd)); } diff --git a/src/ps2_mca.c b/src/ps2_mca.c index 74183a8ed..5af537b6e 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -192,16 +192,16 @@ static void model_50_write(uint16_t port, uint8_t val) break; case 0x102: lpt1_remove(); - serial1_remove(); + serial_remove(1); if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_init(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); } else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -248,16 +248,16 @@ static void model_55sx_write(uint16_t port, uint8_t val) break; case 0x102: lpt1_remove(); - serial1_remove(); + serial_remove(1); if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_init(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); } else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -324,16 +324,16 @@ static void model_80_write(uint16_t port, uint8_t val) break; case 0x102: lpt1_remove(); - serial1_remove(); + serial_remove(1); if (val & 0x04) { if (val & 0x08) - serial1_init(0x3f8, 4); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); else - serial1_init(0x2f8, 3); + serial_setup(1, SERIAL2_ADDR, SERIAL2_IRQ); } else - serial1_remove(); + serial_remove(1); if (val & 0x10) { switch ((val >> 5) & 3) @@ -556,8 +556,8 @@ static void ps2_mca_board_common_init() lpt2_remove(); lpt1_init(0x3bc); - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); } void ps2_mca_board_model_50_init() diff --git a/src/serial.c b/src/serial.c index 4eb78e821..840686808 100644 --- a/src/serial.c +++ b/src/serial.c @@ -1,295 +1,621 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of NS8250-series UART devices. + * + * The original IBM-PC design did not have any serial ports of + * any kind. Rather, these were offered as add-on devices, most + * likely because a) most people did not need one at the time, + * and, b) this way, IBM could make more money off them. + * + * So, for the PC, the offerings were for an IBM Asynchronous + * Communications Adapter, and, later, a model for synchronous + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. + * + * Of course, many system builders came up with similar boards, + * and even more boards were designed where several I/O functions + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. + * + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. + * + * Based on the 86Box serial port driver as a framework. + * + * Version: @(#)serial.c 1.0.3 2017/05/06 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ #include "ibm.h" #include "io.h" -#include "mouse.h" #include "pic.h" -#include "serial.h" #include "timer.h" +#include "serial.h" +#include "plat-serial.h" -enum -{ - SERIAL_INT_LSR = 1, - SERIAL_INT_RECEIVE = 2, - SERIAL_INT_TRANSMIT = 4, - SERIAL_INT_MSR = 8 + +enum { + SERINT_LSR = 1, + SERINT_RECEIVE = 2, + SERINT_TRANSMIT = 4, + SERINT_MSR = 8 }; -SERIAL serial1, serial2; -void serial_reset() -{ - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; - serial2.fifo_read = serial2.fifo_write = 0; -} +/* IER register bits. */ +#define IER_RDAIE (0x01) +#define IER_THREIE (0x02) +#define IER_RXLSIE (0x04) +#define IER_MSIE (0x08) +#define IER_SLEEP (0x10) /* NS16750 */ +#define IER_LOWPOWER (0x20) /* NS16750 */ +#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ -void serial_update_ints(SERIAL *serial) +/* IIR register bits. */ +#define IIR_IP (0x01) +#define IIR_IID (0x0e) +# define IID_IDMDM (0x00) +# define IID_IDTX (0x02) +# define IID_IDRX (0x04) +# define IID_IDERR (0x06) +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) +# define IIR_FIFO64 (0x20) +# define IIR_FIFOBAD (0x80) /* 16550 */ +# define IIR_FIFOENB (0xc0) + +/* FCR register bits. */ +#define FCR_FCRFE (0x01) +#define FCR_RFR (0x02) +#define FCR_TFR (0x04) +#define FCR_SELDMA1 (0x08) +#define FCR_FENB64 (0x20) /* 16750 */ +#define FCR_RTLS (0xc0) +# define FCR_RTLS1 (0x00) +# define FCR_RTLS4 (0x40) +# define FCR_RTLS8 (0x80) +# define FCR_RTLS14 (0xc0) + +/* LCR register bits. */ +#define LCR_WLS (0x03) +# define WLS_BITS5 (0x00) +# define WLS_BITS6 (0x01) +# define WLS_BITS7 (0x02) +# define WLS_BITS8 (0x03) +#define LCR_SBS (0x04) +#define LCR_PE (0x08) +#define LCR_EP (0x10) +#define LCR_PS (0x20) +# define PAR_NONE (0x00) +# define PAR_EVEN (LCR_PE | LCR_EP) +# define PAR_ODD (LCR_PE) +# define PAR_MARK (LCR_PE | LCR_PS) +# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) +#define LCR_BC (0x40) +#define LCR_DLAB (0x80) + +/* MCR register bits. */ +#define MCR_DTR (0x01) +#define MCR_RTS (0x02) +#define MCR_OUT1 (0x04) /* 8250 */ +#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ +#define MCR_LMS (0x10) +#define MCR_AUTOFLOW (0x20) /* 16750 + +/* LSR register bits. */ +#define LSR_DR (0x01) +#define LSR_OE (0x02) +#define LSR_PE (0x04) +#define LSR_FE (0x08) +#define LSR_BI (0x10) +#define LSR_THRE (0x20) +#define LSR_TEMT (0x40) +#define LSR_RXFE (0x80) + +/* MSR register bits. */ +#define MSR_DCTS (0x01) +#define MSR_DDSR (0x02) +#define MSR_TERI (0x04) +#define MSR_DDCD (0x08) +#define MSR_CTS (0x10) +#define MSR_DSR (0x20) +#define MSR_RI (0x40) +#define MSR_DCD (0x80) +#define MSR_MASK (0x0f) + + +static SERIAL serial1, /* serial port 1 data */ + serial2; /* serial port 2 data */ + + +static void +update_ints(SERIAL *sp) { - int stat = 0; + int stat = 0; - serial->iir = 1; + sp->iir = IIR_IP; + if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { + /* Line Status interrupt. */ + stat = 1; + sp->iir = IID_IDERR; + } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { + /* Received Data available. */ + stat = 1; + sp->iir = IID_IDRX; + } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { + /* Transmit Data empty. */ + stat = 1; + sp->iir = IID_IDTX; + } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { + /* Modem Status interrupt. */ + stat = 1; + sp->iir = IID_IDMDM; + } - if ((serial->ier & 4) && (serial->int_status & SERIAL_INT_LSR)) /*Line status interrupt*/ - { - stat = 1; - serial->iir = 6; - } - else if ((serial->ier & 1) && (serial->int_status & SERIAL_INT_RECEIVE)) /*Recieved data available*/ - { - stat = 1; - serial->iir = 4; - } - else if ((serial->ier & 2) && (serial->int_status & SERIAL_INT_TRANSMIT)) /*Transmit data empty*/ - { - stat = 1; - serial->iir = 2; - } - else if ((serial->ier & 8) && (serial->int_status & SERIAL_INT_MSR)) /*Modem status interrupt*/ - { - stat = 1; - serial->iir = 0; - } - - if (stat && ((serial->mctrl & 8) || PCJR)) - picintlevel(1 << serial->irq); - else - picintc(1 << serial->irq); + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); } -void serial_write_fifo(SERIAL *serial, uint8_t dat) + +/* Fake interrupt generator, needed for Serial Mouse. */ +static void +serial_timer(void *priv) { - serial->fifo[serial->fifo_write] = dat; - serial->fifo_write = (serial->fifo_write + 1) & 0xFF; - if (!(serial->lsr & 1)) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + SERIAL *sp = (SERIAL *)priv; + + sp->receive_delay = 0; + + if (sp->fifo_read != sp->fifo_write) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } } -uint8_t serial_read_fifo(SERIAL *serial) + +/* Write data to the (input) FIFO. Used by MOUSE driver. */ +void +serial_write_fifo(SERIAL *sp, uint8_t dat) { - if (serial->fifo_read != serial->fifo_write) - { - serial->dat = serial->fifo[serial->fifo_read]; - serial->fifo_read = (serial->fifo_read + 1) & 0xFF; - } - return serial->dat; + /* Stuff data into FIFO. */ + sp->fifo[sp->fifo_write] = dat; + sp->fifo_write = (sp->fifo_write + 1) & 0xFF; + + if (! (sp->lsr & LSR_DR)) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } } -void serial_write(uint16_t addr, uint8_t val, void *p) + +static uint8_t +read_fifo(SERIAL *sp) { - SERIAL *serial = (SERIAL *)p; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - serial->dlab1 = val; - return; - } - serial->thr = val; - serial->lsr |= 0x20; - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - if (serial->mctrl & 0x10) - { - serial_write_fifo(serial, val); - } - break; - case 1: - if (serial->lcr & 0x80) - { - serial->dlab2 = val; - return; - } - serial->ier = val & 0xf; - serial_update_ints(serial); - break; - case 2: - serial->fcr = val; - break; - case 3: - serial->lcr = val; - break; - case 4: - if ((val & 2) && !(serial->mctrl & 2)) - { - if (serial->rcr_callback) - serial->rcr_callback(serial, serial->rcr_callback_p); - } - serial->mctrl = val; - if (val & 0x10) - { - uint8_t new_msr; - - new_msr = (val & 0x0c) << 4; - new_msr |= (val & 0x02) ? 0x10: 0; - new_msr |= (val & 0x01) ? 0x20: 0; - - if ((serial->msr ^ new_msr) & 0x10) - new_msr |= 0x01; - if ((serial->msr ^ new_msr) & 0x20) - new_msr |= 0x02; - if ((serial->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((serial->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - serial->msr = new_msr; - } - break; - case 5: - serial->lsr = val; - if (serial->lsr & 0x01) - serial->int_status |= SERIAL_INT_RECEIVE; - if (serial->lsr & 0x1e) - serial->int_status |= SERIAL_INT_LSR; - if (serial->lsr & 0x20) - serial->int_status |= SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - break; - case 6: - serial->msr = val; - if (serial->msr & 0x0f) - serial->int_status |= SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - serial->scratch = val; - break; - } + if (sp->fifo_read != sp->fifo_write) { + sp->dat = sp->fifo[sp->fifo_read]; + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; + } + + return(sp->dat); } -uint8_t serial_read(uint16_t addr, void *p) -{ - SERIAL *serial = (SERIAL *)p; - uint8_t temp = 0; - switch (addr&7) - { - case 0: - if (serial->lcr & 0x80) - { - temp = serial->dlab1; - break; - } - serial->lsr &= ~1; - serial->int_status &= ~SERIAL_INT_RECEIVE; - serial_update_ints(serial); - temp = serial_read_fifo(serial); - if (serial->fifo_read != serial->fifo_write) - serial->recieve_delay = 1000 * TIMER_USEC; - break; - case 1: - if (serial->lcr & 0x80) - temp = serial->dlab2; - else - temp = serial->ier; - break; - case 2: - temp = serial->iir; - if ((temp & 0xe) == 2) - { - serial->int_status &= ~SERIAL_INT_TRANSMIT; - serial_update_ints(serial); - } - if (serial->fcr & 1) - temp |= 0xc0; - break; - case 3: - temp = serial->lcr; - break; - case 4: - temp = serial->mctrl; - break; - case 5: - if (serial->lsr & 0x20) - serial->lsr |= 0x40; - serial->lsr |= 0x20; - temp = serial->lsr; - if (serial->lsr & 0x1f) - serial->lsr &= ~0x1e; - serial->int_status &= ~SERIAL_INT_LSR; - serial_update_ints(serial); - break; - case 6: - temp = serial->msr; - serial->msr &= ~0x0f; - serial->int_status &= ~SERIAL_INT_MSR; - serial_update_ints(serial); - break; - case 7: - temp = serial->scratch; - break; - } - return temp; +/* BHTTY WRITE COMPLETE handler. */ +static void +serial_wr_done(void *arg) +{ + SERIAL *sp = (SERIAL *)arg; + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); } -void serial_recieve_callback(void *p) + +/* Handle a WRITE operation to one of our registers. */ +static void +serial_write(uint16_t addr, uint8_t val, void *priv) { - SERIAL *serial = (SERIAL *)p; - - serial->recieve_delay = 0; - - if (serial->fifo_read != serial->fifo_write) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } + SERIAL *sp = (SERIAL *)priv; + uint8_t wl, sb, pa; + uint16_t baud; + long speed; + + switch (addr & 0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab1 = val; + return; + } + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ +#if 0 + bhtty_write((BHTTY *)sp->bh, + sp->thr, serial_wr_done, sp); +#else + bhtty_write((BHTTY *)sp->bh, sp->thr); + serial_wr_done(sp); +#endif + } else { + /* Not linked. Just fake LOOPBACK mode. */ + if (! (sp->mctrl & MCR_LMS)) + serial_write_fifo(sp, val); + } + + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val); + } + break; + + case 1: /* IER / DLAB2 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab2 = val; + return; + } + sp->ier = (val & IER_MASK); + update_ints(sp); + break; + + case 2: /* FCR */ + sp->fcr = val; + break; + + case 3: /* LCR */ + if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { + /* We dropped DLAB, so handle baudrate. */ + baud = ((sp->dlab2 << 8) | sp->dlab1); + speed = 115200UL/baud; +#if 0 + pclog("Serial%d: new divisor %u, baudrate %ld\n", + sp->port, baud, speed); +#endif + if (sp->bh != NULL) + bhtty_speed((BHTTY *)sp->bh, speed); + } + wl = (val & LCR_WLS) + 5; /* databits */ + sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ + pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; +#if 0 + pclog("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); +#endif + if (sp->bh != NULL) + bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; + break; + + case 4: + if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { + /* + * This is old code for use by the Serial Mouse + * driver. If the user toggles RTS, serial mice + * are expected to send an ID, to inform any + * enumerator there 'is' something. + */ + if (sp->rts_callback) { + sp->rts_callback(sp, sp->rts_callback_p); +#if 0 + pclog("RTS raised; sending ID\n"); +#endif + } + } + + if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { + if (sp->bh != NULL) { + /* Linked, start reading from host port. */ + (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); + } else { + /* Not linked, start RX timer. */ + timer_add(serial_timer, + &sp->receive_delay, + &sp->receive_delay, sp); +#if 0 + pclog("Serial%d: RX timer started!\n",sp->port); +#endif + } + } + sp->mctrl = val; + if (val & MCR_LMS) { /* loopback mode */ + uint8_t new_msr; + + /*FIXME: WTF does this do?? --FvK */ + new_msr = (val & 0x0c) << 4; + new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; + new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; + + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + sp->msr = new_msr; + } + break; + + case 5: + sp->lsr = val; + if (sp->lsr & LSR_DR) + sp->int_status |= SERINT_RECEIVE; + if (sp->lsr & 0x1e) + sp->int_status |= SERINT_LSR; + if (sp->lsr & LSR_THRE) + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + break; + + case 6: + sp->msr = val; + if (sp->msr & MSR_MASK) + sp->int_status |= SERINT_MSR; + update_ints(sp); + break; + + case 7: + sp->scratch = val; + break; + } } -uint16_t serial_addr[2] = { 0x3f8, 0x2f8 }; -int serial_irq[2] = { 4, 3 }; -/*Tandy might need COM1 at 2f8*/ -void serial1_init(uint16_t addr, int irq) +/* BHTTY READ COMPLETE handler. */ +static void +serial_rd_done(void *arg, int num) { - memset(&serial1, 0, sizeof(serial1)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial1.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial1.recieve_delay, &serial1.recieve_delay, &serial1); - serial_addr[0] = addr; - serial_irq[0] = irq; -} -void serial1_set(uint16_t addr, int irq) -{ - serial1_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); - serial1.irq = irq; - serial_addr[0] = addr; - serial_irq[0] = irq; -} -void serial1_remove() -{ - io_removehandler(serial_addr[0], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial1); + SERIAL *sp = (SERIAL *)arg; +#if 0 +pclog("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); +#endif + + /* Stuff the byte in the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + + /* Start up the next read from the real port. */ + if (sp->bh != NULL) + (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); } -void serial2_init(uint16_t addr, int irq) + +/* Handle a READ operation from one of our registers. */ +static uint8_t +serial_read(uint16_t addr, void *priv) { - memset(&serial2, 0, sizeof(serial2)); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial2.rcr_callback = NULL; - timer_add(serial_recieve_callback, &serial2.recieve_delay, &serial2.recieve_delay, &serial2); - serial_addr[1] = addr; - serial_irq[1] = irq; + SERIAL *sp = (SERIAL *)priv; + uint8_t ret = 0x00; + + switch (addr&0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + ret = sp->dlab1; + break; + } + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; + break; + + case 1: /* LCR / DLAB2 */ + if (sp->lcr & LCR_DLAB) + ret = sp->dlab2; + else + ret = sp->ier; + break; + + case 2: /* IIR */ + ret = sp->iir; + if ((ret & IIR_IID) == IID_IDTX) { + sp->int_status &= ~SERINT_TRANSMIT; + update_ints(sp); + } + if (sp->fcr & 0x01) { + ret |= 0xc0; + } + break; + + case 3: /* LCR */ + ret = sp->lcr; + break; + + case 4: /* MCR */ + ret = sp->mctrl; + break; + + case 5: /* LSR */ + if (sp->lsr & LSR_THRE) + sp->lsr |= LSR_TEMT; + sp->lsr |= LSR_THRE; + ret = sp->lsr; + if (sp->lsr & 0x1f) + sp->lsr &= ~0x1e; +#if 0 + sp->lsr |= (LSR_THRE | LSR_TEMT); +#endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); + break; + + case 6: + ret = sp->msr; + sp->msr &= ~0x0f; + sp->int_status &= ~SERINT_MSR; + update_ints(sp); + break; + + case 7: + ret = sp->scratch; + break; + } + + return(ret); } -void serial2_set(uint16_t addr, int irq) + + +/* Set up a serial port for use. */ +void +serial_setup(int port, uint16_t addr, int irq) { - serial2_remove(); - io_sethandler(addr, 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); - serial2.irq = irq; - serial_addr[1] = addr; - serial_irq[1] = irq; + SERIAL *sp; + + pclog("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + /* Set up the basic info. */ + if (sp->addr != 0x0000) { + /* Unlink the previous handler. Just in case. */ + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, + serial_write, NULL, NULL, sp); + } + sp->addr = addr; + sp->irq = irq; + + /* Request an I/O range. */ + io_sethandler(sp->addr, 8, + serial_read, NULL, NULL, + serial_write, NULL, NULL, sp); + + /* No DTR/RTS callback for now. */ + sp->rts_callback = NULL; } -void serial2_remove() + + +/* Release all resources held by a serial port. */ +void +serial_remove(int port) { - io_removehandler(serial_addr[1], 0x0008, serial_read, NULL, NULL, serial_write, NULL, NULL, &serial2); + SERIAL *sp; + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + // FIXME: stop timer, if enabled! + + /* Remove any callbacks. */ + sp->rts_callback = NULL; + + /* Close the host device. */ + (void)serial_link(port, NULL); + + /* Release our I/O range. */ + if (sp->addr != 0x0000) { + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, + serial_write, NULL, NULL, sp); + } + sp->addr = 0x0000; + sp->irq = 0; +} + + +/* Initialize the serial ports. */ +void +serial_init(void) +{ + memset(&serial1, 0x00, sizeof(SERIAL)); + serial1.port = 1; + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + + memset(&serial2, 0x00, sizeof(SERIAL)); + serial2.port = 2; + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); +} + + +/* + * Reset the serial ports. + * + * This should be a per-port function. + */ +void +serial_reset(void) +{ + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; + serial1.fifo_read = serial1.fifo_write = 0; + + serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; + serial2.fifo_read = serial2.fifo_write = 0; +} + + +/* Link a serial port to a host (serial) port. */ +int +serial_link(int port, char *arg) +{ + SERIAL *sp; + BHTTY *bh; + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + if (arg != NULL) { + /* Make sure we're not already linked. */ + if (sp->bh != NULL) { + pclog("Serial%d already linked!\n", port); + return(-1); + } + + /* Request a port from the host system. */ + bh = bhtty_open(arg, 0); + if (bh == NULL) { + pclog("Serial%d unable to link to '%s' !\n", port, arg); + return(-1); + } + sp->bh = bh; + + /* Set up bottom-half I/O callback info. */ + bh->rd_done = serial_rd_done; + bh->rd_arg = sp; + } else { + /* If we are linked, unlink it. */ + if (sp->bh != NULL) { + bhtty_close((BHTTY *)sp->bh); + sp->bh = NULL; + } + + } + + return(0); +} + + +/* Attach another device (MOUSE) to a serial port. */ +SERIAL * +serial_attach(int port, void *func, void *arg) +{ + SERIAL *sp; + + /* Grab the desired port block. */ + sp = (port == 2) ? &serial2 : &serial1; + + /* Set up callback info. */ + sp->rts_callback = func; + sp->rts_callback_p = arg; + + return(sp); } diff --git a/src/serial.h b/src/serial.h index 96104068e..837b13d12 100644 --- a/src/serial.h +++ b/src/serial.h @@ -1,35 +1,64 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void serial1_init(uint16_t addr, int irq); -void serial2_init(uint16_t addr, int irq); -void serial1_set(uint16_t addr, int irq); -void serial2_set(uint16_t addr, int irq); -void serial1_remove(); -void serial2_remove(); -void serial_reset(); +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the SERIAL card. + * + * Version: @(#)serial.h 1.0.2 2017/05/06 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef SERIAL_H +# define SERIAL_H -struct SERIAL; -typedef struct -{ - uint8_t lsr,thr,mctrl,rcr,iir,ier,lcr,msr; - uint8_t dlab1,dlab2; - uint8_t dat; - uint8_t int_status; - uint8_t scratch; - uint8_t fcr; - - int irq; +/* Default settings for the standard ports. */ +#define SERIAL1_ADDR 0x03f8 +#define SERIAL1_IRQ 4 +#define SERIAL2_ADDR 0x02f8 +#define SERIAL2_IRQ 3 - void (*rcr_callback)(struct SERIAL *serial, void *p); - void *rcr_callback_p; - uint8_t fifo[256]; - int fifo_read, fifo_write; - - int recieve_delay; + +typedef struct _serial_ { + int8_t port; /* port number (1,2,..) */ + int8_t irq; /* IRQ channel used */ + uint16_t addr; /* I/O address used */ + + uint8_t lsr, thr, mctrl, rcr, /* UART registers */ + iir, ier, lcr, msr; + uint8_t dlab1, dlab2; + uint8_t dat; + uint8_t int_status; + uint8_t scratch; + uint8_t fcr; + + /* Data for the RTS-toggle callback. */ + void (*rts_callback)(struct _serial_ *, void *); + void *rts_callback_p; + + uint8_t hold; + uint8_t fifo[256]; + int fifo_read, fifo_write; + + int receive_delay; + + void *bh; /* BottomHalf handler */ } SERIAL; -extern SERIAL serial1, serial2; -void serial_write_fifo(SERIAL *serial, uint8_t dat); +/* Functions. */ +extern void serial_init(void); +extern void serial_reset(void); +extern void serial_setup(int port, uint16_t addr, int irq); +extern void serial_remove(int port); +extern SERIAL *serial_attach(int, void *, void *); +extern int serial_link(int, char *); +extern void serial_write_fifo(SERIAL *, uint8_t); + + +#endif /*SERIAL_H*/ diff --git a/src/sis85c471.c b/src/sis85c471.c index 5d12ae341..e7d5af86c 100644 --- a/src/sis85c471.c +++ b/src/sis85c471.c @@ -58,13 +58,13 @@ process_value: { if (val & 0x20) { - serial1_init(0x3f8, 4); - serial2_init(0x2f8, 3); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); } else { - serial1_remove(); - serial2_remove(); + serial_remove(1); + serial_remove(2); } } diff --git a/src/um8669f.c b/src/um8669f.c index a20b1589e..00433f24c 100644 --- a/src/um8669f.c +++ b/src/um8669f.c @@ -92,10 +92,10 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) temp |= 2; switch (temp) { - case 0: serial1_set(0x3f8, 4); break; - case 1: serial1_set(0x2f8, 4); break; - case 2: serial1_set(0x3e8, 4); break; - case 3: serial1_set(0x2e8, 4); break; + case 0: serial_setup(1, 0x3f8, 4); break; + case 1: serial_setup(1, 0x2f8, 4); break; + case 2: serial_setup(1, 0x3e8, 4); break; + case 3: serial_setup(1, 0x2e8, 4); break; } } @@ -106,10 +106,10 @@ void um8669f_write(uint16_t port, uint8_t val, void *priv) temp |= 2; switch (temp) { - case 0: serial2_set(0x3f8, 3); break; - case 1: serial2_set(0x2f8, 3); break; - case 2: serial2_set(0x3e8, 3); break; - case 3: serial2_set(0x2e8, 3); break; + case 0: serial_setup(2, 0x3f8, 3); break; + case 1: serial_setup(2, 0x2f8, 3); break; + case 2: serial_setup(2, 0x3e8, 3); break; + case 3: serial_setup(2, 0x2e8, 3); break; } } diff --git a/src/w83877f.c b/src/w83877f.c index ebb22513d..cb980df09 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -340,15 +340,15 @@ process_value: case 4: if (valxor & 0x10) { - serial2_remove(); - if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF); + serial_remove(2); + if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); } if (valxor & 0x20) { - serial1_remove(); + serial_remove(1); if (!(w83877f_regs[4] & 0x20)) { - serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); + serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); } } if (valxor & 0x80) @@ -407,28 +407,28 @@ process_value: { if (!(w83877f_regs[4] & 0x20)) { - serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); + serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); } } break; case 0x25: if (valxor & 0xfe) { - if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF); + if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); } break; case 0x28: if (valxor & 0xf) { if ((w83877f_regs[0x28] & 0xf) == 0) w83877f_regs[0x28] |= 0x3; - if (!(w83877f_regs[2] & 0x10)) serial2_set(make_port(0x25), w83877f_regs[0x28] & 0xF); + if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); } if (valxor & 0xf0) { if ((w83877f_regs[0x28] & 0xf0) == 0) w83877f_regs[0x28] |= 0x40; if (!(w83877f_regs[4] & 0x20)) { - serial1_set(make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); + serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); } } break; @@ -498,8 +498,8 @@ void w83877f_reset(void) disable_write = 0; fdc_update_drv2en(1); fdd_setswap(0); - serial1_set(0x3f8, 4); - serial2_set(0x2f8, 3); + serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); w83877f_remap(); w83877f_locked = 0; w83877f_rw_locked = 0; diff --git a/src/wd76c10.c b/src/wd76c10.c index 595a1d6f3..9644058ae 100644 --- a/src/wd76c10.c +++ b/src/wd76c10.c @@ -50,17 +50,17 @@ void wd76c10_write(uint16_t port, uint16_t val, void *priv) switch ((val >> 5) & 7) { - case 1: serial1_set(0x3f8, 4); break; - case 2: serial1_set(0x2f8, 4); break; - case 3: serial1_set(0x3e8, 4); break; - case 4: serial1_set(0x2e8, 4); break; + case 1: serial_setup(1, 0x3f8, 4); break; + case 2: serial_setup(1, 0x2f8, 4); break; + case 3: serial_setup(1, 0x3e8, 4); break; + case 4: serial_setup(1, 0x2e8, 4); break; } switch ((val >> 1) & 7) { - case 1: serial2_set(0x3f8, 3); break; - case 2: serial2_set(0x2f8, 3); break; - case 3: serial2_set(0x3e8, 3); break; - case 4: serial2_set(0x2e8, 3); break; + case 1: serial_setup(2, 0x3f8, 3); break; + case 2: serial_setup(2, 0x2f8, 3); break; + case 3: serial_setup(2, 0x3e8, 3); break; + case 4: serial_setup(2, 0x2e8, 3); break; } break; diff --git a/src/win-serial.c b/src/win-serial.c index e49ebc09f..fb92b8bea 100644 --- a/src/win-serial.c +++ b/src/win-serial.c @@ -22,7 +22,7 @@ #include #include #define BHTTY_C -#include "win-serial.h" +#include "plat-serial.h" extern void pclog(char *__fmt, ...); diff --git a/src/win-serial.h b/src/win-serial.h deleted file mode 100644 index 6c77fbe75..000000000 --- a/src/win-serial.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Bottom Half of the SERIAL card. - * - * Version: @(#)win-serial.h 1.0.2 2017/05/05 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef SERIAL_BH_H -# define SERIAL_BH_H - - -#define BHTTY_PORT1 "COM2" /* port 1 connects to .. */ -#define BHTTY_PORT2 "COM4" /* port 2 connects to .. */ - - -typedef struct { - char name[79]; /* name of open port */ - void (*rd_done)(void *, int); - void *rd_arg; -#ifdef BHTTY_C - HANDLE handle; - OVERLAPPED rov, /* READ and WRITE events */ - wov; - int tmo; /* current timeout value */ - DCB dcb, /* terminal settings */ - odcb; -#endif -} BHTTY; - - -extern BHTTY *bhtty_open(char *__port, int __tmo); -extern void bhtty_close(BHTTY *); -extern int bhtty_flush(BHTTY *); -extern void bhtty_raw(BHTTY *, void *__arg); -extern int bhtty_speed(BHTTY *, long __speed); -extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); -extern int bhtty_sstate(BHTTY *, void *__arg); -extern int bhtty_gstate(BHTTY *, void *__arg); -extern int bhtty_crtscts(BHTTY *, char __yesno); - -extern int bhtty_write(BHTTY *, unsigned char); -extern int bhtty_read(BHTTY *, unsigned char *, int); - - -#endif /*SERIAL_BH_H*/ From 1a5d86716738cbb348f764d0e558d39026724861 Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 7 May 2017 02:18:53 -0400 Subject: [PATCH 169/392] New file, replaces win-serial.h. --- src/plat-serial.h | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/plat-serial.h diff --git a/src/plat-serial.h b/src/plat-serial.h new file mode 100644 index 000000000..e11737a89 --- /dev/null +++ b/src/plat-serial.h @@ -0,0 +1,49 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the Bottom Half of the SERIAL card. + * + * Version: @(#)plat-serial.h 1.0.3 2017/05/06 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef PLAT_SERIAL_H +# define PLAT_SERIAL_H + + +typedef struct { + char name[79]; /* name of open port */ + void (*rd_done)(void *, int); + void *rd_arg; +#ifdef BHTTY_C + HANDLE handle; + OVERLAPPED rov, /* READ and WRITE events */ + wov; + int tmo; /* current timeout value */ + DCB dcb, /* terminal settings */ + odcb; +#endif +} BHTTY; + + +extern BHTTY *bhtty_open(char *__port, int __tmo); +extern void bhtty_close(BHTTY *); +extern int bhtty_flush(BHTTY *); +extern void bhtty_raw(BHTTY *, void *__arg); +extern int bhtty_speed(BHTTY *, long __speed); +extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); +extern int bhtty_sstate(BHTTY *, void *__arg); +extern int bhtty_gstate(BHTTY *, void *__arg); +extern int bhtty_crtscts(BHTTY *, char __yesno); + +extern int bhtty_write(BHTTY *, unsigned char); +extern int bhtty_read(BHTTY *, unsigned char *, int); + + +#endif /*PLAT_SERIAL_H*/ From d75d630976a31350e025c6085982cb5ff4b16cd9 Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 7 May 2017 20:26:39 -0400 Subject: [PATCH 170/392] Added check for invalid baudrate divisor. --- src/serial.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/serial.c b/src/serial.c index 840686808..1d401ad00 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,7 +33,7 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.3 2017/05/06 + * Version: @(#)serial.c 1.0.4 2017/05/07 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -283,13 +283,18 @@ serial_write(uint16_t addr, uint8_t val, void *priv) if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { /* We dropped DLAB, so handle baudrate. */ baud = ((sp->dlab2 << 8) | sp->dlab1); - speed = 115200UL/baud; + if (baud > 0) { + speed = 115200UL/baud; #if 0 - pclog("Serial%d: new divisor %u, baudrate %ld\n", + pclog("Serial%d: divisor %u, baudrate %ld\n", sp->port, baud, speed); #endif - if (sp->bh != NULL) - bhtty_speed((BHTTY *)sp->bh, speed); + if (sp->bh != NULL) + bhtty_speed((BHTTY *)sp->bh, speed); + } else { + pclog("Serial%d: divisor %u invalid!\n", + sp->port, baud); + } } wl = (val & LCR_WLS) + 5; /* databits */ sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ From 55a294ad37eb3ecd8f28aa78c0f11094a4adb70d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 04:54:17 +0200 Subject: [PATCH 171/392] Fixed serial (and serial mouse) operation on boards with Super I/O chips; A few video bug fixes per patches from the mainline PCem forum; Added CUE/BIN image support per patches from the mainline PCem forum. --- src/86Box.rc | 10 +- src/Makefile.mingw | 2 +- src/VIDEO/vid_cga.c | 2 +- src/VIDEO/vid_colorplus.c | 2 +- src/VIDEO/vid_ega.c | 6 +- src/VIDEO/vid_genius.c | 2 +- src/VIDEO/vid_hercules.c | 2 +- src/VIDEO/vid_herculesplus.c | 2 +- src/VIDEO/vid_incolor.c | 2 +- src/VIDEO/vid_mda.c | 2 +- src/VIDEO/vid_s3.c | 69 ++-- src/VIDEO/vid_svga.c | 6 +- src/VIDEO/vid_wy700.c | 2 +- src/cdrom-ioctl.c | 1 - src/cdrom-iso.c | 632 ----------------------------------- src/cdrom-iso.h | 15 - src/cdrom-null.c | 31 +- src/cdrom.c | 3 +- src/cdrom.h | 34 +- src/config.c | 446 ++++++++++++++++++++++++ src/config.h | 12 + src/fdc37c932fr.c | 2 + src/ibm.h | 2 - src/network.c | 3 + src/network.h | 3 + src/pc.c | 451 +------------------------ src/resource.h | 8 +- src/serial.c | 24 +- src/win.c | 50 ++- 29 files changed, 610 insertions(+), 1216 deletions(-) delete mode 100644 src/cdrom-iso.c delete mode 100644 src/cdrom-iso.h diff --git a/src/86Box.rc b/src/86Box.rc index 8bc4756d9..f0e8fb74e 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -63,7 +63,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_1_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_1_ISO + MENUITEM "&Image...", IDM_CDROM_1_IMAGE END POPUP "CD-ROM 2" BEGIN @@ -72,7 +72,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_2_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_2_ISO + MENUITEM "&Image...", IDM_CDROM_2_IMAGE END POPUP "CD-ROM 3" BEGIN @@ -81,7 +81,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_3_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_3_ISO + MENUITEM "&Image...", IDM_CDROM_3_IMAGE END POPUP "CD-ROM 4" BEGIN @@ -90,7 +90,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_4_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_4_ISO + MENUITEM "&Image...", IDM_CDROM_4_IMAGE END END @@ -808,7 +808,7 @@ BEGIN 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0" + 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" 2177 "Olivetti M24 mouse" 2178 "" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 71ce8e4e7..93196a298 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -128,7 +128,7 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ - cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o + cdrom.o cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o NETOBJ = network.o net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index 646ba51e9..41553f671 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -469,7 +469,7 @@ void *cga_standalone_init() cga_comp_init(cga->revision); timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); + mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); overscan_x = overscan_y = 16; diff --git a/src/VIDEO/vid_colorplus.c b/src/VIDEO/vid_colorplus.c index 25ceb71dc..ab07127f7 100644 --- a/src/VIDEO/vid_colorplus.c +++ b/src/VIDEO/vid_colorplus.c @@ -379,7 +379,7 @@ void *colorplus_standalone_init() cga_comp_init(1); timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus); - mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, 0, colorplus); + mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); return colorplus; diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index 9243c825f..d97f13ba1 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -925,7 +925,7 @@ void *ega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -961,7 +961,7 @@ void *cpqega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -997,7 +997,7 @@ void *sega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; diff --git a/src/VIDEO/vid_genius.c b/src/VIDEO/vid_genius.c index a0053cc93..35db8905f 100644 --- a/src/VIDEO/vid_genius.c +++ b/src/VIDEO/vid_genius.c @@ -562,7 +562,7 @@ void *genius_init() /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, 0, genius); + mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, genius); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); diff --git a/src/VIDEO/vid_hercules.c b/src/VIDEO/vid_hercules.c index 8eefb409f..a7c5ab73a 100644 --- a/src/VIDEO/vid_hercules.c +++ b/src/VIDEO/vid_hercules.c @@ -320,7 +320,7 @@ void *hercules_init() hercules->vram = malloc(0x10000); timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); - mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, 0, hercules); + mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, hercules); io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); for (c = 0; c < 256; c++) diff --git a/src/VIDEO/vid_herculesplus.c b/src/VIDEO/vid_herculesplus.c index a2a004312..459107d03 100644 --- a/src/VIDEO/vid_herculesplus.c +++ b/src/VIDEO/vid_herculesplus.c @@ -667,7 +667,7 @@ void *herculesplus_init() herculesplus->vram = malloc(0x10000); /* 64k VRAM */ timer_add(herculesplus_poll, &herculesplus->vidtime, TIMER_ALWAYS_ENABLED, herculesplus); - mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, 0, herculesplus); + mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, herculesplus); io_sethandler(0x03b0, 0x0010, herculesplus_in, NULL, NULL, herculesplus_out, NULL, NULL, herculesplus); for (c = 0; c < 256; c++) diff --git a/src/VIDEO/vid_incolor.c b/src/VIDEO/vid_incolor.c index 45cf15d41..636697c1a 100644 --- a/src/VIDEO/vid_incolor.c +++ b/src/VIDEO/vid_incolor.c @@ -1014,7 +1014,7 @@ void *incolor_init() incolor->vram = malloc(0x40000); /* 4 planes of 64k */ timer_add(incolor_poll, &incolor->vidtime, TIMER_ALWAYS_ENABLED, incolor); - mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, 0, incolor); + mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, incolor); io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor); for (c = 0; c < 64; c++) diff --git a/src/VIDEO/vid_mda.c b/src/VIDEO/vid_mda.c index 689cc56ab..7180a4921 100644 --- a/src/VIDEO/vid_mda.c +++ b/src/VIDEO/vid_mda.c @@ -269,7 +269,7 @@ void *mda_init() mda->vram = malloc(0x1000); timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, mda); + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); for (c = 0; c < 256; c++) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index a597cbad8..ae5c8c701 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -736,8 +736,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (val & 8 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; } break; @@ -767,6 +769,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x32: svga->vrammask = (val & 0x40) ? 0x3ffff : s3->vram_mask; @@ -790,19 +796,25 @@ void s3_out(uint16_t addr, uint8_t val, void *p) case 0x35: s3->bank = (s3->bank & 0x70) | (val & 0xf); - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x51: s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: s3->bank = val; - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x3a: @@ -981,7 +993,12 @@ void s3_updatemapping(s3_t *s3) return; } - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) + { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } + else switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -1646,9 +1663,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { - READ(s3->accel.src + s3->accel.cx, src_dat); - - dest_dat = src_dat; + READ(s3->accel.src + s3->accel.cx, dest_dat); + + MIX WRITE(s3->accel.dest + s3->accel.dx); } @@ -1672,8 +1689,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; return; } } @@ -2183,19 +2198,9 @@ int s3_phoenix_trio32_available() void *s3_trio64_init(wchar_t *bios_fn) { - int card_id = 0; s3_t *s3 = s3_init(bios_fn, S3_TRIO64); - card_id = device_get_config_int("card_id"); - - if (card_id) - { - s3->id = 0xc1; /*Vision864P*/ - } - else - { - s3->id = 0xe1; /*Trio64*/ - } + s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; @@ -2390,20 +2395,6 @@ static device_config_t s3_phoenix_trio64_config[] = } } }, - { - "card_id", "Card ID", CONFIG_SELECTION, "", 0, - { - { - "S3 Trio64", 0 - }, - { - "S3 Vision864", 1 - }, - { - "" - } - } - }, { "", "", -1 } diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 80d5983cc..6da19608d 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -971,7 +971,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); memset(svga->vgapal, 0, sizeof(PALETTE)); @@ -1236,7 +1236,7 @@ uint8_t svga_read(uint32_t addr, void *p) if (svga->chain4 || svga->fb_only) { if (addr >= svga->vram_limit) - return 0xff; + return 0x00; return svga->vram[svga_mask_addr(addr, svga)]; } else if (svga->chain2_read) @@ -1254,7 +1254,7 @@ uint8_t svga_read(uint32_t addr, void *p) addr<<=2; if (addr >= svga->vram_limit) - return 0xff; + return 0x00; addr = svga_mask_addr(addr, svga); diff --git a/src/VIDEO/vid_wy700.c b/src/VIDEO/vid_wy700.c index a7b612e09..0091ba534 100644 --- a/src/VIDEO/vid_wy700.c +++ b/src/VIDEO/vid_wy700.c @@ -884,7 +884,7 @@ void *wy700_init() /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, 0, wy700); + mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, wy700); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 5ab4d09a3..c81bd7f14 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -1050,7 +1050,6 @@ static CDROM ioctl_cdrom= NULL, ioctl_getcurrentsubchannel, ioctl_pass_through, - ioctl_sector_data_type, NULL, ioctl_playaudio, ioctl_load, diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c deleted file mode 100644 index 2247baccb..000000000 --- a/src/cdrom-iso.c +++ /dev/null @@ -1,632 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -/*ISO CD-ROM support*/ - -#include - -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-iso.h" - -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE - -#include - -static CDROM iso_cdrom; - -int cdrom_iso_do_log = 0; - -void cdrom_iso_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_ISO_LOG - if (cdrom_iso_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void iso_close(uint8_t id); - -void iso_audio_callback(uint8_t id, int16_t *output, int len) -{ - memset(output, 0, len * 2); - return; -} - -void iso_audio_stop(uint8_t id) -{ - return; -} - -static int iso_ready(uint8_t id) -{ - if (wcslen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - return 1; - } - - if (cdrom_iso[id].iso_changed) - { - cdrom_iso[id].iso_changed = 0; - return 1; - } - - return 1; -} - -static int iso_medium_changed(uint8_t id) -{ - if (wcslen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - return 1; - } - - if (cdrom_iso[id].iso_changed) - { - cdrom_iso[id].iso_changed = 0; - return 1; - } - - return 0; -} - -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - -static uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - int pos=0; - int32_t temp; - if (wcslen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - - b[pos++]=0; - b[pos++]=0; - b[pos++]=0; - - temp = cdrom[id].seek_pos; - if (msf) - { - memset(&(b[pos]), 0, 8); - lba_to_msf(&(b[pos]), temp); - pos += 4; - lba_to_msf(&(b[pos]), temp); - pos += 4; - } - else - { - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } - - return 0x15; -} - -static void iso_eject(uint8_t id) -{ - return; -} - -static void iso_load(uint8_t id) -{ - return; -} - -static int iso_sector_data_type(uint8_t id, int sector, int ismsf) -{ - return 2; /* Always Mode 1 */ -} - -static void iso_readsector(uint8_t id, uint8_t *b, int sector) -{ - uint64_t file_pos = sector; - if (!cdrom_drives[id].host_drive) - { - return; - } - file_pos <<= 11; - memset(b, 0, 2856); - cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); - fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); - fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); - fclose(cdrom_iso[id].iso_image); - - /* sync bytes */ - b[0] = 0; - memset(b + 1, 0xff, 10); - b[11] = 0; - b += 12; - lba_to_msf(b, sector); - b[3] = 1; /* mode 1 data */ - b += 4; - b += 2048; - memset(b, 0, 288); - b += 288; - memset(b, 0, 392); -} - -typedef struct __attribute__((__packed__)) -{ - uint8_t user_data[2048]; - uint8_t ecc[288]; -} m1_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sub_header[8]; - uint8_t user_data[2328]; -} m2_data_t; - -typedef union __attribute__((__packed__)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2352]; -} sector_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((__packed__)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_size; - -static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - uint8_t *b; - uint8_t *temp_b; - int real_pos; - - b = temp_b = buffer; - - *len = 0; - - if (ismsf) - { - real_pos = cdrom_lba_to_msf_accurate(sector); - } - else - { - real_pos = sector; - } - - memset(cdrom_sector_buffer.buffer, 0, 2856); - - if ((cdrom_sector_type == 1) || (cdrom_sector_type > 2)) - { - if (cdrom_sector_type == 1) - { - cdrom_iso_log("CD-ROM %i: Attempting to read an audio sector from an ISO\n", id); - } - if (cdrom_sector_type >= 2) - { - cdrom_iso_log("CD-ROM %i: Attempting to read a non-mode 1 data sector from an ISO\n", id); - } - return 0; - } - - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_iso_log("CD-ROM %i: 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_iso_log("CD-ROM %i: Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_iso_log("CD-ROM %i: Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_iso_log("CD-ROM %i: EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - iso_readsector(id, cdrom_sector_buffer.buffer, real_pos); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_iso_log("CD-ROM %i: Sync\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_iso_log("CD-ROM %i: Header\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - cdrom_iso_log("CD-ROM %i: Sub-header\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_iso_log("CD-ROM %i: User data\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_iso_log("CD-ROM %i: EDC/ECC\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - - if ((cdrom_sector_flags & 0x06) == 0x02) - { - /* Add error flags. */ - cdrom_iso_log("CD-ROM %i: Error flags\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); - cdrom_sector_size += 294; - } - else if ((cdrom_sector_flags & 0x06) == 0x04) - { - /* Add error flags. */ - cdrom_iso_log("CD-ROM %i: Full error flags\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) - { - cdrom_iso_log("CD-ROM %i: Raw subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); - cdrom_sector_size += 96; - } - else if ((cdrom_sector_flags & 0x700) == 0x200) - { - cdrom_iso_log("CD-ROM %i: Q subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); - cdrom_sector_size += 16; - } - else if ((cdrom_sector_flags & 0x700) == 0x400) - { - cdrom_iso_log("CD-ROM %i: R/W subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; -} - -static int iso_readtoc(uint8_t id, unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single) -{ - uint8_t *q; - int len; - - if (start_track > 1 && start_track != 0xaa) - return -1; - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - if (start_track <= 1) { - *q++ = 0; /* reserved */ - *q++ = 0x14; /* ADR, control */ - *q++ = 1; /* track number */ - *q++ = 0; /* reserved */ - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } else { - /* sector 0 */ - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - } - /* lead out track */ - *q++ = 0; /* reserved */ - *q++ = 0x16; /* ADR, control */ - *q++ = 0xaa; /* track number */ - *q++ = 0; /* reserved */ - cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, cdrom_iso[id].last_block); - q += 3; - } else { - *q++ = cdrom_iso[id].last_block >> 24; - *q++ = cdrom_iso[id].last_block >> 16; - *q++ = cdrom_iso[id].last_block >> 8; - *q++ = cdrom_iso[id].last_block; - } - len = q - buf; - if (len > maxlen) - { - len = maxlen; - } - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static int iso_readtoc_session(uint8_t id, unsigned char *buf, int msf, int maxlen) -{ - uint8_t *q; - - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - - if (maxlen < 12) - { - return maxlen; - } - return 12; -} - -static int iso_readtoc_raw(uint8_t id, unsigned char *buf, int msf, int maxlen) -{ - uint8_t *q; - int len; - - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* first track */ - *q++ = 0x00; /* disk type */ - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa1; - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* last track */ - *q++ = 0x00; - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa2; /* lead-out */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; - /* this is raw, must be msf */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, cdrom_iso[id].last_block); - q += 3; - } - else - { - *q++ = (cdrom_iso[id].last_block >> 24) & 0xff; - *q++ = (cdrom_iso[id].last_block >> 16) & 0xff; - *q++ = (cdrom_iso[id].last_block >> 8) & 0xff; - *q++ = cdrom_iso[id].last_block & 0xff; - } - - *q++ = 1; /* session number */ - *q++ = 0x14; /* ADR, control */ - *q++ = 0; /* track number */ - *q++ = 1; /* point */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - /* same here */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } - else - { - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - - len = q - buf; - if (len > maxlen) - { - len = maxlen; - } - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static uint32_t iso_size(uint8_t id) -{ - uint64_t iso_size; - - cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); - fseeko64(cdrom_iso[id].iso_image, 0, SEEK_END); - iso_size = ftello64(cdrom_iso[id].iso_image); - iso_size >>= 11; - fclose(cdrom_iso[id].iso_image); - - return (uint32_t) (iso_size); -} - -static int iso_status(uint8_t id) -{ - if (!(iso_ready(id)) && (cdrom_drives[id].host_drive != 200)) return CD_STATUS_EMPTY; - - return CD_STATUS_DATA_ONLY; -} - -void iso_reset(uint8_t id) -{ -} - -int iso_open(uint8_t id, wchar_t *fn) -{ - FILE *f; - - if (wcscmp(fn, cdrom_iso[id].iso_path) != 0) - { - cdrom_iso[id].iso_changed = 1; - } - /* Make sure iso_changed stays when changing from ISO to another ISO. */ - if (!cdrom_iso[id].iso_inited && (cdrom_drives[id].host_drive != 200)) cdrom_iso[id].iso_changed = 0; - if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) - { - _swprintf(cdrom_iso[id].iso_path, L"%ws", fn); - } - cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); - cdrom_drives[id].handler = &iso_cdrom; - if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) - { - if (!cdrom_iso[id].iso_inited) cdrom_iso[id].iso_inited = 1; - fclose(cdrom_iso[id].iso_image); - } - - f = _wfopen(cdrom_iso[id].iso_path, L"rb"); - fseeko64(f, 0, SEEK_END); - cdrom_iso[id].image_size = ftello64(f); - fclose(f); - - return 0; -} - -void iso_close(uint8_t id) -{ - if (cdrom_iso[id].iso_image) fclose(cdrom_iso[id].iso_image); - memset(cdrom_iso[id].iso_path, 0, 1024); -} - -static void iso_exit(uint8_t id) -{ - cdrom_iso[id].iso_inited = 0; -} - -static int iso_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - return 0; -} - -static int iso_media_type_id(uint8_t id) -{ - if (iso_size(id) <= 405000) - { - return 1; /* Data CD. */ - } - else - { - return 65; /* DVD. */ - } -} - -static CDROM iso_cdrom = -{ - iso_ready, - iso_medium_changed, - iso_media_type_id, - NULL, - NULL, - iso_readtoc, - iso_readtoc_session, - iso_readtoc_raw, - iso_getcurrentsubchannel, - NULL, - iso_sector_data_type, - iso_readsector_raw, - NULL, - iso_load, - iso_eject, - NULL, - NULL, - iso_size, - iso_status, - iso_is_track_audio, - NULL, - iso_exit -}; diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h deleted file mode 100644 index fa7b734fa..000000000 --- a/src/cdrom-iso.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_ISO_H -#define CDROM_ISO_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern int iso_open(uint8_t id, wchar_t *fn); -extern void iso_reset(uint8_t id); - -extern void iso_close(uint8_t id); - -#endif /* ! CDROM_ISO_H */ diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 9c52cc848..e5a8caf2d 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -31,11 +31,6 @@ static void null_load(uint8_t id) { } -static int null_sector_data_type(uint8_t id, int sector, int ismsf) -{ - return 0; -} - static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) { *len = 0; @@ -100,28 +95,34 @@ static int null_media_type_id(uint8_t id) return 0x70; } +void cdrom_set_null_handler(uint8_t id) +{ + cdrom_drives[id].handler = &null_cdrom; + cdrom_drives[id].host_drive = 0; + update_status_bar_icon_state(0x10 | id, 1); +} + static CDROM null_cdrom = { - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, + null_ready, + null_medium_changed, + null_media_type_id, + NULL, + NULL, null_readtoc, null_readtoc_session, - null_readtoc_raw, + null_readtoc_raw, null_getcurrentsubchannel, null_pass_through, - null_sector_data_type, - null_readsector_raw, + null_readsector_raw, NULL, null_load, null_eject, NULL, NULL, null_size, - null_status, - null_is_track_audio, + null_status, + null_is_track_audio, NULL, null_exit }; diff --git a/src/cdrom.c b/src/cdrom.c index 09f55ac4d..bb286451f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2893,8 +2893,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; } - if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || - !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) + if ((cdrom_drive < 1) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { cdrom_illegal_mode(id); break; diff --git a/src/cdrom.h b/src/cdrom.h index 85f03a4b0..678b64086 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -15,7 +15,7 @@ #define BUF_SIZE 32768 -#define CDROM_ISO 200 +#define CDROM_IMAGE 200 #define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) #define CDROM_TIME (5 * 100 * (1 << TIMER_SHIFT)) @@ -32,7 +32,6 @@ typedef struct CDROM int (*readtoc_raw)(uint8_t id, uint8_t *b, int msf, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len); - int (*sector_data_type)(uint8_t id, int sector, int ismsf); int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); void (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf); void (*load)(uint8_t id); @@ -170,18 +169,23 @@ extern void (*ide_bus_master_set_irq)(int channel); typedef struct { - uint32_t last_block; - uint64_t image_size; - int iso_inited; - wchar_t iso_path[1024]; - FILE* iso_image; - int iso_changed; + int image_is_iso; + uint32_t last_block; + uint32_t cdrom_capacity; + int image_inited; + wchar_t image_path[1024]; + FILE* image; + int image_changed; + + int cd_state; uint32_t cd_pos; uint32_t cd_end; -} cdrom_iso_t; + int16_t cd_buffer[BUF_SIZE]; + int cd_buflen; +} cdrom_image_t; -cdrom_iso_t cdrom_iso[CDROM_NUM]; +cdrom_image_t cdrom_image[CDROM_NUM]; typedef struct { @@ -211,7 +215,17 @@ void cdrom_command(uint8_t id, uint8_t *cdb); void cdrom_phase_callback(uint8_t id); uint32_t cdrom_read(uint8_t channel, int length); void cdrom_write(uint8_t channel, uint32_t val, int length); + +#ifdef __cplusplus +extern "C" { +#endif + int cdrom_lba_to_msf_accurate(int lba); + +#ifdef __cplusplus +} +#endif + void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); diff --git a/src/config.c b/src/config.c index c72de4da8..f52cfd978 100644 --- a/src/config.c +++ b/src/config.c @@ -2,11 +2,33 @@ see COPYING for more details */ #include +#include #include #include #include + +#include "cdrom.h" #include "config.h" +#include "device.h" +#include "disc.h" +#include "fdc.h" +#include "fdd.h" #include "ibm.h" +#include "cpu/cpu.h" +#include "gameport.h" +#include "ide.h" +#include "hdd.h" +#include "model.h" +#include "mouse.h" +#include "network.h" +#include "net_ne2000.h" +#include "nvr.h" +#include "plat-joystick.h" +#include "scsi.h" +#include "sound/snd_dbopl.h" +#include "sound/snd_opl.h" +#include "sound/sound.h" +#include "video/video.h" wchar_t config_file_default[256]; @@ -495,3 +517,427 @@ void config_save(wchar_t *fn) fclose(f); } +void loadconfig(wchar_t *fn) +{ + int c, d; + char s[512]; + char *p; + wchar_t *wp, *wq; + char temps[512]; + + if (!fn) + config_load(config_file_default); + else + config_load(fn); + + GAMEBLASTER = config_get_int(NULL, "gameblaster", 0); + GUS = config_get_int(NULL, "gus", 0); + SSI2001 = config_get_int(NULL, "ssi2001", 0); + voodoo_enabled = config_get_int(NULL, "voodoo", 0); + + /* SCSI */ + p = (char *)config_get_string(NULL, "scsicard", ""); + if (p) + scsi_card_current = scsi_card_get_from_internal_name(p); + else + scsi_card_current = 0; + + /* network */ + ethif = config_get_int(NULL, "netinterface", 1); + if (ethif >= inum) + inum = ethif + 1; + p = (char *)config_get_string(NULL, "netcard", ""); + if (p) + network_card_current = network_card_get_from_internal_name(p); + else + network_card_current = 0; + ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); + ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); + + p = (char *)config_get_string(NULL, "model", ""); + if (p) + model = model_get_model_from_internal_name(p); + else + model = 0; + + if (model >= model_count()) + model = model_count() - 1; + + romset = model_getromset(); + cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); + cpu = config_get_int(NULL, "cpu", 0); + cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0); + + cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); + + p = (char *)config_get_string(NULL, "gfxcard", ""); + if (p) + gfxcard = video_get_video_from_internal_name(p); + else + gfxcard = 0; + video_speed = config_get_int(NULL, "video_speed", 3); + p = (char *)config_get_string(NULL, "sndcard", ""); + if (p) + sound_card_current = sound_card_get_from_internal_name(p); + else + sound_card_current = 0; + + mem_size = config_get_int(NULL, "mem_size", 4096); + if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); + if (p) + fdd_set_type(c, fdd_get_from_internal_name(p)); + else + fdd_set_type(c, (c < 2) ? 2 : 0); + + sprintf(temps, "fdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(discfns[c], wp, 512); + else { + memcpy(discfns[c], L"", 2); + discfns[c][0] = L'\0'; + } + printf("Floppy: %ws\n", discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = config_get_int(NULL, temps, 0); + } + + p = (char *)config_get_string(NULL, "hdd_controller", ""); + if (p) + strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); + else + strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + ide_enable[c] = config_get_int(NULL, temps, 0); + sprintf(temps, "ide_%02i_irq", c + 1); + ide_irq[c] = config_get_int(NULL, temps, 8 + c); + } + + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + hdc[c].spt = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_heads", c + 1); + hdc[c].hpc = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + hdc[c].tracks = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + hdc[c].bus = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + hdc[c].mfm_channel = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + hdc[c].ide_channel = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + hdc[c].scsi_lun = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(hdd_fn[c], wp, 512); + else { + memcpy(hdd_fn[c], L"", 2); + hdd_fn[c][0] = L'\0'; + } + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); + cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; + sprintf(temps, "cdrom_%02i_enabled", c + 1); + cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(cdrom_image[c].image_path, wp, 512); + else { + memcpy(cdrom_image[c].image_path, L"", 2); + cdrom_image[c].image_path[0] = L'\0'; + } + } + + vid_resize = config_get_int(NULL, "vid_resize", 0); + vid_api = config_get_int(NULL, "vid_api", 0); + video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); + + force_43 = config_get_int(NULL, "force_43", 0); + scale = config_get_int(NULL, "scale", 1); + enable_overscan = config_get_int(NULL, "enable_overscan", 0); + + enable_sync = config_get_int(NULL, "enable_sync", 1); + opl3_type = config_get_int(NULL, "opl3_type", 1); + + window_w = config_get_int(NULL, "window_w", 0); + window_h = config_get_int(NULL, "window_h", 0); + window_x = config_get_int(NULL, "window_x", 0); + window_y = config_get_int(NULL, "window_y", 0); + window_remember = config_get_int(NULL, "window_remember", 0); + + joystick_type = config_get_int(NULL, "joystick_type", 0); + p = (char *)config_get_string(NULL, "mouse_type", ""); + if (p) + mouse_type = mouse_get_from_internal_name(p); + else + mouse_type = 0; + + enable_xtide = config_get_int(NULL, "enable_xtide", 1); + enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); + } + } + } + + memset(nvr_path, 0, 2048); + wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); + if (wp) { + if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); + else + { + append_filename_w(nvr_path, pcempath, L"nvr", 511); + } + } + else append_filename_w(nvr_path, pcempath, L"nvr", 511); + + if (nvr_path[wcslen(nvr_path) - 1] != L'/') + { + if (nvr_path[wcslen(nvr_path) - 1] != L'\\') + { + nvr_path[wcslen(nvr_path)] = L'/'; + nvr_path[wcslen(nvr_path) + 1] = L'\0'; + } + } + + path_len = wcslen(nvr_path); + + serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); + serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); + lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); + bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); +} + +wchar_t temp_nvr_path[1024]; + +wchar_t *nvr_concat(wchar_t *to_concat) +{ + char *p; + + memset(temp_nvr_path, 0, 2048); + wcscpy(temp_nvr_path, nvr_path); + + p = (char *) temp_nvr_path; + p += (path_len * 2); + wchar_t *wp = (wchar_t *) p; + + wcscpy(wp, to_concat); + return temp_nvr_path; +} + +void saveconfig(void) +{ + int c, d; + + char temps[512]; + + config_set_int(NULL, "gameblaster", GAMEBLASTER); + config_set_int(NULL, "gus", GUS); + config_set_int(NULL, "ssi2001", SSI2001); + config_set_int(NULL, "voodoo", voodoo_enabled); + + config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + + config_set_int(NULL, "netinterface", ethif); + config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); + config_set_int(NULL, "maclocal", net2000_get_maclocal()); + config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); + + config_set_string(NULL, "model", model_get_internal_name()); + config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); + config_set_int(NULL, "cpu", cpu); + config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); + config_set_int(NULL, "cpu_waitstates", cpu_waitstates); + + config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int(NULL, "video_speed", video_speed); + config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); + config_set_int(NULL, "cpu_speed", cpuspeed); + config_set_int(NULL, "has_fpu", hasfpu); + + config_set_int(NULL, "mem_size", mem_size); + + memset(temps, 0, 512); + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); + sprintf(temps, "fdd_%02i_fn", c + 1); + config_set_wstring(NULL, temps, discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_set_int(NULL, temps, ui_writeprot[c]); + } + + config_set_string(NULL, "hdd_controller", hdd_controller_name); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + config_set_int(NULL, temps, ide_enable[c]); + sprintf(temps, "ide_%02i_irq", c + 1); + config_set_int(NULL, temps, ide_irq[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + config_set_int(NULL, temps, hdc[c].spt); + sprintf(temps, "hdd_%02i_heads", c + 1); + config_set_int(NULL, temps, hdc[c].hpc); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + config_set_int(NULL, temps, hdc[c].tracks); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + config_set_int(NULL, temps, hdc[c].bus); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + config_set_int(NULL, temps, hdc[c].mfm_channel); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, hdc[c].ide_channel); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_id); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_lun); + sprintf(temps, "hdd_%02i_fn", c + 1); + config_set_wstring(NULL, temps, hdd_fn[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].host_drive); + sprintf(temps, "cdrom_%02i_enabled", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].enabled); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].sound_on); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].bus_type); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].ide_channel); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + config_set_wstring(NULL, temps, cdrom_image[c].image_path); + } + + config_set_int(NULL, "vid_resize", vid_resize); + config_set_int(NULL, "vid_api", vid_api); + config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); + + config_set_int(NULL, "force_43", force_43); + config_set_int(NULL, "scale", scale); + config_set_int(NULL, "enable_overscan", enable_overscan); + + config_set_int(NULL, "enable_sync", enable_sync); + config_set_int(NULL, "opl3_type", opl3_type); + + config_set_int(NULL, "joystick_type", joystick_type); + config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); + + config_set_int(NULL, "enable_xtide", enable_xtide); + config_set_int(NULL, "enable_external_fpu", enable_external_fpu); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + char s[80]; + + sprintf(s, "joystick_%i_nr", c); + config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); + } + } + } + + config_set_int(NULL, "window_w", window_w); + config_set_int(NULL, "window_h", window_h); + config_set_int(NULL, "window_x", window_x); + config_set_int(NULL, "window_y", window_y); + config_set_int(NULL, "window_remember", window_remember); + + config_set_int(NULL, "serial1_enabled", serial_enabled[0]); + config_set_int(NULL, "serial2_enabled", serial_enabled[1]); + config_set_int(NULL, "lpt_enabled", lpt_enabled); + config_set_int(NULL, "bugger_enabled", bugger_enabled); + + config_save(config_file_default); +} diff --git a/src/config.h b/src/config.h index feab20d60..766257f37 100644 --- a/src/config.h +++ b/src/config.h @@ -15,11 +15,23 @@ void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); void put_backslash(char *s); void put_backslash_w(wchar_t *s); char *get_extension(char *s); + +#ifdef __cplusplus +extern "C" { +#endif + wchar_t *get_extension_w(wchar_t *s); +#ifdef __cplusplus +} +#endif + void config_load(wchar_t *fn); void config_save(wchar_t *fn); void config_dump(void); void config_free(void); extern wchar_t config_file_default[256]; + +void loadconfig(wchar_t *fn); +void saveconfig(void); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 96469ef5b..5b4057d1e 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -443,6 +443,7 @@ void fdc37c932fr_reset(void) fdc37c932fr_ld_regs[4][0x61] = 0xf8; fdc37c932fr_ld_regs[4][0x70] = 4; fdc37c932fr_ld_regs[4][0xF0] = 3; + serial_setup(1, 0x3f8, fdc37c932fr_ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ fdc37c932fr_ld_regs[5][0x30] = 1; @@ -452,6 +453,7 @@ void fdc37c932fr_reset(void) fdc37c932fr_ld_regs[5][0x74] = 4; fdc37c932fr_ld_regs[5][0xF1] = 2; fdc37c932fr_ld_regs[5][0xF2] = 3; + serial_setup(2, 0x2f8, fdc37c932fr_ld_regs[5][0x70]); /* Logical device 6: RTC */ fdc37c932fr_ld_regs[6][0x63] = 0x70; diff --git a/src/ibm.h b/src/ibm.h index c163e5f15..668462244 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -676,8 +676,6 @@ uint64_t timer_read(); extern uint64_t timer_freq; -void loadconfig(wchar_t *fn); - extern int infocus; void onesec(); diff --git a/src/network.c b/src/network.c index 5f4a3f95e..861a09ded 100644 --- a/src/network.c +++ b/src/network.c @@ -39,6 +39,9 @@ static NETCARD net_cards[] = { int network_card_current = 0; +uint8_t ethif; +int inum; + static void net_poll(void *priv) diff --git a/src/network.h b/src/network.h index 59c379a64..559be9e34 100644 --- a/src/network.h +++ b/src/network.h @@ -12,6 +12,9 @@ extern int network_card_current; +extern uint8_t ethif; +extern int inum; + extern void network_init(void); extern void network_reset(void); diff --git a/src/pc.c b/src/pc.c index b2a2c7a82..67a088d2e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -36,7 +36,7 @@ #include "hdd.h" #include "ide.h" #include "cdrom.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "cdrom-null.h" #include "scsi.h" #include "keyboard.h" @@ -70,9 +70,6 @@ #endif -uint8_t ethif; -int inum; - wchar_t nvr_path[1024]; int path_len; @@ -373,17 +370,7 @@ void initpc(int argc, wchar_t *argv[]) { if (cdrom_drives[i].host_drive == 200) { - ff = _wfopen(cdrom_iso[i].iso_path, L"rb"); - if (ff) - { - fclose(ff); - iso_open(i, cdrom_iso[i].iso_path); - } - else - { - cdrom_drives[i].host_drive = 0; - cdrom_null_open(i, cdrom_drives[i].host_drive); - } + image_open(i, cdrom_image[i].image_path); } else { @@ -422,7 +409,7 @@ void initpc(int argc, wchar_t *argv[]) { if (cdrom_drives[i].host_drive == 200) { - iso_reset(i); + image_reset(i); } else { @@ -485,7 +472,6 @@ void resetpchard(void) disc_reset(); model_init(); - mouse_emu_init(); video_init(); speaker_init(); @@ -526,6 +512,7 @@ void resetpchard(void) device_add(&voodoo_device); hdd_controller_init(hdd_controller_name); pc_reset(); + mouse_emu_init(); loadnvr(); @@ -542,7 +529,7 @@ void resetpchard(void) { if (cdrom_drives[i].host_drive == 200) { - iso_reset(i); + image_reset(i); } else { @@ -700,431 +687,3 @@ void closepc(void) device_close_all(); midi_close(); } - - -void loadconfig(wchar_t *fn) -{ - int c, d; - char s[512]; - char *p; - wchar_t *wp, *wq; - char temps[512]; - - if (!fn) - config_load(config_file_default); - else - config_load(fn); - - GAMEBLASTER = config_get_int(NULL, "gameblaster", 0); - GUS = config_get_int(NULL, "gus", 0); - SSI2001 = config_get_int(NULL, "ssi2001", 0); - voodoo_enabled = config_get_int(NULL, "voodoo", 0); - - /* SCSI */ - p = (char *)config_get_string(NULL, "scsicard", ""); - if (p) - scsi_card_current = scsi_card_get_from_internal_name(p); - else - scsi_card_current = 0; - - /* network */ - ethif = config_get_int(NULL, "netinterface", 1); - if (ethif >= inum) - inum = ethif + 1; - p = (char *)config_get_string(NULL, "netcard", ""); - if (p) - network_card_current = network_card_get_from_internal_name(p); - else - network_card_current = 0; - ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); - ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); - - p = (char *)config_get_string(NULL, "model", ""); - if (p) - model = model_get_model_from_internal_name(p); - else - model = 0; - - if (model >= model_count()) - model = model_count() - 1; - - romset = model_getromset(); - cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); - cpu = config_get_int(NULL, "cpu", 0); - cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0); - - cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); - - p = (char *)config_get_string(NULL, "gfxcard", ""); - if (p) - gfxcard = video_get_video_from_internal_name(p); - else - gfxcard = 0; - video_speed = config_get_int(NULL, "video_speed", 3); - p = (char *)config_get_string(NULL, "sndcard", ""); - if (p) - sound_card_current = sound_card_get_from_internal_name(p); - else - sound_card_current = 0; - - mem_size = config_get_int(NULL, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); - if (p) - fdd_set_type(c, fdd_get_from_internal_name(p)); - else - fdd_set_type(c, (c < 2) ? 2 : 0); - - sprintf(temps, "fdd_%02i_fn", c + 1); - wp = (WCHAR *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(discfns[c], wp, 512); - else { - memcpy(discfns[c], L"", 2); - discfns[c][0] = L'\0'; - } - printf("Floppy: %ws\n", discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = config_get_int(NULL, temps, 0); - } - - p = (char *)config_get_string(NULL, "hdd_controller", ""); - if (p) - strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); - else - strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - ide_enable[c] = config_get_int(NULL, temps, 0); - sprintf(temps, "ide_%02i_irq", c + 1); - ide_irq[c] = config_get_int(NULL, temps, 8 + c); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - hdc[c].spt = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_heads", c + 1); - hdc[c].hpc = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - hdc[c].tracks = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - hdc[c].bus = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - hdc[c].scsi_lun = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_fn", c + 1); - wp = (WCHAR *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(hdd_fn[c], wp, 512); - else { - memcpy(hdd_fn[c], L"", 2); - hdd_fn[c][0] = L'\0'; - } - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); - cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; - sprintf(temps, "cdrom_%02i_enabled", c + 1); - cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); - - sprintf(temps, "cdrom_%02i_iso_path", c + 1); - wp = (WCHAR *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(cdrom_iso[c].iso_path, wp, 512); - else { - memcpy(cdrom_iso[c].iso_path, L"", 2); - cdrom_iso[c].iso_path[0] = L'\0'; - } - } - - vid_resize = config_get_int(NULL, "vid_resize", 0); - vid_api = config_get_int(NULL, "vid_api", 0); - video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); - - force_43 = config_get_int(NULL, "force_43", 0); - scale = config_get_int(NULL, "scale", 1); - enable_overscan = config_get_int(NULL, "enable_overscan", 0); - enable_flash = config_get_int(NULL, "enable_flash", 1); - - enable_sync = config_get_int(NULL, "enable_sync", 1); - opl3_type = config_get_int(NULL, "opl3_type", 1); - - window_w = config_get_int(NULL, "window_w", 0); - window_h = config_get_int(NULL, "window_h", 0); - window_x = config_get_int(NULL, "window_x", 0); - window_y = config_get_int(NULL, "window_y", 0); - window_remember = config_get_int(NULL, "window_remember", 0); - - joystick_type = config_get_int(NULL, "joystick_type", 0); - p = (char *)config_get_string(NULL, "mouse_type", ""); - if (p) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; - - enable_xtide = config_get_int(NULL, "enable_xtide", 1); - enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); - } - } - } - - memset(nvr_path, 0, 2048); - wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); - if (wp) { - if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); - else - { - append_filename_w(nvr_path, pcempath, L"nvr", 511); - } - } - else append_filename_w(nvr_path, pcempath, L"nvr", 511); - - if (nvr_path[wcslen(nvr_path) - 1] != L'/') - { - if (nvr_path[wcslen(nvr_path) - 1] != L'\\') - { - nvr_path[wcslen(nvr_path)] = L'/'; - nvr_path[wcslen(nvr_path) + 1] = L'\0'; - } - } - - path_len = wcslen(nvr_path); - - serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); - serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); - lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); - bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); -} - -wchar_t temp_nvr_path[1024]; - -wchar_t *nvr_concat(wchar_t *to_concat) -{ - char *p; - - memset(temp_nvr_path, 0, 2048); - wcscpy(temp_nvr_path, nvr_path); - - p = (char *) temp_nvr_path; - p += (path_len * 2); - wchar_t *wp = (wchar_t *) p; - - wcscpy(wp, to_concat); - return temp_nvr_path; -} - -void saveconfig(void) -{ - int c, d; - - char temps[512]; - - config_set_int(NULL, "gameblaster", GAMEBLASTER); - config_set_int(NULL, "gus", GUS); - config_set_int(NULL, "ssi2001", SSI2001); - config_set_int(NULL, "voodoo", voodoo_enabled); - - config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - - config_set_int(NULL, "netinterface", ethif); - config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); - config_set_int(NULL, "maclocal", net2000_get_maclocal()); - config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); - - config_set_string(NULL, "model", model_get_internal_name()); - config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); - config_set_int(NULL, "cpu", cpu); - config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(NULL, "cpu_waitstates", cpu_waitstates); - - config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(NULL, "video_speed", video_speed); - config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int(NULL, "cpu_speed", cpuspeed); - config_set_int(NULL, "has_fpu", hasfpu); - - config_set_int(NULL, "mem_size", mem_size); - - memset(temps, 0, 512); - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); - sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring(NULL, temps, discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int(NULL, temps, ui_writeprot[c]); - } - - config_set_string(NULL, "hdd_controller", hdd_controller_name); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - config_set_int(NULL, temps, ide_enable[c]); - sprintf(temps, "ide_%02i_irq", c + 1); - config_set_int(NULL, temps, ide_irq[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - config_set_int(NULL, temps, hdc[c].spt); - sprintf(temps, "hdd_%02i_heads", c + 1); - config_set_int(NULL, temps, hdc[c].hpc); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - config_set_int(NULL, temps, hdc[c].tracks); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - config_set_int(NULL, temps, hdc[c].bus); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int(NULL, temps, hdc[c].mfm_channel); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, hdc[c].ide_channel); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_id); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_lun); - sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring(NULL, temps, hdd_fn[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].host_drive); - sprintf(temps, "cdrom_%02i_enabled", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].enabled); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].sound_on); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].bus_type); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].ide_channel); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); - - sprintf(temps, "cdrom_%02i_iso_path", c + 1); - config_set_wstring(NULL, temps, cdrom_iso[c].iso_path); - } - - config_set_int(NULL, "vid_resize", vid_resize); - config_set_int(NULL, "vid_api", vid_api); - config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); - - config_set_int(NULL, "force_43", force_43); - config_set_int(NULL, "scale", scale); - config_set_int(NULL, "enable_overscan", enable_overscan); - config_set_int(NULL, "enable_flash", enable_flash); - - config_set_int(NULL, "enable_sync", enable_sync); - config_set_int(NULL, "opl3_type", opl3_type); - - config_set_int(NULL, "joystick_type", joystick_type); - config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); - - config_set_int(NULL, "enable_xtide", enable_xtide); - config_set_int(NULL, "enable_external_fpu", enable_external_fpu); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - char s[80]; - - sprintf(s, "joystick_%i_nr", c); - config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); - } - } - } - - config_set_int(NULL, "window_w", window_w); - config_set_int(NULL, "window_h", window_h); - config_set_int(NULL, "window_x", window_x); - config_set_int(NULL, "window_y", window_y); - config_set_int(NULL, "window_remember", window_remember); - - config_set_int(NULL, "serial1_enabled", serial_enabled[0]); - config_set_int(NULL, "serial2_enabled", serial_enabled[1]); - config_set_int(NULL, "lpt_enabled", lpt_enabled); - config_set_int(NULL, "bugger_enabled", bugger_enabled); - - config_save(config_file_default); -} diff --git a/src/resource.h b/src/resource.h index 2fffe255d..bc0d8da03 100644 --- a/src/resource.h +++ b/src/resource.h @@ -158,22 +158,22 @@ #define IDM_VID_INVERT 40079 #define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_ISO 40144 +#define IDM_CDROM_1_IMAGE 40144 #define IDM_CDROM_1_RELOAD 40160 #define IDM_CDROM_1_EMPTY 40176 #define IDM_CDROM_1_REAL 40192 #define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_ISO 40145 +#define IDM_CDROM_2_IMAGE 40145 #define IDM_CDROM_2_RELOAD 40161 #define IDM_CDROM_2_EMPTY 40177 #define IDM_CDROM_2_REAL 40193 #define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_ISO 40146 +#define IDM_CDROM_3_IMAGE 40146 #define IDM_CDROM_3_RELOAD 40162 #define IDM_CDROM_3_EMPTY 40178 #define IDM_CDROM_3_REAL 40194 #define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_ISO 40147 +#define IDM_CDROM_4_IMAGE 40147 #define IDM_CDROM_4_RELOAD 40163 #define IDM_CDROM_4_EMPTY 40179 #define IDM_CDROM_4_REAL 40195 diff --git a/src/serial.c b/src/serial.c index 1d401ad00..60b7ba3a3 100644 --- a/src/serial.c +++ b/src/serial.c @@ -505,8 +505,7 @@ serial_setup(int port, uint16_t addr, int irq) serial_read, NULL, NULL, serial_write, NULL, NULL, sp); - /* No DTR/RTS callback for now. */ - sp->rts_callback = NULL; + pclog("Serial%d: RTSCallback=%08X\n", port, sp->rts_callback); } @@ -519,13 +518,16 @@ serial_remove(int port) /* Grab the desired port block. */ sp = (port == 2) ? &serial2 : &serial1; + pclog("Serial%d: Remove I/O=%04x, IRQ=%d\n", port, sp->addr, sp->irq); + // FIXME: stop timer, if enabled! /* Remove any callbacks. */ - sp->rts_callback = NULL; + /* Commented out by Kotori: This messes with the Super I/O chip. */ + /* sp->rts_callback = NULL; */ /* Close the host device. */ - (void)serial_link(port, NULL); + /* (void)serial_link(port, NULL); */ /* Release our I/O range. */ if (sp->addr != 0x0000) { @@ -535,6 +537,8 @@ serial_remove(int port) } sp->addr = 0x0000; sp->irq = 0; + + pclog("Serial%d: RTSCallback=%08X\n", port, sp->rts_callback); } @@ -542,13 +546,19 @@ serial_remove(int port) void serial_init(void) { + pclog("serial_init()\n"); + memset(&serial1, 0x00, sizeof(SERIAL)); serial1.port = 1; serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + /* No DTR/RTS callback for now. */ + serial1.rts_callback = NULL; memset(&serial2, 0x00, sizeof(SERIAL)); serial2.port = 2; serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); + /* No DTR/RTS callback for now. */ + serial2.rts_callback = NULL; } @@ -560,11 +570,17 @@ serial_init(void) void serial_reset(void) { + pclog("serial_reset()\n"); + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; serial1.fifo_read = serial1.fifo_write = 0; + /* No DTR/RTS callback for now. */ + serial1.rts_callback = NULL; serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; serial2.fifo_read = serial2.fifo_write = 0; + /* No DTR/RTS callback for now. */ + serial2.rts_callback = NULL; } diff --git a/src/win.c b/src/win.c index faf311758..ef37362d3 100644 --- a/src/win.c +++ b/src/win.c @@ -33,7 +33,7 @@ #include "cdrom.h" #include "cdrom-null.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "video/video.h" #include "video/vid_ega.h" #include "plat-keyboard.h" @@ -760,7 +760,7 @@ void update_status_bar_icon_state(int tag, int state) discfns[tag & 0x0f][0] = L'\0'; break; case 0x10: - cdrom_iso[tag & 0x0f].iso_path[0] = L'\0'; + cdrom_image[tag & 0x0f].image_path[0] = L'\0'; break; } } @@ -807,13 +807,13 @@ void create_cdrom_tip(int part) if (cdrom_drives[drive].host_drive == 200) { - if (wcslen(cdrom_iso[drive].iso_path) == 0) + if (wcslen(cdrom_image[drive].image_path) == 0) { _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_iso[drive].iso_path); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); } } else if (cdrom_drives[drive].host_drive < 0x41) @@ -885,7 +885,7 @@ static int get_cd_state(int id) { if (cdrom_drives[id].host_drive == 0x200) { - return (wcslen(cdrom_iso[id].iso_path) == 0) ? 1 : 0; + return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; } else { @@ -983,7 +983,7 @@ void update_status_bar_panes(HWND hwnds) { if (cdrom_drives[id].host_drive == 0x200) { - sb_icon_flags[i] = (wcslen(cdrom_iso[id].iso_path) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; } else { @@ -1216,7 +1216,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (cdrom_drives[e].host_drive == 200) { - CheckMenuItem(smenu, IDM_CDROM_1_ISO + e, MF_CHECKED); + CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); } else if (cdrom_drives[e].host_drive >= 65) { @@ -1411,9 +1411,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, TerminateThread(mainthreadh,0); savenvr(); saveconfig(); - if (save_window_pos && window_remember) - saveconfig(); - closepc(); + closepc(); vid_apis[video_fullscreen][vid_api].close(); @@ -1464,7 +1462,7 @@ void cdrom_close(uint8_t id) ioctl_close(id); break; case 200: - iso_close(id); + image_close(id); break; } } @@ -1547,7 +1545,7 @@ void win_cdrom_eject(uint8_t id) } if (cdrom_drives[id].host_drive == 200) { - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); } else { @@ -1574,7 +1572,7 @@ void win_cdrom_reload(uint8_t id) cdrom_close(id); if (cdrom_drives[id].prev_host_drive == 200) { - iso_open(id, cdrom_iso[id].iso_path); + image_open(id, cdrom_image[id].image_path); if (cdrom_drives[id].enabled) { /* Signal disc change to the emulated machine. */ @@ -1582,7 +1580,7 @@ void win_cdrom_reload(uint8_t id) } CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); } else { @@ -2144,7 +2142,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR RECT rc; POINT pt; - WCHAR temp_iso_path[1024]; + WCHAR temp_image_path[1024]; int new_cdrom_drive; int cdrom_id = 0; int menu_sub_param = 0; @@ -2261,24 +2259,24 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR win_cdrom_reload(cdrom_id); break; - case IDM_CDROM_1_ISO: - case IDM_CDROM_2_ISO: - case IDM_CDROM_3_ISO: - case IDM_CDROM_4_ISO: + case IDM_CDROM_1_IMAGE: + case IDM_CDROM_2_IMAGE: + case IDM_CDROM_3_IMAGE: + case IDM_CDROM_4_IMAGE: cdrom_id = LOWORD(wParam) & 3; hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_w_st(hwnd, 2175, cdrom_iso[cdrom_id].iso_path, 0)) + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) { cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - wcscpy(temp_iso_path, wopenfilestring); - if ((wcscmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) { - /* Switching from ISO to the same ISO. Do nothing. */ + /* Switching from image to the same image. Do nothing. */ break; } cdrom_drives[cdrom_id].handler->exit(cdrom_id); cdrom_close(cdrom_id); - iso_open(cdrom_id, temp_iso_path); + image_open(cdrom_id, temp_image_path); if (cdrom_drives[cdrom_id].enabled) { /* Signal disc change to the emulated machine. */ @@ -2290,7 +2288,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); } cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); @@ -2324,7 +2322,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); } - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); From adfbf25391723bbc73cad0c1cfe552220d1ac3e5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 05:15:04 +0200 Subject: [PATCH 172/392] Committed 4 files I forgot to commit earlier. --- src/cdrom-dosbox.cpp | 560 +++++++++++++++++++++++ src/cdrom-dosbox.h | 173 +++++++ src/cdrom-image.cc | 1018 ++++++++++++++++++++++++++++++++++++++++++ src/cdrom-image.h | 25 ++ 4 files changed, 1776 insertions(+) create mode 100644 src/cdrom-dosbox.cpp create mode 100644 src/cdrom-dosbox.h create mode 100644 src/cdrom-image.cc create mode 100644 src/cdrom-image.h diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp new file mode 100644 index 000000000..86f09e8c8 --- /dev/null +++ b/src/cdrom-dosbox.cpp @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#include +#include +#include +#include +#include +#include +#include //GCC 2.95 +#include +#include +#include +#include "cdrom-dosbox.h" + +#if !defined(WIN32) +#include +#else +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = (int)file->tellg(); + if (file->fail()) return -1; + return length; +} + +CDROM_Interface_Image::CDROM_Interface_Image() +{ +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + ClearTracks(); +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + //printf("Could not load image file: %s\n", path); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = (int)(tracks.size() - 1); + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > (int)tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + track_number = tracks[track - 1].track_number; + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + int cur_track = GetTrack(sector); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success = true; //Gobliiins reads 0 sectors + for(unsigned long i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector + i); + if (!success) break; + } + + memcpy((void*)buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +bool CDROM_Interface_Image::IsMode2(unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + if (tracks[track].mode2) + { + return true; + } + else + { + return false; + } +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.attr = DATA_TRACK;//data + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.track_number = 0xAA; + track.attr = 0; + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); +} + +#if defined(WIN32) +static string dirname(char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + safe_strncpy(tmp, file, len+1); + return tmp; + } +} +#endif + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + string pathname(dirname(tmp)); + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + track.track_number = track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = AUDIO_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = DATA_TRACK; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.track_number = 0xAA; + track.attr = 0;//sync with load iso + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x14 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == DATA_TRACK) return true; + } + return false; +} + +bool CDROM_Interface_Image::HasAudioTracks(void) +{ + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == AUDIO_TRACK) return true; + } + return false; +} + + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = (int)in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/cdrom-dosbox.h b/src/cdrom-dosbox.h new file mode 100644 index 000000000..39ed79bed --- /dev/null +++ b/src/cdrom-dosbox.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#include +#include +#include +#include +#include +#include +//#include "dosbox.h" +//#include "mem.h" +//#include "mixer.h" +//#include "SDL.h" +//#include "SDL_thread.h" + +#include +typedef signed int Bits; +typedef unsigned int Bitu; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; +typedef uint16_t Bit16u; +typedef int32_t Bit32s; +typedef uint32_t Bit32u; + +typedef size_t PhysPt; + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + +extern int CDROM_GetMountType(char* path, int force); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path, int forceCD) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; +}; + +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile() { }; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); + bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool IsMode2 (unsigned long sector); + bool HasDataTrack (void); + bool HasAudioTracks (void); + + int GetTrack (int sector); + +private: + // player +static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; +typedef std::vector::iterator track_it; + std::string mcn; +}; + +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc new file mode 100644 index 000000000..47c494291 --- /dev/null +++ b/src/cdrom-image.cc @@ -0,0 +1,1018 @@ +/* Copyright holders: RichardG867, Tenshi, bit + see COPYING for more details +*/ +/*CD-ROM image support*/ + +#include + +// #include "ibm.h" +#include "config.h" +#include "cdrom-dosbox.h" +#include "cdrom.h" +#include "cdrom-image.h" +#include "cdrom-null.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include + +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +extern CDROM image_cdrom; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_image_do_log = 1; + +CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; + +void cdrom_image_log(const char *format, ...) +{ +// #ifdef ENABLE_CDROM_IMAGE_LOG + if (cdrom_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +// #endif +} + +void image_close(uint8_t id); + +void image_audio_callback(uint8_t id, int16_t *output, int len) +{ + if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_image[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + { + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + } + memcpy(output, cdrom_image[id].cd_buffer, len * 2); + memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + cdrom_image[id].cd_buflen -= len; +} + +void image_audio_stop(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdimg[id]) return; + int number; + unsigned char attr; + TMSF tmsf; + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + cdrom_image_log("Can't play data track\n"); + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_state = CD_STOPPED; + return; + } + cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); + pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); + len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_image_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_image_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_image[id].cd_end = len; + cdrom_image[id].cd_state = CD_PLAYING; + if (cdrom[id].seek_pos < 150) + cdrom[id].seek_pos = 150; + cdrom_image[id].cd_buflen = 0; +} + +static void image_pause(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PLAYING) + cdrom_image[id].cd_state = CD_PAUSED; +} + +static void image_resume(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PAUSED) + cdrom_image[id].cd_state = CD_PLAYING; +} + +static void image_stop(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_seek(uint8_t id, uint32_t pos) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_pos = pos; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static int image_ready(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + return 0; + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 1; +} + +static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdimg[id]) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + { + return 0; + } + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + if (!cdimg[id]) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = cdrom[id].seek_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (cdrom_image[id].image_is_iso) + { + ret = 0x15; + } + else + { + if (cdrom_image[id].cd_state == CD_PLAYING) + ret = 0x11; + else if (cdrom_image[id].cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + } + + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; + + if (msf) + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + } + + return ret; +} + +static void image_eject(uint8_t id) +{ + return; +} + +static void image_load(uint8_t id) +{ + return; +} + +static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m, s, f; + unsigned char attr; + TMSF tmsf; + int number; + + if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +typedef struct __attribute__((__packed__)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((__packed__)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2336]; +} sector_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; +} sector_raw_data_t; + +typedef union __attribute__((__packed__)) +{ + sector_raw_data_t sector_data; + uint8_t raw_data[2352]; +} sector_t; + +typedef struct __attribute__((__packed__)) +{ + sector_t sector; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((__packed__)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; +uint8_t raw_buffer[2352]; +uint8_t extra_buffer[296]; + +static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + uint8_t *b; + uint8_t *temp_b; + int real_pos; + int audio; + int mode2; + + if (!cdimg[id]) + { + return 0; + } + + if (!cdrom_drives[id].host_drive) + { + return 0; + } + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + if (cdrom_image[id].image_is_iso) + { + audio = 0; + mode2 = 0; + } + else + { + audio = image_is_track_audio(id, real_pos, 1); + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; + } + + memset(raw_buffer, 0, 2352); + memset(extra_buffer, 0, 296); + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + { + if (cdrom_sector_type == 3) + { + cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); + } + if (cdrom_sector_type > 4) + { + cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); + } + return 0; + } + else if (cdrom_sector_type == 1) + { + if (!audio || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); + return 0; + } + +read_audio: + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + memcpy(temp_b, raw_buffer, 2352); + } + else if (cdrom_sector_type == 2) + { + if (audio || mode2) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); + return 0; + } + +read_mode1: + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 4; + bb += 2048; + memset(bb, 0, 288); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); + memcpy(temp_b, raw_buffer + 16, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2064, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + } + else if (cdrom_sector_type == 4) + { + if (audio || !mode2 || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); + return 0; + } + +read_mode2: + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); + memcpy(temp_b, raw_buffer + 24, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2072, 280); + cdrom_sector_size += 280; + temp_b += 280; + } + } + else + { + if (mode2) + { + goto read_mode2; + } + else + { + if (audio) + { + goto read_audio; + } + else + { + goto read_mode1; + } + } + } + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Full error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + + *len = cdrom_sector_size; + + return 1; +} + + +static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdimg[id]) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; +} + +static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + + b[2] = 1; + b[3] = 1; + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + for (track = first_track; track <= last_track; track++) + { + if ((len + 11) > maxlen) + { + cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + if (msf) + { + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + } + return len; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + +static int image_status(uint8_t id) +{ + if (!cdimg[id]) return CD_STATUS_EMPTY; + if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; + if (cdimg[id]->HasAudioTracks()) + { + switch(cdrom_image[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } + } + return CD_STATUS_DATA_ONLY; +} + +void image_reset(uint8_t id) +{ +} + +void image_close(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; + if (cdimg[id]) + { + delete cdimg[id]; + cdimg[id] = NULL; + } + memset(cdrom_image[id].image_path, 0, 2048); +} + +static char afn[1024]; + +int image_open(uint8_t id, wchar_t *fn) +{ + if (wcscmp(fn, cdrom_image[id].image_path) != 0) + { + cdrom_image[id].image_changed = 1; + } + + /* Make sure image_changed stays when changing from an image to another image. */ + if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + _swprintf(cdrom_image[id].image_path, L"%ws", fn); + } + + if (!wcsicmp(get_extension_w(fn), L"ISO")) + { + cdrom_image[id].image_is_iso = 1; + } + else + { + cdrom_image[id].image_is_iso = 0; + } + + cdimg[id] = new CDROM_Interface_Image(); + wcstombs(afn, fn, (wcslen(fn) << 1) + 2); + if (!cdimg[id]->SetDevice(afn, false)) + { + image_close(id); + cdrom_set_null_handler(id); + return 1; + } + cdrom_image[id].cd_state = CD_STOPPED; + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_buflen = 0; + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0); + cdrom_drives[id].handler = &image_cdrom; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + if (!cdrom_image[id].image_inited) + cdrom_image[id].image_inited = 1; + } + return 0; +} + +static void image_exit(uint8_t id) +{ + cdrom_image[id].image_inited = 0; +} + +/* TODO: Check for what data type a mixed CD is. */ +static int image_media_type_id(uint8_t id) +{ + if (!cdrom_image[id].image_is_iso) + { + return 3; /* Mixed mode CD. */ + } + + if (image_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + +CDROM image_cdrom = +{ + image_ready, + image_medium_changed, + image_media_type_id, + image_audio_callback, + image_audio_stop, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + NULL, + image_readsector_raw, + image_playaudio, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit +}; diff --git a/src/cdrom-image.h b/src/cdrom-image.h new file mode 100644 index 000000000..3a49226a3 --- /dev/null +++ b/src/cdrom-image.h @@ -0,0 +1,25 @@ +/* Copyright holders: RichardG867, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IMAGE_H +#define CDROM_IMAGE_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int image_open(uint8_t id, wchar_t *fn); +extern void image_reset(uint8_t id); + +extern void image_close(uint8_t id); + +extern void cdrom_set_null_handler(uint8_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_IMAGE_H */ From baa847b7597a62ce33988da4f92797b6ad9546de Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 7 May 2017 23:39:45 -0400 Subject: [PATCH 173/392] Another fixup for the serial driver for chipset-based boards. Serial mice now work as expected on those as well. --- src/mouse_serial.c | 4 ++-- src/serial.c | 21 +++++++++++++++++---- src/serial.h | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index e9e4338d5..8afe9b3b3 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * Based on the 86Box Serial Mouse driver as a framework. * - * Version: @(#)mouse_serial.c 1.0.2 2017/05/06 + * Version: @(#)mouse_serial.c 1.0.3 2017/05/07 * * Author: Fred N. van Kempen, */ @@ -33,7 +33,7 @@ typedef struct mouse_serial_t { /* Callback from serial driver: RTS was toggled. */ static void -sermouse_callback(SERIAL *serial, void *priv) +sermouse_callback(void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; diff --git a/src/serial.c b/src/serial.c index 1d401ad00..a2b896321 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,7 +33,7 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.4 2017/05/07 + * Version: @(#)serial.c 1.0.5 2017/05/07 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -238,6 +238,9 @@ serial_write(uint16_t addr, uint8_t val, void *priv) uint16_t baud; long speed; +#if 0 + pclog("Serial%d: write(%04x, %02x)\n", sp->port, addr, val); +#endif switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { @@ -282,18 +285,20 @@ serial_write(uint16_t addr, uint8_t val, void *priv) case 3: /* LCR */ if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { /* We dropped DLAB, so handle baudrate. */ - baud = ((sp->dlab2 << 8) | sp->dlab1); + baud = ((sp->dlab2<<8) | sp->dlab1); if (baud > 0) { speed = 115200UL/baud; #if 0 pclog("Serial%d: divisor %u, baudrate %ld\n", sp->port, baud, speed); #endif - if (sp->bh != NULL) + if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); +#if 0 } else { pclog("Serial%d: divisor %u invalid!\n", sp->port, baud); +#endif } } wl = (val & LCR_WLS) + 5; /* databits */ @@ -316,7 +321,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) * enumerator there 'is' something. */ if (sp->rts_callback) { - sp->rts_callback(sp, sp->rts_callback_p); + sp->rts_callback(sp->rts_callback_p); #if 0 pclog("RTS raised; sending ID\n"); #endif @@ -505,8 +510,12 @@ serial_setup(int port, uint16_t addr, int irq) serial_read, NULL, NULL, serial_write, NULL, NULL, sp); +#if 1 + /* Do not disable here, it breaks the SIO chips. */ +#else /* No DTR/RTS callback for now. */ sp->rts_callback = NULL; +#endif } @@ -521,8 +530,12 @@ serial_remove(int port) // FIXME: stop timer, if enabled! +#if 1 + /* Do not disable here, it breaks the SIO chips. */ +#else /* Remove any callbacks. */ sp->rts_callback = NULL; +#endif /* Close the host device. */ (void)serial_link(port, NULL); diff --git a/src/serial.h b/src/serial.h index 837b13d12..bf361a0b1 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,7 +8,7 @@ * * Definitions for the SERIAL card. * - * Version: @(#)serial.h 1.0.2 2017/05/06 + * Version: @(#)serial.h 1.0.3 2017/05/07 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -38,7 +38,7 @@ typedef struct _serial_ { uint8_t fcr; /* Data for the RTS-toggle callback. */ - void (*rts_callback)(struct _serial_ *, void *); + void (*rts_callback)(void *); void *rts_callback_p; uint8_t hold; From 5a87f91bc521c3e84e3dc198129fdb0b6b32c186 Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 7 May 2017 23:42:05 -0400 Subject: [PATCH 174/392] Splitting Buslogic and Aha154x up, cleanups. First phase. --- src/CPU/808x.c | 2 - src/ibm.h | 27 +- src/scsi.c | 1 + src/scsi.h | 44 +- src/scsi_aha154x.c | 1996 ++++++++++++++++++++++++++++++++++++++++++- src/scsi_buslogic.c | 771 ++++------------- src/scsi_buslogic.h | 24 +- 7 files changed, 2218 insertions(+), 647 deletions(-) diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 1f6f67cca..c102fa45f 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -577,7 +577,6 @@ void resetx86() codegen_reset(); x86_was_reset = 1; port_92_clear_reset(); - BuslogicSoftReset(); } void softresetx86() @@ -596,7 +595,6 @@ void softresetx86() x86seg_reset(); x86_was_reset = 1; port_92_clear_reset(); - BuslogicSoftReset(); } static void setznp8(uint8_t val) diff --git a/src/ibm.h b/src/ibm.h index c163e5f15..b191154ec 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -556,13 +556,8 @@ wchar_t pcempath[512]; /*Hard disc*/ -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { FILE *f; uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ uint64_t tracks; @@ -575,17 +570,10 @@ typedef struct __attribute((__packed__)) uint8_t scsi_id; uint8_t scsi_lun; } hard_disk_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { /* Stuff for SCSI hard disks. */ uint8_t cdb[16]; uint8_t current_cdb[16]; @@ -619,9 +607,7 @@ typedef struct __attribute((__packed__)) uint64_t base; uint8_t hd_cdb[16]; } scsi_hard_disk_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) #define HDC_NUM 16 #define IDE_NUM 8 @@ -744,7 +730,6 @@ uint32_t svga_color_transform(uint32_t color); extern int scale; /* Function prototypes. */ -void BuslogicSoftReset(); int checkio(int port); void closepc(); void codegen_block_end(); diff --git a/src/scsi.c b/src/scsi.c index 3b88ed36b..733e2a0a7 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -10,6 +10,7 @@ #include "device.h" #include "cdrom.h" #include "scsi.h" +#include "scsi_aha154x.h" #include "scsi_buslogic.h" diff --git a/src/scsi.h b/src/scsi.h index 788dcb7f3..2c9280c29 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -1,14 +1,14 @@ /* Copyright holders: SA1988 see COPYING for more details */ -#ifndef __SCSI_H__ -#define __SCSI_H__ +#ifndef SCSI_H +#define SCSI_H -#include "timer.h" #define SCSI_TIME (5 * 100 * (1 << TIMER_SHIFT)) -/* SCSI Commands */ + +/* SCSI commands. */ #define GPCMD_TEST_UNIT_READY 0x00 #define GPCMD_REZERO_UNIT 0x01 #define GPCMD_REQUEST_SENSE 0x03 @@ -266,4 +266,40 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l void scsi_hd_command(uint8_t id, uint8_t *cdb); void scsi_hd_callback(uint8_t id); + +#pragma pack(push,1) +typedef struct { + uint8_t hi; + uint8_t mid; + uint8_t lo; +} addr24; +#pragma pack(pop) + +#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) +#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) + + +/* + * + * Scatter/Gather Segment List Definitions + * + * Adapter limits + */ +#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ + +#pragma pack(push,1) +typedef struct { + uint32_t Segment; + uint32_t SegmentPointer; +} SGE32; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + addr24 Segment; + addr24 SegmentPointer; +} SGE; +#pragma pack(pop) + + #endif diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 2161fa934..253d4929c 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -6,24 +6,34 @@ * * This file is part of the 86Box distribution. * - * Implementation of several low-level support functions for - * the AHA-154x series of ISA Host Adapters made by Adaptec. - * These functions implement the support needed by the ROM - * BIOS of these cards. + * Implementation of the AHA-154x series of SCSI Host Adapters + * made by Adaptec, Inc. These controllers were designed for + * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.5 2017/05/05 + * NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go. * - * Author: Fred N. van Kempen, + * Version: @(#)scsi_aha154x.c 1.0.6 2017/05/06 + * + * Authors: Fred N. van Kempen, + * Original Buslogic version by SA1988. * Copyright 2017 Fred N. van Kempen. */ +#include #include #include #include +#include #include "ibm.h" +#include "io.h" #include "mem.h" #include "rom.h" +#include "dma.h" +#include "pic.h" +#include "timer.h" #include "device.h" -#include "scsi_buslogic.h" +#include "cdrom.h" +#include "scsi.h" +#include "scsi_aha154x.h" #define AHA AHA154xCF /* set desired card type */ @@ -100,6 +110,61 @@ #define EEE_START 0x08 /* EE(E) [3] Enable Start Unit */ +/* + * Host Adapter I/O ports. + * + * READ Port x+0: STATUS + * WRITE Port x+0: CONTROL + * + * READ Port x+1: DATA + * WRITE Port x+1: COMMAND + * + * READ Port x+2: INTERRUPT STATUS + * WRITE Port x+2: (undefined?) + * + * R/W Port x+3: (undefined) + */ + +/* WRITE CONTROL commands. */ +#define CTRL_HRST 0x80 /* Hard reset */ +#define CTRL_SRST 0x40 /* Soft reset */ +#define CTRL_IRST 0x20 /* interrupt reset */ +#define CTRL_SCRST 0x10 /* SCSI bus reset */ + +/* READ STATUS. */ +#define STAT_STST 0x80 /* self-test in progress */ +#define STAT_DFAIL 0x40 /* internal diagnostic failure */ +#define STAT_INIT 0x20 /* mailbox initialization required */ +#define STAT_IDLE 0x10 /* HBA is idle */ +#define STAT_CDFULL 0x08 /* Command/Data output port is full */ +#define STAT_DFULL 0x04 /* Data input port is full */ +#define STAT_INVCMD 0x01 /* Invalid command */ + +/* READ/WRITE DATA. */ +#define CMD_NOP 0x00 /* No operation */ +#define CMD_MBINIT 0x01 /* mailbox initialization */ +#define CMD_START_SCSI 0x02 /* Start SCSI command */ +#define CMD_BIOS 0x03 /* Execute ROM BIOS command */ +#define CMD_INQUIRY 0x04 /* Adapter inquiry */ +#define CMD_EMBOI 0x05 /* enable Mailbox Out Interrupt */ +#define CMD_SELTIMEOUT 0x06 /* Set SEL timeout */ +#define CMD_BUSON_TIME 0x07 /* set bus-On time */ +#define CMD_BUSOFF_TIME 0x08 /* set bus-off time */ +#define CMD_DMASPEED 0x09 /* set ISA DMA speed */ +#define CMD_RETDEVS 0x0A /* return installed devices */ +#define CMD_RETCONF 0x0B /* return configuration data */ +#define CMD_TARGET 0x0C /* set HBA to target mode */ +#define CMD_RETSETUP 0x0D /* return setup data */ +#define CMD_ECHO 0x1F /* ECHO command data */ + +/* READ INTERRUPT STATUS. */ +#define INTR_ANY 0x80 /* any interrupt */ +#define INTR_SRCD 0x08 /* SCSI reset detected */ +#define INTR_HACC 0x04 /* HA command complete */ +#define INTR_MBOA 0x02 /* MBO empty */ +#define INTR_MBIF 0x01 /* MBI full */ + + static rom_t aha_bios; /* active ROM */ static uint8_t *aha_rom1; /* main BIOS */ static uint8_t *aha_rom2; /* SCSI-Select */ @@ -192,8 +257,8 @@ aha_patch(uint8_t *romptr, uint16_t ioaddr) /* Initialize AHA-154xNN-specific stuff. */ -void -aha154x_init(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) +static void +aha154x_bios(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) { uint32_t bios_size; uint32_t bios_addr; @@ -335,7 +400,7 @@ again: /* Mess with the AHA-154xCF's Shadow RAM. */ -uint8_t +static uint8_t aha154x_shram(uint8_t cmd) { #ifdef ROM_SHRAM @@ -359,7 +424,7 @@ aha154x_shram(uint8_t cmd) } -uint8_t +static uint8_t aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) { uint8_t r = 0xff; @@ -387,7 +452,7 @@ aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) } -uint8_t +static uint8_t aha154x_memory(uint8_t cmd) { uint8_t r = 0xff; @@ -405,3 +470,1910 @@ aha154x_memory(uint8_t cmd) return(0); } + + +#define AHA_RESET_DURATION_NS UINT64_C(50000000) + + +/* + * Auto SCSI structure which is located in host adapter RAM + * and contains several configuration parameters. + */ +#pragma pack(push,1) +typedef struct { + uint8_t aInternalSignature[2]; + uint8_t cbInformation; + uint8_t aHostAdaptertype[6]; + uint8_t uReserved1; + uint8_t fFloppyEnabled :1, + fFloppySecondary :1, + fLevelSensitiveInterrupt:1, + uReserved2 :2, + uSystemRAMAreForBIOS :3; + uint8_t uDMAChannel :7, + fDMAAutoConfiguration :1, + uIrqChannel :7, + fIrqAutoConfiguration :1; + uint8_t uDMATransferRate; + uint8_t uSCSIId; + uint8_t fLowByteTerminated :1, + fParityCheckingEnabled :1, + fHighByteTerminated :1, + fNoisyCablingEnvironment:1, + fFastSyncNegotiation :1, + fBusResetEnabled :1, + fReserved3 :1, + fActiveNegotiationEna :1; + uint8_t uBusOnDelay; + uint8_t uBusOffDelay; + uint8_t fHostAdapterBIOSEnabled :1, + fBIOSRedirectionOfInt19 :1, + fExtendedTranslation :1, + fMapRemovableAsFixed :1, + fReserved4 :1, + fBIOSMoreThan2Drives :1, + fBIOSInterruptMode :1, + fFlopticalSupport :1; + uint16_t u16DeviceEnabledMask; + uint16_t u16WidePermittedMask; + uint16_t u16FastPermittedMask; + uint16_t u16SynchronousPermittedMask; + uint16_t u16DisconnectPermittedMask; + uint16_t u16SendStartUnitCommandMask; + uint16_t u16IgnoreInBIOSScanMask; + unsigned char uPCIInterruptPin : 2; + unsigned char uHostAdapterIoPortAddress : 2; + uint8_t fStrictRoundRobinMode : 1; + uint8_t fVesaBusSpeedGreaterThan33MHz : 1; + uint8_t fVesaBurstWrite : 1; + uint8_t fVesaBurstRead : 1; + uint16_t u16UltraPermittedMask; + uint32_t uReserved5; + uint8_t uReserved6; + uint8_t uAutoSCSIMaximumLUN; + uint8_t fReserved7 : 1; + uint8_t fSCAMDominant : 1; + uint8_t fSCAMenabled : 1; + uint8_t fSCAMLevel2 : 1; + unsigned char uReserved8 : 4; + uint8_t fInt13Extension : 1; + uint8_t fReserved9 : 1; + uint8_t fCDROMBoot : 1; + unsigned char uReserved10 : 5; + unsigned char uBootTargetId : 4; + unsigned char uBootChannel : 4; + uint8_t fForceBusDeviceScanningOrder : 1; + unsigned char uReserved11 : 7; + uint16_t u16NonTaggedToAlternateLunPermittedMask; + uint16_t u16RenegotiateSyncAfterCheckConditionMask; + uint8_t aReserved12[10]; + uint8_t aManufacturingDiagnostic[2]; + uint16_t u16Checksum; +} AutoSCSIRam; +#pragma pack(pop) + +/* The local RAM. */ +#pragma pack(push,1) +typedef union { + uint8_t u8View[256]; /* byte view */ + struct { /* structured view */ + uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ + AutoSCSIRam autoSCSIData; /* Auto SCSI structure */ + } structured; +} HALocalRAM; +#pragma pack(pop) + +/* Structure for the INQUIRE_SETUP_INFORMATION reply. */ +#pragma pack(push,1) +typedef struct { + uint8_t uOffset :4, + uTransferPeriod :3, + fSynchronous :1; +} ReplyInquireSetupInformationSynchronousValue; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t fSynchronousInitiationEnabled :1, + fParityCheckingEnabled :1, + uReserved1 :6; + uint8_t uBusTransferRate; + uint8_t uPreemptTimeOnBus; + uint8_t uTimeOffBus; + uint8_t cMailbox; + addr24 MailboxAddress; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId0To7[8]; + uint8_t uDisconnectPermittedId0To7; + uint8_t uSignature; + uint8_t uCharacterD; + uint8_t uHostBusType; + uint8_t uWideTransferPermittedId0To7; + uint8_t uWideTransfersActiveId0To7; + ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15[8]; + uint8_t uDisconnectPermittedId8To15; + uint8_t uReserved2; + uint8_t uWideTransferPermittedId8To15; + uint8_t uWideTransfersActiveId8To15; +} ReplyInquireSetupInformation; +#pragma pack(pop) + +/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ +#pragma pack(push,1) +typedef struct { + uint8_t uBusType; + uint8_t uBiosAddress; + uint16_t u16ScatterGatherLimit; + uint8_t cMailbox; + uint32_t uMailboxAddressBase; + uint8_t uReserved1 :2, + fFastEISA :1, + uReserved2 :3, + fLevelSensitiveInterrupt:1, + uReserved3 :1; + uint8_t aFirmwareRevision[3]; + uint8_t fHostWideSCSI :1, + fHostDifferentialSCSI :1, + fHostSupportsSCAM :1, + fHostUltraSCSI :1, + fHostSmartTermination :1, + uReserved4 :3; +} ReplyInquireExtendedSetupInformation; +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct { + uint8_t Count; + addr24 Address; +} MailboxInit_t; +#pragma pack(pop) + + +/* + * Mailbox Definitions. + * + * Mailbox Out (MBO) command values. + */ +#define MBO_FREE 0x00 +#define MBO_START 0x01 +#define MBO_ABORT 0x02 + +/* Mailbox In (MBI) status values. */ +#define MBI_FREE 0x00 +#define MBI_SUCCESS 0x01 +#define MBI_ABORT 0x02 +#define MBI_NOT_FOUND 0x03 +#define MBI_ERROR 0x04 + + +#pragma pack(push,1) +typedef struct { + uint8_t CmdStatus; + addr24 CCBPointer; +} Mailbox_t; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint32_t CCBPointer; + union { + struct { + uint8_t Reserved[3]; + uint8_t ActionCode; + } out; + struct { + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved; + uint8_t CompletionCode; + } in; + } u; +} Mailbox32_t; +#pragma pack(pop) + + +/* + * + * CCB - SCSI Command Control Block + * + * The CCB is a superset of the CDB (Command Descriptor Block) + * and specifies detailed information about a SCSI command. + * + */ +/* Byte 0 Command Control Block Operation Code */ +#define SCSI_INITIATOR_COMMAND 0x00 +#define TARGET_MODE_COMMAND 0x01 +#define SCATTER_GATHER_COMMAND 0x02 +#define SCSI_INITIATOR_COMMAND_RES 0x03 +#define SCATTER_GATHER_COMMAND_RES 0x04 +#define BUS_RESET 0x81 + +/* Byte 1 Address and Direction Control */ +#define CCB_TARGET_ID_SHIFT 0x06 /* CCB Op Code = 00, 02 */ +#define CCB_INITIATOR_ID_SHIFT 0x06 /* CCB Op Code = 01 */ +#define CCB_DATA_XFER_IN 0x01 +#define CCB_DATA_XFER_OUT 0x02 +#define CCB_LUN_MASK 0x07 /* Logical Unit Number */ + +/* Byte 2 SCSI_Command_Length - Length of SCSI CDB + Byte 3 Request Sense Allocation Length */ +#define FOURTEEN_BYTES 0x00 /* Request Sense Buffer size */ +#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */ + +/* Bytes 4, 5 and 6 Data Length - Data transfer byte count */ +/* Bytes 7, 8 and 9 Data Pointer - SGD List or Data Buffer */ +/* Bytes 10, 11 and 12 Link Pointer - Next CCB in Linked List */ +/* Byte 13 Command Link ID - TBD (I don't know yet) */ +/* Byte 14 Host Status - Host Adapter status */ +#define CCB_COMPLETE 0x00 /* CCB completed without error */ +#define CCB_LINKED_COMPLETE 0x0A /* Linked command completed */ +#define CCB_LINKED_COMPLETE_INT 0x0B /* Linked complete with intr */ +#define CCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */ +#define CCB_DATA_OVER_UNDER_RUN 0x12 +#define CCB_UNEXPECTED_BUS_FREE 0x13 /* Trg dropped SCSI BSY */ +#define CCB_PHASE_SEQUENCE_FAIL 0x14 /* Trg bus phase sequence fail */ +#define CCB_BAD_MBO_COMMAND 0x15 /* MBO command not 0, 1 or 2 */ +#define CCB_INVALID_OP_CODE 0x16 /* CCB invalid operation code */ +#define CCB_BAD_LINKED_LUN 0x17 /* Linked CCB LUN diff from 1st */ +#define CCB_INVALID_DIRECTION 0x18 /* Invalid target direction */ +#define CCB_DUPLICATE_CCB 0x19 /* Duplicate CCB */ +#define CCB_INVALID_CCB 0x1A /* Invalid CCB - bad parameter */ + +/* Byte 15 Target Status + + See scsi.h files for these statuses. + Bytes 16 and 17 Reserved (must be 0) + Bytes 18 through 18+n-1, where n=size of CDB Command Descriptor Block */ + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Reserved1 :3, + ControlByte :2, + TagQueued :1, + QueueTag :2; + uint8_t CdbLength; + uint8_t RequestSenseLength; + uint32_t DataLength; + uint32_t DataPointer; + uint8_t Reserved2[2]; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Id; + uint8_t Lun :5, + LegacyTagEnable :1, + LegacyQueueTag :2; + uint8_t Cdb[12]; + uint8_t Reserved3[6]; + uint32_t SensePointer; +} CCB32; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Lun :3, + ControlByte :2, + Id :3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + addr24 DataLength; + addr24 DataPointer; + addr24 LinkPointer; + uint8_t LinkId; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Reserved[2]; + uint8_t Cdb[12]; +} CCB; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + uint8_t Opcode; + uint8_t Pad1 :3, + ControlByte :2, + Pad2 :3; + uint8_t CdbLength; + uint8_t RequestSenseLength; + uint8_t Pad3[10]; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t Pad4[2]; + uint8_t Cdb[12]; +} CCBC; +#pragma pack(pop) + +#pragma pack(push,1) +typedef union { + CCB32 new; + CCB old; + CCBC common; +} CCBU; +#pragma pack(pop) + +#pragma pack(push,1) +typedef struct { + CCBU CmdBlock; + uint8_t *RequestSenseBuffer; + uint32_t CCBPointer; + int Is24bit; + uint8_t TargetID; + uint8_t LUN; + uint8_t HostStatus; + uint8_t TargetStatus; + uint8_t MailboxCompletionCode; +} Req_t; +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct { + rom_t bios; + int UseLocalRAM; + int StrictRoundRobinMode; + int ExtendedLUNCCBFormat; + HALocalRAM LocalRAM; + Req_t Req; + uint8_t Status; + uint8_t Interrupt; + uint8_t Geometry; + uint8_t Control; + uint8_t Command; + uint8_t CmdBuf[53]; + uint8_t CmdParam; + uint8_t CmdParamLeft; + uint8_t DataBuf[64]; + uint16_t DataReply; + uint16_t DataReplyLeft; + uint32_t MailboxCount; + uint32_t MailboxOutAddr; + uint32_t MailboxOutPosCur; + uint32_t MailboxInAddr; + uint32_t MailboxInPosCur; + int Base; + int Irq; + int DmaChannel; + int IrqEnabled; + int Mbx24bit; + int MailboxOutInterrupts; + int MbiActive[256]; + int PendingInterrupt; + int Lock; + mem_mapping_t mmio_mapping; + aha_info aha; + int chip; +} aha_t; +#pragma pack(pop) + + +static int ResetCB = 0; +static int AHA_Callback = 0; +static int AHA_InOperation = 0; +static aha_t *ResetDev; + + +enum { + CHIP_AHA154XB, + CHIP_AHA154XCF +}; + + +#ifdef WALTJE +int aha_do_log = 1; +# define ENABLE_AHA154X_LOG +#else +int aha_do_log = 0; +#endif + + +static void +aha_log(const char *format, ...) +{ +#ifdef ENABLE_AHA154X_LOG + va_list ap; + + if (aha_do_log) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#define pclog aha_log + + +static void +ClearIntr(aha_t *dev) +{ + dev->Interrupt = 0; + pclog("AHA154X: lowering IRQ %i (stat 0x%02x)\n", + dev->Irq, dev->Interrupt); + picintc(1 << dev->Irq); + if (dev->PendingInterrupt) { + dev->Interrupt = dev->PendingInterrupt; + pclog("AHA154X: Raising Interrupt 0x%02X (Pending)\n", dev->Interrupt); + if (dev->MailboxOutInterrupts || !(dev->Interrupt & INTR_MBOA)) { + if (dev->IrqEnabled) picint(1 << dev->Irq); + } + dev->PendingInterrupt = 0; + } +} + + +static void +RaiseIntr(aha_t *dev, uint8_t Interrupt) +{ + if (dev->Interrupt & INTR_HACC) { + pclog("Pending IRQ\n"); + dev->PendingInterrupt = Interrupt; + } else { + dev->Interrupt = Interrupt; + pclog("Raising IRQ %i\n", dev->Irq); + if (dev->IrqEnabled) + picint(1 << dev->Irq); + } +} + + +static void +LocalRAM(aha_t *dev) +{ + /* + * These values are mostly from what I think is right + * looking at the dmesg output from a Linux guest inside + * a VMware server VM. + * + * So they don't have to be right :) + */ + memset(dev->LocalRAM.u8View, 0, sizeof(HALocalRAM)); + dev->LocalRAM.structured.autoSCSIData.fLevelSensitiveInterrupt = 1; + dev->LocalRAM.structured.autoSCSIData.fParityCheckingEnabled = 1; + dev->LocalRAM.structured.autoSCSIData.fExtendedTranslation = 1; /* Same as in geometry register. */ + dev->LocalRAM.structured.autoSCSIData.u16DeviceEnabledMask = UINT16_MAX; /* All enabled. Maybe mask out non present devices? */ + dev->LocalRAM.structured.autoSCSIData.u16WidePermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.u16FastPermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.u16SynchronousPermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.u16DisconnectPermittedMask = UINT16_MAX; + dev->LocalRAM.structured.autoSCSIData.fStrictRoundRobinMode = dev->StrictRoundRobinMode; + dev->LocalRAM.structured.autoSCSIData.u16UltraPermittedMask = UINT16_MAX; + /** @todo calculate checksum? */ +} + + +static void +aha_reset(aha_t *dev) +{ + AHA_Callback = 0; + ResetCB = 0; + dev->Status = STAT_IDLE | STAT_INIT; + dev->Geometry = 0x80; + dev->Command = 0xFF; + dev->CmdParam = 0; + dev->CmdParamLeft = 0; + dev->IrqEnabled = 1; + dev->StrictRoundRobinMode = 0; + dev->ExtendedLUNCCBFormat = 0; + dev->MailboxOutPosCur = 0; + dev->MailboxInPosCur = 0; + dev->MailboxOutInterrupts = 0; + dev->PendingInterrupt = 0; + dev->Lock = 0; + AHA_InOperation = 0; + + ClearIntr(dev); + + LocalRAM(dev); +} + + +static void +aha_softreset(void) +{ + if (ResetDev != NULL) { + aha_reset(ResetDev); + } +} + + +static void +aha_reset_ctrl(aha_t *dev, uint8_t Reset) +{ + aha_reset(dev); + if (Reset) { + dev->Status |= STAT_STST; + dev->Status &= ~STAT_IDLE; + } + ResetCB = AHA_RESET_DURATION_NS * TIMER_USEC; +} + + +static void +aha_cmd_done(aha_t *dev) +{ + dev->DataReply = 0; + dev->Status |= STAT_IDLE; + + if ((dev->Command != 0x02) && (dev->Command != 0x82)) { + dev->Status &= ~STAT_DFULL; + dev->Interrupt = (INTR_ANY | INTR_HACC); + pclog("Raising IRQ %i\n", dev->Irq); + if (dev->IrqEnabled) + picint(1 << dev->Irq); + } + + dev->Command = 0xFF; + dev->CmdParam = 0; +} + + +static void +aha_mbi_setup(aha_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, + uint8_t HostStatus, uint8_t TargetStatus, uint8_t mbcc) +{ + Req_t *req = &dev->Req; + + req->CCBPointer = CCBPointer; + memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); + req->Is24bit = dev->Mbx24bit; + req->HostStatus = HostStatus; + req->TargetStatus = TargetStatus; + req->MailboxCompletionCode = mbcc; + + pclog("Mailbox in setup\n"); + + AHA_InOperation = 2; +} + + +static void +aha_mbi(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint32_t CCBPointer = req->CCBPointer; + CCBU *CmdBlock = &(req->CmdBlock); + uint8_t HostStatus = req->HostStatus; + uint8_t TargetStatus = req->TargetStatus; + uint8_t MailboxCompletionCode = req->MailboxCompletionCode; + Mailbox32_t Mailbox32; + Mailbox_t MailboxIn; + uint32_t Incoming; + + Mailbox32.CCBPointer = CCBPointer; + Mailbox32.u.in.HostStatus = HostStatus; + Mailbox32.u.in.TargetStatus = TargetStatus; + Mailbox32.u.in.CompletionCode = MailboxCompletionCode; + + Incoming = dev->MailboxInAddr + (dev->MailboxInPosCur * (dev->Mbx24bit ? sizeof(Mailbox_t) : sizeof(Mailbox32_t))); + + if (MailboxCompletionCode != MBI_NOT_FOUND) { + CmdBlock->common.HostStatus = HostStatus; + CmdBlock->common.TargetStatus = TargetStatus; + + /* Rewrite the CCB up to the CDB. */ + pclog("CCB rewritten to the CDB (pointer %08X, length %i)\n", CCBPointer, offsetof(CCBC, Cdb)); + DMAPageWrite(CCBPointer, (char *)CmdBlock, offsetof(CCBC, Cdb)); + } else { + pclog("Mailbox not found!\n"); + } + + pclog("Host Status 0x%02X, Target Status 0x%02X\n",HostStatus,TargetStatus); + + if (dev->Mbx24bit) { + MailboxIn.CmdStatus = Mailbox32.u.in.CompletionCode; + U32_TO_ADDR(MailboxIn.CCBPointer, Mailbox32.CCBPointer); + pclog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); + + DMAPageWrite(Incoming, (char *)&MailboxIn, sizeof(Mailbox_t)); + pclog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); + } else { + pclog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); + + DMAPageWrite(Incoming, (char *)&Mailbox32, sizeof(Mailbox32_t)); + pclog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + } + + dev->MailboxInPosCur++; + if (dev->MailboxInPosCur >= dev->MailboxCount) + dev->MailboxInPosCur = 0; + + RaiseIntr(dev, INTR_MBIF | INTR_ANY); + + AHA_InOperation = 0; +} + + +static void +aha_rd_sge(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) +{ + uint32_t i; + SGE SGE24[MAX_SG_DESCRIPTORS]; + + if (Is24bit) { + DMAPageRead(SGList, (char *)&SGE24, Entries * sizeof(SGE)); + + for (i=0;iCmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + } else { + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; + } + pclog("Data Buffer write: length %d, pointer 0x%04X\n", + DataLength, DataPointer); + + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { + if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || + req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { + uint32_t SGRead; + uint32_t ScatterEntry; + SGE32 SGBuffer[MAX_SG_DESCRIPTORS]; + uint32_t SGLeft = DataLength / SGEntryLength; + uint32_t SGAddrCurrent = DataPointer; + uint32_t DataToTransfer = 0; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + aha_rd_sge(Is24bit, SGAddrCurrent, SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + + pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer += SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + } + + SGAddrCurrent += SGRead * SGEntryLength; + } while (SGLeft > 0); + + pclog("Data to transfer (S/G) %d\n", DataToTransfer); + + SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without + checking its length, so do this procedure for both no read/write commands. */ + if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || + (req->CmdBlock.common.ControlByte == 0x00)) { + SGLeft = DataLength / SGEntryLength; + SGAddrCurrent = DataPointer; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + aha_rd_sge(Is24bit, SGAddrCurrent, + SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + + pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer = SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G Write: Address=%08X DatatoTransfer=%u\n", Address, DataToTransfer); + + DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; + } + + SGAddrCurrent += SGRead * (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + } while (SGLeft > 0); + } + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || + req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + uint32_t Address = DataPointer; + + SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + if (DataLength > 0) { + DMAPageRead(Address, + (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, + SCSIDevices[req->TargetID][req->LUN].InitLength); + } + } + } +} + + +static void +aha_buf_free(Req_t *req) +{ + SGE32 SGBuffer[MAX_SG_DESCRIPTORS]; + uint32_t DataPointer = 0; + uint32_t DataLength = 0; + uint32_t sg_buffer_pos = 0; + uint32_t SGRead; + uint32_t ScatterEntry; + uint32_t SGEntrySize; + uint32_t SGLeft; + uint32_t SGAddrCurrent; + uint32_t Address; + uint32_t Residual; + + if (req->Is24bit) { + DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); + DataLength = ADDR_TO_U32(req->CmdBlock.old.DataLength); + } else { + DataPointer = req->CmdBlock.new.DataPointer; + DataLength = req->CmdBlock.new.DataLength; + } + + if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) { + pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n", + DataLength, SCSIDevices[req->TargetID][req->LUN].InitLength); + } + + if (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY) { + DataLength = 0; + } + + pclog("Data Buffer read: length %d, pointer 0x%04X\n", + DataLength, DataPointer); + + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without + checking its length, so do this procedure for both read/write commands. */ + if ((DataLength > 0) && + ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_IN) || + (req->CmdBlock.common.ControlByte == 0x00))) { + if ((req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND) || + (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + SGEntrySize = (req->Is24bit ? sizeof(SGE) : sizeof(SGE32)); + SGLeft = DataLength / SGEntrySize; + SGAddrCurrent = DataPointer; + + do { + SGRead = (SGLeft < ELEMENTS(SGBuffer)) ? SGLeft : ELEMENTS(SGBuffer); + SGLeft -= SGRead; + + aha_rd_sge(req->Is24bit, SGAddrCurrent, + SGRead, SGBuffer); + + for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { + uint32_t Address; + uint32_t DataToTransfer; + + pclog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); + + Address = SGBuffer[ScatterEntry].SegmentPointer; + DataToTransfer = SGBuffer[ScatterEntry].Segment; + + pclog("BusLogic S/G: Writing %i bytes at %08X\n", DataToTransfer, Address); + + DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); + sg_buffer_pos += DataToTransfer; + } + + SGAddrCurrent += (SGRead * SGEntrySize); + } while (SGLeft > 0); + } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || + req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { + Address = DataPointer; + + pclog("BusLogic DMA: Writing %i bytes at %08X\n", DataLength, Address); + DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, DataLength); + } + } + + if ((req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) || + (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES)) { + /* Should be 0 when scatter/gather? */ + if (DataLength >= SCSIDevices[req->TargetID][req->LUN].InitLength) { + Residual = DataLength; + Residual -= SCSIDevices[req->TargetID][req->LUN].InitLength; + } else { + Residual = 0; + } + + if (req->Is24bit) { + U32_TO_ADDR(req->CmdBlock.old.DataLength, Residual); + pclog("24-bit Residual data length for reading: %d\n", + ADDR_TO_U32(req->CmdBlock.old.DataLength)); + } else { + req->CmdBlock.new.DataLength = Residual; + pclog("32-bit Residual data length for reading: %d\n", + req->CmdBlock.new.DataLength); + } + } +} + + +static uint8_t +aha_read(uint16_t port, void *priv) +{ + aha_t *dev = (aha_t *)priv; + uint8_t ret; + + switch (port & 3) { + case 0: + ret = dev->Status; + break; + + case 1: + if (dev->UseLocalRAM) + ret = dev->LocalRAM.u8View[dev->DataReply]; + else + ret = dev->DataBuf[dev->DataReply]; + if (dev->DataReplyLeft) { + dev->DataReply++; + dev->DataReplyLeft--; + if (! dev->DataReplyLeft) + aha_cmd_done(dev); + } + break; + + case 2: + ret = dev->Interrupt; + break; + + case 3: + ret = dev->Geometry; + break; + } + + if (port < 0x1000) { + pclog("AHA154X: Read Port 0x%02X, Returned Value %02X\n", port, ret); + } + + return(ret); +} + + +static uint16_t +aha_readw(uint16_t port, void *priv) +{ + return aha_read(port, priv); +} + + +static uint32_t +aha_readl(uint16_t port, void *priv) +{ + return aha_read(port, priv); +} + + +/* This is BS - we just need a 'dev_present' indication.. --FvK */ +static int +aha_dev_present(uint8_t id, uint8_t lun) +{ + if (lun > 7) return(0); + + if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); + + if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && + cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && + (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) return(1); + + return(0); +} + + +static void +aha_write(uint16_t port, uint8_t val, void *priv) +{ + int i = 0; + uint8_t j = 0; + aha_t *dev = (aha_t *)priv; + uint8_t max_id = 8; + uint8_t Offset; + MailboxInit_t *MailboxInit; + ReplyInquireSetupInformation *ReplyISI; + ReplyInquireExtendedSetupInformation *ReplyIESI; + int cCharsToTransfer; + + pclog("AHA154X: Write Port 0x%02X, Value %02X\n", port, val); + + switch (port & 3) { + case 0: + if ((val & CTRL_HRST) || (val & CTRL_SRST)) { + uint8_t Reset = !(val & CTRL_HRST); + aha_reset_ctrl(dev, Reset); + break; + } + + if (val & CTRL_IRST) { + ClearIntr(dev); + } + break; + + case 1: + /* Fast path for the mailbox execution command. */ + if (((val == 0x02) || (val == 0x82)) && + (dev->Command == 0xFF)) { + /* If there are no mailboxes configured, don't even try to do anything. */ + if (dev->MailboxCount) { + if (!AHA_Callback) { + AHA_Callback = 50 * SCSI_TIME; + } + } + return; + } + + if (dev->Command == 0xFF) { + dev->Command = val; + dev->CmdParam = 0; + dev->CmdParamLeft = 0; + + dev->Status &= ~(STAT_INVCMD | STAT_IDLE); + pclog("AHA154X: Operation Code 0x%02X\n", val); + switch (dev->Command) { + case 0x01: + dev->CmdParamLeft = sizeof(MailboxInit_t); + break; + + case 0x03: /* Exec BIOS Command */ + dev->CmdParamLeft = 10; + break; + + case 0x25: + /* Same as 0x01 for AHA. */ + dev->CmdParamLeft = sizeof(MailboxInit_t); + break; + + case 0x05: + case 0x07: + case 0x08: + case 0x09: + case 0x0D: + case 0x1F: + case 0x21: + case 0x24: + dev->CmdParamLeft = 1; + break; + + case 0x06: + dev->CmdParamLeft = 4; + break; + + case 0x1C: + case 0x1D: + dev->CmdParamLeft = 3; + break; + + case 0x22: /* write EEPROM */ + dev->CmdParamLeft = 3+32; + break; + + case 0x23: /* read EEPROM */ + dev->CmdParamLeft = 3; + break; + + case 0x29: + dev->CmdParamLeft = 2; + break; + + case 0x91: + dev->CmdParamLeft = 2; + break; + } + } else { + dev->CmdBuf[dev->CmdParam] = val; + dev->CmdParam++; + dev->CmdParamLeft--; + } + + if (! dev->CmdParamLeft) { + pclog("Running Operation Code 0x%02X\n", dev->Command); + switch (dev->Command) { + case 0x00: + dev->DataReplyLeft = 0; + break; + + case 0x01: +aha_0x01: + { + dev->Mbx24bit = 1; + + MailboxInit = (MailboxInit_t *)dev->CmdBuf; + + dev->MailboxCount = MailboxInit->Count; + dev->MailboxOutAddr = ADDR_TO_U32(MailboxInit->Address); + dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t)); + + pclog("Initialize Mailbox Command\n"); + pclog("Mailbox Out Address=0x%08X\n", dev->MailboxOutAddr); + pclog("Mailbox In Address=0x%08X\n", dev->MailboxInAddr); + pclog("Initialized Mailbox, %d entries at 0x%08X\n", MailboxInit->Count, ADDR_TO_U32(MailboxInit->Address)); + + dev->Status &= ~STAT_INIT; + dev->DataReplyLeft = 0; + } + break; + + case 0x03: + dev->DataBuf[0] = 0x00; + dev->DataReplyLeft = 1; + break; + + case 0x04: + dev->DataBuf[0] = dev->aha.bid; + dev->DataBuf[1] = 0x30; + dev->DataBuf[2] = dev->aha.fwh; + dev->DataBuf[3] = dev->aha.fwl; + dev->DataReplyLeft = 4; + break; + + case 0x05: + if (dev->CmdBuf[0] <= 1) { + dev->MailboxOutInterrupts = dev->CmdBuf[0]; + pclog("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); + } else { + dev->Status |= STAT_INVCMD; + } + dev->DataReplyLeft = 0; + break; + + case 0x06: + dev->DataReplyLeft = 0; + break; + + case 0x07: + dev->DataReplyLeft = 0; + dev->LocalRAM.structured.autoSCSIData.uBusOnDelay = dev->CmdBuf[0]; + pclog("Bus-on time: %d\n", dev->CmdBuf[0]); + break; + + case 0x08: + dev->DataReplyLeft = 0; + dev->LocalRAM.structured.autoSCSIData.uBusOffDelay = dev->CmdBuf[0]; + pclog("Bus-off time: %d\n", dev->CmdBuf[0]); + break; + + case 0x09: + dev->DataReplyLeft = 0; + dev->LocalRAM.structured.autoSCSIData.uDMATransferRate = dev->CmdBuf[0]; + pclog("DMA transfer rate: %02X\n", dev->CmdBuf[0]); + break; + + case 0x0A: + memset(dev->DataBuf, 0, 8); + for (i=0; i<7; i++) { + dev->DataBuf[i] = 0; + for (j=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + dev->DataBuf[i] |= (1<DataBuf[7] = 0; + dev->DataReplyLeft = 8; + break; + + case 0x0B: + dev->DataBuf[0] = (1<DmaChannel); + if (dev->Irq >= 8) + dev->DataBuf[1]=(1<<(dev->Irq-9)); + else + dev->DataBuf[1]=(1<Irq); + dev->DataBuf[2] = 7; /* HOST ID */ + dev->DataReplyLeft = 3; + break; + + case 0x0D: + { + dev->DataReplyLeft = dev->CmdBuf[0]; + + ReplyISI = (ReplyInquireSetupInformation *)dev->DataBuf; + memset(ReplyISI, 0, sizeof(ReplyInquireSetupInformation)); + + ReplyISI->fSynchronousInitiationEnabled = 1; + ReplyISI->fParityCheckingEnabled = 1; + ReplyISI->cMailbox = dev->MailboxCount; + U32_TO_ADDR(ReplyISI->MailboxAddress, dev->MailboxOutAddr); + pclog("Return Setup Information: %d\n", dev->CmdBuf[0]); + } + break; + + case 0x1C: + { + uint32_t FIFOBuf; + addr24 Address; + + dev->DataReplyLeft = 0; + Address.hi = dev->CmdBuf[0]; + Address.mid = dev->CmdBuf[1]; + Address.lo = dev->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + DMAPageRead(FIFOBuf, (char *)&dev->LocalRAM.u8View[64], 64); + } + break; + + case 0x1D: + { + uint32_t FIFOBuf; + addr24 Address; + + dev->DataReplyLeft = 0; + Address.hi = dev->CmdBuf[0]; + Address.mid = dev->CmdBuf[1]; + Address.lo = dev->CmdBuf[2]; + FIFOBuf = ADDR_TO_U32(Address); + pclog("FIFO: Writing 64 bytes at %08X\n", FIFOBuf); + DMAPageWrite(FIFOBuf, (char *)&dev->LocalRAM.u8View[64], 64); + } + break; + + case 0x1F: + dev->DataBuf[0] = dev->CmdBuf[0]; + dev->DataReplyLeft = 1; + break; + + case 0x21: + if (dev->CmdParam == 1) + dev->CmdParamLeft = dev->CmdBuf[0]; + dev->DataReplyLeft = 0; + break; + + case 0x22: /* write EEPROM */ + /* Sent by CF BIOS. */ + dev->DataReplyLeft = + aha154x_eeprom(dev->Command, + dev->CmdBuf[0], + dev->CmdBuf[1], + dev->CmdBuf[2], + &dev->CmdBuf[3]); + if (dev->DataReplyLeft == 0xff) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + + case 0x23: + dev->DataReplyLeft = + aha154x_eeprom(dev->Command, + dev->CmdBuf[0], + dev->CmdBuf[1], + dev->CmdBuf[2], + dev->DataBuf); + if (dev->DataReplyLeft == 0xff) { + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + } + break; + + case 0x24: + /* + * For AHA1542CF, this is the command + * to play with the Shadow RAM. BIOS + * gives us one argument (00,02,03) + * and expects a 0x04 back in the INTR + * register. --FvK + */ + dev->Interrupt = aha154x_shram(val); + break; + + case 0x25: + goto aha_0x01; + + case 0x26: /* AHA memory mapper */ + case 0x27: /* AHA memory mapper */ + dev->DataReplyLeft = + aha154x_memory(dev->Command); + break; + + case 0x28: + dev->DataBuf[0] = 0x08; + dev->DataBuf[1] = dev->Lock; + dev->DataReplyLeft = 2; + break; + + case 0x29: + if (dev->CmdBuf[1] == dev->Lock) { + if (dev->CmdBuf[0] & 1) { + dev->Lock = 1; + } else { + dev->Lock = 0; + } + } + dev->DataReplyLeft = 0; + break; + + case 0x2C: /* AHA-1542CP sends this */ + dev->DataBuf[0] = 0x00; + dev->DataReplyLeft = 1; + break; + + case 0x33: /* AHA-1542CP sends this */ + dev->DataBuf[0] = 0x00; + dev->DataBuf[1] = 0x00; + dev->DataBuf[2] = 0x00; + dev->DataBuf[3] = 0x00; + dev->DataReplyLeft = 256; + break; + + case 0x91: + Offset = dev->CmdBuf[0]; + dev->DataReplyLeft = dev->CmdBuf[1]; + + dev->UseLocalRAM = 1; + dev->DataReply = Offset; + break; + + default: + dev->DataReplyLeft = 0; + dev->Status |= STAT_INVCMD; + break; + } + } + + if (dev->DataReplyLeft) + dev->Status |= STAT_DFULL; + else if (!dev->CmdParamLeft) + aha_cmd_done(dev); + break; + + case 2: + break; + + case 3: + break; + } +} + + +static void +aha_writew(uint16_t Port, uint16_t Val, void *p) +{ + aha_write(Port, Val & 0xFF, p); +} + + +static void +aha_writeL(uint16_t Port, uint32_t Val, void *p) +{ + aha_write(Port, Val & 0xFF, p); +} + + +static uint8_t +ConvertSenseLength(uint8_t RequestSenseLength) +{ + pclog("Unconverted Request Sense length %i\n", RequestSenseLength); + + if (RequestSenseLength == 0) + RequestSenseLength = 14; + else if (RequestSenseLength == 1) + RequestSenseLength = 0; + + pclog("Request Sense length %i\n", RequestSenseLength); + + return(RequestSenseLength); +} + + +static void +SenseBufferFree(Req_t *req, int Copy, int is_hd) +{ + uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); + uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN]; + uint8_t hdc_id = scsi_hard_disks[req->TargetID][req->LUN]; + uint32_t SenseBufferAddress; + uint8_t temp_sense[256]; + + if (SenseLength && Copy) { + if (is_hd) + { + scsi_hd_request_sense_for_scsi(hdc_id, temp_sense, SenseLength); + } + else + { + cdrom_request_sense_for_scsi(cdrom_id, temp_sense, SenseLength); + } + + /* + * The sense address, in 32-bit mode, is located in the + * Sense Pointer of the CCB, but in 24-bit mode, it is + * located at the end of the Command Descriptor Block. + */ + if (req->Is24bit) { + SenseBufferAddress = req->CCBPointer; + SenseBufferAddress += req->CmdBlock.common.CdbLength + offsetof(CCB, Cdb); + } else { + SenseBufferAddress = req->CmdBlock.new.SensePointer; + } + + pclog("Request Sense address: %02X\n", SenseBufferAddress); + + pclog("SenseBufferFree(): Writing %i bytes at %08X\n", + SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, (char *)temp_sense, SenseLength); + pclog("Sense data written to buffer: %02X %02X %02X\n", + temp_sense[2], temp_sense[12], temp_sense[13]); + } +} + + +static void +aha_disk_cmd(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint8_t Id, Lun; + uint8_t hdc_id; + uint8_t hd_phase; + uint8_t temp_cdb[12]; + uint32_t i; + + Id = req->TargetID; + Lun = req->LUN; + hdc_id = scsi_hard_disks[Id][Lun]; + + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", + Id, Lun, hdc_id); + + pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) { + pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, shdc[hdc_id].cdb_len); + if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len); + } + + /* + * Since that field in the HDC struct is never used when + * the bus type is SCSI, let's use it for this scope. + */ + shdc[hdc_id].request_length = temp_cdb[1]; + + if (req->CmdBlock.common.CdbLength != 12) { + /* + * Make sure the LUN field of the temporary CDB is always 0, + * otherwise Daemon Tools drives will misbehave when a command + * is passed through to them. + */ + temp_cdb[1] &= 0x1f; + } + + /* Finally, execute the SCSI command immediately and get the transfer length. */ + SCSIPhase = SCSI_PHASE_COMMAND; + scsi_hd_command(hdc_id, temp_cdb); + SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id); + if (SCSIStatus == SCSI_STATUS_OK) { + hd_phase = scsi_hd_phase_to_scsi(hdc_id); + if (hd_phase == 2) { + /* Command completed - call the phase callback to complete the command. */ + scsi_hd_callback(hdc_id); + } else { + /* Command first phase complete - call the callback to execute the second phase. */ + scsi_hd_callback(hdc_id); + SCSIStatus = scsi_hd_err_stat_to_scsi(hdc_id); + /* Command second phase complete - call the callback to complete the command. */ + scsi_hd_callback(hdc_id); + } + } else { + /* Error (Check Condition) - call the phase callback to complete the command. */ + scsi_hd_callback(hdc_id); + } + + pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", shdc[hdc_id].sense[2], shdc[hdc_id].sense[12], shdc[hdc_id].sense[13]); + + aha_buf_free(req); + + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 1); + + pclog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + + +static void +aha_cdrom_cmd(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint8_t Id, Lun; + uint8_t cdrom_id; + uint8_t cdrom_phase; + uint8_t temp_cdb[12]; + uint32_t i; + + Id = req->TargetID; + Lun = req->LUN; + cdrom_id = scsi_cdrom_drives[Id][Lun]; + + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", + Id, Lun, cdrom_id); + + pclog("SCSI Cdb[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i = 1; i < req->CmdBlock.common.CdbLength; i++) { + pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + } + + memset(temp_cdb, 0, cdrom[cdrom_id].cdb_len); + if (req->CmdBlock.common.CdbLength <= cdrom[cdrom_id].cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, cdrom[cdrom_id].cdb_len); + } + + /* + * Since that field in the CDROM struct is never used when + * the bus type is SCSI, let's use it for this scope. + */ + cdrom[cdrom_id].request_length = temp_cdb[1]; + + if (req->CmdBlock.common.CdbLength != 12) { + /* + * Make sure the LUN field of the temporary CDB is always 0, + * otherwise Daemon Tools drives will misbehave when a command + * is passed through to them. + */ + temp_cdb[1] &= 0x1f; + } + + /* Finally, execute the SCSI command immediately and get the transfer length. */ + SCSIPhase = SCSI_PHASE_COMMAND; + cdrom_command(cdrom_id, temp_cdb); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + if (SCSIStatus == SCSI_STATUS_OK) { + cdrom_phase = cdrom_atapi_phase_to_scsi(cdrom_id); + if (cdrom_phase == 2) { + /* Command completed - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } else { + /* Command first phase complete - call the callback to execute the second phase. */ + cdrom_phase_callback(cdrom_id); + SCSIStatus = cdrom_CDROM_PHASE_to_scsi(cdrom_id); + /* Command second phase complete - call the callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + } else { + /* Error (Check Condition) - call the phase callback to complete the command. */ + cdrom_phase_callback(cdrom_id); + } + + pclog("SCSI Status: %s, Sense: %02X, ASC: %02X, ASCQ: %02X\n", (SCSIStatus == SCSI_STATUS_OK) ? "OK" : "CHECK CONDITION", cdrom[cdrom_id].sense[2], cdrom[cdrom_id].sense[12], cdrom[cdrom_id].sense[13]); + + aha_buf_free(req); + + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK), 0); + + pclog("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + + +static void +aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +{ + Req_t *req = &dev->Req; + uint8_t Id, Lun; + uint8_t last_id = 7; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&req->CmdBlock, sizeof(CCB32)); + + req->Is24bit = dev->Mbx24bit; + req->CCBPointer = CCBPointer; + req->TargetID = dev->Mbx24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; + req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; + + Id = req->TargetID; + Lun = req->LUN; + if ((Id > last_id) || (Lun > 7)) { + aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + return; + } + + pclog("Scanning SCSI Target ID %i\n", Id); + + SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[Id][Lun].InitLength = 0; + + /* Do this here, so MODE SELECT data does not get lost in transit. */ + memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); + + aha_buf_alloc(req, req->Is24bit); + + if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { + pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun); + aha_buf_free(req); + SenseBufferFree(req, 0, 0); + aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); + } else { + pclog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); + + pclog("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); + pclog("CDB Length %i\n", req->CmdBlock.common.CdbLength); + pclog("CCB Opcode %x\n", req->CmdBlock.common.Opcode); + if (req->CmdBlock.common.ControlByte > 0x03) { + pclog("Invalid control byte: %02X\n", + req->CmdBlock.common.ControlByte); + } + + AHA_InOperation = (SCSIDevices[Id][Lun].LunType == SCSI_DISK) ? 0x11 : 1; + pclog("SCSI (%i:%i) -> %i\n", Id, Lun, SCSIDevices[Id][Lun].LunType); + } +} + + +static void +aha_req_abort(aha_t *dev, uint32_t CCBPointer) +{ + CCBU CmdBlock; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&CmdBlock, sizeof(CCB32)); + + aha_mbi_setup(dev, CCBPointer, &CmdBlock, + 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); +} + + +static uint32_t +aha_mbo(aha_t *dev, Mailbox32_t *Mailbox32) +{ + Mailbox_t MailboxOut; + uint32_t Outgoing; + + if (dev->Mbx24bit) { + Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox_t)); + DMAPageRead(Outgoing, (char *)&MailboxOut, sizeof(Mailbox_t)); + + Mailbox32->CCBPointer = ADDR_TO_U32(MailboxOut.CCBPointer); + Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; + } else { + Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox32_t)); + + DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t)); + } + + return Outgoing; +} + + +static void +aha_mbo_adv(aha_t *dev) +{ + dev->MailboxOutPosCur = (dev->MailboxOutPosCur + 1) % dev->MailboxCount; +} + + +static void +aha_do_mail(aha_t *dev) +{ + Mailbox32_t mb32; + uint32_t Outgoing; + uint8_t CmdStatus = MBO_FREE; + uint32_t CodeOffset = 0; + + CodeOffset = dev->Mbx24bit ? offsetof(Mailbox_t, CmdStatus) : offsetof(Mailbox32_t, u.out.ActionCode); + + if (! dev->StrictRoundRobinMode) { + uint8_t MailboxCur = dev->MailboxOutPosCur; + + /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ + do { + /* Fetch mailbox from guest memory. */ + Outgoing = aha_mbo(dev, &mb32); + + /* Check the next mailbox. */ + aha_mbo_adv(dev); + } while ((mb32.u.out.ActionCode == MBO_FREE) && (MailboxCur != dev->MailboxOutPosCur)); + } else { + Outgoing = aha_mbo(dev, &mb32); + } + + if (mb32.u.out.ActionCode != MBO_FREE) { + /* We got the mailbox, mark it as free in the guest. */ + pclog("aha_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); + } + + if (dev->MailboxOutInterrupts) + RaiseIntr(dev, INTR_MBOA | INTR_ANY); + + /* Check if the mailbox is actually loaded. */ + if (mb32.u.out.ActionCode == MBO_FREE) { + return; + } + + if (mb32.u.out.ActionCode == MBO_START) { + pclog("Start Mailbox Command\n"); + aha_req_setup(dev, mb32.CCBPointer, &mb32); + } else if (mb32.u.out.ActionCode == MBO_ABORT) { + pclog("Abort Mailbox Command\n"); + aha_req_abort(dev, mb32.CCBPointer); + } else { + pclog("Invalid action code: %02X\n", mb32.u.out.ActionCode); + } + + /* Advance to the next mailbox. */ + if (dev->StrictRoundRobinMode) + aha_mbo_adv(dev); +} + + +static void +aha_reset_poll(void *priv) +{ + aha_t *dev = (aha_t *)priv; + + dev->Status &= ~STAT_STST; + dev->Status |= STAT_IDLE; + + ResetCB = 0; +} + + +static void +aha_cmd_cb(void *priv) +{ + aha_t *dev = (aha_t *)priv; + + if (AHA_InOperation == 0) { + if (dev->MailboxCount) { + aha_do_mail(dev); + } else { + AHA_Callback += 50 * SCSI_TIME; + return; + } + } else if (AHA_InOperation == 1) { + pclog("BusLogic Callback: Process CD-ROM request\n"); + aha_cdrom_cmd(dev); + } else if (AHA_InOperation == 2) { + pclog("BusLogic Callback: Send incoming mailbox\n"); + aha_mbi(dev); + } else if (AHA_InOperation == 0x11) { + pclog("BusLogic Callback: Process DISK request\n"); + aha_disk_cmd(dev); + } else { + fatal("Invalid BusLogic callback phase: %i\n", AHA_InOperation); + } + + AHA_Callback += 50 * SCSI_TIME; +} + + +static void * +aha_init(int chip, int has_bios) +{ + aha_t *dev; + int i = 0; + int j = 0; + uint32_t bios_addr = 0; + int bios = 0; + + dev = malloc(sizeof(aha_t)); + memset(dev, 0x00, sizeof(aha_t)); + + ResetDev = dev; + dev->chip = chip; + dev->Base = device_get_config_int("addr"); + dev->Irq = device_get_config_int("irq"); + dev->DmaChannel = device_get_config_int("dma"); + bios = device_get_config_int("bios"); + bios_addr = device_get_config_int("bios_addr"); + + if (dev->Base != 0) { + io_sethandler(dev->Base, 4, + aha_read, aha_readw, NULL, + aha_write, aha_writew, NULL, dev); + } + + pclog("Building SCSI hard disk map...\n"); + build_scsi_hd_map(); + pclog("Building SCSI CD-ROM map...\n"); + build_scsi_cdrom_map(); + + for (i=0; i<16; i++) { + for (j=0; j<8; j++) { + if (scsi_hard_disks[i][j] != 0xff) { + SCSIDevices[i][j].LunType = SCSI_DISK; + } + } + } + + for (i=0; iBase); + + aha_reset_ctrl(dev, CTRL_HRST); + + if (bios) { + /* Perform AHA-154xNN-specific initialization. */ + aha154x_bios(dev->Base, bios_addr, &dev->aha); + } + + return(dev); +} + + +static void * +aha_154xB_init(void) +{ + return(aha_init(CHIP_AHA154XB, 0)); +} + + +static void * +aha_154xCF_init(void) +{ + return(aha_init(CHIP_AHA154XCF, 1)); +} + + +static void +aha_close(void *priv) +{ + aha_t *dev = (aha_t *)priv; + free(dev); + ResetDev = NULL; +} + + +static device_config_t aha_154XCF_config[] = { + { + "addr", "Address", CONFIG_SELECTION, "", 0x334, + { + { + "None", 0 + }, + { + "0x330", 0x330 + }, + { + "0x334", 0x334 + }, + { + "0x230", 0x230 + }, + { + "0x234", 0x234 + }, + { + "0x130", 0x130 + }, + { + "0x134", 0x134 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, + { + { + "DMA 5", 5 + }, + { + "DMA 6", 6 + }, + { + "DMA 7", 7 + }, + { + "" + } + }, + }, + { + "bios", "Enable BIOS", CONFIG_BINARY, 0 + }, + { + "bios_addr", "BIOS Address", CONFIG_SELECTION, "", 0xd8000, + { + { + "C800H", 0xc8000 + }, + { + "D000H", 0xd0000 + }, + { + "D800H", 0xd8000 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; + + +device_t aha1540b_device = { + "Adaptec AHA-1540B", + 0, + aha_154xB_init, + aha_close, + NULL, + NULL, + NULL, + NULL, + aha_154XCF_config +}; + +device_t aha1542cf_device = { + "Adaptec AHA-1542CF", + 0, + aha_154xCF_init, + aha_close, + NULL, + NULL, + NULL, + NULL, + aha_154XCF_config +}; diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 39da63367..14e6a249a 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -1,13 +1,11 @@ /* Copyright holders: SA1988 see COPYING for more details */ -/*Buslogic SCSI emulation (including Adaptec 154x ISA software backward compatibility) and the Adaptec 154x itself*/ +/*Buslogic SCSI emulation*/ /* Emulated SCSI controllers: - 0 - Adaptec AHA-154xB ISA; - 1 - Adaptec AHA-154xCF ISA; - 2 - BusLogic BT-542B ISA; - 3 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ + 0 - BusLogic BT-542B ISA; + 1 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ #include #include @@ -15,7 +13,6 @@ #include #include #include "ibm.h" -#include "device.h" #include "io.h" #include "mem.h" #include "rom.h" @@ -23,6 +20,7 @@ #include "pic.h" #include "pci.h" #include "timer.h" +#include "device.h" #include "scsi.h" #include "cdrom.h" #include "scsi_buslogic.h" @@ -31,18 +29,6 @@ #define BUSLOGIC_RESET_DURATION_NS UINT64_C(50000000) -#pragma pack(push,1) -typedef struct { - uint8_t hi; - uint8_t mid; - uint8_t lo; -} addr24; -#pragma pack(pop) - -#define ADDR_TO_U32(x) (((x).hi<<16)|((x).mid<<8)|((x).lo&0xFF)) -#define U32_TO_ADDR(a,x) do {(a).hi=(x)>>16;(a).mid=(x)>>8;(a).lo=(x)&0xFF;}while(0) - - /* * Host Adapter I/O ports. * @@ -439,29 +425,6 @@ typedef union { #pragma pack(pop) -/* - * - * Scatter/Gather Segment List Definitions - * - * Adapter limits - */ -/* #define MAX_SG_DESCRIPTORS ((bl->chip >= CHIP_BUSLOGIC_ISA) ? 32 : 17) */ -#define MAX_SG_DESCRIPTORS 32 /* Always make the array 32 elements long, if less are used, that's not an issue. */ - -#pragma pack(push,1) -typedef struct { - uint32_t Segment; - uint32_t SegmentPointer; -} SGE32; -#pragma pack(pop) - -#pragma pack(push,1) -typedef struct { - addr24 Segment; - addr24 SegmentPointer; -} SGE; -#pragma pack(pop) - #pragma pack(push,1) typedef struct { CCBU CmdBlock; @@ -473,7 +436,7 @@ typedef struct { uint8_t HostStatus; uint8_t TargetStatus; uint8_t MailboxCompletionCode; -} BuslogicRequests_t; +} Req_t; #pragma pack(pop) #pragma pack(push,1) @@ -483,7 +446,7 @@ typedef struct { int StrictRoundRobinMode; int ExtendedLUNCCBFormat; HALocalRAM LocalRAM; - BuslogicRequests_t BuslogicRequests; + Req_t Req; uint8_t Status; uint8_t Interrupt; uint8_t Geometry; @@ -512,30 +475,23 @@ typedef struct { int PendingInterrupt; int Lock; mem_mapping_t mmio_mapping; - aha_info aha; int chip; } Buslogic_t; #pragma pack(pop) -int scsi_model = 1; -int BuslogicResetCallback = 0; -int BuslogicCallback = 0; -int BuslogicInOperation = 0; +static int BuslogicResetCallback = 0; +static int BuslogicCallback = 0; +static int BuslogicInOperation = 0; static Buslogic_t *BuslogicResetDevice; -enum -{ - CHIP_AHA154XB, - CHIP_AHA154XCF, - CHIP_BUSLOGIC_ISA, - CHIP_BUSLOGIC_PCI +enum { + CHIP_BUSLOGIC_ISA, + CHIP_BUSLOGIC_PCI }; -static void BuslogicStartMailbox(Buslogic_t *Buslogic); - #ifdef WALTJE int buslogic_do_log = 1; # define ENABLE_BUSLOGIC_LOG @@ -544,7 +500,11 @@ int buslogic_do_log = 0; #endif -static void BuslogicLog(const char *format, ...) +static void BuslogicStartMailbox(Buslogic_t *); + + +static void +BuslogicLog(const char *format, ...) { #ifdef ENABLE_BUSLOGIC_LOG va_list ap; @@ -560,7 +520,8 @@ static void BuslogicLog(const char *format, ...) #define pclog BuslogicLog -static void BuslogicClearInterrupt(Buslogic_t *bl) +static void +BuslogicClearInterrupt(Buslogic_t *bl) { pclog("Buslogic: Lowering Interrupt 0x%02X\n", bl->Interrupt); bl->Interrupt = 0; @@ -577,7 +538,8 @@ static void BuslogicClearInterrupt(Buslogic_t *bl) } -static void BuslogicLocalRAM(Buslogic_t *bl) +static void +BuslogicLocalRAM(Buslogic_t *bl) { /* * These values are mostly from what I think is right @@ -601,7 +563,8 @@ static void BuslogicLocalRAM(Buslogic_t *bl) } -static void BuslogicReset(Buslogic_t *bl) +static void +BuslogicReset(Buslogic_t *bl) { BuslogicCallback = 0; BuslogicResetCallback = 0; @@ -626,7 +589,8 @@ static void BuslogicReset(Buslogic_t *bl) } -void BuslogicSoftReset(void) +static void +BuslogicSoftReset(void) { if (BuslogicResetDevice != NULL) { BuslogicReset(BuslogicResetDevice); @@ -634,7 +598,8 @@ void BuslogicSoftReset(void) } -static void BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) +static void +BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) { BuslogicReset(bl); if (Reset) { @@ -645,16 +610,13 @@ static void BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) } -static void BuslogicCommandComplete(Buslogic_t *bl) +static void +BuslogicCommandComplete(Buslogic_t *bl) { bl->DataReply = 0; bl->Status |= STAT_IDLE; -#ifdef WALTJE - if ((bl->Command != 0x02) && (bl->Command != 0x82)) { -#else if (bl->Command != 0x02) { -#endif bl->Status &= ~STAT_DFULL; bl->Interrupt = (INTR_ANY | INTR_HACC); pclog("Raising IRQ %i\n", bl->Irq); @@ -667,7 +629,8 @@ static void BuslogicCommandComplete(Buslogic_t *bl) } -static void BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) +static void +BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) { if (bl->Interrupt & INTR_HACC) { pclog("Pending IRQ\n"); @@ -681,12 +644,12 @@ static void BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) } -static void BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, - CCBU *CmdBlock, uint8_t HostStatus, - uint8_t TargetStatus, - uint8_t MailboxCompletionCode) +static void +BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, CCBU *CmdBlock, + uint8_t HostStatus, uint8_t TargetStatus, + uint8_t MailboxCompletionCode) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; req->CCBPointer = CCBPointer; memcpy(&(req->CmdBlock), CmdBlock, sizeof(CCB32)); @@ -701,9 +664,10 @@ static void BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, } -static void BuslogicMailboxIn(Buslogic_t *bl) +static void +BuslogicMailboxIn(Buslogic_t *bl) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint32_t CCBPointer = req->CCBPointer; CCBU *CmdBlock = &(req->CmdBlock); uint8_t HostStatus = req->HostStatus; @@ -758,7 +722,8 @@ static void BuslogicMailboxIn(Buslogic_t *bl) } -static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) +static void +BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries, SGE32 *SG) { uint32_t i; SGE SGE24[MAX_SG_DESCRIPTORS]; @@ -777,7 +742,8 @@ static void BuslogicReadSGEntries(int Is24bit, uint32_t SGList, uint32_t Entries } -void BuslogicDataBufferAllocate(BuslogicRequests_t *req, int Is24bit) +static void +BuslogicDataBufferAllocate(Req_t *req, int Is24bit) { uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; @@ -873,7 +839,8 @@ void BuslogicDataBufferAllocate(BuslogicRequests_t *req, int Is24bit) } -void BuslogicDataBufferFree(BuslogicRequests_t *req) +static void +BuslogicDataBufferFree(Req_t *req) { uint32_t DataPointer = 0; uint32_t DataLength = 0; @@ -974,7 +941,8 @@ void BuslogicDataBufferFree(BuslogicRequests_t *req) } -static uint8_t BuslogicRead(uint16_t Port, void *p) +static uint8_t +BuslogicRead(uint16_t Port, void *p) { Buslogic_t *bl = (Buslogic_t *)p; uint8_t Temp; @@ -1016,20 +984,22 @@ static uint8_t BuslogicRead(uint16_t Port, void *p) } -static uint16_t BuslogicReadW(uint16_t Port, void *p) +static uint16_t +BuslogicReadW(uint16_t Port, void *p) { return BuslogicRead(Port, p); } -static uint32_t BuslogicReadL(uint16_t Port, void *p) +static uint32_t +BuslogicReadL(uint16_t Port, void *p) { return BuslogicRead(Port, p); } /* This is BS - we just need a 'dev_present' indication.. --FvK */ -int +static int buslogic_dev_present(uint8_t id, uint8_t lun) { if (lun > 7) return(0); @@ -1046,7 +1016,8 @@ buslogic_dev_present(uint8_t id, uint8_t lun) static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); -static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) +static void +BuslogicWrite(uint16_t Port, uint8_t Val, void *p) { int i = 0; uint8_t j = 0; @@ -1078,8 +1049,7 @@ static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 1: /* Fast path for the mailbox execution command. */ - if (((Val == 0x02) || (Val == 0x82)) && - (bl->Command == 0xFF)) { + if ((Val == 0x02) && (bl->Command == 0xFF)) { /* If there are no mailboxes configured, don't even try to do anything. */ if (bl->MailboxCount) { if (!BuslogicCallback) { @@ -1101,19 +1071,8 @@ static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) bl->CmdParamLeft = sizeof(MailboxInit_t); break; - case 0x03: /* Exec BIOS Command */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->CmdParamLeft = 10; - } - break; - case 0x25: - if (bl->chip < CHIP_BUSLOGIC_ISA) { - /* Same as 0x01 for AHA. */ - bl->CmdParamLeft = sizeof(MailboxInit_t); - } else { bl->CmdParamLeft = 1; - } break; case 0x05: @@ -1136,36 +1095,19 @@ static void BuslogicWrite(uint16_t Port, uint8_t Val, void *p) bl->CmdParamLeft = 3; break; - case 0x22: /* write EEPROM */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->CmdParamLeft = 3+32; - } - break; - - case 0x23: /* read EEPROM */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->CmdParamLeft = 3; - } - break; - - case 0x29: - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 0 : 2; - break; - case 0x8B: case 0x8D: case 0x8F: case 0x96: - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 1 : 0; + bl->CmdParamLeft = 1; break; case 0x81: - pclog("Command 0x81 on %s\n", (bl->chip >= CHIP_BUSLOGIC_ISA) ? "BusLogic" : "Adaptec"); - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? sizeof(MailboxInitExtended_t) : 0; + bl->CmdParamLeft = sizeof(MailboxInitExtended_t); break; case 0x8C: - bl->CmdParamLeft = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 1 : 0; + bl->CmdParamLeft = 1; break; case 0x91: @@ -1216,17 +1158,10 @@ aha_0x01: break; case 0x04: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { bl->DataBuf[0] = 0x41; bl->DataBuf[1] = 0x41; bl->DataBuf[2] = '5'; bl->DataBuf[3] = '0'; - } else { - bl->DataBuf[0] = bl->aha.bid; - bl->DataBuf[1] = 0x30; - bl->DataBuf[2] = bl->aha.fwh; - bl->DataBuf[3] = bl->aha.fwl; - } bl->DataReplyLeft = 4; break; @@ -1277,14 +1212,7 @@ aha_0x01: case 0x0B: bl->DataBuf[0] = (1 << bl->DmaChannel); - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataBuf[1] = (1<<(bl->Irq-9)); - } else { - if (bl->Irq >= 8) - bl->DataBuf[1]=(1<<(bl->Irq-9)); - else - bl->DataBuf[1]=(1<Irq); - } + bl->DataBuf[1] = (1<<(bl->Irq-9)); bl->DataBuf[2] = 7; /* HOST ID */ bl->DataReplyLeft = 3; break; @@ -1301,14 +1229,12 @@ aha_0x01: ReplyISI->cMailbox = bl->MailboxCount; U32_TO_ADDR(ReplyISI->MailboxAddress, bl->MailboxOutAddr); - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - ReplyISI->uSignature = 'B'; - /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too - * friendly with Adaptec hardware and upsetting the HBA state. - */ - ReplyISI->uCharacterD = 'D'; /* BusLogic model. */ - ReplyISI->uHostBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'F' : 'A'; /* ISA bus. */ - } + ReplyISI->uSignature = 'B'; + /* The 'D' signature prevents Buslogic's OS/2 drivers from getting too + * friendly with Adaptec hardware and upsetting the HBA state. + */ + ReplyISI->uCharacterD = 'D'; /* BusLogic model. */ + ReplyISI->uHostBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'F' : 'A'; /* ISA bus. */ pclog("Return Setup Information: %d\n", bl->CmdBuf[0]); } @@ -1350,11 +1276,7 @@ aha_0x01: case 0x20: bl->DataReplyLeft = 0; - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - BuslogicResetControl(bl, 1); - } else { - bl->Status |= STAT_INVCMD; - } + BuslogicResetControl(bl, 1); break; case 0x21: @@ -1363,53 +1285,27 @@ aha_0x01: bl->DataReplyLeft = 0; break; - case 0x22: /* write EEPROM */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - /* Sent by CF BIOS. */ - bl->DataReplyLeft = - aha154x_eeprom(bl->Command, - bl->CmdBuf[0], - bl->CmdBuf[1], - bl->CmdBuf[2], - &bl->CmdBuf[3]); - if (bl->DataReplyLeft == 0xff) { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - } else { - bl->Status |= STAT_INVCMD; - bl->DataReplyLeft = 0; - } - break; - case 0x23: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { memset(bl->DataBuf, 0, 8); for (i = 8; i < 16; i++) { +#if 1 /* FIXME: Kotori, check this! */ + bl->DataBuf[i-8] = 0; + for (j=0; j<8; j++) { + if (SCSIDevices[i][j].LunType != SCSI_NONE) + bl->DataBuf[i-8] |= (1<DataBuf[i] = 0; for (i=0; j<8; j++) { if (SCSIDevices[i][j].LunType != SCSI_NONE) - bl->DataBuf[i] |= (1 << j); + bl->DataBuf[i] |= (1<DataReplyLeft = 8; - } else { - /* Sent by CF BIOS. */ - bl->DataReplyLeft = - aha154x_eeprom(bl->Command, - bl->CmdBuf[0], - bl->CmdBuf[1], - bl->CmdBuf[2], - bl->DataBuf); - if (bl->DataReplyLeft == 0xff) { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - } - break; + break; case 0x24: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { + { uint16_t TargetsPresentMask = 0; for (i=0; i<16; i++) { @@ -1421,135 +1317,46 @@ aha_0x01: bl->DataBuf[0] = TargetsPresentMask & 0xFF; bl->DataBuf[1] = TargetsPresentMask >> 8; bl->DataReplyLeft = 2; - } else { - /* - * For AHA1542CF, this is the command - * to play with the Shadow RAM. BIOS - * gives us one argument (00,02,03) - * and expects a 0x04 back in the INTR - * register. --FvK - */ - bl->Interrupt = aha154x_shram(Val); } break; - + case 0x25: - if ((bl->chip < CHIP_BUSLOGIC_ISA)) { - goto aha_0x01; - } else { if (bl->CmdBuf[0] == 0) bl->IrqEnabled = 0; else bl->IrqEnabled = 1; pclog("Lowering IRQ %i\n", bl->Irq); picintc(1 << bl->Irq); - } break; - case 0x26: /* AHA memory mapper */ - case 0x27: /* AHA memory mapper */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataReplyLeft = - aha154x_memory(bl->Command); - } else { - bl->Status |= STAT_INVCMD; - bl->DataReplyLeft = 0; - } - break; - - case 0x28: - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 0x08; - bl->DataBuf[1] = bl->Lock; - bl->DataReplyLeft = 2; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - - case 0x29: - if (bl->chip < CHIP_BUSLOGIC_ISA) { - if (bl->CmdBuf[1] == bl->Lock) { - if (bl->CmdBuf[0] & 1) { - bl->Lock = 1; - } else { - bl->Lock = 0; - } - } - bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - - case 0x2C: /* AHA-1542CP sends this */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 0x00; - bl->DataReplyLeft = 1; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - - case 0x33: /* AHA-1542CP sends this */ - if (bl->chip < CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 0x00; - bl->DataBuf[1] = 0x00; - bl->DataBuf[2] = 0x00; - bl->DataBuf[3] = 0x00; - bl->DataReplyLeft = 256; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - case 0x81: { - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->Mbx24bit = 0; - - MailboxInitE = (MailboxInitExtended_t *)bl->CmdBuf; + bl->Mbx24bit = 0; - bl->MailboxCount = MailboxInitE->Count; - bl->MailboxOutAddr = MailboxInitE->Address; - bl->MailboxInAddr = MailboxInitE->Address + (bl->MailboxCount * sizeof(Mailbox32_t)); - - pclog("Buslogic Extended Initialize Mailbox Command\n"); - pclog("Mailbox Out Address=0x%08X\n", bl->MailboxOutAddr); - pclog("Mailbox In Address=0x%08X\n", bl->MailboxInAddr); - pclog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); - - bl->Status &= ~STAT_INIT; - bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } + MailboxInitE = (MailboxInitExtended_t *)bl->CmdBuf; + + bl->MailboxCount = MailboxInitE->Count; + bl->MailboxOutAddr = MailboxInitE->Address; + bl->MailboxInAddr = MailboxInitE->Address + (bl->MailboxCount * sizeof(Mailbox32_t)); + + pclog("Buslogic Extended Initialize Mailbox Command\n"); + pclog("Mailbox Out Address=0x%08X\n", bl->MailboxOutAddr); + pclog("Mailbox In Address=0x%08X\n", bl->MailboxInAddr); + pclog("Initialized Extended Mailbox, %d entries at 0x%08X\n", MailboxInitE->Count, MailboxInitE->Address); + + bl->Status &= ~STAT_INIT; + bl->DataReplyLeft = 0; } break; case 0x84: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = '7'; - bl->DataReplyLeft = 1; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } + bl->DataBuf[0] = '7'; + bl->DataReplyLeft = 1; break; case 0x85: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataBuf[0] = 'B'; - bl->DataReplyLeft = 1; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } + bl->DataBuf[0] = 'B'; + bl->DataReplyLeft = 1; break; case 0x86: @@ -1592,64 +1399,47 @@ aha_0x01: case 0x8B: { - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - /* The reply length is set by the guest and is found in the first byte of the command buffer. */ - bl->DataReplyLeft = bl->CmdBuf[0]; - memset(bl->DataBuf, 0, bl->DataReplyLeft); - if (bl->chip == CHIP_BUSLOGIC_PCI) { - aModelName[0] = '9'; - aModelName[1] = '5'; - aModelName[2] = '8'; - aModelName[3] = 'D'; - } - cCharsToTransfer = bl->DataReplyLeft <= sizeof(aModelName) - ? bl->DataReplyLeft - : sizeof(aModelName); - - for (i = 0; i < cCharsToTransfer; i++) - bl->DataBuf[i] = aModelName[i]; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; + /* The reply length is set by the guest and is found in the first byte of the command buffer. */ + bl->DataReplyLeft = bl->CmdBuf[0]; + memset(bl->DataBuf, 0, bl->DataReplyLeft); + if (bl->chip == CHIP_BUSLOGIC_PCI) { + aModelName[0] = '9'; + aModelName[1] = '5'; + aModelName[2] = '8'; + aModelName[3] = 'D'; } + cCharsToTransfer = bl->DataReplyLeft <= sizeof(aModelName) + ? bl->DataReplyLeft + : sizeof(aModelName); + + for (i = 0; i < cCharsToTransfer; i++) + bl->DataBuf[i] = aModelName[i]; } break; case 0x8C: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { bl->DataReplyLeft = bl->CmdBuf[0]; memset(bl->DataBuf, 0, bl->DataReplyLeft); - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; + break; case 0x8D: - { - if (bl->chip >= CHIP_BUSLOGIC_ISA) { - bl->DataReplyLeft = bl->CmdBuf[0]; - ReplyIESI = (ReplyInquireExtendedSetupInformation *)bl->DataBuf; - memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); + bl->DataReplyLeft = bl->CmdBuf[0]; + ReplyIESI = (ReplyInquireExtendedSetupInformation *)bl->DataBuf; + memset(ReplyIESI, 0, sizeof(ReplyInquireExtendedSetupInformation)); - ReplyIESI->uBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'E' : 'A'; /* ISA style */ - ReplyIESI->uBiosAddress = 0; - ReplyIESI->u16ScatterGatherLimit = 8192; - ReplyIESI->cMailbox = bl->MailboxCount; - ReplyIESI->uMailboxAddressBase = bl->MailboxOutAddr; - if (bl->chip == CHIP_BUSLOGIC_PCI) { - ReplyIESI->fLevelSensitiveInterrupt = 1; - ReplyIESI->fHostWideSCSI = 1; - ReplyIESI->fHostUltraSCSI = 1; - } - memcpy(ReplyIESI->aFirmwareRevision, "07B", sizeof(ReplyIESI->aFirmwareRevision)); - pclog("Return Extended Setup Information: %d\n", bl->CmdBuf[0]); - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; + ReplyIESI->uBusType = (bl->chip == CHIP_BUSLOGIC_PCI) ? 'E' : 'A'; /* ISA style */ + ReplyIESI->uBiosAddress = 0; + ReplyIESI->u16ScatterGatherLimit = 8192; + ReplyIESI->cMailbox = bl->MailboxCount; + ReplyIESI->uMailboxAddressBase = bl->MailboxOutAddr; + if (bl->chip == CHIP_BUSLOGIC_PCI) { + ReplyIESI->fLevelSensitiveInterrupt = 1; + ReplyIESI->fHostWideSCSI = 1; + ReplyIESI->fHostUltraSCSI = 1; } - } - break; + memcpy(ReplyIESI->aFirmwareRevision, "07B", sizeof(ReplyIESI->aFirmwareRevision)); + pclog("Return Extended Setup Information: %d\n", bl->CmdBuf[0]); + break; /* VirtualBox has these two modes implemented in reverse. According to the BusLogic datasheet: @@ -1658,28 +1448,21 @@ aha_0x01: 1 is the aggressive round robin mode, which "hunts" for an active outgoing mailbox and then processes it. */ case 0x8F: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { if (bl->CmdBuf[0] == 0) bl->StrictRoundRobinMode = 1; else if (bl->CmdBuf[0] == 1) bl->StrictRoundRobinMode = 0; bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; - + break; + case 0x91: - { Offset = bl->CmdBuf[0]; bl->DataReplyLeft = bl->CmdBuf[1]; bl->UseLocalRAM = 1; bl->DataReply = Offset; - } - break; + break; case 0x95: if (bl->chip == CHIP_BUSLOGIC_PCI) { @@ -1734,18 +1517,13 @@ aha_0x01: break; case 0x96: - if (bl->chip >= CHIP_BUSLOGIC_ISA) { if (bl->CmdBuf[0] == 0) bl->ExtendedLUNCCBFormat = 0; else if (bl->CmdBuf[0] == 1) bl->ExtendedLUNCCBFormat = 1; bl->DataReplyLeft = 0; - } else { - bl->DataReplyLeft = 0; - bl->Status |= STAT_INVCMD; - } - break; + break; default: bl->DataReplyLeft = 0; @@ -1761,31 +1539,32 @@ aha_0x01: break; case 2: - if (bl->chip >= CHIP_BUSLOGIC_ISA) - bl->Interrupt = Val; /* For Buslogic */ + bl->Interrupt = Val; break; case 3: - if (bl->chip >= CHIP_BUSLOGIC_ISA) - bl->Geometry = Val; /* For Buslogic */ + bl->Geometry = Val; break; } } -static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) +static void +BuslogicWriteW(uint16_t Port, uint16_t Val, void *p) { BuslogicWrite(Port, Val & 0xFF, p); } -static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) +static void +BuslogicWriteL(uint16_t Port, uint32_t Val, void *p) { BuslogicWrite(Port, Val & 0xFF, p); } -static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) +static uint8_t +BuslogicConvertSenseLength(uint8_t RequestSenseLength) { pclog("Unconverted Request Sense length %i\n", RequestSenseLength); @@ -1800,7 +1579,8 @@ static uint8_t BuslogicConvertSenseLength(uint8_t RequestSenseLength) } -static void BuslogicSenseBufferFree(BuslogicRequests_t *req, int Copy, int is_hd) +static void +BuslogicSenseBufferFree(Req_t *req, int Copy, int is_hd) { uint8_t SenseLength = BuslogicConvertSenseLength(req->CmdBlock.common.RequestSenseLength); uint8_t cdrom_id = scsi_cdrom_drives[req->TargetID][req->LUN]; @@ -1841,9 +1621,10 @@ static void BuslogicSenseBufferFree(BuslogicRequests_t *req, int Copy, int is_hd } -static void BuslogicHDCommand(Buslogic_t *bl) +static void +BuslogicHDCommand(Buslogic_t *bl) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint8_t Id, Lun; uint8_t hdc_id; uint8_t hd_phase; @@ -1923,9 +1704,11 @@ static void BuslogicHDCommand(Buslogic_t *bl) } } -static void BuslogicCDROMCommand(Buslogic_t *bl) + +static void +BuslogicCDROMCommand(Buslogic_t *bl) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint8_t Id, Lun; uint8_t cdrom_id; uint8_t cdrom_phase; @@ -2006,9 +1789,10 @@ static void BuslogicCDROMCommand(Buslogic_t *bl) } -static void BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +static void +BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailbox32) { - BuslogicRequests_t *req = &bl->BuslogicRequests; + Req_t *req = &bl->Req; uint8_t Id, Lun; uint8_t last_id = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 15 : 7; @@ -2061,7 +1845,8 @@ static void BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbo } -static void BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) +static void +BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) { CCBU CmdBlock; @@ -2074,7 +1859,8 @@ static void BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) } -static uint32_t BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) +static uint32_t +BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) { Mailbox_t MailboxOut; uint32_t Outgoing; @@ -2095,13 +1881,15 @@ static uint32_t BuslogicMailboxOut(Buslogic_t *bl, Mailbox32_t *Mailbox32) } -static void BuslogicMailboxOutAdvance(Buslogic_t *bl) +static void +BuslogicMailboxOutAdvance(Buslogic_t *bl) { bl->MailboxOutPosCur = (bl->MailboxOutPosCur + 1) % bl->MailboxCount; } -static void BuslogicProcessMailbox(Buslogic_t *bl) +static void +BuslogicProcessMailbox(Buslogic_t *bl) { Mailbox32_t mb32; uint32_t Outgoing; @@ -2155,7 +1943,8 @@ static void BuslogicProcessMailbox(Buslogic_t *bl) } -void BuslogicResetPoll(void *p) +static void +BuslogicResetPoll(void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2166,7 +1955,8 @@ void BuslogicResetPoll(void *p) } -void BuslogicCommandCallback(void *p) +static void +BuslogicCommandCallback(void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2194,19 +1984,22 @@ void BuslogicCommandCallback(void *p) } -static uint8_t mem_read_null(uint32_t addr, void *priv) +static uint8_t +mem_read_null(uint32_t addr, void *priv) { return(0); } -static uint16_t mem_read_nullw(uint32_t addr, void *priv) +static uint16_t +mem_read_nullw(uint32_t addr, void *priv) { return(0); } -static uint32_t mem_read_nulll(uint32_t addr, void *priv) +static uint32_t +mem_read_nulll(uint32_t addr, void *priv) { return(0); } @@ -2222,7 +2015,8 @@ uint8_t buslogic_pci_regs[256]; bar_t buslogic_pci_bar[3]; -static uint8_t BuslogicPCIRead(int func, int addr, void *p) +static uint8_t +BuslogicPCIRead(int func, int addr, void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2291,7 +2085,8 @@ static uint8_t BuslogicPCIRead(int func, int addr, void *p) } -static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) +static void +BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) { Buslogic_t *bl = (Buslogic_t *)p; @@ -2387,84 +2182,8 @@ static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } -void *AdaptecInit(int has_bios, int chip) -{ - Buslogic_t *bl; - int i = 0; - int j = 0; - uint32_t bios_addr = 0; - int bios = 0; - - bl = malloc(sizeof(Buslogic_t)); - memset(bl, 0x00, sizeof(Buslogic_t)); - - BuslogicResetDevice = bl; - bl->chip = chip; - bl->Base = device_get_config_int("addr"); - bl->PCIBase = 0; - bl->MMIOBase = 0; - bl->Irq = device_get_config_int("irq"); - bl->DmaChannel = device_get_config_int("dma"); - bios = device_get_config_int("bios"); - bios_addr = device_get_config_int("bios_addr"); - - if (bl->Base != 0) { - io_sethandler(bl->Base, 4, - BuslogicRead, BuslogicReadW, NULL, - BuslogicWrite, BuslogicWriteW, NULL, bl); - } - - pclog("Building SCSI hard disk map...\n"); - build_scsi_hd_map(); - pclog("Building SCSI CD-ROM map...\n"); - build_scsi_cdrom_map(); - - for (i=0; i<16; i++) { - for (j=0; j<8; j++) - { - if (scsi_hard_disks[i][j] != 0xff) - { - SCSIDevices[i][j].LunType = SCSI_DISK; - } - } - } - - for (i=0; iBase); - - BuslogicResetControl(bl, CTRL_HRST); - - if (bios) { - /* Perform AHA-154xNN-specific initialization. */ - aha154x_init(bl->Base, bios_addr, &bl->aha); - } - - return(bl); -} - -void *AHA_154xB_Init() -{ - return AdaptecInit(0, CHIP_AHA154XB); -} - -void *AHA_154xCF_Init() -{ - return AdaptecInit(1, CHIP_AHA154XCF); -} - - -void *BuslogicInit(int chip) +static void * +BuslogicInit(int chip) { Buslogic_t *bl; @@ -2550,18 +2269,23 @@ void *BuslogicInit(int chip) return(bl); } -void *Buslogic_542B_Init() + +static void * +Buslogic_542B_Init(void) { return BuslogicInit(CHIP_BUSLOGIC_ISA); } -void *Buslogic_958D_Init() + +static void * +Buslogic_958D_Init(void) { return BuslogicInit(CHIP_BUSLOGIC_PCI); } -void BuslogicClose(void *p) +static void +BuslogicClose(void *p) { Buslogic_t *bl = (Buslogic_t *)p; free(bl); @@ -2569,107 +2293,7 @@ void BuslogicClose(void *p) } -static device_config_t AHA154XCF_Config[] = -{ - { - "addr", "Address", CONFIG_SELECTION, "", 0x334, - { - { - "None", 0 - }, - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 9, - { - { - "IRQ 9", 9 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, - }, - { - "bios", "Enable BIOS", CONFIG_BINARY, 0 - }, - { - "bios_addr", "BIOS Address", CONFIG_SELECTION, "", 0xd8000, - { - { - "C800H", 0xc8000 - }, - { - "D000H", 0xd0000 - }, - { - "D800H", 0xd8000 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - -static device_config_t BuslogicConfig[] = -{ +static device_config_t BuslogicConfig[] = { { "addr", "Address", CONFIG_SELECTION, "", 0x334, { @@ -2747,34 +2371,8 @@ static device_config_t BuslogicConfig[] = } }; -device_t aha1540b_device = -{ - "Adaptec AHA-1540B", - 0, - AHA_154xB_Init, - BuslogicClose, - NULL, - NULL, - NULL, - NULL, - BuslogicConfig -}; -device_t aha1542cf_device = -{ - "Adaptec AHA-1542CF", - 0, - AHA_154xCF_Init, - BuslogicClose, - NULL, - NULL, - NULL, - NULL, - AHA154XCF_Config -}; - -device_t buslogic_device = -{ +device_t buslogic_device = { "Buslogic BT-542B PCI", 0, Buslogic_542B_Init, @@ -2786,8 +2384,7 @@ device_t buslogic_device = BuslogicConfig }; -device_t buslogic_pci_device = -{ +device_t buslogic_pci_device = { "Buslogic BT-542B PCI", 0, Buslogic_958D_Init, diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h index 46ec9bf3b..c2d5dccc5 100644 --- a/src/scsi_buslogic.h +++ b/src/scsi_buslogic.h @@ -1,27 +1,9 @@ -#ifndef BUSLOGIC_H -# define BUSLOGIC_H +#ifndef SCSI_BUSLOGIC_H +# define SCSI_BUSLOGIC_H -typedef struct { - uint8_t flags; /* local flags */ - uint8_t bid; /* board ID */ - char fwl, fwh; /* firmware info */ -} aha_info; -#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ - - -extern device_t aha1540b_device; -extern device_t aha1542cf_device; extern device_t buslogic_device; extern device_t buslogic_pci_device; -extern int buslogic_dev_present(uint8_t id, uint8_t lun); - -extern void aha154x_init(uint16_t, uint32_t, aha_info *); -extern uint8_t aha154x_shram(uint8_t); -extern uint8_t aha154x_eeprom(uint8_t,uint8_t,uint8_t,uint8_t,uint8_t *); -extern uint8_t aha154x_memory(uint8_t); - - -#endif /*BUSLOGIC_H*/ +#endif /*SCSI_BUSLOGIC_H*/ From df4fdb803bcb38977d0a6f4a5a502bac31e11e3d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 16:46:28 +0200 Subject: [PATCH 175/392] Recommitted the 4 files that waltje's file caused to disappear. --- src/cdrom-dosbox.cpp | 560 +++++++++++++++++++++++ src/cdrom-dosbox.h | 173 +++++++ src/cdrom-image.cc | 1017 ++++++++++++++++++++++++++++++++++++++++++ src/cdrom-image.h | 25 ++ 4 files changed, 1775 insertions(+) create mode 100644 src/cdrom-dosbox.cpp create mode 100644 src/cdrom-dosbox.h create mode 100644 src/cdrom-image.cc create mode 100644 src/cdrom-image.h diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp new file mode 100644 index 000000000..86f09e8c8 --- /dev/null +++ b/src/cdrom-dosbox.cpp @@ -0,0 +1,560 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#include +#include +#include +#include +#include +#include +#include //GCC 2.95 +#include +#include +#include +#include "cdrom-dosbox.h" + +#if !defined(WIN32) +#include +#else +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = (int)file->tellg(); + if (file->fail()) return -1; + return length; +} + +CDROM_Interface_Image::CDROM_Interface_Image() +{ +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + ClearTracks(); +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + //printf("Could not load image file: %s\n", path); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = (int)(tracks.size() - 1); + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > (int)tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + track_number = tracks[track - 1].track_number; + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + int cur_track = GetTrack(sector); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success = true; //Gobliiins reads 0 sectors + for(unsigned long i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector + i); + if (!success) break; + } + + memcpy((void*)buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +bool CDROM_Interface_Image::IsMode2(unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + if (tracks[track].mode2) + { + return true; + } + else + { + return false; + } +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.attr = DATA_TRACK;//data + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.track_number = 0xAA; + track.attr = 0; + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); +} + +#if defined(WIN32) +static string dirname(char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + safe_strncpy(tmp, file, len+1); + return tmp; + } +} +#endif + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + string pathname(dirname(tmp)); + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + track.track_number = track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = AUDIO_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = DATA_TRACK; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.track_number = 0xAA; + track.attr = 0;//sync with load iso + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x14 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == DATA_TRACK) return true; + } + return false; +} + +bool CDROM_Interface_Image::HasAudioTracks(void) +{ + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == AUDIO_TRACK) return true; + } + return false; +} + + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = (int)in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/cdrom-dosbox.h b/src/cdrom-dosbox.h new file mode 100644 index 000000000..39ed79bed --- /dev/null +++ b/src/cdrom-dosbox.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#include +#include +#include +#include +#include +#include +//#include "dosbox.h" +//#include "mem.h" +//#include "mixer.h" +//#include "SDL.h" +//#include "SDL_thread.h" + +#include +typedef signed int Bits; +typedef unsigned int Bitu; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; +typedef uint16_t Bit16u; +typedef int32_t Bit32s; +typedef uint32_t Bit32u; + +typedef size_t PhysPt; + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + +extern int CDROM_GetMountType(char* path, int force); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path, int forceCD) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; +}; + +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile() { }; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); + bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool IsMode2 (unsigned long sector); + bool HasDataTrack (void); + bool HasAudioTracks (void); + + int GetTrack (int sector); + +private: + // player +static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; +typedef std::vector::iterator track_it; + std::string mcn; +}; + +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc new file mode 100644 index 000000000..24d4c4b85 --- /dev/null +++ b/src/cdrom-image.cc @@ -0,0 +1,1017 @@ +/* Copyright holders: RichardG867, Tenshi, bit + see COPYING for more details +*/ +/*CD-ROM image support*/ + +#include + +#include "config.h" +#include "cdrom-dosbox.h" +#include "cdrom.h" +#include "cdrom-image.h" +#include "cdrom-null.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include + +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +extern CDROM image_cdrom; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_image_do_log = 0; + +CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; + +void cdrom_image_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_IMAGE_LOG + if (cdrom_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void image_close(uint8_t id); + +void image_audio_callback(uint8_t id, int16_t *output, int len) +{ + if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_image[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + { + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + } + memcpy(output, cdrom_image[id].cd_buffer, len * 2); + memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + cdrom_image[id].cd_buflen -= len; +} + +void image_audio_stop(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdimg[id]) return; + int number; + unsigned char attr; + TMSF tmsf; + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + cdrom_image_log("Can't play data track\n"); + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_state = CD_STOPPED; + return; + } + cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); + pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); + len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_image_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_image_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_image[id].cd_end = len; + cdrom_image[id].cd_state = CD_PLAYING; + if (cdrom[id].seek_pos < 150) + cdrom[id].seek_pos = 150; + cdrom_image[id].cd_buflen = 0; +} + +static void image_pause(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PLAYING) + cdrom_image[id].cd_state = CD_PAUSED; +} + +static void image_resume(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PAUSED) + cdrom_image[id].cd_state = CD_PLAYING; +} + +static void image_stop(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_seek(uint8_t id, uint32_t pos) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_pos = pos; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static int image_ready(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + return 0; + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 1; +} + +static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdimg[id]) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + { + return 0; + } + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + if (!cdimg[id]) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = cdrom[id].seek_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (cdrom_image[id].image_is_iso) + { + ret = 0x15; + } + else + { + if (cdrom_image[id].cd_state == CD_PLAYING) + ret = 0x11; + else if (cdrom_image[id].cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + } + + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; + + if (msf) + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + } + + return ret; +} + +static void image_eject(uint8_t id) +{ + return; +} + +static void image_load(uint8_t id) +{ + return; +} + +static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m, s, f; + unsigned char attr; + TMSF tmsf; + int number; + + if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +typedef struct __attribute__((__packed__)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((__packed__)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2336]; +} sector_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; +} sector_raw_data_t; + +typedef union __attribute__((__packed__)) +{ + sector_raw_data_t sector_data; + uint8_t raw_data[2352]; +} sector_t; + +typedef struct __attribute__((__packed__)) +{ + sector_t sector; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((__packed__)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; +uint8_t raw_buffer[2352]; +uint8_t extra_buffer[296]; + +static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + uint8_t *b; + uint8_t *temp_b; + int real_pos; + int audio; + int mode2; + + if (!cdimg[id]) + { + return 0; + } + + if (!cdrom_drives[id].host_drive) + { + return 0; + } + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + if (cdrom_image[id].image_is_iso) + { + audio = 0; + mode2 = 0; + } + else + { + audio = image_is_track_audio(id, real_pos, 1); + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; + } + + memset(raw_buffer, 0, 2352); + memset(extra_buffer, 0, 296); + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + { + if (cdrom_sector_type == 3) + { + cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); + } + if (cdrom_sector_type > 4) + { + cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); + } + return 0; + } + else if (cdrom_sector_type == 1) + { + if (!audio || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); + return 0; + } + +read_audio: + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + memcpy(temp_b, raw_buffer, 2352); + } + else if (cdrom_sector_type == 2) + { + if (audio || mode2) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); + return 0; + } + +read_mode1: + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 4; + bb += 2048; + memset(bb, 0, 288); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); + memcpy(temp_b, raw_buffer + 16, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2064, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + } + else if (cdrom_sector_type == 4) + { + if (audio || !mode2 || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); + return 0; + } + +read_mode2: + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); + memcpy(temp_b, raw_buffer + 24, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2072, 280); + cdrom_sector_size += 280; + temp_b += 280; + } + } + else + { + if (mode2) + { + goto read_mode2; + } + else + { + if (audio) + { + goto read_audio; + } + else + { + goto read_mode1; + } + } + } + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Full error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + + *len = cdrom_sector_size; + + return 1; +} + + +static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdimg[id]) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; +} + +static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + + b[2] = 1; + b[3] = 1; + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + for (track = first_track; track <= last_track; track++) + { + if ((len + 11) > maxlen) + { + cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + if (msf) + { + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + } + return len; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + +static int image_status(uint8_t id) +{ + if (!cdimg[id]) return CD_STATUS_EMPTY; + if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; + if (cdimg[id]->HasAudioTracks()) + { + switch(cdrom_image[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } + } + return CD_STATUS_DATA_ONLY; +} + +void image_reset(uint8_t id) +{ +} + +void image_close(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; + if (cdimg[id]) + { + delete cdimg[id]; + cdimg[id] = NULL; + } + memset(cdrom_image[id].image_path, 0, 2048); +} + +static char afn[1024]; + +int image_open(uint8_t id, wchar_t *fn) +{ + if (wcscmp(fn, cdrom_image[id].image_path) != 0) + { + cdrom_image[id].image_changed = 1; + } + + /* Make sure image_changed stays when changing from an image to another image. */ + if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + _swprintf(cdrom_image[id].image_path, L"%ws", fn); + } + + if (!wcsicmp(get_extension_w(fn), L"ISO")) + { + cdrom_image[id].image_is_iso = 1; + } + else + { + cdrom_image[id].image_is_iso = 0; + } + + cdimg[id] = new CDROM_Interface_Image(); + wcstombs(afn, fn, (wcslen(fn) << 1) + 2); + if (!cdimg[id]->SetDevice(afn, false)) + { + image_close(id); + cdrom_set_null_handler(id); + return 1; + } + cdrom_image[id].cd_state = CD_STOPPED; + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_buflen = 0; + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0); + cdrom_drives[id].handler = &image_cdrom; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + if (!cdrom_image[id].image_inited) + cdrom_image[id].image_inited = 1; + } + return 0; +} + +static void image_exit(uint8_t id) +{ + cdrom_image[id].image_inited = 0; +} + +/* TODO: Check for what data type a mixed CD is. */ +static int image_media_type_id(uint8_t id) +{ + if (!cdrom_image[id].image_is_iso) + { + return 3; /* Mixed mode CD. */ + } + + if (image_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + +CDROM image_cdrom = +{ + image_ready, + image_medium_changed, + image_media_type_id, + image_audio_callback, + image_audio_stop, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + NULL, + image_readsector_raw, + image_playaudio, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit +}; diff --git a/src/cdrom-image.h b/src/cdrom-image.h new file mode 100644 index 000000000..3a49226a3 --- /dev/null +++ b/src/cdrom-image.h @@ -0,0 +1,25 @@ +/* Copyright holders: RichardG867, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IMAGE_H +#define CDROM_IMAGE_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int image_open(uint8_t id, wchar_t *fn); +extern void image_reset(uint8_t id); + +extern void image_close(uint8_t id); + +extern void cdrom_set_null_handler(uint8_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_IMAGE_H */ From 80b85db6a4a3302cd41767421c4f80efc91f0464 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 19:32:28 +0200 Subject: [PATCH 176/392] Attempt to create my own scsi_aha154x.h to make the emulator compile. --- src/scsi_aha154x.h | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/scsi_aha154x.h diff --git a/src/scsi_aha154x.h b/src/scsi_aha154x.h new file mode 100644 index 000000000..69b23aa0f --- /dev/null +++ b/src/scsi_aha154x.h @@ -0,0 +1,9 @@ +#ifndef SCSI_AHA154X_H +# define SCSI_AHA154X_H + + +extern device_t aha1540b_device; +extern device_t aha1542cf_device; + + +#endif /*SCSI_AHA154X_H*/ From 9cabdf4a36339eeb8a020de63157af578544da6d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 19:43:57 +0200 Subject: [PATCH 177/392] Removing that .h file, I can't make a correct one. --- src/disc_86f.c | 6 +++++- src/scsi_aha154x.h | 9 --------- 2 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 src/scsi_aha154x.h diff --git a/src/disc_86f.c b/src/disc_86f.c index 5a7614e32..bda81815f 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1909,7 +1909,11 @@ void d86f_format_track(int drive, int side, int do_write) break; case FMT_SECTOR_DATA: max_len = dtl; - if (do_write) d86f_write_direct(drive, side, d86f[drive].fill, 0); + if (do_write) + { + d86f_write_direct(drive, side, d86f[drive].fill, 0); + d86f_handler[drive].write_data(drive, side, d86f[drive].datac++, d86f[drive].pos); + } d86f_calccrc(drive, d86f[drive].fill); break; case FMT_SECTOR_GAP3: diff --git a/src/scsi_aha154x.h b/src/scsi_aha154x.h deleted file mode 100644 index 69b23aa0f..000000000 --- a/src/scsi_aha154x.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef SCSI_AHA154X_H -# define SCSI_AHA154X_H - - -extern device_t aha1540b_device; -extern device_t aha1542cf_device; - - -#endif /*SCSI_AHA154X_H*/ From 3f15cb7be7d9501f85e2b5b2b9b208f36d249bbd Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 23:10:57 +0200 Subject: [PATCH 178/392] Fixed a very stupid error I introduced in disc_86f.c. --- src/disc_86f.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disc_86f.c b/src/disc_86f.c index bda81815f..eca278532 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1912,7 +1912,7 @@ void d86f_format_track(int drive, int side, int do_write) if (do_write) { d86f_write_direct(drive, side, d86f[drive].fill, 0); - d86f_handler[drive].write_data(drive, side, d86f[drive].datac++, d86f[drive].pos); + d86f_handler[drive].write_data(drive, side, d86f[drive].datac++, d86f[drive].fill); } d86f_calccrc(drive, d86f[drive].fill); break; From cedf55114564b2a6ac7fa5ee858947254a15fe48 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 8 May 2017 18:24:44 -0400 Subject: [PATCH 179/392] Fixed SLIRP warnings, disabled its TFTP module. --- src/slirp/ip_input.c | 1 - src/slirp/slirp.c | 10 ++++++++-- src/slirp/slirp.h | 9 +++++++-- src/slirp/tcp_input.c | 1 - src/slirp/udp.c | 2 ++ 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/slirp/ip_input.c b/src/slirp/ip_input.c index fb8f3fcf1..62fd5d202 100644 --- a/src/slirp/ip_input.c +++ b/src/slirp/ip_input.c @@ -37,7 +37,6 @@ * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ - #include "slirp.h" #include "ip_icmp.h" diff --git a/src/slirp/slirp.c b/src/slirp/slirp.c index 8725b8922..eb803d236 100644 --- a/src/slirp/slirp.c +++ b/src/slirp/slirp.c @@ -12,6 +12,7 @@ struct in_addr special_addr; /* virtual address alias for host */ struct in_addr alias_addr; +/* FIXME: this is probably not working with new MAC address stuff.. --FvK */ const uint8_t special_ethaddr[6] = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 }; @@ -29,6 +30,11 @@ fd_set *global_readfds, *global_writefds, *global_xfds; char slirp_hostname[33]; + +extern void pclog(const char *, ...); +extern int config_get_int(char *, char *, int); + + #ifdef _WIN32 static int get_dns_addr(struct in_addr *pdns_addr) @@ -464,7 +470,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) //winsock2.h:549:32: note: expected 'const char *' but argument is of type 'int *' //WINSOCK_API_LINKAGE int PASCAL send(SOCKET,const char*,int,int); JASON //ret = send(so->s, "a", 1, 0); WHY THE HELL WAS THIS HERE?! - ret = send(so->s, &ret, 0, 0); //This is what it should be. + ret = send(so->s, (char *)&ret, 0, 0); //This is what it should be. if (ret < 0) { /* XXXXX Must fix, zero bytes is a NOP */ if (errno == EAGAIN || errno == EWOULDBLOCK || @@ -510,7 +516,7 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds) /* tcp_input will take care of it */ } else { - ret = send(so->s, &ret, 0,0); + ret = send(so->s, (char *)&ret, 0,0); if (ret < 0) { /* XXX */ if (errno == EAGAIN || errno == EWOULDBLOCK || diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index b7b077527..3f4efd0bd 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -328,8 +328,13 @@ extern int do_echo; # define insque_32 insque # define remque_32 remque #else - extern __inline void insque_32 _P((void *, void *)); - extern __inline void remque_32 _P((void *)); +# ifdef NEED_QUE32_INLINE +extern __inline void insque_32 _P((void *, void *)); +extern __inline void remque_32 _P((void *)); +# else +extern void insque_32 _P((void *, void *)); +extern void remque_32 _P((void *)); +# endif #endif #ifndef _WIN32 diff --git a/src/slirp/tcp_input.c b/src/slirp/tcp_input.c index 77006a2d7..97187788d 100644 --- a/src/slirp/tcp_input.c +++ b/src/slirp/tcp_input.c @@ -37,7 +37,6 @@ * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */ - #include #include "slirp.h" #include "ip_icmp.h" diff --git a/src/slirp/udp.c b/src/slirp/udp.c index 318ac6400..fbeb3c340 100644 --- a/src/slirp/udp.c +++ b/src/slirp/udp.c @@ -150,6 +150,7 @@ udp_input(m, iphlen) goto bad; } +#ifdef NEED_TFTP /* * handle TFTP */ @@ -157,6 +158,7 @@ udp_input(m, iphlen) tftp_input(m); goto bad; } +#endif /* * Locate pcb for datagram. From 769a2939d57446b859b4961be1cd7495940c639e Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 8 May 2017 18:26:27 -0400 Subject: [PATCH 180/392] Re-committed scsi_aha154x.h file - sorry ! --- src/scsi_aha154x.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/scsi_aha154x.h diff --git a/src/scsi_aha154x.h b/src/scsi_aha154x.h new file mode 100644 index 000000000..67734e070 --- /dev/null +++ b/src/scsi_aha154x.h @@ -0,0 +1,17 @@ +#ifndef SCSI_AHA154X_H +# define SCSI_AHA154X_H + + +typedef struct { + uint8_t flags; /* local flags */ + uint8_t bid; /* board ID */ + char fwl, fwh; /* firmware info */ +} aha_info; +#define AHA_GLAG_MEMEN 0x01 /* BIOS Shadow RAM enabled */ + + +extern device_t aha1540b_device; +extern device_t aha1542cf_device; + + +#endif /*SCSI_AHA154X_H*/ From 52cf57cf569e848639d84b66dbb7986e4e8f7a4a Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 8 May 2017 18:27:42 -0400 Subject: [PATCH 181/392] Added pcap_if.exe utility, updated net_ne2000.c and updated Makefile.mingw. --- src/Makefile.mingw | 20 +++++++++++++---- src/net_ne2000.c | 7 ++++++ src/pcap_if.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/pcap_if.c diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 93196a298..8eaecd43b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.7 2017/05/07 +# Version: @(#)Makefile.mingw 1.0.8 2017/05/08 # # Authors: Kotori, # Fred N. van Kempen, @@ -128,7 +128,8 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ - cdrom.o cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o + cdrom.o \ + cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o NETOBJ = network.o net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o @@ -182,7 +183,7 @@ OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ LZFOBJ = lzf_c.o lzf_d.o SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ - ip_input.o queue.o tcp_input.o tftp.o debug.o ip_output.o \ + ip_input.o queue.o tcp_input.o debug.o ip_output.o \ sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ @@ -204,6 +205,9 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ @echo $< @$(CPP) $(CFLAGS) -c $< +all: $(PROG).exe pcap_if.exe + + $(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. @$(CC) -o $(PROG).exe \ @@ -212,7 +216,15 @@ ifneq ($(DEBUG), y) strip $(PROG).exe endif -all: $(PROG).exe +pcap_if.exe: pcap_if.o + @echo Linking pcap_if.exe .. + @$(CC) -o pcap_if.exe \ + pcap_if.o -static -L. -lwpcapdelay +ifneq ($(DEBUG), y) + strip pcap_if.exe +endif + + clean: rm *.o diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 30a1553bd..f1a0eb44d 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -222,7 +222,14 @@ uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len); void ne2000_rx_frame(void *p, const void *buf, int io_len); + + +#ifdef WALTJE +#define ENABLE_NE2000_LOG +int ne2000_do_log = 1; +#else int ne2000_do_log = 0; +#endif void ne2000_log(const char *format, ...) diff --git a/src/pcap_if.c b/src/pcap_if.c new file mode 100644 index 000000000..6a7a46480 --- /dev/null +++ b/src/pcap_if.c @@ -0,0 +1,56 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Simple program to show usable interfaces for WinPcap. + * + * Based on the "libpcap" example. + * + * Version: @(#)pcap_if.c 1.0.1 2017/05/08 + * + * Author: Fred N. van Kempen, + */ +#include +#include +#include + + +int +main(int argc, char **argv) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *alldevs; + pcap_if_t *d; + int i=0; + + /* Retrieve the device list from the local machine */ + if (pcap_findalldevs(&alldevs, errbuf) == -1) { + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + exit(1); + } + + /* Print the list */ + for (d= alldevs; d != NULL; d= d->next) { + printf("%d. %s\n", ++i, d->name); + if (d->description) + printf(" (%s)\n", d->description); + else + printf(" (No description available)\n"); + printf("\n"); + i++; + } + + if (i == 0) { + printf("No interfaces found! Make sure WinPcap is installed.\n"); + return(i); + } + + /* Not really needed as we are about to exit, but oh-well. */ + pcap_freealldevs(alldevs); + + return(i); +} From cbb8d2a64bb6f6651247544e67d58f4c2a814fae Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 May 2017 04:36:09 +0200 Subject: [PATCH 182/392] Change to the MAC address handling. --- src/device.h | 1 + src/net_ne2000.c | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/device.h b/src/device.h index fb509ce7f..7dace2286 100644 --- a/src/device.h +++ b/src/device.h @@ -3,6 +3,7 @@ #define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 #define CONFIG_MIDI 4 +#define CONFIG_ETHIF 5 typedef struct device_config_selection_t { diff --git a/src/net_ne2000.c b/src/net_ne2000.c index f1a0eb44d..9647d0856 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -246,15 +246,15 @@ void ne2000_log(const char *format, ...) #endif } -static uint8_t *ne2000_mac(void) +static void ne2000_mac(uint8_t *mac) { if (network_card_current == 2) { - return maclocal_pci; + memcpy(mac, maclocal_pci, 6); } else { - return maclocal; + memcpy(mac, maclocal, 6); } } @@ -1720,6 +1720,8 @@ void ne2000_poller(void *p) struct pcap_pkthdr h; uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; + uint8_t temp_mac[6] = { 0, 0, 0, 0, 0, 0 }; + ne2000_mac(temp_mac); if (!net_is_pcap) { @@ -1756,8 +1758,8 @@ void ne2000_poller(void *p) mac_cmp32[0] = *(uint32_t *) (data+6); mac_cmp16[0] = *(uint16_t *) (data+10); /* Local. */ - mac_cmp32[1] = *(uint32_t *) (ne2000_mac()); - mac_cmp16[1] = *(uint16_t *) (ne2000_mac() + 4); + mac_cmp32[1] = *(uint32_t *) (temp_mac); + mac_cmp16[1] = *(uint16_t *) (temp_mac + 4); if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { ne2000_rx_frame(ne2000,data,h.caplen); @@ -2002,6 +2004,7 @@ void *ne2000_init(void) int is_rtl8029as = 0; ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); + uint8_t temp_mac[6] = { 0, 0, 0, 0, 0, 0 }; if (PCI && (network_card_current == 2)) { @@ -2048,7 +2051,8 @@ void *ne2000_init(void) ne2000_io_set(ne2000->base_address, ne2000); - memcpy(ne2000->physaddr, ne2000_mac(), 6); + ne2000_mac(temp_mac); + ne2000_mac(ne2000->physaddr); if (!disable_netbios) { @@ -2192,8 +2196,8 @@ initialize_pcap: char filter_exp[255]; ne2000_log("ne2000 Building packet filter..."); sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5],\ - ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5]); + temp_mac[0], temp_mac[1], temp_mac[2], temp_mac[3], temp_mac[4], temp_mac[5],\ + temp_mac[0], temp_mac[1], temp_mac[2], temp_mac[3], temp_mac[4], temp_mac[5]); /* I'm doing a MAC level filter so TCP/IP doesn't matter. */ if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) From 4e7c404922e01717ae14993fb242b066b27e133b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 May 2017 15:35:06 +0200 Subject: [PATCH 183/392] Reverting previous commit --- src/device.h | 1 - src/net_ne2000.c | 20 ++++++++------------ 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/device.h b/src/device.h index 7dace2286..fb509ce7f 100644 --- a/src/device.h +++ b/src/device.h @@ -3,7 +3,6 @@ #define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 #define CONFIG_MIDI 4 -#define CONFIG_ETHIF 5 typedef struct device_config_selection_t { diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 9647d0856..f1a0eb44d 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -246,15 +246,15 @@ void ne2000_log(const char *format, ...) #endif } -static void ne2000_mac(uint8_t *mac) +static uint8_t *ne2000_mac(void) { if (network_card_current == 2) { - memcpy(mac, maclocal_pci, 6); + return maclocal_pci; } else { - memcpy(mac, maclocal, 6); + return maclocal; } } @@ -1720,8 +1720,6 @@ void ne2000_poller(void *p) struct pcap_pkthdr h; uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; - uint8_t temp_mac[6] = { 0, 0, 0, 0, 0, 0 }; - ne2000_mac(temp_mac); if (!net_is_pcap) { @@ -1758,8 +1756,8 @@ void ne2000_poller(void *p) mac_cmp32[0] = *(uint32_t *) (data+6); mac_cmp16[0] = *(uint16_t *) (data+10); /* Local. */ - mac_cmp32[1] = *(uint32_t *) (temp_mac); - mac_cmp16[1] = *(uint16_t *) (temp_mac + 4); + mac_cmp32[1] = *(uint32_t *) (ne2000_mac()); + mac_cmp16[1] = *(uint16_t *) (ne2000_mac() + 4); if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { ne2000_rx_frame(ne2000,data,h.caplen); @@ -2004,7 +2002,6 @@ void *ne2000_init(void) int is_rtl8029as = 0; ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); memset(ne2000, 0, sizeof(ne2000_t)); - uint8_t temp_mac[6] = { 0, 0, 0, 0, 0, 0 }; if (PCI && (network_card_current == 2)) { @@ -2051,8 +2048,7 @@ void *ne2000_init(void) ne2000_io_set(ne2000->base_address, ne2000); - ne2000_mac(temp_mac); - ne2000_mac(ne2000->physaddr); + memcpy(ne2000->physaddr, ne2000_mac(), 6); if (!disable_netbios) { @@ -2196,8 +2192,8 @@ initialize_pcap: char filter_exp[255]; ne2000_log("ne2000 Building packet filter..."); sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - temp_mac[0], temp_mac[1], temp_mac[2], temp_mac[3], temp_mac[4], temp_mac[5],\ - temp_mac[0], temp_mac[1], temp_mac[2], temp_mac[3], temp_mac[4], temp_mac[5]); + ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5],\ + ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5]); /* I'm doing a MAC level filter so TCP/IP doesn't matter. */ if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) From d3b39f61bd13c4d935ab4ad2a809697524c9b858 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 May 2017 21:37:47 +0200 Subject: [PATCH 184/392] PIIX3 now sets the correct reset handler. --- src/piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/piix.c b/src/piix.c index 2cb81a739..04cf62418 100644 --- a/src/piix.c +++ b/src/piix.c @@ -674,5 +674,5 @@ void piix3_init(int card) dma_alias_set(); - pci_reset_handler.pci_set_reset = piix_reset; + pci_reset_handler.pci_set_reset = piix3_reset; } From 7f509c985007ffec49bd470c720723012b6bc9ca Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 May 2017 21:42:08 +0200 Subject: [PATCH 185/392] Ported the MPU401 core of dosbox-x to 86box, intelligent mode works (SB16 and up only) Renamed the mpu401 source files to be about generic mpu401 handling as it is no longer UART specific. --- src/Makefile.mingw | 2 +- src/SOUND/snd_mpu401_uart.c | 60 ------------------------- src/SOUND/snd_mpu401_uart.h | 9 ---- src/SOUND/snd_sb.c | 88 +++++++++++++++++++++++++++++++++++-- 4 files changed, 85 insertions(+), 74 deletions(-) delete mode 100644 src/SOUND/snd_mpu401_uart.c delete mode 100644 src/SOUND/snd_mpu401_uart.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 8eaecd43b..6eccad94b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -144,7 +144,7 @@ SNDOBJ = sound.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ snd_emu8k.o snd_gus.o snd_opl.o \ - snd_mpu401_uart.o snd_pas16.o snd_resid.o \ + snd_mpu401.o snd_pas16.o snd_resid.o \ snd_sn76489.o snd_ssi2001.o snd_wss.o \ snd_ym7128.o VIDOBJ = video.o \ diff --git a/src/SOUND/snd_mpu401_uart.c b/src/SOUND/snd_mpu401_uart.c deleted file mode 100644 index ac145f49f..000000000 --- a/src/SOUND/snd_mpu401_uart.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "../ibm.h" -#include "../io.h" -#include "../plat-midi.h" -#include "snd_mpu401_uart.h" - - -enum -{ - STATUS_OUTPUT_NOT_READY = 0x40, - STATUS_INPUT_NOT_READY = 0x80 -}; - - -static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p) -{ - mpu401_uart_t *mpu = (mpu401_uart_t *)p; - - if (addr & 1) /*Command*/ - { - switch (val) - { - case 0xff: /*Reset*/ - mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = 0; - mpu->uart_mode = 0; - break; - - case 0x3f: /*Enter UART mode*/ - mpu->rx_data = 0xfe; /*Acknowledge*/ - mpu->status = 0; - mpu->uart_mode = 1; - break; - } - return; - } - - /*Data*/ - if (mpu->uart_mode) - midi_write(val); -} - -static uint8_t mpu401_uart_read(uint16_t addr, void *p) -{ - mpu401_uart_t *mpu = (mpu401_uart_t *)p; - - if (addr & 1) /*Status*/ - return mpu->status; - - /*Data*/ - mpu->status |= STATUS_INPUT_NOT_READY; - return mpu->rx_data; -} - -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr) -{ - mpu->status = STATUS_INPUT_NOT_READY; - mpu->uart_mode = 0; - - io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu); -} diff --git a/src/SOUND/snd_mpu401_uart.h b/src/SOUND/snd_mpu401_uart.h deleted file mode 100644 index 893c53fc4..000000000 --- a/src/SOUND/snd_mpu401_uart.h +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct mpu401_uart_t -{ - uint8_t status; - uint8_t rx_data; - - int uart_mode; -} mpu401_uart_t; - -void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr); diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 32f3fbc34..9b3d817e1 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -7,7 +7,7 @@ #include "../device.h" #include "sound.h" #include "snd_emu8k.h" -#include "snd_mpu401_uart.h" +#include "snd_mpu401.h" #include "snd_opl.h" #include "snd_sb.h" #include "snd_sb_dsp.h" @@ -33,7 +33,7 @@ typedef struct sb_t opl_t opl; sb_dsp_t dsp; sb_mixer_t mixer; - mpu401_uart_t mpu; + mpu_t mpu; emu8k_t emu8k; int pos; @@ -631,7 +631,7 @@ void *sb_16_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); - mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); + mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); sb->mixer.regs[0x30] = 31 << 3; sb->mixer.regs[0x31] = 31 << 3; @@ -677,7 +677,7 @@ void *sb_awe32_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_uart_init(&sb->mpu, device_get_config_int("addr401")); + mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); emu8k_init(&sb->emu8k, onboard_ram); sb->mixer.regs[0x30] = 31 << 3; @@ -934,6 +934,32 @@ static device_config_t sb_16_config[] = } } }, + { + "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, { "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, { @@ -971,6 +997,20 @@ static device_config_t sb_16_config[] = { "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, + { + "mode", "MPU-401 mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, { "", "", -1 } @@ -1032,6 +1072,32 @@ static device_config_t sb_awe32_config[] = } } }, + { + "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 2, + { + { + "IRQ 2", 2 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, { "dma", "Low DMA channel", CONFIG_SELECTION, "", 1, { @@ -1069,6 +1135,20 @@ static device_config_t sb_awe32_config[] = { "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, + { + "mode", "MPU-401 mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, { "onboard_ram", "Onboard RAM", CONFIG_SELECTION, "", 512, { From ae67b8f71bf25d898a00d3548ee9d86acc9220c2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 May 2017 21:45:20 +0200 Subject: [PATCH 186/392] Forgot to include the new file names. --- src/SOUND/snd_mpu401.c | 647 +++++++++++++++++++++++++++++++++++++++++ src/SOUND/snd_mpu401.h | 61 ++++ 2 files changed, 708 insertions(+) create mode 100644 src/SOUND/snd_mpu401.c create mode 100644 src/SOUND/snd_mpu401.h diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c new file mode 100644 index 000000000..b56283e05 --- /dev/null +++ b/src/SOUND/snd_mpu401.c @@ -0,0 +1,647 @@ +#include "../ibm.h" +#include "../io.h" +#include "../pic.h" +#include "../timer.h" +#include "../plat-midi.h" +#include "snd_mpu401.h" + +enum +{ + STATUS_OUTPUT_NOT_READY = 0x40, + STATUS_INPUT_NOT_READY = 0x80 +}; + +static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); +static void MPU401_EOIHandlerDispatch(void *p); + +static int mpu401_event_callback = 0; + +static void QueueByte(mpu_t *mpu, uint8_t data) +{ + if (mpu->state.block_ack) + { + mpu->state.block_ack=0; + return; + } + + if (mpu->queue_used == 0 && mpu->intelligent) + { + mpu->state.irq_pending=1; + //PIC_ActivateIRQ(mpu->irq); + picint(1 << mpu->irq); + } + if (mpu->queue_used < MPU401_QUEUE) + { + int pos = mpu->queue_used+mpu->queue_pos; + + if (mpu->queue_pos >= MPU401_QUEUE) + mpu->queue_pos -= MPU401_QUEUE; + + if (pos>=MPU401_QUEUE) + pos-=MPU401_QUEUE; + + mpu->queue_used++; + mpu->queue[pos]=data; + } + else + pclog("MPU401:Data queue full\n"); +} + +static void ClrQueue(mpu_t *mpu) +{ + mpu->queue_used=0; + mpu->queue_pos=0; +} + +static void MPU401_Reset(mpu_t *mpu) +{ + uint8_t i; + + picintc(1 << mpu->irq); + mpu->mode=(mpu->intelligent ? M_INTELLIGENT : M_UART); + mpu->state.eoi_scheduled=0; + mpu->state.wsd=0; + mpu->state.wsm=0; + mpu->state.conductor=0; + mpu->state.cond_req=0; + mpu->state.cond_set=0; + mpu->state.playing=0; + mpu->state.run_irq=0; + mpu->state.irq_pending=0; + mpu->state.cmask=0xff; + mpu->state.amask=mpu->state.tmask=0; + mpu->state.midi_mask=0xffff; + mpu->state.data_onoff=0; + mpu->state.command_byte=0; + mpu->state.block_ack=0; + mpu->clock.tempo=mpu->clock.old_tempo=100; + mpu->clock.timebase=mpu->clock.old_timebase=120; + mpu->clock.tempo_rel=mpu->clock.old_tempo_rel=40; + mpu->clock.tempo_grad=0; + mpu->clock.clock_to_host=0; + mpu->clock.cth_rate=60; + mpu->clock.cth_counter=0; + ClrQueue(mpu); + mpu->state.req_mask=0; + mpu->condbuf.counter=0; + mpu->condbuf.type=T_OVERFLOW; + for (i=0;i<8;i++) {mpu->playbuf[i].type=T_OVERFLOW;mpu->playbuf[i].counter=0;} +} + +static void MPU401_ResetDone(mpu_t *mpu, int reset) +{ + mpu->state.reset=0; + if (mpu->state.cmd_pending) + { + MPU401_WriteCommand(mpu, mpu->state.cmd_pending-1); + mpu->state.cmd_pending=0; + } +} + +static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) +{ + uint8_t i; + + if (mpu->state.reset) + { + mpu->state.cmd_pending=val+1; + return; + } + + if (val<=0x2f) + { + switch (val&3) + { /* MIDI stop, start, continue */ + case 1: {midi_write(0xfc);break;} + case 2: {midi_write(0xfa);break;} + case 3: {midi_write(0xfb);break;} + } +// if (val&0x20) LOG(LOG_MISC,LOG_ERROR)("MPU-401:Unhandled Recording Command %x",(int)val); + switch (val&0xc) + { + case 0x4: /* Stop */ + mpu->state.playing=0; + for (i=0xb0;i<0xbf;i++) + { /* All notes off */ + midi_write(i); + midi_write(0x7b); + midi_write(0); + } + break; + case 0x8: /* Play */ +// LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started"); + mpu->state.playing=1; + mpu401_event_callback = MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase); + ClrQueue(mpu); + break; + } + } + else if (val>=0xa0 && val<=0xa7) + { /* Request play counter */ + if (mpu->state.cmask&(1<<(val&7))) QueueByte(mpu, mpu->playbuf[val&7].counter); + } + else if (val>=0xd0 && val<=0xd7) + { /* Send data */ + mpu->state.old_chan=mpu->state.channel; + mpu->state.channel=val&7; + mpu->state.wsd=1; + mpu->state.wsm=0; + mpu->state.wsd_start=1; + } + else + switch (val) + { + case 0xdf: /* Send system message */ + mpu->state.wsd=0; + mpu->state.wsm=1; + mpu->state.wsd_start=1; + break; + case 0x8e: /* Conductor */ + mpu->state.cond_set=0; + break; + case 0x8f: + mpu->state.cond_set=1; + break; + case 0x94: /* Clock to host */ + mpu->clock.clock_to_host=0; + break; + case 0x95: + mpu->clock.clock_to_host=1; + break; + case 0xc2: /* Internal timebase */ + mpu->clock.timebase=48; + break; + case 0xc3: + mpu->clock.timebase=72; + break; + case 0xc4: + mpu->clock.timebase=96; + break; + case 0xc5: + mpu->clock.timebase=120; + break; + case 0xc6: + mpu->clock.timebase=144; + break; + case 0xc7: + mpu->clock.timebase=168; + break; + case 0xc8: + mpu->clock.timebase=192; + break; + /* Commands with data byte */ + case 0xe0: case 0xe1: case 0xe2: case 0xe4: case 0xe6: + case 0xe7: case 0xec: case 0xed: case 0xee: case 0xef: + mpu->state.command_byte=val; + break; + /* Commands 0xa# returning data */ + case 0xab: /* Request and clear recording counter */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, 0); + return; + case 0xac: /* Request version */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, MPU401_VERSION); + return; + case 0xad: /* Request revision */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, MPU401_REVISION); + return; + case 0xaf: /* Request tempo */ + QueueByte(mpu, MSG_MPU_ACK); + QueueByte(mpu, mpu->clock.tempo); + return; + case 0xb1: /* Reset relative tempo */ + mpu->clock.tempo_rel=40; + break; + case 0xb9: /* Clear play map */ + case 0xb8: /* Clear play counters */ + for (i=0xb0;i<0xbf;i++) + { /* All notes off */ + midi_write(i); + midi_write(0x7b); + midi_write(0); + } + for (i=0;i<8;i++) + { + mpu->playbuf[i].counter=0; + mpu->playbuf[i].type=T_OVERFLOW; + } + mpu->condbuf.counter=0; + mpu->condbuf.type=T_OVERFLOW; + if (!(mpu->state.conductor=mpu->state.cond_set)) mpu->state.cond_req=0; + mpu->state.amask=mpu->state.tmask; + mpu->state.req_mask=0; + mpu->state.irq_pending=1; + break; + case 0xff: /* Reset MPU-401 */ + pclog("MPU-401:Reset %X\n",val); + MPU401_ResetDone(mpu, MPU401_RESETBUSY); + mpu->state.reset=1; + MPU401_Reset(mpu); + if (mpu->mode==M_UART) return;//do not send ack in UART mode + break; + case 0x3f: /* UART mode */ + pclog("MPU-401:Set UART mode %X\n",val); + mpu->mode=M_UART; + break; + default:; + //LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Unhandled command %X",val); + } + QueueByte(mpu, MSG_MPU_ACK); +} + +static void MPU401_WriteData(mpu_t *mpu, uint8_t val) +{ + if (mpu->mode==M_UART) {midi_write(val);} + + switch (mpu->state.command_byte) + { /* 0xe# command data */ + case 0x00: + break; + case 0xe0: /* Set tempo */ + mpu->state.command_byte=0; + mpu->clock.tempo=val; + return; + case 0xe1: /* Set relative tempo */ + mpu->state.command_byte=0; + if (val!=0x40) //default value + pclog("MPU-401:Relative tempo change not implemented\n"); + return; + case 0xe7: /* Set internal clock to host interval */ + mpu->state.command_byte=0; + mpu->clock.cth_rate=val>>2; + return; + case 0xec: /* Set active track mask */ + mpu->state.command_byte=0; + mpu->state.tmask=val; + return; + case 0xed: /* Set play counter mask */ + mpu->state.command_byte=0; + mpu->state.cmask=val; + return; + case 0xee: /* Set 1-8 MIDI channel mask */ + mpu->state.command_byte=0; + mpu->state.midi_mask&=0xff00; + mpu->state.midi_mask|=val; + return; + case 0xef: /* Set 9-16 MIDI channel mask */ + mpu->state.command_byte=0; + mpu->state.midi_mask&=0x00ff; + mpu->state.midi_mask|=((uint16_t)val)<<8; + return; + //case 0xe2: /* Set graduation for relative tempo */ + //case 0xe4: /* Set metronome */ + //case 0xe6: /* Set metronome measure length */ + default: + mpu->state.command_byte=0; + return; + } + static int length,cnt,posd; + if (mpu->state.wsd) + { /* Directly send MIDI message */ + if (mpu->state.wsd_start) + { + mpu->state.wsd_start=0; + cnt=0; + switch (val&0xf0) { + case 0xc0:case 0xd0: + mpu->playbuf[mpu->state.channel].value[0]=val; + length=2; + break; + case 0x80:case 0x90:case 0xa0:case 0xb0:case 0xe0: + mpu->playbuf[mpu->state.channel].value[0]=val; + length=3; + break; + case 0xf0: + //pclog("MPU-401:Illegal WSD byte\n"); + mpu->state.wsd=0; + mpu->state.channel=mpu->state.old_chan; + return; + default: /* MIDI with running status */ + cnt++; + midi_write(mpu->playbuf[mpu->state.channel].value[0]); + } + } + if (cntstate.wsd=0; + mpu->state.channel=mpu->state.old_chan; + } + return; + } + if (mpu->state.wsm) + { /* Directly send system message */ + if (val==MSG_EOX) {midi_write(MSG_EOX);mpu->state.wsm=0;return;} + if (mpu->state.wsd_start) { + mpu->state.wsd_start=0; + cnt=0; + switch (val) + { + case 0xf2:{ length=3; break;} + case 0xf3:{ length=2; break;} + case 0xf6:{ length=1; break;} + case 0xf0:{ length=0; break;} + default: + length=0; + } + } + if (!length || cntstate.wsm=0; + return; + } + if (mpu->state.cond_req) + { /* Command */ + switch (mpu->state.data_onoff) { + case -1: + return; + case 0: /* Timing byte */ + mpu->condbuf.vlength=0; + if (val<0xf0) mpu->state.data_onoff++; + else { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + return; + } + if (val==0) mpu->state.send_now=1; + else mpu->state.send_now=0; + mpu->condbuf.counter=val; + break; + case 1: /* Command byte #1 */ + mpu->condbuf.type=T_COMMAND; + if (val==0xf8 || val==0xf9) mpu->condbuf.type=T_OVERFLOW; + mpu->condbuf.value[mpu->condbuf.vlength]=val; + mpu->condbuf.vlength++; + if ((val&0xf0)!=0xe0) MPU401_EOIHandlerDispatch(mpu); + else mpu->state.data_onoff++; + break; + case 2:/* Command byte #2 */ + mpu->condbuf.value[mpu->condbuf.vlength]=val; + mpu->condbuf.vlength++; + MPU401_EOIHandlerDispatch(mpu); + break; + } + return; + } + switch (mpu->state.data_onoff) + { /* Data */ + case -1: + return; + case 0: /* Timing byte */ + if (val<0xf0) mpu->state.data_onoff=1; + else { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + return; + } + if (val==0) mpu->state.send_now=1; + else mpu->state.send_now=0; + mpu->playbuf[mpu->state.channel].counter=val; + break; + case 1: /* MIDI */ + mpu->playbuf[mpu->state.channel].vlength++; + posd=mpu->playbuf[mpu->state.channel].vlength; + if (posd==1) { + switch (val&0xf0) { + case 0xf0: /* System message or mark */ + if (val>0xf7) { + mpu->playbuf[mpu->state.channel].type=T_MARK; + mpu->playbuf[mpu->state.channel].sys_val=val; + length=1; + } else { + //LOG(LOG_MISC,LOG_ERROR)("MPU-401:Illegal message"); + mpu->playbuf[mpu->state.channel].type=T_MIDI_SYS; + mpu->playbuf[mpu->state.channel].sys_val=val; + length=1; + } + break; + case 0xc0: case 0xd0: /* MIDI Message */ + mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; + length=mpu->playbuf[mpu->state.channel].length=2; + break; + case 0x80: case 0x90: case 0xa0: case 0xb0: case 0xe0: + mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; + length=mpu->playbuf[mpu->state.channel].length=3; + break; + default: /* MIDI data with running status */ + posd++; + mpu->playbuf[mpu->state.channel].vlength++; + mpu->playbuf[mpu->state.channel].type=T_MIDI_NORM; + length=mpu->playbuf[mpu->state.channel].length; + break; + } + } + if (!(posd==1 && val>=0xf0)) mpu->playbuf[mpu->state.channel].value[posd-1]=val; + if (posd==length) MPU401_EOIHandlerDispatch(mpu); + } +} + +static void MPU401_IntelligentOut(mpu_t *mpu, uint8_t chan) +{ + uint8_t val; + uint8_t i; + switch (mpu->playbuf[chan].type) + { + case T_OVERFLOW: + break; + case T_MARK: + val=mpu->playbuf[chan].sys_val; + if (val==0xfc) + { + midi_write(val); + mpu->state.amask&=~(1<state.req_mask&=~(1<playbuf[chan].vlength;i++) + midi_write(mpu->playbuf[chan].value[i]); + break; + default: + break; + } +} + +static void UpdateTrack(mpu_t *mpu, uint8_t chan) +{ + MPU401_IntelligentOut(mpu, chan); + if (mpu->state.amask&(1<playbuf[chan].vlength=0; + mpu->playbuf[chan].type=T_OVERFLOW; + mpu->playbuf[chan].counter=0xf0; + mpu->state.req_mask|=(1<state.amask==0 && !mpu->state.conductor) mpu->state.req_mask|=(1<<12); + } +} + +static void UpdateConductor(mpu_t *mpu) +{ + if (mpu->condbuf.value[0]==0xfc) + { + mpu->condbuf.value[0]=0; + mpu->state.conductor=0; + mpu->state.req_mask&=~(1<<9); + if (mpu->state.amask==0) mpu->state.req_mask|=(1<<12); + return; + } + mpu->condbuf.vlength=0; + mpu->condbuf.counter=0xf0; + mpu->state.req_mask|=(1<<9); +} + +//Updates counters and requests new data on "End of Input" +static void MPU401_EOIHandler(void *p, uint8_t val) +{ + mpu_t *mpu = (mpu_t *)p; + + mpu->state.eoi_scheduled=0; + if (mpu->state.send_now) + { + mpu->state.send_now=0; + if (mpu->state.cond_req) UpdateConductor(mpu); + else UpdateTrack(mpu, mpu->state.channel); + } + mpu->state.irq_pending=0; + if (!mpu->state.playing || !mpu->state.req_mask) return; + uint8_t i=0; + do { + if (mpu->state.req_mask&(1<state.req_mask&=~(1<state.send_now) + { + mpu->state.eoi_scheduled=1; + MPU401_EOIHandler(mpu, 0.06f); //Possible a bit longer + } + else if (!mpu->state.eoi_scheduled) + MPU401_EOIHandler(mpu, 0); +} + +static void mpu401_write(uint16_t addr, uint8_t val, void *p) +{ + mpu_t *mpu = (mpu_t *)p; + + pclog("MPU401 Write Port %04X, val %x\n", addr, val); + + switch (addr & 1) + { + case 0: /*Data*/ + MPU401_WriteData(mpu, val); + break; + + case 1: /*Command*/ + MPU401_WriteCommand(mpu, val); + break; + } +} + +static uint8_t mpu401_read(uint16_t addr, void *p) +{ + mpu_t *mpu = (mpu_t *)p; + uint8_t ret; + + switch (addr & 1) + { + case 0: //Read Data + ret = MSG_MPU_ACK; + if (mpu->queue_used) + { + if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; + ret=mpu->queue[mpu->queue_pos]; + mpu->queue_pos++;mpu->queue_used--; + } + if (!mpu->intelligent) return ret; + + if (mpu->queue_used == 0) picintc(1 << mpu->irq); + + if (ret>=0xf0 && ret<=0xf7) + { /* MIDI data request */ + mpu->state.channel=ret&7; + mpu->state.data_onoff=0; + mpu->state.cond_req=0; + } + if (ret==MSG_MPU_COMMAND_REQ) + { + mpu->state.data_onoff=0; + mpu->state.cond_req=1; + if (mpu->condbuf.type!=T_OVERFLOW) + { + mpu->state.block_ack=1; + MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); + if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); + } + mpu->condbuf.type=T_OVERFLOW; + } + if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + } + break; + + case 1: //Read Status + mpu->status = 0x3f; /* Bits 6 and 7 clear */ + if (mpu->state.cmd_pending) ret|=STATUS_OUTPUT_NOT_READY; + if (!mpu->queue_used) ret|=STATUS_INPUT_NOT_READY; + return mpu->status; + } + pclog("MPU401 Read Port %04X, ret %x\n", addr, ret); + return ret; +} + + +static void MPU401_Event(void *p) +{ + mpu_t *mpu = (mpu_t *)p; + uint8_t i; + + if (mpu->mode==M_UART) return; + if (mpu->state.irq_pending) goto next_event; + for (i=0;i<8;i++) { /* Decrease counters */ + if (mpu->state.amask&(1<playbuf[i].counter--; + if (mpu->playbuf[i].counter<=0) UpdateTrack(mpu, i); + } + } + if (mpu->state.conductor) { + mpu->condbuf.counter--; + if (mpu->condbuf.counter<=0) UpdateConductor(mpu); + } + if (mpu->clock.clock_to_host) { + mpu->clock.cth_counter++; + if (mpu->clock.cth_counter >= mpu->clock.cth_rate) { + mpu->clock.cth_counter=0; + mpu->state.req_mask|=(1<<13); + } + } + if (!mpu->state.irq_pending && mpu->state.req_mask) MPU401_EOIHandler(mpu, 0); +next_event: + mpu401_event_callback = 0; + int new_time; + if ((new_time=mpu->clock.tempo*mpu->clock.timebase)==0) return; + mpu401_event_callback = MPU401_TIMECONSTANT/new_time; +} + +void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) +{ + mpu->status = STATUS_INPUT_NOT_READY; + mpu->irq = irq; + mpu->queue_used = 0; + mpu->queue_pos = 0; + mpu->mode = mode; + + io_sethandler(addr, 0x0002, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + timer_add(MPU401_Event, &mpu401_event_callback, &mpu401_event_callback, mpu); + + MPU401_Reset(mpu); +} diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h new file mode 100644 index 000000000..d8eedc25b --- /dev/null +++ b/src/SOUND/snd_mpu401.h @@ -0,0 +1,61 @@ +#define MPU401_VERSION 0x15 +#define MPU401_REVISION 0x01 +#define MPU401_QUEUE 32 +#define MPU401_TIMECONSTANT (60000000/1000.0f) +#define MPU401_RESETBUSY 27.0f + +typedef enum MpuMode { M_UART,M_INTELLIGENT } MpuMode; +typedef enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND} MpuDataType; + +/* Messages sent to MPU-401 from host */ +#define MSG_EOX 0xf7 +#define MSG_OVERFLOW 0xf8 +#define MSG_MARK 0xfc + +/* Messages sent to host from MPU-401 */ +#define MSG_MPU_OVERFLOW 0xf8 +#define MSG_MPU_COMMAND_REQ 0xf9 +#define MSG_MPU_END 0xfc +#define MSG_MPU_CLOCK 0xfd +#define MSG_MPU_ACK 0xfe + +typedef struct mpu_t +{ + int intelligent; + MpuMode mode; + int irq; + uint8_t status; + uint8_t queue[MPU401_QUEUE]; + int queue_pos,queue_used; + struct track + { + int counter; + uint8_t value[8],sys_val; + uint8_t vlength,length; + MpuDataType type; + } playbuf[8],condbuf; + struct { + int conductor,cond_req,cond_set, block_ack; + int playing,reset; + int wsd,wsm,wsd_start; + int run_irq,irq_pending; + int send_now; + int eoi_scheduled; + int data_onoff; + uint32_t command_byte,cmd_pending; + uint8_t tmask,cmask,amask; + uint16_t midi_mask; + uint16_t req_mask; + uint8_t channel,old_chan; + } state; + struct { + uint8_t timebase,old_timebase; + uint8_t tempo,old_tempo; + uint8_t tempo_rel,old_tempo_rel; + uint8_t tempo_grad; + uint8_t cth_rate,cth_counter; + int clock_to_host,cth_active; + } clock; +} mpu_t; + +void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); From 42e90fb0b0ecec77ed6d4e92d5985688900d6b94 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 9 May 2017 21:58:29 +0200 Subject: [PATCH 187/392] Attempt to fix the full screen black bar. --- src/win-d3d-fs.cc | 2 +- src/win-ddraw-fs.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc index 9c0c7f557..dff2e0d6f 100644 --- a/src/win-d3d-fs.cc +++ b/src/win-d3d-fs.cc @@ -396,7 +396,7 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) fatal("LockRect failed\n"); for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), (uint32_t *) &(buffer32->line[yy + y][x]), w * 4); + memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); video_blit_complete(); d3dTexture->UnlockRect(0); diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc index ed458af7a..9fc355c63 100644 --- a/src/win-ddraw-fs.cc +++ b/src/win-ddraw-fs.cc @@ -203,7 +203,7 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h } for (yy = y1; yy < y2; yy++) { - if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), ((uint32_t *) &(((uint8_t *)buffer32->line[y + yy]))[x]), w * 4); + if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); } video_blit_complete(); lpdds_back->Unlock(NULL); From 95d201d4fd6316b993c82804050da741a5e8fa35 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 00:38:21 +0200 Subject: [PATCH 188/392] The old ISO Read TOC handlers are now used if the image is ISO - fixes reading ISO images under Windows 9x and NT 5.x. --- src/cdrom-image.cc | 200 +++++++++++++++++++++++++++++++++++++++++++-- src/cdrom-image.h | 1 + src/cdrom-ioctl.c | 1 + src/cdrom-null.c | 4 +- src/win.c | 2 - 5 files changed, 197 insertions(+), 11 deletions(-) diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 24d4c4b85..1959a8328 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -728,18 +728,83 @@ read_mode2: } +static void lba_to_msf(uint8_t *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { if (!cdimg[id]) return 0; int len=4; int c,d; uint32_t temp; - + uint8_t *q; int first_track; int last_track; int number; unsigned char attr; TMSF tmsf; + int lb; + + if (cdrom_image[id].image_is_iso) + { + if (starttrack > 1 && starttrack != 0xaa) + return -1; + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + if (starttrack <= 1) { + *q++ = 0; /* reserved */ + *q++ = 0x14; /* ADR, control */ + *q++ = 1; /* track number */ + *q++ = 0; /* reserved */ + if (msf) { + *q++ = 0; /* reserved */ + lba_to_msf(q, 0); + q += 3; + } else { + /* sector 0 */ + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + } + /* lead out track */ + *q++ = 0; /* reserved */ + *q++ = 0x16; /* ADR, control */ + *q++ = 0xaa; /* track number */ + *q++ = 0; /* reserved */ + lb = image_size(id) - 1; + if (msf) { + *q++ = 0; /* reserved */ + lba_to_msf(q, lb); + q += 3; + } else { + *q++ = lb >> 24; + *q++ = lb >> 16; + *q++ = lb >> 8; + *q++ = lb; + } + len = q - b; + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; + } + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); b[2] = first_track; @@ -787,6 +852,12 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, if (single) break; } + + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); b[1] = (uint8_t)((len-2) & 0xff); return len; @@ -796,10 +867,33 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl { if (!cdimg[id]) return 0; int len = 4; - int number; TMSF tmsf; unsigned char attr; + uint8_t *q; + + if (cdrom_image[id].image_is_iso) + { + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + + if (maxlen < 12) + { + return maxlen; + } + return 12; + } + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); b[2] = 1; @@ -824,6 +918,11 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl b[len++] = temp; } + if (maxlen < len) + { + return maxlen; + } + return len; } @@ -839,6 +938,94 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) int number; unsigned char attr; TMSF tmsf; + uint8_t *q; + int lb; + + if (cdrom_image[id].image_is_iso) + { + q = b + 2; + *q++ = 1; /* first session */ + *q++ = 1; /* last session */ + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa0; /* lead-in */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* first track */ + *q++ = 0x00; /* disk type */ + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa1; + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + *q++ = 0; + *q++ = 1; /* last track */ + *q++ = 0x00; + *q++ = 0x00; + + *q++ = 1; /* session number */ + *q++ = 0x14; /* data track */ + *q++ = 0; /* track number */ + *q++ = 0xa2; /* lead-out */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + lb = image_size(id) >> 11; + /* this is raw, must be msf */ + if (msf) + { + *q++ = 0; /* reserved */ + lba_to_msf(q, lb); + q += 3; + } + else + { + *q++ = (lb >> 24) & 0xff; + *q++ = (lb >> 16) & 0xff; + *q++ = (lb >> 8) & 0xff; + *q++ = lb & 0xff; + } + + *q++ = 1; /* session number */ + *q++ = 0x14; /* ADR, control */ + *q++ = 0; /* track number */ + *q++ = 1; /* point */ + *q++ = 0; /* min */ + *q++ = 0; /* sec */ + *q++ = 0; /* frame */ + /* same here */ + if (msf) + { + *q++ = 0; /* reserved */ + lba_to_msf(q, 0); + q += 3; + } + else + { + *q++ = 0; + *q++ = 0; + *q++ = 0; + *q++ = 0; + } + + len = q - b; + if (len > maxlen) + { + len = maxlen; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; + } + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); b[2] = first_track; @@ -880,11 +1067,6 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) return len; } -static uint32_t image_size(uint8_t id) -{ - return cdrom_image[id].cdrom_capacity; -} - static int image_status(uint8_t id) { if (!cdimg[id]) return CD_STATUS_EMPTY; @@ -957,7 +1139,7 @@ int image_open(uint8_t id, wchar_t *fn) cdrom_image[id].cd_state = CD_STOPPED; cdrom[id].seek_pos = 0; cdrom_image[id].cd_buflen = 0; - cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0); + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; cdrom_drives[id].handler = &image_cdrom; if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) @@ -965,6 +1147,8 @@ int image_open(uint8_t id, wchar_t *fn) if (!cdrom_image[id].image_inited) cdrom_image[id].image_inited = 1; } + + update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom-image.h b/src/cdrom-image.h index 3a49226a3..415956e56 100644 --- a/src/cdrom-image.h +++ b/src/cdrom-image.h @@ -16,6 +16,7 @@ extern void image_reset(uint8_t id); extern void image_close(uint8_t id); +void update_status_bar_icon_state(int tag, int state); extern void cdrom_set_null_handler(uint8_t id); #ifdef __cplusplus diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index c81bd7f14..3534dd2e2 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -1019,6 +1019,7 @@ int ioctl_open(uint8_t id, char d) CloseHandle(cdrom_ioctl_windows[id].hIOCTL); cdrom_ioctl_windows[id].hIOCTL = NULL; } + update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom-null.c b/src/cdrom-null.c index e5a8caf2d..f7d117077 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -66,9 +66,11 @@ void cdrom_null_reset(uint8_t id) { } +void cdrom_set_null_handler(uint8_t id); + int cdrom_null_open(uint8_t id, char d) { - cdrom_drives[id].handler = &null_cdrom; + cdrom_set_null_handler(id); return 0; } diff --git a/src/win.c b/src/win.c index ef37362d3..1c74724a6 100644 --- a/src/win.c +++ b/src/win.c @@ -2289,7 +2289,6 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR } cdrom_drives[cdrom_id].host_drive = 200; CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); - update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); } @@ -2325,7 +2324,6 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); } From ff8186741a8cdafb0e5fe7d82378f3e7a55e2cc7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 02:46:01 +0200 Subject: [PATCH 189/392] Added emulation IDE PIO-only hard disks (affects hard disk bus type in the configuration files - make sure to correct it in Settings after loading a configuration file from previous 86Box builds); The IDENTIFY PACKET DEVICE command of ATAPI PIO-only drives now behaves like that of mainline PCem ATAPI CD-ROM's; Added two functions in win.c for waltje for updating the status bar text; The configuration loader now does sanity checks on most loaded values. --- src/86Box.rc | 40 +++++++----- src/ICONS/hard_disk_mfm.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_mfm_active.ico | Bin 0 -> 1150 bytes src/config.c | 98 ++++++++++++++++++++++------- src/ibm.h | 2 + src/ide.c | 42 ++++++------- src/scsi_disk.c | 16 ++--- src/win-language.c | 2 +- src/win-settings.c | 65 ++++++++++++------- src/win.c | 49 +++++++++++++-- 10 files changed, 217 insertions(+), 97 deletions(-) create mode 100644 src/ICONS/hard_disk_mfm.ico create mode 100644 src/ICONS/hard_disk_mfm_active.ico diff --git a/src/86Box.rc b/src/86Box.rc index f0e8fb74e..388ab93b7 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -514,12 +514,14 @@ END 163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" 164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" 165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk.ico" -177 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -178 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -179 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -180 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -181 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" +177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" +178 ICON DISCARDABLE "ICONS/hard_disk.ico" +179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" 256 ICON DISCARDABLE "ICONS/machine.ico" 257 ICON DISCARDABLE "ICONS/video.ico" 258 ICON DISCARDABLE "ICONS/input_devices.ico" @@ -660,7 +662,7 @@ BEGIN 2048 "86Box" IDS_STRING2049 "86Box Error" IDS_STRING2050 "86Box Fatal Error" - IDS_STRING2051 "This will reset 86Box.\nDo you want to save the settings?" + IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" IDS_STRING2052 "DirectDraw Screenshot Error" IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" @@ -790,17 +792,17 @@ BEGIN 2154 "Internal IDE" 2155 "IRQ %i" 2156 "MFM (%01i:%01i)" - 2157 "IDE (%01i:%01i)" + 2157 "IDE (PIO+DMA) (%01i:%01i)" 2158 "SCSI (%02i:%02i)" - 2159 "IDE (PIO-only)" + 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" 2160 "%" PRIu64 2161 "Genius Bus mouse" 2162 "Amstrad mouse" 2163 "Attempting to create a spuriously large hard disk image" 2164 "Invalid number of sectors (valid values are between 1 and 99)" - 2165 "Invalid number of cylinders (valid values are between 1 and 1023)" - 2166 "MFM" - 2167 "IDE" + 2165 "MFM" + 2166 "IDE (PIO-only)" + 2167 "IDE (PIO and DMA)" 2168 "SCSI" 2169 "%01i:%01i" 2170 "Custom..." @@ -811,12 +813,12 @@ BEGIN 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" 2177 "Olivetti M24 mouse" - 2178 "" + 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" 2179 "Floppy %i (%s): %ws" 2180 "CD-ROM %i: %ws" - 2181 "Removable disk %i: %s" - 2182 "MFM hard disk" - 2183 "IDE hard disk" + 2181 "MFM hard disk" + 2182 "IDE hard disk (PIO-only)" + 2183 "IDE hard disk (PIO and DMA)" 2184 "SCSI hard disk" 2185 "(empty)" 2186 "(host drive %c:)" @@ -828,7 +830,11 @@ BEGIN 2192 "ATAPI (PIO and DMA) (%01i:%01i)" 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" 2194 "Unable to create bitmap file: %s" - 2195 "English (United States)" + 2195 "IDE (PIO-only) (%01i:%01i)" + 2196 "Add New Hard Disk" + 2197 "Add Existing Hard Disk" + 2198 "Removable disk %i: %s" + 2199 "English (United States)" END diff --git a/src/ICONS/hard_disk_mfm.ico b/src/ICONS/hard_disk_mfm.ico new file mode 100644 index 0000000000000000000000000000000000000000..ee44a85a07f989fe832a8f433a9fe9212858a57d GIT binary patch literal 1150 zcmd6l%S%>K6vg+UW)az>QS^m9Y!(DfoD@h7gd&QlfkY3?Bt$+!MC@T9_Ao1vAn8RI z4TS!IAc&y8O3TvJ(oz~VXebRXX215jheOt+VcpBR=iYtyT5IofwpsAItjzqm+Kw(Z zTVZA!93JvWjQe8d|CTR_$iM%C$C@gJ4z!ZhHk0iulI>~Y`|d{A(Ev4duQ2NQt*%95 zN91na75xsifjHtz=lF$~({UYyhW4mce+o8kho(;G>5rQ7mWPn)Xzq$R(owE_rLn&y z?}zg@m>Zphkq^J){WMH{ju`(0!{abC3NJ@~!R!3tn$Pr4@mFIoITJZ!Q}AXYYD!;v ziamb|PX?hh48GrkVeP~b@df25R}fcv@=TD2;^ICkK`4JwA6DI8)_ad{iYGtSD@Z5R zoobiA_`XN8wz6-jM$pf>e<4SEA#T!0wa8z5!T0`F8sAVDs8UbjsE5=?(nZ2{*(W&zQIiR+tnV-ax5}?>`1(y=3++7 literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_mfm_active.ico b/src/ICONS/hard_disk_mfm_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..caf8ef5414c102514d9cb43868d586ada593a303 GIT binary patch literal 1150 zcmc(dPe>I}6voe`b`ja8Rb=#s+O=xaDv&nuYEc9&S~N41$@5Rocnl)aBSb6H5;s|C zh!tUIn=lB149iOEP5RV&me!(G%V_aP`#Rs;F1}ZbY8AsbGxyB>ednAzN5tq=RwjDi zC?{5mtP_##Dh+AG#`Phh-`1|Oir4>e^R9Ra|E`}4?gj9N{2bSRi+g=uA{Y%2WQ(M0 zug6PluE5061{98@Q8=7J;ZPkG57q$ttAM@7fIS{id%L!j{psWPCKr=ufcERa#Xg{= z8))hT8ajaRf>o*&2!=K9r>5UMG+xte*_{V$KEDwlL!LgT&H?p<^$0$M2 1048576) + { + mem_size = 1048576; + } for (c = 0; c < FDD_NUM; c++) { @@ -594,6 +598,10 @@ void loadconfig(wchar_t *fn) fdd_set_type(c, fdd_get_from_internal_name(p)); else fdd_set_type(c, (c < 2) ? 2 : 0); + if (fdd_get_type(c) > 13) + { + fdd_set_type(c, 13); + } sprintf(temps, "fdd_%02i_fn", c + 1); wp = (wchar_t *)config_get_wstring(NULL, temps, L""); @@ -604,7 +612,7 @@ void loadconfig(wchar_t *fn) } printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = config_get_int(NULL, temps, 0); + ui_writeprot[c] = !!config_get_int(NULL, temps, 0); } p = (char *)config_get_string(NULL, "hdd_controller", ""); @@ -627,20 +635,52 @@ void loadconfig(wchar_t *fn) { sprintf(temps, "hdd_%02i_sectors", c + 1); hdc[c].spt = config_get_int(NULL, temps, 0); + if (hdc[c].spt > 99) + { + hdc[c].spt = 99; + } sprintf(temps, "hdd_%02i_heads", c + 1); hdc[c].hpc = config_get_int(NULL, temps, 0); + if (hdc[c].hpc > 64) + { + hdc[c].hpc = 64; + } sprintf(temps, "hdd_%02i_cylinders", c + 1); hdc[c].tracks = config_get_int(NULL, temps, 0); + if (hdc[c].tracks > 266305) + { + hdc[c].tracks = 266305; + } sprintf(temps, "hdd_%02i_bus_type", c + 1); hdc[c].bus = config_get_int(NULL, temps, 0); + if (hdc[c].bus > 4) + { + hdc[c].bus = 4; + } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); hdc[c].mfm_channel = config_get_int(NULL, temps, 0); + if (hdc[c].mfm_channel > 1) + { + hdc[c].mfm_channel = 1; + } sprintf(temps, "hdd_%02i_ide_channel", c + 1); hdc[c].ide_channel = config_get_int(NULL, temps, 0); + if (hdc[c].ide_channel > 7) + { + hdc[c].ide_channel = 7; + } sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); + if (hdc[c].scsi_id > 15) + { + hdc[c].scsi_id = 15; + } sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); hdc[c].scsi_lun = config_get_int(NULL, temps, 0); + if (hdc[c].scsi_lun > 7) + { + hdc[c].scsi_lun = 7; + } sprintf(temps, "hdd_%02i_fn", c + 1); wp = (wchar_t *)config_get_wstring(NULL, temps, L""); if (wp) memcpy(hdd_fn[c], wp, 512); @@ -657,19 +697,35 @@ void loadconfig(wchar_t *fn) cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; sprintf(temps, "cdrom_%02i_enabled", c + 1); - cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); + cdrom_drives[c].enabled = !!config_get_int(NULL, temps, 0); sprintf(temps, "cdrom_%02i_sound_on", c + 1); - cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); + cdrom_drives[c].sound_on = !!config_get_int(NULL, temps, 1); sprintf(temps, "cdrom_%02i_bus_type", c + 1); cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); + if (cdrom_drives[c].bus_type > 1) + { + cdrom_drives[c].bus_type = 1; + } sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); + cdrom_drives[c].atapi_dma = !!config_get_int(NULL, temps, 0); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); + if (cdrom_drives[c].ide_channel > 7) + { + cdrom_drives[c].ide_channel = 7; + } sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); + if (cdrom_drives[c].scsi_device_id > 15) + { + cdrom_drives[c].scsi_device_id = 15; + } sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); + if (cdrom_drives[c].scsi_device_lun > 7) + { + cdrom_drives[c].scsi_device_lun = 7; + } sprintf(temps, "cdrom_%02i_image_path", c + 1); wp = (wchar_t *)config_get_wstring(NULL, temps, L""); @@ -680,17 +736,17 @@ void loadconfig(wchar_t *fn) } } - vid_resize = config_get_int(NULL, "vid_resize", 0); + vid_resize = !!config_get_int(NULL, "vid_resize", 0); vid_api = config_get_int(NULL, "vid_api", 0); video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); - force_43 = config_get_int(NULL, "force_43", 0); - scale = config_get_int(NULL, "scale", 1); - enable_overscan = config_get_int(NULL, "enable_overscan", 0); + force_43 = !!config_get_int(NULL, "force_43", 0); + scale = !!config_get_int(NULL, "scale", 1); + enable_overscan = !!config_get_int(NULL, "enable_overscan", 0); - enable_sync = config_get_int(NULL, "enable_sync", 1); - opl3_type = config_get_int(NULL, "opl3_type", 1); + enable_sync = !!config_get_int(NULL, "enable_sync", 1); + opl3_type = !!config_get_int(NULL, "opl3_type", 1); window_w = config_get_int(NULL, "window_w", 0); window_h = config_get_int(NULL, "window_h", 0); @@ -705,8 +761,7 @@ void loadconfig(wchar_t *fn) else mouse_type = 0; - enable_xtide = config_get_int(NULL, "enable_xtide", 1); - enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); + enable_external_fpu = !!config_get_int(NULL, "enable_external_fpu", 0); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { @@ -757,10 +812,10 @@ void loadconfig(wchar_t *fn) path_len = wcslen(nvr_path); - serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); - serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); - lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); - bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); + serial_enabled[0] = !!config_get_int(NULL, "serial1_enabled", 1); + serial_enabled[1] = !!config_get_int(NULL, "serial2_enabled", 1); + lpt_enabled = !!config_get_int(NULL, "lpt_enabled", 1); + bugger_enabled = !!config_get_int(NULL, "bugger_enabled", 0); } wchar_t temp_nvr_path[1024]; @@ -896,7 +951,6 @@ void saveconfig(void) config_set_int(NULL, "joystick_type", joystick_type); config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); - config_set_int(NULL, "enable_xtide", enable_xtide); config_set_int(NULL, "enable_external_fpu", enable_external_fpu); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) diff --git a/src/ibm.h b/src/ibm.h index 69abd7fd6..e71d29ccb 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -761,6 +761,8 @@ void runpc(); void saveconfig(); void softresetx86(); void speedchanged(); +void status_settextw(wchar_t *wstr); +void status_settext(char *str); void trc_reset(uint8_t val); void update_status_bar_icon(int tag, int active); void update_status_bar_icon_state(int tag, int state); diff --git a/src/ide.c b/src/ide.c index aa8855eba..f6c2c3454 100644 --- a/src/ide.c +++ b/src/ide.c @@ -382,7 +382,7 @@ static void ide_identify(IDE *ide) ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ ide->buffer[48] = 1; /*Dword transfers supported*/ - if (PCI && (ide->board < 2)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) { ide->buffer[49] = (1 << 8); /* LBA and DMA supported */ } @@ -396,7 +396,6 @@ static void ide_identify(IDE *ide) } ide->buffer[50] = 0x4000; /* Capabilities */ ide->buffer[51] = 2 << 8; /*PIO timing mode*/ - ide->buffer[52] = 2 << 8; /*DMA timing mode*/ #if 0 ide->buffer[53] = 1; ide->buffer[55] = ide->hpc; @@ -419,8 +418,9 @@ static void ide_identify(IDE *ide) ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[61] = ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16) & 0x0FFF; } - if (PCI && (ide->board < 2)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) { + ide->buffer[52] = 2 << 8; /*DMA timing mode*/ ide->buffer[63] = 7; } ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ @@ -444,16 +444,16 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ - ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] = 0x200; /* LBA supported */ - ide->buffer[73] = 6; - ide->buffer[74] = 9; - ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) { + ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] |= 0x100; /* DMA supported */ ide->buffer[63] = 7; + ide->buffer[73] = 6; + ide->buffer[74] = 9; + ide->buffer[80] = 0x10; /*ATA/ATAPI-4 supported*/ } } @@ -787,7 +787,7 @@ void resetide(void) c = 0; for (d = 0; d < HDC_NUM; d++) { - if ((hdc[d].bus == 2) && (hdc[d].ide_channel < IDE_NUM)) + if (((hdc[d].bus == 2) || (hdc[d].bus == 3)) && (hdc[d].ide_channel < IDE_NUM)) { pclog("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); loadhd(&ide_drives[hdc[d].ide_channel], d, hdd_fn[d]); @@ -1413,7 +1413,7 @@ uint32_t ide_read_data(int ide_board, int length) } else { - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } } } @@ -1736,7 +1736,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; case WIN_READ_DMA: @@ -1770,12 +1770,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide_irq_raise(ide); - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } } } @@ -1813,7 +1813,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; case WIN_WRITE: @@ -1836,12 +1836,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } return; @@ -1877,12 +1877,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide_irq_raise(ide); - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } } } @@ -1913,12 +1913,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon(0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); } return; @@ -1935,7 +1935,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - update_status_bar_icon(0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; case WIN_FORMAT: @@ -1957,7 +1957,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - /* update_status_bar_icon(0x21, 1); */ + /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: diff --git a/src/scsi_disk.c b/src/scsi_disk.c index e0b7f09a2..31623fbed 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -175,7 +175,7 @@ int find_hdc_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 3) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) + if ((hdc[i].bus == 4) && (hdc[i].scsi_id == scsi_id) && (hdc[i].scsi_lun == scsi_lun)) { return i; } @@ -852,11 +852,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x22, 1); + update_status_bar_icon(0x23, 1); } else { - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); } return; @@ -913,11 +913,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x22, 1); + update_status_bar_icon(0x23, 1); } else { - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); } return; @@ -1129,7 +1129,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].status = READY_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0xFF; - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); return; case CDROM_PHASE_DATA_OUT: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); @@ -1142,7 +1142,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); return; case CDROM_PHASE_DATA_IN: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); @@ -1155,7 +1155,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon(0x22, 0); + update_status_bar_icon(0x23, 0); return; case CDROM_PHASE_ERROR: scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); diff --git a/src/win-language.c b/src/win-language.c index 51f3e6c86..333729302 100644 --- a/src/win-language.c +++ b/src/win-language.c @@ -21,7 +21,7 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -#define STRINGS_NUM 148 +#define STRINGS_NUM 152 WCHAR lpResourceString[STRINGS_NUM][512]; diff --git a/src/win-settings.c b/src/win-settings.c index 035a554d5..86e1ee792 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -1457,7 +1457,7 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); - for (i = 0; i < 6; i += 2) + for (i = 0; i < 8; i += 2) { hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); ImageList_AddIcon(hSmall, hiconItem); @@ -1486,11 +1486,6 @@ static void normalize_hd_list() } for (i = 0; i < HDC_NUM; i++) { - if ((temp_hdc[i].bus == 3) && (temp_hdc[i].scsi_id == 7)) - { - /* SCSI ID 7 is the host adapter, so any hard disk set to SCSI bus and ID 7 is to be treated as disabled and marked as such. */ - temp_hdc[i].bus = 0; - } if (temp_hdc[i].bus > 0) { memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); @@ -1540,9 +1535,9 @@ static void add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2166 + i)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); } h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); @@ -1623,7 +1618,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); break; - case 1: /* IDE */ + case 1: /* IDE (PIO-only) */ + case 2: /* IDE (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1633,7 +1629,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); break; - case 2: /* SCSI */ + case 3: /* SCSI */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1661,8 +1657,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) ShowWindow(h, SW_HIDE); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); + EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); } else { @@ -1682,7 +1677,8 @@ static void recalc_next_free_id(HWND hdlg) int i; int c_mfm = 0; - int c_ide = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; int c_scsi = 0; int enable_add = 0; @@ -1696,9 +1692,13 @@ static void recalc_next_free_id(HWND hdlg) } else if (temp_hdc[i].bus == 2) { - c_ide++; + c_ide_pio++; } else if (temp_hdc[i].bus == 3) + { + c_ide_dma++; + } + else if (temp_hdc[i].bus == 4) { c_scsi++; } @@ -1717,7 +1717,7 @@ static void recalc_next_free_id(HWND hdlg) enable_add = enable_add || (next_free_id >= 0); /* pclog("Enable add: %i\n", enable_add); */ - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide < IDE_NUM) || (c_scsi < SCSI_NUM)); + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); /* pclog("Enable add: %i\n", enable_add); */ h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); @@ -1744,7 +1744,7 @@ static void recalc_next_free_id(HWND hdlg) h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - if ((c_mfm == 0) && (c_ide == 0) && (c_scsi == 0)) + if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) { EnableWindow(h, FALSE); } @@ -1773,9 +1773,12 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; case 2: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; } @@ -1845,9 +1848,12 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; case 2: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; } @@ -1946,11 +1952,11 @@ static BOOL win_settings_hard_disks_init_columns(HWND hwndList) { case 0: /* Bus */ - lvc.cx = 85; + lvc.cx = 135; lvc.fmt = LVCFMT_LEFT; break; case 2: /* Cylinders */ - lvc.cx = 51; + lvc.cx = 41; lvc.fmt = LVCFMT_RIGHT; break; case 3: /* Heads */ @@ -1959,11 +1965,11 @@ static BOOL win_settings_hard_disks_init_columns(HWND hwndList) lvc.fmt = LVCFMT_RIGHT; break; case 1: /* File */ - lvc.cx = 180; + lvc.cx = 150; lvc.fmt = LVCFMT_LEFT; break; case 5: /* Size (MB) 8 */ - lvc.cx = 51; + lvc.cx = 41; lvc.fmt = LVCFMT_RIGHT; break; } @@ -2086,6 +2092,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W case WM_INITDIALOG: memset(hd_file_name, 0, 512); + SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); + no_update = 1; spt = existing ? 0 : 17; set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); @@ -2223,6 +2231,19 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W case IDC_CFILE: if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) { + if (!existing) + { + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) + { + fclose(f); + if (msgbox_question(ghwnd, 2178) != IDYES) + { + return FALSE; + } + } + } + f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); if (f == NULL) { diff --git a/src/win.c b/src/win.c index 1c74724a6..049b0cbc0 100644 --- a/src/win.c +++ b/src/win.c @@ -832,7 +832,7 @@ void create_hd_tip(int part) WCHAR *szText; int bus = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2182 + bus); + szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); } @@ -894,6 +894,34 @@ static int get_cd_state(int id) } } +void status_settextw(wchar_t *wstr) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == 0x30) + { + part = i; + } + } + + if (part != -1) + { + SendMessage(hwndStatus, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) wstr); + } +} + +static wchar_t cwstr[512]; + +void status_settext(char *str) +{ + memset(cwstr, 0, 1024); + mbstowcs(cwstr, str, strlen(str) + 1); + status_settextw(cwstr); +} + void update_status_bar_panes(HWND hwnds) { int i, j, id; @@ -901,12 +929,14 @@ void update_status_bar_panes(HWND hwnds) int c_rll = 0; int c_mfm = 0; - int c_ide = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; int c_scsi = 0; c_mfm = count_hard_disks(1); - c_ide = count_hard_disks(2); - c_scsi = count_hard_disks(3); + c_ide_pio = count_hard_disks(2); + c_ide_dma = count_hard_disks(3); + c_scsi = count_hard_disks(4); sb_parts = 0; memset(sb_part_meanings, 0, 40); @@ -938,20 +968,27 @@ void update_status_bar_panes(HWND hwnds) sb_part_meanings[sb_parts] = 0x20; sb_parts++; } - if (c_ide && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) + if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = 0x21; sb_parts++; } - if (c_scsi) + if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = 0x22; sb_parts++; } + if (c_scsi) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x23; + sb_parts++; + } if (sb_parts) { iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); From 37b313a7587edd7adddc048407f339b55a1f2d16 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 10 May 2017 02:50:54 +0200 Subject: [PATCH 190/392] Fixed MPU401 irq in the awe32 config. --- src/SOUND/snd_sb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 9b3d817e1..0308fa632 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -1073,10 +1073,10 @@ static device_config_t sb_awe32_config[] = } }, { - "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 2, + "irq401", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, { { - "IRQ 2", 2 + "IRQ 9", 9 }, { "IRQ 3", 3 From 456aaec6274b8b6cd4a82974e448a242329e81af Mon Sep 17 00:00:00 2001 From: waltje Date: Tue, 9 May 2017 22:07:39 -0400 Subject: [PATCH 191/392] General cleanups. --- src/VIDEO/vid_voodoo.c | 2 +- src/config.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/VIDEO/vid_voodoo.c b/src/VIDEO/vid_voodoo.c index 815d071a6..57bb0084a 100644 --- a/src/VIDEO/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -2215,7 +2215,7 @@ static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, #define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) /*Perform texture fetch and blending for both TMUs*/ -static __inline voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) +static __inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) { int r,g,b,a; int c_reverse, a_reverse; diff --git a/src/config.c b/src/config.c index f52cfd978..e97afe22e 100644 --- a/src/config.c +++ b/src/config.c @@ -795,8 +795,8 @@ void saveconfig(void) config_set_int(NULL, "netinterface", ethif); config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); - config_set_int(NULL, "maclocal", net2000_get_maclocal()); - config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); + config_set_int(NULL, "maclocal", ne2000_get_maclocal()); + config_set_int(NULL, "maclocal_pci", ne2000_get_maclocal_pci()); config_set_string(NULL, "model", model_get_internal_name()); config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); From b975839b41a70c82f811ba10cf2b69522fbbadda Mon Sep 17 00:00:00 2001 From: waltje Date: Tue, 9 May 2017 22:09:55 -0400 Subject: [PATCH 192/392] Network cleanup, updated pcap_if to have a sniffer, PCAP now works properly. Removed all Slirp warnings. --- src/net_ne2000.c | 3644 ++++++++++++++++++++++----------------------- src/net_ne2000.h | 21 +- src/network.c | 75 +- src/network.h | 25 +- src/pc.c | 8 +- src/pcap_if.c | 227 ++- src/slirp/misc.c | 9 +- src/slirp/slirp.c | 6 +- src/slirp/slirp.h | 2 + 9 files changed, 2081 insertions(+), 1936 deletions(-) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index f1a0eb44d..80d836751 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1,21 +1,25 @@ -/* Copyright holders: Peter Grehan, SA1988, Tenshi - see COPYING for more details -*/ /* - $Id: ne2k.cc,v 1.56.2.1 2004/02/02 22:37:22 cbothamy Exp $ -*/ -/* - Copyright (C) 2002 MandrakeSoft S.A. - - MandrakeSoft S.A. - 43, rue d'Aboukir - 75002 Paris - France - http://www.linux-mandrake.com/ - http://www.mandrakesoft.com/ -*/ - -/* Peter Grehan (grehan@iprg.nokia.com) coded all of this - NE2000/ether stuff. */ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of an NE2000/RTL8029AS network controller. + * + * NOTE: Its still a mess, but we're getting there. The file will + * also implement an NE1000 for 8-bit ISA systems. + * + * Version: @(#)net_ne2000.c 1.0.1 2017/05/09 + * + * Authors: Fred N. van Kempen, + * Peter Grehan, grehan@iprg.nokia.com> + * SA1988, Tenshi + * + * Based on @(#)ne2k.cc v1.56.2.1 2004/02/02 22:37:22 cbothamy + * Portions Copyright (C) 2002 MandrakeSoft S.A. + */ #include #include #include @@ -36,21 +40,44 @@ #include "disc_random.h" #include "network.h" #include "net_ne2000.h" +#include "bswap.h" -/* THIS IS THE DEFAULT MAC ADDRESS .... so it wont place nice with multiple VMs. YET. */ -uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; -uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; - +#ifdef WALTJE +# define ENABLE_NE2000_LOG 1 +#endif #define NETBLOCKING 0 /* we won't block our pcap */ -pcap_t *net_pcap; -queueADT slirpq; -int net_slirp_inited=0; -int net_is_pcap=0; /* and pretend pcap is dead. */ -int fizz=0; -void slirp_tic(); +/* For PCI. */ +typedef union { + uint32_t addr; + uint8_t addr_regs[4]; +} bar_t; + + +/* Most of this stuff should go into the struct. --FvK */ +static uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; +static uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; +static uint8_t rtl8029as_eeprom[128]; +static uint8_t pci_regs[256]; +static bar_t pci_bar[2]; +static uint32_t bios_addr = 0xD0000; +static uint32_t old_base_addr = 0; +static uint32_t bios_size = 0; +static uint32_t bios_mask = 0; +static pcap_t *net_pcap; +static queueADT slirpq; +static int disable_netbios = 0; +static int net_slirp_inited = 0; +static int net_is_pcap = 0; /* and pretend pcap is dead. */ +static int fizz = 0; +#ifdef ENABLE_NE2000_LOG +static int ne2000_do_log = ENABLE_NE2000_LOG; +#else +static int ne2000_do_log = 0; +#endif + #define BX_RESET_HARDWARE 0 #define BX_RESET_SOFTWARE 1 @@ -63,463 +90,245 @@ void slirp_tic(); #define BX_NE2K_MEMSTART (16*1024) #define BX_NE2K_MEMEND (BX_NE2K_MEMSTART + BX_NE2K_MEMSIZ) -uint8_t rtl8029as_eeprom[128]; -typedef struct ne2000_t -{ - /* ne2k register state */ +/* ne2k register state */ +typedef struct { + /* Page 0 */ - /* Page 0 */ + /* Command Register - 00h read/write */ + struct CR_t { + int stop; /* STP - Software Reset command */ + int start; /* START - start the NIC */ + int tx_packet; /* TXP - initiate packet transmission */ + uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ + uint8_t pgsel; /* PS0,PS1 - Page select */ + } CR; - /* Command Register - 00h read/write */ - struct CR_t - { - int stop; /* STP - Software Reset command */ - int start; /* START - start the NIC */ - int tx_packet; /* TXP - initiate packet transmission */ - uint8_t rdma_cmd; /* RD0,RD1,RD2 - Remote DMA command */ - uint8_t pgsel; /* PS0,PS1 - Page select */ - } CR; - /* Interrupt Status Register - 07h read/write */ - struct ISR_t - { - int pkt_rx; /* PRX - packet received with no errors */ - int pkt_tx; /* PTX - packet transmitted with no errors */ - int rx_err; /* RXE - packet received with 1 or more errors */ - int tx_err; /* TXE - packet tx'd " " " " " */ - int overwrite; /* OVW - rx buffer resources exhausted */ - int cnt_oflow; /* CNT - network tally counter MSB's set */ - int rdma_done; /* RDC - remote DMA complete */ - int reset; /* RST - reset status */ - } ISR; - /* Interrupt Mask Register - 0fh write */ - struct IMR_t - { - int rx_inte; /* PRXE - packet rx interrupt enable */ - int tx_inte; /* PTXE - packet tx interrput enable */ - int rxerr_inte; /* RXEE - rx error interrupt enable */ - int txerr_inte; /* TXEE - tx error interrupt enable */ - int overw_inte; /* OVWE - overwrite warn int enable */ - int cofl_inte; /* CNTE - counter o'flow int enable */ - int rdma_inte; /* RDCE - remote DMA complete int enable */ - int reserved; /* D7 - reserved */ - } IMR; - /* Data Configuration Register - 0eh write */ - struct DCR_t - { - int wdsize; /* WTS - 8/16-bit select */ - int endian; /* BOS - byte-order select */ - int longaddr; /* LAS - long-address select */ - int loop; /* LS - loopback select */ - int auto_rx; /* AR - auto-remove rx packets with remote DMA */ - uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ - } DCR; - /* Transmit Configuration Register - 0dh write */ - struct TCR_t - { - int crc_disable; /* CRC - inhibit tx CRC */ - uint8_t loop_cntl; /* LB0,LB1 - loopback control */ - int ext_stoptx; /* ATD - allow tx disable by external mcast */ - int coll_prio; /* OFST - backoff algorithm select */ - uint8_t reserved; /* D5,D6,D7 - reserved */ - } TCR; - /* Transmit Status Register - 04h read */ - struct TSR_t - { - int tx_ok; /* PTX - tx complete without error */ - int reserved; /* D1 - reserved */ - int collided; /* COL - tx collided >= 1 times */ - int aborted; /* ABT - aborted due to excessive collisions */ - int no_carrier; /* CRS - carrier-sense lost */ - int fifo_ur; /* FU - FIFO underrun */ - int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ - int ow_coll; /* OWC - out-of-window collision */ - } TSR; - /* Receive Configuration Register - 0ch write */ - struct RCR_t - { - int errors_ok; /* SEP - accept pkts with rx errors */ - int runts_ok; /* AR - accept < 64-byte runts */ - int broadcast; /* AB - accept eth broadcast address */ - int multicast; /* AM - check mcast hash array */ - int promisc; /* PRO - accept all packets */ - int monitor; /* MON - check pkts, but don't rx */ - uint8_t reserved; /* D6,D7 - reserved */ - } RCR; - /* Receive Status Register - 0ch read */ - struct RSR_t - { - int rx_ok; /* PRX - rx complete without error */ - int bad_crc; /* CRC - Bad CRC detected */ - int bad_falign; /* FAE - frame alignment error */ - int fifo_or; /* FO - FIFO overrun */ - int rx_missed; /* MPA - missed packet error */ - int rx_mbit; /* PHY - unicast or mcast/bcast address match */ - int rx_disabled; /* DIS - set when in monitor mode */ - int deferred; /* DFR - collision active */ - } RSR; + /* Interrupt Status Register - 07h read/write */ + struct ISR_t { + int pkt_rx; /* PRX - packet received with no errors */ + int pkt_tx; /* PTX - packet txed with no errors */ + int rx_err; /* RXE - packet rxed with 1 or more errors */ + int tx_err; /* TXE - packet txed " " " " " */ + int overwrite; /* OVW - rx buffer resources exhausted */ + int cnt_oflow; /* CNT - network tally counter MSB's set */ + int rdma_done; /* RDC - remote DMA complete */ + int reset; /* RST - reset status */ + } ISR; - uint16_t local_dma; /* 01,02h read ; current local DMA addr */ - uint8_t page_start; /* 01h write ; page start register */ - uint8_t page_stop; /* 02h write ; page stop register */ - uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ - uint8_t tx_page_start; /* 04h write ; transmit page start register */ - uint8_t num_coll; /* 05h read ; number-of-collisions register */ - uint16_t tx_bytes; /* 05,06h write ; transmit byte-count register */ - uint8_t fifo; /* 06h read ; FIFO */ - uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ - uint16_t remote_start; /* 08,09h write ; remote start address register */ - uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count register */ - uint8_t tallycnt_0; /* 0dh read ; tally counter 0 (frame align errors) */ - uint8_t tallycnt_1; /* 0eh read ; tally counter 1 (CRC errors) */ - uint8_t tallycnt_2; /* 0fh read ; tally counter 2 (missed pkt errors) */ + /* Interrupt Mask Register - 0fh write */ + struct IMR_t { + int rx_inte; /* PRXE - packet rx interrupt enable */ + int tx_inte; /* PTXE - packet tx interrput enable */ + int rxerr_inte; /* RXEE - rx error interrupt enable */ + int txerr_inte; /* TXEE - tx error interrupt enable */ + int overw_inte; /* OVWE - overwrite warn int enable */ + int cofl_inte; /* CNTE - counter o'flow int enable */ + int rdma_inte; /* RDCE - remote DMA complete int enable */ + int reserved; /* D7 - reserved */ + } IMR; - /* Page 1 */ + /* Data Configuration Register - 0eh write */ + struct DCR_t { + int wdsize; /* WTS - 8/16-bit select */ + int endian; /* BOS - byte-order select */ + int longaddr; /* LAS - long-address select */ + int loop; /* LS - loopback select */ + int auto_rx; /* AR - auto-remove rx pkts with remote DMA */ + uint8_t fifo_size; /* FT0,FT1 - fifo threshold */ + } DCR; - /* Command Register 00h (repeated) */ + /* Transmit Configuration Register - 0dh write */ + struct TCR_t { + int crc_disable; /* CRC - inhibit tx CRC */ + uint8_t loop_cntl; /* LB0,LB1 - loopback control */ + int ext_stoptx; /* ATD - allow tx disable by external mcast */ + int coll_prio; /* OFST - backoff algorithm select */ + uint8_t reserved; /* D5,D6,D7 - reserved */ + } TCR; - uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ - uint8_t curr_page; /* 07h read/write ; current page register */ - uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ + /* Transmit Status Register - 04h read */ + struct TSR_t { + int tx_ok; /* PTX - tx complete without error */ + int reserved; /* D1 - reserved */ + int collided; /* COL - tx collided >= 1 times */ + int aborted; /* ABT - aborted due to excessive collisions */ + int no_carrier; /* CRS - carrier-sense lost */ + int fifo_ur; /* FU - FIFO underrun */ + int cd_hbeat; /* CDH - no tx cd-heartbeat from transceiver */ + int ow_coll; /* OWC - out-of-window collision */ + } TSR; - /* Page 2 - diagnostic use only */ + /* Receive Configuration Register - 0ch write */ + struct RCR_t { + int errors_ok; /* SEP - accept pkts with rx errors */ + int runts_ok; /* AR - accept < 64-byte runts */ + int broadcast; /* AB - accept eth broadcast address */ + int multicast; /* AM - check mcast hash array */ + int promisc; /* PRO - accept all packets */ + int monitor; /* MON - check pkts, but don't rx */ + uint8_t reserved; /* D6,D7 - reserved */ + } RCR; - /* Command Register 00h (repeated) */ + /* Receive Status Register - 0ch read */ + struct RSR_t { + int rx_ok; /* PRX - rx complete without error */ + int bad_crc; /* CRC - Bad CRC detected */ + int bad_falign; /* FAE - frame alignment error */ + int fifo_or; /* FO - FIFO overrun */ + int rx_missed; /* MPA - missed packet error */ + int rx_mbit; /* PHY - unicast or mcast/bcast address match */ + int rx_disabled; /* DIS - set when in monitor mode */ + int deferred; /* DFR - collision active */ + } RSR; - /* Page Start Register 01h read (repeated) - Page Stop Register 02h read (repeated) - Current Local DMA Address 01,02h write (repeated) - Transmit Page start address 04h read (repeated) - Receive Configuration Register 0ch read (repeated) - Transmit Configuration Register 0dh read (repeated) - Data Configuration Register 0eh read (repeated) - Interrupt Mask Register 0fh read (repeated) - */ - uint8_t rempkt_ptr; /* 03h read/write ; remote next-packet pointer */ - uint8_t localpkt_ptr; /* 05h read/write ; local next-packet pointer */ - uint16_t address_cnt; /* 06,07h read/write ; address counter */ + uint16_t local_dma; /* 01,02h read ; current local DMA addr */ + uint8_t page_start; /* 01h write ; page start regr */ + uint8_t page_stop; /* 02h write ; page stop regr */ + uint8_t bound_ptr; /* 03h read/write ; boundary pointer */ + uint8_t tx_page_start; /* 04h write ; transmit page start reg */ + uint8_t num_coll; /* 05h read ; number-of-collisions reg */ + uint16_t tx_bytes; /* 05,06h write ; transmit byte-count reg */ + uint8_t fifo; /* 06h read ; FIFO */ + uint16_t remote_dma; /* 08,09h read ; current remote DMA addr */ + uint16_t remote_start; /* 08,09h write ; remote start address reg */ + uint16_t remote_bytes; /* 0a,0bh write ; remote byte-count reg */ + uint8_t tallycnt_0; /* 0dh read ; tally ctr 0 (frame align errs) */ + uint8_t tallycnt_1; /* 0eh read ; tally ctr 1 (CRC errors) */ + uint8_t tallycnt_2; /* 0fh read ; tally ctr 2 (missed pkt errs) */ - /* Page 3 - should never be modified. */ + /* Page 1 */ - /* Novell ASIC state */ - uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ - uint8_t mem[BX_NE2K_MEMSIZ]; /* on-chip packet memory */ + /* Command Register 00h (repeated) */ - /* ne2k internal state */ - uint32_t base_address; - int base_irq; - int tx_timer_index; - int tx_timer_active; + uint8_t physaddr[6]; /* 01-06h read/write ; MAC address */ + uint8_t curr_page; /* 07h read/write ; current page register */ + uint8_t mchash[8]; /* 08-0fh read/write ; multicast hash array */ - rom_t bios_rom; + /* Page 2 - diagnostic use only */ + /* Command Register 00h (repeated) */ + + /* Page Start Register 01h read (repeated) + * Page Stop Register 02h read (repeated) + * Current Local DMA Address 01,02h write (repeated) + * Transmit Page start address 04h read (repeated) + * Receive Configuration Register 0ch read (repeated) + * Transmit Configuration Register 0dh read (repeated) + * Data Configuration Register 0eh read (repeated) + * Interrupt Mask Register 0fh read (repeated) + */ + uint8_t rempkt_ptr; /* 03h read/write ; remote next-packet ptr */ + uint8_t localpkt_ptr; /* 05h read/write ; local next-packet ptr */ + uint16_t address_cnt; /* 06,07h read/write ; address counter */ + + /* Page 3 - should never be modified. */ + + /* Novell ASIC state */ + uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ + uint8_t mem[BX_NE2K_MEMSIZ]; /* on-chip packet memory */ + + /* ne2k internal state */ + uint32_t base_address; + int base_irq; + int tx_timer_index; + int tx_timer_active; + + rom_t bios_rom; } ne2000_t; -int disable_netbios = 0; -void ne2000_tx_event(void *p, uint32_t val); -uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len); -void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len); -void ne2000_rx_frame(void *p, const void *buf, int io_len); +static void ne2000_tx_event(void *, uint32_t); +static void ne2000_rx_frame(void *, const void *, int); + +void slirp_tic(void); - -#ifdef WALTJE -#define ENABLE_NE2000_LOG -int ne2000_do_log = 1; -#else -int ne2000_do_log = 0; -#endif - - -void ne2000_log(const char *format, ...) +static void +nelog(int lvl, const char *fmt, ...) { #ifdef ENABLE_NE2000_LOG - if (ne2000_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } + va_list ap; + + if (ne2000_do_log >= lvl) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + } +} #endif -} +#define pclog nelog -static uint8_t *ne2000_mac(void) -{ - if (network_card_current == 2) - { - return maclocal_pci; - } - else - { - return maclocal; - } -} - -void ne2000_generate_maclocal(uint32_t mac) -{ - maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ - maclocal[1] = 0x00; - maclocal[2] = 0xD8; - - if (mac & 0xff000000) - { - /* Generating new MAC. */ - maclocal[3] = disc_random_generate(); - maclocal[4] = disc_random_generate(); - maclocal[5] = disc_random_generate(); - } - else - { - maclocal[3] = (mac >> 16) & 0xff; - maclocal[4] = (mac >> 8) & 0xff; - maclocal[5] = mac & 0xff; - } -} - -void ne2000_generate_maclocal_pci(uint32_t mac) -{ - maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - maclocal_pci[1] = 0x20; - maclocal_pci[2] = 0x18; - - if (mac & 0xff000000) - { - /* Generating new MAC. */ - maclocal_pci[3] = disc_random_generate(); - maclocal_pci[4] = disc_random_generate(); - maclocal_pci[5] = disc_random_generate(); - } - else - { - maclocal_pci[3] = (mac >> 16) & 0xff; - maclocal_pci[4] = (mac >> 8) & 0xff; - maclocal_pci[5] = mac & 0xff; - } -} - -uint32_t net2000_get_maclocal() -{ - uint32_t temp; - temp = (((int) maclocal[3]) << 16); - temp |= (((int) maclocal[4]) << 8); - temp |= ((int) maclocal[5]); - return temp; -} - -uint32_t net2000_get_maclocal_pci() -{ - uint32_t temp; - temp = (((int) maclocal_pci[3]) << 16); - temp |= (((int) maclocal_pci[4]) << 8); - temp |= ((int) maclocal_pci[5]); - return temp; -} - -static void ne2000_setirq(ne2000_t *ne2000, int irq) -{ - ne2000->base_irq = irq; -} /* reset - restore state to power-up, cancelling all i/o */ - -static void ne2000_reset(void *p, int reset) +static void +ne2000_reset(void *priv, int reset) { - ne2000_t *ne2000 = (ne2000_t *)p; - int i; + ne2000_t *dev = (ne2000_t *)priv; + int i; - ne2000_log("ne2000 reset\n"); + pclog(1, "ne2000 reset\n"); - /* Initialise the mac address area by doubling the physical address */ - ne2000->macaddr[0] = ne2000->physaddr[0]; - ne2000->macaddr[1] = ne2000->physaddr[0]; - ne2000->macaddr[2] = ne2000->physaddr[1]; - ne2000->macaddr[3] = ne2000->physaddr[1]; - ne2000->macaddr[4] = ne2000->physaddr[2]; - ne2000->macaddr[5] = ne2000->physaddr[2]; - ne2000->macaddr[6] = ne2000->physaddr[3]; - ne2000->macaddr[7] = ne2000->physaddr[3]; - ne2000->macaddr[8] = ne2000->physaddr[4]; - ne2000->macaddr[9] = ne2000->physaddr[4]; - ne2000->macaddr[10] = ne2000->physaddr[5]; - ne2000->macaddr[11] = ne2000->physaddr[5]; + /* Initialize the MAC address area by doubling the physical address */ + dev->macaddr[0] = dev->physaddr[0]; + dev->macaddr[1] = dev->physaddr[0]; + dev->macaddr[2] = dev->physaddr[1]; + dev->macaddr[3] = dev->physaddr[1]; + dev->macaddr[4] = dev->physaddr[2]; + dev->macaddr[5] = dev->physaddr[2]; + dev->macaddr[6] = dev->physaddr[3]; + dev->macaddr[7] = dev->physaddr[3]; + dev->macaddr[8] = dev->physaddr[4]; + dev->macaddr[9] = dev->physaddr[4]; + dev->macaddr[10] = dev->physaddr[5]; + dev->macaddr[11] = dev->physaddr[5]; - /* ne2k signature */ - for (i = 12; i < 32; i++) - { - ne2000->macaddr[i] = 0x57; - } + /* ne2k signature */ + for (i = 12; i < 32; i++) { + dev->macaddr[i] = 0x57; + } - /* Zero out registers and memory */ - memset( & ne2000->CR, 0, sizeof(ne2000->CR) ); - memset( & ne2000->ISR, 0, sizeof(ne2000->ISR)); - memset( & ne2000->IMR, 0, sizeof(ne2000->IMR)); - memset( & ne2000->DCR, 0, sizeof(ne2000->DCR)); - memset( & ne2000->TCR, 0, sizeof(ne2000->TCR)); - memset( & ne2000->TSR, 0, sizeof(ne2000->TSR)); - memset( & ne2000->RSR, 0, sizeof(ne2000->RSR)); - ne2000->tx_timer_active = 0; - ne2000->local_dma = 0; - ne2000->page_start = 0; - ne2000->page_stop = 0; - ne2000->bound_ptr = 0; - ne2000->tx_page_start = 0; - ne2000->num_coll = 0; - ne2000->tx_bytes = 0; - ne2000->fifo = 0; - ne2000->remote_dma = 0; - ne2000->remote_start = 0; - ne2000->remote_bytes = 0; - ne2000->tallycnt_0 = 0; - ne2000->tallycnt_1 = 0; - ne2000->tallycnt_2 = 0; + /* Zero out registers and memory */ + memset(&dev->CR, 0x00, sizeof(dev->CR) ); + memset(&dev->ISR, 0x00, sizeof(dev->ISR)); + memset(&dev->IMR, 0x00, sizeof(dev->IMR)); + memset(&dev->DCR, 0x00, sizeof(dev->DCR)); + memset(&dev->TCR, 0x00, sizeof(dev->TCR)); + memset(&dev->TSR, 0x00, sizeof(dev->TSR)); + memset(&dev->RSR, 0x00, sizeof(dev->RSR)); + dev->tx_timer_active = 0; + dev->local_dma = 0; + dev->page_start = 0; + dev->page_stop = 0; + dev->bound_ptr = 0; + dev->tx_page_start = 0; + dev->num_coll = 0; + dev->tx_bytes = 0; + dev->fifo = 0; + dev->remote_dma = 0; + dev->remote_start = 0; + dev->remote_bytes = 0; + dev->tallycnt_0 = 0; + dev->tallycnt_1 = 0; + dev->tallycnt_2 = 0; - ne2000->curr_page = 0; + dev->curr_page = 0; - ne2000->rempkt_ptr = 0; - ne2000->localpkt_ptr = 0; - ne2000->address_cnt = 0; + dev->rempkt_ptr = 0; + dev->localpkt_ptr = 0; + dev->address_cnt = 0; - memset( & ne2000->mem, 0, sizeof(ne2000->mem)); + memset(&dev->mem, 0x00, sizeof(dev->mem)); - /* Set power-up conditions */ - ne2000->CR.stop = 1; - ne2000->CR.rdma_cmd = 4; - ne2000->ISR.reset = 1; - ne2000->DCR.longaddr = 1; - picint(1 << ne2000->base_irq); - picintc(1 << ne2000->base_irq); + /* Set power-up conditions */ + dev->CR.stop = 1; + dev->CR.rdma_cmd = 4; + dev->ISR.reset = 1; + dev->DCR.longaddr = 1; + picint(1 << dev->base_irq); + picintc(1 << dev->base_irq); } -#include "bswap.h" - -/* read_cr/write_cr - utility routines for handling reads/writes to - the Command Register */ - -uint32_t ne2000_read_cr(ne2000_t *ne2000) -{ - uint32_t val; - - val = (((ne2000->CR.pgsel & 0x03) << 6) | - ((ne2000->CR.rdma_cmd & 0x07) << 3) | - (ne2000->CR.tx_packet << 2) | - (ne2000->CR.start << 1) | - (ne2000->CR.stop)); - ne2000_log("%s: read CR returns 0x%02x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); - return val; -} - -void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) -{ - ne2000_log("%s: wrote 0x%02x to CR\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", value); - - /* Validate remote-DMA */ - if ((value & 0x38) == 0x00) - { - ne2000_log("CR write - invalid rDMA value 0\n"); - value |= 0x20; /* dma_cmd == 4 is a safe default */ - } - - /* Check for s/w reset */ - if (value & 0x01) - { - ne2000->ISR.reset = 1; - ne2000->CR.stop = 1; - } else { - ne2000->CR.stop = 0; - } - - ne2000->CR.rdma_cmd = (value & 0x38) >> 3; - - /* If start command issued, the RST bit in the ISR */ - /* must be cleared */ - if ((value & 0x02) && !ne2000->CR.start) - { - ne2000->ISR.reset = 0; - } - - ne2000->CR.start = ((value & 0x02) == 0x02); - ne2000->CR.pgsel = (value & 0xc0) >> 6; - - /* Check for send-packet command */ - if (ne2000->CR.rdma_cmd == 3) - { - /* Set up DMA read from receive ring */ - ne2000->remote_start = ne2000->remote_dma = ne2000->bound_ptr * 256; - ne2000->remote_bytes = (uint16_t) ne2000_chipmem_read(ne2000, ne2000->bound_ptr * 256 + 2, 2); - ne2000_log("Sending buffer #x%x length %d\n", ne2000->remote_start, ne2000->remote_bytes); - } - - /* Check for start-tx */ - if ((value & 0x04) && ne2000->TCR.loop_cntl) - { - if (ne2000->TCR.loop_cntl != 1) - { - ne2000_log("Loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } - else - { - ne2000_rx_frame(ne2000, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - } - } - else if (value & 0x04) - { - if (ne2000->CR.stop || (!ne2000->CR.start && (network_card_current == 1))) - { - if (ne2000->tx_bytes == 0) /* njh@bandsman.co.uk */ - { - return; /* Solaris9 probe */ - } - ne2000_log("CR write - tx start, dev in reset\n"); - } - - if (ne2000->tx_bytes == 0) - { - ne2000_log("CR write - tx start, tx bytes == 0\n"); - } - - /* Send the packet to the system driver */ - ne2000->CR.tx_packet = 1; - if(!net_is_pcap) - { - slirp_input(&ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - ne2000_log("ne2000 slirp sending packet\n"); - } - else if (net_is_pcap && (net_pcap != NULL)) - { - pcap_sendpacket(net_pcap, &ne2000->mem[ne2000->tx_page_start*256 - BX_NE2K_MEMSTART], ne2000->tx_bytes); - ne2000_log("ne2000 pcap sending packet\n"); - } - - /* some more debug */ - if (ne2000->tx_timer_active) - { - ne2000_log("CR write, tx timer still active\n"); - } - - ne2000_tx_event(ne2000, value); - } - - /* Linux probes for an interrupt by setting up a remote-DMA read - of 0 bytes with remote-DMA completion interrupts enabled. - Detect this here */ - if (ne2000->CR.rdma_cmd == 0x01 && - ne2000->CR.start && - ne2000->remote_bytes == 0) - { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) - { - picint(1 << ne2000->base_irq); - if (network_card_current == 1) - { - picintc(1 << ne2000->base_irq); - } - } - } -} /* chipmem_read/chipmem_write - access the 64K private RAM. The ne2000 memory is accessed through the data port of @@ -528,93 +337,79 @@ void ne2000_write_cr(ne2000_t *ne2000, uint32_t value) The first 16 bytes contains the MAC address at even locations, and there is 16K of buffer memory starting at 16K */ - -uint32_t ne2000_chipmem_read(ne2000_t *ne2000, uint32_t address, unsigned int io_len) +static uint32_t +chipmem_read(ne2000_t *dev, uint32_t addr, unsigned int len) { - uint32_t retval = 0; + uint32_t retval = 0; - if ((io_len == 2) && (address & 0x1)) - { - ne2000_log("unaligned chipmem word read\n"); + if ((len == 2) && (addr & 0x1)) { + pclog(1, "unaligned chipmem word read\n"); + } + + /* ROM'd MAC address */ + if ((addr >=0) && (addr <= 31)) { + retval = dev->macaddr[addr % 32]; + if ((len == 2) || (len == 4)) { + retval |= (dev->macaddr[(addr + 1) % 32] << 8); } - - /* ROM'd MAC address */ - if ((address >=0) && (address <= 31)) - { - retval = ne2000->macaddr[address % 32]; - if ((io_len == 2) || (io_len == 4)) - { - retval |= (ne2000->macaddr[(address + 1) % 32] << 8); - } - if (io_len == 4) - { - retval |= (ne2000->macaddr[(address + 2) % 32] << 16); - retval |= (ne2000->macaddr[(address + 3) % 32] << 24); - } - return (retval); + if (len == 4) { + retval |= (dev->macaddr[(addr + 2) % 32] << 16); + retval |= (dev->macaddr[(addr + 3) % 32] << 24); } + return(retval); + } - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - { - retval = ne2000->mem[address - BX_NE2K_MEMSTART]; - if ((io_len == 2) || (io_len == 4)) - { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 1] << 8); - } - if (io_len == 4) - { - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 2] << 16); - retval |= (ne2000->mem[address - BX_NE2K_MEMSTART + 3] << 24); - } - return (retval); + if ((addr >= BX_NE2K_MEMSTART) && (addr < BX_NE2K_MEMEND)) { + retval = dev->mem[addr - BX_NE2K_MEMSTART]; + if ((len == 2) || (len == 4)) { + retval |= (dev->mem[addr - BX_NE2K_MEMSTART + 1] << 8); } - - ne2000_log("out-of-bounds chipmem read, %04X\n", address); - - if (network_card_current == 1) - { - switch(io_len) - { - case 1: - return 0xff; - case 2: - return 0xffff; - } - } - else - { - return 0xff; + if (len == 4) { + retval |= (dev->mem[addr - BX_NE2K_MEMSTART + 2] << 16); + retval |= (dev->mem[addr - BX_NE2K_MEMSTART + 3] << 24); } + return(retval); + } - return 0xffff; + pclog(1, "out-of-bounds chipmem read, %04X\n", addr); + + if (network_card_current == 1) { + switch(len) { + case 1: + return(0xff); + case 2: + return(0xffff); + } + } else { + return(0xff); + } + + return(0xffff); } -void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) -{ - if ((io_len == 2) && (address & 0x1)) - { - ne2000_log("unaligned chipmem word write\n"); - } - if ((address >= BX_NE2K_MEMSTART) && (address < BX_NE2K_MEMEND)) - { - ne2000->mem[address - BX_NE2K_MEMSTART] = value & 0xff; - if ((io_len == 2) || (io_len == 4)) - { - ne2000->mem[address - BX_NE2K_MEMSTART + 1] = value >> 8; - } - if (io_len == 4) - { - ne2000->mem[address - BX_NE2K_MEMSTART + 2] = value >> 16; - ne2000->mem[address - BX_NE2K_MEMSTART + 3] = value >> 24; - } +static void +chipmem_write(ne2000_t *dev, uint32_t addr, uint32_t val, unsigned len) +{ + if ((len == 2) && (addr & 0x1)) { + pclog(1, "unaligned chipmem word write\n"); + } + + if ((addr >= BX_NE2K_MEMSTART) && (addr < BX_NE2K_MEMEND)) { + dev->mem[addr - BX_NE2K_MEMSTART] = val & 0xff; + if ((len == 2) || (len == 4)) { + dev->mem[addr - BX_NE2K_MEMSTART + 1] = val >> 8; } - else - { - ne2000_log("out-of-bounds chipmem write, %04X\n", address); + if (len == 4) { + dev->mem[addr - BX_NE2K_MEMSTART + 2] = val >> 16; + dev->mem[addr - BX_NE2K_MEMSTART + 3] = val >> 24; } + } else { + pclog(1, "out-of-bounds chipmem write, %04X\n", addr); + } } + /* asic_read/asic_write - This is the high 16 bytes of i/o space (the lower 16 bytes is for the DS8390). Only two locations are used: offset 0, which is used for data transfer, and @@ -624,859 +419,1189 @@ void ne2000_chipmem_write(ne2000_t *ne2000, uint32_t address, uint32_t value, un after that, insw/outsw instructions can be used to move the appropriate number of bytes to/from the device. */ -uint32_t ne2000_asic_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +static uint32_t +asic_read(ne2000_t *dev, uint32_t off, unsigned int len) { - uint32_t retval = 0; + uint32_t retval = 0; - switch (offset) - { - case 0x0: /* Data register */ + switch (off) { + case 0x0: /* Data register */ - /* A read remote-DMA command must have been issued, - and the source-address and length registers must - have been initialised. */ + /* A read remote-DMA command must have been issued, + and the source-address and length registers must + have been initialised. */ - if (io_len > ne2000->remote_bytes) - { - ne2000_log("dma read underrun iolen=%d remote_bytes=%d\n",io_len,ne2000->remote_bytes); + if (len > dev->remote_bytes) { + pclog(1, "dma read underrun iolen=%d remote_bytes=%d\n", + len, dev->remote_bytes); + } + + pclog(2, "%s read DMA: addr=%4x remote_bytes=%d\n", + (network_card_current==1)?"NE2000":"RTL8029AS", + dev->remote_dma,dev->remote_bytes); + retval = chipmem_read(dev, dev->remote_dma, len); + + /* The 8390 bumps the address and decreases the byte count + by the selected word size after every access, not by + the amount of data requested by the host (io_len). */ + if (len == 4) { + dev->remote_dma += len; + } else { + dev->remote_dma += (dev->DCR.wdsize + 1); + } + + if (dev->remote_dma == dev->page_stop << 8) { + dev->remote_dma = dev->page_start << 8; + } + + /* keep s.remote_bytes from underflowing */ + if (dev->remote_bytes > dev->DCR.wdsize) { + if (len == 4) { + dev->remote_bytes -= len; + } else { + dev->remote_bytes -= (dev->DCR.wdsize + 1); } + } else { + dev->remote_bytes = 0; + } - ne2000_log("%s read DMA: addr=%4x remote_bytes=%d\n",(network_card_current == 1) ? "NE2000" : "RTL8029AS",ne2000->remote_dma,ne2000->remote_bytes); - retval = ne2000_chipmem_read(ne2000, ne2000->remote_dma, io_len); - - /* The 8390 bumps the address and decreases the byte count - by the selected word size after every access, not by - the amount of data requested by the host (io_len). */ - - if (io_len == 4) - { - ne2000->remote_dma += io_len; - } - else - { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); + /* If all bytes have been written, signal remote-DMA complete */ + if (dev->remote_bytes == 0) { + dev->ISR.rdma_done = 1; + if (dev->IMR.rdma_inte) { + picint(1 << dev->base_irq); } + } + break; - if (ne2000->remote_dma == ne2000->page_stop << 8) - { - ne2000->remote_dma = ne2000->page_start << 8; - } + case 0xf: /* Reset register */ + ne2000_reset(dev, BX_RESET_SOFTWARE); + break; - /* keep s.remote_bytes from underflowing */ - if (ne2000->remote_bytes > ne2000->DCR.wdsize) - { - if (io_len == 4) - { - ne2000->remote_bytes -= io_len; - } - else - { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - } - else - { - ne2000->remote_bytes = 0; - } + default: + pclog(1, "asic read invalid address %04x\n", (unsigned)off); + break; + } - /* If all bytes have been written, signal remote-DMA complete */ - if (ne2000->remote_bytes == 0) - { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) - { - picint(1 << ne2000->base_irq); - } - } - break; - - case 0xf: /* Reset register */ - ne2000_reset(ne2000, BX_RESET_SOFTWARE); - break; - - default: - ne2000_log("asic read invalid address %04x\n", (unsigned) offset); - break; - } - - return (retval); + return(retval); } -void ne2000_asic_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) + +static void +asic_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) { - ne2000_log("%s: asic write addr=0x%02x, value=0x%04x\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS",(unsigned) offset, (unsigned) value); - switch (offset) - { - case 0x0: /* Data register - see asic_read for a description */ - if ((io_len > 1) && (ne2000->DCR.wdsize == 0)) - { - ne2000_log("dma write length %d on byte mode operation\n", io_len); - break; - } - if (ne2000->remote_bytes == 0) - { - ne2000_log("dma write, byte count 0\n"); - } - - ne2000_chipmem_write(ne2000, ne2000->remote_dma, value, io_len); - if (io_len == 4) - { - ne2000->remote_dma += io_len; - } - else - { - ne2000->remote_dma += (ne2000->DCR.wdsize + 1); - } - - if (ne2000->remote_dma == ne2000->page_stop << 8) - { - ne2000->remote_dma = ne2000->page_start << 8; - } - - if (io_len == 4) - { - ne2000->remote_bytes -= io_len; - } - else - { - ne2000->remote_bytes -= (ne2000->DCR.wdsize + 1); - } - - if (ne2000->remote_bytes > BX_NE2K_MEMSIZ) - { - ne2000->remote_bytes = 0; - } - - /* If all bytes have been written, signal remote-DMA complete */ - if (ne2000->remote_bytes == 0) - { - ne2000->ISR.rdma_done = 1; - if (ne2000->IMR.rdma_inte) - { - picint(1 << ne2000->base_irq); - } - } + pclog(2, "%s: asic write addr=0x%02x, value=0x%04x\n", + (network_card_current==1)?"NE2000":"RTL8029AS",(unsigned)off, (unsigned) val); + switch(off) { + case 0x0: /* Data register - see asic_read for a description */ + if ((len > 1) && (dev->DCR.wdsize == 0)) { + pclog(2, "dma write length %d on byte mode operation\n", + len); break; + } + if (dev->remote_bytes == 0) { + pclog(2, "dma write, byte count 0\n"); + } - case 0xf: /* Reset register */ - /* end of reset pulse */ - break; + chipmem_write(dev, dev->remote_dma, val, len); + if (len == 4) { + dev->remote_dma += len; + } else { + dev->remote_dma += (dev->DCR.wdsize + 1); + } - default: /* this is invalid, but happens under win95 device detection */ - ne2000_log("asic write invalid address %04x, ignoring\n", (unsigned) offset); - break; - } + if (dev->remote_dma == dev->page_stop << 8) { + dev->remote_dma = dev->page_start << 8; + } + + if (len == 4) { + dev->remote_bytes -= len; + } else { + dev->remote_bytes -= (dev->DCR.wdsize + 1); + } + + if (dev->remote_bytes > BX_NE2K_MEMSIZ) { + dev->remote_bytes = 0; + } + + /* If all bytes have been written, signal remote-DMA complete */ + if (dev->remote_bytes == 0) { + dev->ISR.rdma_done = 1; + if (dev->IMR.rdma_inte) { + picint(1 << dev->base_irq); + } + } + break; + + case 0xf: /* Reset register */ + /* end of reset pulse */ + break; + + default: /* this is invalid, but happens under win95 device detection */ + pclog(1, "asic write invalid address %04x, ignoring\n", + (unsigned)off); + break; + } } + /* page0_read/page0_write - These routines handle reads/writes to the 'zeroth' page of the DS8390 register file */ - -uint32_t ne2000_page0_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +static uint32_t +page0_read(ne2000_t *dev, uint32_t off, unsigned int len) { - uint8_t value = 0; + uint8_t retval = 0; - if (io_len > 1) - { - ne2000_log("bad length! page 0 read from register 0x%02x, len=%u\n", offset, io_len); /* encountered with win98 hardware probe */ - return value; - } + if (len > 1) { + /* encountered with win98 hardware probe */ + pclog(1, "bad length! page 0 read from register 0x%02x, len=%u\n", + off, len); + return(retval); + } - switch (offset) - { - case 0x1: /* CLDA0 */ - value = (ne2000->local_dma & 0xff); - break; + switch(off) { + case 0x01: /* CLDA0 */ + retval = (dev->local_dma & 0xff); + break; - case 0x2: /* CLDA1 */ - value = (ne2000->local_dma >> 8); - break; + case 0x02: /* CLDA1 */ + retval = (dev->local_dma >> 8); + break; - case 0x3: /* BNRY */ - value = ne2000->bound_ptr; - break; + case 0x03: /* BNRY */ + retval = dev->bound_ptr; + break; - case 0x4: /* TSR */ - value = ((ne2000->TSR.ow_coll << 7) | - (ne2000->TSR.cd_hbeat << 6) | - (ne2000->TSR.fifo_ur << 5) | - (ne2000->TSR.no_carrier << 4) | - (ne2000->TSR.aborted << 3) | - (ne2000->TSR.collided << 2) | - (ne2000->TSR.tx_ok)); - break; + case 0x04: /* TSR */ + retval = ((dev->TSR.ow_coll << 7) | + (dev->TSR.cd_hbeat << 6) | + (dev->TSR.fifo_ur << 5) | + (dev->TSR.no_carrier << 4) | + (dev->TSR.aborted << 3) | + (dev->TSR.collided << 2) | + (dev->TSR.tx_ok)); + break; - case 0x5: /* NCR */ - value = ne2000->num_coll; - break; + case 0x05: /* NCR */ + retval = dev->num_coll; + break; - case 0x6: /* FIFO */ - /* reading FIFO is only valid in loopback mode */ - ne2000_log("reading FIFO not supported yet\n"); - value = ne2000->fifo; - break; + case 0x06: /* FIFO */ + /* reading FIFO is only valid in loopback mode */ + pclog(1, "reading FIFO not supported yet\n"); + retval = dev->fifo; + break; - case 0x7: /* ISR */ - value = ((ne2000->ISR.reset << 7) | - (ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - break; + case 0x07: /* ISR */ + retval = ((dev->ISR.reset << 7) | + (dev->ISR.rdma_done << 6) | + (dev->ISR.cnt_oflow << 5) | + (dev->ISR.overwrite << 4) | + (dev->ISR.tx_err << 3) | + (dev->ISR.rx_err << 2) | + (dev->ISR.pkt_tx << 1) | + (dev->ISR.pkt_rx)); + break; - case 0x8: /* CRDA0 */ - value = (ne2000->remote_dma & 0xff); - break; + case 0x08: /* CRDA0 */ + retval = (dev->remote_dma & 0xff); + break; - case 0x9: /* CRDA1 */ - value = (ne2000->remote_dma >> 8); - break; + case 0x09: /* CRDA1 */ + retval = (dev->remote_dma >> 8); + break; - case 0xa: /* reserved / RTL8029ID0 */ - if (network_card_current == 2) - { - value = 0x50; - } - else - { - ne2000_log("reserved read - page 0, 0xa\n"); - value = 0xff; - } - break; - - case 0xb: /* reserved / RTL8029ID1 */ - if (network_card_current == 2) - { - value = 0x43; - } - else - { - ne2000_log("reserved read - page 0, 0xb\n"); - value = 0xff; - } - break; - - case 0xc: /* RSR */ - value = ((ne2000->RSR.deferred << 7) | - (ne2000->RSR.rx_disabled << 6) | - (ne2000->RSR.rx_mbit << 5) | - (ne2000->RSR.rx_missed << 4) | - (ne2000->RSR.fifo_or << 3) | - (ne2000->RSR.bad_falign << 2) | - (ne2000->RSR.bad_crc << 1) | - (ne2000->RSR.rx_ok)); - break; - - case 0xd: /* CNTR0 */ - value = ne2000->tallycnt_0; - break; - - case 0xe: /* CNTR1 */ - value = ne2000->tallycnt_1; - break; - - case 0xf: /* CNTR2 */ - value = ne2000->tallycnt_2; - break; - - default: - ne2000_log("page 0 register 0x%02x out of range\n", offset); - break; - } - - ne2000_log("page 0 read from register 0x%02x, value=0x%02x\n", offset, value); - return value; -} - -void ne2000_page0_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - uint8_t value2; - - /* It appears to be a common practice to use outw on page0 regs... */ - - /* break up outw into two outb's */ - if (io_len == 2) - { - ne2000_page0_write(ne2000, offset, (value & 0xff), 1); - if (offset < 0x0f) - { - ne2000_page0_write(ne2000, offset + 1, ((value >> 8) & 0xff), 1); + case 0x0a: /* reserved / RTL8029ID0 */ + if (network_card_current == 2) { + retval = 0x50; + } else { + pclog(1, "reserved read - page 0, 0x0a\n"); + retval = 0xff; } - return; - } + break; - ne2000_log("page 0 write to register 0x%02x, value=0x%02x\n", offset, value); + case 0x0b: /* reserved / RTL8029ID1 */ + if (network_card_current == 2) { + retval = 0x43; + } else { + pclog(1, "reserved read - page 0, 0xb\n"); + retval = 0xff; + } + break; - switch (offset) - { - case 0x1: /* PSTART */ - ne2000->page_start = value; - break; + case 0x0c: /* RSR */ + retval = ((dev->RSR.deferred << 7) | + (dev->RSR.rx_disabled << 6) | + (dev->RSR.rx_mbit << 5) | + (dev->RSR.rx_missed << 4) | + (dev->RSR.fifo_or << 3) | + (dev->RSR.bad_falign << 2) | + (dev->RSR.bad_crc << 1) | + (dev->RSR.rx_ok)); + break; - case 0x2: /* PSTOP */ - ne2000->page_stop = value; - break; + case 0x0d: /* CNTR0 */ + retval = dev->tallycnt_0; + break; - case 0x3: /* BNRY */ - ne2000->bound_ptr = value; - break; + case 0x0e: /* CNTR1 */ + retval = dev->tallycnt_1; + break; - case 0x4: /* TPSR */ - ne2000->tx_page_start = value; - break; + case 0x0f: /* CNTR2 */ + retval = dev->tallycnt_2; + break; - case 0x5: /* TBCR0 */ - /* Clear out low byte and re-insert */ - ne2000->tx_bytes &= 0xff00; - ne2000->tx_bytes |= (value & 0xff); - break; + default: + pclog(1, "page 0 register 0x%02x out of range\n", off); + break; + } - case 0x6: /* TBCR1 */ - /* Clear out high byte and re-insert */ - ne2000->tx_bytes &= 0x00ff; - ne2000->tx_bytes |= ((value & 0xff) << 8); - break; + pclog(2, "page 0 read from register 0x%02x, value=0x%02x\n", off, retval); - case 0x7: /* ISR */ - value &= 0x7f; /* clear RST bit - status-only bit */ - /* All other values are cleared iff the ISR bit is 1 */ - ne2000->ISR.pkt_rx &= ~((int)((value & 0x01) == 0x01)); - ne2000->ISR.pkt_tx &= ~((int)((value & 0x02) == 0x02)); - ne2000->ISR.rx_err &= ~((int)((value & 0x04) == 0x04)); - ne2000->ISR.tx_err &= ~((int)((value & 0x08) == 0x08)); - ne2000->ISR.overwrite &= ~((int)((value & 0x10) == 0x10)); - ne2000->ISR.cnt_oflow &= ~((int)((value & 0x20) == 0x20)); - ne2000->ISR.rdma_done &= ~((int)((value & 0x40) == 0x40)); - value = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - value &= ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); - if (value == 0) - { - picintc(1 << ne2000->base_irq); - } - break; - - case 0x8: /* RSAR0 */ - /* Clear out low byte and re-insert */ - ne2000->remote_start &= 0xff00; - ne2000->remote_start |= (value & 0xff); - ne2000->remote_dma = ne2000->remote_start; - break; - - case 0x9: /* RSAR1 */ - /* Clear out high byte and re-insert */ - ne2000->remote_start &= 0x00ff; - ne2000->remote_start |= ((value & 0xff) << 8); - ne2000->remote_dma = ne2000->remote_start; - break; - - case 0xa: /* RBCR0 */ - /* Clear out low byte and re-insert */ - ne2000->remote_bytes &= 0xff00; - ne2000->remote_bytes |= (value & 0xff); - break; - - case 0xb: /* RBCR1 */ - /* Clear out high byte and re-insert */ - ne2000->remote_bytes &= 0x00ff; - ne2000->remote_bytes |= ((value & 0xff) << 8); - break; - - case 0xc: /* RCR */ - /* Check if the reserved bits are set */ - if (value & 0xc0) - { - ne2000_log("RCR write, reserved bits set\n"); - } - - /* Set all other bit-fields */ - ne2000->RCR.errors_ok = ((value & 0x01) == 0x01); - ne2000->RCR.runts_ok = ((value & 0x02) == 0x02); - ne2000->RCR.broadcast = ((value & 0x04) == 0x04); - ne2000->RCR.multicast = ((value & 0x08) == 0x08); - ne2000->RCR.promisc = ((value & 0x10) == 0x10); - ne2000->RCR.monitor = ((value & 0x20) == 0x20); - - /* Monitor bit is a little suspicious... */ - if (value & 0x20) - { - ne2000_log("RCR write, monitor bit set!\n"); - } - break; - - case 0xd: /* TCR */ - /* Check reserved bits */ - if (value & 0xe0) - { - ne2000_log("TCR write, reserved bits set\n"); - } - - /* Test loop mode (not supported) */ - if (value & 0x06) - { - ne2000->TCR.loop_cntl = (value & 0x6) >> 1; - ne2000_log("TCR write, loop mode %d not supported\n", ne2000->TCR.loop_cntl); - } - else - { - ne2000->TCR.loop_cntl = 0; - } - - /* Inhibit-CRC not supported. */ - if (value & 0x01) - { - ne2000_log("TCR write, inhibit-CRC not supported\n"); - } - - /* Auto-transmit disable very suspicious */ - if (value & 0x08) - { - ne2000_log("TCR write, auto transmit disable not supported\n"); - } - - /* Allow collision-offset to be set, although not used */ - ne2000->TCR.coll_prio = ((value & 0x08) == 0x08); - break; - - case 0xe: /* DCR */ - /* the loopback mode is not suppported yet */ - if (!(value & 0x08)) - { - ne2000_log("DCR write, loopback mode selected\n"); - } - /* It is questionable to set longaddr and auto_rx, since they - aren't supported on the ne2000. Print a warning and continue */ - if (value & 0x04) - { - ne2000_log("DCR write - LAS set ???\n"); - } - if (value & 0x10) - { - ne2000_log("DCR write - AR set ???\n"); - } - - /* Set other values. */ - ne2000->DCR.wdsize = ((value & 0x01) == 0x01); - ne2000->DCR.endian = ((value & 0x02) == 0x02); - ne2000->DCR.longaddr = ((value & 0x04) == 0x04); /* illegal ? */ - ne2000->DCR.loop = ((value & 0x08) == 0x08); - ne2000->DCR.auto_rx = ((value & 0x10) == 0x10); /* also illegal ? */ - ne2000->DCR.fifo_size = (value & 0x50) >> 5; - break; - - case 0xf: /* IMR */ - /* Check for reserved bit */ - if (value & 0x80) - { - ne2000_log("IMR write, reserved bit set\n"); - } - - /* Set other values */ - ne2000->IMR.rx_inte = ((value & 0x01) == 0x01); - ne2000->IMR.tx_inte = ((value & 0x02) == 0x02); - ne2000->IMR.rxerr_inte = ((value & 0x04) == 0x04); - ne2000->IMR.txerr_inte = ((value & 0x08) == 0x08); - ne2000->IMR.overw_inte = ((value & 0x10) == 0x10); - ne2000->IMR.cofl_inte = ((value & 0x20) == 0x20); - ne2000->IMR.rdma_inte = ((value & 0x40) == 0x40); - value2 = ((ne2000->ISR.rdma_done << 6) | - (ne2000->ISR.cnt_oflow << 5) | - (ne2000->ISR.overwrite << 4) | - (ne2000->ISR.tx_err << 3) | - (ne2000->ISR.rx_err << 2) | - (ne2000->ISR.pkt_tx << 1) | - (ne2000->ISR.pkt_rx)); - if (((value & value2) & 0x7f) == 0) - { - picintc(1 << ne2000->base_irq); - } - else - { - picint(1 << ne2000->base_irq); - } - break; - - default: - ne2000_log("page 0 write, bad register 0x%02x\n", offset); - break; - } + return(retval); } + +static void +page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + uint8_t val2; + + /* It appears to be a common practice to use outw on page0 regs... */ + + /* break up outw into two outb's */ + if (len == 2) { + page0_write(dev, off, (val & 0xff), 1); + if (off < 0x0f) + page0_write(dev, off+1, ((val>>8)&0xff), 1); + return; + } + + pclog(2, "page 0 write to register 0x%02x, value=0x%02x\n", off, val); + + switch(off) { + case 0x01: /* PSTART */ + dev->page_start = val; + break; + + case 0x02: /* PSTOP */ + dev->page_stop = val; + break; + + case 0x03: /* BNRY */ + dev->bound_ptr = val; + break; + + case 0x04: /* TPSR */ + dev->tx_page_start = val; + break; + + case 0x05: /* TBCR0 */ + /* Clear out low byte and re-insert */ + dev->tx_bytes &= 0xff00; + dev->tx_bytes |= (val & 0xff); + break; + + case 0x06: /* TBCR1 */ + /* Clear out high byte and re-insert */ + dev->tx_bytes &= 0x00ff; + dev->tx_bytes |= ((val & 0xff) << 8); + break; + + case 0x07: /* ISR */ + val &= 0x7f; /* clear RST bit - status-only bit */ + /* All other values are cleared iff the ISR bit is 1 */ + dev->ISR.pkt_rx &= ~((int)((val & 0x01) == 0x01)); + dev->ISR.pkt_tx &= ~((int)((val & 0x02) == 0x02)); + dev->ISR.rx_err &= ~((int)((val & 0x04) == 0x04)); + dev->ISR.tx_err &= ~((int)((val & 0x08) == 0x08)); + dev->ISR.overwrite &= ~((int)((val & 0x10) == 0x10)); + dev->ISR.cnt_oflow &= ~((int)((val & 0x20) == 0x20)); + dev->ISR.rdma_done &= ~((int)((val & 0x40) == 0x40)); + val = ((dev->ISR.rdma_done << 6) | + (dev->ISR.cnt_oflow << 5) | + (dev->ISR.overwrite << 4) | + (dev->ISR.tx_err << 3) | + (dev->ISR.rx_err << 2) | + (dev->ISR.pkt_tx << 1) | + (dev->ISR.pkt_rx)); + val &= ((dev->IMR.rdma_inte << 6) | + (dev->IMR.cofl_inte << 5) | + (dev->IMR.overw_inte << 4) | + (dev->IMR.txerr_inte << 3) | + (dev->IMR.rxerr_inte << 2) | + (dev->IMR.tx_inte << 1) | + (dev->IMR.rx_inte)); + if (val == 0x00) { + picintc(1 << dev->base_irq); + } + break; + + case 0x08: /* RSAR0 */ + /* Clear out low byte and re-insert */ + dev->remote_start &= 0xff00; + dev->remote_start |= (val & 0xff); + dev->remote_dma = dev->remote_start; + break; + + case 0x09: /* RSAR1 */ + /* Clear out high byte and re-insert */ + dev->remote_start &= 0x00ff; + dev->remote_start |= ((val & 0xff) << 8); + dev->remote_dma = dev->remote_start; + break; + + case 0x0a: /* RBCR0 */ + /* Clear out low byte and re-insert */ + dev->remote_bytes &= 0xff00; + dev->remote_bytes |= (val & 0xff); + break; + + case 0x0b: /* RBCR1 */ + /* Clear out high byte and re-insert */ + dev->remote_bytes &= 0x00ff; + dev->remote_bytes |= ((val & 0xff) << 8); + break; + + case 0x0c: /* RCR */ + /* Check if the reserved bits are set */ + if (val & 0xc0) { + pclog(1, "RCR write, reserved bits set\n"); + } + + /* Set all other bit-fields */ + dev->RCR.errors_ok = ((val & 0x01) == 0x01); + dev->RCR.runts_ok = ((val & 0x02) == 0x02); + dev->RCR.broadcast = ((val & 0x04) == 0x04); + dev->RCR.multicast = ((val & 0x08) == 0x08); + dev->RCR.promisc = ((val & 0x10) == 0x10); + dev->RCR.monitor = ((val & 0x20) == 0x20); + + /* Monitor bit is a little suspicious... */ + if (val & 0x20) { + pclog(1, "RCR write, monitor bit set!\n"); + } + break; + + case 0x0d: /* TCR */ + /* Check reserved bits */ + if (val & 0xe0) { + pclog(1, "TCR write, reserved bits set\n"); + } + + /* Test loop mode (not supported) */ + if (val & 0x06) { + dev->TCR.loop_cntl = (val & 0x6) >> 1; + pclog(1, "TCR write, loop mode %d not supported\n", + dev->TCR.loop_cntl); + } else { + dev->TCR.loop_cntl = 0; + } + + /* Inhibit-CRC not supported. */ + if (val & 0x01) { + pclog(1, "TCR write, inhibit-CRC not supported\n"); + } + + /* Auto-transmit disable very suspicious */ + if (val & 0x08) { + pclog(1, "TCR write, auto transmit disable not supported\n"); + } + + /* Allow collision-offset to be set, although not used */ + dev->TCR.coll_prio = ((val & 0x08) == 0x08); + break; + + case 0x0e: /* DCR */ + /* the loopback mode is not suppported yet */ + if (! (val & 0x08)) { + pclog(1, "DCR write, loopback mode selected\n"); + } + + /* It is questionable to set longaddr and auto_rx, since + * they are not supported on the NE2000. Print a warning + * and continue. */ + if (val & 0x04) { + pclog(1, "DCR write - LAS set ???\n"); + } + if (val & 0x10) { + pclog(1, "DCR write - AR set ???\n"); + } + + /* Set other values. */ + dev->DCR.wdsize = ((val & 0x01) == 0x01); + dev->DCR.endian = ((val & 0x02) == 0x02); + dev->DCR.longaddr = ((val & 0x04) == 0x04); /* illegal ? */ + dev->DCR.loop = ((val & 0x08) == 0x08); + dev->DCR.auto_rx = ((val & 0x10) == 0x10); /* also illegal ? */ + dev->DCR.fifo_size = (val & 0x50) >> 5; + break; + + case 0x0f: /* IMR */ + /* Check for reserved bit */ + if (val & 0x80) { + pclog(1, "IMR write, reserved bit set\n"); + } + + /* Set other values */ + dev->IMR.rx_inte = ((val & 0x01) == 0x01); + dev->IMR.tx_inte = ((val & 0x02) == 0x02); + dev->IMR.rxerr_inte = ((val & 0x04) == 0x04); + dev->IMR.txerr_inte = ((val & 0x08) == 0x08); + dev->IMR.overw_inte = ((val & 0x10) == 0x10); + dev->IMR.cofl_inte = ((val & 0x20) == 0x20); + dev->IMR.rdma_inte = ((val & 0x40) == 0x40); + val2 = ((dev->ISR.rdma_done << 6) | + (dev->ISR.cnt_oflow << 5) | + (dev->ISR.overwrite << 4) | + (dev->ISR.tx_err << 3) | + (dev->ISR.rx_err << 2) | + (dev->ISR.pkt_tx << 1) | + (dev->ISR.pkt_rx)); + if (((val & val2) & 0x7f) == 0) { + picintc(1 << dev->base_irq); + } else { + picint(1 << dev->base_irq); + } + break; + + default: + pclog(1, "page 0 write, bad register 0x%02x\n", off); + break; + } +} + + /* page1_read/page1_write - These routines handle reads/writes to the first page of the DS8390 register file */ - -uint32_t ne2000_page1_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +static uint32_t +page1_read(ne2000_t *dev, uint32_t off, unsigned int len) { - ne2000_log("page 1 read from register 0x%02x, len=%u\n", offset, io_len); + pclog(2, "page 1 read from register 0x%02x, len=%u\n", off, len); - switch (offset) - { - case 0x1: /* PAR0-5 */ - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - return (ne2000->physaddr[offset - 1]); + switch(off) { + case 0x01: /* PAR0-5 */ + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + return(dev->physaddr[off - 1]); - case 0x7: /* CURR */ - ne2000_log("returning current page: 0x%02x\n", (ne2000->curr_page)); - return (ne2000->curr_page); + case 0x07: /* CURR */ + pclog(2, "returning current page: 0x%02x\n", (dev->curr_page)); + return(dev->curr_page); - case 0x8: /* MAR0-7 */ - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - return (ne2000->mchash[offset - 8]); + case 0x08: /* MAR0-7 */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + return(dev->mchash[off - 8]); - default: - ne2000_log("page 1 read register 0x%02x out of range\n", offset); - return 0; - } + default: + pclog(1, "page 1 read register 0x%02x out of range\n", off); + return(0); + } } -void ne2000_page1_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) + +static void +page1_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) { - ne2000_log("page 1 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); + pclog(2, "page 1 write to register 0x%02x, len=%u, value=0x%04x\n", + off, len, val); - switch (offset) - { - case 0x1: /* PAR0-5 */ - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - ne2000->physaddr[offset - 1] = value; - if (offset == 6) - { - ne2000_log("Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", ne2000->physaddr[0], ne2000->physaddr[1], ne2000->physaddr[2], ne2000->physaddr[3], ne2000->physaddr[4], ne2000->physaddr[5]); - } - break; + switch(off) { + case 0x01: /* PAR0-5 */ + case 0x02: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + dev->physaddr[off - 1] = val; + if (off == 6) { + pclog(1, "Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->physaddr[0], dev->physaddr[1], + dev->physaddr[2], dev->physaddr[3], + dev->physaddr[4], dev->physaddr[5]); + } + break; - case 0x7: /* CURR */ - ne2000->curr_page = value; - break; + case 0x07: /* CURR */ + dev->curr_page = val; + break; - case 0x8: /* MAR0-7 */ - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000->mchash[offset - 8] = value; - break; + case 0x08: /* MAR0-7 */ + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + dev->mchash[off - 8] = val; + break; - default: - ne2000_log("page 1 write register 0x%02x out of range\n", offset); - break; - } + default: + pclog(1, "page 1 write register 0x%02x out of range\n", off); + break; + } } + /* page2_read/page2_write - These routines handle reads/writes to the second page of the DS8390 register file */ - -uint32_t ne2000_page2_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +static uint32_t +page2_read(ne2000_t *dev, uint32_t off, unsigned int len) { - ne2000_log("page 2 read from register 0x%02x, len=%u\n", offset, io_len); + pclog(2, "page 2 read from register 0x%02x, len=%u\n", off, len); - switch (offset) - { - case 0x1: /* PSTART */ - return (ne2000->page_start); + switch(off) { + case 0x01: /* PSTART */ + return(dev->page_start); - case 0x2: /* PSTOP */ - return (ne2000->page_stop); + case 0x02: /* PSTOP */ + return(dev->page_stop); - case 0x3: /* Remote Next-packet pointer */ - return (ne2000->rempkt_ptr); + case 0x03: /* Remote Next-packet pointer */ + return(dev->rempkt_ptr); - case 0x4: /* TPSR */ - return (ne2000->tx_page_start); + case 0x04: /* TPSR */ + return(dev->tx_page_start); - case 0x5: /* Local Next-packet pointer */ - return (ne2000->localpkt_ptr); + case 0x05: /* Local Next-packet pointer */ + return(dev->localpkt_ptr); - case 0x6: /* Address counter (upper) */ - return (ne2000->address_cnt >> 8); + case 0x06: /* Address counter (upper) */ + return(dev->address_cnt >> 8); - case 0x7: /* Address counter (lower) */ - return (ne2000->address_cnt & 0xff); + case 0x07: /* Address counter (lower) */ + return(dev->address_cnt & 0xff); - case 0x8: /* Reserved */ - case 0x9: - case 0xa: - case 0xb: - ne2000_log("reserved read - page 2, register 0x%02x\n", offset); - return (0xff); + case 0x08: /* Reserved */ + case 0x09: + case 0x0a: + case 0x0b: + pclog(1, "reserved read - page 2, register 0x%02x\n", off); + return(0xff); - case 0xc: /* RCR */ - return ((ne2000->RCR.monitor << 5) | - (ne2000->RCR.promisc << 4) | - (ne2000->RCR.multicast << 3) | - (ne2000->RCR.broadcast << 2) | - (ne2000->RCR.runts_ok << 1) | - (ne2000->RCR.errors_ok)); + case 0x0c: /* RCR */ + return ((dev->RCR.monitor << 5) | + (dev->RCR.promisc << 4) | + (dev->RCR.multicast << 3) | + (dev->RCR.broadcast << 2) | + (dev->RCR.runts_ok << 1) | + (dev->RCR.errors_ok)); - case 0xd: /* TCR */ - return ((ne2000->TCR.coll_prio << 4) | - (ne2000->TCR.ext_stoptx << 3) | - ((ne2000->TCR.loop_cntl & 0x3) << 1) | - (ne2000->TCR.crc_disable)); + case 0x0d: /* TCR */ + return ((dev->TCR.coll_prio << 4) | + (dev->TCR.ext_stoptx << 3) | + ((dev->TCR.loop_cntl & 0x3) << 1) | + (dev->TCR.crc_disable)); - case 0xe: /* DCR */ - return (((ne2000->DCR.fifo_size & 0x3) << 5) | - (ne2000->DCR.auto_rx << 4) | - (ne2000->DCR.loop << 3) | - (ne2000->DCR.longaddr << 2) | - (ne2000->DCR.endian << 1) | - (ne2000->DCR.wdsize)); + case 0x0e: /* DCR */ + return (((dev->DCR.fifo_size & 0x3) << 5) | + (dev->DCR.auto_rx << 4) | + (dev->DCR.loop << 3) | + (dev->DCR.longaddr << 2) | + (dev->DCR.endian << 1) | + (dev->DCR.wdsize)); - case 0xf: /* IMR */ - return ((ne2000->IMR.rdma_inte << 6) | - (ne2000->IMR.cofl_inte << 5) | - (ne2000->IMR.overw_inte << 4) | - (ne2000->IMR.txerr_inte << 3) | - (ne2000->IMR.rxerr_inte << 2) | - (ne2000->IMR.tx_inte << 1) | - (ne2000->IMR.rx_inte)); + case 0x0f: /* IMR */ + return ((dev->IMR.rdma_inte << 6) | + (dev->IMR.cofl_inte << 5) | + (dev->IMR.overw_inte << 4) | + (dev->IMR.txerr_inte << 3) | + (dev->IMR.rxerr_inte << 2) | + (dev->IMR.tx_inte << 1) | + (dev->IMR.rx_inte)); - default: - ne2000_log("page 2 register 0x%02x out of range\n", offset); - break; - } + default: + pclog(1, "page 2 register 0x%02x out of range\n", off); + break; + } - return (0); + return(0); } -void ne2000_page2_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) + +static void +page2_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) { - /* Maybe all writes here should be BX_PANIC()'d, since they - affect internal operation, but let them through for now - and print a warning. */ - ne2000_log("page 2 write to register 0x%02x, len=%u, value=0x%04x\n", offset, io_len, value); +/* Maybe all writes here should be BX_PANIC()'d, since they + affect internal operation, but let them through for now + and print a warning. */ + pclog(2, "page 2 write to register 0x%02x, len=%u, value=0x%04x\n", + off, len, val); + switch(off) { + case 0x01: /* CLDA0 */ + /* Clear out low byte and re-insert */ + dev->local_dma &= 0xff00; + dev->local_dma |= (val & 0xff); + break; - switch (offset) - { - case 0x1: /* CLDA0 */ - /* Clear out low byte and re-insert */ - ne2000->local_dma &= 0xff00; - ne2000->local_dma |= (value & 0xff); - break; + case 0x02: /* CLDA1 */ + /* Clear out high byte and re-insert */ + dev->local_dma &= 0x00ff; + dev->local_dma |= ((val & 0xff) << 8); + break; - case 0x2: /* CLDA1 */ - /* Clear out high byte and re-insert */ - ne2000->local_dma &= 0x00ff; - ne2000->local_dma |= ((value & 0xff) << 8); - break; + case 0x03: /* Remote Next-pkt pointer */ + dev->rempkt_ptr = val; + break; - case 0x3: /* Remote Next-pkt pointer */ - ne2000->rempkt_ptr = value; - break; + case 0x04: + pclog(1, "page 2 write to reserved register 0x04\n"); + break; - case 0x4: - ne2000_log("page 2 write to reserved register 0x04\n"); - break; + case 0x05: /* Local Next-packet pointer */ + dev->localpkt_ptr = val; + break; - case 0x5: /* Local Next-packet pointer */ - ne2000->localpkt_ptr = value; - break; + case 0x06: /* Address counter (upper) */ + /* Clear out high byte and re-insert */ + dev->address_cnt &= 0x00ff; + dev->address_cnt |= ((val & 0xff) << 8); + break; - case 0x6: /* Address counter (upper) */ - /* Clear out high byte and re-insert */ - ne2000->address_cnt &= 0x00ff; - ne2000->address_cnt |= ((value & 0xff) << 8); - break; + case 0x07: /* Address counter (lower) */ + /* Clear out low byte and re-insert */ + dev->address_cnt &= 0xff00; + dev->address_cnt |= (val & 0xff); + break; - case 0x7: /* Address counter (lower) */ - /* Clear out low byte and re-insert */ - ne2000->address_cnt &= 0xff00; - ne2000->address_cnt |= (value & 0xff); - break; + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x0e: + case 0x0f: + pclog(1, "page 2 write to reserved register 0x%02x\n", off); + break; - case 0x8: - case 0x9: - case 0xa: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - ne2000_log("page 2 write to reserved register 0x%02x\n", offset); - break; - - default: - ne2000_log("page 2 write, illegal register 0x%02x\n", offset); - break; - } + default: + pclog(1, "page 2 write, illegal register 0x%02x\n", off); + break; + } } + /* page3_read/page3_write - writes to this page are illegal */ - -uint32_t ne2000_page3_read(ne2000_t *ne2000, uint32_t offset, unsigned int io_len) +static uint32_t +page3_read(ne2000_t *dev, uint32_t off, unsigned int len) { + if (network_card_current == 2) switch(off) { + case 0x3: /* CONFIG0 */ + return(0x00); + + case 0x5: /* CONFIG2 */ + return(0x40); + + case 0x6: /* CONFIG3 */ + return(0x40); + + default: + break; + } + + pclog(1, "page 3 read register 0x%02x attempted\n", off); + return(0x00); +} + + +static void +page3_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +{ + pclog(1, "page 3 write register 0x%02x attempted\n", off); +} + + +/* read_cr/write_cr - utility routines for handling reads/writes to + the Command Register */ +static uint32_t +read_cr(ne2000_t *dev) +{ + uint32_t retval; + + retval = (((dev->CR.pgsel & 0x03) << 6) | + ((dev->CR.rdma_cmd & 0x07) << 3) | + (dev->CR.tx_packet << 2) | + (dev->CR.start << 1) | + (dev->CR.stop)); + pclog(2, "%s: read CR returns 0x%02x\n", + (network_card_current==1)?"NE2000":"RTL8029AS", retval); + + return(retval); +} + + +static void +write_cr(ne2000_t *dev, uint32_t val) +{ + pclog(2, "%s: wrote 0x%02x to CR\n", + (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); + + /* Validate remote-DMA */ + if ((val & 0x38) == 0x00) { + pclog(1, "CR write - invalid rDMA value 0\n"); + val |= 0x20; /* dma_cmd == 4 is a safe default */ + } + + /* Check for s/w reset */ + if (val & 0x01) { + dev->ISR.reset = 1; + dev->CR.stop = 1; + } else { + dev->CR.stop = 0; + } + + dev->CR.rdma_cmd = (val & 0x38) >> 3; + + /* If start command issued, the RST bit in the ISR */ + /* must be cleared */ + if ((val & 0x02) && !dev->CR.start) { + dev->ISR.reset = 0; + } + + dev->CR.start = ((val & 0x02) == 0x02); + dev->CR.pgsel = (val & 0xc0) >> 6; + + /* Check for send-packet command */ + if (dev->CR.rdma_cmd == 3) { + /* Set up DMA read from receive ring */ + dev->remote_start = dev->remote_dma = dev->bound_ptr * 256; + dev->remote_bytes = (uint16_t) chipmem_read(dev, dev->bound_ptr * 256 + 2, 2); + pclog(2, "Sending buffer #x%x length %d\n", dev->remote_start, dev->remote_bytes); + } + + /* Check for start-tx */ + if ((val & 0x04) && dev->TCR.loop_cntl) { + if (dev->TCR.loop_cntl != 1) { + pclog(1, "Loop mode %d not supported\n", dev->TCR.loop_cntl); + } else { + ne2000_rx_frame(dev, &dev->mem[dev->tx_page_start*256 - BX_NE2K_MEMSTART], dev->tx_bytes); + } + } else if (val & 0x04) { + if (dev->CR.stop || (!dev->CR.start && (network_card_current == 1))) { + if (dev->tx_bytes == 0) /* njh@bandsman.co.uk */ { + return; /* Solaris9 probe */ + } + pclog(1, "CR write - tx start, dev in reset\n"); + } + + if (dev->tx_bytes == 0) { + pclog(1, "CR write - tx start, tx bytes == 0\n"); + } + + /* Send the packet to the system driver */ + dev->CR.tx_packet = 1; + if (! net_is_pcap) { + slirp_input(&dev->mem[dev->tx_page_start*256 - BX_NE2K_MEMSTART], dev->tx_bytes); + pclog(1, "ne2000 slirp sending packet\n"); + } else if (net_is_pcap && (net_pcap != NULL)) { + pcap_sendpacket(net_pcap, &dev->mem[dev->tx_page_start*256 - BX_NE2K_MEMSTART], dev->tx_bytes); + pclog(1, "ne2000 pcap sending packet\n"); + } + + /* some more debug */ + if (dev->tx_timer_active) { + pclog(1, "CR write, tx timer still active\n"); + } + + ne2000_tx_event(dev, val); + } + + /* Linux probes for an interrupt by setting up a remote-DMA read + * of 0 bytes with remote-DMA completion interrupts enabled. + * Detect this here */ + if (dev->CR.rdma_cmd == 0x01 && dev->CR.start && dev->remote_bytes == 0) { + dev->ISR.rdma_done = 1; + if (dev->IMR.rdma_inte) { + picint(1 << dev->base_irq); + if (network_card_current == 1) { + picintc(1 << dev->base_irq); + } + } + } +} + + +static uint32_t +ne2000_read(ne2000_t *dev, uint32_t addr, unsigned len) +{ + uint32_t retval = 0; + int off = addr - dev->base_address; + + pclog(2, "%s: read addr %x, len %d\n", + (network_card_current==1)?"NE2000":"RTL8029AS", addr, len); + + if (off >= 0x10) { + retval = asic_read(dev, off - 0x10, len); + } else if (off == 0x00) { + retval = read_cr(dev); + } else switch(dev->CR.pgsel) { + case 0x00: + retval = page0_read(dev, off, len); + break; + + case 0x01: + retval = page1_read(dev, off, len); + break; + + case 0x02: + retval = page2_read(dev, off, len); + break; + + case 0x03: + retval = page3_read(dev, off, len); + break; + + default: + pclog(1, "unknown value of pgsel in read - %d\n", dev->CR.pgsel); + break; + } + + return(retval); +} + + +static uint8_t +ne2000_readb(uint16_t addr, void *priv) +{ + return(ne2000_read((ne2000_t *)priv, addr, 1)); +} + + +static uint16_t +ne2000_readw(uint16_t addr, void *priv) +{ + ne2000_t *dev = (ne2000_t *)priv; + + if (dev->DCR.wdsize & 1) + return(ne2000_read(dev, addr, 2)); + else + return(ne2000_read(dev, addr, 1)); +} + + +static uint32_t +ne2000_readl(uint16_t addr, void *priv) +{ + return(ne2000_read((ne2000_t *)priv, addr, 4)); +} + + +static void +ne2000_write(ne2000_t *dev, uint32_t addr, uint32_t val, unsigned len) +{ + int off = addr - dev->base_address; + + pclog(2, "%s: write addr %x, value %x len %d\n", + (network_card_current==1)?"NE2000":"RTL8029AS", addr, val, len); + + /* The high 16 bytes of i/o space are for the ne2000 asic - + the low 16 bytes are for the DS8390, with the current + page being selected by the PS0,PS1 registers in the + command register */ + if (off >= 0x10) { + asic_write(dev, off - 0x10, val, len); + } else if (off == 0x00) { + write_cr(dev, val); + } else switch(dev->CR.pgsel) { + case 0x00: + page0_write(dev, off, val, len); + break; + + case 0x01: + page1_write(dev, off, val, len); + break; + + case 0x02: + page2_write(dev, off, val, len); + break; + + case 0x03: + page3_write(dev, off, val, len); + break; + + default: + pclog(1, "unknown value of pgsel in write - %d\n", dev->CR.pgsel); + break; + } +} + + +static void +ne2000_writeb(uint16_t addr, uint8_t val, void *priv) +{ + ne2000_write((ne2000_t *)priv, addr, val, 1); +} + + +static void +ne2000_writew(uint16_t addr, uint16_t val, void *priv) +{ + ne2000_t *dev = (ne2000_t *)priv; + + if (dev->DCR.wdsize & 1) + ne2000_write(dev, addr, val, 2); + else + ne2000_write(dev, addr, val, 1); +} + + +static void +ne2000_writel(uint16_t addr, uint32_t val, void *priv) +{ + ne2000_write((ne2000_t *)priv, addr, val, 4); +} + + +static void +ne2000_ioset(uint16_t addr, ne2000_t *dev) +{ + old_base_addr = addr; + + if (network_card_current == 1) { + io_sethandler(addr, 16, + ne2000_readb, NULL, NULL, + ne2000_writeb, NULL, NULL, dev); + io_sethandler(addr+16, 16, + ne2000_readb, ne2000_readw, NULL, + ne2000_writeb, ne2000_writew, NULL, dev); + io_sethandler(addr+0x1f, 1, + ne2000_readb, NULL, NULL, + ne2000_writeb, NULL, NULL, dev); + } else { + io_sethandler(addr, 16, + ne2000_readb, ne2000_readw, ne2000_readl, + ne2000_writeb, ne2000_writew, ne2000_writel, dev); + io_sethandler(addr+16, 16, + ne2000_readb, ne2000_readw, ne2000_readl, + ne2000_writeb, ne2000_writew, ne2000_writel, dev); + io_sethandler(addr+0x1f, 1, + ne2000_readb, ne2000_readw, ne2000_readl, + ne2000_writeb, ne2000_writew, ne2000_writel, dev); + } +} + + +static void +ne2000_ioremove(int16_t addr, ne2000_t *dev) +{ + if (network_card_current == 1) { + io_removehandler(addr, 16, + ne2000_readb, NULL, NULL, + ne2000_writeb, NULL, NULL, dev); + io_removehandler(addr+16, 16, + ne2000_readb, ne2000_readw, NULL, + ne2000_writeb, ne2000_writew, NULL, dev); + io_removehandler(addr+0x1f, 1, + ne2000_readb, NULL, NULL, + ne2000_writeb, NULL, NULL, dev); + } else { + io_removehandler(addr, 16, + ne2000_readb, ne2000_readw, ne2000_readl, + ne2000_writeb, ne2000_writew, ne2000_writel, dev); + io_removehandler(addr+16, 16, + ne2000_readb, ne2000_readw, ne2000_readl, + ne2000_writeb, ne2000_writew, ne2000_writel, dev); + io_removehandler(addr+0x1f, 1, + ne2000_readb, ne2000_readw, ne2000_readl, + ne2000_writeb, ne2000_writew, ne2000_writel, dev); + } +} + + +static void +ne2000_update_bios(ne2000_t *dev) +{ + int reg_bios_enable; + + reg_bios_enable = 1; + + /* PCI BIOS stuff, just enable_disable. */ + if (!disable_netbios && reg_bios_enable) { + mem_mapping_enable(&dev->bios_rom.mapping); + mem_mapping_set_addr(&dev->bios_rom.mapping, bios_addr, 0x10000); + pclog(1, "NE2000 BIOS now at: %08X\n", bios_addr); + } else { + mem_mapping_disable(&dev->bios_rom.mapping); if (network_card_current == 2) - { - switch (offset) - { - case 0x3: /* CONFIG0 */ - return (0); - case 0x5: /* CONFIG2 */ - return (0x40); - case 0x6: /* CONFIG3 */ - return (0x40); - default: - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); + pci_bar[1].addr = 0; + } +} + + +static uint8_t +ne2000_pci_read(int func, int addr, void *priv) +{ + switch(addr) { + case 0x00: + return 0xec; + case 0x01: + return 0x10; + + case 0x02: + return 0x29; + case 0x03: + return 0x80; + + case 0x2C: + return 0xF4; + case 0x2D: + return 0x1A; + case 0x2E: + return 0x00; + case 0x2F: + return 0x11; + + case 0x04: + return pci_regs[0x04]; /*Respond to IO and memory accesses*/ + case 0x05: + return pci_regs[0x05]; + + case 0x07: + return 2; + + case 0x08: + return 0; /*Revision ID*/ + case 0x09: + return 0; /*Programming interface*/ + + case 0x0B: + return pci_regs[0x0B]; + + case 0x10: + return 1; /*I/O space*/ + case 0x11: + return pci_bar[0].addr_regs[1]; + case 0x12: + return pci_bar[0].addr_regs[2]; + case 0x13: + return pci_bar[0].addr_regs[3]; + + case 0x30: + return pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ + case 0x31: + return (pci_bar[1].addr_regs[1] & bios_mask) | 0x18; + case 0x32: + return pci_bar[1].addr_regs[2]; + case 0x33: + return pci_bar[1].addr_regs[3]; + + case 0x3C: + return pci_regs[0x3C]; + case 0x3D: + return pci_regs[0x3D]; + } + + return 0; +} + + +static void +ne2000_pci_write(int func, int addr, uint8_t val, void *priv) +{ + ne2000_t *dev = (ne2000_t *)priv; + + switch(addr) { + case 0x04: + ne2000_ioremove(dev->base_address, dev); + if (val & PCI_COMMAND_IO) { + ne2000_ioset(dev->base_address, dev); } - } - else - { - ne2000_log("page 3 read register 0x%02x attempted\n", offset); - return (0); - } -} + pci_regs[addr] = val; + break; -void ne2000_page3_write(ne2000_t *ne2000, uint32_t offset, uint32_t value, unsigned io_len) -{ - ne2000_log("page 3 write register 0x%02x attempted\n", offset); - return; -} + case 0x10: + val &= 0xfc; + val |= 1; + case 0x11: case 0x12: case 0x13: + /* I/O Base set. */ + /* First, remove the old I/O, if old base was >= 0x280. */ + ne2000_ioremove(dev->base_address, dev); -void ne2000_tx_event(void *p, uint32_t val) -{ - ne2000_t *ne2000 = (ne2000_t *)p; + /* Then let's set the PCI regs. */ + pci_bar[0].addr_regs[addr & 3] = val; - ne2000_log("tx_timer\n"); - ne2000->CR.tx_packet = 0; - ne2000->TSR.tx_ok = 1; - ne2000->ISR.pkt_tx = 1; - /* Generate an interrupt if not masked */ - if (ne2000->IMR.tx_inte) - { - picint(1 << ne2000->base_irq); - } - ne2000->tx_timer_active = 0; -} + /* Then let's calculate the new I/O base. */ + dev->base_address = pci_bar[0].addr & 0xff00; -/* read_handler/read - i/o 'catcher' function called from BOCHS - mainline when the CPU attempts a read in the i/o space registered - by this ne2000 instance */ - -uint32_t ne2000_read(ne2000_t *ne2000, uint32_t address, unsigned io_len) -{ - uint32_t retval = 0; - int offset = address - ne2000->base_address; - - ne2000_log("%s: read addr %x, len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, io_len); - - if (offset >= 0x10) - { - retval = ne2000_asic_read(ne2000, offset - 0x10, io_len); - } - else if (offset == 0x00) - { - retval = ne2000_read_cr(ne2000); - } - else - { - switch (ne2000->CR.pgsel) - { - case 0x00: - retval = ne2000_page0_read(ne2000, offset, io_len); - break; - - case 0x01: - retval = ne2000_page1_read(ne2000, offset, io_len); - break; - - case 0x02: - retval = ne2000_page2_read(ne2000, offset, io_len); - break; - - case 0x03: - retval = ne2000_page3_read(ne2000, offset, io_len); - break; - - default: - ne2000_log("unknown value of pgsel in read - %d\n", ne2000->CR.pgsel); - break; + /* Log the new base. */ + pclog(1, "NE2000 RTL8029AS PCI: New I/O base is %04X\n", + dev->base_address); + /* We're done, so get out of the here. */ + if (val & PCI_COMMAND_IO) { + ne2000_ioset(dev->base_address, dev); } - } + return; - return (retval); -} + case 0x30: case 0x31: case 0x32: case 0x33: + pci_bar[1].addr_regs[addr & 3] = val; + pci_bar[1].addr_regs[1] &= bios_mask; + bios_addr = pci_bar[1].addr & 0xffffe000; + pci_bar[1].addr &= 0xffffe000; + pci_bar[1].addr |= 0x1801; + ne2000_update_bios(dev); + return; -void ne2000_write(ne2000_t *ne2000, uint32_t address, uint32_t value, unsigned io_len) -{ - int offset = address - ne2000->base_address; - - ne2000_log("%s: write addr %x, value %x len %d\n", (network_card_current == 1) ? "NE2000" : "RTL8029AS", address, value, io_len); - - /* The high 16 bytes of i/o space are for the ne2000 asic - - the low 16 bytes are for the DS8390, with the current - page being selected by the PS0,PS1 registers in the - command register */ - - if (offset >= 0x10) - { - ne2000_asic_write(ne2000, offset - 0x10, value, io_len); - } - else if (offset == 0x00) - { - ne2000_write_cr(ne2000, value); - } - else - { - switch (ne2000->CR.pgsel) - { - case 0x00: - ne2000_page0_write(ne2000, offset, value, io_len); - break; - - case 0x01: - ne2000_page1_write(ne2000, offset, value, io_len); - break; - - case 0x02: - ne2000_page2_write(ne2000, offset, value, io_len); - break; - - case 0x03: - ne2000_page3_write(ne2000, offset, value, io_len); - break; - - default: - ne2000_log("unknown value of pgsel in write - %d\n", ne2000->CR.pgsel); - break; +#if 0 + /* Commented out until an APIC controller is emulated for + * the PIIX3, otherwise the RTL-8029/AS will not get an IRQ + * on boards using the PIIX3. */ + case 0x3C: + pci_regs[addr] = val; + if (val != 0xFF) { + pclog(1, "NE2000 IRQ now: %i\n", val); + dev->base_irq = irq; } + return; +#endif } } + +static uint8_t * +ne2000_mac(void) +{ + if (network_card_current == 2) + return(maclocal_pci); + + return(maclocal); +} + + +static void +ne2000_tx_event(void *priv, uint32_t val) +{ + ne2000_t *dev = (ne2000_t *)priv; + + pclog(1, "tx_timer\n"); + dev->CR.tx_packet = 0; + dev->TSR.tx_ok = 1; + dev->ISR.pkt_tx = 1; + + /* Generate an interrupt if not masked */ + if (dev->IMR.tx_inte) + picint(1 << dev->base_irq); + dev->tx_timer_active = 0; +} + + /* * mcast_index() - return the 6-bit index into the multicast * table. Stolen unashamedly from FreeBSD's if_ed.c */ -static int mcast_index(const void *dst) +static int +mcast_index(const void *dst) { #define POLYNOMIAL 0x04c11db6 unsigned long crc = 0xffffffffL; @@ -1511,7 +1636,7 @@ static int mcast_index(const void *dst) */ void ne2000_rx_frame(void *p, const void *buf, int io_len) { - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *dev = (ne2000_t *)p; int pages; int avail; @@ -1526,11 +1651,11 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) if(io_len != 60) { - ne2000_log("rx_frame with length %d\n", io_len); + pclog(1, "rx_frame with length %d\n", io_len); } - if ((ne2000->CR.stop != 0) || - (ne2000->page_start == 0)) + if ((dev->CR.stop != 0) || + (dev->page_start == 0)) { return; } @@ -1539,13 +1664,13 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) out how many 256-byte pages the frame would occupy */ pages = (io_len + 4 + 4 + 255)/256; - if (ne2000->curr_page < ne2000->bound_ptr) + if (dev->curr_page < dev->bound_ptr) { - avail = ne2000->bound_ptr - ne2000->curr_page; + avail = dev->bound_ptr - dev->curr_page; } else { - avail = (ne2000->page_stop - ne2000->page_start) - (ne2000->curr_page - ne2000->bound_ptr); + avail = (dev->page_stop - dev->page_start) - (dev->curr_page - dev->bound_ptr); } /* Avoid getting into a buffer overflow condition by not attempting @@ -1557,13 +1682,13 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) #endif ) { - ne2000_log("no space\n"); + pclog(1, "no space\n"); return; } - if ((io_len < 40/*60*/) && !ne2000->RCR.runts_ok) + if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { - ne2000_log("rejected small packet, length %d\n", io_len); + pclog(1, "rejected small packet, length %d\n", io_len); return; } /* some computers don't care... */ @@ -1573,7 +1698,7 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) } /* Do address filtering if not in promiscuous mode */ - if (! ne2000->RCR.promisc) + if (! dev->RCR.promisc) { /* Received. */ mac_cmp32[0] = *(uint32_t *) (buf); @@ -1583,39 +1708,39 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) { - if (!ne2000->RCR.broadcast) + if (!dev->RCR.broadcast) { return; } } else if (pktbuf[0] & 0x01) { - if (! ne2000->RCR.multicast) + if (! dev->RCR.multicast) { return; } idx = mcast_index(buf); - if (!(ne2000->mchash[idx >> 3] & (1 << (idx & 0x7)))) + if (!(dev->mchash[idx >> 3] & (1 << (idx & 0x7)))) { return; } } - else if (0 != memcmp(buf, ne2000->physaddr, 6)) + else if (0 != memcmp(buf, dev->physaddr, 6)) { return; } } else { - ne2000_log("rx_frame promiscuous receive\n"); + pclog(1, "rx_frame promiscuous receive\n"); } - ne2000_log("rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + pclog(1, "rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); - nextpage = ne2000->curr_page + pages; - if (nextpage >= ne2000->page_stop) + nextpage = dev->curr_page + pages; + if (nextpage >= dev->page_stop) { - nextpage -= ne2000->page_stop - ne2000->page_start; + nextpage -= dev->page_stop - dev->page_start; } /* Setup packet header */ @@ -1631,622 +1756,435 @@ void ne2000_rx_frame(void *p, const void *buf, int io_len) pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ /* copy into buffer, update curpage, and signal interrupt if config'd */ - startptr = & ne2000->mem[ne2000->curr_page * 256 - BX_NE2K_MEMSTART]; - if ((nextpage > ne2000->curr_page) || ((ne2000->curr_page + pages) == ne2000->page_stop)) + startptr = & dev->mem[dev->curr_page * 256 - BX_NE2K_MEMSTART]; + if ((nextpage > dev->curr_page) || ((dev->curr_page + pages) == dev->page_stop)) { *(uint32_t *) startptr = *(uint32_t *) pkthdr; memcpy(startptr + 4, buf, io_len); - ne2000->curr_page = nextpage; + dev->curr_page = nextpage; } else { - int endbytes = (ne2000->page_stop - ne2000->curr_page) * 256; + int endbytes = (dev->page_stop - dev->curr_page) * 256; *(uint32_t *) startptr = *(uint32_t *) pkthdr; memcpy(startptr + 4, buf, endbytes - 4); - startptr = & ne2000->mem[ne2000->page_start * 256 - BX_NE2K_MEMSTART]; + startptr = & dev->mem[dev->page_start * 256 - BX_NE2K_MEMSTART]; memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); - ne2000->curr_page = nextpage; + dev->curr_page = nextpage; } - ne2000->RSR.rx_ok = 1; + dev->RSR.rx_ok = 1; if (pktbuf[0] & 0x80) { - ne2000->RSR.rx_mbit = 1; + dev->RSR.rx_mbit = 1; } - ne2000->ISR.pkt_rx = 1; + dev->ISR.pkt_rx = 1; - if (ne2000->IMR.rx_inte) + if (dev->IMR.rx_inte) { - picint(1 << ne2000->base_irq); + picint(1 << dev->base_irq); } } -uint8_t ne2000_readb(uint16_t addr, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - return ne2000_read(ne2000, addr, 1); -} -uint16_t ne2000_readw(uint16_t addr, void *p) +void +ne2000_poller(void *priv) { - ne2000_t *ne2000 = (ne2000_t *)p; - if (ne2000->DCR.wdsize & 1) - { - return ne2000_read(ne2000, addr, 2); - } - else - { - return ne2000_read(ne2000, addr, 1); - } -} - -uint32_t ne2000_readl(uint16_t addr, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - return ne2000_read(ne2000, addr, 4); -} - -void ne2000_writeb(uint16_t addr, uint8_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_write(ne2000, addr, val, 1); -} - -void ne2000_writew(uint16_t addr, uint16_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - if (ne2000->DCR.wdsize & 1) - { - ne2000_write(ne2000, addr, val, 2); - } - else - { - ne2000_write(ne2000, addr, val, 1); - } -} - -void ne2000_writel(uint16_t addr, uint32_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_write(ne2000, addr, val, 4); -} - -void ne2000_poller(void *p) -{ - ne2000_t *ne2000 = (ne2000_t *)p; + ne2000_t *dev = (ne2000_t *)priv; struct queuepacket *qp; const unsigned char *data; struct pcap_pkthdr h; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; + uint32_t mac_cmp32[2]; + uint16_t mac_cmp16[2]; - if (!net_is_pcap) - { - while(QueuePeek(slirpq) > 0) - { - qp=QueueDelete(slirpq); - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - { - free(qp); - return; - } - ne2000_rx_frame(ne2000,&qp->data,qp->len); - ne2000_log("ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); + if (! net_is_pcap) { + while(QueuePeek(slirpq) > 0) { + qp = QueueDelete(slirpq); + if ((dev->DCR.loop == 0) || (dev->TCR.loop_cntl != 0)) { free(qp); + return; } + ne2000_rx_frame(dev, &qp->data, qp->len); + pclog(1, "ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); + free(qp); + } fizz++; - if (fizz>1200) - { - fizz=0;slirp_tic(); - } - } /* end slirp */ - else if (net_is_pcap && (net_pcap != NULL)) - { - if((ne2000->DCR.loop == 0) || (ne2000->TCR.loop_cntl != 0)) - { - return; - } - data=pcap_next(net_pcap,&h); - if(data==0x0) - { - return; - } - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (data+6); - mac_cmp16[0] = *(uint16_t *) (data+10); - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (ne2000_mac()); - mac_cmp16[1] = *(uint16_t *) (ne2000_mac() + 4); - if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) - { - ne2000_rx_frame(ne2000,data,h.caplen); - } + if (fizz > 1200) { + fizz=0; + slirp_tic(); } -} -typedef union -{ - uint32_t addr; - uint8_t addr_regs[4]; -} bar_t; + return; + } -uint8_t ne2000_pci_regs[256]; - -bar_t ne2000_pci_bar[2]; - -uint32_t bios_addr = 0xD0000; -uint32_t old_base_addr = 0; - -uint32_t bios_size = 0; -uint32_t bios_mask = 0; - -void ne2000_io_set(uint16_t addr, ne2000_t *ne2000) -{ - old_base_addr = addr; - if (network_card_current == 1) - { - io_sethandler(addr, 0x0010, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, NULL, ne2000_writeb, ne2000_writew, NULL, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - } - else - { - io_sethandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_sethandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - } -} - -void ne2000_io_remove(int16_t addr, ne2000_t *ne2000) -{ - if (network_card_current == 1) - { - io_removehandler(addr, 0x0010, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, NULL, ne2000_writeb, ne2000_writew, NULL, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, NULL, NULL, ne2000_writeb, NULL, NULL, ne2000); - } - else - { - io_removehandler(addr, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x10, 0x0010, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - io_removehandler(addr+0x1f, 0x0001, ne2000_readb, ne2000_readw, ne2000_readl, ne2000_writeb, ne2000_writew, ne2000_writel, ne2000); - } -} - -uint8_t ne2000_pci_read(int func, int addr, void *p) -{ - switch (addr) - { - case 0x00: - return 0xec; - case 0x01: - return 0x10; - - case 0x02: - return 0x29; - case 0x03: - return 0x80; - - case 0x2C: - return 0xF4; - case 0x2D: - return 0x1A; - case 0x2E: - return 0x00; - case 0x2F: - return 0x11; - - case 0x04: - return ne2000_pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return ne2000_pci_regs[0x05]; - - case 0x07: - return 2; - - case 0x08: - return 0; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ - - case 0x0B: - return ne2000_pci_regs[0x0B]; - - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return ne2000_pci_bar[0].addr_regs[1]; - case 0x12: - return ne2000_pci_bar[0].addr_regs[2]; - case 0x13: - return ne2000_pci_bar[0].addr_regs[3]; - - case 0x30: - return ne2000_pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ - case 0x31: - return (ne2000_pci_bar[1].addr_regs[1] & bios_mask) | 0x18; - case 0x32: - return ne2000_pci_bar[1].addr_regs[2]; - case 0x33: - return ne2000_pci_bar[1].addr_regs[3]; - - case 0x3C: - return ne2000_pci_regs[0x3C]; - case 0x3D: - return ne2000_pci_regs[0x3D]; - } - return 0; -} - -void ne2000_update_bios(ne2000_t *ne2000) -{ - int reg_bios_enable; - - reg_bios_enable = 1; - - /* PCI BIOS stuff, just enable_disable. */ - if (!disable_netbios && reg_bios_enable) - { - mem_mapping_enable(&ne2000->bios_rom.mapping); - mem_mapping_set_addr(&ne2000->bios_rom.mapping, bios_addr, 0x10000); - ne2000_log("Network BIOS now at: %08X\n", bios_addr); - } - else - { - mem_mapping_disable(&ne2000->bios_rom.mapping); - if (network_card_current == 2) ne2000_pci_bar[1].addr = 0; - } -} - -void ne2000_pci_write(int func, int addr, uint8_t val, void *p) -{ - ne2000_t *ne2000 = (ne2000_t *) p; - - switch (addr) - { - case 0x04: - ne2000_io_remove(ne2000->base_address, ne2000); - if (val & PCI_COMMAND_IO) - { - ne2000_io_set(ne2000->base_address, ne2000); - } - ne2000_pci_regs[addr] = val; - break; - - case 0x10: - val &= 0xfc; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O, if old base was >= 0x280. */ - ne2000_io_remove(ne2000->base_address, ne2000); - /* Then let's set the PCI regs. */ - ne2000_pci_bar[0].addr_regs[addr & 3] = val; - /* Then let's calculate the new I/O base. */ - ne2000->base_address = ne2000_pci_bar[0].addr & 0xff00; - /* Log the new base. */ - ne2000_log("NE2000 RTL8029AS PCI: New I/O base is %04X\n" , ne2000->base_address); - /* We're done, so get out of the here. */ - if (val & PCI_COMMAND_IO) - { - ne2000_io_set(ne2000->base_address, ne2000); - } - return; - - case 0x30: case 0x31: case 0x32: case 0x33: - ne2000_pci_bar[1].addr_regs[addr & 3] = val; - ne2000_pci_bar[1].addr_regs[1] &= bios_mask; - bios_addr = ne2000_pci_bar[1].addr & 0xffffe000; - ne2000_pci_bar[1].addr &= 0xffffe000; - ne2000_pci_bar[1].addr |= 0x1801; - ne2000_update_bios(ne2000); - return; - - /* Commented out until an APIC controller is emulated for the PIIX3, - otherwise the RTL-8029/AS will not get an IRQ on boards using the PIIX3. */ -#if 0 - case 0x3C: - ne2000_pci_regs[addr] = val; - if (val != 0xFF) - { - ne2000_log("NE2000 IRQ now: %i\n", val); - ne2000_setirq(ne2000, val); - } - return; -#endif - } -} - -void ne2000_rom_init(ne2000_t *ne2000, wchar_t *s) -{ - FILE *f = romfopen(s, L"rb"); - uint32_t temp; - if(!f) - { - disable_netbios = 1; - ne2000_update_bios(ne2000); + if (net_pcap != NULL) { + if ((dev->DCR.loop == 0) || (dev->TCR.loop_cntl != 0)) { return; } - fseek(f, 0, SEEK_END); - temp = ftell(f); - fclose(f); - bios_size = 0x10000; - if (temp <= 0x8000) - { - bios_size = 0x8000; + data = pcap_next(net_pcap, &h); + if (data == NULL) { + return; } - if (temp <= 0x4000) - { - bios_size = 0x4000; - } - if (temp <= 0x2000) - { - bios_size = 0x2000; - } - bios_mask = (bios_size >> 8) & 0xff; - bios_mask = (0x100 - bios_mask) & 0xff; - rom_init(&ne2000->bios_rom, s, 0xd0000, bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); + /* Received. */ + mac_cmp32[0] = *(uint32_t *)(data+6); + mac_cmp16[0] = *(uint16_t *)(data+10); + + /* Local. */ + mac_cmp32[1] = *(uint32_t *)(ne2000_mac()); + mac_cmp16[1] = *(uint16_t *)(ne2000_mac()+4); + if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { + ne2000_rx_frame(dev, data, h.caplen); + } else { + pclog(1, "NE2000: RX pkt, not for me!\n"); + } + } } -static char errbuf[32768]; - -void *ne2000_init(void) +static void +ne2000_rom_init(ne2000_t *dev, wchar_t *s) { + FILE *f = romfopen(s, L"rb"); + uint32_t temp; + + if (f != NULL) { + disable_netbios = 1; + ne2000_update_bios(dev); + return; + } + fseek(f, 0, SEEK_END); + temp = ftell(f); + fclose(f); + bios_size = 0x10000; + if (temp <= 0x8000) + bios_size = 0x8000; + if (temp <= 0x4000) + bios_size = 0x4000; + if (temp <= 0x2000) + bios_size = 0x2000; + bios_mask = (bios_size >> 8) & 0xff; + bios_mask = (0x100 - bios_mask) & 0xff; + + rom_init(&dev->bios_rom, s, 0xd0000, + bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); +} + + +static void * +ne2000_init(void) +{ + char errbuf[32768]; int rc; int config_net_type; - int irq; - int pcap_device_available = 0; - int is_rtl8029as = 0; - ne2000_t *ne2000 = malloc(sizeof(ne2000_t)); - memset(ne2000, 0, sizeof(ne2000_t)); + int irq; + int pcap_device_available = 0; + int is_rtl8029as = 0; + ne2000_t *dev; + char *pcap_dev; + + dev = malloc(sizeof(ne2000_t)); + memset(dev, 0x00, sizeof(ne2000_t)); - if (PCI && (network_card_current == 2)) - { - is_rtl8029as = 1; - } - else - { - network_card_current = 1; - is_rtl8029as = 0; - } + if (PCI && (network_card_current == 2)) { + is_rtl8029as = 1; + } else { + network_card_current = 1; + is_rtl8029as = 0; + } - if (is_rtl8029as) - { - ne2000->base_address = 0x340; - } - else - { - ne2000->base_address = device_get_config_int("addr"); - } + if (is_rtl8029as) { + dev->base_address = 0x340; + } else { + dev->base_address = device_get_config_int("addr"); + } + irq = device_get_config_int("irq"); + dev->base_irq = irq; - disable_netbios = device_get_config_int("disable_netbios"); + disable_netbios = device_get_config_int("disable_netbios"); - irq = device_get_config_int("irq"); - ne2000_setirq(ne2000, irq); + /* Network type is now specified in device config. */ + config_net_type = device_get_config_int("net_type"); - config_net_type = device_get_config_int("net_type"); - /* Network type is now specified in device config. */ - net_is_pcap = config_net_type ? 0 : 1; - if(!strcmp("nothing", config_get_string(NULL, "pcap_device", "nothing"))) - { + net_is_pcap = config_net_type ? 0 : 1; + if (net_is_pcap) { + pcap_dev = config_get_string(NULL, "pcap_device", "nothing"); + if (! strcmp(pcap_dev, "nothing")) { net_is_pcap = 0; pcap_device_available = 0; - } - else - { + } else { pcap_device_available = 1; } - ne2000_log("net_is_pcap = %i\n", net_is_pcap); + } + pclog(1, "net_is_pcap = %i\n", net_is_pcap); - if (is_rtl8029as) - { - pci_add(ne2000_pci_read, ne2000_pci_write, ne2000); - } - - ne2000_io_set(ne2000->base_address, ne2000); - - memcpy(ne2000->physaddr, ne2000_mac(), 6); - - if (!disable_netbios) - { - ne2000_rom_init(ne2000, is_rtl8029as ? L"roms/rtl8029as.rom" : L"roms/ne2000.rom"); - - if (is_rtl8029as) - { - mem_mapping_disable(&ne2000->bios_rom.mapping); - } + if (is_rtl8029as) { + pci_add(ne2000_pci_read, ne2000_pci_write, dev); + } + + ne2000_ioset(dev->base_address, dev); + + memcpy(dev->physaddr, ne2000_mac(), 6); + + if (! disable_netbios) { + ne2000_rom_init(dev, is_rtl8029as ? L"roms/rtl8029as.rom" + : L"roms/ne2000.rom"); + if (is_rtl8029as) { + mem_mapping_disable(&dev->bios_rom.mapping); } + } - if (is_rtl8029as) - { - ne2000_pci_regs[0x04] = 1; - ne2000_pci_regs[0x05] = 0; + if (is_rtl8029as) { + pci_regs[0x04] = 1; + pci_regs[0x05] = 0; - ne2000_pci_regs[0x07] = 2; + pci_regs[0x07] = 2; /* Network controller. */ - ne2000_pci_regs[0x0B] = 2; + pci_regs[0x0B] = 2; - ne2000_pci_bar[0].addr_regs[0] = 1; + pci_bar[0].addr_regs[0] = 1; - if (disable_netbios) - { - ne2000_pci_bar[1].addr = 0; - bios_addr = 0; - } - else - { - ne2000_pci_bar[1].addr = 0x000F8000; - ne2000_pci_bar[1].addr_regs[1] = bios_mask; - ne2000_pci_bar[1].addr |= 0x1801; - bios_addr = 0xD0000; - } + if (disable_netbios) { + pci_bar[1].addr = 0; + bios_addr = 0; + } else { + pci_bar[1].addr = 0x000F8000; + pci_bar[1].addr_regs[1] = bios_mask; + pci_bar[1].addr |= 0x1801; + bios_addr = 0xD0000; + } - ne2000_pci_regs[0x3C] = irq; - pclog("RTL8029AS IRQ: %i\n", ne2000_pci_regs[0x3C]); - ne2000_pci_regs[0x3D] = 1; + pci_regs[0x3C] = irq; + pclog(1, "RTL8029AS IRQ: %i\n", pci_regs[0x3C]); + pci_regs[0x3D] = 1; memset(rtl8029as_eeprom, 0, 128); - rtl8029as_eeprom[0x76] = rtl8029as_eeprom[0x7A] = rtl8029as_eeprom[0x7E] = 0x29; - rtl8029as_eeprom[0x77] = rtl8029as_eeprom[0x7B] = rtl8029as_eeprom[0x7F] = 0x80; - rtl8029as_eeprom[0x78] = rtl8029as_eeprom[0x7C] = 0x10; - rtl8029as_eeprom[0x79] = rtl8029as_eeprom[0x7D] = 0xEC; - } + rtl8029as_eeprom[0x76] = + rtl8029as_eeprom[0x7A] = + rtl8029as_eeprom[0x7E] = 0x29; + rtl8029as_eeprom[0x77] = + rtl8029as_eeprom[0x7B] = + rtl8029as_eeprom[0x7F] = 0x80; + rtl8029as_eeprom[0x78] = + rtl8029as_eeprom[0x7C] = 0x10; + rtl8029as_eeprom[0x79] = + rtl8029as_eeprom[0x7D] = 0xEC; + } - ne2000_reset(ne2000, BX_RESET_HARDWARE); - network_add_handler(ne2000_poller, ne2000); + ne2000_reset(dev, BX_RESET_HARDWARE); - ne2000_log("ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n",is_rtl8029as ? "pci" : "isa",ne2000->base_address,device_get_config_int("irq"),net_is_pcap); + network_add_handler(ne2000_poller, dev); + + pclog(1, "ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n", + is_rtl8029as?"PCI":"ISA", + dev->base_address, + device_get_config_int("irq"), + net_is_pcap); /* need a switch statment for more network types. */ - if (!net_is_pcap) - { + if (! net_is_pcap) { initialize_slirp: - ne2000_log("ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - ne2000_log("ne2000 slirp_init returned: %d\n",rc); - if (!rc) - { - ne2000_log("ne2000 slirp initalized!\n"); + pclog(1, "ne2000 initalizing SLiRP\n"); + net_is_pcap=0; + rc=slirp_init(); + pclog(1, "ne2000 slirp_init returned: %d\n",rc); + if (! rc) { + pclog(1, "ne2000 slirp initalized!\n"); - net_slirp_inited = 1; - slirpq = QueueCreate(); - fizz=0; - ne2000_log("ne2000 slirpq is %x\n",&slirpq); - } - else - { - net_slirp_inited = 0; - if (pcap_device_available) - { - net_is_pcap = 1; - goto initialize_pcap; - } - else - { - ne2000_log("Neither SLiRP nor PCap is available on your host, disabling network adapter...\n"); - free(ne2000); - network_card_current = 0; - resetpchard(); - return NULL; - } + net_slirp_inited = 1; + slirpq = QueueCreate(); + fizz=0; + pclog(1, "ne2000 slirpq is %x\n",&slirpq); + } else { + net_slirp_inited = 0; + if (pcap_device_available) { + net_is_pcap = 1; + goto initialize_pcap; + } else { + pclog(1, "Neither SLiRP nor PCap available, disabling network adapter...\n"); + free(dev); + network_card_current = 0; + resetpchard(); + return(NULL); } } - else - { + } else { initialize_pcap: - ne2000_log("ne2000 initalizing libpcap\n"); + pclog(1, "ne2000 initalizing libpcap\n"); - ne2000_log("ne2000 Pcap version [%s]\n",pcap_lib_version()); + pclog(1, "ne2000 Pcap version [%s]\n", pcap_lib_version()); - if((net_pcap=pcap_open_live(config_get_string(NULL,"pcap_device","nothing"),1518,1,15,errbuf))==0) - { - ne2000_log("ne2000 pcap_open_live error on %s!\n",config_get_string(NULL,"pcap_device","whatever the ethernet is")); - net_is_pcap=0; - return(ne2000); /* YUCK!!! */ - } + net_pcap = pcap_open_live(pcap_dev, 1518, 1, 15, errbuf); + if (net_pcap == NULL) { + pclog(1, "NE2000 pcap_open_live error on %s!\n", pcap_dev); + net_is_pcap=0; + return(dev); /* YUCK!!! */ + } - /* Time to check that we are in non-blocking mode. */ - rc=pcap_getnonblock(net_pcap,errbuf); - ne2000_log("ne2000 pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - switch(rc) - { - case 0: - ne2000_log("ne2000 Setting interface to non-blocking mode.."); - rc = pcap_setnonblock(net_pcap,1,errbuf); - if (rc==0) - { /* no errors! */ - ne2000_log(".."); - rc=pcap_getnonblock(net_pcap,errbuf); - if(rc == 1) - { - ne2000_log("..!",rc); - net_is_pcap=1; - } - else - { - ne2000_log("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap=0; - } - } /* end set nonblock */ - else - { - ne2000_log("There was an unexpected error of [%s]\n\nexiting.\n",errbuf);net_is_pcap=0;} - ne2000_log("\n"); - break; - case 1: - ne2000_log("non blocking\n"); - break; - default: - ne2000_log("this isn't right!!!\n"); - net_is_pcap=0; - break; - } - if (net_is_pcap) - { - struct bpf_program fp; - char filter_exp[255]; - ne2000_log("ne2000 Building packet filter..."); - sprintf(filter_exp,"( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", \ - ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5],\ - ne2000_mac()[0], ne2000_mac()[1], ne2000_mac()[2], ne2000_mac()[3], ne2000_mac()[4], ne2000_mac()[5]); - - /* I'm doing a MAC level filter so TCP/IP doesn't matter. */ - if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) - { - ne2000_log("\nne2000 Couldn't compile filter\n"); - } - else - { - ne2000_log("..."); - if (pcap_setfilter(net_pcap, &fp) == -1) - { - ne2000_log("\nError installing pcap filter.\n"); - } /* end of set_filter failure */ - else - { - ne2000_log("...!\n"); + /* Time to check that we are in non-blocking mode. */ + rc = pcap_getnonblock(net_pcap, errbuf); + pclog(1, "ne2000 pcap is currently in %s mode\n", + rc?"non-blocking":"blocking"); + switch(rc) { + case 0: + pclog(1, "NE2000: setting to non-blocking mode.."); + rc = pcap_setnonblock(net_pcap, 1, errbuf); + if (rc == 0) { + /* no errors! */ + pclog(1, ".."); + rc = pcap_getnonblock(net_pcap, errbuf); + if (rc == 1) { + pclog(1, "..!"); + net_is_pcap = 1; + } else { + pclog(1, "\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + net_is_pcap = 0; } + } else { + pclog(1, "There was an unexpected error of [%s]\n\nexiting.\n", errbuf); + net_is_pcap = 0; } - ne2000_log("ne2000 Using filter\t[%s]\n",filter_exp); - } - else - { - pcap_device_available = 0; - goto initialize_slirp; - } - ne2000_log("ne2000 net_is_pcap is %d and net_pcap is %x\n",net_is_pcap,net_pcap); - } /* end pcap setup */ + pclog(1, "\n"); + break; - ne2000_log("ne2000 is_pcap %d\n", net_is_pcap); - return ne2000; + case 1: + pclog(1, "non blocking\n"); + break; + + default: + pclog(1, "this isn't right!!!\n"); + net_is_pcap = 0; + break; + } + + if (net_is_pcap) { + char filter_exp[255]; + struct bpf_program fp; + uint8_t *mac; + + mac = ne2000_mac(); + pclog(1, "ne2000 Building packet filter ..."); + sprintf(filter_exp, + "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { + pclog(1, "\nne2000 Couldn't compile filter\n"); + } else { + pclog(1, "..."); + if (pcap_setfilter(net_pcap, &fp) == -1) { + pclog(1, "\nError installing pcap filter.\n"); + } else { + pclog(1, "...!\n"); + } + } + pclog(1, "ne2000 Using filter\t[%s]\n", filter_exp); + } else { + pcap_device_available = 0; + goto initialize_slirp; + } + pclog(1, "ne2000 net_is_pcap is %d and net_pcap is %x\n", + net_is_pcap, net_pcap); + } + + pclog(1, "ne2000 is_pcap %d\n", net_is_pcap); + + return(dev); } -void ne2000_close(void *p) + +static void +ne2000_close(void *priv) { - ne2000_t *ne2000 = (ne2000_t *)p; - ne2000_io_remove(ne2000->base_address, ne2000); - free(ne2000); + ne2000_t *dev = (ne2000_t *)priv; - if(!net_is_pcap) - { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited=0; - ne2000_log("ne2000 exiting slirp\n"); - } - else if (net_is_pcap && (net_pcap != NULL)) - { - pcap_close(net_pcap); - ne2000_log("ne2000 closing pcap\n"); - } - ne2000_log("ne2000 close\n"); + if (! net_is_pcap) { + QueueDestroy(slirpq); + slirp_exit(0); + net_slirp_inited=0; + pclog(1, "NE2000 exiting slirp\n"); + } else if (net_is_pcap && (net_pcap != NULL)) { + pcap_close(net_pcap); + pclog(1, "NE2000 closing pcap\n"); + } + + ne2000_ioremove(dev->base_address, dev); + + free(dev); + + pclog(1, "Ne2000 close\n"); } + +void +ne2000_generate_maclocal(uint32_t mac) +{ + maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ + maclocal[1] = 0x00; + maclocal[2] = 0xD8; + + if (mac & 0xff000000) { + /* Generating new MAC. */ + maclocal[3] = disc_random_generate(); + maclocal[4] = disc_random_generate(); + maclocal[5] = disc_random_generate(); + } else { + maclocal[3] = (mac>>16) & 0xff; + maclocal[4] = (mac>>8) & 0xff; + maclocal[5] = mac & 0xff; + } +} + + +uint32_t +ne2000_get_maclocal(void) +{ + uint32_t temp; + + temp = (((int) maclocal[3]) << 16); + temp |= (((int) maclocal[4]) << 8); + temp |= ((int) maclocal[5]); + + return(temp); +} + + +void +ne2000_generate_maclocal_pci(uint32_t mac) +{ + maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + maclocal_pci[1] = 0x20; + maclocal_pci[2] = 0x18; + + if (mac & 0xff000000) { + /* Generating new MAC. */ + maclocal_pci[3] = disc_random_generate(); + maclocal_pci[4] = disc_random_generate(); + maclocal_pci[5] = disc_random_generate(); + } else { + maclocal_pci[3] = (mac >> 16) & 0xff; + maclocal_pci[4] = (mac >> 8) & 0xff; + maclocal_pci[5] = mac & 0xff; + } +} + + +uint32_t +ne2000_get_maclocal_pci(void) +{ + uint32_t temp; + + temp = (((int) maclocal_pci[3]) << 16); + temp |= (((int) maclocal_pci[4]) << 8); + temp |= ((int) maclocal_pci[5]); + + return(temp); +} + + static device_config_t ne2000_config[] = { { @@ -2367,6 +2305,7 @@ static device_config_t rtl8029as_config[] = } }; + device_t ne2000_device = { "Novell NE2000", @@ -2393,52 +2332,55 @@ device_t rtl8029as_device = rtl8029as_config }; + /* SLIRP stuff */ -int slirp_can_output(void) +int +slirp_can_output(void) { - return net_slirp_inited; + return(net_slirp_inited); } -void slirp_output (const unsigned char *pkt, int pkt_len) + +void +slirp_output(const unsigned char *pkt, int pkt_len) { - struct queuepacket *p; - p=(struct queuepacket *)malloc(sizeof(struct queuepacket)); - p->len=pkt_len; - memcpy(p->data,pkt,pkt_len); - QueueEnter(slirpq,p); - ne2000_log("ne2000 slirp_output %d @%d\n",pkt_len,p); + struct queuepacket *p; + + p = (struct queuepacket *)malloc(sizeof(struct queuepacket)); + p->len = pkt_len; + memcpy(p->data, pkt, pkt_len); + QueueEnter(slirpq, p); + pclog(1, "ne2000 slirp_output %d @%d\n", pkt_len, p); } + /* Instead of calling this and crashing some times or experencing jitter, this is called by the 60Hz clock which seems to do the job. */ -void slirp_tic() +void +slirp_tic(void) { - int ret2,nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int timeout; - nfds=-1; + int ret2,nfds; + struct timeval tv; + fd_set rfds, wfds, xfds; + int tmo; + nfds=-1; - if(net_slirp_inited) - { - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - timeout=slirp_select_fill(&nfds,&rfds,&wfds,&xfds); /* this can crash */ - - if(timeout<0) - { - timeout=500; - } + if (! net_slirp_inited) return; - tv.tv_sec=0; - tv.tv_usec = timeout; /* basilisk default 10000 */ + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ + if (tmo < 0) { + tmo = 500; + } - ret2 = select(nfds + 1, &rfds, &wfds, &xfds, &tv); - if(ret2>=0) - { - slirp_select_poll(&rfds, &wfds, &xfds); - } - } /* end if slirp inited */ + tv.tv_sec = 0; + tv.tv_usec = tmo; /* basilisk default 10000 */ + + ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); + if (ret2 >= 0) { + slirp_select_poll(&rfds, &wfds, &xfds); + } } diff --git a/src/net_ne2000.h b/src/net_ne2000.h index 550219dac..af46ec311 100644 --- a/src/net_ne2000.h +++ b/src/net_ne2000.h @@ -1,6 +1,17 @@ -/* Copyright holders: SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the NE2000 ethernet controller. + * + * Version: @(#)net_ne2000.h 1.0.1 2017/05/09 + * + * Author: Fred N. van Kempen, + */ #ifndef NET_NE2000_H # define NET_NE2000_H @@ -10,10 +21,10 @@ extern device_t rtl8029as_device; extern void ne2000_generate_maclocal(uint32_t mac); -extern uint32_t net2000_get_maclocal(void); +extern uint32_t ne2000_get_maclocal(void); extern void ne2000_generate_maclocal_pci(uint32_t mac); -extern uint32_t net2000_get_maclocal_pci(void); +extern uint32_t ne2000_get_maclocal_pci(void); #endif /*NET_NE2000_H*/ diff --git a/src/network.c b/src/network.c index 861a09ded..ccacdeed9 100644 --- a/src/network.c +++ b/src/network.c @@ -1,16 +1,27 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the network module. + * + * Version: @(#)network.c 1.0.1 2017/05/09 + * + * Authors: Kotori, + * Fred N. van Kempen, + */ #include #include #include #include #include "ibm.h" #include "device.h" -#include "network.h" #include "timer.h" #include "thread.h" - +#include "network.h" #include "net_ne2000.h" @@ -21,14 +32,13 @@ typedef struct { } NETCARD; typedef struct { - void (*poller)(void *p); + void (*poller)(void *); void *priv; } NETPOLL; static int net_handlers_num; -static int net_card_last = 0; -static uint32_t net_poll_time = 0; +static uint32_t net_poll_time = 100; static NETPOLL net_handlers[8]; static NETCARD net_cards[] = { { "None", "none", NULL }, @@ -37,8 +47,8 @@ static NETCARD net_cards[] = { { "", "", NULL } }; -int network_card_current = 0; +int network_card_current = 0; uint8_t ethif; int inum; @@ -65,24 +75,12 @@ net_poll(void *priv) void network_init(void) { - if (net_cards[network_card_current].device) - device_add(net_cards[network_card_current].device); + /* No network interface right now. */ + network_card_current = 0; + net_handlers_num = 0; - net_card_last = network_card_current; - - if (network_card_current != 0) { - network_reset(); - } -} - - -/* Add a handler for a network card. */ -void -network_add_handler(void (*poller)(void *p), void *p) -{ - net_handlers[net_handlers_num].poller = poller; - net_handlers[net_handlers_num].priv = p; - net_handlers_num++; + /* This should be a config value, really. --FvK */ + net_poll_time = 100; } @@ -90,15 +88,28 @@ network_add_handler(void (*poller)(void *p), void *p) void network_reset(void) { - pclog("network_reset()\n"); + pclog("NETWORK: reset (card=%d)\n", network_card_current); - net_handlers_num = 0; + if (! network_card_current) return; - if (network_card_current) { - pclog("NETWORK: adding timer...\n"); - - timer_add(net_poll, &net_poll_time, TIMER_ALWAYS_ENABLED, NULL); + if (net_cards[network_card_current].device) { + pclog("NETWORK: adding device '%s'\n", + net_cards[network_card_current].name); + device_add(net_cards[network_card_current].device); } + + pclog("NETWORK: adding timer...\n"); + timer_add(net_poll, &net_poll_time, TIMER_ALWAYS_ENABLED, NULL); +} + + +/* Add a handler for a network card. */ +void +network_add_handler(void (*poller)(void *), void *p) +{ + net_handlers[net_handlers_num].poller = poller; + net_handlers[net_handlers_num].priv = p; + net_handlers_num++; } diff --git a/src/network.h b/src/network.h index 559be9e34..b674d8409 100644 --- a/src/network.h +++ b/src/network.h @@ -1,6 +1,18 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the network module. + * + * Version: @(#)network.h 1.0.1 2017/05/09 + * + * Authors: Kotori, + * Fred N. van Kempen, + */ #ifndef NETWORK_H # define NETWORK_H # include @@ -10,10 +22,9 @@ #define RTL8029AS 2 -extern int network_card_current; - -extern uint8_t ethif; -extern int inum; +extern int network_card_current; +extern uint8_t ethif; +extern int inum; extern void network_init(void); diff --git a/src/pc.c b/src/pc.c index 67a088d2e..7b0615abe 100644 --- a/src/pc.c +++ b/src/pc.c @@ -319,9 +319,12 @@ void initpc(int argc, wchar_t *argv[]) } } + /* Initialize modules. */ + network_init(); mouse_init(); midi_init(); serial_init(); + disc_random_init(); if (config_file == NULL) { @@ -332,8 +335,6 @@ void initpc(int argc, wchar_t *argv[]) append_filename_w(config_file_default, pcempath, config_file, 511); } - disc_random_init(); - loadconfig(config_file); pclog("Config loaded\n"); if (config_file) @@ -488,8 +489,6 @@ void resetpchard(void) ide_qua_init(); } - network_init(); - for (i = 0; i < CDROM_NUM; i++) { if (cdrom_drives[i].bus_type) @@ -498,6 +497,7 @@ void resetpchard(void) } } + network_reset(); resetide(); scsi_card_init(); diff --git a/src/pcap_if.c b/src/pcap_if.c index 6a7a46480..588ee01e8 100644 --- a/src/pcap_if.c +++ b/src/pcap_if.c @@ -6,51 +6,218 @@ * * This file is part of the 86Box distribution. * - * Simple program to show usable interfaces for WinPcap. + * Simple program to show usage of WinPcap. * - * Based on the "libpcap" example. + * Based on the "libpcap" examples. * - * Version: @(#)pcap_if.c 1.0.1 2017/05/08 + * Version: @(#)pcap_if.c 1.0.2 2017/05/09 * * Author: Fred N. van Kempen, */ #include #include +#include #include +typedef struct { + char device[128]; + char description[128]; +} dev_t; + + +/* Retrieve an easy-to-use list of devices. */ +static int +get_devlist(dev_t *list) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *devlist, *dev; + int i = 0; + + /* Retrieve the device list from the local machine */ + if (pcap_findalldevs(&devlist, errbuf) == -1) { + fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); + return(-1); + } + + for (dev=devlist; dev!=NULL; dev=dev->next) { + strcpy(list->device, dev->name); + if (dev->description) + strcpy(list->description, dev->description); + else + memset(list->description, '\0', sizeof(list->description)); + list++; + i++; + } + + /* Release the memory. */ + pcap_freealldevs(devlist); + + return(i); +} + + +/* Simple HEXDUMP routine for raw data. */ +static void +hex_dump(unsigned char *bufp, int len) +{ + char asci[20]; + unsigned char c; + long addr; + + addr = 0; + while (len-- > 0) { + c = bufp[addr]; + if ((addr % 16) == 0) + printf("%04x %02x", addr, c); + else + printf(" %02x", c); + asci[(addr & 15)] = (uint8_t)isprint(c) ? c : '.'; + if ((++addr % 16) == 0) { + asci[16] = '\0'; + printf(" | %s |\n", asci); + } + } + + if (addr % 16) { + while (addr % 16) { + printf(" "); + asci[(addr & 15)] = ' '; + addr++; + } + asci[16] = '\0'; + printf(" | %s |\n", asci); + } +} + + +/* Print a standard Ethernet MAC address. */ +static void +eth_praddr(unsigned char *ptr) +{ + printf("%02x:%02x:%02x:%02x:%02x:%02x", + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); +} + + +/* Print a standard Ethernet header. */ +static int +eth_prhdr(unsigned char *ptr) +{ + unsigned short type; + + printf("Ethernet "); + eth_praddr(ptr+6); + printf(" > "); + eth_praddr(ptr); + type = (ptr[12] << 8) | ptr[13]; + printf(" type %04x\n", type); + + return(14); +} + + +/* Capture packets from the network, and print them. */ +static int +start_cap(char *dev) +{ + char temp[PCAP_ERRBUF_SIZE]; + struct pcap_pkthdr *hdr; + const unsigned char *pkt; + struct tm *ltime; + time_t now; + pcap_t *pcap; + int rc; + + /* Open the device for reading from it. */ + pcap = pcap_open_live(dev, + 1518, /* MTU */ + 1, /* promisc mode */ + 10, /* timeout */ + temp); + if (pcap == NULL) { + fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); + return(2); + } + + printf("Listening on '%s'..\n", dev); + for (;;) { + rc = pcap_next_ex(pcap, &hdr, &pkt); + if (rc < 0) break; + + /* Did we time out? */ + if (rc == 0) continue; + + /* Convert the timestamp to readable format. */ + now = hdr->ts.tv_sec; + ltime = localtime(&now); + strftime(temp, sizeof(temp), "%H:%M:%S", ltime); + + /* Process and print the packet. */ + printf("\n<< %s,%.6d len=%d\n", + temp, hdr->ts.tv_usec, hdr->len); + rc = eth_prhdr((unsigned char *)pkt); + hex_dump((unsigned char *)pkt+rc, hdr->len-rc); + } + + /* All done, close up. */ + pcap_close(pcap); + + return(0); +} + + +/* Show a list of available network interfaces. */ +static void +show_devs(dev_t *list, int num) +{ + int i; + + if (num > 0) { + printf("Available network interfaces:\n\n"); + + for (i=0; idevice); + if (list->description[0] != '\0') + printf(" (%s)\n", list->description); + else + printf(" (No description available)\n"); + list++; + printf("\n"); + } + } else { + printf("No interfaces found!\nMake sure WinPcap is installed.\n"); + } +} + + int main(int argc, char **argv) { - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *alldevs; - pcap_if_t *d; - int i=0; - - /* Retrieve the device list from the local machine */ - if (pcap_findalldevs(&alldevs, errbuf) == -1) { - fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); - exit(1); - } - - /* Print the list */ - for (d= alldevs; d != NULL; d= d->next) { - printf("%d. %s\n", ++i, d->name); - if (d->description) - printf(" (%s)\n", d->description); - else - printf(" (No description available)\n"); - printf("\n"); - i++; - } - - if (i == 0) { - printf("No interfaces found! Make sure WinPcap is installed.\n"); - return(i); + dev_t interfaces[32]; + dev_t *dev = interfaces; + int numdev, i; + + /* Get the list. */ + numdev = get_devlist(interfaces); + + if (argc == 1) { + /* No arguments, just show the list. */ + show_devs(interfaces, numdev); + + return(numdev); } - /* Not really needed as we are about to exit, but oh-well. */ - pcap_freealldevs(alldevs); + /* Assume argument to be the interface number to listen on. */ + i = atoi(argv[1]); + if (i < 0 || i > numdev) { + fprintf(stderr, "Invalid interface number %d !\n", i); + + return(1); + } + + /* Looks good, go and listen.. */ + i = start_cap(interfaces[i-1].device); return(i); } diff --git a/src/slirp/misc.c b/src/slirp/misc.c index b39a4d9a3..d3fb66b3d 100644 --- a/src/slirp/misc.c +++ b/src/slirp/misc.c @@ -91,14 +91,14 @@ getouraddr() char buff[512]; struct hostent *he = NULL; #define ANCIENT - #ifdef ANCIENT +#ifdef ANCIENT if (gethostname(buff,500) == 0) he = gethostbyname(buff); if (he) our_addr = *(struct in_addr *)he->h_addr; if (our_addr.s_addr == 0) our_addr.s_addr = loopback_addr.s_addr; - #else +#else if (gethostname(buff,256) == 0) { struct addrinfo hints = { 0 }; @@ -113,8 +113,9 @@ getouraddr() } if (our_addr.s_addr == 0) our_addr.s_addr = loopback_addr.s_addr; - #endif - #undef ANCIENT +#endif +#undef ANCIENT + pclog("My IP address: %s (%s)\n", inet_ntoa(our_addr), buff); } //#if SIZEOF_CHAR_P == 8 diff --git a/src/slirp/slirp.c b/src/slirp/slirp.c index eb803d236..c8861b965 100644 --- a/src/slirp/slirp.c +++ b/src/slirp/slirp.c @@ -36,7 +36,6 @@ extern int config_get_int(char *, char *, int); #ifdef _WIN32 - static int get_dns_addr(struct in_addr *pdns_addr) { FIXED_INFO *FixedInfo=NULL; @@ -68,7 +67,7 @@ static int get_dns_addr(struct in_addr *pdns_addr) pIPAddr = &(FixedInfo->DnsServerList); inet_aton(pIPAddr->IpAddress.String, &tmp_addr); *pdns_addr = tmp_addr; -#if 0 +#if 1 printf( "DNS Servers:\n" ); printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); @@ -123,9 +122,9 @@ static int get_dns_addr(struct in_addr *pdns_addr) return -1; return 0; } - #endif + #ifdef _WIN32 void slirp_cleanup(void) { @@ -649,6 +648,7 @@ void slirp_input(const uint8_t *pkt, int pkt_len) struct SLIRPmbuf *m; int proto; +pclog("SLIRP_input(%08lx, %d)\n", pkt, pkt_len); if (pkt_len < ETH_HLEN) return; diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index 3f4efd0bd..7ca179335 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -1,6 +1,8 @@ #ifndef __COMMON_H__ #define __COMMON_H__ +#define SLIRP_DEBUG 1 + #define SLIRP_VERSION "Cockatrice special" #define CONFIG_QEMU From 2e3ce399e2c6e6cd6a451d9efd0159031a49fa38 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 04:36:19 +0200 Subject: [PATCH 193/392] Changed network timer back to signed int, and made it default to 0 again - SLiRP now works again. --- src/net_ne2000.c | 2 +- src/network.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 80d836751..1ca0add6e 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -255,8 +255,8 @@ nelog(int lvl, const char *fmt, ...) vprintf(fmt, ap); va_end(ap); } -} #endif +} #define pclog nelog diff --git a/src/network.c b/src/network.c index ccacdeed9..dc996e6bb 100644 --- a/src/network.c +++ b/src/network.c @@ -38,7 +38,7 @@ typedef struct { static int net_handlers_num; -static uint32_t net_poll_time = 100; +static int net_poll_time = 0; static NETPOLL net_handlers[8]; static NETCARD net_cards[] = { { "None", "none", NULL }, @@ -59,7 +59,7 @@ net_poll(void *priv) int c; /* Reset the poll timer. */ - net_poll_time += (uint32_t)((double)TIMER_USEC * (1000000.0/8.0/3000.0)); + net_poll_time += (int)((double)TIMER_USEC * (1000000.0/8.0/3000.0)); /* If we have active cards.. */ if (net_handlers_num) { From 578619d11faa60d685ab8588db12eedf75e56ccd Mon Sep 17 00:00:00 2001 From: waltje Date: Tue, 9 May 2017 22:59:01 -0400 Subject: [PATCH 194/392] Cleaned up ibm.h, updated Bugger to use new UI function, misc network stuff. --- src/CPU/x86seg.c | 2 +- src/bugger.c | 6 +- src/ibm.h | 176 ++++++++++++++++++++++----------------------- src/network.c | 9 +-- src/scsi_aha154x.c | 2 +- src/slirp/misc.c | 4 ++ src/win-status.c | 11 --- 7 files changed, 99 insertions(+), 111 deletions(-) diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index 71fe5ccef..cc0cc6dbc 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -49,7 +49,7 @@ void x86abort(const char *format, ...) va_end(ap); fflush(stdout); savenvr(); - dumpregs(); + dumpregs(1); fflush(stdout); exit(-1); } diff --git a/src/bugger.c b/src/bugger.c index d9a79aafa..ce5ed03a9 100644 --- a/src/bugger.c +++ b/src/bugger.c @@ -44,7 +44,7 @@ * configuration register (CTRL_SPCFG bit set) but have to * remember that stuff first... * - * Version: @(#)bugger.c 1.0.3 2017/04/07 + * Version: @(#)bugger.c 1.0.4 2017/05/09 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -98,10 +98,8 @@ bug_setui(void) (bug_ledr&0x08)?'R':'r', (bug_ledr&0x04)?'R':'r', (bug_ledr&0x02)?'R':'r', (bug_ledr&0x01)?'R':'r'); -#if 0 /* Send formatted string to the UI. */ - set_bugui(bug_str); -#endif + status_settext(bug_str); } diff --git a/src/ibm.h b/src/ibm.h index e71d29ccb..44c9c1df6 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -7,9 +7,9 @@ #include #define printf pclog + /*Memory*/ uint8_t *ram; - uint32_t rammask; int readlookup[256],readlookupp[256]; @@ -25,32 +25,30 @@ extern int mmu_perm; #define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE)?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC)?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -uint8_t readmembl(uint32_t addr); -void writemembl(uint32_t addr, uint8_t val); -uint8_t readmemb386l(uint32_t seg, uint32_t addr); -void writememb386l(uint32_t seg, uint32_t addr, uint8_t val); -uint16_t readmemwl(uint32_t seg, uint32_t addr); -void writememwl(uint32_t seg, uint32_t addr, uint16_t val); -uint32_t readmemll(uint32_t seg, uint32_t addr); -void writememll(uint32_t seg, uint32_t addr, uint32_t val); -uint64_t readmemql(uint32_t seg, uint32_t addr); -void writememql(uint32_t seg, uint32_t addr, uint64_t val); +extern uint8_t readmembl(uint32_t addr); +extern void writemembl(uint32_t addr, uint8_t val); +extern uint8_t readmemb386l(uint32_t seg, uint32_t addr); +extern void writememb386l(uint32_t seg, uint32_t addr, uint8_t val); +extern uint16_t readmemwl(uint32_t seg, uint32_t addr); +extern void writememwl(uint32_t seg, uint32_t addr, uint16_t val); +extern uint32_t readmemll(uint32_t seg, uint32_t addr); +extern void writememll(uint32_t seg, uint32_t addr, uint32_t val); +extern uint64_t readmemql(uint32_t seg, uint32_t addr); +extern void writememql(uint32_t seg, uint32_t addr, uint64_t val); -uint8_t *getpccache(uint32_t a); - -uint32_t mmutranslatereal(uint32_t addr, int rw); - -void addreadlookup(uint32_t virt, uint32_t phys); -void addwritelookup(uint32_t virt, uint32_t phys); +extern uint8_t *getpccache(uint32_t a); +extern uint32_t mmutranslatereal(uint32_t addr, int rw); +extern void addreadlookup(uint32_t virt, uint32_t phys); +extern void addwritelookup(uint32_t virt, uint32_t phys); /*IO*/ -uint8_t inb(uint16_t port); -void outb(uint16_t port, uint8_t val); -uint16_t inw(uint16_t port); -void outw(uint16_t port, uint16_t val); -uint32_t inl(uint16_t port); -void outl(uint16_t port, uint32_t val); +extern uint8_t inb(uint16_t port); +extern void outb(uint16_t port, uint8_t val); +extern uint16_t inw(uint16_t port); +extern void outw(uint16_t port, uint16_t val); +extern uint32_t inl(uint16_t port); +extern void outl(uint16_t port, uint32_t val); extern int shadowbios,shadowbios_write; extern int mem_size; @@ -163,6 +161,9 @@ struct } cpu_state; #define cycles cpu_state._cycles +#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm +#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod +#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg #ifdef __MSC__ # define COMPILE_TIME_ASSERT(expr) /*nada*/ @@ -292,13 +293,8 @@ typedef struct PIT } PIT; PIT pit, pit2; -void setpitclock(float clock); - -float pit_timer0_freq(); - -#define cpu_rm cpu_state.rm_data.rm_mod_reg.rm -#define cpu_mod cpu_state.rm_data.rm_mod_reg.mod -#define cpu_reg cpu_state.rm_data.rm_mod_reg.reg +extern void setpitclock(float clock); +extern float pit_timer0_freq(void); @@ -649,24 +645,22 @@ extern uint32_t SCSIGetCDChannel(int channel); extern int ui_writeprot[4]; -void pclog(const char *format, ...); -void pclog_w(const wchar_t *format, ...); + extern int nmi; extern int nmi_auto_clear; - extern float isa_timing, bus_timing; -uint64_t timer_read(); +extern uint64_t timer_read(void); extern uint64_t timer_freq; extern int infocus; -void onesec(); +extern void onesec(void); -void resetpc_cad(); +extern void resetpc_cad(void); extern int dump_on_exit; extern int start_in_fullscreen; @@ -692,7 +686,6 @@ wchar_t *nvr_concat(wchar_t *to_concat); int mem_a20_state; -void fatal(const char *format, ...); #ifdef ENABLE_LOG_TOGGLES extern int buslogic_do_log; @@ -714,65 +707,72 @@ typedef struct PCI_RESET extern PCI_RESET pci_reset_handler; -uint8_t trc_read(uint16_t port, void *priv); -void trc_write(uint16_t port, uint8_t val, void *priv); -void trc_init(); +extern uint8_t trc_read(uint16_t port, void *priv); +extern void trc_write(uint16_t port, uint8_t val, void *priv); +extern void trc_init(void); extern int enable_xtide; extern int enable_external_fpu; +extern int serial_enabled[2]; +extern int lpt_enabled, bugger_enabled; + extern int invert_display; uint32_t svga_color_transform(uint32_t color); extern int scale; -/* Function prototypes. */ -int checkio(int port); -void closepc(); -void codegen_block_end(); -void codegen_reset(); -void cpu_set_edx(); -int divl(uint32_t val); -void dumpregs(); -void exec386(int cycs); -void exec386_dynarec(int cycs); -void execx86(int cycs); -void flushmmucache(); -void flushmmucache_cr3(); -int idivl(int32_t val); -void initpc(int argc, wchar_t *argv[]); -void loadcscall(uint16_t seg); -void loadcsjmp(uint16_t seg, uint32_t oxpc); -void mmu_invalidate(uint32_t addr); -void pclog(const char *format, ...); -void pmodeint(int num, int soft); -void pmoderetf(int is32, uint16_t off); -void pmodeiret(int is32); -void port_92_clear_reset(); -uint8_t readdacfifo(); -void refreshread(); -int rep386(int fv); -void resetmcr(); -void resetpchard(); -void resetreadlookup(); -void resetx86(); -void runpc(); -void saveconfig(); -void softresetx86(); -void speedchanged(); -void status_settextw(wchar_t *wstr); -void status_settext(char *str); -void trc_reset(uint8_t val); -void update_status_bar_icon(int tag, int active); -void update_status_bar_icon_state(int tag, int state); -void x86_int_sw(int num); -void x86gpf(char *s, uint16_t error); -void x86np(char *s, uint16_t error); -void x86ss(char *s, uint16_t error); -void x86ts(char *s, uint16_t error); -void x87_dumpregs(); -void x87_reset(); -extern int serial_enabled[2]; -extern int lpt_enabled, bugger_enabled; +/* Function prototypes. */ +extern int checkio(int port); +extern void closepc(void); +extern void codegen_block_end(void); +extern void codegen_reset(void); +extern void cpu_set_edx(void); +extern int divl(uint32_t val); +extern void dumpregs(int __force); +extern void exec386(int cycs); +extern void exec386_dynarec(int cycs); +extern void execx86(int cycs); +extern void flushmmucache(void); +extern void flushmmucache_cr3(void); +extern int idivl(int32_t val); +extern void initpc(int argc, wchar_t *argv[]); +extern void loadcscall(uint16_t seg); +extern void loadcsjmp(uint16_t seg, uint32_t oxpc); +extern void mmu_invalidate(uint32_t addr); +extern void pclog(const char *format, ...); +extern void pmodeint(int num, int soft); +extern void pmoderetf(int is32, uint16_t off); +extern void pmodeiret(int is32); +extern void port_92_clear_reset(void); +extern uint8_t readdacfifo(void); +extern void refreshread(void); +extern int rep386(int fv); +extern void resetmcr(void); +extern void resetpchard(void); +extern void resetreadlookup(void); +extern void resetx86(void); +extern void runpc(void); +extern void saveconfig(void); +extern void softresetx86(void); +extern void speedchanged(void); +extern void trc_reset(uint8_t val); +extern void x86_int_sw(int num); +extern void x86gpf(char *s, uint16_t error); +extern void x86np(char *s, uint16_t error); +extern void x86ss(char *s, uint16_t error); +extern void x86ts(char *s, uint16_t error); +extern void x87_dumpregs(void); +extern void x87_reset(void); + +/* Platform functions. */ +extern void pclog(const char *format, ...); +extern void pclog_w(const wchar_t *format, ...); +extern void fatal(const char *format, ...); + +extern void update_status_bar_icon(int tag, int active); +extern void update_status_bar_icon_state(int tag, int state); +extern void status_settextw(wchar_t *wstr); +extern void status_settext(char *str); diff --git a/src/network.c b/src/network.c index ccacdeed9..8889bd248 100644 --- a/src/network.c +++ b/src/network.c @@ -8,7 +8,7 @@ * * Implementation of the network module. * - * Version: @(#)network.c 1.0.1 2017/05/09 + * Version: @(#)network.c 1.0.2 2017/05/09 * * Authors: Kotori, * Fred N. van Kempen, @@ -38,7 +38,7 @@ typedef struct { static int net_handlers_num; -static uint32_t net_poll_time = 100; +static int net_poll_time; static NETPOLL net_handlers[8]; static NETCARD net_cards[] = { { "None", "none", NULL }, @@ -75,12 +75,9 @@ net_poll(void *priv) void network_init(void) { - /* No network interface right now. */ network_card_current = 0; net_handlers_num = 0; - - /* This should be a config value, really. --FvK */ - net_poll_time = 100; + net_poll_time = 0; } diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 253d4929c..316679ab8 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -859,7 +859,7 @@ enum { }; -#ifdef WALTJE +#ifdef xWALTJE int aha_do_log = 1; # define ENABLE_AHA154X_LOG #else diff --git a/src/slirp/misc.c b/src/slirp/misc.c index d3fb66b3d..39dc1e6e5 100644 --- a/src/slirp/misc.c +++ b/src/slirp/misc.c @@ -82,6 +82,10 @@ inet_aton(cp, ia) } #endif + +extern void pclog(char *fmt, ...); + + /* * Get our IP address and put it in our_addr */ diff --git a/src/win-status.c b/src/win-status.c index 858a3646c..a39d38700 100644 --- a/src/win-status.c +++ b/src/win-status.c @@ -93,14 +93,3 @@ void status_open(HWND hwnd) status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); ShowWindow(status_hwnd, SW_SHOW); } - - -#if 0 -void -set_bugui(char *str) -{ - if (str == NULL) - str = "L:R GGGGGGGG-RRRRRRRR"; - SendMessage(status_hwnd, SB_SETTEXT, 2, (WPARAM)str); -} -#endif From 53317aed28b599a964e93ff72d8587aad4e451c9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 14:52:38 +0200 Subject: [PATCH 195/392] Fixed device configuration name mistakes in scsi_buslogic.c; Improvements/fixes for MPU-401 and win-midi.c, NT 3.51 Extended MIDI now works, but Princess Maker 2 is still silent (looking into that as we speak). --- src/SOUND/snd_mpu401.c | 25 +++--- src/scsi_buslogic.c | 4 +- src/win-midi.c | 199 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 214 insertions(+), 14 deletions(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index b56283e05..526eecf84 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -253,7 +253,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) static void MPU401_WriteData(mpu_t *mpu, uint8_t val) { - if (mpu->mode==M_UART) {midi_write(val);} + if (mpu->mode==M_UART) {midi_write(val); return;} switch (mpu->state.command_byte) { /* 0xe# command data */ @@ -634,14 +634,17 @@ next_event: void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) { - mpu->status = STATUS_INPUT_NOT_READY; - mpu->irq = irq; - mpu->queue_used = 0; - mpu->queue_pos = 0; - mpu->mode = mode; - - io_sethandler(addr, 0x0002, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); - timer_add(MPU401_Event, &mpu401_event_callback, &mpu401_event_callback, mpu); - - MPU401_Reset(mpu); + mpu->status = STATUS_INPUT_NOT_READY; + mpu->irq = irq; + mpu->queue_used = 0; + mpu->queue_pos = 0; + mpu->mode = M_UART; + + mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; + + io_sethandler(addr, 0x0002, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_sethandler(0x2A20, 0x0010, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + timer_add(MPU401_Event, &mpu401_event_callback, &mpu401_event_callback, mpu); + + MPU401_Reset(mpu); } diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 14e6a249a..c5155d4ea 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -2373,7 +2373,7 @@ static device_config_t BuslogicConfig[] = { device_t buslogic_device = { - "Buslogic BT-542B PCI", + "Buslogic BT-542B ISA", 0, Buslogic_542B_Init, BuslogicClose, @@ -2385,7 +2385,7 @@ device_t buslogic_device = { }; device_t buslogic_pci_device = { - "Buslogic BT-542B PCI", + "Buslogic BT-958D PCI", 0, Buslogic_958D_Init, BuslogicClose, diff --git a/src/win-midi.c b/src/win-midi.c index 8fa56c768..621510ab2 100644 --- a/src/win-midi.c +++ b/src/win-midi.c @@ -10,21 +10,33 @@ static int midi_id; static HMIDIOUT midi_out_device = NULL; +HANDLE m_event; + void midi_close(); void midi_init() { - MMRESULT hr; + MMRESULT hr = MMSYSERR_NOERROR; midi_id = config_get_int(NULL, "midi", 0); + m_event = CreateEvent(NULL, TRUE, TRUE, NULL); + +#if 0 hr = midiOutOpen(&midi_out_device, midi_id, 0, 0, CALLBACK_NULL); +#endif + hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, + 0, CALLBACK_EVENT); if (hr != MMSYSERR_NOERROR) { printf("midiOutOpen error - %08X\n",hr); midi_id = 0; +#if 0 hr = midiOutOpen(&midi_out_device, midi_id, 0, 0, CALLBACK_NULL); +#endif + hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, + 0, CALLBACK_EVENT); if (hr != MMSYSERR_NOERROR) { printf("midiOutOpen error - %08X\n",hr); return; @@ -41,6 +53,7 @@ void midi_close() midiOutReset(midi_out_device); midiOutClose(midi_out_device); midi_out_device = NULL; + CloseHandle(m_event); } } @@ -81,6 +94,7 @@ static void midi_send_sysex() midi_insysex = 0; } +#if 0 void midi_write(uint8_t val) { if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) @@ -111,3 +125,186 @@ void midi_write(uint8_t val) midiOutShortMsg(midi_out_device, midi_command); } } +#endif + +static uint8_t midi_rt_buf[1024] = { 0, 0, 0, 0 }; +static uint8_t midi_cmd_buf[1024] = { 0, 0, 0, 0 }; +static int midi_cmd_pos = 0; +static int midi_cmd_len = 0; +static uint8_t midi_status = 0; +static int midi_sysex_start = 0; +static int midi_sysex_delay = 0; + +uint8_t MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 +}; + +void PlayMsg(uint8_t *msg) +{ + midiOutShortMsg(midi_out_device, *(uint32_t *) msg); +} + +MIDIHDR m_hdr; + +void PlaySysex(uint8_t *sysex, unsigned int len) +{ + MMRESULT result; + + if (WaitForSingleObject(m_event, 2000) == WAIT_TIMEOUT) + { + pclog("Can't send MIDI message\n"); + return; + } + + midiOutUnprepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); + + m_hdr.lpData = (char *) sysex; + m_hdr.dwBufferLength = len; + m_hdr.dwBytesRecorded = len; + m_hdr.dwUser = 0; + + result = midiOutPrepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); + + if (result != MMSYSERR_NOERROR) return; + ResetEvent(m_event); + result = midiOutLongMsg(midi_out_device, &m_hdr, sizeof(m_hdr)); + if (result != MMSYSERR_NOERROR) + { + SetEvent(m_event); + return; + } +} + +#define SYSEX_SIZE 1024 +#define RAWBUF 1024 + +int GetTicks() +{ +} + +void midi_write(uint8_t val) +{ + /* Test for a realtime MIDI message */ + if (val >= 0xf8) + { + midi_rt_buf[0] = val; + PlayMsg(midi_rt_buf); + return; + } + + /* Test for a active sysex transfer */ + + if (midi_status == 0xf0) + { + if (!(val & 0x80)) + { + if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; + return; + } + else + { + midi_sysex_data[midi_pos++] = 0xf7; + + if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) + { + /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ + } + else + { + PlaySysex(midi_sysex_data, midi_pos); + if (midi_sysex_start) + { + if (midi_sysex_data[5] == 0x7f) + { + midi_sysex_delay = 290; /* All parameters reset */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) + { + midi_sysex_delay = 145; /* Viking Child */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) + { + midi_sysex_delay = 30; /* Dark Sun 1 */ + } + else + midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; + + midi_sysex_start = GetTicks(); + } + } + } + } + + + if (val & 0x80) + { + midi_status = val; + midi_cmd_pos = 0; + midi_cmd_len = MIDI_evt_len[val]; + if (midi_status == 0xf0) + { + midi_sysex_data[0] = 0xf0; + midi_pos = 1; + } + } + + if (midi_cmd_len) + { + midi_cmd_buf[midi_cmd_pos++] = val; + if (midi_cmd_pos >= midi_cmd_len) + { + PlayMsg(midi_cmd_buf); + midi_cmd_pos = 1; + } + } +} + +void midi_reset() +{ + uint8_t buf[64], used; + + /* Flush buffers */ + midiOutReset(midi_out_device); + + /* GM1 reset */ + buf[0] = 0xf0; + buf[1] = 0x7e; + buf[2] = 0x7f; + buf[3] = 0x09; + buf[4] = 0x01; + buf[5] = 0xf7; + PlaySysex((uint8_t *) buf, 6); + + /* GS1 reset */ + buf[0] = 0xf0; + buf[1] = 0x41; + buf[2] = 0x10; + buf[3] = 0x42; + buf[4] = 0x12; + buf[5] = 0x40; + buf[6] = 0x00; + buf[7] = 0x7f; + buf[8] = 0x00; + buf[9] = 0x41; + buf[10] = 0xf7; + PlaySysex((uint8_t *) buf, 11); +} From 8576e2523bce461f9bf24694d0f7ec0e714955cf Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 10 May 2017 18:29:16 +0200 Subject: [PATCH 196/392] Implemented Sound Blaster MIDI through the DSP (was surprisingly missing before). Native Windows 3.1 and NT Sound Blaster drivers can now use their DSP to drive the MIDI out. Added MIDI out config to pre-SB16's for this new change. --- src/SOUND/snd_mpu401.c | 75 +++++++++++++++++++++++------------------- src/SOUND/snd_mpu401.h | 2 ++ src/SOUND/snd_sb.c | 9 +++++ src/SOUND/snd_sb_dsp.c | 35 ++++++++++++++++++++ src/SOUND/snd_sb_dsp.h | 6 +++- 5 files changed, 93 insertions(+), 34 deletions(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 526eecf84..5fcb15484 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -528,6 +528,47 @@ static void MPU401_EOIHandlerDispatch(void *p) MPU401_EOIHandler(mpu, 0); } +uint8_t MPU401_ReadData(mpu_t *mpu) +{ + uint8_t ret; + + ret = MSG_MPU_ACK; + if (mpu->queue_used) + { + if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; + ret=mpu->queue[mpu->queue_pos]; + mpu->queue_pos++;mpu->queue_used--; + } + if (!mpu->intelligent) return ret; + + if (mpu->queue_used == 0) picintc(1 << mpu->irq); + + if (ret>=0xf0 && ret<=0xf7) + { /* MIDI data request */ + mpu->state.channel=ret&7; + mpu->state.data_onoff=0; + mpu->state.cond_req=0; + } + if (ret==MSG_MPU_COMMAND_REQ) + { + mpu->state.data_onoff=0; + mpu->state.cond_req=1; + if (mpu->condbuf.type!=T_OVERFLOW) + { + mpu->state.block_ack=1; + MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); + if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); + } + mpu->condbuf.type=T_OVERFLOW; + } + if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { + mpu->state.data_onoff=-1; + MPU401_EOIHandlerDispatch(mpu); + } + + return ret; +} + static void mpu401_write(uint16_t addr, uint8_t val, void *p) { mpu_t *mpu = (mpu_t *)p; @@ -554,39 +595,7 @@ static uint8_t mpu401_read(uint16_t addr, void *p) switch (addr & 1) { case 0: //Read Data - ret = MSG_MPU_ACK; - if (mpu->queue_used) - { - if (mpu->queue_pos>=MPU401_QUEUE) mpu->queue_pos-=MPU401_QUEUE; - ret=mpu->queue[mpu->queue_pos]; - mpu->queue_pos++;mpu->queue_used--; - } - if (!mpu->intelligent) return ret; - - if (mpu->queue_used == 0) picintc(1 << mpu->irq); - - if (ret>=0xf0 && ret<=0xf7) - { /* MIDI data request */ - mpu->state.channel=ret&7; - mpu->state.data_onoff=0; - mpu->state.cond_req=0; - } - if (ret==MSG_MPU_COMMAND_REQ) - { - mpu->state.data_onoff=0; - mpu->state.cond_req=1; - if (mpu->condbuf.type!=T_OVERFLOW) - { - mpu->state.block_ack=1; - MPU401_WriteCommand(mpu, mpu->condbuf.value[0]); - if (mpu->state.command_byte) MPU401_WriteData(mpu, mpu->condbuf.value[1]); - } - mpu->condbuf.type=T_OVERFLOW; - } - if (ret==MSG_MPU_END || ret==MSG_MPU_CLOCK || ret==MSG_MPU_ACK) { - mpu->state.data_onoff=-1; - MPU401_EOIHandlerDispatch(mpu); - } + ret = MPU401_ReadData(mpu); break; case 1: //Read Status diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h index d8eedc25b..8cb721883 100644 --- a/src/SOUND/snd_mpu401.h +++ b/src/SOUND/snd_mpu401.h @@ -58,4 +58,6 @@ typedef struct mpu_t } clock; } mpu_t; +uint8_t MPU401_ReadData(mpu_t *mpu); + void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 0308fa632..d5dee73d0 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -780,6 +780,9 @@ static device_config_t sb_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -818,6 +821,9 @@ static device_config_t sb_mcv_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } @@ -873,6 +879,9 @@ static device_config_t sb_pro_config[] = } } }, + { + "midi", "MIDI out device", CONFIG_MIDI, "", 0 + }, { "", "", -1 } diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 16215d05e..f078cede9 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -11,8 +11,10 @@ #include "../dma.h" #include "../timer.h" #include "sound.h" +#include "snd_mpu401.h" #include "snd_sb_dsp.h" +mpu_t mpu; void pollsb(void *p); void sb_poll_i(void *p); @@ -321,6 +323,29 @@ void sb_exec_command(sb_dsp_t *dsp) temp = 1000000 / temp; dsp->sb_freq = temp; break; + + case 0x30: + case 0x31: + break; + + case 0x34: + dsp->uart_midi = 1; + dsp->uart_irq = 0; + break; + + case 0x35: + dsp->uart_midi = 1; + dsp->uart_irq = 1; + break; + + case 0x36: + case 0x37: + break; + + case 0x38: + dsp->onebyte_midi = 1; + break; + case 0x41: /*Set output sampling rate*/ case 0x42: /*Set input sampling rate*/ if (dsp->sb_type < SB16) break; @@ -514,6 +539,12 @@ void sb_write(uint16_t a, uint8_t v, void *priv) dsp->sbreset = v; return; case 0xC: /*Command/data write*/ + if (dsp->uart_midi || dsp->onebyte_midi) + { + midi_write(v); + dsp->onebyte_midi = 0; + return; + } timer_process(); dsp->wb_time = TIMER_USEC * 1; dsp->wb_full = 1; @@ -549,6 +580,10 @@ uint8_t sb_read(uint16_t a, void *priv) switch (a & 0xf) { case 0xA: /*Read data*/ + if (dsp->uart_midi) + { + return MPU401_ReadData(&mpu); + } dsp->sbreaddat = dsp->sb_read_data[dsp->sb_read_rp]; if (dsp->sb_read_rp != dsp->sb_read_wp) { diff --git a/src/SOUND/snd_sb_dsp.h b/src/SOUND/snd_sb_dsp.h index 9d4dee133..fb14284fa 100644 --- a/src/SOUND/snd_sb_dsp.h +++ b/src/SOUND/snd_sb_dsp.h @@ -1,5 +1,9 @@ typedef struct sb_dsp_t -{ +{ + int uart_midi; + int uart_irq; + int onebyte_midi; + int sb_type; int sb_8_length, sb_8_format, sb_8_autoinit, sb_8_pause, sb_8_enable, sb_8_autolen, sb_8_output; From c165fdbaea502ba9572ead683e2a4164070ab803 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 20:39:46 +0200 Subject: [PATCH 197/392] Fixed DOSBox OPL to correctly use OPL3 when it's used for such - patch from TheCollector1995; Merged my own MPU-401 improvements with TheCollector1995's. --- src/SOUND/snd_dbopl.cc | 4 +-- src/SOUND/snd_mpu401.c | 69 +++++++++++++++++++++++++++++++++--------- src/SOUND/snd_sb_dsp.c | 1 + 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/SOUND/snd_dbopl.cc b/src/SOUND/snd_dbopl.cc index bf3260b84..cecc1c35e 100644 --- a/src/SOUND/snd_dbopl.cc +++ b/src/SOUND/snd_dbopl.cc @@ -44,8 +44,8 @@ void opl_init(void (*timer_callback)(void *param, int timer, int64_t period), vo { if (!is_opl3 || !opl3_type) { - DBOPL::InitTables(); - opl[nr].chip.Setup(48000, 0); + DBOPL::InitTables(); + opl[nr].chip.Setup(48000, is_opl3); opl[nr].timer_callback = timer_callback; opl[nr].timer_param = timer_param; opl[nr].is_opl3 = is_opl3; diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 5fcb15484..00fbe21f5 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -15,6 +15,8 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); static void MPU401_EOIHandlerDispatch(void *p); static int mpu401_event_callback = 0; +static int mpu401_eoi_callback = 0; +static int mpu401_reset_callback = 0; static void QueueByte(mpu_t *mpu, uint8_t data) { @@ -88,8 +90,14 @@ static void MPU401_Reset(mpu_t *mpu) for (i=0;i<8;i++) {mpu->playbuf[i].type=T_OVERFLOW;mpu->playbuf[i].counter=0;} } -static void MPU401_ResetDone(mpu_t *mpu, int reset) +static void MPU401_ResetDone(void *p) { + mpu_t *mpu = (mpu_t *)p; + + pclog("MPU-401 reset callback\n"); + + mpu401_reset_callback = 0; + mpu->state.reset=0; if (mpu->state.cmd_pending) { @@ -121,6 +129,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) { case 0x4: /* Stop */ mpu->state.playing=0; + mpu401_event_callback = 0; for (i=0xb0;i<0xbf;i++) { /* All notes off */ midi_write(i); @@ -131,7 +140,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) case 0x8: /* Play */ // LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started"); mpu->state.playing=1; - mpu401_event_callback = MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase); + mpu401_event_callback = (MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase)) * TIMER_USEC; ClrQueue(mpu); break; } @@ -236,7 +245,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) break; case 0xff: /* Reset MPU-401 */ pclog("MPU-401:Reset %X\n",val); - MPU401_ResetDone(mpu, MPU401_RESETBUSY); + mpu401_reset_callback = MPU401_RESETBUSY * TIMER_USEC; mpu->state.reset=1; MPU401_Reset(mpu); if (mpu->mode==M_UART) return;//do not send ack in UART mode @@ -492,10 +501,14 @@ static void UpdateConductor(mpu_t *mpu) } //Updates counters and requests new data on "End of Input" -static void MPU401_EOIHandler(void *p, uint8_t val) +static void MPU401_EOIHandler(void *p) { mpu_t *mpu = (mpu_t *)p; + uint8_t i; + + pclog("MPU-401 end of input callback\n"); + mpu401_eoi_callback = 0; mpu->state.eoi_scheduled=0; if (mpu->state.send_now) { @@ -504,8 +517,8 @@ static void MPU401_EOIHandler(void *p, uint8_t val) else UpdateTrack(mpu, mpu->state.channel); } mpu->state.irq_pending=0; - if (!mpu->state.playing || !mpu->state.req_mask) return; - uint8_t i=0; + if (!mpu->state.playing || !mpu->state.req_mask) return; + i=0; do { if (mpu->state.req_mask&(1<state.send_now) { mpu->state.eoi_scheduled=1; - MPU401_EOIHandler(mpu, 0.06f); //Possible a bit longer + mpu401_eoi_callback = 0.06f * TIMER_USEC; /* Possible a bit longer */ } else if (!mpu->state.eoi_scheduled) - MPU401_EOIHandler(mpu, 0); + MPU401_EOIHandler(mpu); +} + +static void imf_write(uint16_t addr, uint8_t val, void *p) +{ + pclog("IMF:Wr %4X,%X\n", addr, val); } uint8_t MPU401_ReadData(mpu_t *mpu) @@ -613,8 +631,15 @@ static void MPU401_Event(void *p) { mpu_t *mpu = (mpu_t *)p; uint8_t i; + int new_time; + + pclog("MPU-401 event callback\n"); - if (mpu->mode==M_UART) return; + if (mpu->mode==M_UART) + { + mpu401_event_callback = 0; + return; + } if (mpu->state.irq_pending) goto next_event; for (i=0;i<8;i++) { /* Decrease counters */ if (mpu->state.amask&(1<state.req_mask|=(1<<13); } } - if (!mpu->state.irq_pending && mpu->state.req_mask) MPU401_EOIHandler(mpu, 0); + if (!mpu->state.irq_pending && mpu->state.req_mask) MPU401_EOIHandler(mpu); next_event: - mpu401_event_callback = 0; - int new_time; - if ((new_time=mpu->clock.tempo*mpu->clock.timebase)==0) return; - mpu401_event_callback = MPU401_TIMECONSTANT/new_time; + /* mpu401_event_callback = 0; */ + new_time = (mpu->clock.tempo * mpu->clock.timebase); + if (new_time == 0) + { + mpu401_event_callback = 0; + return; + } + else + { + mpu401_event_callback += (MPU401_TIMECONSTANT/new_time) * TIMER_USEC; + pclog("Next event after %i us\n", (MPU401_TIMECONSTANT/new_time) * TIMER_USEC); + } } void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) @@ -651,9 +684,15 @@ void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; + mpu401_event_callback = 0; + mpu401_eoi_callback = 0; + mpu401_reset_callback = 0; + io_sethandler(addr, 0x0002, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); - io_sethandler(0x2A20, 0x0010, mpu401_read, NULL, NULL, mpu401_write, NULL, NULL, mpu); + io_sethandler(0x2A20, 0x0010, NULL, NULL, NULL, imf_write, NULL, NULL, mpu); timer_add(MPU401_Event, &mpu401_event_callback, &mpu401_event_callback, mpu); + timer_add(MPU401_EOIHandler, &mpu401_eoi_callback, &mpu401_eoi_callback, mpu); + timer_add(MPU401_ResetDone, &mpu401_reset_callback, &mpu401_reset_callback, mpu); MPU401_Reset(mpu); } diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index f078cede9..92f7cacd0 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -9,6 +9,7 @@ #include "../io.h" #include "../pic.h" #include "../dma.h" +#include "../plat-midi.h" #include "../timer.h" #include "sound.h" #include "snd_mpu401.h" From 619ad20cf3ce5c6829dcff2a411689c927ecec84 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 22:52:11 +0200 Subject: [PATCH 198/392] MPU-401 is now initialized in the correct mode (specified in configuration file / Settings dialog) and intelligent mode works properly, tested with Princess Maker 2 in both MIDI (MT-32) and General MIDI modes. --- src/SOUND/snd_mpu401.c | 49 ++++++++++++++++++++++++++++++++++-------- src/SOUND/snd_sb.c | 4 ++-- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 00fbe21f5..14e18192a 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -5,6 +5,8 @@ #include "../plat-midi.h" #include "snd_mpu401.h" +#include + enum { STATUS_OUTPUT_NOT_READY = 0x40, @@ -18,6 +20,30 @@ static int mpu401_event_callback = 0; static int mpu401_eoi_callback = 0; static int mpu401_reset_callback = 0; +#ifdef ENABLE_MPU401_LOG +static int mpu401_do_log = 1; +static char logfmt[512]; +#endif + +static void +mpulog(const char *fmt, ...) +{ +#ifdef ENABLE_MPU401_LOG + va_list ap; + + if (mpu401_do_log) { + va_start(ap, fmt); + memset(logfmt, 0, 512); + strcpy(logfmt, "MPU-401: "); + strcpy(logfmt + strlen(logfmt), fmt); + vprintf(logfmt, ap); + va_end(ap); + } +#endif +} +#define pclog mpulog + + static void QueueByte(mpu_t *mpu, uint8_t data) { if (mpu->state.block_ack) @@ -140,7 +166,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) case 0x8: /* Play */ // LOG(LOG_MISC,LOG_NORMAL)("MPU-401:Intelligent mode playback started"); mpu->state.playing=1; - mpu401_event_callback = (MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase)) * TIMER_USEC; + mpu401_event_callback = (MPU401_TIMECONSTANT / (mpu->clock.tempo*mpu->clock.timebase)) * 1000 * TIMER_USEC; ClrQueue(mpu); break; } @@ -245,7 +271,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) break; case 0xff: /* Reset MPU-401 */ pclog("MPU-401:Reset %X\n",val); - mpu401_reset_callback = MPU401_RESETBUSY * TIMER_USEC; + mpu401_reset_callback = MPU401_RESETBUSY * 1000 * TIMER_USEC; mpu->state.reset=1; MPU401_Reset(mpu); if (mpu->mode==M_UART) return;//do not send ack in UART mode @@ -535,7 +561,7 @@ static void MPU401_EOIHandlerDispatch(void *p) if (mpu->state.send_now) { mpu->state.eoi_scheduled=1; - mpu401_eoi_callback = 0.06f * TIMER_USEC; /* Possible a bit longer */ + mpu401_eoi_callback = 60 * TIMER_USEC; /* Possible a bit longer */ } else if (!mpu->state.eoi_scheduled) MPU401_EOIHandler(mpu); @@ -591,16 +617,18 @@ static void mpu401_write(uint16_t addr, uint8_t val, void *p) { mpu_t *mpu = (mpu_t *)p; - pclog("MPU401 Write Port %04X, val %x\n", addr, val); + /* pclog("MPU401 Write Port %04X, val %x\n", addr, val); */ switch (addr & 1) { case 0: /*Data*/ MPU401_WriteData(mpu, val); + pclog("Write Data (0x330) %X\n", val); break; case 1: /*Command*/ MPU401_WriteCommand(mpu, val); + pclog("Write Command (0x331) %x\n", val); break; } } @@ -614,15 +642,17 @@ static uint8_t mpu401_read(uint16_t addr, void *p) { case 0: //Read Data ret = MPU401_ReadData(mpu); + pclog("Read Data (0x330) %X\n", ret); break; case 1: //Read Status - mpu->status = 0x3f; /* Bits 6 and 7 clear */ + ret = 0x3f; /* Bits 6 and 7 clear */ if (mpu->state.cmd_pending) ret|=STATUS_OUTPUT_NOT_READY; if (!mpu->queue_used) ret|=STATUS_INPUT_NOT_READY; - return mpu->status; + pclog("Read Status (0x331) %x\n", ret); + break; } - pclog("MPU401 Read Port %04X, ret %x\n", addr, ret); + /* pclog("MPU401 Read Port %04X, ret %x\n", addr, ret); */ return ret; } @@ -669,8 +699,8 @@ next_event: } else { - mpu401_event_callback += (MPU401_TIMECONSTANT/new_time) * TIMER_USEC; - pclog("Next event after %i us\n", (MPU401_TIMECONSTANT/new_time) * TIMER_USEC); + mpu401_event_callback += (MPU401_TIMECONSTANT/new_time) * 1000 * TIMER_USEC; + pclog("Next event after %i us (time constant: %i)\n", (int) ((MPU401_TIMECONSTANT/new_time) * 1000 * TIMER_USEC), (int) MPU401_TIMECONSTANT); } } @@ -683,6 +713,7 @@ void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) mpu->mode = M_UART; mpu->intelligent = (mode == M_INTELLIGENT) ? 1 : 0; + pclog("Starting as %s (mode is %s)\n", mpu->intelligent ? "INTELLIGENT" : "UART", (mode == M_INTELLIGENT) ? "INTELLIGENT" : "UART"); mpu401_event_callback = 0; mpu401_eoi_callback = 0; diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index d5dee73d0..d1471ee34 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -1007,7 +1007,7 @@ static device_config_t sb_16_config[] = "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, { - "mode", "MPU-401 mode", CONFIG_SELECTION, "", 1, + "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, { { "UART", M_UART @@ -1145,7 +1145,7 @@ static device_config_t sb_awe32_config[] = "midi", "MIDI out device", CONFIG_MIDI, "", 0 }, { - "mode", "MPU-401 mode", CONFIG_SELECTION, "", 1, + "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, { { "UART", M_UART From 08cf490f3f5aa50cb33e6e3387ca9029aed90957 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 10 May 2017 23:16:30 +0200 Subject: [PATCH 199/392] Removed the Dell System 200. --- src/mem.c | 12 ------------ src/model.c | 1 - src/nvr.c | 2 -- 3 files changed, 15 deletions(-) diff --git a/src/mem.c b/src/mem.c index 2e087651f..b6651ad20 100644 --- a/src/mem.c +++ b/src/mem.c @@ -306,18 +306,6 @@ int loadbios() fclose(f); biosmask = 0x7fff; return 1; - case ROM_DELL200: - f=romfopen(L"roms/dells200/dell0.bin",L"rb"); - ff=romfopen(L"roms/dells200/dell1.bin",L"rb"); - if (!f || !ff) break; - for (c=0x0000;c<0x10000;c+=2) - { - rom[c]=getc(f); - rom[c+1]=getc(ff); - } - fclose(ff); - fclose(f); - return 1; case ROM_AMI386SX: f=romfopen(L"roms/ami386/ami386.bin",L"rb"); if (!f) break; diff --git a/src/model.c b/src/model.c index 3b3b8f9b5..5be1bab9c 100644 --- a/src/model.c +++ b/src/model.c @@ -158,7 +158,6 @@ MODEL models[] = {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, - {"DELL System 200", ROM_DELL200, "dells200", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index acfa6c4d7..f3490260a 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -210,7 +210,6 @@ void loadnvr() case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"rb"); break; case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"rb"); nvrmask = 127; break; case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"rb"); nvrmask = 127; break; - case ROM_DELL200: f = nvrfopen(L"dell200.nvr", L"rb"); nvrmask = 127; break; case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"rb"); nvrmask = 127; break; case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"rb"); nvrmask = 127; break; case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"rb"); nvrmask = 127; break; @@ -295,7 +294,6 @@ void savenvr() case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"wb"); break; case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"wb"); break; case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"wb"); break; - case ROM_DELL200: f = nvrfopen(L"dell200.nvr", L"wb"); break; case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"wb"); break; case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"wb"); break; case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"wb"); break; From 18e21107392ab927d7dc362c826c5859dc7ca069 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 May 2017 06:34:25 +0200 Subject: [PATCH 200/392] Both SCSI controllers now set the next callback to be issued after 1000 * TIMER_USEC instead of 50 * TIMER_USEC if the device is CD-ROM and the command is 0x42 (READ SUBCHANNEL); A few CD-ROM IOCTL commands are cached now; CD Audio over IOCTL works again; The status bar icons are now only loaded once at emulator start, and subsequently just used on demand. --- src/cdrom-ioctl.c | 62 +++++++++++++++++++++++++++++--------- src/cdrom.c | 6 +++- src/cdrom.h | 7 +++++ src/scsi_aha154x.c | 6 ++++ src/scsi_buslogic.c | 6 ++++ src/win.c | 73 ++++++++++++++++++++++++++++++--------------- 6 files changed, 121 insertions(+), 39 deletions(-) diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 3534dd2e2..98c7cc538 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -107,6 +107,11 @@ static int get_track_nr(uint8_t id, uint32_t pos) return 0; } + if (cdrom_ioctl[id].last_track_pos == pos) + { + return cdrom_ioctl[id].last_track_nr; + } + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) { uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + @@ -118,6 +123,9 @@ static int get_track_nr(uint8_t id, uint32_t pos) track = c; } } + cdrom_ioctl[id].last_track_pos = pos; + cdrom_ioctl[id].last_track_nr = track; + return track; } @@ -349,19 +357,35 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) CDROM_SUB_Q_DATA_FORMAT insub; SUB_Q_CHANNEL_DATA sub; unsigned long size; - int pos=0; + int pos = 0, track; + uint32_t cdpos, track_address, dat; + if (!cdrom_drives[id].host_drive) return 0; - - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); - ioctl_close(id); + + cdpos = cdrom[id].seek_pos; + + if (cdrom_ioctl[id].last_subchannel_pos == cdpos) + { + memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); + memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); + } + else + { + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); + ioctl_close(id); + memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); + memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); + memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); + memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); + cdrom_ioctl[id].last_subchannel_pos = cdpos; + } if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) { - uint32_t cdpos = cdrom[id].seek_pos; - int track = get_track_nr(id, cdpos); - uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); + track = get_track_nr(id, cdpos); + track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); @@ -371,7 +395,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (msf) { - uint32_t dat = cdpos; + dat = cdpos; b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; b[pos + 1] = (uint8_t)dat; @@ -709,11 +733,19 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; UCHAR buf[16]; - ioctl_open(id, 0); + if (!cdrom_ioctl[id].capacity_read) + { + ioctl_open(id, 0); - SCSICommand(id, cdb, buf, &len, 1); + SCSICommand(id, cdb, buf, &len, 1); - memcpy(b, buf, len); + memcpy(cdrom_ioctl[id].rcbuf, buf, len); + cdrom_ioctl[id].capacity_read = 1; + } + else + { + memcpy(b, cdrom_ioctl[id].rcbuf, 16); + } ioctl_close(id); } @@ -1016,10 +1048,12 @@ int ioctl_open(uint8_t id, char d) if (!cdrom_ioctl[id].ioctl_inited) { cdrom_ioctl[id].ioctl_inited=1; + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); CloseHandle(cdrom_ioctl_windows[id].hIOCTL); cdrom_ioctl_windows[id].hIOCTL = NULL; + update_status_bar_icon_state(0x10 | id, 0); } - update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom.c b/src/cdrom.c index bb286451f..74968157d 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2953,7 +2953,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) alloc_length = 24; break; } - if (alloc_length < len) + if (!(cdb[2] & 0x40) || (cdb[3] == 0)) + { + len = 4; + } + else { len = alloc_length; } diff --git a/src/cdrom.h b/src/cdrom.h index 678b64086..a3a3a69a9 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -199,6 +199,13 @@ typedef struct int16_t cd_buffer[BUF_SIZE]; int cd_buflen; int actual_requested_blocks; + int last_track_pos; + int last_track_nr; + int capacity_read; + uint8_t rcbuf[16]; + uint8_t sub_q_data_format[16]; + uint8_t sub_q_channel_data[256]; + int last_subchannel_pos; } cdrom_ioctl_t; void ioctl_close(uint8_t id); diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 316679ab8..615bd8675 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -2156,6 +2156,12 @@ aha_cmd_cb(void *priv) } else if (AHA_InOperation == 1) { pclog("BusLogic Callback: Process CD-ROM request\n"); aha_cdrom_cmd(dev); + if (dev->Req.CmdBlock.common.Cdb[0] == 0x42) + { + /* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */ + AHA_Callback += 1000 * SCSI_TIME; + return; + } } else if (AHA_InOperation == 2) { pclog("BusLogic Callback: Send incoming mailbox\n"); aha_mbi(dev); diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index c5155d4ea..11a4d3d27 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -1970,6 +1970,12 @@ BuslogicCommandCallback(void *p) } else if (BuslogicInOperation == 1) { pclog("BusLogic Callback: Process CD-ROM request\n"); BuslogicCDROMCommand(bl); + if (bl->Req.CmdBlock.common.Cdb[0] == 0x42) + { + /* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */ + BuslogicCallback += 1000 * SCSI_TIME; + return; + } } else if (BuslogicInOperation == 2) { pclog("BusLogic Callback: Send incoming mailbox\n"); BuslogicMailboxIn(bl); diff --git a/src/win.c b/src/win.c index 049b0cbc0..4d7bc0631 100644 --- a/src/win.c +++ b/src/win.c @@ -617,7 +617,7 @@ HANDLE hinstAcc; HICON LoadIconEx(PCTSTR pszIconName) { - return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, 0); + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); } HICON LoadIconBig(PCTSTR pszIconName) @@ -722,9 +722,7 @@ void update_status_bar_icon(int tag, int active) sb_part_icons[found] &= ~257; sb_part_icons[found] |= sb_icon_flags[found]; - DestroyIcon(hIcon[found]); - hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]); - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]); + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); } } } @@ -751,29 +749,13 @@ void update_status_bar_icon_state(int tag, int state) if (found != -1) { - if (state) - { - switch(tag & 0xf0) - { - case 0x00: - default: - discfns[tag & 0x0f][0] = L'\0'; - break; - case 0x10: - cdrom_image[tag & 0x0f].image_path[0] = L'\0'; - break; - } - } - sb_icon_flags[found] &= ~256; sb_icon_flags[found] |= state ? 256 : 0; sb_part_icons[found] &= ~257; sb_part_icons[found] |= sb_icon_flags[found]; - DestroyIcon(hIcon[found]); - hIcon[found] = LoadIconEx((PCTSTR) sb_part_icons[found]); - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[found]); + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); } } @@ -1052,9 +1034,7 @@ void update_status_bar_panes(HWND hwnds) if (sb_part_icons[i] != -1) { SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); - DestroyIcon(hIcon[i]); - hIcon[i] = LoadIconEx((PCTSTR) sb_part_icons[i]); - SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[i]); + SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ } @@ -1072,6 +1052,51 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) RECT rectDialog; int dw, dh; + for (i = 128; i < 136; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 144; i < 148; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 150; i < 154; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 160; i < 166; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 176; i < 184; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 384; i < 392; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 400; i < 404; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 406; i < 410; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 416; i < 422; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + GetWindowRect(hwndParent, &rectDialog); dw = rectDialog.right - rectDialog.left; dh = rectDialog.bottom - rectDialog.top; From deb30e41a044d4f237ec7f1b3c8b88614dc56e93 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 11 May 2017 03:25:23 -0400 Subject: [PATCH 201/392] Some old variables deleted, no longer used. Also, updated pcap_if.rc. --- src/Makefile.mingw | 14 +++++++++---- src/config.c | 20 +++++++----------- src/pcap_if.rc | 52 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 src/pcap_if.rc diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 6eccad94b..0cc074200 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.8 2017/05/08 +# Version: @(#)Makefile.mingw 1.0.10 2017/05/10 # # Authors: Kotori, # Fred N. van Kempen, @@ -131,7 +131,9 @@ DEVOBJ = bugger.o lpt.o serial.o \ cdrom.o \ cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o -NETOBJ = network.o net_ne2000.o +NETOBJ = network.o \ + net_pcap.o \ + net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ convolve.o convolve-sse.o envelope.o extfilt.o \ @@ -216,10 +218,10 @@ ifneq ($(DEBUG), y) strip $(PROG).exe endif -pcap_if.exe: pcap_if.o +pcap_if.exe: pcap_if.o pcap_if.res @echo Linking pcap_if.exe .. @$(CC) -o pcap_if.exe \ - pcap_if.o -static -L. -lwpcapdelay + pcap_if.o pcap_if.res -static -L. -lwpcapdelay ifneq ($(DEBUG), y) strip pcap_if.exe endif @@ -235,5 +237,9 @@ clean: @echo Processing $< @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res +pcap_if.res: pcap_if.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -i pcap_if.rc -o pcap_if.res + # End of Makefile.mingw. diff --git a/src/config.c b/src/config.c index bf42e9066..4687b1a40 100644 --- a/src/config.c +++ b/src/config.c @@ -30,10 +30,12 @@ #include "sound/sound.h" #include "video/video.h" + wchar_t config_file_default[256]; static wchar_t config_file[256]; + typedef struct list_t { struct list_t *next; @@ -70,7 +72,7 @@ typedef struct entry_t (new)->next = NULL; \ } -void config_dump() +void config_dump(void) { section_t *current_section; @@ -97,7 +99,7 @@ void config_dump() } } -void config_free() +void config_free(void) { section_t *current_section; current_section = (section_t *)config_head.next; @@ -220,7 +222,7 @@ void config_load(wchar_t *fn) -void config_new() +void config_new(void) { FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); fclose(f); @@ -543,16 +545,9 @@ void loadconfig(wchar_t *fn) scsi_card_current = 0; /* network */ - ethif = config_get_int(NULL, "netinterface", 1); - if (ethif >= inum) - inum = ethif + 1; p = (char *)config_get_string(NULL, "netcard", ""); - if (p) - network_card_current = network_card_get_from_internal_name(p); - else - network_card_current = 0; - ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); - ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); + if (p != NULL) + network_setup(p); p = (char *)config_get_string(NULL, "model", ""); if (p) @@ -848,7 +843,6 @@ void saveconfig(void) config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - config_set_int(NULL, "netinterface", ethif); config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); config_set_int(NULL, "maclocal", ne2000_get_maclocal()); config_set_int(NULL, "maclocal_pci", ne2000_get_maclocal_pci()); diff --git a/src/pcap_if.rc b/src/pcap_if.rc new file mode 100644 index 000000000..57d78e657 --- /dev/null +++ b/src/pcap_if.rc @@ -0,0 +1,52 @@ +#ifdef _WIN32 +#include +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box.ico" +#endif + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,2,0 + PRODUCTVERSION 1,0,2,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "IRC #SoftHistory\0" + VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0" + VALUE "FileVersion", "1.0.2\0" + VALUE "InternalName", "pcap_if\0" + VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "pcap_if.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "WinPcap Test Tool\0" + VALUE "ProductVersion", "1.0.2\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END From ced75af0c2ab5d4a63bc7aaa9333d717a0940232 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 11 May 2017 03:30:55 -0400 Subject: [PATCH 202/392] More Slirp cleanups. --- src/slirp/misc.c | 2 +- src/slirp/slirp.c | 90 +++++++++++++++++++++-------------------------- src/slirp/slirp.h | 2 -- src/timer.h | 10 +++--- 4 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/slirp/misc.c b/src/slirp/misc.c index 39dc1e6e5..90bc2483e 100644 --- a/src/slirp/misc.c +++ b/src/slirp/misc.c @@ -119,7 +119,7 @@ getouraddr() our_addr.s_addr = loopback_addr.s_addr; #endif #undef ANCIENT - pclog("My IP address: %s (%s)\n", inet_ntoa(our_addr), buff); + pclog(" Our IP address: %s (%s)\n", inet_ntoa(our_addr), buff); } //#if SIZEOF_CHAR_P == 8 diff --git a/src/slirp/slirp.c b/src/slirp/slirp.c index c8861b965..6a9670f12 100644 --- a/src/slirp/slirp.c +++ b/src/slirp/slirp.c @@ -1,23 +1,20 @@ #include "slirp.h" -/* host address */ -struct in_addr our_addr; -/* host dns address */ -struct in_addr dns_addr; -/* host loopback address */ -struct in_addr loopback_addr; -/* address for slirp virtual addresses */ -struct in_addr special_addr; -/* virtual address alias for host */ -struct in_addr alias_addr; +/* Our actual addresses. */ +char slirp_hostname[33]; +struct in_addr our_addr; /* host IP address */ +struct in_addr dns_addr; /* host DNS server */ +struct in_addr loopback_addr; /* host loopback address */ -/* FIXME: this is probably not working with new MAC address stuff.. --FvK */ +/* Our SLiRP virtual addresses. */ +struct in_addr special_addr; /* virtual IP address */ +struct in_addr alias_addr; /* virtual address alias for host */ const uint8_t special_ethaddr[6] = { - 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 + 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 /* virtual MAC address. */ }; -uint8_t client_ethaddr[6]; +uint8_t client_ethaddr[6]; /* guest's MAC address */ int do_slowtimo; int link_up; @@ -28,8 +25,6 @@ struct ex_list *exec_list; /* XXX: suppress those select globals */ fd_set *global_readfds, *global_writefds, *global_xfds; -char slirp_hostname[33]; - extern void pclog(const char *, ...); extern int config_get_int(char *, char *, int); @@ -67,16 +62,11 @@ static int get_dns_addr(struct in_addr *pdns_addr) pIPAddr = &(FixedInfo->DnsServerList); inet_aton(pIPAddr->IpAddress.String, &tmp_addr); *pdns_addr = tmp_addr; -#if 1 - printf( "DNS Servers:\n" ); - printf( "DNS Addr:%s\n", pIPAddr->IpAddress.String ); - - pIPAddr = FixedInfo -> DnsServerList.Next; + printf( " DNS Servers:\n" ); while ( pIPAddr ) { - printf( "DNS Addr:%s\n", pIPAddr ->IpAddress.String ); + printf( " Address: %s\n", pIPAddr ->IpAddress.String ); pIPAddr = pIPAddr ->Next; } -#endif if (FixedInfo) { GlobalFree(FixedInfo); FixedInfo = NULL; @@ -132,13 +122,17 @@ void slirp_cleanup(void) } #endif -int slirp_init(void) + +int +slirp_init(void) { - struct in_addr myaddr; - int rc; - char* category = "SLiRP Port Forwarding"; - char key[32]; - int i = 0, udp, from, to; + char* category = "SLiRP Port Forwarding"; + char key[32]; + struct in_addr myaddr; + int i = 0, udp, from, to; + int rc; + + pclog("%s initializing..\n", category); #ifdef SLIRP_DEBUG // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); @@ -170,29 +164,28 @@ debug_init("slirplog.txt",DEBUG_DEFAULT); return -1; inet_aton(CTL_SPECIAL, &special_addr); - alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); - getouraddr(); + alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + getouraddr(); + inet_aton(CTL_LOCAL, &myaddr); - inet_aton("10.0.2.15",&myaddr); + while (1) { + sprintf(key, "%d_udp", i); + udp = config_get_int(category, key, 0); + sprintf(key, "%d_from", i); + from = config_get_int(category, key, 0); + if (from < 1) + break; + sprintf(key, "%d_to", i); + to = config_get_int(category, key, from); - while (1) { - sprintf(key, "%d_udp", i); - udp = config_get_int(category, key, 0); - sprintf(key, "%d_from", i); - from = config_get_int(category, key, 0); - if (from < 1) - break; - sprintf(key, "%d_to", i); - to = config_get_int(category, key, from); + rc = slirp_redir(udp, from, myaddr, to); + if (rc == 0) + pclog("slirp redir %d -> %d successful\n", from, to); + else + pclog("slirp redir %d -> %d failed (%d)\n", from, to, rc); - rc = slirp_redir(udp, from, myaddr, to); - if (rc == 0) - pclog("slirp redir %d -> %d successful\n", from, to); - else - pclog("slirp redir %d -> %d failed (%d)\n", from, to, rc); - - i++; - } + i++; + } return 0; } @@ -648,7 +641,6 @@ void slirp_input(const uint8_t *pkt, int pkt_len) struct SLIRPmbuf *m; int proto; -pclog("SLIRP_input(%08lx, %d)\n", pkt, pkt_len); if (pkt_len < ETH_HLEN) return; diff --git a/src/slirp/slirp.h b/src/slirp/slirp.h index 7ca179335..3f4efd0bd 100644 --- a/src/slirp/slirp.h +++ b/src/slirp/slirp.h @@ -1,8 +1,6 @@ #ifndef __COMMON_H__ #define __COMMON_H__ -#define SLIRP_DEBUG 1 - #define SLIRP_VERSION "Cockatrice special" #define CONFIG_QEMU diff --git a/src/timer.h b/src/timer.h index b2e7fec93..bdc77493b 100644 --- a/src/timer.h +++ b/src/timer.h @@ -39,11 +39,11 @@ extern int timer_start; timer_update_outstanding(); \ } while (0) -void timer_process(); -void timer_update_outstanding(); -void timer_reset(); -int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv); -void timer_set_callback(int timer, void (*callback)(void *priv)); +extern void timer_process(void); +extern void timer_update_outstanding(void); +extern void timer_reset(void); +extern int timer_add(void (*callback)(void *priv), int *count, int *enable, void *priv); +extern void timer_set_callback(int timer, void (*callback)(void *priv)); #define TIMER_ALWAYS_ENABLED &timer_one From 8d5ca5c57dabef95c7867b7a2032bc1783d9b105 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 11 May 2017 20:15:08 +0200 Subject: [PATCH 203/392] Fixed the makefile to not include a file that is not there. --- src/Makefile.mingw | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 0cc074200..942710e4b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -132,7 +132,6 @@ DEVOBJ = bugger.o lpt.o serial.o \ cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o NETOBJ = network.o \ - net_pcap.o \ net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ From 1f3f8a65f49af87498c0b773b66785ec410a66e1 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 12 May 2017 05:19:45 +0200 Subject: [PATCH 204/392] Fixed MPU-401 reset callback. Space Quest 3 and Hard Ball 3 (possibly other games too) now work. --- src/SOUND/snd_mpu401.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 14e18192a..837186188 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -271,7 +271,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) break; case 0xff: /* Reset MPU-401 */ pclog("MPU-401:Reset %X\n",val); - mpu401_reset_callback = MPU401_RESETBUSY * 1000 * TIMER_USEC; + mpu401_reset_callback = MPU401_RESETBUSY * 200 * TIMER_USEC; mpu->state.reset=1; MPU401_Reset(mpu); if (mpu->mode==M_UART) return;//do not send ack in UART mode From 2f9bda8a1839a36bae471bdbe5d296b690c7cdc3 Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 12 May 2017 05:05:20 -0400 Subject: [PATCH 205/392] Updated network code, major cleanup. SLiRP and Pcap both tested. UI configuration will need extra work by Kotori. --- src/Makefile.mingw | 4 +- src/config.c | 12 +- src/net_ne2000.c | 1329 +++++++++++++++++++------------------------- src/net_ne2000.h | 8 +- src/net_pcap.c | 212 +++++++ src/net_slirp.c | 199 +++++++ src/network.c | 197 ++++--- src/network.h | 60 +- src/pc.c | 1 + src/win-settings.c | 6 +- 10 files changed, 1174 insertions(+), 854 deletions(-) create mode 100644 src/net_pcap.c create mode 100644 src/net_slirp.c diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 0cc074200..098a56fe1 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.10 2017/05/10 +# Version: @(#)Makefile.mingw 1.0.11 2017/05/11 # # Authors: Kotori, # Fred N. van Kempen, @@ -132,7 +132,7 @@ DEVOBJ = bugger.o lpt.o serial.o \ cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o NETOBJ = network.o \ - net_pcap.o \ + net_pcap.o net_slirp.o \ net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ diff --git a/src/config.c b/src/config.c index 4687b1a40..7fb3c7637 100644 --- a/src/config.c +++ b/src/config.c @@ -21,7 +21,6 @@ #include "model.h" #include "mouse.h" #include "network.h" -#include "net_ne2000.h" #include "nvr.h" #include "plat-joystick.h" #include "scsi.h" @@ -545,9 +544,9 @@ void loadconfig(wchar_t *fn) scsi_card_current = 0; /* network */ - p = (char *)config_get_string(NULL, "netcard", ""); - if (p != NULL) - network_setup(p); + p = (char *)config_get_string(NULL, "net_card", ""); + network_type = config_get_int(NULL, "net_type", -1); + network_setup(p); p = (char *)config_get_string(NULL, "model", ""); if (p) @@ -843,9 +842,12 @@ void saveconfig(void) config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); + config_set_string(NULL, "net_card", network_card_get_internal_name(network_card)); + config_set_int(NULL, "net_type", network_type); +#if 1 config_set_int(NULL, "maclocal", ne2000_get_maclocal()); config_set_int(NULL, "maclocal_pci", ne2000_get_maclocal_pci()); +#endif config_set_string(NULL, "model", model_get_internal_name()); config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 1ca0add6e..30210f259 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.1 2017/05/09 + * Version: @(#)net_ne2000.c 1.0.2 2017/05/11 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -25,28 +25,21 @@ #include #include #include -#include -#include "slirp/slirp.h" -#include "slirp/queue.h" #include "ibm.h" #include "io.h" #include "mem.h" #include "rom.h" #include "pci.h" #include "pic.h" -#include "timer.h" #include "device.h" #include "config.h" #include "disc_random.h" #include "network.h" #include "net_ne2000.h" #include "bswap.h" - - #ifdef WALTJE # define ENABLE_NE2000_LOG 1 #endif -#define NETBLOCKING 0 /* we won't block our pcap */ /* For PCI. */ @@ -56,26 +49,17 @@ typedef union { } bar_t; -/* Most of this stuff should go into the struct. --FvK */ +/* This stuff should go into the struct. --FvK */ static uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; static uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; static uint8_t rtl8029as_eeprom[128]; static uint8_t pci_regs[256]; static bar_t pci_bar[2]; -static uint32_t bios_addr = 0xD0000; static uint32_t old_base_addr = 0; -static uint32_t bios_size = 0; -static uint32_t bios_mask = 0; -static pcap_t *net_pcap; -static queueADT slirpq; -static int disable_netbios = 0; -static int net_slirp_inited = 0; -static int net_is_pcap = 0; /* and pretend pcap is dead. */ -static int fizz = 0; -#ifdef ENABLE_NE2000_LOG -static int ne2000_do_log = ENABLE_NE2000_LOG; +#if ENABLE_NE2000_LOG +static int nic_do_log = ENABLE_NE2000_LOG; #else -static int ne2000_do_log = 0; +static int nic_do_log = 0; #endif @@ -84,14 +68,13 @@ static int ne2000_do_log = 0; /* Never completely fill the ne2k ring so that we never hit the unclear completely full buffer condition. */ -#define BX_NE2K_NEVER_FULL_RING (1) +#define NE2K_NEVER_FULL_RING (1) -#define BX_NE2K_MEMSIZ (32*1024) -#define BX_NE2K_MEMSTART (16*1024) -#define BX_NE2K_MEMEND (BX_NE2K_MEMSTART + BX_NE2K_MEMSIZ) +#define NE2K_MEMSIZ (32*1024) +#define NE2K_MEMSTART (16*1024) +#define NE2K_MEMEND (NE2K_MEMSTART+NE2K_MEMSIZ) -/* ne2k register state */ typedef struct { /* Page 0 */ @@ -226,22 +209,26 @@ typedef struct { /* Novell ASIC state */ uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ - uint8_t mem[BX_NE2K_MEMSIZ]; /* on-chip packet memory */ + uint8_t mem[NE2K_MEMSIZ]; /* on-chip packet memory */ /* ne2k internal state */ + char name[32]; uint32_t base_address; int base_irq; + int is_rtl8029as; int tx_timer_index; int tx_timer_active; + uint32_t bios_addr, + bios_size, + bios_mask; + int disable_netbios; rom_t bios_rom; -} ne2000_t; +} nic_t; -static void ne2000_tx_event(void *, uint32_t); -static void ne2000_rx_frame(void *, const void *, int); - -void slirp_tic(void); +static void nic_rx(void *, uint8_t *, int); +static void nic_tx(nic_t *, uint32_t); static void @@ -250,7 +237,7 @@ nelog(int lvl, const char *fmt, ...) #ifdef ENABLE_NE2000_LOG va_list ap; - if (ne2000_do_log >= lvl) { + if (nic_do_log >= lvl) { va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); @@ -262,12 +249,12 @@ nelog(int lvl, const char *fmt, ...) /* reset - restore state to power-up, cancelling all i/o */ static void -ne2000_reset(void *priv, int reset) +nic_reset(void *priv, int reset) { - ne2000_t *dev = (ne2000_t *)priv; + nic_t *dev = (nic_t *)priv; int i; - pclog(1, "ne2000 reset\n"); + pclog(1, "%s: reset\n", dev->name); /* Initialize the MAC address area by doubling the physical address */ dev->macaddr[0] = dev->physaddr[0]; @@ -325,8 +312,9 @@ ne2000_reset(void *priv, int reset) dev->CR.rdma_cmd = 4; dev->ISR.reset = 1; dev->DCR.longaddr = 1; - picint(1 << dev->base_irq); - picintc(1 << dev->base_irq); + + picint(1<base_irq); + picintc(1<base_irq); } @@ -338,12 +326,12 @@ ne2000_reset(void *priv, int reset) and there is 16K of buffer memory starting at 16K */ static uint32_t -chipmem_read(ne2000_t *dev, uint32_t addr, unsigned int len) +chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) { uint32_t retval = 0; if ((len == 2) && (addr & 0x1)) { - pclog(1, "unaligned chipmem word read\n"); + pclog(1, "%s: unaligned chipmem word read\n", dev->name); } /* ROM'd MAC address */ @@ -359,29 +347,29 @@ chipmem_read(ne2000_t *dev, uint32_t addr, unsigned int len) return(retval); } - if ((addr >= BX_NE2K_MEMSTART) && (addr < BX_NE2K_MEMEND)) { - retval = dev->mem[addr - BX_NE2K_MEMSTART]; + if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { + retval = dev->mem[addr - NE2K_MEMSTART]; if ((len == 2) || (len == 4)) { - retval |= (dev->mem[addr - BX_NE2K_MEMSTART + 1] << 8); + retval |= (dev->mem[addr - NE2K_MEMSTART + 1] << 8); } if (len == 4) { - retval |= (dev->mem[addr - BX_NE2K_MEMSTART + 2] << 16); - retval |= (dev->mem[addr - BX_NE2K_MEMSTART + 3] << 24); + retval |= (dev->mem[addr - NE2K_MEMSTART + 2] << 16); + retval |= (dev->mem[addr - NE2K_MEMSTART + 3] << 24); } return(retval); } - pclog(1, "out-of-bounds chipmem read, %04X\n", addr); + pclog(1, "%s: out-of-bounds chipmem read, %04X\n", dev->name, addr); - if (network_card_current == 1) { + if (dev->is_rtl8029as) { + return(0xff); + } else { switch(len) { case 1: return(0xff); case 2: return(0xffff); } - } else { - return(0xff); } return(0xffff); @@ -389,23 +377,23 @@ chipmem_read(ne2000_t *dev, uint32_t addr, unsigned int len) static void -chipmem_write(ne2000_t *dev, uint32_t addr, uint32_t val, unsigned len) +chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) { if ((len == 2) && (addr & 0x1)) { - pclog(1, "unaligned chipmem word write\n"); + pclog(1, "%s: unaligned chipmem word write\n", dev->name); } - if ((addr >= BX_NE2K_MEMSTART) && (addr < BX_NE2K_MEMEND)) { - dev->mem[addr - BX_NE2K_MEMSTART] = val & 0xff; + if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { + dev->mem[addr-NE2K_MEMSTART] = val & 0xff; if ((len == 2) || (len == 4)) { - dev->mem[addr - BX_NE2K_MEMSTART + 1] = val >> 8; + dev->mem[addr-NE2K_MEMSTART+1] = val >> 8; } if (len == 4) { - dev->mem[addr - BX_NE2K_MEMSTART + 2] = val >> 16; - dev->mem[addr - BX_NE2K_MEMSTART + 3] = val >> 24; + dev->mem[addr-NE2K_MEMSTART+2] = val >> 16; + dev->mem[addr-NE2K_MEMSTART+3] = val >> 24; } } else { - pclog(1, "out-of-bounds chipmem write, %04X\n", addr); + pclog(1, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); } } @@ -420,25 +408,22 @@ chipmem_write(ne2000_t *dev, uint32_t addr, uint32_t val, unsigned len) the appropriate number of bytes to/from the device. */ static uint32_t -asic_read(ne2000_t *dev, uint32_t off, unsigned int len) +asic_read(nic_t *dev, uint32_t off, unsigned int len) { uint32_t retval = 0; - switch (off) { - case 0x0: /* Data register */ - + switch(off) { + case 0x00: /* Data register */ /* A read remote-DMA command must have been issued, and the source-address and length registers must have been initialised. */ - if (len > dev->remote_bytes) { - pclog(1, "dma read underrun iolen=%d remote_bytes=%d\n", - len, dev->remote_bytes); + pclog(1, "%s: DMA read underrun iolen=%d remote_bytes=%d\n", + dev->name, len, dev->remote_bytes); } - pclog(2, "%s read DMA: addr=%4x remote_bytes=%d\n", - (network_card_current==1)?"NE2000":"RTL8029AS", - dev->remote_dma,dev->remote_bytes); + pclog(2, "%s: DMA read: addr=%4x remote_bytes=%d\n", + dev->name, dev->remote_dma,dev->remote_bytes); retval = chipmem_read(dev, dev->remote_dma, len); /* The 8390 bumps the address and decreases the byte count @@ -474,12 +459,13 @@ asic_read(ne2000_t *dev, uint32_t off, unsigned int len) } break; - case 0xf: /* Reset register */ - ne2000_reset(dev, BX_RESET_SOFTWARE); + case 0x0f: /* Reset register */ + nic_reset(dev, BX_RESET_SOFTWARE); break; default: - pclog(1, "asic read invalid address %04x\n", (unsigned)off); + pclog(1, "%s: ASIC read invalid address %04x\n", + dev->name, (unsigned)off); break; } @@ -488,19 +474,19 @@ asic_read(ne2000_t *dev, uint32_t off, unsigned int len) static void -asic_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { pclog(2, "%s: asic write addr=0x%02x, value=0x%04x\n", - (network_card_current==1)?"NE2000":"RTL8029AS",(unsigned)off, (unsigned) val); + dev->name, (unsigned)off, (unsigned) val); switch(off) { - case 0x0: /* Data register - see asic_read for a description */ + case 0x00: /* Data register - see asic_read for a description */ if ((len > 1) && (dev->DCR.wdsize == 0)) { - pclog(2, "dma write length %d on byte mode operation\n", - len); + pclog(2, "%s: DMA write length %d on byte mode operation\n", + dev->name, len); break; } if (dev->remote_bytes == 0) { - pclog(2, "dma write, byte count 0\n"); + pclog(2, "%s: DMA write, byte count 0\n", dev->name); } chipmem_write(dev, dev->remote_dma, val, len); @@ -520,7 +506,7 @@ asic_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) dev->remote_bytes -= (dev->DCR.wdsize + 1); } - if (dev->remote_bytes > BX_NE2K_MEMSIZ) { + if (dev->remote_bytes > NE2K_MEMSIZ) { dev->remote_bytes = 0; } @@ -533,13 +519,13 @@ asic_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) } break; - case 0xf: /* Reset register */ + case 0x0f: /* Reset register */ /* end of reset pulse */ break; default: /* this is invalid, but happens under win95 device detection */ - pclog(1, "asic write invalid address %04x, ignoring\n", - (unsigned)off); + pclog(1, "%s: ASIC write invalid address %04x, ignoring\n", + dev->name, (unsigned)off); break; } } @@ -548,14 +534,14 @@ asic_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) /* page0_read/page0_write - These routines handle reads/writes to the 'zeroth' page of the DS8390 register file */ static uint32_t -page0_read(ne2000_t *dev, uint32_t off, unsigned int len) +page0_read(nic_t *dev, uint32_t off, unsigned int len) { uint8_t retval = 0; if (len > 1) { /* encountered with win98 hardware probe */ - pclog(1, "bad length! page 0 read from register 0x%02x, len=%u\n", - off, len); + pclog(1, "%s: bad length! Page0 read from register 0x%02x, len=%u\n", + dev->name, off, len); return(retval); } @@ -588,7 +574,7 @@ page0_read(ne2000_t *dev, uint32_t off, unsigned int len) case 0x06: /* FIFO */ /* reading FIFO is only valid in loopback mode */ - pclog(1, "reading FIFO not supported yet\n"); + pclog(1, "%s: reading FIFO not supported yet\n", dev->name); retval = dev->fifo; break; @@ -612,19 +598,19 @@ page0_read(ne2000_t *dev, uint32_t off, unsigned int len) break; case 0x0a: /* reserved / RTL8029ID0 */ - if (network_card_current == 2) { + if (dev->is_rtl8029as) { retval = 0x50; } else { - pclog(1, "reserved read - page 0, 0x0a\n"); + pclog(1, "%s: reserved Page0 read - 0x0a\n", dev->name); retval = 0xff; } break; case 0x0b: /* reserved / RTL8029ID1 */ - if (network_card_current == 2) { + if (dev->is_rtl8029as) { retval = 0x43; } else { - pclog(1, "reserved read - page 0, 0xb\n"); + pclog(1, "%s: reserved Page0 read - 0x0b\n", dev->name); retval = 0xff; } break; @@ -653,18 +639,20 @@ page0_read(ne2000_t *dev, uint32_t off, unsigned int len) break; default: - pclog(1, "page 0 register 0x%02x out of range\n", off); + pclog(1, "%s: Page0 register 0x%02x out of range\n", + dev->name, off); break; } - pclog(2, "page 0 read from register 0x%02x, value=0x%02x\n", off, retval); + pclog(2, "%s: Page0 read from register 0x%02x, value=0x%02x\n", + dev->name, off, retval); return(retval); } static void -page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { uint8_t val2; @@ -678,7 +666,8 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) return; } - pclog(2, "page 0 write to register 0x%02x, value=0x%02x\n", off, val); + pclog(2, "%s: Page0 write to register 0x%02x, value=0x%02x\n", + dev->name, off, val); switch(off) { case 0x01: /* PSTART */ @@ -767,7 +756,8 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0c: /* RCR */ /* Check if the reserved bits are set */ if (val & 0xc0) { - pclog(1, "RCR write, reserved bits set\n"); + pclog(1, "%s: RCR write, reserved bits set\n", + dev->name); } /* Set all other bit-fields */ @@ -779,35 +769,32 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) dev->RCR.monitor = ((val & 0x20) == 0x20); /* Monitor bit is a little suspicious... */ - if (val & 0x20) { - pclog(1, "RCR write, monitor bit set!\n"); - } + if (val & 0x20) pclog(1, "%s: RCR write, monitor bit set!\n", + dev->name); break; case 0x0d: /* TCR */ /* Check reserved bits */ - if (val & 0xe0) { - pclog(1, "TCR write, reserved bits set\n"); - } + if (val & 0xe0) pclog(1, "%s: TCR write, reserved bits set\n", + dev->name); /* Test loop mode (not supported) */ if (val & 0x06) { dev->TCR.loop_cntl = (val & 0x6) >> 1; - pclog(1, "TCR write, loop mode %d not supported\n", - dev->TCR.loop_cntl); + pclog(1, "%s: TCR write, loop mode %d not supported\n", + dev->name, dev->TCR.loop_cntl); } else { dev->TCR.loop_cntl = 0; } /* Inhibit-CRC not supported. */ - if (val & 0x01) { - pclog(1, "TCR write, inhibit-CRC not supported\n"); - } + if (val & 0x01) pclog(1, + "%s: TCR write, inhibit-CRC not supported\n",dev->name); /* Auto-transmit disable very suspicious */ - if (val & 0x08) { - pclog(1, "TCR write, auto transmit disable not supported\n"); - } + if (val & 0x08) pclog(1, + "%s: TCR write, auto transmit disable not supported\n", + dev->name); /* Allow collision-offset to be set, although not used */ dev->TCR.coll_prio = ((val & 0x08) == 0x08); @@ -815,19 +802,16 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0e: /* DCR */ /* the loopback mode is not suppported yet */ - if (! (val & 0x08)) { - pclog(1, "DCR write, loopback mode selected\n"); - } + if (! (val & 0x08)) pclog(1, + "%s: DCR write, loopback mode selected\n", dev->name); /* It is questionable to set longaddr and auto_rx, since * they are not supported on the NE2000. Print a warning * and continue. */ - if (val & 0x04) { - pclog(1, "DCR write - LAS set ???\n"); - } - if (val & 0x10) { - pclog(1, "DCR write - AR set ???\n"); - } + if (val & 0x04) + pclog(1, "%s: DCR write - LAS set ???\n", dev->name); + if (val & 0x10) + pclog(1, "%s: DCR write - AR set ???\n", dev->name); /* Set other values. */ dev->DCR.wdsize = ((val & 0x01) == 0x01); @@ -840,9 +824,8 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0f: /* IMR */ /* Check for reserved bit */ - if (val & 0x80) { - pclog(1, "IMR write, reserved bit set\n"); - } + if (val & 0x80) + pclog(1, "%s: IMR write, reserved bit set\n",dev->name); /* Set other values */ dev->IMR.rx_inte = ((val & 0x01) == 0x01); @@ -867,7 +850,8 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) break; default: - pclog(1, "page 0 write, bad register 0x%02x\n", off); + pclog(1, "%s: Page0 write, bad register 0x%02x\n", + dev->name, off); break; } } @@ -876,9 +860,10 @@ page0_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) /* page1_read/page1_write - These routines handle reads/writes to the first page of the DS8390 register file */ static uint32_t -page1_read(ne2000_t *dev, uint32_t off, unsigned int len) +page1_read(nic_t *dev, uint32_t off, unsigned int len) { - pclog(2, "page 1 read from register 0x%02x, len=%u\n", off, len); + pclog(2, "%s: Page1 read from register 0x%02x, len=%u\n", + dev->name, off, len); switch(off) { case 0x01: /* PAR0-5 */ @@ -890,7 +875,8 @@ page1_read(ne2000_t *dev, uint32_t off, unsigned int len) return(dev->physaddr[off - 1]); case 0x07: /* CURR */ - pclog(2, "returning current page: 0x%02x\n", (dev->curr_page)); + pclog(2, "%s: returning current page: 0x%02x\n", + dev->name, (dev->curr_page)); return(dev->curr_page); case 0x08: /* MAR0-7 */ @@ -904,17 +890,18 @@ page1_read(ne2000_t *dev, uint32_t off, unsigned int len) return(dev->mchash[off - 8]); default: - pclog(1, "page 1 read register 0x%02x out of range\n", off); + pclog(1, "%s: Page1 read register 0x%02x out of range\n", + dev->name, off); return(0); } } static void -page1_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - pclog(2, "page 1 write to register 0x%02x, len=%u, value=0x%04x\n", - off, len, val); + pclog(2, "%s: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", + dev->name, off, len, val); switch(off) { case 0x01: /* PAR0-5 */ @@ -924,12 +911,12 @@ page1_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x05: case 0x06: dev->physaddr[off - 1] = val; - if (off == 6) { - pclog(1, "Physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", - dev->physaddr[0], dev->physaddr[1], - dev->physaddr[2], dev->physaddr[3], - dev->physaddr[4], dev->physaddr[5]); - } + if (off == 6) pclog(1, + "%s: physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", + dev->name, + dev->physaddr[0], dev->physaddr[1], + dev->physaddr[2], dev->physaddr[3], + dev->physaddr[4], dev->physaddr[5]); break; case 0x07: /* CURR */ @@ -948,7 +935,8 @@ page1_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) break; default: - pclog(1, "page 1 write register 0x%02x out of range\n", off); + pclog(1, "%s: Page1 write register 0x%02x out of range\n", + dev->name, off); break; } } @@ -957,9 +945,10 @@ page1_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) /* page2_read/page2_write - These routines handle reads/writes to the second page of the DS8390 register file */ static uint32_t -page2_read(ne2000_t *dev, uint32_t off, unsigned int len) +page2_read(nic_t *dev, uint32_t off, unsigned int len) { - pclog(2, "page 2 read from register 0x%02x, len=%u\n", off, len); + pclog(2, "%s: Page2 read from register 0x%02x, len=%u\n", + dev->name, off, len); switch(off) { case 0x01: /* PSTART */ @@ -987,7 +976,8 @@ page2_read(ne2000_t *dev, uint32_t off, unsigned int len) case 0x09: case 0x0a: case 0x0b: - pclog(1, "reserved read - page 2, register 0x%02x\n", off); + pclog(1, "%s: reserved Page2 read - register 0x%02x\n", + dev->name, off); return(0xff); case 0x0c: /* RCR */ @@ -1022,7 +1012,8 @@ page2_read(ne2000_t *dev, uint32_t off, unsigned int len) (dev->IMR.rx_inte)); default: - pclog(1, "page 2 register 0x%02x out of range\n", off); + pclog(1, "%s: Page2 register 0x%02x out of range\n", + dev->name, off); break; } @@ -1031,13 +1022,13 @@ page2_read(ne2000_t *dev, uint32_t off, unsigned int len) static void -page2_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { /* Maybe all writes here should be BX_PANIC()'d, since they affect internal operation, but let them through for now and print a warning. */ - pclog(2, "page 2 write to register 0x%02x, len=%u, value=0x%04x\n", - off, len, val); + pclog(2, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", + dev->name, off, len, val); switch(off) { case 0x01: /* CLDA0 */ /* Clear out low byte and re-insert */ @@ -1083,11 +1074,13 @@ page2_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0d: case 0x0e: case 0x0f: - pclog(1, "page 2 write to reserved register 0x%02x\n", off); + pclog(1, "%s: Page2 write to reserved register 0x%02x\n", + dev->name, off); break; default: - pclog(1, "page 2 write, illegal register 0x%02x\n", off); + pclog(1, "%s: Page2 write, illegal register 0x%02x\n", + dev->name, off); break; } } @@ -1095,9 +1088,9 @@ page2_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) /* page3_read/page3_write - writes to this page are illegal */ static uint32_t -page3_read(ne2000_t *dev, uint32_t off, unsigned int len) -{ - if (network_card_current == 2) switch(off) { +page3_read(nic_t *dev, uint32_t off, unsigned int len) +{ + if (dev->is_rtl8029as) switch(off) { case 0x3: /* CONFIG0 */ return(0x00); @@ -1111,22 +1104,22 @@ page3_read(ne2000_t *dev, uint32_t off, unsigned int len) break; } - pclog(1, "page 3 read register 0x%02x attempted\n", off); + pclog(1, "%s: Page3 read register 0x%02x attempted\n", dev->name, off); return(0x00); } static void -page3_write(ne2000_t *dev, uint32_t off, uint32_t val, unsigned len) +page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - pclog(1, "page 3 write register 0x%02x attempted\n", off); + pclog(1, "%s: Page3 write register 0x%02x attempted\n", dev->name, off); } /* read_cr/write_cr - utility routines for handling reads/writes to the Command Register */ static uint32_t -read_cr(ne2000_t *dev) +read_cr(nic_t *dev) { uint32_t retval; @@ -1135,22 +1128,20 @@ read_cr(ne2000_t *dev) (dev->CR.tx_packet << 2) | (dev->CR.start << 1) | (dev->CR.stop)); - pclog(2, "%s: read CR returns 0x%02x\n", - (network_card_current==1)?"NE2000":"RTL8029AS", retval); + pclog(2, "%s: read CR returns 0x%02x\n", dev->name, retval); return(retval); } static void -write_cr(ne2000_t *dev, uint32_t val) +write_cr(nic_t *dev, uint32_t val) { - pclog(2, "%s: wrote 0x%02x to CR\n", - (network_card_current == 1) ? "NE2000" : "RTL8029AS", val); + pclog(2, "%s: wrote 0x%02x to CR\n", dev->name, val); /* Validate remote-DMA */ if ((val & 0x38) == 0x00) { - pclog(1, "CR write - invalid rDMA value 0\n"); + pclog(2, "%s: CR write - invalid rDMA value 0\n", dev->name); val |= 0x20; /* dma_cmd == 4 is a safe default */ } @@ -1178,44 +1169,41 @@ write_cr(ne2000_t *dev, uint32_t val) /* Set up DMA read from receive ring */ dev->remote_start = dev->remote_dma = dev->bound_ptr * 256; dev->remote_bytes = (uint16_t) chipmem_read(dev, dev->bound_ptr * 256 + 2, 2); - pclog(2, "Sending buffer #x%x length %d\n", dev->remote_start, dev->remote_bytes); + pclog(2, "%s: sending buffer #x%x length %d\n", + dev->name, dev->remote_start, dev->remote_bytes); } /* Check for start-tx */ if ((val & 0x04) && dev->TCR.loop_cntl) { if (dev->TCR.loop_cntl != 1) { - pclog(1, "Loop mode %d not supported\n", dev->TCR.loop_cntl); + pclog(1, "%s: loop mode %d not supported\n", + dev->name, dev->TCR.loop_cntl); } else { - ne2000_rx_frame(dev, &dev->mem[dev->tx_page_start*256 - BX_NE2K_MEMSTART], dev->tx_bytes); + nic_rx(dev, + &dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], + dev->tx_bytes); } } else if (val & 0x04) { - if (dev->CR.stop || (!dev->CR.start && (network_card_current == 1))) { + if (dev->CR.stop || (!dev->CR.start && !dev->is_rtl8029as)) { if (dev->tx_bytes == 0) /* njh@bandsman.co.uk */ { return; /* Solaris9 probe */ } - pclog(1, "CR write - tx start, dev in reset\n"); + pclog(1, "%s: CR write - tx start, dev in reset\n", dev->name); } - if (dev->tx_bytes == 0) { - pclog(1, "CR write - tx start, tx bytes == 0\n"); - } + if (dev->tx_bytes == 0) + pclog(1, "%s: CR write - tx start, tx bytes == 0\n", dev->name); /* Send the packet to the system driver */ dev->CR.tx_packet = 1; - if (! net_is_pcap) { - slirp_input(&dev->mem[dev->tx_page_start*256 - BX_NE2K_MEMSTART], dev->tx_bytes); - pclog(1, "ne2000 slirp sending packet\n"); - } else if (net_is_pcap && (net_pcap != NULL)) { - pcap_sendpacket(net_pcap, &dev->mem[dev->tx_page_start*256 - BX_NE2K_MEMSTART], dev->tx_bytes); - pclog(1, "ne2000 pcap sending packet\n"); - } + network_tx(&dev->mem[dev->tx_page_start*256 - NE2K_MEMSTART], + dev->tx_bytes); /* some more debug */ - if (dev->tx_timer_active) { - pclog(1, "CR write, tx timer still active\n"); - } + if (dev->tx_timer_active) + pclog(1, "%s: CR write, tx timer still active\n", dev->name); - ne2000_tx_event(dev, val); + nic_tx(dev, val); } /* Linux probes for an interrupt by setting up a remote-DMA read @@ -1225,7 +1213,7 @@ write_cr(ne2000_t *dev, uint32_t val) dev->ISR.rdma_done = 1; if (dev->IMR.rdma_inte) { picint(1 << dev->base_irq); - if (network_card_current == 1) { + if (! dev->is_rtl8029as) { picintc(1 << dev->base_irq); } } @@ -1234,13 +1222,12 @@ write_cr(ne2000_t *dev, uint32_t val) static uint32_t -ne2000_read(ne2000_t *dev, uint32_t addr, unsigned len) +nic_read(nic_t *dev, uint32_t addr, unsigned len) { uint32_t retval = 0; int off = addr - dev->base_address; - pclog(2, "%s: read addr %x, len %d\n", - (network_card_current==1)?"NE2000":"RTL8029AS", addr, len); + pclog(2, "%s: read addr %x, len %d\n", dev->name, addr, len); if (off >= 0x10) { retval = asic_read(dev, off - 0x10, len); @@ -1264,7 +1251,8 @@ ne2000_read(ne2000_t *dev, uint32_t addr, unsigned len) break; default: - pclog(1, "unknown value of pgsel in read - %d\n", dev->CR.pgsel); + pclog(1, "%s: unknown value of pgsel in read - %d\n", + dev->name, dev->CR.pgsel); break; } @@ -1273,38 +1261,37 @@ ne2000_read(ne2000_t *dev, uint32_t addr, unsigned len) static uint8_t -ne2000_readb(uint16_t addr, void *priv) +nic_readb(uint16_t addr, void *priv) { - return(ne2000_read((ne2000_t *)priv, addr, 1)); + return(nic_read((nic_t *)priv, addr, 1)); } static uint16_t -ne2000_readw(uint16_t addr, void *priv) +nic_readw(uint16_t addr, void *priv) { - ne2000_t *dev = (ne2000_t *)priv; + nic_t *dev = (nic_t *)priv; if (dev->DCR.wdsize & 1) - return(ne2000_read(dev, addr, 2)); + return(nic_read(dev, addr, 2)); else - return(ne2000_read(dev, addr, 1)); + return(nic_read(dev, addr, 1)); } static uint32_t -ne2000_readl(uint16_t addr, void *priv) +nic_readl(uint16_t addr, void *priv) { - return(ne2000_read((ne2000_t *)priv, addr, 4)); + return(nic_read((nic_t *)priv, addr, 4)); } static void -ne2000_write(ne2000_t *dev, uint32_t addr, uint32_t val, unsigned len) +nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) { int off = addr - dev->base_address; - pclog(2, "%s: write addr %x, value %x len %d\n", - (network_card_current==1)?"NE2000":"RTL8029AS", addr, val, len); + pclog(2, "%s: write addr %x, value %x len %d\n", dev->name, addr, val, len); /* The high 16 bytes of i/o space are for the ne2000 asic - the low 16 bytes are for the DS8390, with the current @@ -1332,117 +1319,120 @@ ne2000_write(ne2000_t *dev, uint32_t addr, uint32_t val, unsigned len) break; default: - pclog(1, "unknown value of pgsel in write - %d\n", dev->CR.pgsel); + pclog(1, "%s: unknown value of pgsel in write - %d\n", + dev->name, dev->CR.pgsel); break; } } static void -ne2000_writeb(uint16_t addr, uint8_t val, void *priv) +nic_writeb(uint16_t addr, uint8_t val, void *priv) { - ne2000_write((ne2000_t *)priv, addr, val, 1); + nic_write((nic_t *)priv, addr, val, 1); } static void -ne2000_writew(uint16_t addr, uint16_t val, void *priv) +nic_writew(uint16_t addr, uint16_t val, void *priv) { - ne2000_t *dev = (ne2000_t *)priv; + nic_t *dev = (nic_t *)priv; if (dev->DCR.wdsize & 1) - ne2000_write(dev, addr, val, 2); + nic_write(dev, addr, val, 2); else - ne2000_write(dev, addr, val, 1); + nic_write(dev, addr, val, 1); } static void -ne2000_writel(uint16_t addr, uint32_t val, void *priv) +nic_writel(uint16_t addr, uint32_t val, void *priv) { - ne2000_write((ne2000_t *)priv, addr, val, 4); + nic_write((nic_t *)priv, addr, val, 4); } static void -ne2000_ioset(uint16_t addr, ne2000_t *dev) +nic_ioset(nic_t *dev, uint16_t addr) { old_base_addr = addr; - if (network_card_current == 1) { + if (dev->is_rtl8029as) { io_sethandler(addr, 16, - ne2000_readb, NULL, NULL, - ne2000_writeb, NULL, NULL, dev); + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); io_sethandler(addr+16, 16, - ne2000_readb, ne2000_readw, NULL, - ne2000_writeb, ne2000_writew, NULL, dev); + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); io_sethandler(addr+0x1f, 1, - ne2000_readb, NULL, NULL, - ne2000_writeb, NULL, NULL, dev); + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); } else { io_sethandler(addr, 16, - ne2000_readb, ne2000_readw, ne2000_readl, - ne2000_writeb, ne2000_writew, ne2000_writel, dev); + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); io_sethandler(addr+16, 16, - ne2000_readb, ne2000_readw, ne2000_readl, - ne2000_writeb, ne2000_writew, ne2000_writel, dev); + nic_readb, nic_readw, NULL, + nic_writeb, nic_writew, NULL, dev); io_sethandler(addr+0x1f, 1, - ne2000_readb, ne2000_readw, ne2000_readl, - ne2000_writeb, ne2000_writew, ne2000_writel, dev); + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); } } static void -ne2000_ioremove(int16_t addr, ne2000_t *dev) +nic_ioremove(nic_t *dev, int16_t addr) { - if (network_card_current == 1) { + if (dev->is_rtl8029as) { io_removehandler(addr, 16, - ne2000_readb, NULL, NULL, - ne2000_writeb, NULL, NULL, dev); + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); io_removehandler(addr+16, 16, - ne2000_readb, ne2000_readw, NULL, - ne2000_writeb, ne2000_writew, NULL, dev); + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); io_removehandler(addr+0x1f, 1, - ne2000_readb, NULL, NULL, - ne2000_writeb, NULL, NULL, dev); + nic_readb, nic_readw, nic_readl, + nic_writeb, nic_writew, nic_writel, dev); } else { io_removehandler(addr, 16, - ne2000_readb, ne2000_readw, ne2000_readl, - ne2000_writeb, ne2000_writew, ne2000_writel, dev); + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); io_removehandler(addr+16, 16, - ne2000_readb, ne2000_readw, ne2000_readl, - ne2000_writeb, ne2000_writew, ne2000_writel, dev); + nic_readb, nic_readw, NULL, + nic_writeb, nic_writew, NULL, dev); io_removehandler(addr+0x1f, 1, - ne2000_readb, ne2000_readw, ne2000_readl, - ne2000_writeb, ne2000_writew, ne2000_writel, dev); + nic_readb, NULL, NULL, + nic_writeb, NULL, NULL, dev); } } static void -ne2000_update_bios(ne2000_t *dev) +nic_update_bios(nic_t *dev) { int reg_bios_enable; reg_bios_enable = 1; /* PCI BIOS stuff, just enable_disable. */ - if (!disable_netbios && reg_bios_enable) { + if (!dev->disable_netbios && reg_bios_enable) { mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, bios_addr, 0x10000); - pclog(1, "NE2000 BIOS now at: %08X\n", bios_addr); + mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios_addr, 0x10000); + pclog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); } else { mem_mapping_disable(&dev->bios_rom.mapping); - if (network_card_current == 2) - pci_bar[1].addr = 0; + if (dev->is_rtl8029as) + pci_bar[1].addr = 0; } } static uint8_t -ne2000_pci_read(int func, int addr, void *priv) +nic_pci_read(int func, int addr, void *priv) { + nic_t *dev = (nic_t *)priv; + switch(addr) { case 0x00: return 0xec; @@ -1491,7 +1481,7 @@ ne2000_pci_read(int func, int addr, void *priv) case 0x30: return pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ case 0x31: - return (pci_bar[1].addr_regs[1] & bios_mask) | 0x18; + return (pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; case 0x32: return pci_bar[1].addr_regs[2]; case 0x33: @@ -1508,15 +1498,15 @@ ne2000_pci_read(int func, int addr, void *priv) static void -ne2000_pci_write(int func, int addr, uint8_t val, void *priv) +nic_pci_write(int func, int addr, uint8_t val, void *priv) { - ne2000_t *dev = (ne2000_t *)priv; + nic_t *dev = (nic_t *)priv; switch(addr) { case 0x04: - ne2000_ioremove(dev->base_address, dev); + nic_ioremove(dev, dev->base_address); if (val & PCI_COMMAND_IO) { - ne2000_ioset(dev->base_address, dev); + nic_ioset(dev, dev->base_address); } pci_regs[addr] = val; break; @@ -1527,7 +1517,7 @@ ne2000_pci_write(int func, int addr, uint8_t val, void *priv) case 0x11: case 0x12: case 0x13: /* I/O Base set. */ /* First, remove the old I/O, if old base was >= 0x280. */ - ne2000_ioremove(dev->base_address, dev); + nic_ioremove(dev, dev->base_address); /* Then let's set the PCI regs. */ pci_bar[0].addr_regs[addr & 3] = val; @@ -1536,21 +1526,20 @@ ne2000_pci_write(int func, int addr, uint8_t val, void *priv) dev->base_address = pci_bar[0].addr & 0xff00; /* Log the new base. */ - pclog(1, "NE2000 RTL8029AS PCI: New I/O base is %04X\n", - dev->base_address); + pclog(1, "%s: PCI: new I/O base is %04X\n", + dev->name, dev->base_address); /* We're done, so get out of the here. */ - if (val & PCI_COMMAND_IO) { - ne2000_ioset(dev->base_address, dev); - } + if (val & PCI_COMMAND_IO) + nic_ioset(dev, dev->base_address); return; case 0x30: case 0x31: case 0x32: case 0x33: pci_bar[1].addr_regs[addr & 3] = val; - pci_bar[1].addr_regs[1] &= bios_mask; - bios_addr = pci_bar[1].addr & 0xffffe000; + pci_bar[1].addr_regs[1] &= dev->bios_mask; + dev->bios_addr = pci_bar[1].addr & 0xffffe000; pci_bar[1].addr &= 0xffffe000; pci_bar[1].addr |= 0x1801; - ne2000_update_bios(dev); + nic_update_bios(dev); return; #if 0 @@ -1560,7 +1549,7 @@ ne2000_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3C: pci_regs[addr] = val; if (val != 0xFF) { - pclog(1, "NE2000 IRQ now: %i\n", val); + pclog(1, "%s: IRQ now: %i\n", dev->name, val); dev->base_irq = irq; } return; @@ -1569,22 +1558,9 @@ ne2000_pci_write(int func, int addr, uint8_t val, void *priv) } -static uint8_t * -ne2000_mac(void) -{ - if (network_card_current == 2) - return(maclocal_pci); - - return(maclocal); -} - - static void -ne2000_tx_event(void *priv, uint32_t val) +nic_tx(nic_t *dev, uint32_t val) { - ne2000_t *dev = (ne2000_t *)priv; - - pclog(1, "tx_timer\n"); dev->CR.tx_packet = 0; dev->TSR.tx_ok = 1; dev->ISR.pkt_tx = 1; @@ -1627,6 +1603,7 @@ mcast_index(const void *dst) #undef POLYNOMIAL } + /* * rx_frame() - called by the platform-specific code when an * ethernet frame has been received. The destination address @@ -1634,311 +1611,248 @@ mcast_index(const void *dst) * rx ring has enough room, it is copied into it and * the receive process is updated */ -void ne2000_rx_frame(void *p, const void *buf, int io_len) +static void +nic_rx(void *priv, uint8_t *buf, int io_len) { - ne2000_t *dev = (ne2000_t *)p; - - int pages; - int avail; - int idx; - int nextpage; - uint8_t pkthdr[4]; - uint8_t *pktbuf = (uint8_t *) buf; - uint8_t *startptr; - static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; - - if(io_len != 60) - { - pclog(1, "rx_frame with length %d\n", io_len); - } - - if ((dev->CR.stop != 0) || - (dev->page_start == 0)) - { - return; - } - - /* Add the pkt header + CRC to the length, and work - out how many 256-byte pages the frame would occupy */ - pages = (io_len + 4 + 4 + 255)/256; - - if (dev->curr_page < dev->bound_ptr) - { - avail = dev->bound_ptr - dev->curr_page; - } - else - { - avail = (dev->page_stop - dev->page_start) - (dev->curr_page - dev->bound_ptr); - } - - /* Avoid getting into a buffer overflow condition by not attempting - to do partial receives. The emulation to handle this condition - seems particularly painful. */ - if ((avail < pages) -#if BX_NE2K_NEVER_FULL_RING - || (avail == pages) -#endif - ) - { - pclog(1, "no space\n"); - return; - } - - if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) - { - pclog(1, "rejected small packet, length %d\n", io_len); - return; - } - /* some computers don't care... */ - if (io_len < 60) - { - io_len=60; - } - - /* Do address filtering if not in promiscuous mode */ - if (! dev->RCR.promisc) - { - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (buf); - mac_cmp16[0] = *(uint16_t *) (((uint8_t *) buf) + 4); - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (bcast_addr); - mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); - if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) - { - if (!dev->RCR.broadcast) - { - return; - } - } - else if (pktbuf[0] & 0x01) - { - if (! dev->RCR.multicast) - { - return; - } - idx = mcast_index(buf); - if (!(dev->mchash[idx >> 3] & (1 << (idx & 0x7)))) - { - return; - } - } - else if (0 != memcmp(buf, dev->physaddr, 6)) - { - return; - } - } - else - { - pclog(1, "rx_frame promiscuous receive\n"); - } - - pclog(1, "rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", io_len, pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); - - nextpage = dev->curr_page + pages; - if (nextpage >= dev->page_stop) - { - nextpage -= dev->page_stop - dev->page_start; - } - - /* Setup packet header */ - pkthdr[0] = 0; /* rx status - old behavior - pkthdr[0] = 1; /* Probably better to set it all the time - rather than set it to 0, which is clearly wrong. */ - if (pktbuf[0] & 0x01) - { - pkthdr[0] |= 0x20; /* rx status += multicast packet */ - } - pkthdr[1] = nextpage; /* ptr to next packet */ - pkthdr[2] = (io_len + 4) & 0xff; /* length-low */ - pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ - - /* copy into buffer, update curpage, and signal interrupt if config'd */ - startptr = & dev->mem[dev->curr_page * 256 - BX_NE2K_MEMSTART]; - if ((nextpage > dev->curr_page) || ((dev->curr_page + pages) == dev->page_stop)) - { - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, io_len); - dev->curr_page = nextpage; - } - else - { - int endbytes = (dev->page_stop - dev->curr_page) * 256; - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, endbytes - 4); - startptr = & dev->mem[dev->page_start * 256 - BX_NE2K_MEMSTART]; - memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); - dev->curr_page = nextpage; - } - - dev->RSR.rx_ok = 1; - if (pktbuf[0] & 0x80) - { - dev->RSR.rx_mbit = 1; - } - - dev->ISR.pkt_rx = 1; - - if (dev->IMR.rx_inte) - { - picint(1 << dev->base_irq); - } -} - - -void -ne2000_poller(void *priv) -{ - ne2000_t *dev = (ne2000_t *)priv; - struct queuepacket *qp; - const unsigned char *data; - struct pcap_pkthdr h; + static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; + nic_t *dev = (nic_t *)priv; + int pages; + int avail; + int idx; + int nextpage; + uint8_t pkthdr[4]; + uint8_t *pktbuf = (uint8_t *) buf; + uint8_t *startptr; uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; - if (! net_is_pcap) { - while(QueuePeek(slirpq) > 0) { - qp = QueueDelete(slirpq); - if ((dev->DCR.loop == 0) || (dev->TCR.loop_cntl != 0)) { - free(qp); - return; - } - ne2000_rx_frame(dev, &qp->data, qp->len); - pclog(1, "ne2000 inQ:%d got a %dbyte packet @%d\n",QueuePeek(slirpq),qp->len,qp); - free(qp); - } - fizz++; - if (fizz > 1200) { - fizz=0; - slirp_tic(); - } + if (io_len != 60) + pclog(2, "%s: rx_frame with length %d\n", dev->name, io_len); + if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; + + /* Add the pkt header + CRC to the length, and work + out how many 256-byte pages the frame would occupy */ + pages = (io_len + 4 + 4 + 255)/256; + if (dev->curr_page < dev->bound_ptr) { + avail = dev->bound_ptr - dev->curr_page; + } else { + avail = (dev->page_stop - dev->page_start) - (dev->curr_page - dev->bound_ptr); + } + + /* Avoid getting into a buffer overflow condition by not attempting + to do partial receives. The emulation to handle this condition + seems particularly painful. */ + if ((avail < pages) +#if NE2K_NEVER_FULL_RING + || (avail == pages) +#endif + ) { + pclog(1, "%s: no space\n", dev->name); return; } - if (net_pcap != NULL) { - if ((dev->DCR.loop == 0) || (dev->TCR.loop_cntl != 0)) { - return; - } - data = pcap_next(net_pcap, &h); - if (data == NULL) { - return; - } + if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { + pclog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); + return; + } + /* some computers don't care... */ + if (io_len < 60) { + io_len=60; + } + + /* Do address filtering if not in promiscuous mode */ + if (! dev->RCR.promisc) { /* Received. */ - mac_cmp32[0] = *(uint32_t *)(data+6); - mac_cmp16[0] = *(uint16_t *)(data+10); + mac_cmp32[0] = *(uint32_t *) (buf); + mac_cmp16[0] = *(uint16_t *) (((uint8_t *) buf) + 4); /* Local. */ - mac_cmp32[1] = *(uint32_t *)(ne2000_mac()); - mac_cmp16[1] = *(uint16_t *)(ne2000_mac()+4); - if ((mac_cmp32[0] != mac_cmp32[1]) || (mac_cmp16[0] != mac_cmp16[1])) { - ne2000_rx_frame(dev, data, h.caplen); - } else { - pclog(1, "NE2000: RX pkt, not for me!\n"); + mac_cmp32[1] = *(uint32_t *) (bcast_addr); + mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); + if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) { + if (! dev->RCR.broadcast) { + return; + } + } else if (pktbuf[0] & 0x01) { + if (! dev->RCR.multicast) { + return; + } + idx = mcast_index(buf); + if (!(dev->mchash[idx >> 3] & (1 << (idx & 0x7)))) { + return; + } + } else if (0 != memcmp(buf, dev->physaddr, 6)) { + return; } + } else { + pclog(2, "%s: rx_frame promiscuous receive\n", dev->name); } + + pclog(2, "%s: rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", + dev->name, io_len, + pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], + pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + + nextpage = dev->curr_page + pages; + if (nextpage >= dev->page_stop) { + nextpage -= dev->page_stop - dev->page_start; + } + + /* Setup packet header */ + pkthdr[0] = 0; /* rx status - old behavior + pkthdr[0] = 1; /* Probably better to set it all the time + rather than set it to 0, which is clearly wrong. */ + if (pktbuf[0] & 0x01) { + pkthdr[0] |= 0x20; /* rx status += multicast packet */ + } + pkthdr[1] = nextpage; /* ptr to next packet */ + pkthdr[2] = (io_len + 4) & 0xff; /* length-low */ + pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ + + /* copy into buffer, update curpage, and signal interrupt if config'd */ + startptr = & dev->mem[dev->curr_page * 256 - NE2K_MEMSTART]; + if ((nextpage > dev->curr_page) || + ((dev->curr_page + pages) == dev->page_stop)) { + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, io_len); + dev->curr_page = nextpage; + } else { + int endbytes = (dev->page_stop - dev->curr_page) * 256; + *(uint32_t *) startptr = *(uint32_t *) pkthdr; + memcpy(startptr + 4, buf, endbytes - 4); + startptr = & dev->mem[dev->page_start * 256 - NE2K_MEMSTART]; + memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); + dev->curr_page = nextpage; + } + + dev->RSR.rx_ok = 1; + if (pktbuf[0] & 0x80) { + dev->RSR.rx_mbit = 1; + } + + dev->ISR.pkt_rx = 1; + + if (dev->IMR.rx_inte) + picint(1 << dev->base_irq); } static void -ne2000_rom_init(ne2000_t *dev, wchar_t *s) +nic_rom_init(nic_t *dev, wchar_t *s) { FILE *f = romfopen(s, L"rb"); uint32_t temp; if (f != NULL) { - disable_netbios = 1; - ne2000_update_bios(dev); + dev->disable_netbios = 1; + nic_update_bios(dev); return; } fseek(f, 0, SEEK_END); temp = ftell(f); fclose(f); - bios_size = 0x10000; + dev->bios_size = 0x10000; if (temp <= 0x8000) - bios_size = 0x8000; + dev->bios_size = 0x8000; if (temp <= 0x4000) - bios_size = 0x4000; + dev->bios_size = 0x4000; if (temp <= 0x2000) - bios_size = 0x2000; - bios_mask = (bios_size >> 8) & 0xff; - bios_mask = (0x100 - bios_mask) & 0xff; + dev->bios_size = 0x2000; + dev->bios_mask = (dev->bios_size >> 8) & 0xff; + dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; +#if 1 + /* Shouldn't we use the configured address?? --FvK */ rom_init(&dev->bios_rom, s, 0xd0000, - bios_size, bios_size - 1, 0, MEM_MAPPING_EXTERNAL); + dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); +#else + rom_init(&dev->bios_rom, s, dev->bios_addr, + dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); +#endif } static void * -ne2000_init(void) +nic_init(int board) { - char errbuf[32768]; - int rc; - int config_net_type; - int irq; - int pcap_device_available = 0; - int is_rtl8029as = 0; - ne2000_t *dev; - char *pcap_dev; + uint32_t mac; + uint8_t *ptr; + nic_t *dev; - dev = malloc(sizeof(ne2000_t)); - memset(dev, 0x00, sizeof(ne2000_t)); - - if (PCI && (network_card_current == 2)) { - is_rtl8029as = 1; - } else { - network_card_current = 1; - is_rtl8029as = 0; - } + dev = malloc(sizeof(nic_t)); + memset(dev, 0x00, sizeof(nic_t)); + dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; + if (board == NE2K_RTL8029AS) + strcpy(dev->name, "RTL8029AS"); + else if (board == NE2K_NE1000) + strcpy(dev->name, "NE1000"); + else + strcpy(dev->name, "NE2000"); - if (is_rtl8029as) { + if (dev->is_rtl8029as) { dev->base_address = 0x340; + mac = config_get_int(NULL, "maclocal_pci", -1); } else { dev->base_address = device_get_config_int("addr"); + mac = config_get_int(NULL, "maclocal", -1); } - irq = device_get_config_int("irq"); - dev->base_irq = irq; + dev->base_irq = device_get_config_int("irq"); + dev->disable_netbios = device_get_config_int("disable_netbios"); - disable_netbios = device_get_config_int("disable_netbios"); - - /* Network type is now specified in device config. */ - config_net_type = device_get_config_int("net_type"); - - net_is_pcap = config_net_type ? 0 : 1; - if (net_is_pcap) { - pcap_dev = config_get_string(NULL, "pcap_device", "nothing"); - if (! strcmp(pcap_dev, "nothing")) { - net_is_pcap = 0; - pcap_device_available = 0; - } else { - pcap_device_available = 1; - } + /* Set up our MAC address. */ + if (dev->is_rtl8029as) { + maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + maclocal_pci[1] = 0x20; + maclocal_pci[2] = 0x18; + ptr = maclocal_pci; + } else { + maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ + maclocal[1] = 0x00; + maclocal[2] = 0xD8; + ptr = maclocal; } - pclog(1, "net_is_pcap = %i\n", net_is_pcap); - - if (is_rtl8029as) { - pci_add(ne2000_pci_read, ne2000_pci_write, dev); +pclog(1, "MAClocal: mac=%08lx\n", mac); + if (mac & 0xff000000) { + /* Generating new MAC. */ + ptr[3] = disc_random_generate(); + ptr[4] = disc_random_generate(); + ptr[5] = disc_random_generate(); + } else { + ptr[3] = (mac>>16) & 0xff; + ptr[4] = (mac>>8) & 0xff; + ptr[5] = mac & 0xff; + } + memcpy(dev->physaddr, ptr, 6); + + pclog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x BIOS=%d\n", + dev->name, dev->base_address, dev->base_irq, + dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], + dev->physaddr[3], dev->physaddr[4], dev->physaddr[5], + !dev->disable_netbios); + + if (network_attach(dev, dev->physaddr, nic_rx) < 0) { + pclog(1, "%s: unable to init platform network type %d\n", + dev->name, network_type); + free(dev); + return(NULL); } - ne2000_ioset(dev->base_address, dev); + if (dev->is_rtl8029as) + pci_add(nic_pci_read, nic_pci_write, dev); + nic_ioset(dev, dev->base_address); - memcpy(dev->physaddr, ne2000_mac(), 6); - - if (! disable_netbios) { - ne2000_rom_init(dev, is_rtl8029as ? L"roms/rtl8029as.rom" - : L"roms/ne2000.rom"); - if (is_rtl8029as) { + if (! dev->disable_netbios) { + nic_rom_init(dev, dev->is_rtl8029as ? L"roms/rtl8029as.rom" + : L"roms/ne2000.rom"); + if (dev->is_rtl8029as) mem_mapping_disable(&dev->bios_rom.mapping); - } } - if (is_rtl8029as) { + if (dev->is_rtl8029as) { pci_regs[0x04] = 1; pci_regs[0x05] = 0; - pci_regs[0x07] = 2; /* Network controller. */ @@ -1946,18 +1860,18 @@ ne2000_init(void) pci_bar[0].addr_regs[0] = 1; - if (disable_netbios) { + if (! dev->disable_netbios) { pci_bar[1].addr = 0; - bios_addr = 0; + dev->bios_addr = 0; } else { pci_bar[1].addr = 0x000F8000; - pci_bar[1].addr_regs[1] = bios_mask; + pci_bar[1].addr_regs[1] = dev->bios_mask; pci_bar[1].addr |= 0x1801; - bios_addr = 0xD0000; + dev->bios_addr = 0xD0000; } - pci_regs[0x3C] = irq; - pclog(1, "RTL8029AS IRQ: %i\n", pci_regs[0x3C]); + pci_regs[0x3C] = dev->base_irq; + pclog(1, "%s: IRQ=%i\n", dev->name, pci_regs[0x3C]); pci_regs[0x3D] = 1; memset(rtl8029as_eeprom, 0, 128); @@ -1973,169 +1887,28 @@ ne2000_init(void) rtl8029as_eeprom[0x7D] = 0xEC; } - ne2000_reset(dev, BX_RESET_HARDWARE); + nic_reset(dev, BX_RESET_HARDWARE); - network_add_handler(ne2000_poller, dev); - - pclog(1, "ne2000 %s init 0x%X %d\tnet_is_pcap is %d\n", - is_rtl8029as?"PCI":"ISA", - dev->base_address, - device_get_config_int("irq"), - net_is_pcap); - - /* need a switch statment for more network types. */ - if (! net_is_pcap) { -initialize_slirp: - pclog(1, "ne2000 initalizing SLiRP\n"); - net_is_pcap=0; - rc=slirp_init(); - pclog(1, "ne2000 slirp_init returned: %d\n",rc); - if (! rc) { - pclog(1, "ne2000 slirp initalized!\n"); - - net_slirp_inited = 1; - slirpq = QueueCreate(); - fizz=0; - pclog(1, "ne2000 slirpq is %x\n",&slirpq); - } else { - net_slirp_inited = 0; - if (pcap_device_available) { - net_is_pcap = 1; - goto initialize_pcap; - } else { - pclog(1, "Neither SLiRP nor PCap available, disabling network adapter...\n"); - free(dev); - network_card_current = 0; - resetpchard(); - return(NULL); - } - } - } else { -initialize_pcap: - pclog(1, "ne2000 initalizing libpcap\n"); - - pclog(1, "ne2000 Pcap version [%s]\n", pcap_lib_version()); - - net_pcap = pcap_open_live(pcap_dev, 1518, 1, 15, errbuf); - if (net_pcap == NULL) { - pclog(1, "NE2000 pcap_open_live error on %s!\n", pcap_dev); - net_is_pcap=0; - return(dev); /* YUCK!!! */ - } - - /* Time to check that we are in non-blocking mode. */ - rc = pcap_getnonblock(net_pcap, errbuf); - pclog(1, "ne2000 pcap is currently in %s mode\n", - rc?"non-blocking":"blocking"); - switch(rc) { - case 0: - pclog(1, "NE2000: setting to non-blocking mode.."); - rc = pcap_setnonblock(net_pcap, 1, errbuf); - if (rc == 0) { - /* no errors! */ - pclog(1, ".."); - rc = pcap_getnonblock(net_pcap, errbuf); - if (rc == 1) { - pclog(1, "..!"); - net_is_pcap = 1; - } else { - pclog(1, "\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - net_is_pcap = 0; - } - } else { - pclog(1, "There was an unexpected error of [%s]\n\nexiting.\n", errbuf); - net_is_pcap = 0; - } - pclog(1, "\n"); - break; - - case 1: - pclog(1, "non blocking\n"); - break; - - default: - pclog(1, "this isn't right!!!\n"); - net_is_pcap = 0; - break; - } - - if (net_is_pcap) { - char filter_exp[255]; - struct bpf_program fp; - uint8_t *mac; - - mac = ne2000_mac(); - pclog(1, "ne2000 Building packet filter ..."); - sprintf(filter_exp, - "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - - if (pcap_compile(net_pcap, &fp, filter_exp, 0, 0xffffffff) == -1) { - pclog(1, "\nne2000 Couldn't compile filter\n"); - } else { - pclog(1, "..."); - if (pcap_setfilter(net_pcap, &fp) == -1) { - pclog(1, "\nError installing pcap filter.\n"); - } else { - pclog(1, "...!\n"); - } - } - pclog(1, "ne2000 Using filter\t[%s]\n", filter_exp); - } else { - pcap_device_available = 0; - goto initialize_slirp; - } - pclog(1, "ne2000 net_is_pcap is %d and net_pcap is %x\n", - net_is_pcap, net_pcap); - } - - pclog(1, "ne2000 is_pcap %d\n", net_is_pcap); + pclog(1, "%s: %s init 0x%X %d\n", dev->name, + dev->is_rtl8029as?"PCI":"ISA", dev->base_address, dev->base_irq); return(dev); } static void -ne2000_close(void *priv) +nic_close(void *priv) { - ne2000_t *dev = (ne2000_t *)priv; + nic_t *dev = (nic_t *)priv; - if (! net_is_pcap) { - QueueDestroy(slirpq); - slirp_exit(0); - net_slirp_inited=0; - pclog(1, "NE2000 exiting slirp\n"); - } else if (net_is_pcap && (net_pcap != NULL)) { - pcap_close(net_pcap); - pclog(1, "NE2000 closing pcap\n"); - } + /* Make sure the platform layer is shut down. */ + network_close(); - ne2000_ioremove(dev->base_address, dev); + nic_ioremove(dev, dev->base_address); free(dev); - pclog(1, "Ne2000 close\n"); -} - - -void -ne2000_generate_maclocal(uint32_t mac) -{ - maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ - maclocal[1] = 0x00; - maclocal[2] = 0xD8; - - if (mac & 0xff000000) { - /* Generating new MAC. */ - maclocal[3] = disc_random_generate(); - maclocal[4] = disc_random_generate(); - maclocal[5] = disc_random_generate(); - } else { - maclocal[3] = (mac>>16) & 0xff; - maclocal[4] = (mac>>8) & 0xff; - maclocal[5] = mac & 0xff; - } + pclog(1, "%s: closed\n", dev->name); } @@ -2152,26 +1925,6 @@ ne2000_get_maclocal(void) } -void -ne2000_generate_maclocal_pci(uint32_t mac) -{ - maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - maclocal_pci[1] = 0x20; - maclocal_pci[2] = 0x18; - - if (mac & 0xff000000) { - /* Generating new MAC. */ - maclocal_pci[3] = disc_random_generate(); - maclocal_pci[4] = disc_random_generate(); - maclocal_pci[5] = disc_random_generate(); - } else { - maclocal_pci[3] = (mac >> 16) & 0xff; - maclocal_pci[4] = (mac >> 8) & 0xff; - maclocal_pci[5] = mac & 0xff; - } -} - - uint32_t ne2000_get_maclocal_pci(void) { @@ -2185,6 +1938,94 @@ ne2000_get_maclocal_pci(void) } +static void * +ne1000_init(void) +{ + return(nic_init(NE2K_NE1000)); +} + + +static void * +ne2000_init(void) +{ + return(nic_init(NE2K_NE2000)); +} + + +static void * +rtl8029as_init(void) +{ + return(nic_init(NE2K_RTL8029AS)); +} + + +static device_config_t ne1000_config[] = +{ + { + "addr", "Address", CONFIG_SELECTION, "", 0x300, + { + { + "0x280", 0x280 + }, + { + "0x300", 0x300 + }, + { + "0x320", 0x320 + }, + { + "0x340", 0x340 + }, + { + "0x360", 0x360 + }, + { + "0x380", 0x380 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 3, + { + { + "IRQ 3", 3 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "" + } + }, + }, + { + "net_type", "Network type", CONFIG_SELECTION, "", 0, + { + { + "PCap", 0 + }, + { + "SLiRP", 1 + }, + { + "" + } + }, + }, + { + "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + }, + { + "", "", -1 + } +}; + static device_config_t ne2000_config[] = { { @@ -2306,81 +2147,39 @@ static device_config_t rtl8029as_config[] = }; -device_t ne2000_device = -{ - "Novell NE2000", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - ne2000_config + +device_t ne1000_device = { + "Novell NE1000", + 0, + ne1000_init, + nic_close, + NULL, + NULL, + NULL, + NULL, + ne1000_config }; -device_t rtl8029as_device = -{ - "Realtek RTL8029AS", - 0, - ne2000_init, - ne2000_close, - NULL, - NULL, - NULL, - NULL, - rtl8029as_config +device_t ne2000_device = { + "Novell NE2000", + 0, + ne2000_init, + nic_close, + NULL, + NULL, + NULL, + NULL, + ne2000_config }; - -/* SLIRP stuff */ -int -slirp_can_output(void) -{ - return(net_slirp_inited); -} - - -void -slirp_output(const unsigned char *pkt, int pkt_len) -{ - struct queuepacket *p; - - p = (struct queuepacket *)malloc(sizeof(struct queuepacket)); - p->len = pkt_len; - memcpy(p->data, pkt, pkt_len); - QueueEnter(slirpq, p); - pclog(1, "ne2000 slirp_output %d @%d\n", pkt_len, p); -} - - -/* Instead of calling this and crashing some times - or experencing jitter, this is called by the - 60Hz clock which seems to do the job. */ -void -slirp_tic(void) -{ - int ret2,nfds; - struct timeval tv; - fd_set rfds, wfds, xfds; - int tmo; - nfds=-1; - - if (! net_slirp_inited) return; - - FD_ZERO(&rfds); - FD_ZERO(&wfds); - FD_ZERO(&xfds); - tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ - if (tmo < 0) { - tmo = 500; - } - - tv.tv_sec = 0; - tv.tv_usec = tmo; /* basilisk default 10000 */ - - ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); - if (ret2 >= 0) { - slirp_select_poll(&rfds, &wfds, &xfds); - } -} +device_t rtl8029as_device = { + "Realtek RTL8029AS", + 0, + rtl8029as_init, + nic_close, + NULL, + NULL, + NULL, + NULL, + rtl8029as_config +}; diff --git a/src/net_ne2000.h b/src/net_ne2000.h index af46ec311..4ff2fd0f6 100644 --- a/src/net_ne2000.h +++ b/src/net_ne2000.h @@ -8,7 +8,7 @@ * * Definitions for the NE2000 ethernet controller. * - * Version: @(#)net_ne2000.h 1.0.1 2017/05/09 + * Version: @(#)net_ne2000.h 1.0.2 2017/05/11 * * Author: Fred N. van Kempen, */ @@ -16,6 +16,12 @@ # define NET_NE2000_H +#define NE2K_NE1000 1 /* 8bit ISA NE1000 */ +#define NE2K_NE2000 2 /* 16bit ISA NE2000 */ +#define NE2K_RTL8029AS 3 /* 32bi PCI Realtek 8029AS */ + + +extern device_t ne1000_device; extern device_t ne2000_device; extern device_t rtl8029as_device; diff --git a/src/net_pcap.c b/src/net_pcap.c new file mode 100644 index 000000000..69a47b9a8 --- /dev/null +++ b/src/net_pcap.c @@ -0,0 +1,212 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handle WinPcap library processing. + * + * Version: @(#)net_pcap.c 1.0.1 2017/05/11 + * + * Author: Fred N. van Kempen, + */ +#include +#include +#include +#include +#include +#include "ibm.h" +#include "config.h" +#include "thread.h" +#include "device.h" +#include "network.h" + + +static pcap_t *pcap; /* handle to WinPcap library */ +static thread_t *poll_tid; +static NETRXCB poll_rx; /* network RX function to call */ +static void *poll_arg; /* network RX function arg */ + + +/* Check if the interface has a packet for us. */ +static void +poll_thread(void *arg) +{ + const unsigned char *data; + uint8_t *mac = (uint8_t *)arg; + struct pcap_pkthdr h; + event_t *evt; + uint32_t mac_cmp32[2]; + uint16_t mac_cmp16[2]; + + pclog("PCAP: polling thread started, arg %08lx\n", arg); + + /* Create a waitable event. */ + evt = thread_create_event(); + pclog("PCAP: poll event is %08lx\n", evt); + + while (pcap != NULL) { + /* Wait for the next packet to arrive. */ + data = pcap_next(pcap, &h); + if (data != NULL) { + /* Received MAC. */ + mac_cmp32[0] = *(uint32_t *)(data+6); + mac_cmp16[0] = *(uint16_t *)(data+10); + + /* Local MAC. */ + mac_cmp32[1] = *(uint32_t *)mac; + mac_cmp16[1] = *(uint16_t *)(mac+4); + if ((mac_cmp32[0] != mac_cmp32[1]) || + (mac_cmp16[0] != mac_cmp16[1])) { + if (poll_rx != NULL) + poll_rx(poll_arg, (uint8_t *)data, h.caplen); + } else { + /* Mark as invalid packet. */ + data = NULL; + } + } + + /* If we did not get anything, wait a while. */ + if (data == NULL) + thread_wait_event(evt, 10); + } + + thread_destroy_event(evt); + poll_tid = NULL; + + pclog("PCAP: polling stopped.\n"); +} + + +/* Initialize WinPcap for us. */ +int +network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) +{ + char temp[PCAP_ERRBUF_SIZE]; + char filter_exp[255]; + struct bpf_program fp; + char *dev; + + /* Messy, but gets rid of a lot of useless info. */ + strcpy(temp, pcap_lib_version()); + dev = strchr(temp, '('); + if (dev != NULL) *(dev-1) = '\0'; + pclog("Initializing WinPcap, version %s\n", temp); + + /* Get the value of our capture interface. */ + dev = config_get_string(NULL, "pcap_device", NULL); + if (dev == NULL) { + pclog(" No network device configured!\n"); + return(-1); + } + pclog(" Network interface: '%s'\n", dev); + + pcap = pcap_open_live(dev, /* interface name */ + 1518, /* maximum packet size */ + 1, /* promiscuous mode? */ + 10, /* timeout in msec */ + temp); /* error buffer */ + if (pcap == NULL) { + pclog("Unable to open WinPcap: %s!\n", temp); + return(-1); + } + + /* Create a MAC address based packet filter. */ + pclog("Building packet filter ..."); + sprintf(filter_exp, + "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + if (pcap_compile(pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { + pclog("..."); + if (pcap_setfilter(pcap, &fp) == -1) { + pclog(" error installing filter!\n"); + } else { + pclog("!\nUsing filter\t[%s]\n", filter_exp); + } + } else { + pclog(" could not compile filter!\n"); + } + + /* Save the callback info. */ + poll_rx = func; + poll_arg = arg; + + pclog("PCAP: creating thread..\n"); + poll_tid = thread_create(poll_thread, mac); + + return(0); +} + + +/* Close up shop. */ +void +network_pcap_close(void) +{ + pcap_t *pc; + + if (pcap != NULL) { + pclog("Closing WinPcap\n"); + + /* Tell the polling thread to shut down. */ + pc = pcap; pcap = NULL; +#if 1 + /* Terminate the polling thread. */ + if (poll_tid != NULL) { + thread_kill(poll_tid); + poll_tid = NULL; + } +#else + /* Wait for the polling thread to shut down. */ + while (poll_tid != NULL) + ; +#endif + + /* OK, now shut down WinPcap itself. */ + pcap_close(pc); + } + poll_rx = NULL; + poll_arg = NULL; +} + + +/* Send a packet to the Pcap interface. */ +void +network_pcap_in(uint8_t *bufp, int len) +{ + if (pcap != NULL) + pcap_sendpacket(pcap, bufp, len); +} + + +/* Retrieve an easy-to-use list of devices. */ +int +network_devlist(netdev_t *list) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *devlist, *dev; + int i = 0; + + /* Retrieve the device list from the local machine */ + if (pcap_findalldevs(&devlist, errbuf) == -1) { + pclog("NETWORK: error in pcap_findalldevs_ex: %s\n", errbuf); + return(-1); + } + + for (dev=devlist; dev!=NULL; dev=dev->next) { + strcpy(list->device, dev->name); + if (dev->description) + strcpy(list->description, dev->description); + else + memset(list->description, '\0', sizeof(list->description)); + list++; + i++; + } + + /* Release the memory. */ + pcap_freealldevs(devlist); + + return(i); +} diff --git a/src/net_slirp.c b/src/net_slirp.c new file mode 100644 index 000000000..43574eccf --- /dev/null +++ b/src/net_slirp.c @@ -0,0 +1,199 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handle SLiRP library processing. + * + * Version: @(#)net_slirp.c 1.0.1 2017/05/11 + * + * Author: Fred N. van Kempen, + */ +#include +#include +#include +#include +#include "slirp/slirp.h" +#include "slirp/queue.h" +#include "ibm.h" +#include "config.h" +#include "device.h" +#include "thread.h" +#include "network.h" + + +static queueADT slirpq; /* SLiRP library handle */ +static thread_t *poll_tid; +static NETRXCB poll_rx; /* network RX function to call */ +static void *poll_arg; /* network RX function arg */ +static int fizz; + + +/* Instead of calling this and crashing some times + or experencing jitter, this is called by the + 60Hz clock which seems to do the job. */ +static void +slirp_tic(void) +{ + int ret2,nfds; + struct timeval tv; + fd_set rfds, wfds, xfds; + int tmo; + nfds=-1; + + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&xfds); + tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ + if (tmo < 0) { + tmo = 500; + } + + tv.tv_sec = 0; + tv.tv_usec = tmo; /* basilisk default 10000 */ + + ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); + if (ret2 >= 0) { + slirp_select_poll(&rfds, &wfds, &xfds); + } +} + + +/* Check if the interface has a packet for us. */ +static void +poll_thread(void *arg) +{ + uint8_t *mac = (uint8_t *)arg; + struct queuepacket *qp; + event_t *evt; + + pclog("SLiRP: polling thread started, arg %08lx\n", arg); + + /* Create a waitable event. */ + evt = thread_create_event(); + pclog("SLiRP: poll event is %08lx\n", evt); + + while (slirpq != NULL) { + if (++fizz > 1200) { + fizz = 0; + slirp_tic(); + } + + /* Wait for the next packet to arrive. */ + if (QueuePeek(slirpq) == 0) { + /* If we did not get anything, wait a while. */ + thread_wait_event(evt, 10); + continue; + } + + /* Grab a packet from the queue. */ + qp = QueueDelete(slirpq); + pclog("SLiRP: inQ:%d got a %dbyte packet @%08lx\n", + QueuePeek(slirpq), qp->len, qp); + + if (poll_rx != NULL) + poll_rx(poll_arg, (uint8_t *)&qp->data, qp->len); + + /* Done with this one. */ + free(qp); + } + + thread_destroy_event(evt); + poll_tid = NULL; + + pclog("SLiRP: polling stopped.\n"); +} + + +/* Initialize SLiRP for us. */ +int +network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) +{ + int rc; + + pclog("Initializing SLiRP\n"); + + if (slirp_init() != 0) { + pclog("SLiRP could not be initialized!\n"); + return(-1); + } + + slirpq = QueueCreate(); + pclog(" Packet queue is at %08lx\n", &slirpq); + + fizz = 0; + + /* Save the callback info. */ + poll_rx = func; + poll_arg = arg; + + pclog("SLiRP: creating thread..\n"); + poll_tid = thread_create(poll_thread, mac); + + return(0); +} + + +void +network_slirp_close(void) +{ + queueADT sl; + + if (slirpq != NULL) { + pclog("Closing SLiRP\n"); + + /* Tell the polling thread to shut down. */ + sl = slirpq; slirpq = NULL; +#if 1 + /* Terminate the polling thread. */ + if (poll_tid != NULL) { + thread_kill(poll_tid); + poll_tid = NULL; + } +#else + /* Wait for the polling thread to shut down. */ + while (poll_tid != NULL) + ; +#endif + + /* OK, now shut down SLiRP itself. */ + QueueDestroy(sl); + slirp_exit(0); + } + + poll_rx = NULL; + poll_arg = NULL; +} + + +/* Send a packet to the SLiRP interface. */ +void +network_slirp_in(uint8_t *pkt, int pkt_len) +{ + if (slirpq != NULL) + slirp_input((const uint8_t *)pkt, pkt_len); +} + + +void +slirp_output(const uint8_t *pkt, int pkt_len) +{ + struct queuepacket *qp; + + if (slirpq != NULL) { + qp = (struct queuepacket *)malloc(sizeof(struct queuepacket)); + qp->len = pkt_len; + memcpy(qp->data, pkt, pkt_len); + QueueEnter(slirpq, qp); + } +} + + +int +slirp_can_output(void) +{ + return((slirpq != NULL)?1:0); +} diff --git a/src/network.c b/src/network.c index 2dee11313..067e7f752 100644 --- a/src/network.c +++ b/src/network.c @@ -8,7 +8,11 @@ * * Implementation of the network module. * - * Version: @(#)network.c 1.0.2 2017/05/09 + * NOTE The definition of the netcard_t is currently not optimal; + * it should be malloc'ed and then linked to the NETCARD def. + * Will be done later. + * + * Version: @(#)network.c 1.0.2 2017/05/11 * * Authors: Kotori, * Fred N. van Kempen, @@ -18,99 +22,161 @@ #include #include #include "ibm.h" +#include "config.h" #include "device.h" -#include "timer.h" -#include "thread.h" #include "network.h" #include "net_ne2000.h" -typedef struct { - char name[64]; - char internal_name[32]; - device_t *device; -} NETCARD; - -typedef struct { - void (*poller)(void *); - void *priv; -} NETPOLL; - - -static int net_handlers_num; -static int net_poll_time = 0; -static int net_poll_time; -static NETPOLL net_handlers[8]; -static NETCARD net_cards[] = { - { "None", "none", NULL }, - { "Novell NE2000", "ne2k", &ne2000_device }, - { "Realtek RTL8029AS", "ne2kpci", &rtl8029as_device }, - { "", "", NULL } +static netcard_t net_cards[] = { + { "None", "none", NULL, + NULL, NULL }, + { "Novell NE1000", "ne1k", &ne1000_device, + NULL, NULL }, + { "Novell NE2000", "ne2k", &ne2000_device, + NULL, NULL }, + { "Realtek RTL8029AS", "ne2kpci", &rtl8029as_device, + NULL, NULL }, + { "", "", NULL, + NULL, NULL } }; -int network_card_current = 0; -uint8_t ethif; -int inum; +int network_card; +int network_type; -static void -net_poll(void *priv) -{ - int c; - - /* Reset the poll timer. */ - net_poll_time += (int)((double)TIMER_USEC * (1000000.0/8.0/3000.0)); - - /* If we have active cards.. */ - if (net_handlers_num) { - /* .. poll each of them. */ - for (c=0; c * Fred N. van Kempen, @@ -18,28 +18,58 @@ # include -#define NE2000 1 -#define RTL8029AS 2 +#define NE1000 1 +#define NE2000 2 +#define RTL8029AS 3 -extern int network_card_current; -extern uint8_t ethif; -extern int inum; +typedef void (*NETRXCB)(void *, uint8_t *, int); +typedef struct { + char name[64]; + char internal_name[32]; + device_t *device; + void *private; + int (*poll)(void *); + NETRXCB rx; +} netcard_t; + +typedef struct { + char device[128]; + char description[128]; +} netdev_t; + + +/* Global variables. */ +extern int network_card; +extern int network_type; + + +/* Function prototypes. */ extern void network_init(void); +extern void network_setup(char *); +extern int network_attach(void *, uint8_t *, NETRXCB); +extern void network_close(void); extern void network_reset(void); -extern void network_add_handler(void (*poller)(void *p), void *p); +extern void network_tx(uint8_t *, int); -extern int network_card_available(int card); -extern char *network_card_getname(int card); -extern int network_card_has_config(int card); -extern char *network_card_get_internal_name(int card); -extern int network_card_get_from_internal_name(char *s); -extern struct device_t *network_card_getdevice(int card); +extern int network_pcap_setup(uint8_t *, NETRXCB, void *); +extern void network_pcap_close(void); +extern void network_pcap_in(uint8_t *, int); +extern int network_devlist(netdev_t *); -extern void initpcap(void); -extern void closepcap(void); +extern int network_slirp_setup(uint8_t *, NETRXCB, void *); +extern void network_slirp_close(void); +extern void network_slirp_in(uint8_t *, int); + +extern int network_devlist(netdev_t *); +extern int network_card_available(int); +extern char *network_card_getname(int); +extern int network_card_has_config(int); +extern char *network_card_get_internal_name(int); +extern int network_card_get_from_internal_name(char *); +extern struct device_t *network_card_getdevice(int); #endif /*NETWORK_H*/ diff --git a/src/pc.c b/src/pc.c index 7b0615abe..bc00e8948 100644 --- a/src/pc.c +++ b/src/pc.c @@ -686,4 +686,5 @@ void closepc(void) closevideo(); device_close_all(); midi_close(); + network_close(); } diff --git a/src/win-settings.c b/src/win-settings.c index 86e1ee792..3e48e898d 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -109,7 +109,7 @@ static void win_settings_init() /* Peripherals category */ temp_scsi_card = scsi_card_current; - temp_net_card = network_card_current; + temp_net_card = network_card; strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); temp_ide_ter = ide_enable[2]; temp_ide_ter_irq = ide_irq[2]; @@ -168,7 +168,7 @@ static int win_settings_changed() /* Peripherals category */ i = i || (scsi_card_current != temp_scsi_card); - i = i || (network_card_current != temp_net_card); + i = i || (network_card != temp_net_card); i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); i = i || (temp_ide_ter != ide_enable[2]); i = i || (temp_ide_ter_irq != ide_irq[2]); @@ -259,7 +259,7 @@ static void win_settings_save() /* Peripherals category */ scsi_card_current = temp_scsi_card; - network_card_current = temp_net_card; + network_card = temp_net_card; strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); ide_enable[2] = temp_ide_ter; ide_irq[2] = temp_ide_ter_irq; From bce795b632484c1837f5fe408daba6ec9ee59d93 Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 12 May 2017 17:33:28 -0400 Subject: [PATCH 206/392] Fixes to Network layer code. --- src/Makefile.mingw | 14 ++-- src/config.c | 6 +- src/net_ne2000.c | 130 ++++++++++++++++----------------- src/network.c | 30 ++------ src/network.h | 3 +- src/pc.c | 2 +- src/{ => pcap}/libwpcapdelay.a | Bin 7 files changed, 80 insertions(+), 105 deletions(-) rename src/{ => pcap}/libwpcapdelay.a (100%) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 098a56fe1..23df94f56 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.11 2017/05/11 +# Version: @(#)Makefile.mingw 1.0.12 2017/05/12 # # Authors: Kotori, # Fred N. van Kempen, @@ -190,8 +190,7 @@ SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ - -lstdc++ -lpsapi -static-libstdc++ -static-libgcc \ - -static -L. -lwpcapdelay + -lstdc++ -lpsapi -static-libstdc++ -static-libgcc # Build rules. @@ -213,17 +212,18 @@ all: $(PROG).exe pcap_if.exe $(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. @$(CC) -o $(PROG).exe \ - $(OBJ) $(LZFOBJ) $(SLIRPOBJ) $(LIBS) + $(OBJ) $(LZFOBJ) $(SLIRPOBJ) \ + $(LIBS) -static -Lpcap -lwpcapdelay ifneq ($(DEBUG), y) - strip $(PROG).exe + @strip $(PROG).exe endif pcap_if.exe: pcap_if.o pcap_if.res @echo Linking pcap_if.exe .. @$(CC) -o pcap_if.exe \ - pcap_if.o pcap_if.res -static -L. -lwpcapdelay + pcap_if.o pcap_if.res -static -Lpcap -lwpcapdelay ifneq ($(DEBUG), y) - strip pcap_if.exe + @strip pcap_if.exe endif diff --git a/src/config.c b/src/config.c index 7fb3c7637..8b31042d3 100644 --- a/src/config.c +++ b/src/config.c @@ -543,10 +543,10 @@ void loadconfig(wchar_t *fn) else scsi_card_current = 0; - /* network */ - p = (char *)config_get_string(NULL, "net_card", ""); + /* Network */ network_type = config_get_int(NULL, "net_type", -1); - network_setup(p); + p = (char *)config_get_string(NULL, "net_card", NULL); + network_card = (p) ? network_card_get_from_internal_name(p) : 0; p = (char *)config_get_string(NULL, "model", ""); if (p) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 30210f259..365cd2b75 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.2 2017/05/11 + * Version: @(#)net_ne2000.c 1.0.3 2017/05/12 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -52,10 +52,6 @@ typedef union { /* This stuff should go into the struct. --FvK */ static uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; static uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; -static uint8_t rtl8029as_eeprom[128]; -static uint8_t pci_regs[256]; -static bar_t pci_bar[2]; -static uint32_t old_base_addr = 0; #if ENABLE_NE2000_LOG static int nic_do_log = ENABLE_NE2000_LOG; #else @@ -63,9 +59,6 @@ static int nic_do_log = 0; #endif -#define BX_RESET_HARDWARE 0 -#define BX_RESET_SOFTWARE 1 - /* Never completely fill the ne2k ring so that we never hit the unclear completely full buffer condition. */ #define NE2K_NEVER_FULL_RING (1) @@ -201,28 +194,30 @@ typedef struct { * Data Configuration Register 0eh read (repeated) * Interrupt Mask Register 0fh read (repeated) */ - uint8_t rempkt_ptr; /* 03h read/write ; remote next-packet ptr */ - uint8_t localpkt_ptr; /* 05h read/write ; local next-packet ptr */ - uint16_t address_cnt; /* 06,07h read/write ; address counter */ + uint8_t rempkt_ptr; /* 03h read/write ; rmt next-pkt ptr */ + uint8_t localpkt_ptr; /* 05h read/write ; lcl next-pkt ptr */ + uint16_t address_cnt; /* 06,07h read/write ; address cter */ /* Page 3 - should never be modified. */ /* Novell ASIC state */ - uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ + uint8_t macaddr[32]; /* ASIC ROM'd MAC address, even bytes */ uint8_t mem[NE2K_MEMSIZ]; /* on-chip packet memory */ - /* ne2k internal state */ + int board; + int is_rtl8029as; char name[32]; uint32_t base_address; int base_irq; - int is_rtl8029as; - int tx_timer_index; - int tx_timer_active; - uint32_t bios_addr, bios_size, bios_mask; + bar_t pci_bar[2]; int disable_netbios; + int tx_timer_index; + int tx_timer_active; + uint8_t pci_regs[256]; + uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; } nic_t; @@ -460,7 +455,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) break; case 0x0f: /* Reset register */ - nic_reset(dev, BX_RESET_SOFTWARE); + nic_reset(dev, 1); break; default: @@ -1355,8 +1350,6 @@ nic_writel(uint16_t addr, uint32_t val, void *priv) static void nic_ioset(nic_t *dev, uint16_t addr) { - old_base_addr = addr; - if (dev->is_rtl8029as) { io_sethandler(addr, 16, nic_readb, nic_readw, nic_readl, @@ -1423,7 +1416,7 @@ nic_update_bios(nic_t *dev) } else { mem_mapping_disable(&dev->bios_rom.mapping); if (dev->is_rtl8029as) - pci_bar[1].addr = 0; + dev->pci_bar[1].addr = 0; } } @@ -1454,9 +1447,9 @@ nic_pci_read(int func, int addr, void *priv) return 0x11; case 0x04: - return pci_regs[0x04]; /*Respond to IO and memory accesses*/ + return dev->pci_regs[0x04]; /*Respond to IO and memory accesses*/ case 0x05: - return pci_regs[0x05]; + return dev->pci_regs[0x05]; case 0x07: return 2; @@ -1467,30 +1460,30 @@ nic_pci_read(int func, int addr, void *priv) return 0; /*Programming interface*/ case 0x0B: - return pci_regs[0x0B]; + return dev->pci_regs[0x0B]; case 0x10: return 1; /*I/O space*/ case 0x11: - return pci_bar[0].addr_regs[1]; + return dev->pci_bar[0].addr_regs[1]; case 0x12: - return pci_bar[0].addr_regs[2]; + return dev->pci_bar[0].addr_regs[2]; case 0x13: - return pci_bar[0].addr_regs[3]; + return dev->pci_bar[0].addr_regs[3]; case 0x30: - return pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ + return dev->pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ case 0x31: - return (pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; + return (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; case 0x32: - return pci_bar[1].addr_regs[2]; + return dev->pci_bar[1].addr_regs[2]; case 0x33: - return pci_bar[1].addr_regs[3]; + return dev->pci_bar[1].addr_regs[3]; case 0x3C: - return pci_regs[0x3C]; + return dev->pci_regs[0x3C]; case 0x3D: - return pci_regs[0x3D]; + return dev->pci_regs[0x3D]; } return 0; @@ -1508,7 +1501,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) if (val & PCI_COMMAND_IO) { nic_ioset(dev, dev->base_address); } - pci_regs[addr] = val; + dev->pci_regs[addr] = val; break; case 0x10: @@ -1520,10 +1513,10 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) nic_ioremove(dev, dev->base_address); /* Then let's set the PCI regs. */ - pci_bar[0].addr_regs[addr & 3] = val; + dev->pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - dev->base_address = pci_bar[0].addr & 0xff00; + dev->base_address = dev->pci_bar[0].addr & 0xff00; /* Log the new base. */ pclog(1, "%s: PCI: new I/O base is %04X\n", @@ -1534,11 +1527,11 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) return; case 0x30: case 0x31: case 0x32: case 0x33: - pci_bar[1].addr_regs[addr & 3] = val; - pci_bar[1].addr_regs[1] &= dev->bios_mask; - dev->bios_addr = pci_bar[1].addr & 0xffffe000; - pci_bar[1].addr &= 0xffffe000; - pci_bar[1].addr |= 0x1801; + dev->pci_bar[1].addr_regs[addr & 3] = val; + dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; + dev->bios_addr = dev->pci_bar[1].addr & 0xffffe000; + dev->pci_bar[1].addr &= 0xffffe000; + dev->pci_bar[1].addr |= 0x1801; nic_update_bios(dev); return; @@ -1547,7 +1540,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) * the PIIX3, otherwise the RTL-8029/AS will not get an IRQ * on boards using the PIIX3. */ case 0x3C: - pci_regs[addr] = val; + dev->pci_regs[addr] = val; if (val != 0xFF) { pclog(1, "%s: IRQ now: %i\n", dev->name, val); dev->base_irq = irq; @@ -1783,6 +1776,7 @@ nic_init(int board) dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); + dev->board = board; dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; if (board == NE2K_RTL8029AS) strcpy(dev->name, "RTL8029AS"); @@ -1791,6 +1785,8 @@ nic_init(int board) else strcpy(dev->name, "NE2000"); + dev->base_irq = device_get_config_int("irq"); + dev->disable_netbios = device_get_config_int("disable_netbios"); if (dev->is_rtl8029as) { dev->base_address = 0x340; mac = config_get_int(NULL, "maclocal_pci", -1); @@ -1798,8 +1794,6 @@ nic_init(int board) dev->base_address = device_get_config_int("addr"); mac = config_get_int(NULL, "maclocal", -1); } - dev->base_irq = device_get_config_int("irq"); - dev->disable_netbios = device_get_config_int("disable_netbios"); /* Set up our MAC address. */ if (dev->is_rtl8029as) { @@ -1851,43 +1845,43 @@ pclog(1, "MAClocal: mac=%08lx\n", mac); } if (dev->is_rtl8029as) { - pci_regs[0x04] = 1; - pci_regs[0x05] = 0; - pci_regs[0x07] = 2; + dev->pci_regs[0x04] = 1; + dev->pci_regs[0x05] = 0; + dev->pci_regs[0x07] = 2; /* Network controller. */ - pci_regs[0x0B] = 2; + dev->pci_regs[0x0B] = 2; - pci_bar[0].addr_regs[0] = 1; + dev->pci_bar[0].addr_regs[0] = 1; if (! dev->disable_netbios) { - pci_bar[1].addr = 0; + dev->pci_bar[1].addr = 0; dev->bios_addr = 0; } else { - pci_bar[1].addr = 0x000F8000; - pci_bar[1].addr_regs[1] = dev->bios_mask; - pci_bar[1].addr |= 0x1801; + dev->pci_bar[1].addr = 0x000F8000; + dev->pci_bar[1].addr_regs[1] = dev->bios_mask; + dev->pci_bar[1].addr |= 0x1801; dev->bios_addr = 0xD0000; } - pci_regs[0x3C] = dev->base_irq; - pclog(1, "%s: IRQ=%i\n", dev->name, pci_regs[0x3C]); - pci_regs[0x3D] = 1; + dev->pci_regs[0x3C] = dev->base_irq; + pclog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]); + dev->pci_regs[0x3D] = 1; - memset(rtl8029as_eeprom, 0, 128); - rtl8029as_eeprom[0x76] = - rtl8029as_eeprom[0x7A] = - rtl8029as_eeprom[0x7E] = 0x29; - rtl8029as_eeprom[0x77] = - rtl8029as_eeprom[0x7B] = - rtl8029as_eeprom[0x7F] = 0x80; - rtl8029as_eeprom[0x78] = - rtl8029as_eeprom[0x7C] = 0x10; - rtl8029as_eeprom[0x79] = - rtl8029as_eeprom[0x7D] = 0xEC; + memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); + dev->eeprom[0x76] = + dev->eeprom[0x7A] = + dev->eeprom[0x7E] = 0x29; + dev->eeprom[0x77] = + dev->eeprom[0x7B] = + dev->eeprom[0x7F] = 0x80; + dev->eeprom[0x78] = + dev->eeprom[0x7C] = 0x10; + dev->eeprom[0x79] = + dev->eeprom[0x7D] = 0xEC; } - nic_reset(dev, BX_RESET_HARDWARE); + nic_reset(dev, 0); pclog(1, "%s: %s init 0x%X %d\n", dev->name, dev->is_rtl8029as?"PCI":"ISA", dev->base_address, dev->base_irq); diff --git a/src/network.c b/src/network.c index 067e7f752..f79f91628 100644 --- a/src/network.c +++ b/src/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.2 2017/05/11 + * Version: @(#)network.c 1.0.3 2017/05/12 * * Authors: Kotori, * Fred N. van Kempen, @@ -22,7 +22,6 @@ #include #include #include "ibm.h" -#include "config.h" #include "device.h" #include "network.h" #include "net_ne2000.h" @@ -61,27 +60,6 @@ network_init(void) } -/* - * Set up the network for a card. - * - * This function gets called whenever we load a new - * system configuration file. It only grabs the variables - * from that file, and saves them locally. - */ -void -network_setup(char *name) -{ - /* No platform support, give up. */ - if (network_type < 0) return; - - network_card = network_card_get_from_internal_name(name); - if (network_card == 0) return; - - pclog("NETWORK: set up for card '%s' (%d) in %s\n", - name, network_card, (network_type==1)?"SLiRP":"WinPcap"); -} - - /* * Attach a network card to the system. * @@ -143,7 +121,7 @@ network_close(void) void network_reset(void) { - pclog("NETWORK: reset (card=%d)\n", network_card); + pclog("NETWORK: reset (type=%d, card=%d\n", network_type, network_card); /* Just in case.. */ network_close(); @@ -151,6 +129,10 @@ network_reset(void) /* If no active card, we're done. */ if (!network_card || (network_type<0)) return; + pclog("NETWORK: set up for %s, card=%s\n", + (network_type==1)?"SLiRP":"WinPcap", net_cards[network_card].name); + + pclog("NETWORK: reset (card=%d)\n", network_card); /* Add the (new?) card to the I/O system. */ if (net_cards[network_card].device) { pclog("NETWORK: adding device '%s'\n", diff --git a/src/network.h b/src/network.h index 535419638..ed971e9b7 100644 --- a/src/network.h +++ b/src/network.h @@ -8,7 +8,7 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.2 2017/05/11 + * Version: @(#)network.h 1.0.3 2017/05/12 * * Authors: Kotori, * Fred N. van Kempen, @@ -48,7 +48,6 @@ extern int network_type; /* Function prototypes. */ extern void network_init(void); -extern void network_setup(char *); extern int network_attach(void *, uint8_t *, NETRXCB); extern void network_close(void); extern void network_reset(void); diff --git a/src/pc.c b/src/pc.c index bc00e8948..38c3b2672 100644 --- a/src/pc.c +++ b/src/pc.c @@ -475,6 +475,7 @@ void resetpchard(void) model_init(); video_init(); speaker_init(); + network_reset(); ide_ter_disable(); ide_qua_disable(); @@ -497,7 +498,6 @@ void resetpchard(void) } } - network_reset(); resetide(); scsi_card_init(); diff --git a/src/libwpcapdelay.a b/src/pcap/libwpcapdelay.a similarity index 100% rename from src/libwpcapdelay.a rename to src/pcap/libwpcapdelay.a From 5ba88cba300a3ead645e6c43b0103e910bc4a1cc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 13 May 2017 02:58:36 +0200 Subject: [PATCH 207/392] Reduced the MPU-401 reset timer multiplier to 33, should make Harball 3 work on most, if not all, emulated machines; The Read TOC command no longer sends more data than requested, and it always returns the correct value in the data field if the request data length is smaller than the actual data length. --- src/SOUND/snd_mpu401.c | 2 +- src/cdrom.c | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 837186188..eace343f3 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -271,7 +271,7 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) break; case 0xff: /* Reset MPU-401 */ pclog("MPU-401:Reset %X\n",val); - mpu401_reset_callback = MPU401_RESETBUSY * 200 * TIMER_USEC; + mpu401_reset_callback = MPU401_RESETBUSY * 33 * TIMER_USEC; mpu->state.reset=1; MPU401_Reset(mpu); if (mpu->mode==M_UART) return;//do not send ack in UART mode diff --git a/src/cdrom.c b/src/cdrom.c index 74968157d..8617e35af 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2424,19 +2424,17 @@ void cdrom_command(uint8_t id, uint8_t *cdb) toc_format = (cdb[9] >> 6) & 3; } - len = cdb[8] + (cdb[7] << 8); - switch (toc_format) { case 0: /*Normal*/ - len = cdrom_drives[id].handler->readtoc(id, cdbufferb, cdb[6], msf, len, 0); + len = cdrom_drives[id].handler->readtoc(id, cdbufferb, cdb[6], msf, max_len, 0); break; case 1: /*Multi session*/ - len = cdrom_drives[id].handler->readtoc_session(id, cdbufferb, msf, len); + len = cdrom_drives[id].handler->readtoc_session(id, cdbufferb, msf, max_len); cdbufferb[0] = 0; cdbufferb[1] = 0xA; break; case 2: /*Raw*/ - len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, len); + len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, max_len); break; default: cdrom_invalid_field(id); @@ -2444,6 +2442,14 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } } + if (len > max_len) + { + len = max_len; + + cdbufferb[0] = ((len - 2) >> 8) & 0xff; + cdbufferb[1] = (len - 2) & 0xff; + } + cdrom_data_command_finish(id, len, len, len, 0); /* cdrom_log("CD-ROM %i: READ_TOC_PMA_ATIP format %02X, length %i (%i)\n", id, toc_format, ide->cylinder, cdbufferb[1]); */ return; From 428d73e4f7bba4b8c77fa498e7e55df068d86f5a Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 12 May 2017 22:16:19 -0400 Subject: [PATCH 208/392] Added new win-opendir.c and plat-dir.c for Kotori, fixed some minor stuff elsewhere. --- src/Makefile.mingw | 2 +- src/net_pcap.c | 11 ++- src/pc.c | 22 ++++- src/plat-dir.h | 76 ++++++++++++++++ src/win-opendir.c | 213 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 321 insertions(+), 3 deletions(-) create mode 100644 src/plat-dir.h create mode 100644 src/win-opendir.c diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 23df94f56..ff573e673 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -175,7 +175,7 @@ VIDOBJ = video.o \ WINOBJ = win.o \ win-d3d.o win-d3d-fs.o \ win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o \ + win-language.o win-status.o win-opendir.o \ win-video.o win-serial.o win-mouse.o \ win-joystick.o win-midi.o \ win-settings.o win-deviceconfig.o win-joystickconfig.o \ diff --git a/src/net_pcap.c b/src/net_pcap.c index 69a47b9a8..f3db05131 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -90,7 +90,16 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) char *dev; /* Messy, but gets rid of a lot of useless info. */ - strcpy(temp, pcap_lib_version()); + dev = (char *)pcap_lib_version(); + if (dev == NULL) { + /* Hmm, WinPcap doesn't seem to be alive.. */ + pclog("PCAP: WinPcap library not found, disabling network!\n"); + network_type = -1; + return(-1); + } + + /* OK, good for now.. */ + strcpy(temp, dev); dev = strchr(temp, '('); if (dev != NULL) *(dev-1) = '\0'; pclog("Initializing WinPcap, version %s\n", temp); diff --git a/src/pc.c b/src/pc.c index 38c3b2672..3dd43745b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -46,7 +46,6 @@ #include "mouse.h" #include "plat-mouse.h" #include "network.h" -#include "net_ne2000.h" #include "serial.h" #include "sound/sound.h" #include "sound/snd_cms.h" @@ -59,6 +58,10 @@ #include "video/video.h" #include "video/vid_voodoo.h" #include "amstrad.h" +#ifdef WALTJE +# define UNICODE +# include "plat-dir.h" +#endif #ifndef __unix #define UNICODE @@ -313,6 +316,23 @@ void initpc(int argc, wchar_t *argv[]) else if (!_wcsicmp(argv[c], L"--test")) { /* some (undocumented) test function here.. */ +#ifdef WALTJE + DIR *dir; + struct direct *dp; + + dir = opendirw(pcempath); + if (dir != NULL) { + printf("Directory '%ws':\n", pcempath); + for (;;) { + dp = readdir(dir); + if (dp == NULL) break; + printf(">> '%ws'\n", dp->d_name); + } + closedir(dir); + } else { + printf("Could not open '%ws'..\n", pcempath); + } +#endif /* .. and then exit. */ exit(0); diff --git a/src/plat-dir.h b/src/plat-dir.h new file mode 100644 index 000000000..f9fbf2a9d --- /dev/null +++ b/src/plat-dir.h @@ -0,0 +1,76 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the platform OpenDir module. + * + * Version: @(#)plat-dir.h 1.0.1 2017/05/12 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef PLAT_DIR_H +# define PLAT_DIR_H + + +#ifdef _MAX_FNAME +# define MAXNAMLEN _MAX_FNAME +#else +# define MAXNAMLEN 15 +#endif +# define MAXDIRLEN 127 + + +struct direct { + long d_ino; + unsigned short d_reclen; + unsigned short d_off; +#ifdef UNICODE + wchar_t d_name[MAXNAMLEN + 1]; +#else + char d_name[MAXNAMLEN + 1]; +#endif +}; +#define d_namlen d_reclen + + +typedef struct { + short flags; /* internal flags */ + short offset; /* offset of entry into dir */ + long handle; /* open handle to Win32 system */ + short sts; /* last known status code */ + char *dta; /* internal work data */ +#ifdef UNICODE + wchar_t dir[MAXDIRLEN+1]; /* open dir */ +#else + char dir[MAXDIRLEN+1]; /* open dir */ +#endif + struct direct dent; /* actual directory entry */ +} DIR; + + +/* Directory routine flags. */ +#define DIR_F_LOWER 0x0001 /* force to lowercase */ +#define DIR_F_SANE 0x0002 /* force this to sane path */ +#define DIR_F_ISROOT 0x0010 /* this is the root directory */ + + +/* Function prototypes. */ +#ifdef UNICODE +extern DIR *opendirw(const wchar_t *); +#else +extern DIR *opendir(const char *); +#endif +extern struct direct *readdir(DIR *); +extern long telldir(DIR *); +extern void seekdir(DIR *, long); +extern int closedir(DIR *); + +#define rewinddir(dirp) seekdir(dirp, 0L) + + +#endif /*PLAT_DIR_H*/ diff --git a/src/win-opendir.c b/src/win-opendir.c new file mode 100644 index 000000000..847265582 --- /dev/null +++ b/src/win-opendir.c @@ -0,0 +1,213 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation POSIX OpenDir(3) and friends for Win32 API. + * + * Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19 + * + * Version: @(#)win-opendir.c 1.0.1 2017/05/12 + * + * Author: Fred N. van Kempen, + * Copyright 1998-2007 MicroWalt Corporation + * Copyright 2017 Fred N. van Kempen + */ +#define UNICODE +#include +#include +#include +#include +#include +#include +#include "ibm.h" +#include "plat-dir.h" + + +#ifdef UNICODE +# define SUFFIX L"\\*" +# define FINDATA struct _wfinddata_t +# define FINDFIRST _wfindfirst +# define FINDNEXT _wfindnext +#else +# define SUFFIX "\\*" +# define FINDATA struct _finddata_t +# define FINDFIRST _findfirst +# define FINDNEXT _findnext +#endif + + +/* Open a directory. */ +DIR * +#ifdef UNICODE +opendirw(const wchar_t *name) +#else +opendir(const char *name) +#endif +{ + DIR *p; + + /* Create a new control structure. */ + p = (DIR *) malloc(sizeof(DIR)); + if (p == NULL) + return(NULL); + memset(p, 0x00, sizeof(DIR)); + p->flags = (DIR_F_LOWER | DIR_F_SANE); + p->offset = 0; + p->sts = 0; + + /* Create a work area. */ + p->dta = (char *)malloc(sizeof(FINDATA)); + if (p->dta == NULL) { + free(p); + return(NULL); + } + memset(p->dta, 0x00, sizeof(struct _finddata_t)); + + /* Add search filespec. */ +#ifdef UNICODE + wcscpy(p->dir, name); + wcscat(p->dir, SUFFIX); +#else + strcpy(p->dir, name); + strcat(p->dir, SUFFIX); +#endif + + /* Special case: flag if we are in the root directory. */ +#ifdef UNICODE + if (wcslen(p->dir) == 3) +#else + if (strlen(p->dir) == 3) +#endif + p->flags |= DIR_F_ISROOT; + + /* Start the searching by doing a FindFirst. */ + p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); + if (p->handle < 0L) { + free(p->dta); + free(p); + return(NULL); + } + + /* All OK. */ + return(p); +} + + +/* Close an open directory. */ +int +closedir(DIR *p) +{ + if (p == NULL) + return(0); + + _findclose(p->handle); + + if (p->dta != NULL) + free(p->dta); + free(p); + + return(0); +} + + +/* + * Read the next entry from a directory. + * Note that the DOS (FAT), Windows (FAT, FAT32) and Windows NTFS + * file systems do not have a root directory containing the UNIX- + * standard "." and ".." entries. Many applications do assume + * this anyway, so we simply fake these entries. + */ +struct direct * +readdir(DIR *p) +{ + FINDATA *ffp; + + if (p == NULL || p->sts == 1) + return(NULL); + + /* Format structure with current data. */ + ffp = (FINDATA *)p->dta; + p->dent.d_ino = 1L; + p->dent.d_off = p->offset++; + switch(p->offset) { + case 1: /* . */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, L".", MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, ".", MAXNAMLEN+1); +#endif + p->dent.d_reclen = 1; + break; + + case 2: /* .. */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, L"..", MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, "..", MAXNAMLEN+1); +#endif + p->dent.d_reclen = 2; + break; + + default: /* regular entry. */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); +#endif + p->dent.d_reclen = (char) wcslen(p->dent.d_name); + } + + /* Read next entry. */ + p->sts = 0; + + /* Fake the "." and ".." entries here.. */ + if ((p->flags & DIR_F_ISROOT) && (p->offset <= 2)) + return(&(p->dent)); + + /* Get the next entry if we did not fake the above. */ + if (FINDNEXT(p->handle, ffp) < 0) + p->sts = 1; + + return(&(p->dent)); +} + + +/* Report current position within the directory. */ +long +telldir(DIR *p) +{ + return(p->offset); +} + + +void +seekdir(DIR *p, long newpos) +{ + short pos; + + /* First off, rewind to start of directory. */ + p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); + if (p->handle < 0L) { + p->sts = 1; + return; + } + p->offset = 0; + p->sts = 0; + + /* If we are rewinding, that's all... */ + if (newpos == 0L) return; + + /* Nope.. read entries until we hit the right spot. */ + pos = (short) newpos; + while (p->offset != pos) { + p->offset++; + if (FINDNEXT(p->handle, (FINDATA *)p->dta) < 0) { + p->sts = 1; + return; + } + } +} From bcc505e4b8fe1fd02f07f92921bdd89b1066b968 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 14 May 2017 16:46:15 +0200 Subject: [PATCH 209/392] Added Adaptec AHA-1640 MCA SCSI adapter for IBM PS/2 Model 50+ only at the moment. --- src/scsi.c | 1 + src/scsi_aha154x.c | 141 ++++++++++++++++++++++++++++++++++++++++++--- src/scsi_aha154x.h | 1 + src/win-settings.c | 28 +++++---- 4 files changed, 152 insertions(+), 19 deletions(-) diff --git a/src/scsi.c b/src/scsi.c index 733e2a0a7..c01458d44 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -35,6 +35,7 @@ static SCSI_CARD scsi_cards[] = { { "None", "none", NULL }, { "Adaptec AHA-1540B", "aha1540b", &aha1540b_device }, { "Adaptec AHA-1542CF", "aha1542cf", &aha1542cf_device }, + { "Adaptec AHA-1640", "aha1640", &aha1640_device }, { "BusLogic BT-542B", "bt542b", &buslogic_device }, { "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device }, { "", "", NULL } diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 615bd8675..8a82b7e36 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -176,7 +176,6 @@ static uint16_t aha_ports[] = { 0x0130, 0x0134, 0x0000, 0x0000 }; - /* * Write data to the BIOS space. * @@ -258,7 +257,7 @@ aha_patch(uint8_t *romptr, uint16_t ioaddr) /* Initialize AHA-154xNN-specific stuff. */ static void -aha154x_bios(uint16_t ioaddr, uint32_t memaddr, aha_info *aha) +aha154x_bios(uint16_t ioaddr, uint32_t memaddr, aha_info *aha, int irq, int dma) { uint32_t bios_size; uint32_t bios_addr; @@ -388,10 +387,11 @@ again: /* Initialize the on-board EEPROM. */ memset(aha_eep, 0x00, EEP_SIZE); aha_eep[0] = 7; /* SCSI ID 7 */ - aha_eep[1] = 15-9; /* IRQ15 */ - aha_eep[1] |= (6<<4); /* DMA6 */ - aha_eep[2] = (EE2_HABIOS | /* BIOS Space Reserved */ - EE2_SEEKRET); /* Immediate return on seek */ + aha_eep[0] |= (0x10 | 0x20 | 0x40); + aha_eep[1] = irq-9; /* IRQ15 */ + aha_eep[1] |= (dma<<4); /* DMA6 */ + aha_eep[2] = (EE2_DYNSCAN | /* BIOS Space Reserved */ + EE2_EXT1G | EE2_RMVOK); /* Immediate return on seek */ aha_eep[3] = SPEED_50; /* speed 5.0 MB/s */ aha_eep[6] = (EE6_TERM | /* host term enable */ EE6_RSTBUS); /* reset SCSI bus on boot */ @@ -843,6 +843,7 @@ typedef struct { mem_mapping_t mmio_mapping; aha_info aha; int chip; + uint8_t pos_regs[8]; } aha_t; #pragma pack(pop) @@ -855,7 +856,8 @@ static aha_t *ResetDev; enum { CHIP_AHA154XB, - CHIP_AHA154XCF + CHIP_AHA154XCF, + CHIP_AHA1640 }; @@ -2175,6 +2177,32 @@ aha_cmd_cb(void *priv) AHA_Callback += 50 * SCSI_TIME; } +uint8_t aha_mca_read(int port, void *p) +{ + aha_t *dev = (aha_t *)p; + + return dev->pos_regs[port & 7]; +} + +static uint16_t aha_mca_addr[6] = {0x130, 0x134, 0x230, 0x234, 0x330, 0x334}; + +void aha_mca_write(int port, uint8_t val, void *p) +{ + aha_t *dev = (aha_t *)p; + uint16_t addr; + + if (port < 0x102) + return; + + addr = aha_mca_addr[dev->pos_regs[4] & 7]; + if ((dev->pos_regs[2] & 1) && !(val & 1)) + io_removehandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); + if (!(dev->pos_regs[2] & 1) && (val & 1)) + io_sethandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); + + dev->pos_regs[port & 7] = val; +} + static void * aha_init(int chip, int has_bios) @@ -2222,6 +2250,14 @@ aha_init(int chip, int has_bios) } } + if (dev->chip == CHIP_AHA1640) + { + pclog("Aha1640 initialized\n"); + mca_add(aha_mca_read, aha_mca_write, dev); + dev->pos_regs[0] = 0x1F; + dev->pos_regs[1] = 0x0F; + } + timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev); timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev); @@ -2231,7 +2267,7 @@ aha_init(int chip, int has_bios) if (bios) { /* Perform AHA-154xNN-specific initialization. */ - aha154x_bios(dev->Base, bios_addr, &dev->aha); + aha154x_bios(dev->Base, bios_addr, &dev->aha, dev->Irq, dev->DmaChannel); } return(dev); @@ -2251,6 +2287,12 @@ aha_154xCF_init(void) return(aha_init(CHIP_AHA154XCF, 1)); } +static void * +aha_1640_init(void) +{ + return(aha_init(CHIP_AHA1640, 1)); +} + static void aha_close(void *priv) @@ -2359,6 +2401,77 @@ static device_config_t aha_154XCF_config[] = { } }; +static device_config_t aha_1640_config[] = { + { + "addr", "Address", CONFIG_SELECTION, "", 0x330, + { + { + "0x330", 0x330 + }, + { + "0x334", 0x334 + }, + { + "0x230", 0x230 + }, + { + "0x234", 0x234 + }, + { + "0x130", 0x130 + }, + { + "0x134", 0x134 + }, + { + "" + } + }, + }, + { + "irq", "IRQ", CONFIG_SELECTION, "", 10, + { + { + "IRQ 10", 10 + }, + { + "IRQ 11", 11 + }, + { + "IRQ 12", 12 + }, + { + "IRQ 14", 14 + }, + { + "IRQ 15", 15 + }, + { + "" + } + }, + }, + { + "dma", "DMA channel", CONFIG_SELECTION, "", 6, + { + { + "DMA 5", 5 + }, + { + "DMA 6", 6 + }, + { + "DMA 7", 7 + }, + { + "" + } + }, + }, + { + "", "", -1 + } +}; device_t aha1540b_device = { "Adaptec AHA-1540B", @@ -2383,3 +2496,15 @@ device_t aha1542cf_device = { NULL, aha_154XCF_config }; + +device_t aha1640_device = { + "Adaptec AHA-1640", + DEVICE_MCA, + aha_1640_init, + aha_close, + NULL, + NULL, + NULL, + NULL, + aha_1640_config +}; \ No newline at end of file diff --git a/src/scsi_aha154x.h b/src/scsi_aha154x.h index 67734e070..0e7db0d0d 100644 --- a/src/scsi_aha154x.h +++ b/src/scsi_aha154x.h @@ -12,6 +12,7 @@ typedef struct { extern device_t aha1540b_device; extern device_t aha1542cf_device; +extern device_t aha1640_device; #endif /*SCSI_AHA154X_H*/ diff --git a/src/win-settings.c b/src/win-settings.c index 3e48e898d..8567391d1 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -1192,6 +1192,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR int c = 0; int d = 0; LPTSTR lptsTemp; + device_t *scsi_dev; switch (message) { @@ -1210,21 +1211,26 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR break; } - settings_scsi_to_list[c] = d; - + settings_scsi_to_list[c] = d; + if (scsi_card_available(c)) { - if (c == 0) + scsi_dev = scsi_card_getdevice(c); + + if (!scsi_dev || (scsi_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_scsi[d] = c; + d++; } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_scsi[d] = c; - d++; } c++; From 0d0d479280c77b3b1554e96bc7eb48bea4d05ffe Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 May 2017 18:10:46 +0200 Subject: [PATCH 210/392] Attempt to fix the status bar icons bug. --- src/ICONS/network.ico | Bin 0 -> 1150 bytes src/ICONS/other_peripherals.ico | Bin 1150 -> 1150 bytes src/cdrom-image.cc | 186 ++------------------------------ src/win.c | 8 +- 4 files changed, 16 insertions(+), 178 deletions(-) create mode 100644 src/ICONS/network.ico diff --git a/src/ICONS/network.ico b/src/ICONS/network.ico new file mode 100644 index 0000000000000000000000000000000000000000..b078387d39de419d0da0d3fb2c782e5da19eb1a0 GIT binary patch literal 1150 zcmd6l-)mA~9LC?My9h=X(PfvxAZ%+nDycR`nof_KCx1+H&R?h0ETuWel5%OYcCm{_ zEgiGz%K1ClTp`TX59u}t0_h)!F8c$X-gAatv>PLWIDFoR^L(F&_vM_IkbU&&>LPSK zMz{ln93g}pr%;PJyFL{{=!X%dtajAquwm0KAUoBGBY1 zEsyt$(OfIf_hW^JKO|F3v)4AzR6L&e#>Aaq5*#D}6~wMf5WA)5_sDR@rx1K5;rvPG zO`e@MnR=`^3pQ?o>WLldXB0S|rI3=#E-hejcg*NTQhwc2AY%z%WW$Gtf(9y2p zg%9e88ET~ziwm=e-49}?mWAD-hs>>pA$1dDG&A+`FdqF3t{j4EGu(zzq1|A(=1P`_X{2`g-ied literal 0 HcmV?d00001 diff --git a/src/ICONS/other_peripherals.ico b/src/ICONS/other_peripherals.ico index b078387d39de419d0da0d3fb2c782e5da19eb1a0..11150631800ab77275347f61a02a5b7123b19ff2 100644 GIT binary patch literal 1150 zcmd5)T}V@57(PW;-B=OYRYg}q7Eyv=P$*41R1j7K1-mGMq@oBa%hEBIv;Uad(cG{5 z(Iwh+r?t(_=K9rCj)~@$mWrk34|8kgnmavxb9NbYSKr6;zP#`EJv`6%@lwk|?aH^i})X(kkq-vt?ZQDzr;ww4F09+S@A8_IT|3vL?B2OL zW$ywKk~6kR3JQ)sEGr8>P$-L5Rm{H#1gTm#* zea?s5&wNNbRm$I#%f%ea{;XmuqV~o{NQ^8@{2+M00Q=ZHWW95c_kKsKLk($n2!$_( zkjHjH{UL-y1zKJ%lZibJ2dY(SIILD&e`H6!_bd1r0gmw~uD=gM+VdUn{PSQxhf(8h zgQVmZD!q$*sZ{*Dxfy!32F*4bD!6udrhmfW8wF#w;BH?Ccf50Oj{QJMPY7yn0LrdW zXczTmg#VJ`VAN{C+3ire+F_d@{P74nzxeTTavm=x=FviG#y1OPYd;uw7izuJI4sff zvcf{~E4Le_Y8^PI6IF!o3jyw)0a)9*@n$rL>Su4DZ|T6>$p~sKRus!i@TBV__T;O0 z>D8;^*B%cHM4xT4qKx==O#`k;0ZyVB`vco(1WhAhScd0N|0x7>e*iTf0-!G|`NAt# z#4+DamW57lLaDhC#Z`Jdurx!iG2PLWIDFoR^L(F&_vM_IkbU&&>LPSK zMz{ln93g}pr%;PJyFL{{=!X%dtajAquwm0KAUoBGBY1 zEsyt$(OfIf_hW^JKO|F3v)4AzR6L&e#>Aaq5*#D}6~wMf5WA)5_sDR@rx1K5;rvPG zO`e@MnR=`^3pQ?o>WLldXB0S|rI3=#E-hejcg*NTQhwc2AY%z%WW$Gtf(9y2p zg%9e88ET~ziwm=e-49}?mWAD-hs>>pA$1dDG&A+`FdqF3t{j4EGu(zzq1|A(=1P`_X{2`g-ied diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index 1959a8328..f1f59a0bc 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -743,67 +743,17 @@ static uint32_t image_size(uint8_t id) static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { - if (!cdimg[id]) return 0; int len=4; int c,d; uint32_t temp; - uint8_t *q; + int first_track; int last_track; int number; unsigned char attr; TMSF tmsf; - int lb; - if (cdrom_image[id].image_is_iso) - { - if (starttrack > 1 && starttrack != 0xaa) - return -1; - q = b + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - if (starttrack <= 1) { - *q++ = 0; /* reserved */ - *q++ = 0x14; /* ADR, control */ - *q++ = 1; /* track number */ - *q++ = 0; /* reserved */ - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } else { - /* sector 0 */ - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - } - /* lead out track */ - *q++ = 0; /* reserved */ - *q++ = 0x16; /* ADR, control */ - *q++ = 0xaa; /* track number */ - *q++ = 0; /* reserved */ - lb = image_size(id) - 1; - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, lb); - q += 3; - } else { - *q++ = lb >> 24; - *q++ = lb >> 16; - *q++ = lb >> 8; - *q++ = lb; - } - len = q - b; - if (len > maxlen) - { - len = maxlen; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); - return len; - } + if (!cdimg[id]) return 0; cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); @@ -865,34 +815,13 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) { - if (!cdimg[id]) return 0; int len = 4; + int number; TMSF tmsf; unsigned char attr; - uint8_t *q; - if (cdrom_image[id].image_is_iso) - { - q = b + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - - if (maxlen < 12) - { - return maxlen; - } - return 12; - } + if (!cdimg[id]) return 0; cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); @@ -928,8 +857,6 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) { - if (!cdimg[id]) return 0; - int track; int len = 4; @@ -938,93 +865,9 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) int number; unsigned char attr; TMSF tmsf; - uint8_t *q; int lb; - if (cdrom_image[id].image_is_iso) - { - q = b + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* first track */ - *q++ = 0x00; /* disk type */ - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa1; - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* last track */ - *q++ = 0x00; - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa2; /* lead-out */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - lb = image_size(id) >> 11; - /* this is raw, must be msf */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, lb); - q += 3; - } - else - { - *q++ = (lb >> 24) & 0xff; - *q++ = (lb >> 16) & 0xff; - *q++ = (lb >> 8) & 0xff; - *q++ = lb & 0xff; - } - - *q++ = 1; /* session number */ - *q++ = 0x14; /* ADR, control */ - *q++ = 0; /* track number */ - *q++ = 1; /* point */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - /* same here */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } - else - { - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - - len = q - b; - if (len > maxlen) - { - len = maxlen; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); - return len; - } + if (!cdimg[id]) return 0; cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); @@ -1048,21 +891,10 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) b[len++]=0; b[len++]=0; b[len++]=0; - if (msf) - { - b[len++]=0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - else - { - uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; } return len; } diff --git a/src/win.c b/src/win.c index 4d7bc0631..2ac9fdd84 100644 --- a/src/win.c +++ b/src/win.c @@ -920,8 +920,14 @@ void update_status_bar_panes(HWND hwnds) c_ide_dma = count_hard_disks(3); c_scsi = count_hard_disks(4); + for (i = 0; i < sb_parts; i++) + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + sb_parts = 0; - memset(sb_part_meanings, 0, 40); + memset(iStatusWidths, 0, 48); + memset(sb_part_meanings, 0, 48); for (i = 0; i < 4; i++) { if (fdd_get_type(i) != 0) From 6117b6bb1d4a09f441ac65ddf9e601286266d644 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 May 2017 18:17:34 +0200 Subject: [PATCH 211/392] Added missing braces in win.c's update_status_bar_panes(), should hopefully fix the hard disk icons bug when using XTIDE. --- src/win.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win.c b/src/win.c index 2ac9fdd84..0f42ad819 100644 --- a/src/win.c +++ b/src/win.c @@ -956,14 +956,14 @@ void update_status_bar_panes(HWND hwnds) sb_part_meanings[sb_parts] = 0x20; sb_parts++; } - if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) + if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; sb_part_meanings[sb_parts] = 0x21; sb_parts++; } - if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5)) + if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; From 266a9690aea89b3d6aac4c28bb98188a88420062 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 May 2017 18:37:32 +0200 Subject: [PATCH 212/392] Properly reimplemented the IDE SET_FEATURES command, NT 5.00.1743 and Neptune 5.11.5111 now work. --- src/ide.c | 155 +++++++++++++++++++++++------------------------------- src/ide.h | 55 +++++++++---------- 2 files changed, 95 insertions(+), 115 deletions(-) diff --git a/src/ide.c b/src/ide.c index f6c2c3454..d3beb71ce 100644 --- a/src/ide.c +++ b/src/ide.c @@ -421,7 +421,12 @@ static void ide_identify(IDE *ide) if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) { ide->buffer[52] = 2 << 8; /*DMA timing mode*/ + ide->buffer[63] = 7; + if (ide->mdma_mode != -1) + { + ide->buffer[63] = (ide->mdma_mode << 8); + } } ide->buffer[80] = 0xe; /*ATA-1 to ATA-3 supported*/ } @@ -661,78 +666,54 @@ int ide_cdrom_is_pio_only(IDE *ide) return 1; } -#if 0 -int ide_set_features(IDE *ide) +static int ide_set_features(IDE *ide) { - uint8_t cdrom_id = cur_ide[ide->board]; + uint8_t features, features_data; + uint8_t mode, submode; + + features = ide->cylprecomp; + features_data = ide->secount; - uint8_t features = 0; - - uint8_t sf_data = 0; - uint8_t val = 0; - - if (ide_drive_is_cdrom(ide)) - { - features = cdrom[cdrom_id].features; - sf_data = cdrom[cdrom_id].phase; - } - else - { - features = ide->cylprecomp; - sf_data = ide->secount; - } - - val = sf_data & 7; + pclog("Features code %02X\n", features); - if (ide->type == IDE_NONE) return 0; - switch(features) { - case 0x02: - case 0x82: - return 0; - case 0xcc: - case 0x66: - case 0xaa: - case 0x55: - case 0x05: - case 0x85: - case 0x69: - case 0x67: - case 0x96: - case 0x9a: - case 0x42: - case 0xc2: - return 1; - case 0x03: -#if 0 - if (ide->type == IDE_CDROM) + case 0x03: /* Set transfer mode. */ + pclog("Transfer mode %02X\n", features_data >> 3); + + mode = (features_data >> 3); + submode = features_data & 7; + + switch(mode) { - return 0; - } -#endif - switch(sf_data >> 3) - { - case 0: - ide->dma_identify_data[0] = 7; + case 0x00: /* PIO default */ + if (submode != 0) goto abort; + ide->mdma_mode = -1; break; - case 1: - /* We do not (yet) emulate flow control, so return with error if this is attempted. */ - return 0; - case 4: - if (ide_cdrom_is_pio_only(ide) || (ide->board >= 2)) + + case 0x01: /* PIO mode */ + if (submode > 2) goto abort; + ide->mdma_mode = -1; + break; + + case 0x04: /* Multiword DMA mode */ + if (!PCI || (hdc[ide->hdc_num].bus != 3) || (ide->board >= 2) || (submode > 2)) { - return 0; + goto abort; } - ide->dma_identify_data[0] = 7 | (1 << (val + 8)); + ide->mdma_mode = (1 << submode); break; + default: return 0; } + + default: + return 0; } + return 1; } -#endif void ide_set_sector(IDE *ide, int64_t sector_num) { @@ -805,12 +786,10 @@ void resetide(void) ide_set_signature(&ide_drives[d]); -#if 0 - if (ide_drives[d].type != IDE_NONE) + if (ide_drives[d].type == IDE_HDD) { - ide_drives[d].dma_identify_data[0] = 7; + ide_drives[d].mdma_mode = 0; } -#endif ide_drives[d].error = 1; } @@ -1663,7 +1642,7 @@ void callbackide(int ide_board) { /* Initialize the Task File Registers as follows: Status = 00h, Error = 01h, Sector Count = 01h, Sector Number = 01h, Cylinder Low = 14h, Cylinder High =EBh and Drive/Head = 00h. */ - case WIN_SRST: /*ATAPI Device Reset */ + case WIN_SRST: /*ATAPI Device Reset */ ide->atastat = READY_STAT | DSC_STAT; ide->error=1; /*Device passed*/ ide->secount = ide->sector = 1; @@ -1683,8 +1662,8 @@ void callbackide(int ide_board) } return; - case WIN_RESTORE: - case WIN_SEEK: + case WIN_RESTORE: + case WIN_SEEK: if (ide_drive_is_cdrom(ide)) { goto abort_cmd; @@ -1716,8 +1695,8 @@ void callbackide(int ide_board) ide_irq_raise(ide); return; - case WIN_READ: - case WIN_READ_NORETRY: + case WIN_READ: + case WIN_READ_NORETRY: if (ide_drive_is_cdrom(ide)) { ide_set_signature(ide); @@ -1739,7 +1718,7 @@ void callbackide(int ide_board) update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; - case WIN_READ_DMA: + case WIN_READ_DMA: if (ide_drive_is_cdrom(ide) || (ide->board >= 2)) { goto abort_cmd; @@ -1782,7 +1761,7 @@ void callbackide(int ide_board) return; - case WIN_READ_MULTIPLE: + case WIN_READ_MULTIPLE: /* According to the official ATA reference: If the Read Multiple command is attempted before the Set Multiple Mode @@ -1816,8 +1795,8 @@ void callbackide(int ide_board) update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; - case WIN_WRITE: - case WIN_WRITE_NORETRY: + case WIN_WRITE: + case WIN_WRITE_NORETRY: if (ide_drive_is_cdrom(ide)) { goto abort_cmd; @@ -1846,7 +1825,7 @@ void callbackide(int ide_board) return; - case WIN_WRITE_DMA: + case WIN_WRITE_DMA: if (ide_drive_is_cdrom(ide) || (ide_board >= 2)) { goto abort_cmd; @@ -1889,7 +1868,7 @@ void callbackide(int ide_board) return; - case WIN_WRITE_MULTIPLE: + case WIN_WRITE_MULTIPLE: if (ide_drive_is_cdrom(ide)) { goto abort_cmd; @@ -1938,7 +1917,7 @@ void callbackide(int ide_board) update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); return; - case WIN_FORMAT: + case WIN_FORMAT: if (ide_drive_is_cdrom(ide)) { goto abort_cmd; @@ -1960,7 +1939,7 @@ void callbackide(int ide_board) /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); */ return; - case WIN_DRIVE_DIAGNOSTICS: + case WIN_DRIVE_DIAGNOSTICS: ide_set_signature(ide); ide->error=1; /*No error detected*/ @@ -1978,7 +1957,7 @@ void callbackide(int ide_board) } return; - case WIN_SPECIFY: /* Initialize Drive Parameters */ + case WIN_SPECIFY: /* Initialize Drive Parameters */ if (ide_drive_is_cdrom(ide)) { goto abort_cmd; @@ -2000,7 +1979,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); return; - case WIN_PIDENTIFY: /* Identify Packet Device */ + case WIN_PIDENTIFY: /* Identify Packet Device */ if (ide_drive_is_cdrom(ide)) { ide_atapi_identify(ide); @@ -2013,8 +1992,8 @@ void callbackide(int ide_board) } goto abort_cmd; - case WIN_SET_MULTIPLE_MODE: - if (ide_drive_is_cdrom(ide)) + case WIN_SET_MULTIPLE_MODE: + if (ide_drive_is_cdrom(ide)) { goto abort_cmd; } @@ -2023,24 +2002,23 @@ void callbackide(int ide_board) ide_irq_raise(ide); return; -#if 0 case WIN_SET_FEATURES: - if (!(ide_set_features(ide))) + if ((ide->type == IDE_NONE) || ide_drive_is_cdrom(ide)) { goto abort_cmd; } - if (ide_drive_is_cdrom(ide)) + + if (!ide_set_features(ide)) { - cdrom[cdrom_id].status = READY_STAT | DSC_STAT; + goto abort_cmd; } else { ide->atastat = READY_STAT | DSC_STAT; + ide_irq_raise(ide); } - ide_irq_raise(ide); return; -#endif - + case WIN_READ_NATIVE_MAX: if ((ide->type != IDE_HDD) || ide_drive_is_cdrom(ide)) { @@ -2053,8 +2031,8 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); return; - - case WIN_IDENTIFY: /* Identify Device */ + + case WIN_IDENTIFY: /* Identify Device */ if (ide->type == IDE_NONE) { ide_set_signature(ide); @@ -2076,7 +2054,7 @@ void callbackide(int ide_board) } return; - case WIN_PACKETCMD: /* ATAPI Packet */ + case WIN_PACKETCMD: /* ATAPI Packet */ if (!ide_drive_is_cdrom(ide)) { goto abort_cmd; @@ -2089,7 +2067,7 @@ void callbackide(int ide_board) case 0xFF: goto abort_cmd; - } + } abort_cmd: ide->command = 0; @@ -2107,6 +2085,7 @@ abort_cmd: } ide_irq_raise(ide); return; + id_not_found: ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; ide->error = ABRT_ERR | 0x10; diff --git a/src/ide.h b/src/ide.h index dedb41793..db8d52330 100644 --- a/src/ide.h +++ b/src/ide.h @@ -11,33 +11,34 @@ typedef struct IDE typedef struct __attribute__((__packed__)) IDE #endif { - int type; - int board; - uint8_t atastat; - uint8_t error; - int secount,sector,cylinder,head,drive,cylprecomp; - uint8_t command; - uint8_t fdisk; - int pos; - int packlen; - int spt,hpc; - int tracks; - int packetstatus; - uint8_t asc; - int reset; - FILE *hdfile; - uint16_t buffer[65536]; - int irqstat; - int service; - int lba; - int channel; - uint32_t lba_addr; - int skip512; - int blocksize, blockcount; - uint16_t dma_identify_data[3]; - int hdi,base; - int hdc_num; - uint8_t specify_success; + int type; + int board; + uint8_t atastat; + uint8_t error; + int secount,sector,cylinder,head,drive,cylprecomp; + uint8_t command; + uint8_t fdisk; + int pos; + int packlen; + int spt,hpc; + int tracks; + int packetstatus; + uint8_t asc; + int reset; + FILE *hdfile; + uint16_t buffer[65536]; + int irqstat; + int service; + int lba; + int channel; + uint32_t lba_addr; + int skip512; + int blocksize, blockcount; + uint16_t dma_identify_data[3]; + int hdi,base; + int hdc_num; + uint8_t specify_success; + int mdma_mode; } IDE; #ifdef __MSC__ # pragma pack(pop) From 8d6ea357d4fd2cc7e23b6608347b51146eb50c77 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 May 2017 18:39:58 +0200 Subject: [PATCH 213/392] Fixed the stray goto abort's in ide_set_features(), it should now compile. --- src/ide.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ide.c b/src/ide.c index d3beb71ce..6268b38ae 100644 --- a/src/ide.c +++ b/src/ide.c @@ -687,12 +687,18 @@ static int ide_set_features(IDE *ide) switch(mode) { case 0x00: /* PIO default */ - if (submode != 0) goto abort; + if (submode != 0) + { + return 0; + } ide->mdma_mode = -1; break; case 0x01: /* PIO mode */ - if (submode > 2) goto abort; + if (submode > 2) + { + return 0; + } ide->mdma_mode = -1; break; From 84ac082bc4e1d267abaa1d41d0619884366aa797 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 14 May 2017 18:41:58 +0200 Subject: [PATCH 214/392] Fixed the last stray goto abort. --- src/ide.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ide.c b/src/ide.c index 6268b38ae..f90ead29d 100644 --- a/src/ide.c +++ b/src/ide.c @@ -705,7 +705,7 @@ static int ide_set_features(IDE *ide) case 0x04: /* Multiword DMA mode */ if (!PCI || (hdc[ide->hdc_num].bus != 3) || (ide->board >= 2) || (submode > 2)) { - goto abort; + return 0; } ide->mdma_mode = (1 << submode); break; From 0fa41b7b9b7a7015bd7d1b2baa46b94c52319cd6 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 14 May 2017 22:40:53 +0200 Subject: [PATCH 215/392] Included MCA header and fixed aha1640 write function. --- src/scsi_aha154x.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 8a82b7e36..fc31f6af6 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -25,6 +25,7 @@ #include #include "ibm.h" #include "io.h" +#include "mca.h" #include "mem.h" #include "rom.h" #include "dma.h" @@ -2194,13 +2195,15 @@ void aha_mca_write(int port, uint8_t val, void *p) if (port < 0x102) return; - addr = aha_mca_addr[dev->pos_regs[4] & 7]; - if ((dev->pos_regs[2] & 1) && !(val & 1)) - io_removehandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); - if (!(dev->pos_regs[2] & 1) && (val & 1)) - io_sethandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); - + addr = aha_mca_addr[dev->pos_regs[4] & 6]; + io_removehandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); + dev->pos_regs[port & 7] = val; + + if (dev->pos_regs[2] & 1) + { + io_sethandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); + } } From 6a3f3727a72726d2c95338ded53900b6a4d71c56 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 May 2017 00:35:26 +0200 Subject: [PATCH 216/392] Fixed ISO loading; Fixed ESDI and XT MFM hard disk initialization; The IDE SET_FEATURES command is now actually recognized by the command register write handler. --- src/cdrom-dosbox.cpp | 9 +- src/cdrom-image.cc | 38 ++- src/cdrom-image.h | 2 + src/hdd_esdi.c | 18 +- src/ide.c | 657 +++++++++++++++++++++---------------------- src/mfm_xebec.c | 22 +- src/scsi_aha154x.c | 1 + src/win.c | 1 + 8 files changed, 389 insertions(+), 359 deletions(-) diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp index 86f09e8c8..6f966cf1b 100644 --- a/src/cdrom-dosbox.cpp +++ b/src/cdrom-dosbox.cpp @@ -205,6 +205,9 @@ bool CDROM_Interface_Image::IsMode2(unsigned long sector) bool CDROM_Interface_Image::LoadIsoFile(char* filename) { + int shift = 0; + int totalPregap = 0; + tracks.clear(); // data track @@ -216,6 +219,7 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) return false; } track.number = 1; + track.track_number = 1;//IMPORTANT: This is needed. track.attr = DATA_TRACK;//data // try to detect iso type @@ -239,7 +243,7 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) // leadout track track.number = 2; track.track_number = 0xAA; - track.attr = 0; + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ track.start = track.length; track.length = 0; track.file = NULL; @@ -389,7 +393,8 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) // add leadout track track.number++; track.track_number = 0xAA; - track.attr = 0;//sync with load iso + // track.attr = 0;//sync with load iso + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ track.start = 0; track.length = 0; track.file = NULL; diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc index f1f59a0bc..5ec185d65 100644 --- a/src/cdrom-image.cc +++ b/src/cdrom-image.cc @@ -228,7 +228,7 @@ static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int max { uint32_t address; cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150 here as well. */ if (address > lb) lb = address; } @@ -733,7 +733,7 @@ static void lba_to_msf(uint8_t *buf, int lba) lba += 150; buf[0] = (lba / 75) / 60; buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; + buf[2] = lba % 75; } static uint32_t image_size(uint8_t id) @@ -743,6 +743,7 @@ static uint32_t image_size(uint8_t id) static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { + if (!cdimg[id]) return 0; int len=4; int c,d; uint32_t temp; @@ -752,9 +753,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int number; unsigned char attr; TMSF tmsf; - - if (!cdimg[id]) return 0; - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); b[2] = first_track; @@ -779,6 +777,7 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, break; cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); +// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); b[len++] = 0; /* reserved */ b[len++] = attr; b[len++] = number; /* track number */ @@ -793,7 +792,7 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, } else { - temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; b[len++] = temp >> 24; b[len++] = temp >> 16; b[len++] = temp >> 8; @@ -802,14 +801,22 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, if (single) break; } - - if (len > maxlen) - { - len = maxlen; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); b[1] = (uint8_t)((len-2) & 0xff); + /* + pclog("Table of Contents:\n"); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); + } + for (c = 0;c <= last_track; c++) { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); + } + */ return len; } @@ -825,6 +832,11 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + if (number == 0) + { + number = 1; + } + b[2] = 1; b[3] = 1; b[len++] = 0; /* reserved */ @@ -840,7 +852,7 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl } else { - uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150. */ b[len++] = temp >> 24; b[len++] = temp >> 16; b[len++] = temp >> 8; diff --git a/src/cdrom-image.h b/src/cdrom-image.h index 415956e56..4ea4cb78f 100644 --- a/src/cdrom-image.h +++ b/src/cdrom-image.h @@ -19,6 +19,8 @@ extern void image_close(uint8_t id); void update_status_bar_icon_state(int tag, int state); extern void cdrom_set_null_handler(uint8_t id); +void pclog(const char *format, ...); + #ifdef __cplusplus } #endif diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 707e0d1b6..f40345933 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -796,7 +796,7 @@ static void esdi_mca_write(int port, uint8_t val, void *p) } } -static void loadhd(esdi_t *esdi, int d, const wchar_t *fn) +static void loadhd(esdi_t *esdi, int hdc_num, int d, const wchar_t *fn) { esdi_drive_t *drive = &esdi->drives[d]; @@ -829,15 +829,16 @@ static void loadhd(esdi_t *esdi, int d, const wchar_t *fn) } } - drive->spt = hdc[d].spt; - drive->hpc = hdc[d].hpc; - drive->tracks = hdc[d].tracks; - drive->sectors = hdc[d].spt * hdc[d].hpc * hdc[d].tracks; + drive->spt = hdc[hdc_num].spt; + drive->hpc = hdc[hdc_num].hpc; + drive->tracks = hdc[hdc_num].tracks; + drive->sectors = hdc[hdc_num].spt * hdc[hdc_num].hpc * hdc[hdc_num].tracks; } static void *esdi_init() { int i = 0; + int c = 0; esdi_t *esdi = malloc(sizeof(esdi_t)); memset(esdi, 0, sizeof(esdi_t)); @@ -847,7 +848,12 @@ static void *esdi_init() for (i = 0; i < HDC_NUM; i++) { - loadhd(esdi, hdc[i].mfm_channel, hdd_fn[i]); + if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + { + loadhd(esdi, i, hdc[i].mfm_channel, hdd_fn[i]); + c++; + if (c >= MFM_NUM) break; + } } timer_add(esdi_callback, &esdi->callback, &esdi->callback, esdi); diff --git a/src/ide.c b/src/ide.c index f90ead29d..637bb1cf2 100644 --- a/src/ide.c +++ b/src/ide.c @@ -905,7 +905,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) switch (addr) { - case 0x1F0: /* Data */ + case 0x1F0: /* Data */ writeidew(ide_board, val | (val << 8)); return; @@ -924,7 +924,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide_other->cylprecomp = val; return; - case 0x1F2: /* Sector count */ + case 0x1F2: /* Sector count */ if (ide_drive_is_cdrom(ide)) { ide_log("Sector count write: %i\n", val); @@ -940,14 +940,14 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide_other->secount = val; return; - case 0x1F3: /* Sector */ + case 0x1F3: /* Sector */ ide->sector = val; ide->lba_addr = (ide->lba_addr & 0xFFFFF00) | val; ide_other->sector = val; ide_other->lba_addr = (ide_other->lba_addr & 0xFFFFF00) | val; return; - case 0x1F4: /* Cylinder low */ + case 0x1F4: /* Cylinder low */ if (ide_drive_is_cdrom(ide)) { cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF00; @@ -965,7 +965,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide_other->lba_addr = (ide_other->lba_addr&0xFFF00FF) | (val << 8); return; - case 0x1F5: /* Cylinder high */ + case 0x1F5: /* Cylinder high */ if (ide_drive_is_cdrom(ide)) { cdrom[atapi_cdrom_drives[cur_ide[ide_board]]].request_length &= 0xFF; @@ -983,7 +983,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide_other->lba_addr = (ide_other->lba_addr & 0xF00FFFF) | (val << 16); return; - case 0x1F6: /* Drive/Head */ + case 0x1F6: /* Drive/Head */ if (cur_ide[ide_board] != ((val>>4)&1)+(ide_board<<1)) { cur_ide[ide_board]=((val>>4)&1)+(ide_board<<1); @@ -1036,254 +1036,255 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) ide_irq_update(ide); return; - case 0x1F7: /* Command register */ + case 0x1F7: /* Command register */ if (ide->type == IDE_NONE) { return; } - ide_irq_lower(ide); - ide->command=val; + ide_irq_lower(ide); + ide->command=val; - ide->error=0; - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].error = 0; - } - switch (val) - { - case WIN_SRST: /* ATAPI Device Reset */ - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = READY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 100*IDE_TIME; - } - idecallback[ide_board]=100*IDE_TIME; - timer_update_outstanding(); - return; + ide->error=0; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].error = 0; + } + switch (val) + { + case WIN_SRST: /* ATAPI Device Reset */ + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = READY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 100*IDE_TIME; + } + idecallback[ide_board]=100*IDE_TIME; + timer_update_outstanding(); + return; - case WIN_RESTORE: - case WIN_SEEK: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT; - } - else - { - ide->atastat = READY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 100*IDE_TIME; - } - idecallback[ide_board]=100*IDE_TIME; - timer_update_outstanding(); - return; + case WIN_RESTORE: + case WIN_SEEK: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT; + } + else + { + ide->atastat = READY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 100*IDE_TIME; + } + idecallback[ide_board]=100*IDE_TIME; + timer_update_outstanding(); + return; - case WIN_READ_MULTIPLE: - /* Fatal removed in accordance with the official ATAPI reference: - If the Read Multiple command is attempted before the Set Multiple Mode - command has been executed or when Read Multiple commands are - disabled, the Read Multiple operation is rejected with an Aborted Com- - mand error. */ - ide->blockcount = 0; - - case WIN_READ: - case WIN_READ_NORETRY: - case WIN_READ_DMA: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = BUSY_STAT; - } + case WIN_READ_MULTIPLE: + /* Fatal removed in accordance with the official ATAPI reference: + If the Read Multiple command is attempted before the Set Multiple Mode + command has been executed or when Read Multiple commands are + disabled, the Read Multiple operation is rejected with an Aborted Com- + mand error. */ + ide->blockcount = 0; + + case WIN_READ: + case WIN_READ_NORETRY: + case WIN_READ_DMA: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); + return; + + case WIN_WRITE_MULTIPLE: + if (!ide->blocksize && !ide_drive_is_cdrom(ide)) + { + fatal("Write_MULTIPLE - blocksize = 0\n"); + } + ide->blockcount = 0; + + case WIN_WRITE: + case WIN_WRITE_NORETRY: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT | DSC_STAT | READY_STAT; + cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; + } + else + { + ide->atastat = DRQ_STAT | DSC_STAT | READY_STAT; + ide->pos=0; + } + return; + + case WIN_WRITE_DMA: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); + return; + + case WIN_VERIFY: + case WIN_VERIFY_ONCE: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); + return; + + case WIN_FORMAT: + if (ide_drive_is_cdrom(ide)) + { + goto ide_bad_command; + } + else + { + ide->atastat = DRQ_STAT; + ide->pos=0; + } + return; + + case WIN_SPECIFY: /* Initialize Drive Parameters */ + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; + } + idecallback[ide_board]=30*IDE_TIME; + timer_update_outstanding(); + return; + + case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ + case WIN_PIDENTIFY: /* Identify Packet Device */ + case WIN_SET_MULTIPLE_MODE: /* Set Multiple Mode */ + case WIN_SET_FEATURES: /* Set Features */ + case WIN_NOP: + case WIN_STANDBYNOW1: + case WIN_IDLENOW1: + case WIN_SETIDLE1: /* Idle */ + case WIN_CHECKPOWERMODE1: + case WIN_SLEEP1: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; + } + idecallback[ide_board]=30*IDE_TIME; + timer_update_outstanding(); + return; + + case WIN_IDENTIFY: /* Identify Device */ + case WIN_READ_NATIVE_MAX: + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; + } + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); + return; + + case WIN_PACKETCMD: /* ATAPI Packet */ + /* Skip the command callback wait, and process immediately. */ + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].packet_status = CDROM_PHASE_IDLE; + cdrom[atapi_cdrom_drives[ide->channel]].pos=0; + cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]].status & ERR_STAT); + } + else + { + ide->atastat = BUSY_STAT; timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; - } - idecallback[ide_board]=200*IDE_TIME; + idecallback[ide_board]=1; timer_update_outstanding(); - return; - - case WIN_WRITE_MULTIPLE: - if (!ide->blocksize && !ide_drive_is_cdrom(ide)) - { - fatal("Write_MULTIPLE - blocksize = 0\n"); - } - ide->blockcount = 0; - - case WIN_WRITE: - case WIN_WRITE_NORETRY: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = DRQ_STAT | DSC_STAT | READY_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].pos = 0; - } - else - { - ide->atastat = DRQ_STAT | DSC_STAT | READY_STAT; - ide->pos=0; - } - return; + ide->pos=0; + } + return; - case WIN_WRITE_DMA: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = BUSY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; - } - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); - return; - - case WIN_VERIFY: - case WIN_VERIFY_ONCE: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = BUSY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; - } - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); - return; - - case WIN_FORMAT: - if (ide_drive_is_cdrom(ide)) - { - goto ide_bad_command; - } - else - { - ide->atastat = DRQ_STAT; - ide->pos=0; - } - return; - - case WIN_SPECIFY: /* Initialize Drive Parameters */ - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = BUSY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; - } - idecallback[ide_board]=30*IDE_TIME; - timer_update_outstanding(); - return; - - case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - case WIN_PIDENTIFY: /* Identify Packet Device */ - case WIN_SET_MULTIPLE_MODE: /*Set Multiple Mode*/ - case WIN_NOP: - case WIN_STANDBYNOW1: - case WIN_IDLENOW1: - case WIN_SETIDLE1: /* Idle */ - case WIN_CHECKPOWERMODE1: - case WIN_SLEEP1: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = BUSY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; - } - idecallback[ide_board]=30*IDE_TIME; - timer_update_outstanding(); - return; - - case WIN_IDENTIFY: /* Identify Device */ - case WIN_READ_NATIVE_MAX: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; - } - else - { - ide->atastat = BUSY_STAT; - } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 200*IDE_TIME; - } - idecallback[ide_board]=200*IDE_TIME; - timer_update_outstanding(); - return; - - case WIN_PACKETCMD: /* ATAPI Packet */ - /* Skip the command callback wait, and process immediately. */ - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].packet_status = CDROM_PHASE_IDLE; - cdrom[atapi_cdrom_drives[ide->channel]].pos=0; - cdrom[atapi_cdrom_drives[ide->channel]].phase = 1; - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | DRQ_STAT | (cdrom[cur_ide[ide_board]].status & ERR_STAT); - } - else - { - ide->atastat = BUSY_STAT; - timer_process(); - idecallback[ide_board]=1; - timer_update_outstanding(); - ide->pos=0; - } - return; - - case 0xF0: - default: + case 0xF0: + default: ide_bad_command: - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | ERR_STAT | DSC_STAT; - cdrom[atapi_cdrom_drives[ide->channel]].error = ABRT_ERR; - } - else - { - ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; - ide->error = ABRT_ERR; - } - ide_irq_raise(ide); - return; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = READY_STAT | ERR_STAT | DSC_STAT; + cdrom[atapi_cdrom_drives[ide->channel]].error = ABRT_ERR; + } + else + { + ide->atastat = READY_STAT | ERR_STAT | DSC_STAT; + ide->error = ABRT_ERR; + } + ide_irq_raise(ide); + return; } return; @@ -1424,7 +1425,7 @@ uint8_t readide(int ide_board, uint16_t addr) /* For ATAPI: Bits 7-4 = sense key, bit 3 = MCR (media change requested), Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), - and Bit 0 = ILI (illegal length indication). */ + and Bit 0 = ILI (illegal length indication). */ case 0x1F1: /* Error */ if (ide->type == IDE_NONE) { @@ -2125,161 +2126,159 @@ void ide_callback_qua() void ide_write_pri(uint16_t addr, uint8_t val, void *priv) { - writeide(0, addr, val); + writeide(0, addr, val); } void ide_write_pri_w(uint16_t addr, uint16_t val, void *priv) { - writeidew(0, val); + writeidew(0, val); } void ide_write_pri_l(uint16_t addr, uint32_t val, void *priv) { - writeidel(0, val); + writeidel(0, val); } uint8_t ide_read_pri(uint16_t addr, void *priv) { - return readide(0, addr); + return readide(0, addr); } uint16_t ide_read_pri_w(uint16_t addr, void *priv) { - return readidew(0); + return readidew(0); } uint32_t ide_read_pri_l(uint16_t addr, void *priv) { - return readidel(0); + return readidel(0); } void ide_write_sec(uint16_t addr, uint8_t val, void *priv) { - writeide(1, addr, val); + writeide(1, addr, val); } void ide_write_sec_w(uint16_t addr, uint16_t val, void *priv) { - writeidew(1, val); + writeidew(1, val); } void ide_write_sec_l(uint16_t addr, uint32_t val, void *priv) { - writeidel(1, val); + writeidel(1, val); } uint8_t ide_read_sec(uint16_t addr, void *priv) { - return readide(1, addr); + return readide(1, addr); } uint16_t ide_read_sec_w(uint16_t addr, void *priv) { - return readidew(1); + return readidew(1); } uint32_t ide_read_sec_l(uint16_t addr, void *priv) { - return readidel(1); + return readidel(1); } -/* *** REMOVE FROM CODE SUBMITTED TO MAINLINE - START *** */ void ide_write_ter(uint16_t addr, uint8_t val, void *priv) { - writeide(2, addr, val); + writeide(2, addr, val); } void ide_write_ter_w(uint16_t addr, uint16_t val, void *priv) { - writeidew(2, val); + writeidew(2, val); } void ide_write_ter_l(uint16_t addr, uint32_t val, void *priv) { - writeidel(2, val); + writeidel(2, val); } uint8_t ide_read_ter(uint16_t addr, void *priv) { - return readide(2, addr); + return readide(2, addr); } uint16_t ide_read_ter_w(uint16_t addr, void *priv) { - return readidew(2); + return readidew(2); } uint32_t ide_read_ter_l(uint16_t addr, void *priv) { - return readidel(2); + return readidel(2); } void ide_write_qua(uint16_t addr, uint8_t val, void *priv) { - writeide(3, addr, val); + writeide(3, addr, val); } void ide_write_qua_w(uint16_t addr, uint16_t val, void *priv) { - writeidew(3, val); + writeidew(3, val); } void ide_write_qua_l(uint16_t addr, uint32_t val, void *priv) { - writeidel(3, val); + writeidel(3, val); } uint8_t ide_read_qua(uint16_t addr, void *priv) { - return readide(3, addr); + return readide(3, addr); } uint16_t ide_read_qua_w(uint16_t addr, void *priv) { - return readidew(3); + return readidew(3); } uint32_t ide_read_qua_l(uint16_t addr, void *priv) { - return readidel(3); + return readidel(3); } -/* *** REMOVE FROM CODE SUBMITTED TO MAINLINE - END *** */ static uint16_t ide_base_main[2] = { 0x1f0, 0x170 }; static uint16_t ide_side_main[2] = { 0x3f6, 0x376 }; void ide_pri_enable() { - io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); - io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); - ide_base_main[0] = 0x1f0; - ide_side_main[0] = 0x3f6; + io_sethandler(0x01f0, 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); + io_sethandler(0x03f6, 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); + ide_base_main[0] = 0x1f0; + ide_side_main[0] = 0x3f6; } void ide_pri_enable_ex() { - if (ide_base_main[0] & 0x300) - { - pclog("Enabling primary base (%04X)...\n", ide_base_main[0]); - io_sethandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); - } - if (ide_side_main[0] & 0x300) - { - pclog("Enabling primary side (%04X)...\n", ide_side_main[0]); - io_sethandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); - } + if (ide_base_main[0] & 0x300) + { + pclog("Enabling primary base (%04X)...\n", ide_base_main[0]); + io_sethandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); + } + if (ide_side_main[0] & 0x300) + { + pclog("Enabling primary side (%04X)...\n", ide_side_main[0]); + io_sethandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); + } } void ide_pri_disable() { - io_removehandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); - io_removehandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); + io_removehandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); + io_removehandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); } void ide_sec_enable() { - io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); - io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); - ide_base_main[1] = 0x170; - ide_side_main[1] = 0x376; + io_sethandler(0x0170, 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); + io_sethandler(0x0376, 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); + ide_base_main[1] = 0x170; + ide_side_main[1] = 0x376; } void ide_sec_enable_ex() { - if (ide_base_main[1] & 0x300) - { - io_sethandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); - } - if (ide_side_main[1] & 0x300) - { - io_sethandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); - } + if (ide_base_main[1] & 0x300) + { + io_sethandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); + } + if (ide_side_main[1] & 0x300) + { + io_sethandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); + } } void ide_sec_disable() { - io_removehandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); - io_removehandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); + io_removehandler(ide_base_main[1], 0x0008, ide_read_sec, ide_read_sec_w, ide_read_sec_l, ide_write_sec, ide_write_sec_w, ide_write_sec_l, NULL); + io_removehandler(ide_side_main[1], 0x0001, ide_read_sec, NULL, NULL, ide_write_sec, NULL, NULL , NULL); } void ide_set_base(int controller, uint16_t port) @@ -2292,75 +2291,73 @@ void ide_set_side(int controller, uint16_t port) ide_side_main[controller] = port; } -/* *** REMOVE FROM CODE SUBMITTED TO MAINLINE - START *** */ void ide_ter_enable() { - io_sethandler(0x0168, 0x0008, ide_read_ter, ide_read_ter_w, ide_read_ter_l, ide_write_ter, ide_write_ter_w, ide_write_ter_l, NULL); - io_sethandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); + io_sethandler(0x0168, 0x0008, ide_read_ter, ide_read_ter_w, ide_read_ter_l, ide_write_ter, ide_write_ter_w, ide_write_ter_l, NULL); + io_sethandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); } void ide_ter_disable() { - io_removehandler(0x0168, 0x0008, ide_read_ter, ide_read_ter_w, ide_read_ter_l, ide_write_ter, ide_write_ter_w, ide_write_ter_l, NULL); - io_removehandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); + io_removehandler(0x0168, 0x0008, ide_read_ter, ide_read_ter_w, ide_read_ter_l, ide_write_ter, ide_write_ter_w, ide_write_ter_l, NULL); + io_removehandler(0x036e, 0x0001, ide_read_ter, NULL, NULL, ide_write_ter, NULL, NULL , NULL); } void ide_ter_disable_cond() { - if ((ide_drives[4].type == IDE_NONE) && (ide_drives[5].type == IDE_NONE)) - { - ide_ter_disable(); - } + if ((ide_drives[4].type == IDE_NONE) && (ide_drives[5].type == IDE_NONE)) + { + ide_ter_disable(); + } } void ide_ter_init() { - ide_ter_enable(); + ide_ter_enable(); - timer_add(ide_callback_ter, &idecallback[2], &idecallback[2], NULL); + timer_add(ide_callback_ter, &idecallback[2], &idecallback[2], NULL); } void ide_qua_enable() { - io_sethandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); - io_sethandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); + io_sethandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); + io_sethandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); } void ide_qua_disable_cond() { - if ((ide_drives[6].type == IDE_NONE) && (ide_drives[7].type == IDE_NONE)) - { - ide_qua_disable(); - } + if ((ide_drives[6].type == IDE_NONE) && (ide_drives[7].type == IDE_NONE)) + { + ide_qua_disable(); + } } void ide_qua_disable() { - io_removehandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); - io_removehandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); + io_removehandler(0x01e8, 0x0008, ide_read_qua, ide_read_qua_w, ide_read_qua_l, ide_write_qua, ide_write_qua_w, ide_write_qua_l, NULL); + io_removehandler(0x03ee, 0x0001, ide_read_qua, NULL, NULL, ide_write_qua, NULL, NULL , NULL); } void ide_qua_init() { - ide_qua_enable(); + ide_qua_enable(); - timer_add(ide_callback_qua, &idecallback[3], &idecallback[3], NULL); + timer_add(ide_callback_qua, &idecallback[3], &idecallback[3], NULL); } -/* *** REMOVE FROM CODE SUBMITTED TO MAINLINE - END *** */ void ide_init() { - ide_pri_enable(); - ide_sec_enable(); - ide_bus_master_read = ide_bus_master_write = NULL; - - timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); - timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); + ide_pri_enable(); + ide_sec_enable(); + ide_bus_master_read = ide_bus_master_write = NULL; + + timer_add(ide_callback_pri, &idecallback[0], &idecallback[0], NULL); + timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); } void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)) { - ide_bus_master_read = read; - ide_bus_master_write = write; - ide_bus_master_set_irq = set_irq; + ide_bus_master_read = read; + ide_bus_master_write = write; + ide_bus_master_set_irq = set_irq; } diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index fde48c45d..fdbe7e7b3 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -763,7 +763,7 @@ static void xebec_callback(void *p) } } -static void loadhd(xebec_t *xebec, int d, const wchar_t *fn) +static void loadhd(xebec_t *xebec, int c, int d, const wchar_t *fn) { mfm_drive_t *drive = &xebec->drives[d]; @@ -796,9 +796,9 @@ static void loadhd(xebec_t *xebec, int d, const wchar_t *fn) } } - drive->spt = hdc[d].spt; - drive->hpc = hdc[d].hpc; - drive->tracks = hdc[d].tracks; + drive->spt = hdc[c].spt; + drive->hpc = hdc[c].hpc; + drive->tracks = hdc[c].tracks; } static struct @@ -844,15 +844,18 @@ static void xebec_set_switches(xebec_t *xebec) static void *xebec_init() { int i = 0; + int c = 0; xebec_t *xebec = malloc(sizeof(xebec_t)); memset(xebec, 0, sizeof(xebec_t)); for (i = 0; i < HDC_NUM; i++) { - if (hdc[i].bus == 1) + if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) { - loadhd(xebec, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(xebec, i, hdc[i].mfm_channel, hdd_fn[i]); + c++; + if (c > MFM_NUM) break; } } @@ -904,15 +907,18 @@ device_t mfm_xebec_device = static void *dtc_5150x_init() { int i = 0; + int c = 0; xebec_t *xebec = malloc(sizeof(xebec_t)); memset(xebec, 0, sizeof(xebec_t)); for (i = 0; i < HDC_NUM; i++) { - if (hdc[i].bus == 1) + if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) { - loadhd(xebec, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(xebec, i, hdc[i].mfm_channel, hdd_fn[i]); + c++; + if (c > MFM_NUM) break; } } diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 8a82b7e36..6d38435be 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -26,6 +26,7 @@ #include "ibm.h" #include "io.h" #include "mem.h" +#include "mca.h" #include "rom.h" #include "dma.h" #include "pic.h" diff --git a/src/win.c b/src/win.c index 0f42ad819..609b85a1f 100644 --- a/src/win.c +++ b/src/win.c @@ -2400,6 +2400,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR return 0; case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: GetClientRect(hwnd, (LPRECT)& rc); pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam); From e43b45d2edfcf23539ab6c64a1612214e289a88a Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 May 2017 01:44:04 +0200 Subject: [PATCH 217/392] Removed an excess position increase in d86f_format_track(), 86F images can now be formatted again. --- src/disc_86f.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/disc_86f.c b/src/disc_86f.c index eca278532..bfb8f6f50 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1912,7 +1912,7 @@ void d86f_format_track(int drive, int side, int do_write) if (do_write) { d86f_write_direct(drive, side, d86f[drive].fill, 0); - d86f_handler[drive].write_data(drive, side, d86f[drive].datac++, d86f[drive].fill); + d86f_handler[drive].write_data(drive, side, d86f[drive].datac, d86f[drive].fill); } d86f_calccrc(drive, d86f[drive].fill); break; From ba2013064459866efeeb797872220bbd2d62502f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 May 2017 01:55:25 +0200 Subject: [PATCH 218/392] Fixed a bug with floppy icons on the status bar; Fixed a bug with CD-ROM menu items. --- src/win-language.c | 4 ++-- src/win.c | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/win-language.c b/src/win-language.c index 333729302..a2820beb8 100644 --- a/src/win-language.c +++ b/src/win-language.c @@ -188,10 +188,10 @@ int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save) { - file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); + return file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); } int file_dlg_st(HWND hwnd, int i, char *fn, int save) { - file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); + return file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); } diff --git a/src/win.c b/src/win.c index 609b85a1f..354ba252e 100644 --- a/src/win.c +++ b/src/win.c @@ -1611,11 +1611,8 @@ void win_cdrom_eject(uint8_t id) /* Signal disc change to the emulated machine. */ cdrom_insert(id); } - if (cdrom_drives[id].host_drive == 200) - { - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); - } - else + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) { CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); } @@ -2215,6 +2212,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR int cdrom_id = 0; int menu_sub_param = 0; int menu_super_param = 0; + int ret = 0; HMENU hmenu; @@ -2225,7 +2223,8 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { case IDM_DISC_1: case IDM_DISC_1_WP: - if (!file_dlg_w_st(hwnd, 2173, discfns[0], 0)) + ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); + if (!ret) { disc_close(0); ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; @@ -2237,7 +2236,8 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_2: case IDM_DISC_2_WP: - if (!file_dlg_w_st(hwnd, 2173, discfns[1], 0)) + ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); + if (!ret) { disc_close(1); ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; @@ -2249,7 +2249,8 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_3: case IDM_DISC_3_WP: - if (!file_dlg_w_st(hwnd, 2173, discfns[2], 0)) + ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); + if (!ret) { disc_close(2); ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; @@ -2261,7 +2262,8 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; case IDM_DISC_4: case IDM_DISC_4_WP: - if (!file_dlg_w_st(hwnd, 2173, discfns[3], 0)) + ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); + if (!ret) { disc_close(3); ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; From 34c08faf46439743e7def9e81c1063f223703932 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 15 May 2017 03:21:40 +0200 Subject: [PATCH 219/392] Fixed IDE hard disk array indexes wherever they were read from the wrong variable, fixes IDE hard disks when their configuration order does not match their IDE bus order. --- src/ide.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/ide.c b/src/ide.c index 637bb1cf2..afcb47778 100644 --- a/src/ide.c +++ b/src/ide.c @@ -354,27 +354,27 @@ static void ide_identify(IDE *ide) { uint32_t c, h, s; char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; - uint64_t full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); + uint64_t full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); device_identify[6] = ide->channel + 0x30; ide_log("IDE Identify: %s\n", device_identify); memset(ide->buffer, 0, 512); - c = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ - h = hdc[cur_ide[ide->board]].hpc; /* Heads */ - s = hdc[cur_ide[ide->board]].spt; /* Sectors */ + c = hdc[ide->hdc_num].tracks; /* Cylinders */ + h = hdc[ide->hdc_num].hpc; /* Heads */ + s = hdc[ide->hdc_num].spt; /* Sectors */ - if (hdc[cur_ide[ide->board]].tracks <= 16383) + if (hdc[ide->hdc_num].tracks <= 16383) { - ide->buffer[1] = hdc[cur_ide[ide->board]].tracks; /* Cylinders */ + ide->buffer[1] = hdc[ide->hdc_num].tracks; /* Cylinders */ } else { ide->buffer[1] = 16383; /* Cylinders */ } - ide->buffer[3] = hdc[cur_ide[ide->board]].hpc; /* Heads */ - ide->buffer[6] = hdc[cur_ide[ide->board]].spt; /* Sectors */ + ide->buffer[3] = hdc[ide->hdc_num].hpc; /* Heads */ + ide->buffer[6] = hdc[ide->hdc_num].spt; /* Sectors */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ @@ -415,8 +415,8 @@ static void ide_identify(IDE *ide) ide->buffer[59] = ide->blocksize ? (ide->blocksize | 0x100) : 0; if (ide->buffer[49] & (1 << 9)) { - ide->buffer[60] = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ - ide->buffer[61] = ((hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt) >> 16) & 0x0FFF; + ide->buffer[60] = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ + ide->buffer[61] = ((hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) >> 16) & 0x0FFF; } if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) { @@ -732,11 +732,11 @@ void ide_set_sector(IDE *ide, int64_t sector_num) } else { - cyl = sector_num / (hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); - r = sector_num % (hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); + cyl = sector_num / (hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + r = sector_num % (hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); ide->cylinder = cyl; - ide->head = ((r / hdc[cur_ide[ide->board]].spt) & 0x0f); - ide->sector = (r % hdc[cur_ide[ide->board]].spt) + 1; + ide->head = ((r / hdc[ide->hdc_num].spt) & 0x0f); + ide->sector = (r % hdc[ide->hdc_num].spt) + 1; } } @@ -1585,7 +1585,7 @@ void callbackide(int ide_board) ide = &ide_drives[cur_ide[ide_board]]; ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; - full_size = (hdc[cur_ide[ide->board]].tracks * hdc[cur_ide[ide->board]].hpc * hdc[cur_ide[ide->board]].spt); + full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); ext_ide = ide; if (ide_drive_is_cdrom(ide)) @@ -1974,11 +1974,11 @@ void callbackide(int ide_board) ide->specify_success = 1; if (ide->hdi == 2) { - hdc[cur_ide[ide->board]].at_hpc = ide->head+1; - hdc[cur_ide[ide->board]].at_spt = ide->secount; + hdc[ide->hdc_num].at_hpc = ide->head+1; + hdc[ide->hdc_num].at_spt = ide->secount; fseeko64(ide->hdfile, 0x20, SEEK_SET); - fwrite(&(hdc[cur_ide[ide->board]].at_spt), 1, 4, ide->hdfile); - fwrite(&(hdc[cur_ide[ide->board]].at_hpc), 1, 4, ide->hdfile); + fwrite(&(hdc[ide->hdc_num].at_spt), 1, 4, ide->hdfile); + fwrite(&(hdc[ide->hdc_num].at_hpc), 1, 4, ide->hdfile); } ide->spt=ide->secount; ide->hpc=ide->head+1; @@ -2031,9 +2031,9 @@ void callbackide(int ide_board) { goto abort_cmd; } - snum = hdc[cur_ide[ide->board]].spt; - snum *= hdc[cur_ide[ide->board]].hpc; - snum *= hdc[cur_ide[ide->board]].tracks; + snum = hdc[ide->hdc_num].spt; + snum *= hdc[ide->hdc_num].hpc; + snum *= hdc[ide->hdc_num].tracks; ide_set_sector(ide, snum - 1); ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); From 663dc642c7275223858e7124aa3add1c2193584c Mon Sep 17 00:00:00 2001 From: ThingUroboros Date: Mon, 15 May 2017 23:32:08 +0200 Subject: [PATCH 220/392] win.c Condition for fullscreen keyboard shortcut (CTRL+ALT+PAGEUP) --- src/win.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/win.c b/src/win.c index 354ba252e..c3bc6a176 100644 --- a/src/win.c +++ b/src/win.c @@ -1798,21 +1798,25 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case IDM_VID_FULLSCREEN: - if (video_fullscreen_first) - { - video_fullscreen_first = 0; - msgbox_info(ghwnd, 2193); - } - startblit(); - video_wait_for_blit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(ghwnd); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); + + if(video_fullscreen!=1){ + + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + msgbox_info(ghwnd, 2193); + } + startblit(); + video_wait_for_blit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(ghwnd); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + device_force_redraw(); + } break; case IDM_VID_FS_FULL: From 1a9a55c35edd1be280ab2f6c77b06982bc75c1a7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 17 May 2017 21:56:31 +0200 Subject: [PATCH 221/392] Split off the Network configuration from Other peripherals in the Settings dialog and made PCap device configurable; Overhauled the configuration files so that the global variables are now subdivided into sections; Fixed CD-ROM MODE SENSE page 0x2A which was being incorrectly reported as not implemented, fixes among other things Rayman 1 and Spellcross: The Last Battle (both now see the CD-ROM and play CD Audio fine). --- src/86Box.rc | 123 ++-- src/SOUND/snd_sb.c | 15 - src/SOUND/sound.c | 8 +- src/cdrom.c | 96 ++- src/cdrom.h | 14 +- src/config.c | 1273 ++++++++++++++++++++++++++-------------- src/device.c | 31 + src/device.h | 4 +- src/ibm.h | 10 +- src/ide.c | 2 +- src/net_ne2000.c | 76 +-- src/net_pcap.c | 59 +- src/network.c | 2 +- src/network.h | 6 + src/pc.c | 3 + src/plat-midi.h | 2 + src/resource.h | 22 +- src/scsi_aha154x.c | 4 +- src/scsi_buslogic.c | 4 +- src/win-deviceconfig.c | 35 -- src/win-language.c | 2 +- src/win-language.h | 2 + src/win-midi.c | 141 ++--- src/win-settings.c | 468 ++++++++++----- src/win.c | 20 +- 25 files changed, 1523 insertions(+), 899 deletions(-) diff --git a/src/86Box.rc b/src/86Box.rc index 388ab93b7..fb5d56296 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -112,7 +112,7 @@ BEGIN MENUITEM SEPARATOR POPUP "&Video" BEGIN - MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "&Resizeable window", IDM_VID_RESIZE MENUITEM "R&emember size && position", IDM_VID_REMEMBER MENUITEM SEPARATOR MENUITEM "&DirectDraw", IDM_VID_DDRAW @@ -323,7 +323,7 @@ BEGIN CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,147,81,113,10 + WS_TABSTOP,147,80,113,10 EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, @@ -346,7 +346,7 @@ BEGIN LTEXT "Video speed:",1800,7,26,58,10 CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,215,44,45,12 + PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 END @@ -366,53 +366,75 @@ BEGIN PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 END -CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 60 +CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - COMBOBOX IDC_COMBOSND,71,7,141,120,CBS_DROPDOWNLIST | WS_VSCROLL | + COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Sound card:",1800,7,8,59,10 - PUSHBUTTON "Configure",IDC_CONFIGURESND,215,7,45,14 + PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 + COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "MIDI Out Device:",1801,7,26,59,10 CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,87,25,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,25,80,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,174,25,80,10 - CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 + CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 END -CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 132 +CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,215,24,45,14 - LTEXT "HD Controller:",1799,7,44,61,10 - COMBOBOX IDC_COMBO_HDC,71,43,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Network adapter:",1801,7,8,59,10 - COMBOBOX IDC_COMBONET,71,7,141,120,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "Network type:",1800,7,8,59,10 + COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURENET,215,6,45,14 - LTEXT "Tertiary IDE:",1802,7,62,61,10 - COMBOBOX IDC_COMBO_IDE_TER,71,61,189,120,CBS_DROPDOWNLIST | + + LTEXT "PCap device:",1801,7,26,59,10 + COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "Network adapter:",1802,7,44,59,10 + COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 +END + +CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "SCSI Controller:",1804,7,8,59,10 + COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Quaternary IDE:",1803,7,81,61,10 - COMBOBOX IDC_COMBO_IDE_QUA,71,79,189,120,CBS_DROPDOWNLIST | + PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 + + LTEXT "HD Controller:",1799,7,26,61,10 + COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "SCSI Controller:",1804,7,26,59,10 - COMBOBOX IDC_COMBO_SCSI,71,25,141,120,CBS_DROPDOWNLIST | + + LTEXT "Tertiary IDE:",1802,7,44,61,10 + COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + + LTEXT "Quaternary IDE:",1803,7,62,61,10 + COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,97,80,10 - CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,174,97,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,87,97,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + + CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,115,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 END CONFIGUREDLG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 @@ -526,9 +548,10 @@ END 257 ICON DISCARDABLE "ICONS/video.ico" 258 ICON DISCARDABLE "ICONS/input_devices.ico" 259 ICON DISCARDABLE "ICONS/sound.ico" -260 ICON DISCARDABLE "ICONS/other_peripherals.ico" -261 ICON DISCARDABLE "ICONS/hard_disk.ico" -262 ICON DISCARDABLE "ICONS/removable_devices.ico" +260 ICON DISCARDABLE "ICONS/network.ico" +261 ICON DISCARDABLE "ICONS/other_peripherals.ico" +262 ICON DISCARDABLE "ICONS/hard_disk.ico" +263 ICON DISCARDABLE "ICONS/removable_devices.ico" 384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" 385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" 386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" @@ -625,12 +648,28 @@ BEGIN BOTTOMMARGIN, 58 END + CONFIGUREDLG_SOUND, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 71 + END + + CONFIGUREDLG_NETWORK, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + CONFIGUREDLG_PERIPHERALS, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 260 TOPMARGIN, 7 - BOTTOMMARGIN, 125 + BOTTOMMARGIN, 102 END CONFIGUREDLG_HARD_DISKS, DIALOG @@ -684,10 +723,10 @@ BEGIN IDS_STRING2066 "Video" IDS_STRING2067 "Input devices" IDS_STRING2068 "Sound" - IDS_STRING2069 "Other peripherals" - IDS_STRING2070 "Hard disks" - IDS_STRING2071 "Removable devices" - IDS_STRING2072 "Disabled floppy drive" + IDS_STRING2069 "Network" + IDS_STRING2070 "Other peripherals" + IDS_STRING2071 "Hard disks" + IDS_STRING2072 "Removable devices" IDS_STRING2073 "%i"" floppy drive: %s" IDS_STRING2074 "Disabled CD-ROM drive" IDS_STRING2075 "%s CD-ROM drive: %s" @@ -714,7 +753,7 @@ BEGIN 2092 "Bus" 2093 "DMA" 2094 "KB" - 2095 "Master" + 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" END STRINGTABLE DISCARDABLE @@ -730,7 +769,7 @@ BEGIN 2104 "Network Type" 2105 "Surround Module" 2106 "MPU-401 Base Address" - 2107 "MIDI Out Device" + 2107 "No PCap devices found" 2108 "On-board RAM" 2109 "Memory Size" 2110 "Display Type" @@ -834,7 +873,9 @@ BEGIN 2196 "Add New Hard Disk" 2197 "Add Existing Hard Disk" 2198 "Removable disk %i: %s" - 2199 "English (United States)" + 2199 "USB is not yet supported" + 2200 "Invalid PCap device" + 2201 "English (United States)" END diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index d1471ee34..40bfd4213 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -780,9 +780,6 @@ static device_config_t sb_config[] = } } }, - { - "midi", "MIDI out device", CONFIG_MIDI, "", 0 - }, { "", "", -1 } @@ -821,9 +818,6 @@ static device_config_t sb_mcv_config[] = } } }, - { - "midi", "MIDI out device", CONFIG_MIDI, "", 0 - }, { "", "", -1 } @@ -879,9 +873,6 @@ static device_config_t sb_pro_config[] = } } }, - { - "midi", "MIDI out device", CONFIG_MIDI, "", 0 - }, { "", "", -1 } @@ -1003,9 +994,6 @@ static device_config_t sb_16_config[] = } } }, - { - "midi", "MIDI out device", CONFIG_MIDI, "", 0 - }, { "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, { @@ -1141,9 +1129,6 @@ static device_config_t sb_awe32_config[] = } } }, - { - "midi", "MIDI out device", CONFIG_MIDI, "", 0 - }, { "mode401", "MPU-401 mode", CONFIG_SELECTION, "", 1, { diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index aa4c944bd..c3086b8e1 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -146,7 +146,7 @@ static void sound_cd_thread(void *param) has_audio = 0; for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].enabled && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) { has_audio++; } @@ -161,7 +161,7 @@ static void sound_cd_thread(void *param) if (cdrom_drives[i].handler->audio_callback) { cdrom_drives[i].handler->audio_callback(i, cd_buffer[i], CD_BUFLEN*2); - has_audio = (cdrom_drives[i].enabled && cdrom_drives[i].sound_on); + has_audio = (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on); } if (soundon && has_audio) { @@ -240,7 +240,7 @@ void sound_init() for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].enabled && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) { available_cdrom_drives++; } @@ -329,7 +329,7 @@ void sound_cd_thread_reset() for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].enabled && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) { available_cdrom_drives++; } diff --git a/src/cdrom.c b/src/cdrom.c index 8617e35af..60ad3afe5 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -175,25 +175,10 @@ uint8_t cdrom_command_flags[0x100] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -uint8_t cdrom_mode_sense_page_flags[CDROM_NUM][0x40] = -{ - { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED }, - { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED }, - { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED }, - { 0, IMPLEMENTED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, IMPLEMENTED, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED } -}; +uint64_t cdrom_mode_sense_page_flags[CDROM_NUM] = { (1LL << GPMODE_R_W_ERROR_PAGE) | (1LL << GPMODE_CDROM_PAGE) | (1LL << GPMODE_CDROM_AUDIO_PAGE) | (1LL << GPMODE_CAPABILITIES_PAGE) | (1LL << GPMODE_ALL_PAGES), + (1LL << GPMODE_R_W_ERROR_PAGE) | (1LL << GPMODE_CDROM_PAGE) | (1LL << GPMODE_CDROM_AUDIO_PAGE) | (1LL << GPMODE_CAPABILITIES_PAGE) | (1LL << GPMODE_ALL_PAGES), + (1LL << GPMODE_R_W_ERROR_PAGE) | (1LL << GPMODE_CDROM_PAGE) | (1LL << GPMODE_CDROM_AUDIO_PAGE) | (1LL << GPMODE_CAPABILITIES_PAGE) | (1LL << GPMODE_ALL_PAGES), + (1LL << GPMODE_R_W_ERROR_PAGE) | (1LL << GPMODE_CDROM_PAGE) | (1LL << GPMODE_CDROM_AUDIO_PAGE) | (1LL << GPMODE_CAPABILITIES_PAGE) | (1LL << GPMODE_ALL_PAGES) }; const uint8_t cdrom_mode_sense_pages_default[CDROM_NUM][0x40][0x40] = { @@ -747,7 +732,7 @@ int find_cdrom_for_channel(uint8_t channel) for (i = 0; i < CDROM_NUM; i++) { - if (!cdrom_drives[i].bus_type && (cdrom_drives[i].ide_channel == channel)) + if ((cdrom_drives[i].bus_type < 4) && (cdrom_drives[i].ide_channel == channel)) { return i; } @@ -755,7 +740,7 @@ int find_cdrom_for_channel(uint8_t channel) return 0xff; } -void cdrom_init(int id, int cdb_len_setting, int bus_type); +void cdrom_init(int id, int cdb_len_setting); void build_atapi_cdrom_map() { @@ -768,7 +753,7 @@ void build_atapi_cdrom_map() atapi_cdrom_drives[i] = find_cdrom_for_channel(i); if (atapi_cdrom_drives[i] != 0xff) { - cdrom_init(atapi_cdrom_drives[i], 12, 0); + cdrom_init(atapi_cdrom_drives[i], 12); } } } @@ -779,7 +764,7 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) + if ((cdrom_drives[i].bus_type == 4) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) { return i; } @@ -804,7 +789,7 @@ void build_scsi_cdrom_map() scsi_cdrom_drives[i][j] = find_cdrom_for_scsi_id(i, j); if (scsi_cdrom_drives[i][j] != 0xff) { - cdrom_init(scsi_cdrom_drives[i][j], 12, 1); + cdrom_init(scsi_cdrom_drives[i][j], 12); } } } @@ -830,7 +815,7 @@ void cdrom_set_signature(int id) cdrom[id].request_length = 0xEB14; } -void cdrom_init(int id, int cdb_len_setting, int bus_type) +void cdrom_init(int id, int cdb_len_setting) { if (id >= CDROM_NUM) { @@ -847,9 +832,17 @@ void cdrom_init(int id, int cdb_len_setting, int bus_type) cdrom[id].cd_status = CD_STATUS_EMPTY; cdrom[id].sense[0] = 0xf0; cdrom[id].sense[7] = 10; - cdrom_drives[id].bus_mode = cdrom_drives[id].bus_type ? 2 : (cdrom_drives[id].atapi_dma ? 3 : 1); + cdrom_drives[id].bus_mode = 0; + if (cdrom_drives[id].bus_type > 2) + { + cdrom_drives[id].bus_mode |= 2; + } + if (cdrom_drives[id].bus_type < 4) + { + cdrom_drives[id].bus_mode |= 1; + } cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode); - if (!cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type < 4) { cdrom_set_signature(id); cdrom_drives[id].max_blocks_at_once = 1; @@ -1083,7 +1076,7 @@ int cdrom_mode_select_header(uint8_t id, uint8_t val) } else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 2)) { - if (cdrom_drives[id].bus_type && (cdrom[id].current_page_len == 8)) + if ((cdrom_drives[id].bus_type == 4) && (cdrom[id].current_page_len == 8)) { cdrom[id].block_descriptor_len |= ((uint16_t) val) << 8; cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); @@ -1091,7 +1084,7 @@ int cdrom_mode_select_header(uint8_t id, uint8_t val) } else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 1)) { - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { cdrom[id].block_descriptor_len |= (uint16_t) val; cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); @@ -1134,7 +1127,7 @@ int cdrom_mode_select_page_header(uint8_t id, uint8_t val) if (cdrom[id].current_page_pos == 0) { cdrom[id].current_page_code = val & 0x3f; - if (cdrom_mode_sense_page_flags[id][cdrom[id].current_page_code] != IMPLEMENTED) + if (!(cdrom_mode_sense_page_flags[id] & (1LL << cdrom[id].current_page_code))) { cdrom_log("CD-ROM %i: Trying to modify an unimplemented page: %02X\n", id, cdrom[id].current_page_code); cdrom_mode_select_terminate(id, 1); @@ -1342,7 +1335,7 @@ uint32_t cdrom_mode_sense(uint8_t id, uint8_t *buf, uint32_t pos, uint8_t type, { if ((type == GPMODE_ALL_PAGES) || (type == i)) { - if (cdrom_mode_sense_page_flags[id][i] == IMPLEMENTED) + if (cdrom_mode_sense_page_flags[id] & (1LL << cdrom[id].current_page_code)) { buf[pos++] = cdrom_mode_sense_read(id, page_control, i, 0); msplen = cdrom_mode_sense_read(id, page_control, i, 1); @@ -1477,7 +1470,7 @@ static void cdrom_command_write_dma(uint8_t id) static int cdrom_request_length_is_zero(uint8_t id) { - if ((cdrom[id].request_length == 0) && !cdrom_drives[id].bus_type) + if ((cdrom[id].request_length == 0) && (cdrom_drives[id].bus_type < 4)) { return 1; } @@ -1497,7 +1490,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0)) { - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0; } @@ -1513,7 +1506,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (direction == 0) { - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; } @@ -2070,7 +2063,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { int ready = 0; - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { @@ -2082,19 +2075,20 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], cdrom_drives[id].bus_type ? "SCSI" : "ATAPI"); + cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], (cdrom_drives[id].bus_type == 4) ? "SCSI" : ((cdrom_drives[id].bus_type == 3) ? "ATAPI PIO/DMA" : "ATAPI PIO")); + cdrom_illegal_opcode(id); return 0; } - if (!cdrom_drives[id].bus_type && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) + if ((cdrom_drives[id].bus_type < 4) && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", id, cdb[0]); cdrom_illegal_opcode(id); return 0; } - if (cdrom_drives[id].bus_type && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) + if ((cdrom_drives[id].bus_type == 4) && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", id, cdb[0]); cdrom_illegal_opcode(id); @@ -2155,7 +2149,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) return 0; } - cdrom_log("CD-ROM %i: Continuing with command\n", id); + cdrom_log("CD-ROM %i: Continuing with command %02X\n", id, cdb[0]); return 1; } @@ -2309,7 +2303,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) #if 0 int CdbLength; #endif - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { cdrom[id].status &= ~ERR_STAT; } @@ -2507,7 +2501,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } max_len = cdrom[id].sector_len; - /* if (cdrom_drives[id].bus_type) */ + /* if (cdrom_drives[id].bus_type == 4) */ if (cdrom_current_mode(id) == 2) { cdrom[id].requested_blocks = max_len; @@ -2579,7 +2573,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; } @@ -2597,7 +2591,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) len = (cdb[8] | (cdb[7] << 8)); } - if (!(cdrom_mode_sense_page_flags[id][cdb[2] & 0x3F] & IMPLEMENTED)) + cdrom[id].current_page_code = cdb[2] & 0x3F; + + if (!(cdrom_mode_sense_page_flags[id] & (1LL << cdrom[id].current_page_code))) { cdrom_invalid_field(id); return; @@ -3201,8 +3197,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) memset(cdbufferb, 0, 8); cdbufferb[0] = 5; /*CD-ROM*/ cdbufferb[1] = 0x80; /*Removable*/ - cdbufferb[2] = cdrom_drives[id].bus_type ? 0x02 : 0x00; /*SCSI-2 compliant*/ - cdbufferb[3] = cdrom_drives[id].bus_type ? 0x02 : 0x21; + cdbufferb[2] = (cdrom_drives[id].bus_type == 4) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + cdbufferb[3] = (cdrom_drives[id].bus_type == 4) ? 0x02 : 0x21; cdbufferb[4] = 31; ide_padstr8(cdbufferb + 8, 8, "86Box"); /* Vendor */ @@ -3356,7 +3352,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ { int old_pos = 0; - if (!cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type < 4) { cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); @@ -3482,7 +3478,7 @@ int cdrom_read_from_dma(uint8_t id) int in_data_length = 0; - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } @@ -3496,7 +3492,7 @@ int cdrom_read_from_dma(uint8_t id) return 0; } - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { in_data_length = SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength; cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length); @@ -3602,7 +3598,7 @@ int cdrom_write_to_dma(uint8_t id) { int ret = 0; - if (cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type == 4) { ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } @@ -3621,7 +3617,7 @@ int cdrom_write_to_dma(uint8_t id) void cdrom_irq_raise(uint8_t id) { - if (!cdrom_drives[id].bus_type) + if (cdrom_drives[id].bus_type < 4) { ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); } diff --git a/src/cdrom.h b/src/cdrom.h index a3a3a69a9..63470c36f 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -59,7 +59,7 @@ typedef struct __attribute__((__packed__)) int requested_blocks; /* This will be set to something other than 1 when block reads are implemented. */ - int current_page_code; + uint64_t current_page_code; int current_page_len; int current_page_pos; @@ -132,8 +132,6 @@ typedef struct typedef struct __attribute__((__packed__)) #endif { - int enabled; - int max_blocks_at_once; CDROM *handler; @@ -141,17 +139,17 @@ typedef struct __attribute__((__packed__)) int host_drive; int prev_host_drive; - uint8_t bus_type; /* 0 = ATAPI, 1 = SCSI */ + unsigned int bus_type; /* 0 = ATAPI, 1 = SCSI */ uint8_t bus_mode; /* Bit 0 = PIO suported; Bit 1 = DMA supportd. */ uint8_t ide_channel; - uint8_t scsi_device_id; - uint8_t scsi_device_lun; + unsigned int scsi_device_id; + unsigned int scsi_device_lun; - uint8_t sound_on; - uint8_t atapi_dma; + unsigned int sound_on; + unsigned int atapi_dma; } cdrom_drive_t; #ifdef __MSC__ # pragma pack(pop) diff --git a/src/config.c b/src/config.c index 8b31042d3..d4e47b727 100644 --- a/src/config.c +++ b/src/config.c @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ +#include #include #include #include @@ -23,12 +24,22 @@ #include "network.h" #include "nvr.h" #include "plat-joystick.h" +#include "plat-midi.h" #include "scsi.h" #include "sound/snd_dbopl.h" #include "sound/snd_opl.h" #include "sound/sound.h" #include "video/video.h" +#ifndef __unix +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "win.h" +#include "win-language.h" +#endif + wchar_t config_file_default[256]; @@ -123,8 +134,18 @@ void config_free(void) } } +static wchar_t cfgbuffer[1024]; +static char sname[256]; +static char ename[256]; + void config_load(wchar_t *fn) { + int c; + + section_t *new_section; + entry_t *new_entry; + int sd = 0, ed = 0, data_pos; + FILE *f = _wfopen(fn, L"rt, ccs=UNICODE"); section_t *current_section; @@ -139,74 +160,64 @@ void config_load(wchar_t *fn) while (1) { - int c; - wchar_t buffer[1024]; - int org_pos; - - memset(buffer, 0, 2048); - fgetws(buffer, 255, f); + memset(cfgbuffer, 0, 2048); + fgetws(cfgbuffer, 255, f); if (feof(f)) break; c = 0; - while (buffer[c] == L' ') + while (cfgbuffer[c] == L' ') c++; - if (buffer[c] == L'\0') continue; + if (cfgbuffer[c] == L'\0') continue; - if (buffer[c] == L'#') /*Comment*/ + if (cfgbuffer[c] == L'#') /*Comment*/ continue; - if (buffer[c] == L'[') /*Section*/ + if (cfgbuffer[c] == L'[') /*Section*/ { - section_t *new_section; - char name[256]; - int d = 0; - + sd = 0; c++; - while (buffer[c] != L']' && buffer[c]) - wctomb(&(name[d++]), buffer[c++]); + while (cfgbuffer[c] != L']' && cfgbuffer[c]) + wctomb(&(sname[sd++]), cfgbuffer[c++]); - if (buffer[c] != L']') + if (cfgbuffer[c] != L']') continue; - name[d] = 0; + sname[sd] = 0; new_section = malloc(sizeof(section_t)); memset(new_section, 0, sizeof(section_t)); - strncpy(new_section->name, name, 256); + strncpy(new_section->name, sname, 256); list_add(&new_section->list, &config_head); current_section = new_section; } else { - entry_t *new_entry; - char name[256]; - int d = 0, data_pos; - - while (buffer[c] != L'=' && buffer[c] != L' ' && buffer[c]) - wctomb(&(name[d++]), buffer[c++]); + ed = 0; + while (cfgbuffer[c] != L'=' && cfgbuffer[c] != L' ' && cfgbuffer[c]) + wctomb(&(ename[ed++]), cfgbuffer[c++]); - if (buffer[c] == L'\0') continue; - name[d] = 0; + if (cfgbuffer[c] == L'\0') continue; + ename[ed] = 0; - while ((buffer[c] == L'=' || buffer[c] == L' ') && buffer[c]) + while ((cfgbuffer[c] == L'=' || cfgbuffer[c] == L' ') && cfgbuffer[c]) c++; - if (!buffer[c]) continue; + if (!cfgbuffer[c]) continue; data_pos = c; - while (buffer[c]) + while (cfgbuffer[c]) { - if (buffer[c] == L'\n') - buffer[c] = L'\0'; + if (cfgbuffer[c] == L'\n') + cfgbuffer[c] = L'\0'; c++; } new_entry = malloc(sizeof(entry_t)); memset(new_entry, 0, sizeof(entry_t)); - strncpy(new_entry->name, name, 256); - memcpy(new_entry->wdata, &buffer[data_pos], 512); + strncpy(new_entry->name, ename, 256); + memcpy(new_entry->wdata, &cfgbuffer[data_pos], 512); new_entry->wdata[255] = L'\0'; wcstombs(new_entry->data, new_entry->wdata, 512); new_entry->data[255] = '\0'; @@ -304,6 +315,27 @@ int config_get_int(char *head, char *name, int def) return value; } +int config_get_hex16(char *head, char *name, int def) +{ + section_t *section; + entry_t *entry; + int value; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + sscanf(entry->data, "%04X", &value); + + return value; +} + char *config_get_string(char *head, char *name, char *def) { section_t *section; @@ -359,6 +391,25 @@ void config_set_int(char *head, char *name, int val) mbstowcs(entry->wdata, entry->data, 512); } +void config_set_hex16(char *head, char *name, int val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + sprintf(entry->data, "%04X", val); + mbstowcs(entry->wdata, entry->data, 512); +} + void config_set_string(char *head, char *name, char *val) { section_t *section; @@ -483,6 +534,8 @@ void config_save(wchar_t *fn) { FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); section_t *current_section; + + int fl = 0; current_section = (section_t *)config_head.next; @@ -493,7 +546,15 @@ void config_save(wchar_t *fn) if (current_section->name[0]) { mbstowcs(wname, current_section->name, strlen(current_section->name) + 1); - fwprintf(f, L"\n[%ws]\n", wname); + if (fl) + { + fwprintf(f, L"\n[%ws]\n", wname); + } + else + { + fwprintf(f, L"[%ws]\n", wname); + } + fl++; } current_entry = (entry_t *)current_section->entry_head.next; @@ -509,6 +570,7 @@ void config_save(wchar_t *fn) { fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); } + fl++; current_entry = (entry_t *)current_entry->list.next; } @@ -518,274 +580,52 @@ void config_save(wchar_t *fn) fclose(f); } -void loadconfig(wchar_t *fn) + +static char temps[512]; + +void loadconfig_general(void) { - int c, d; - char s[512]; + wchar_t *wp; char *p; - wchar_t *wp, *wq; - char temps[512]; - - if (!fn) - config_load(config_file_default); - else - config_load(fn); - - GAMEBLASTER = !!config_get_int(NULL, "gameblaster", 0); - GUS = !!config_get_int(NULL, "gus", 0); - SSI2001 = !!config_get_int(NULL, "ssi2001", 0); - voodoo_enabled = !!config_get_int(NULL, "voodoo", 0); - /* SCSI */ - p = (char *)config_get_string(NULL, "scsicard", ""); - if (p) - scsi_card_current = scsi_card_get_from_internal_name(p); - else - scsi_card_current = 0; - - /* Network */ - network_type = config_get_int(NULL, "net_type", -1); - p = (char *)config_get_string(NULL, "net_card", NULL); - network_card = (p) ? network_card_get_from_internal_name(p) : 0; - - p = (char *)config_get_string(NULL, "model", ""); - if (p) - model = model_get_model_from_internal_name(p); - else - model = 0; - - if (model >= model_count()) - model = model_count() - 1; - - romset = model_getromset(); - cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); - cpu = config_get_int(NULL, "cpu", 0); - cpu_use_dynarec = !!config_get_int(NULL, "cpu_use_dynarec", 0); - - cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); - - p = (char *)config_get_string(NULL, "gfxcard", ""); - if (p) - gfxcard = video_get_video_from_internal_name(p); - else - gfxcard = 0; - video_speed = config_get_int(NULL, "video_speed", 3); - p = (char *)config_get_string(NULL, "sndcard", ""); - if (p) - sound_card_current = sound_card_get_from_internal_name(p); - else - sound_card_current = 0; - - mem_size = config_get_int(NULL, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - if (mem_size > 1048576) - { - mem_size = 1048576; - } - - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); - if (p) - fdd_set_type(c, fdd_get_from_internal_name(p)); - else - fdd_set_type(c, (c < 2) ? 2 : 0); - if (fdd_get_type(c) > 13) - { - fdd_set_type(c, 13); - } - - sprintf(temps, "fdd_%02i_fn", c + 1); - wp = (wchar_t *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(discfns[c], wp, 512); - else { - memcpy(discfns[c], L"", 2); - discfns[c][0] = L'\0'; - } - printf("Floppy: %ws\n", discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = !!config_get_int(NULL, temps, 0); - } - - p = (char *)config_get_string(NULL, "hdd_controller", ""); - if (p) - strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); - else - strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); + /* General */ + vid_resize = !!config_get_int("General", "vid_resize", 0); + p = (char *)config_get_string("General", "vid_renderer", "d3d9"); memset(temps, 0, 512); - for (c = 2; c < 4; c++) + if (p) { - sprintf(temps, "ide_%02i_enable", c + 1); - ide_enable[c] = config_get_int(NULL, temps, 0); - sprintf(temps, "ide_%02i_irq", c + 1); - ide_irq[c] = config_get_int(NULL, temps, 8 + c); + strcpy(temps, p); + } + if (!strcmp(temps, "ddraw")) + { + vid_api = 0; + } + else + { + vid_api = 1; } - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) + video_fullscreen_scale = config_get_int("General", "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int("General", "video_fullscreen_first", 1); + + force_43 = !!config_get_int("General", "force_43", 0); + scale = !!config_get_int("General", "scale", 1); + enable_overscan = !!config_get_int("General", "enable_overscan", 0); + + p = config_get_string("General", "window_w_coordinates", "0, 0, 0, 0"); + if (p) { - sprintf(temps, "hdd_%02i_sectors", c + 1); - hdc[c].spt = config_get_int(NULL, temps, 0); - if (hdc[c].spt > 99) - { - hdc[c].spt = 99; - } - sprintf(temps, "hdd_%02i_heads", c + 1); - hdc[c].hpc = config_get_int(NULL, temps, 0); - if (hdc[c].hpc > 64) - { - hdc[c].hpc = 64; - } - sprintf(temps, "hdd_%02i_cylinders", c + 1); - hdc[c].tracks = config_get_int(NULL, temps, 0); - if (hdc[c].tracks > 266305) - { - hdc[c].tracks = 266305; - } - sprintf(temps, "hdd_%02i_bus_type", c + 1); - hdc[c].bus = config_get_int(NULL, temps, 0); - if (hdc[c].bus > 4) - { - hdc[c].bus = 4; - } - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int(NULL, temps, 0); - if (hdc[c].mfm_channel > 1) - { - hdc[c].mfm_channel = 1; - } - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int(NULL, temps, 0); - if (hdc[c].ide_channel > 7) - { - hdc[c].ide_channel = 7; - } - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); - if (hdc[c].scsi_id > 15) - { - hdc[c].scsi_id = 15; - } - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - hdc[c].scsi_lun = config_get_int(NULL, temps, 0); - if (hdc[c].scsi_lun > 7) - { - hdc[c].scsi_lun = 7; - } - sprintf(temps, "hdd_%02i_fn", c + 1); - wp = (wchar_t *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(hdd_fn[c], wp, 512); - else { - memcpy(hdd_fn[c], L"", 2); - hdd_fn[c][0] = L'\0'; - } + sscanf(temps, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) + else { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); - cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; - sprintf(temps, "cdrom_%02i_enabled", c + 1); - cdrom_drives[c].enabled = !!config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - cdrom_drives[c].sound_on = !!config_get_int(NULL, temps, 1); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); - if (cdrom_drives[c].bus_type > 1) - { - cdrom_drives[c].bus_type = 1; - } - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - cdrom_drives[c].atapi_dma = !!config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); - if (cdrom_drives[c].ide_channel > 7) - { - cdrom_drives[c].ide_channel = 7; - } - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); - if (cdrom_drives[c].scsi_device_id > 15) - { - cdrom_drives[c].scsi_device_id = 15; - } - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); - if (cdrom_drives[c].scsi_device_lun > 7) - { - cdrom_drives[c].scsi_device_lun = 7; - } - - sprintf(temps, "cdrom_%02i_image_path", c + 1); - wp = (wchar_t *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(cdrom_image[c].image_path, wp, 512); - else { - memcpy(cdrom_image[c].image_path, L"", 2); - cdrom_image[c].image_path[0] = L'\0'; - } + sscanf(temps, "0, 0, 0, 0", &window_w, &window_h, &window_x, &window_y); } - - vid_resize = !!config_get_int(NULL, "vid_resize", 0); - vid_api = config_get_int(NULL, "vid_api", 0); - video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); - - force_43 = !!config_get_int(NULL, "force_43", 0); - scale = !!config_get_int(NULL, "scale", 1); - enable_overscan = !!config_get_int(NULL, "enable_overscan", 0); - - enable_sync = !!config_get_int(NULL, "enable_sync", 1); - opl3_type = !!config_get_int(NULL, "opl3_type", 1); - - window_w = config_get_int(NULL, "window_w", 0); - window_h = config_get_int(NULL, "window_h", 0); - window_x = config_get_int(NULL, "window_x", 0); - window_y = config_get_int(NULL, "window_y", 0); - window_remember = config_get_int(NULL, "window_remember", 0); - - joystick_type = config_get_int(NULL, "joystick_type", 0); - p = (char *)config_get_string(NULL, "mouse_type", ""); - if (p) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; - - enable_external_fpu = !!config_get_int(NULL, "enable_external_fpu", 0); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); - } - } - } + window_remember = config_get_int("General", "window_remember", 0); memset(nvr_path, 0, 2048); - wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); + wp = (wchar_t *)config_get_wstring("General", "nvr_path", L""); if (wp) { if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); else @@ -806,10 +646,484 @@ void loadconfig(wchar_t *fn) path_len = wcslen(nvr_path); - serial_enabled[0] = !!config_get_int(NULL, "serial1_enabled", 1); - serial_enabled[1] = !!config_get_int(NULL, "serial2_enabled", 1); - lpt_enabled = !!config_get_int(NULL, "lpt_enabled", 1); - bugger_enabled = !!config_get_int(NULL, "bugger_enabled", 0); +#ifndef __unix + /* Currently, 86Box is English (US) only, but in the future (version 1.30 at the earliest) other languages will be added, + therefore it is better to future-proof the code. */ + dwLanguage = config_get_hex16("General", "language", 0x0409); +#endif +} + +static void loadconfig_machine(void) +{ + char *p; + + /* Machine */ + p = (char *)config_get_string("Machine", "model", ""); + if (p) + model = model_get_model_from_internal_name(p); + else + model = 0; + + if (model >= model_count()) + model = model_count() - 1; + + romset = model_getromset(); + cpu_manufacturer = config_get_int("Machine", "cpu_manufacturer", 0); + cpu = config_get_int("Machine", "cpu", 0); + + cpu_waitstates = config_get_int("Machine", "cpu_waitstates", 0); + + mem_size = config_get_int("Machine", "mem_size", 4096); + if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + if (mem_size > 1048576) + { + mem_size = 1048576; + } + + cpu_use_dynarec = !!config_get_int("Machine", "cpu_use_dynarec", 0); + + enable_external_fpu = !!config_get_int("Machine", "cpu_enable_fpu", 0); + + enable_sync = !!config_get_int("Machine", "enable_sync", 1); +} + +static void loadconfig_video(void) +{ + char *p; + + /* Video */ + p = (char *)config_get_string("Video", "gfxcard", ""); + if (p) + gfxcard = video_get_video_from_internal_name(p); + else + gfxcard = 0; + + video_speed = config_get_int("Video", "video_speed", 3); + + voodoo_enabled = !!config_get_int("Video", "voodoo", 0); +} + +static char s[512]; + +static void loadconfig_input_devices(void) +{ + int c, d; + char *p; + + /* Input devices */ + p = (char *)config_get_string("Input devices", "mouse_type", ""); + if (p) + mouse_type = mouse_get_from_internal_name(p); + else + mouse_type = 0; + + joystick_type = config_get_int("Input devices", "joystick_type", 0); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int("Input devices", s, 0); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int("Input devices", s, d); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int("Input devices", s, d); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i", c, d); + p = (char *)config_get_string("Input devices", s, "0, 0"); + joystick_state[c].pov_mapping[d][0] = joystick_state[c].pov_mapping[d][1] = 0; + sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0], &joystick_state[c].pov_mapping[d][1]); + } + } + } +} + +static void loadconfig_sound(void) +{ + char *p; + + /* Sound */ + p = (char *)config_get_string("Sound", "sndcard", ""); + if (p) + sound_card_current = sound_card_get_from_internal_name(p); + else + sound_card_current = 0; + + midi_id = config_get_int("Sound", "midi_host_device", 0); + + SSI2001 = !!config_get_int("Sound", "ssi2001", 0); + GAMEBLASTER = !!config_get_int("Sound", "gameblaster", 0); + GUS = !!config_get_int("Sound", "gus", 0); + opl3_type = !!config_get_int("Sound", "opl3_type", 1); +} + +static void loadconfig_network(void) +{ + char *p; + + /* Network */ + network_type = config_get_int("Network", "net_type", -1); + memset(pcap_dev, 0, 512); + p = (char *)config_get_string("Network", "net_pcap_device", "none"); + if (p) + if ((network_dev_to_id(p) == -1) || (netdev_num == 1)) + { + if ((netdev_num == 1) && strcmp(pcap_dev, "none")) + { + msgbox_error(ghwnd, 2107); + } + else if (network_dev_to_id(p) == -1) + { + msgbox_error(ghwnd, 2200); + } + + strcpy(pcap_dev, "none"); + } + else + { + strcpy(pcap_dev, p); + } + else + strcpy(pcap_dev, "none"); + p = (char *)config_get_string("Network", "net_card", NULL); + network_card = (p) ? network_card_get_from_internal_name(p) : 0; +} + +static void loadconfig_other_peripherals(void) +{ + int c; + char *p; + + /* Other peripherals */ + p = (char *)config_get_string("Other peripherals", "scsicard", ""); + if (p) + scsi_card_current = scsi_card_get_from_internal_name(p); + else + scsi_card_current = 0; + + memset(hdd_controller_name, 0, 16); + p = (char *)config_get_string("Other peripherals", "hdd_controller", ""); + if (p) + strcpy(hdd_controller_name, p); + else + strcpy(hdd_controller_name, "none"); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i", c + 1); + p = config_get_string("Other peripherals", temps, "0, 00"); + if (p) + { + sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]); + } + else + { + sscanf(p, "0, 00", &ide_enable[c], &ide_irq[c]); + } + } + + serial_enabled[0] = !!config_get_int("Other peripherals", "serial1_enabled", 1); + serial_enabled[1] = !!config_get_int("Other peripherals", "serial2_enabled", 1); + lpt_enabled = !!config_get_int("Other peripherals", "lpt_enabled", 1); + bugger_enabled = !!config_get_int("Other peripherals", "bugger_enabled", 0); +} + +static char temps2[512]; + +static int config_string_to_bus(char *str, int cdrom) +{ + if (!strcmp(str, "none")) + { + return 0; + } + + if (!strcmp(str, "mfm")) + { + if (cdrom) goto no_mfm_cdrom; + + return 1; + } + + if (!strcmp(str, "rll")) + { + if (cdrom) goto no_mfm_cdrom; + + return 1; + } + + if (!strcmp(str, "esdi")) + { + if (cdrom) goto no_mfm_cdrom; + + return 1; + } + + if (!strcmp(str, "ide_pio_only")) + { + return 2; + } + + if (!strcmp(str, "ide")) + { + return 2; + } + + if (!strcmp(str, "eide")) + { + return 2; + } + + if (!strcmp(str, "xtide")) + { + return 2; + } + + if (!strcmp(str, "atide")) + { + return 2; + } + + if (!strcmp(str, "ide_pio_and_dma")) + { + return 3; + } + + if (!strcmp(str, "scsi")) + { + return 4; + } + + if (!strcmp(str, "usb")) + { + msgbox_error(ghwnd, 2199); + return 0; + } + + return 0; + +no_mfm_cdrom: + msgbox_error(ghwnd, 2095); + return 0; +} + +static void loadconfig_hard_disks(void) +{ + int c; + char *p; + wchar_t *wp; + + /* Hard disks */ + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_parameters", c + 1); + p = (char *)config_get_string("Hard disks", temps, "0, 0, 0, none"); + if (p) + { + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); + } + else + { + sscanf("0, 0, 0, none", "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); + } + + hdc[c].bus = config_string_to_bus(s, 0); + + if (hdc[c].spt > 99) + { + hdc[c].spt = 99; + } + if (hdc[c].hpc > 64) + { + hdc[c].hpc = 64; + } + if (hdc[c].tracks > 266305) + { + hdc[c].tracks = 266305; + } + + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + hdc[c].mfm_channel = config_get_int("Hard disks", temps, 0); + if (hdc[c].mfm_channel > 1) + { + hdc[c].mfm_channel = 1; + } + + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + hdc[c].ide_channel = config_get_int("Hard disks", temps, 0); + if (hdc[c].ide_channel > 7) + { + hdc[c].ide_channel = 7; + } + + sprintf(temps, "hdd_%02i_scsi_location", c + 1); + sprintf(temps2, "%02u:%02u", c, 0); + p = (char *)config_get_string("Hard disks", temps, temps2); + if (p) + { + sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); + } + else + { + sscanf(temps2, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); + } + + if (hdc[c].scsi_id > 15) + { + hdc[c].scsi_id = 15; + } + if (hdc[c].scsi_lun > 7) + { + hdc[c].scsi_lun = 7; + } + + memset(hdd_fn[c], 0, 1024); + sprintf(temps, "hdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring("Hard disks", temps, L""); + if (wp) memcpy(hdd_fn[c], wp, 512); + else { + memcpy(hdd_fn[c], L"", 2); + hdd_fn[c][0] = L'\0'; + } + } +} + +static void loadconfig_removable_devices(void) +{ + int c; + char *p; + wchar_t *wp; + + /* Removable devices */ + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + p = (char *)config_get_string("Removable devices", temps, (c < 2) ? "525_2dd" : "none"); + if (p) + fdd_set_type(c, fdd_get_from_internal_name(p)); + else + fdd_set_type(c, (c < 2) ? 2 : 0); + if (fdd_get_type(c) > 13) + { + fdd_set_type(c, 13); + } + + sprintf(temps, "fdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring("Removable devices", temps, L""); + if (wp) memcpy(discfns[c], wp, 512); + else { + memcpy(discfns[c], L"", 2); + discfns[c][0] = L'\0'; + } + printf("Floppy: %ws\n", discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = !!config_get_int("Removable devices", temps, 0); + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + cdrom_drives[c].host_drive = config_get_int("Removable devices", temps, 0); + cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; + + sprintf(temps, "cdrom_%02i_parameters", c + 1); + p = (char *)config_get_string("Removable devices", temps, "0, none"); + if (p) + { + sscanf(p, "%u, %s", &cdrom_drives[c].sound_on, s); + } + else + { + sscanf("0, none", "%u, %s", &cdrom_drives[c].sound_on, s); + } + + cdrom_drives[c].bus_type = config_string_to_bus(s, 1); + + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + cdrom_drives[c].ide_channel = config_get_int("Removable devices", temps, c + 2); + if (cdrom_drives[c].ide_channel > 7) + { + cdrom_drives[c].ide_channel = 7; + } + + sprintf(temps, "cdrom_%02i_scsi_location", c + 1); + sprintf(temps2, "%02u:%02u", c + 2, 0); + p = (char *)config_get_string("Removable devices", temps, temps2); + if (p) + { + sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); + } + else + { + sscanf(temps2, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); + } + + + if (cdrom_drives[c].scsi_device_id > 15) + { + cdrom_drives[c].scsi_device_id = 15; + } + if (cdrom_drives[c].scsi_device_lun > 7) + { + cdrom_drives[c].scsi_device_lun = 7; + } + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + wp = (wchar_t *)config_get_wstring("Removable devices", temps, L""); + if (wp) memcpy(cdrom_image[c].image_path, wp, 512); + else { + memcpy(cdrom_image[c].image_path, L"", 2); + cdrom_image[c].image_path[0] = L'\0'; + } + } +} + +void loadconfig(wchar_t *fn) +{ + if (!fn) + config_load(config_file_default); + else + config_load(fn); + + /* General */ + loadconfig_general(); + + /* Machine */ + loadconfig_machine(); + + /* Video */ + loadconfig_video(); + + /* Input devices */ + loadconfig_input_devices(); + + /* Sound */ + loadconfig_sound(); + + /* Network */ + loadconfig_network(); + + /* Other peripherals */ + loadconfig_other_peripherals(); + + /* Hard disks */ + loadconfig_hard_disks(); + + /* Removable devices */ + loadconfig_removable_devices(); + } wchar_t temp_nvr_path[1024]; @@ -817,177 +1131,280 @@ wchar_t temp_nvr_path[1024]; wchar_t *nvr_concat(wchar_t *to_concat) { char *p; + wchar_t *wp; memset(temp_nvr_path, 0, 2048); wcscpy(temp_nvr_path, nvr_path); p = (char *) temp_nvr_path; p += (path_len * 2); - wchar_t *wp = (wchar_t *) p; + wp = (wchar_t *) p; wcscpy(wp, to_concat); return temp_nvr_path; } -void saveconfig(void) +void saveconfig_general(void) +{ + config_set_int("General", "vid_resize", vid_resize); + switch(vid_api) + { + case 0: + config_set_string("General", "vid_renderer", "ddraw"); + break; + case 1: + default: + config_set_string("General", "vid_renderer", "d3d9"); + break; + } + config_set_int("General", "video_fullscreen_scale", video_fullscreen_scale); + config_set_int("General", "video_fullscreen_first", video_fullscreen_first); + + config_set_int("General", "force_43", force_43); + config_set_int("General", "scale", scale); + config_set_int("General", "enable_overscan", enable_overscan); + + sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); + config_set_string("General", "window_coordinates", temps); + config_set_int("General", "window_remember", window_remember); + + config_set_wstring("General", "nvr_path", nvr_path); + +#ifndef __unix + config_set_hex16("General", "language", dwLanguage); +#endif +} + +void saveconfig_machine(void) +{ + /* Machine */ + config_set_string("Machine", "model", model_get_internal_name()); + config_set_int("Machine", "cpu_manufacturer", cpu_manufacturer); + config_set_int("Machine", "cpu", cpu); + config_set_int("Machine", "cpu_waitstates", cpu_waitstates); + + config_set_int("Machine", "mem_size", mem_size); + config_set_int("Machine", "cpu_use_dynarec", cpu_use_dynarec); + config_set_int("Machine", "cpu_enable_fpu", enable_external_fpu); + config_set_int("Machine", "enable_sync", enable_sync); +} + +void saveconfig_video(void) +{ + /* Video */ + config_set_string("Video", "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int("Video", "video_speed", video_speed); + config_set_int("Video", "voodoo", voodoo_enabled); +} + +void saveconfig_input_devices(void) { int c, d; - char temps[512]; + /* Input devices */ + config_set_string("Input devices", "mouse_type", mouse_get_internal_name(mouse_type)); - config_set_int(NULL, "gameblaster", GAMEBLASTER); - config_set_int(NULL, "gus", GUS); - config_set_int(NULL, "ssi2001", SSI2001); - config_set_int(NULL, "voodoo", voodoo_enabled); - - config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - - config_set_string(NULL, "net_card", network_card_get_internal_name(network_card)); - config_set_int(NULL, "net_type", network_type); -#if 1 - config_set_int(NULL, "maclocal", ne2000_get_maclocal()); - config_set_int(NULL, "maclocal_pci", ne2000_get_maclocal_pci()); -#endif - - config_set_string(NULL, "model", model_get_internal_name()); - config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); - config_set_int(NULL, "cpu", cpu); - config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(NULL, "cpu_waitstates", cpu_waitstates); - - config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(NULL, "video_speed", video_speed); - config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int(NULL, "cpu_speed", cpuspeed); - config_set_int(NULL, "has_fpu", hasfpu); - - config_set_int(NULL, "mem_size", mem_size); - - memset(temps, 0, 512); - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); - sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring(NULL, temps, discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int(NULL, temps, ui_writeprot[c]); - } - - config_set_string(NULL, "hdd_controller", hdd_controller_name); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - config_set_int(NULL, temps, ide_enable[c]); - sprintf(temps, "ide_%02i_irq", c + 1); - config_set_int(NULL, temps, ide_irq[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - config_set_int(NULL, temps, hdc[c].spt); - sprintf(temps, "hdd_%02i_heads", c + 1); - config_set_int(NULL, temps, hdc[c].hpc); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - config_set_int(NULL, temps, hdc[c].tracks); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - config_set_int(NULL, temps, hdc[c].bus); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int(NULL, temps, hdc[c].mfm_channel); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, hdc[c].ide_channel); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_id); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_lun); - sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring(NULL, temps, hdd_fn[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].host_drive); - sprintf(temps, "cdrom_%02i_enabled", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].enabled); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].sound_on); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].bus_type); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].ide_channel); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); - - sprintf(temps, "cdrom_%02i_image_path", c + 1); - config_set_wstring(NULL, temps, cdrom_image[c].image_path); - } - - config_set_int(NULL, "vid_resize", vid_resize); - config_set_int(NULL, "vid_api", vid_api); - config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); - - config_set_int(NULL, "force_43", force_43); - config_set_int(NULL, "scale", scale); - config_set_int(NULL, "enable_overscan", enable_overscan); - - config_set_int(NULL, "enable_sync", enable_sync); - config_set_int(NULL, "opl3_type", opl3_type); - - config_set_int(NULL, "joystick_type", joystick_type); - config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); - - config_set_int(NULL, "enable_external_fpu", enable_external_fpu); + config_set_int("Input devices", "joystick_type", joystick_type); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - char s[80]; - sprintf(s, "joystick_%i_nr", c); - config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); + config_set_int("Input devices", s, joystick_state[c].plat_joystick_nr); if (joystick_state[c].plat_joystick_nr) { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); + config_set_int("Input devices", s, joystick_state[c].axis_mapping[d]); } for (d = 0; d < joystick_get_button_count(joystick_type); d++) { sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); + config_set_int("Input devices", s, joystick_state[c].button_mapping[d]); } for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); + sprintf(s, "joystick_%i_pov_%i", c, d); + sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); + config_set_string("Input devices", s, temps); } } } +} - config_set_int(NULL, "window_w", window_w); - config_set_int(NULL, "window_h", window_h); - config_set_int(NULL, "window_x", window_x); - config_set_int(NULL, "window_y", window_y); - config_set_int(NULL, "window_remember", window_remember); +void saveconfig_sound(void) +{ + /* Sound */ + config_set_string("Sound", "sndcard", sound_card_get_internal_name(sound_card_current)); + + config_set_int("Sound", "midi_host_device", midi_id); + + config_set_int("Sound", "gameblaster", GAMEBLASTER); + config_set_int("Sound", "gus", GUS); + config_set_int("Sound", "ssi2001", SSI2001); + config_set_int("Sound", "opl3_type", opl3_type); +} + +void saveconfig_network(void) +{ + /* Network */ + if (pcap_dev != NULL) + { + config_set_string("Network", "net_pcap_device", pcap_dev); + } + else + { + config_set_string("Network", "net_pcap_device", "none"); + } + config_set_int("Network", "net_type", network_type); + config_set_string("Network", "net_card", network_card_get_internal_name(network_card)); +} + +void saveconfig_other_peripherals(void) +{ + int c, d; + + /* Other peripherals */ + config_set_string("Other peripherals", "scsicard", scsi_card_get_internal_name(scsi_card_current)); + + config_set_string("Other peripherals", "hdd_controller", hdd_controller_name); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i", c + 1); + sprintf(temps2, "%i, %02i", !!ide_enable[c], ide_irq[c]); + config_set_string("Other peripherals", temps, temps2); + } + + config_set_int("Other peripherals", "serial1_enabled", serial_enabled[0]); + config_set_int("Other peripherals", "serial2_enabled", serial_enabled[1]); + config_set_int("Other peripherals", "lpt_enabled", lpt_enabled); + config_set_int("Other peripherals", "bugger_enabled", bugger_enabled); +} + +static char *config_bus_to_string(int bus) +{ + switch (bus) + { + case 0: + default: + return "none"; + break; + case 1: + return "mfm"; + break; + case 2: + return "ide_pio_only"; + break; + case 3: + return "ide_pio_and_dma"; + break; + case 4: + return "scsi"; + break; + } +} + +void saveconfig_hard_disks(void) +{ + int c, d; + char *p; + + /* Hard disks */ + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_parameters", c + 1); + memset(s, 0, 512); + p = config_bus_to_string(hdc[c].bus); + sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, p); + config_set_string("Hard disks", temps, temps2); + + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + config_set_int("Hard disks", temps, hdc[c].mfm_channel); + + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + config_set_int("Hard disks", temps, hdc[c].ide_channel); + + sprintf(temps, "hdd_%02i_scsi_location", c + 1); + sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); + config_set_string("Hard disks", temps, temps2); + + sprintf(temps, "hdd_%02i_fn", c + 1); + config_set_wstring("Hard disks", temps, hdd_fn[c]); + } +} + +void saveconfig_removable_devices(void) +{ + int c, d; + + /* Removable devices */ + memset(temps, 0, 512); + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_set_string("Removable devices", temps, fdd_get_internal_name(fdd_get_type(c))); + sprintf(temps, "fdd_%02i_fn", c + 1); + config_set_wstring("Removable devices", temps, discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_set_int("Removable devices", temps, ui_writeprot[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_set_int("Removable devices", temps, cdrom_drives[c].host_drive); + + sprintf(temps, "cdrom_%02i_parameters", c + 1); + sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type)); + config_set_string("Removable devices", temps, temps2); + + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_set_int("Removable devices", temps, cdrom_drives[c].ide_channel); + + sprintf(temps, "cdrom_%02i_scsi_location", c + 1); + sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); + config_set_string("Removable devices", temps, temps2); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + config_set_wstring("Removable devices", temps, cdrom_image[c].image_path); + } +} + +void saveconfig(void) +{ + int c, d; + + /* General */ + saveconfig_general(); + + /* Machine */ + saveconfig_machine(); + + /* Video */ + saveconfig_video(); + + /* Input devices */ + saveconfig_input_devices(); + + /* Sound */ + saveconfig_sound(); + + /* Network */ + saveconfig_network(); + + /* Other peripherals */ + saveconfig_other_peripherals(); + + /* Hard disks */ + saveconfig_hard_disks(); + + /* Removable devices */ + saveconfig_removable_devices(); - config_set_int(NULL, "serial1_enabled", serial_enabled[0]); - config_set_int(NULL, "serial2_enabled", serial_enabled[1]); - config_set_int(NULL, "lpt_enabled", lpt_enabled); - config_set_int(NULL, "bugger_enabled", bugger_enabled); - config_save(config_file_default); } diff --git a/src/device.c b/src/device.c index ec63744d5..5d92699c5 100644 --- a/src/device.c +++ b/src/device.c @@ -131,6 +131,37 @@ int device_get_config_int(char *s) return 0; } +int device_get_config_int_ex(char *s, int default_int) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_int(current_device->name, s, default_int); + + config++; + } + return default_int; +} + +void device_set_config_int(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_int(current_device->name, s, val); + return; + } + + config++; + } + return; +} + char *device_get_config_string(char *s) { device_config_t *config = current_device->config; diff --git a/src/device.h b/src/device.h index fb509ce7f..172c5c69b 100644 --- a/src/device.h +++ b/src/device.h @@ -2,7 +2,7 @@ #define CONFIG_INT 1 #define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 -#define CONFIG_MIDI 4 +#define CONFIG_MAC 4 typedef struct device_config_selection_t { @@ -42,6 +42,8 @@ void device_force_redraw(); char *device_add_status_info(char *s, int max_len); int device_get_config_int(char *name); +int device_get_config_int_ex(char *s, int default_int); +void device_set_config_int(char *s, int val); char *device_get_config_string(char *name); enum diff --git a/src/ibm.h b/src/ibm.h index 44c9c1df6..8b4680fc0 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -560,11 +560,11 @@ typedef struct { int is_hdi; uint32_t base; uint64_t at_spt,at_hpc; /*[Translation] Sectors per track, heads per cylinder*/ - int bus; /* 0 = none, 1 = MFM/RLL, 2 = IDE, 3 = SCSI */ - uint8_t mfm_channel; - uint8_t ide_channel; - uint8_t scsi_id; - uint8_t scsi_lun; + unsigned int bus; /* 0 = none, 1 = MFM/RLL, 2 = IDE, 3 = SCSI */ + unsigned int mfm_channel; + unsigned int ide_channel; + unsigned int scsi_id; + unsigned int scsi_lun; } hard_disk_t; #pragma pack(pop) diff --git a/src/ide.c b/src/ide.c index afcb47778..b2b5a51bc 100644 --- a/src/ide.c +++ b/src/ide.c @@ -132,7 +132,7 @@ int ide_drive_is_cdrom(IDE *ide) } else { - if (cdrom_drives[atapi_cdrom_drives[ide->channel]].enabled && !cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_mode & 1)) + if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type > 0) && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type < 3)) { return 1; } diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 365cd2b75..0a4a66781 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1767,6 +1767,19 @@ nic_rom_init(nic_t *dev, wchar_t *s) } +uint32_t +ne2000_get_maclocal(void) +{ + uint32_t temp; + + temp = (((int) maclocal[3]) << 16); + temp |= (((int) maclocal[4]) << 8); + temp |= ((int) maclocal[5]); + + return(temp); +} + + static void * nic_init(int board) { @@ -1779,44 +1792,50 @@ nic_init(int board) dev->board = board; dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; if (board == NE2K_RTL8029AS) + { strcpy(dev->name, "RTL8029AS"); - else if (board == NE2K_NE1000) + } + else if (board == NE2K_NE1000) + { strcpy(dev->name, "NE1000"); - else + } + else + { strcpy(dev->name, "NE2000"); + } dev->base_irq = device_get_config_int("irq"); dev->disable_netbios = device_get_config_int("disable_netbios"); if (dev->is_rtl8029as) { dev->base_address = 0x340; - mac = config_get_int(NULL, "maclocal_pci", -1); } else { dev->base_address = device_get_config_int("addr"); - mac = config_get_int(NULL, "maclocal", -1); } + mac = device_get_config_int_ex("mac", -1); + /* Set up our MAC address. */ if (dev->is_rtl8029as) { - maclocal_pci[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - maclocal_pci[1] = 0x20; - maclocal_pci[2] = 0x18; - ptr = maclocal_pci; + maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + maclocal[1] = 0x20; + maclocal[2] = 0x18; } else { maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ maclocal[1] = 0x00; maclocal[2] = 0xD8; - ptr = maclocal; } + ptr = maclocal; pclog(1, "MAClocal: mac=%08lx\n", mac); if (mac & 0xff000000) { /* Generating new MAC. */ ptr[3] = disc_random_generate(); ptr[4] = disc_random_generate(); - ptr[5] = disc_random_generate(); + ptr[5] = disc_random_generate() | 1; + device_set_config_int("mac", ne2000_get_maclocal()); } else { ptr[3] = (mac>>16) & 0xff; ptr[4] = (mac>>8) & 0xff; - ptr[5] = mac & 0xff; + ptr[5] = (mac & 0xff) | 1; } memcpy(dev->physaddr, ptr, 6); @@ -1906,32 +1925,6 @@ nic_close(void *priv) } -uint32_t -ne2000_get_maclocal(void) -{ - uint32_t temp; - - temp = (((int) maclocal[3]) << 16); - temp |= (((int) maclocal[4]) << 8); - temp |= ((int) maclocal[5]); - - return(temp); -} - - -uint32_t -ne2000_get_maclocal_pci(void) -{ - uint32_t temp; - - temp = (((int) maclocal_pci[3]) << 16); - temp |= (((int) maclocal_pci[4]) << 8); - temp |= ((int) maclocal_pci[5]); - - return(temp); -} - - static void * ne1000_init(void) { @@ -2012,6 +2005,9 @@ static device_config_t ne1000_config[] = } }, }, + { + "mac", "MAC Address", CONFIG_MAC, "", -1 + }, { "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 }, @@ -2085,6 +2081,9 @@ static device_config_t ne2000_config[] = } }, }, + { + "mac", "MAC Address", CONFIG_MAC, "", -1 + }, { "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 }, @@ -2132,6 +2131,9 @@ static device_config_t rtl8029as_config[] = } }, }, + { + "mac", "MAC Address", CONFIG_MAC, "", -1 + }, { "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 }, diff --git a/src/net_pcap.c b/src/net_pcap.c index f3db05131..459e04c71 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -29,6 +29,34 @@ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ + int netdev_num; + netdev_t netdev_list[512]; + + +#ifdef WALTJE +int pcap_do_log = 1; +# define ENABLE_PCAP_LOG +#else +int pcap_do_log = 0; +#endif + + +static void +pcap_log(const char *format, ...) +{ +#ifdef ENABLE_PCAP_LOG + va_list ap; + + if (pcap_do_log) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#define pclog pcap_log + /* Check if the interface has a packet for us. */ static void @@ -80,6 +108,8 @@ poll_thread(void *arg) } +char pcap_dev[512]; + /* Initialize WinPcap for us. */ int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) @@ -105,12 +135,11 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) pclog("Initializing WinPcap, version %s\n", temp); /* Get the value of our capture interface. */ - dev = config_get_string(NULL, "pcap_device", NULL); - if (dev == NULL) { + if (pcap_dev == NULL) { pclog(" No network device configured!\n"); return(-1); } - pclog(" Network interface: '%s'\n", dev); + pclog(" Network interface: '%s'\n", pcap_dev); pcap = pcap_open_live(dev, /* interface name */ 1518, /* maximum packet size */ @@ -198,10 +227,16 @@ network_devlist(netdev_t *list) pcap_if_t *devlist, *dev; int i = 0; + /* Note by Kotori: Add the first (and guaranteed to be always present) device - "None". */ + strcpy(list->device, "none"); + strcpy(list->description, "None"); + list++; + i++; + /* Retrieve the device list from the local machine */ if (pcap_findalldevs(&devlist, errbuf) == -1) { pclog("NETWORK: error in pcap_findalldevs_ex: %s\n", errbuf); - return(-1); + return(i); /* Note by Kotori: The list will always have at least one entry - "None". */ } for (dev=devlist; dev!=NULL; dev=dev->next) { @@ -219,3 +254,19 @@ network_devlist(netdev_t *list) return(i); } + +int network_dev_to_id(char *dev) +{ + int i = 0; + + for (i = 0; i < netdev_num; i++) + { + if (!strcmp(netdev_list[i].device, dev)) + { + return i; + } + } + + /* If the device does not match the list, consider it as if it was set to "none". */ + return 0; +} \ No newline at end of file diff --git a/src/network.c b/src/network.c index f79f91628..7d1d6e98f 100644 --- a/src/network.c +++ b/src/network.c @@ -215,5 +215,5 @@ network_card_get_from_internal_name(char *s) c++; } - return(0); + return(-1); } diff --git a/src/network.h b/src/network.h index ed971e9b7..965d66f0b 100644 --- a/src/network.h +++ b/src/network.h @@ -45,6 +45,11 @@ typedef struct { extern int network_card; extern int network_type; +extern char pcap_dev[512]; + +extern int netdev_num; +extern netdev_t netdev_list[512]; + /* Function prototypes. */ extern void network_init(void); @@ -70,5 +75,6 @@ extern char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); extern struct device_t *network_card_getdevice(int); + int network_dev_to_id(char *dev); #endif /*NETWORK_H*/ diff --git a/src/pc.c b/src/pc.c index 3dd43745b..9fced90fb 100644 --- a/src/pc.c +++ b/src/pc.c @@ -288,6 +288,9 @@ void initpc(int argc, wchar_t *argv[]) *p=L'\0'; pclog("path = %ws\n", pcempath); + /* Initialize list of PCap devices. */ + netdev_num = network_devlist(netdev_list); + for (c = 1; c < argc; c++) { if (!_wcsicmp(argv[c], L"--help")) diff --git a/src/plat-midi.h b/src/plat-midi.h index f258cdbcb..87ed57306 100644 --- a/src/plat-midi.h +++ b/src/plat-midi.h @@ -6,3 +6,5 @@ void midi_close(); void midi_write(uint8_t val); int midi_get_num_devs(); void midi_get_dev_name(int num, char *s); + +extern int midi_id; diff --git a/src/resource.h b/src/resource.h index bc0d8da03..5364bf674 100644 --- a/src/resource.h +++ b/src/resource.h @@ -11,11 +11,12 @@ #define CONFIGUREDLG_VIDEO 102 #define CONFIGUREDLG_INPUT 103 #define CONFIGUREDLG_SOUND 104 -#define CONFIGUREDLG_PERIPHERALS 105 -#define CONFIGUREDLG_HARD_DISKS 106 -#define CONFIGUREDLG_REMOVABLE_DEVICES 107 -#define ABOUTDLG 108 -#define CONFIGUREDLG_HARD_DISKS_ADD 109 +#define CONFIGUREDLG_NETWORK 105 +#define CONFIGUREDLG_PERIPHERALS 106 +#define CONFIGUREDLG_HARD_DISKS 107 +#define CONFIGUREDLG_REMOVABLE_DEVICES 108 +#define ABOUTDLG 109 +#define CONFIGUREDLG_HARD_DISKS_ADD 110 #define CONFIGUREDLG_MAIN 117 #define IDC_SETTINGSCATLIST 1004 #define IDC_LIST_HARD_DISKS 1005 @@ -77,6 +78,7 @@ #define IDC_COMBO_CD_CHANNEL_IDE 1073 #define IDC_COMBO_CD_ID 1074 #define IDC_COMBO_CD_LUN 1075 +#define IDC_COMBO_MIDI 1076 #define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 #define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 #define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 @@ -228,7 +230,9 @@ #define IDC_COMBO386 1005 #define IDC_COMBO486 1006 #define IDC_COMBOSND 1007 -#define IDC_COMBONET 1008 +#define IDC_COMBONETTYPE 1008 +#define IDC_COMBOPCAP 1009 +#define IDC_COMBONET 1010 #define IDC_COMBOCPUM 1060 #define IDC_COMBOSPD 1061 #define IDC_COMBODR1 1062 @@ -361,8 +365,10 @@ #define IDC_CONFIGURESND 1201 #define IDC_CONFIGUREVOODOO 1202 #define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENET 1204 +#define IDC_CONFIGURENETTYPE 1204 #define IDC_CONFIGUREBUSLOGIC 1205 +#define IDC_CONFIGUREPCAP 1206 +#define IDC_CONFIGURENET 1207 #define IDC_JOY1 1210 #define IDC_JOY2 1211 #define IDC_JOY3 1212 @@ -418,7 +424,7 @@ #ifdef APSTUDIO_INVOKED # ifndef APSTUDIO_READONLY_SYMBOLS # define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 110 +# define _APS_NEXT_RESOURCE_VALUE 111 # define _APS_NEXT_COMMAND_VALUE 40002 # define _APS_NEXT_CONTROL_VALUE 1055 # define _APS_NEXT_SYMED_VALUE 101 diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 067b5dcea..7babc817a 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -1370,9 +1370,7 @@ aha_dev_present(uint8_t id, uint8_t lun) if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); - if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && - cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && - (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) return(1); + if ((cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type == 4)) return(1); return(0); } diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 11a4d3d27..e6631958d 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -1006,9 +1006,7 @@ buslogic_dev_present(uint8_t id, uint8_t lun) if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); - if (cdrom_drives[scsi_cdrom_drives[id][lun]].enabled && - cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type && - (cdrom_drives[scsi_cdrom_drives[id][lun]].bus_mode & 2)) return(1); + if ((cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type == 4)) return(1); return(0); } diff --git a/src/win-deviceconfig.c b/src/win-deviceconfig.c index 6d00a0050..196845359 100644 --- a/src/win-deviceconfig.c +++ b/src/win-deviceconfig.c @@ -9,7 +9,6 @@ #include "ibm.h" #include "config.h" #include "device.h" -#include "plat-midi.h" #include "resource.h" #include "win.h" @@ -60,21 +59,6 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; - - case CONFIG_MIDI: - val_int = config_get_int(NULL, config->name, config->default_int); - - num = midi_get_num_devs(); - for (c = 0; c < num; c++) - { - midi_get_dev_name(c, s); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - if (val_int == c) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - id += 2; - break; } config++; } @@ -120,17 +104,6 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; - - case CONFIG_MIDI: - val_int = config_get_int(NULL, config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (val_int != c) - changed = 1; - - id += 2; - break; } config++; } @@ -171,13 +144,6 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; - - case CONFIG_MIDI: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - config_set_int(NULL, config->name, c); - - id += 2; - break; } config++; } @@ -254,7 +220,6 @@ void deviceconfig_open(HWND hwnd, device_t *device) break; case CONFIG_SELECTION: - case CONFIG_MIDI: /*Combo box*/ item = (DLGITEMTEMPLATE *)data; item->x = 70; diff --git a/src/win-language.c b/src/win-language.c index a2820beb8..c2525db48 100644 --- a/src/win-language.c +++ b/src/win-language.c @@ -21,7 +21,7 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -#define STRINGS_NUM 152 +#define STRINGS_NUM 154 WCHAR lpResourceString[STRINGS_NUM][512]; diff --git a/src/win-language.h b/src/win-language.h index 113c16f44..5c4237249 100644 --- a/src/win-language.h +++ b/src/win-language.h @@ -2,6 +2,8 @@ extern "C" { #endif +LCID dwLanguage; + int msgbox_reset(HWND hwndParent); int msgbox_reset_yn(HWND hwndParent); int msgbox_question(HWND hwndParent, int i); diff --git a/src/win-midi.c b/src/win-midi.c index 621510ab2..a11c7bfea 100644 --- a/src/win-midi.c +++ b/src/win-midi.c @@ -7,34 +7,65 @@ #include "config.h" #include "plat-midi.h" -static int midi_id; +int midi_id; static HMIDIOUT midi_out_device = NULL; HANDLE m_event; void midi_close(); +static uint8_t midi_rt_buf[1024]; +static uint8_t midi_cmd_buf[1024]; +static int midi_cmd_pos = 0; +static int midi_cmd_len = 0; +static uint8_t midi_status = 0; +static unsigned int midi_sysex_start = 0; +static unsigned int midi_sysex_delay = 0; + +uint8_t MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 +}; + void midi_init() { MMRESULT hr = MMSYSERR_NOERROR; - + + memset(midi_rt_buf, 0, 1024); + memset(midi_cmd_buf, 0, 1024); + + midi_cmd_pos = midi_cmd_len = 0; + midi_status = 0; + + midi_sysex_start = midi_sysex_delay = 0; + midi_id = config_get_int(NULL, "midi", 0); m_event = CreateEvent(NULL, TRUE, TRUE, NULL); -#if 0 - hr = midiOutOpen(&midi_out_device, midi_id, 0, - 0, CALLBACK_NULL); -#endif hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, 0, CALLBACK_EVENT); if (hr != MMSYSERR_NOERROR) { printf("midiOutOpen error - %08X\n",hr); midi_id = 0; -#if 0 - hr = midiOutOpen(&midi_out_device, midi_id, 0, - 0, CALLBACK_NULL); -#endif hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, 0, CALLBACK_EVENT); if (hr != MMSYSERR_NOERROR) { @@ -82,82 +113,13 @@ static void midi_send_sysex() hdr.lpData = midi_sysex_data; hdr.dwBufferLength = midi_pos; hdr.dwFlags = 0; - -/* pclog("Sending sysex : "); - for (c = 0; c < midi_pos; c++) - pclog("%02x ", midi_sysex_data[c]); - pclog("\n");*/ - + midiOutPrepareHeader(midi_out_device, &hdr, sizeof(MIDIHDR)); midiOutLongMsg(midi_out_device, &hdr, sizeof(MIDIHDR)); - + midi_insysex = 0; } -#if 0 -void midi_write(uint8_t val) -{ - if ((val & 0x80) && !(val == 0xf7 && midi_insysex)) - { - midi_pos = 0; - midi_len = midi_lengths[(val >> 4) & 7]; - midi_command = 0; - if (val == 0xf0) - midi_insysex = 1; - } - - if (midi_insysex) - { - midi_sysex_data[midi_pos++] = val; - - if (val == 0xf7 || midi_pos >= 1024+2) - midi_send_sysex(); - return; - } - - if (midi_len) - { - midi_command |= (val << (midi_pos * 8)); - - midi_pos++; - - if (midi_pos == midi_len) - midiOutShortMsg(midi_out_device, midi_command); - } -} -#endif - -static uint8_t midi_rt_buf[1024] = { 0, 0, 0, 0 }; -static uint8_t midi_cmd_buf[1024] = { 0, 0, 0, 0 }; -static int midi_cmd_pos = 0; -static int midi_cmd_len = 0; -static uint8_t midi_status = 0; -static int midi_sysex_start = 0; -static int midi_sysex_delay = 0; - -uint8_t MIDI_evt_len[256] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 - - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 -}; - void PlayMsg(uint8_t *msg) { midiOutShortMsg(midi_out_device, *(uint32_t *) msg); @@ -197,12 +159,19 @@ void PlaySysex(uint8_t *sysex, unsigned int len) #define SYSEX_SIZE 1024 #define RAWBUF 1024 -int GetTicks() -{ -} - void midi_write(uint8_t val) { + uint32_t passed_ticks; + + if (midi_sysex_start) + { + passed_ticks = GetTickCount() - midi_sysex_start; + if (passed_ticks < midi_sysex_delay) + { + Sleep(midi_sysex_delay - passed_ticks); + } + } + /* Test for a realtime MIDI message */ if (val >= 0xf8) { @@ -248,7 +217,7 @@ void midi_write(uint8_t val) else midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; - midi_sysex_start = GetTicks(); + midi_sysex_start = GetTickCount(); } } } diff --git a/src/win-settings.c b/src/win-settings.c index 8567391d1..308477b70 100644 --- a/src/win-settings.c +++ b/src/win-settings.c @@ -23,6 +23,7 @@ #include "scsi.h" #include "scsi_buslogic.h" #include "network.h" +#include "plat-midi.h" #include "sound/sound.h" #include "sound/snd_dbopl.h" #include "video/video.h" @@ -47,10 +48,14 @@ int temp_gfxcard, temp_video_speed, temp_voodoo; int temp_mouse, temp_joystick; /* Sound category */ -int temp_sound_card, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; +int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; + +/* Network category */ +int temp_net_type, temp_net_card; +char temp_pcap_dev[520]; /* Peripherals category */ -int temp_scsi_card, temp_net_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; +int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; int temp_serial[2], temp_lpt, temp_bugger; char temp_hdc_name[16]; @@ -102,14 +107,20 @@ static void win_settings_init() /* Sound category */ temp_sound_card = sound_card_current; + temp_midi_id = midi_id; temp_SSI2001 = SSI2001; temp_GAMEBLASTER = GAMEBLASTER; temp_GUS = GUS; temp_opl3_type = opl3_type; + /* Network category */ + temp_net_type = network_type; + memset(temp_pcap_dev, 0, 520); + strcpy(temp_pcap_dev, pcap_dev); + temp_net_card = network_card; + /* Peripherals category */ temp_scsi_card = scsi_card_current; - temp_net_card = network_card; strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); temp_ide_ter = ide_enable[2]; temp_ide_ter_irq = ide_irq[2]; @@ -161,14 +172,19 @@ static int win_settings_changed() /* Sound category */ i = i || (sound_card_current != temp_sound_card); + i = i || (midi_id != temp_midi_id); i = i || (SSI2001 != temp_SSI2001); i = i || (GAMEBLASTER != temp_GAMEBLASTER); i = i || (GUS != temp_GUS); i = i || (opl3_type != temp_opl3_type); + /* Network category */ + i = i || (network_type != temp_net_type); + i = i || strcmp(temp_pcap_dev, pcap_dev); + i = i || (network_card != temp_net_card); + /* Peripherals category */ i = i || (scsi_card_current != temp_scsi_card); - i = i || (network_card != temp_net_card); i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); i = i || (temp_ide_ter != ide_enable[2]); i = i || (temp_ide_ter_irq != ide_irq[2]); @@ -252,14 +268,20 @@ static void win_settings_save() /* Sound category */ sound_card_current = temp_sound_card; + midi_id = temp_midi_id; SSI2001 = temp_SSI2001; GAMEBLASTER = temp_GAMEBLASTER; GUS = temp_GUS; opl3_type = temp_opl3_type; + /* Network category */ + network_type = temp_net_type; + memset(pcap_dev, 0, 512); + strcpy(pcap_dev, temp_pcap_dev); + network_card = temp_net_card; + /* Peripherals category */ scsi_card_current = temp_scsi_card; - network_card = temp_net_card; strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); ide_enable[2] = temp_ide_ter; ide_irq[2] = temp_ide_ter_irq; @@ -1061,6 +1083,8 @@ int find_irq_in_array(int irq, int def) return 7 + def; } +static char midi_dev_name_buf[512]; + static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; @@ -1068,6 +1092,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa int d = 0; LPTSTR lptsTemp; device_t *sound_dev; + int num = 0; switch (message) { @@ -1121,6 +1146,18 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa EnableWindow(h, FALSE); } + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + num = midi_get_num_devs(); + for (c = 0; c < num; c++) + { + memset(midi_dev_name_buf, 0, 512); + midi_get_dev_name(c, midi_dev_name_buf); + mbstowcs(lptsTemp, midi_dev_name_buf, strlen(midi_dev_name_buf) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + if (c == temp_midi_id) + SendMessage(h, CB_SETCURSEL, c, 0); + } + h=GetDlgItem(hdlg, IDC_CHECKCMS); SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); @@ -1168,6 +1205,9 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_COMBOSND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECKCMS); temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); @@ -1199,7 +1239,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR case WM_INITDIALOG: lptsTemp = (LPTSTR) malloc(512); - /*NIC config*/ + /*SCSI config*/ h = GetDlgItem(hdlg, IDC_COMBO_SCSI); c = d = 0; while (1) @@ -1249,49 +1289,6 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR recalc_hdd_list(hdlg, temp_model, 0); - /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBONET); - c = d = 0; - while (1) - { - char *s = network_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_network_to_list[c] = d; - - if (network_card_available(c)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_network[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURENET); - if (network_card_has_config(temp_net_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); @@ -1347,28 +1344,6 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR case WM_COMMAND: switch (LOWORD(wParam)) { - case IDC_CONFIGURENET: - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); - break; - - case IDC_COMBONET: - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURENET); - if (network_card_has_config(temp_net_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; - case IDC_CONFIGURE_SCSI: h = GetDlgItem(hdlg, IDC_COMBO_SCSI); temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -1415,9 +1390,6 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR h = GetDlgItem(hdlg, IDC_COMBO_SCSI); temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER); temp_ide_ter = SendMessage(h, CB_GETCURSEL, 0, 0); if (temp_ide_ter > 1) @@ -1452,6 +1424,203 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR return FALSE; } +int net_ignore_message = 0; + +static void network_recalc_combos(HWND hdlg) +{ + HWND h; + + net_ignore_message = 1; + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + if (temp_net_type == 1) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + if (temp_net_type == 0) + { + EnableWindow(h, TRUE); + } + else if ((temp_net_type == 1) && (network_dev_to_id(temp_pcap_dev) > 0)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_CONFIGURENET); + if (network_card_has_config(temp_net_card) && (temp_net_type == 0)) + { + EnableWindow(h, TRUE); + } + else if (network_card_has_config(temp_net_card) && (temp_net_type == 1) && (network_dev_to_id(temp_pcap_dev) > 0)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + net_ignore_message = 0; +} + +static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *scsi_dev; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); + SendMessage(h, CB_SETCURSEL, temp_net_type + 1, 0); + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + if (temp_net_type == 0) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + for (c = 0; c < netdev_num; c++) + { + mbstowcs(lptsTemp, netdev_list[c].description, strlen(netdev_list[c].description) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); + + /*NIC config*/ + h = GetDlgItem(hdlg, IDC_COMBONET); + c = d = 0; + while (1) + { + char *s = network_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_network_to_list[c] = d; + + if (network_card_available(c)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_network[d] = c; + d++; + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); + + network_recalc_combos(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBONETTYPE: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; + + network_recalc_combos(hdlg); + break; + + case IDC_COMBOPCAP: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + memset(temp_pcap_dev, 0, 520); + strcpy(temp_pcap_dev, netdev_list[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBONET: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + network_recalc_combos(hdlg); + break; + + case IDC_CONFIGURENET: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + memset(temp_pcap_dev, 0, 520); + strcpy(temp_pcap_dev, netdev_list[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + default: + return FALSE; + } + + return FALSE; +} + static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) { HICON hiconItem; @@ -2687,32 +2856,6 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA int fdlv_current_sel; int cdlv_current_sel; -static void combo_id_to_bus(int combo_id) -{ - switch (combo_id) - { - case 0: /* Disabled */ - default: - temp_cdrom_drives[cdlv_current_sel].enabled = 0; - break; - case 1: /* Atapi (PIO-only) */ - temp_cdrom_drives[cdlv_current_sel].enabled = 1; - temp_cdrom_drives[cdlv_current_sel].bus_type = 0; - temp_cdrom_drives[cdlv_current_sel].atapi_dma = 0; - break; - case 2: /* Atapi (PIA and DMA) */ - temp_cdrom_drives[cdlv_current_sel].enabled = 1; - temp_cdrom_drives[cdlv_current_sel].bus_type = 0; - temp_cdrom_drives[cdlv_current_sel].atapi_dma = 1; - break; - case 3: /* SCSI */ - temp_cdrom_drives[cdlv_current_sel].enabled = 1; - temp_cdrom_drives[cdlv_current_sel].bus_type = 1; - temp_cdrom_drives[cdlv_current_sel].atapi_dma = 0; - break; - } -} - static int combo_id_to_string_id(int combo_id) { switch (combo_id) @@ -2721,13 +2864,13 @@ static int combo_id_to_string_id(int combo_id) default: return 2151; break; - case 1: /* Atapi (PIO-only) */ + case 2: /* Atapi (PIO-only) */ return 2189; break; - case 2: /* Atapi (PIA and DMA) */ + case 3: /* Atapi (PIA and DMA) */ return 2190; break; - case 3: /* SCSI */ + case 4: /* SCSI */ return 2168; break; } @@ -2741,46 +2884,18 @@ static int combo_id_to_format_string_id(int combo_id) default: return 2151; break; - case 1: /* Atapi (PIO-only) */ + case 2: /* Atapi (PIO-only) */ return 2191; break; - case 2: /* Atapi (PIA and DMA) */ + case 3: /* Atapi (PIA and DMA) */ return 2192; break; - case 3: /* SCSI */ + case 4: /* SCSI */ return 2158; break; } } -static int bus_to_combo_id(int id) -{ - if (temp_cdrom_drives[id].enabled) - { - if (temp_cdrom_drives[id].bus_type) - { - return 3; - } - else - { - if (temp_cdrom_drives[id].atapi_dma) - { - return 2; - } - else - { - return 1; - } - } - } - else - { - return 0; - } - - return 0; -} - static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) { HICON hiconItem; @@ -2883,28 +2998,35 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) for (i = 0; i < 4; i++) { - bid = bus_to_combo_id(i); - fsid = combo_id_to_format_string_id(bid); + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - switch (bid) + switch (temp_cdrom_drives[i].bus_type) { case 0: default: lvI.pszText = win_language_get_string_from_id(fsid); break; - case 1: case 2: + case 3: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); lvI.pszText = szText; break; - case 3: + case 4: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); lvI.pszText = szText; break; } lvI.iItem = i; - lvI.iImage = bid; + + if (temp_cdrom_drives[i].bus_type) + { + lvI.iImage = temp_cdrom_drives[i].bus_type - 1; + } + else + { + lvI.iImage = 0; + } if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; @@ -3035,27 +3157,33 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) lvI.iSubItem = 0; lvI.iItem = i; - bid = bus_to_combo_id(i); - fsid = combo_id_to_format_string_id(bid); + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - switch (bid) + switch (temp_cdrom_drives[i].bus_type) { case 0: default: lvI.pszText = win_language_get_string_from_id(fsid); break; - case 1: case 2: + case 3: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); lvI.pszText = szText; break; - case 3: + case 4: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); lvI.pszText = szText; break; } - lvI.iImage = bid; + if (temp_cdrom_drives[i].bus_type) + { + lvI.iImage = temp_cdrom_drives[i].bus_type - 1; + } + else + { + lvI.iImage = 0; + } if (ListView_SetItem(hwndList, &lvI) == -1) { @@ -3072,7 +3200,7 @@ static void cdrom_add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = 0; i < 4; i++) + for (i = 1; i < 5; i++) { SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); } @@ -3105,7 +3233,7 @@ static void cdrom_recalc_location_controls(HWND hdlg) int i = 0; HWND h; - int bus = bus_to_combo_id(cdlv_current_sel); + int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; for (i = 1800; i < 1803; i++) { @@ -3128,8 +3256,8 @@ static void cdrom_recalc_location_controls(HWND hdlg) switch(bus) { - case 1: /* ATAPI (PIO-only) */ - case 2: /* ATAPI (PIO and DMA) */ + case 2: /* ATAPI (PIO-only) */ + case 3: /* ATAPI (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3139,7 +3267,7 @@ static void cdrom_recalc_location_controls(HWND hdlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); break; - case 3: /* SCSI */ + case 4: /* SCSI */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3205,7 +3333,14 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); cdrom_add_locations(hdlg); h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - SendMessage(h, CB_SETCURSEL, bus_to_combo_id(cdlv_current_sel), 0); + if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + { + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } cdrom_recalc_location_controls(hdlg); rd_ignore_change = 0; @@ -3256,7 +3391,14 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message } rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - SendMessage(h, CB_SETCURSEL, bus_to_combo_id(cdlv_current_sel), 0); + if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + { + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } cdrom_recalc_location_controls(hdlg); rd_ignore_change = 0; } @@ -3287,8 +3429,11 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - cid = SendMessage(h, CB_GETCURSEL, 0, 0); - combo_id_to_bus(cid); + temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) + { + temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + } cdrom_recalc_location_controls(hdlg); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); @@ -3375,12 +3520,15 @@ void win_settings_show_child(HWND hwndParent, DWORD child_id) hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); break; case 4: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); break; case 5: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); break; case 6: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + break; + case 7: hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); break; default: @@ -3402,7 +3550,7 @@ static BOOL win_settings_main_image_list_init(HWND hwndList) GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); - for (i = 0; i < 7; i++) + for (i = 0; i < 8; i++) { hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + i)); ImageList_AddIcon(hSmall, hiconItem); @@ -3422,7 +3570,7 @@ static BOOL win_settings_main_insert_categories(HWND hwndList) lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; lvI.stateMask = lvI.iSubItem = lvI.state = 0; - for (i = 0; i < 7; i++) + for (i = 0; i < 8; i++) { lvI.pszText = win_language_get_settings_category(i); lvI.iItem = i; @@ -3465,7 +3613,7 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) { category = -1; - for (i = 0; i < 7; i++) + for (i = 0; i < 8; i++) { h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); j = ListView_GetItemState(h, i, LVIS_SELECTED); diff --git a/src/win.c b/src/win.c index 354ba252e..4aacef80f 100644 --- a/src/win.c +++ b/src/win.c @@ -941,7 +941,7 @@ void update_status_bar_panes(HWND hwnds) } for (i = 0; i < 4; i++) { - if (cdrom_drives[i].enabled != 0) + if (cdrom_drives[i].bus_type != 0) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; @@ -1015,13 +1015,17 @@ void update_status_bar_panes(HWND hwnds) sb_icon_flags[i] = 0; } } - if (cdrom_drives[id].bus_type == 1) + if (cdrom_drives[id].bus_type == 4) { j = 164; } + else if (cdrom_drives[id].bus_type == 3) + { + j = 162; + } else { - j = (cdrom_drives[id].atapi_dma) ? 162 : 160; + j = 160; } sb_part_icons[i] = j | sb_icon_flags[i]; create_cdrom_tip(i); @@ -1606,7 +1610,7 @@ void win_cdrom_eject(uint8_t id) cdrom_drives[id].handler->exit(id); cdrom_close(id); cdrom_null_open(id, 0); - if (cdrom_drives[id].enabled) + if (cdrom_drives[id].bus_type) { /* Signal disc change to the emulated machine. */ cdrom_insert(id); @@ -1638,7 +1642,7 @@ void win_cdrom_reload(uint8_t id) if (cdrom_drives[id].prev_host_drive == 200) { image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].enabled) + if (cdrom_drives[id].bus_type) { /* Signal disc change to the emulated machine. */ cdrom_insert(id); @@ -1651,7 +1655,7 @@ void win_cdrom_reload(uint8_t id) { new_cdrom_drive = cdrom_drives[id].prev_host_drive; ioctl_open(id, new_cdrom_drive); - if (cdrom_drives[id].enabled) + if (cdrom_drives[id].bus_type) { /* Signal disc change to the emulated machine. */ cdrom_insert(id); @@ -2347,7 +2351,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR cdrom_drives[cdrom_id].handler->exit(cdrom_id); cdrom_close(cdrom_id); image_open(cdrom_id, temp_image_path); - if (cdrom_drives[cdrom_id].enabled) + if (cdrom_drives[cdrom_id].bus_type) { /* Signal disc change to the emulated machine. */ cdrom_insert(cdrom_id); @@ -2381,7 +2385,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR cdrom_drives[cdrom_id].handler->exit(cdrom_id); cdrom_close(cdrom_id); ioctl_open(cdrom_id, new_cdrom_drive); - if (cdrom_drives[cdrom_id].enabled) + if (cdrom_drives[cdrom_id].bus_type) { /* Signal disc change to the emulated machine. */ cdrom_insert(cdrom_id); From 1b83ee8fd3151ce96106a5d2f71f8eb9044fb2ad Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 17 May 2017 21:57:12 +0200 Subject: [PATCH 222/392] Split off the Network configuration from Other peripherals in the Settings dialog and made PCap device configurable; Overhauled the configuration files so that the global variables are now subdivided into sections; Fixed CD-ROM MODE SENSE page 0x2A which was being incorrectly reported as not implemented, fixes among other things Rayman 1 and Spellcross: The Last Battle (both now see the CD-ROM and play CD Audio fine). --- src/net_slirp.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/net_slirp.c b/src/net_slirp.c index 43574eccf..8e3056e9a 100644 --- a/src/net_slirp.c +++ b/src/net_slirp.c @@ -29,7 +29,31 @@ static queueADT slirpq; /* SLiRP library handle */ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ -static int fizz; + + +#ifdef WALTJE +int slirp_do_log = 1; +# define ENABLE_SLIRP_LOG +#else +int slirp_do_log = 0; +#endif + + +static void +slirp_log(const char *format, ...) +{ +#ifdef ENABLE_SLIRP_LOG + va_list ap; + + if (slirp_do_log) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#define pclog slirp_log /* Instead of calling this and crashing some times @@ -77,10 +101,7 @@ poll_thread(void *arg) pclog("SLiRP: poll event is %08lx\n", evt); while (slirpq != NULL) { - if (++fizz > 1200) { - fizz = 0; - slirp_tic(); - } + slirp_tic(); /* Wait for the next packet to arrive. */ if (QueuePeek(slirpq) == 0) { @@ -124,8 +145,6 @@ network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) slirpq = QueueCreate(); pclog(" Packet queue is at %08lx\n", &slirpq); - fizz = 0; - /* Save the callback info. */ poll_rx = func; poll_arg = arg; From a2aa29ced0ed4793f0c70e72be622e45dbbd5710 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 17 May 2017 22:07:20 +0200 Subject: [PATCH 223/392] Revert "Split off the Network configuration from Other peripherals in the Settings dialog and made PCap device configurable;" This reverts commit 1b83ee8fd3151ce96106a5d2f71f8eb9044fb2ad. --- src/net_slirp.c | 33 +++++++-------------------------- 1 file changed, 7 insertions(+), 26 deletions(-) diff --git a/src/net_slirp.c b/src/net_slirp.c index 8e3056e9a..43574eccf 100644 --- a/src/net_slirp.c +++ b/src/net_slirp.c @@ -29,31 +29,7 @@ static queueADT slirpq; /* SLiRP library handle */ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ - - -#ifdef WALTJE -int slirp_do_log = 1; -# define ENABLE_SLIRP_LOG -#else -int slirp_do_log = 0; -#endif - - -static void -slirp_log(const char *format, ...) -{ -#ifdef ENABLE_SLIRP_LOG - va_list ap; - - if (slirp_do_log) { - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} -#define pclog slirp_log +static int fizz; /* Instead of calling this and crashing some times @@ -101,7 +77,10 @@ poll_thread(void *arg) pclog("SLiRP: poll event is %08lx\n", evt); while (slirpq != NULL) { - slirp_tic(); + if (++fizz > 1200) { + fizz = 0; + slirp_tic(); + } /* Wait for the next packet to arrive. */ if (QueuePeek(slirpq) == 0) { @@ -145,6 +124,8 @@ network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) slirpq = QueueCreate(); pclog(" Packet queue is at %08lx\n", &slirpq); + fizz = 0; + /* Save the callback info. */ poll_rx = func; poll_arg = arg; From 69ec4f2193f93fbd2454521699dfdaed68c4ec43 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 00:16:04 +0200 Subject: [PATCH 224/392] Fixed IDE CD-ROM detection, fixes ATAPI PIO and DMA CD-ROM's. --- src/ide.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ide.c b/src/ide.c index b2b5a51bc..18db7d4d6 100644 --- a/src/ide.c +++ b/src/ide.c @@ -132,7 +132,7 @@ int ide_drive_is_cdrom(IDE *ide) } else { - if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type > 0) && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type < 3)) + if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type > 1) && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type < 4)) { return 1; } From 3392a0cb34a9ffa08ed34fc94a61b8daf029b51c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 00:39:59 +0200 Subject: [PATCH 225/392] Window coordinates are now read from the correct configuration file variable. --- src/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index d4e47b727..a05f141f7 100644 --- a/src/config.c +++ b/src/config.c @@ -613,7 +613,7 @@ void loadconfig_general(void) scale = !!config_get_int("General", "scale", 1); enable_overscan = !!config_get_int("General", "enable_overscan", 0); - p = config_get_string("General", "window_w_coordinates", "0, 0, 0, 0"); + p = config_get_string("General", "window_coordinates", "0, 0, 0, 0"); if (p) { sscanf(temps, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); From 0d95385e509330e8244bfeab05d5b1c3f056595d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 00:58:35 +0200 Subject: [PATCH 226/392] More fixes regarding window coordinate saving. --- src/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index a05f141f7..8796c7061 100644 --- a/src/config.c +++ b/src/config.c @@ -616,11 +616,11 @@ void loadconfig_general(void) p = config_get_string("General", "window_coordinates", "0, 0, 0, 0"); if (p) { - sscanf(temps, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); + sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); } else { - sscanf(temps, "0, 0, 0, 0", &window_w, &window_h, &window_x, &window_y); + sscanf("0, 0, 0, 0", "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); } window_remember = config_get_int("General", "window_remember", 0); From 52bf938a6096ed43108048fd180a4fad473304a8 Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Wed, 17 May 2017 23:14:07 -0500 Subject: [PATCH 227/392] Fix a bunch of Voodoo warnings --- src/VIDEO/vid_voodoo.c | 11 ++++++----- src/VIDEO/vid_voodoo_codegen_x86-64.h | 26 +++++++++++++------------- src/VIDEO/vid_voodoo_codegen_x86.h | 26 +++++++++++++------------- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/VIDEO/vid_voodoo.c b/src/VIDEO/vid_voodoo.c index 57bb0084a..38d789a87 100644 --- a/src/VIDEO/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -1,5 +1,6 @@ #include #include +#include #include "../ibm.h" #include "../cpu/cpu.h" #include "../mem.h" @@ -1551,7 +1552,7 @@ typedef struct voodoo_state_t int32_t ib, ig, ir, ia; int32_t z; - int32_t new_depth; + int64_t new_depth; int64_t tmu0_s, tmu0_t; int64_t tmu0_w; @@ -1562,7 +1563,7 @@ typedef struct voodoo_state_t int pixel_count, texel_count; int x, x2; - uint32_t w_depth; + uint64_t w_depth; float log_temp; uint32_t ebp_store; @@ -2719,7 +2720,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood uint16_t dat; uint16_t aux_dat; int sel; - int32_t new_depth, w_depth; + int64_t new_depth, w_depth; if (state->w & 0xffff00000000) w_depth = 0; @@ -5255,7 +5256,7 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; - int32_t w_depth = new_depth; + int64_t w_depth = new_depth; int32_t ia = alpha_data << 12; APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); @@ -5390,7 +5391,7 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; - int32_t w_depth = new_depth; + int64_t w_depth = new_depth; int32_t ia = alpha_data[c] << 12; APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); diff --git a/src/VIDEO/vid_voodoo_codegen_x86-64.h b/src/VIDEO/vid_voodoo_codegen_x86-64.h index 855830a78..1caa67311 100644 --- a/src/VIDEO/vid_voodoo_codegen_x86-64.h +++ b/src/VIDEO/vid_voodoo_codegen_x86-64.h @@ -42,26 +42,26 @@ static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; #define addbyte(val) \ - code_block[block_pos++] = val; \ + code_block[block_pos++] = (uint8_t)val; \ if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ +#define addword(val) \ + *(uint16_t *)&code_block[block_pos] = (uint16_t)val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ +#define addlong(val) \ + *(uint32_t *)&code_block[block_pos] = (uint32_t)val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ +#define addquad(val) \ + *(uint64_t *)&code_block[block_pos] = (uint64_t)val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") diff --git a/src/VIDEO/vid_voodoo_codegen_x86.h b/src/VIDEO/vid_voodoo_codegen_x86.h index fd3d09587..54c09a1bc 100644 --- a/src/VIDEO/vid_voodoo_codegen_x86.h +++ b/src/VIDEO/vid_voodoo_codegen_x86.h @@ -40,26 +40,26 @@ static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; #define addbyte(val) \ - code_block[block_pos++] = val; \ + code_block[block_pos++] = (uint8_t)val; \ if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ +#define addword(val) \ + *(uint16_t *)&code_block[block_pos] = (uint16_t)val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ +#define addlong(val) \ + *(uint32_t *)&code_block[block_pos] = (uint32_t)val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ +#define addquad(val) \ + *(uint64_t *)&code_block[block_pos] = (uint64_t)val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") From 09ca09775c4d03b0223b298c272cd985cac60df4 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 18 May 2017 01:57:16 -0400 Subject: [PATCH 228/392] Cleanup of the configuration code, and source tree layout. --- src/86Box.manifest | 22 - src/86Box.rc | 941 -------- src/Makefile.mingw | 32 +- src/SOUND/snd_mpu401.c | 2 +- src/SOUND/snd_sb_dsp.c | 2 +- src/VIDEO/vid_cga.c | 2 +- src/VIDEO/vid_hercules.c | 2 +- src/VIDEO/vid_mda.c | 2 +- src/VIDEO/video.c | 2 +- src/cdrom-dosbox.cpp | 565 ----- src/cdrom-dosbox.h | 173 -- src/cdrom-image.cc | 1045 -------- src/cdrom-image.h | 28 - src/cdrom-ioctl-linux.c | 725 ------ src/cdrom-ioctl.c | 1099 --------- src/cdrom-ioctl.h | 17 - src/cdrom-null.c | 130 - src/cdrom-null.h | 14 - src/config.c | 515 ++-- src/config.h | 50 +- src/gameport.c | 2 +- src/joystick_ch_flightstick_pro.c | 3 +- src/joystick_standard.c | 3 +- src/joystick_sw_pad.c | 3 +- src/joystick_tm_fcs.c | 3 +- src/keyboard.c | 2 +- src/mouse_bus.c | 4 +- src/mouse_ps2.c | 3 +- src/net_ne2000.c | 64 +- src/net_ne2000.h | 9 +- src/net_pcap.c | 40 +- src/net_slirp.c | 27 +- src/network.c | 48 +- src/network.h | 20 +- src/pc.c | 22 +- src/pcap_if.rc | 52 - src/plat-dinput.h | 4 - src/plat-dir.h | 76 - src/plat-joystick.h | 69 - src/plat-keyboard.h | 22 - src/plat-midi.h | 10 - src/plat-mouse.h | 16 - src/plat-serial.h | 49 - src/ppi.c | 5 +- src/resource.h | 432 ---- src/serial.c | 4 +- src/win-cgapal.h | 13 - src/win-crashdump.c | 185 -- src/win-crashdump.h | 7 - src/win-d3d-fs.cc | 587 ----- src/win-d3d-fs.h | 13 - src/win-d3d.cc | 397 ---- src/win-d3d.h | 13 - src/win-ddraw-fs.cc | 338 --- src/win-ddraw-fs.h | 11 - src/win-ddraw-screenshot.cc | 178 -- src/win-ddraw-screenshot.h | 4 - src/win-ddraw.cc | 318 --- src/win-ddraw.h | 12 - src/win-deviceconfig.c | 317 --- src/win-joystick.cc | 281 --- src/win-joystickconfig.c | 541 ----- src/win-language.c | 197 -- src/win-language.h | 33 - src/win-midi.c | 279 --- src/win-mouse.cc | 75 - src/win-opendir.c | 213 -- src/win-serial.c | 606 ----- src/win-settings.c | 3674 ----------------------------- src/win-status.c | 95 - src/win-video.c | 57 - src/win.c | 2427 ------------------- src/win.h | 51 - 73 files changed, 472 insertions(+), 16810 deletions(-) delete mode 100644 src/86Box.manifest delete mode 100644 src/86Box.rc delete mode 100644 src/cdrom-dosbox.cpp delete mode 100644 src/cdrom-dosbox.h delete mode 100644 src/cdrom-image.cc delete mode 100644 src/cdrom-image.h delete mode 100644 src/cdrom-ioctl-linux.c delete mode 100644 src/cdrom-ioctl.c delete mode 100644 src/cdrom-ioctl.h delete mode 100644 src/cdrom-null.c delete mode 100644 src/cdrom-null.h delete mode 100644 src/pcap_if.rc delete mode 100644 src/plat-dinput.h delete mode 100644 src/plat-dir.h delete mode 100644 src/plat-joystick.h delete mode 100644 src/plat-keyboard.h delete mode 100644 src/plat-midi.h delete mode 100644 src/plat-mouse.h delete mode 100644 src/plat-serial.h delete mode 100644 src/resource.h delete mode 100644 src/win-cgapal.h delete mode 100644 src/win-crashdump.c delete mode 100644 src/win-crashdump.h delete mode 100644 src/win-d3d-fs.cc delete mode 100644 src/win-d3d-fs.h delete mode 100644 src/win-d3d.cc delete mode 100644 src/win-d3d.h delete mode 100644 src/win-ddraw-fs.cc delete mode 100644 src/win-ddraw-fs.h delete mode 100644 src/win-ddraw-screenshot.cc delete mode 100644 src/win-ddraw-screenshot.h delete mode 100644 src/win-ddraw.cc delete mode 100644 src/win-ddraw.h delete mode 100644 src/win-deviceconfig.c delete mode 100644 src/win-joystick.cc delete mode 100644 src/win-joystickconfig.c delete mode 100644 src/win-language.c delete mode 100644 src/win-language.h delete mode 100644 src/win-midi.c delete mode 100644 src/win-mouse.cc delete mode 100644 src/win-opendir.c delete mode 100644 src/win-serial.c delete mode 100644 src/win-settings.c delete mode 100644 src/win-status.c delete mode 100644 src/win-video.c delete mode 100644 src/win.c delete mode 100644 src/win.h diff --git a/src/86Box.manifest b/src/86Box.manifest deleted file mode 100644 index be8c16756..000000000 --- a/src/86Box.manifest +++ /dev/null @@ -1,22 +0,0 @@ - - - -Emulator for X86-based systems. - - - - - - diff --git a/src/86Box.rc b/src/86Box.rc deleted file mode 100644 index fb5d56296..000000000 --- a/src/86Box.rc +++ /dev/null @@ -1,941 +0,0 @@ -#include - -//Microsoft Developer Studio generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#define APSTUDIO_HIDDEN_SYMBOLS -#include "windows.h" -#undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Menu -// - -STATUSBARMENU MENU DISCARDABLE -BEGIN - POPUP "FDD 1" - BEGIN - MENUITEM "&Change...", IDM_DISC_1 - MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP - MENUITEM "&Eject FDD 1", IDM_EJECT_1 - END - POPUP "FDD 2" - BEGIN - MENUITEM "&Change...", IDM_DISC_2 - MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP - MENUITEM "&Eject FDD 2", IDM_EJECT_2 - END - POPUP "FDD 3" - BEGIN - MENUITEM "&Change...", IDM_DISC_3 - MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP - MENUITEM "&Eject FDD 3", IDM_EJECT_3 - END - POPUP "FDD 4" - BEGIN - MENUITEM "&Change...", IDM_DISC_4 - MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP - MENUITEM "&Eject FDD 4", IDM_EJECT_4 - END - POPUP "CD-ROM 1" - BEGIN - MENUITEM "&Mute", IDM_CDROM_1_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_1_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_1_IMAGE - END - POPUP "CD-ROM 2" - BEGIN - MENUITEM "&Mute", IDM_CDROM_2_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_2_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_2_IMAGE - END - POPUP "CD-ROM 3" - BEGIN - MENUITEM "&Mute", IDM_CDROM_3_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_3_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_3_IMAGE - END - POPUP "CD-ROM 4" - BEGIN - MENUITEM "&Mute", IDM_CDROM_4_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_4_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_4_IMAGE - END -END - -MAINMENU MENU DISCARDABLE -BEGIN - POPUP "&Action" - BEGIN - MENUITEM "&Hard Reset", IDM_FILE_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD - MENUITEM SEPARATOR - MENUITEM "E&xit", IDM_FILE_EXIT - END - POPUP "&Tools" - BEGIN - MENUITEM "&Settings...", IDM_CONFIG - MENUITEM SEPARATOR - MENUITEM "&Load configuration...", IDM_CONFIG_LOAD - MENUITEM "&Save configuration...", IDM_CONFIG_SAVE - MENUITEM SEPARATOR - POPUP "&Video" - BEGIN - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - MENUITEM "&DirectDraw", IDM_VID_DDRAW - MENUITEM "Direct&3D 9", IDM_VID_D3D - MENUITEM SEPARATOR - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - END - MENUITEM SEPARATOR - MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels", IDM_VID_FS_SQ - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - MENUITEM SEPARATOR - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT - END - MENUITEM "S&tatus", IDM_STATUS -#ifdef ENABLE_LOG_TOGGLES -#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG - MENUITEM SEPARATOR -#endif -#ifdef ENABLE_BUSLOGIC_LOG - MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC -#endif -#ifdef ENABLE_CDROM_LOG - MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM -#endif -#ifdef ENABLE_D86F_LOG - MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F -#endif -#ifdef ENABLE_FDC_LOG - MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC -#endif -#ifdef ENABLE_IDE_LOG - MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE -#endif -#ifdef ENABLE_NE2000_LOG - MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - MENUITEM SEPARATOR - MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT -#ifdef ENABLE_VRAM_DUMP - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#else -#ifdef ENABLE_VRAM_DUMP - MENUITEM SEPARATOR - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#endif - END - POPUP "&Help" - BEGIN - MENUITEM "&About 86Box...", IDM_ABOUT - END -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Accelerator -// - -MAINACCEL ACCELERATORS MOVEABLE PURE -BEGIN -#ifdef ENABLE_VRAM_DUMP - VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_CDROM_LOG - VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_D86F_LOG - VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_FDC_LOG - VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_IDE_LOG - VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_NE2000_LOG - VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY -#endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT - VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY -#endif - VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL - VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL -END - - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -CONFIGUREDLG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "86Box Settings" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,246,220,50,14 - PUSHBUTTON "Cancel",IDCANCEL,307,220,50,14 - CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,90,197 - CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 - LTEXT "Language:",2047,7,222,41,10 - COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP -END - -CONFIGUREDLG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Add Hard Disk" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,55,89,50,14 - PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14 - EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,153,12 - PUSHBUTTON "&Specify...",IDC_CFILE,167,16,44,12 - EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12 - EDITTEXT IDC_EDIT_HD_HPC,112,34,28,12 - EDITTEXT IDC_EDIT_HD_CYL,42,34,28,12 - EDITTEXT IDC_EDIT_HD_SIZE,42,52,28,12 - COMBOBOX IDC_COMBO_HD_TYPE,113,52,98,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Sectors:",IDC_STATIC,154,35,27,10 - LTEXT "Heads:",1793,81,35,29,8 - LTEXT "Cylinders:",1794,7,35,32,12 - LTEXT "Size (MB):",1795,7,54,33,8 - LTEXT "Type:",1797,86,54,24,8 - LTEXT "File name:",-1,7,7,204,9 - COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,72,24,8 - COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,99,72,34,8 - COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,117,72,15,8 - COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,168,72,15,8 - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,99,72,34,8 -END - -STATUSDLG DIALOG DISCARDABLE 0, 0, 186, 386 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Status" -FONT 9, "Segoe UI" -BEGIN - LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 - LTEXT "1",IDC_STEXT1,16,186,180,1000 -END - -ABOUTDLG DIALOG DISCARDABLE 0, 0, 209, 114 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About 86Box" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,129,94,71,12 - ICON 100,IDC_ABOUT_ICON,7,7,20,20 - LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", - IDC_ABOUT_ICON,54,7,146,73 - CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, - 86,208,1 -END - -CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Machine:",1794,7,8,60,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 - COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU type:",1796,7,26,59,10 - COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Wait states:",1798,7,45,60,10 - COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU:",1797,124,26,18,10 - CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,147,80,113,10 - EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, - 12,12 - LTEXT "MB",IDC_TEXT_MB,123,64,10,10 - LTEXT "Memory:",1802,7,64,30,10 - CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 -END - -CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video:",1795,7,8,55,10 - COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video speed:",1800,7,26,58,10 - CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 - PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 -END - -CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Mouse :",IDC_STATIC,7,8,57,10 - COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - LTEXT "Joystick :",1793,7,26,58,10 - COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 - PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 - PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 -END - -CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Sound card:",1800,7,8,59,10 - PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 - COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "MIDI Out Device:",1801,7,26,59,10 - CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 - CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 -END - -CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Network type:",1800,7,8,59,10 - COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "PCap device:",1801,7,26,59,10 - COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "Network adapter:",1802,7,44,59,10 - COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 -END - -CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "SCSI Controller:",1804,7,8,59,10 - COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 - - LTEXT "HD Controller:",1799,7,26,61,10 - COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Tertiary IDE:",1802,7,44,61,10 - COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Quaternary IDE:",1803,7,62,61,10 - COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 - - CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 - CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 -END - -CONFIGUREDLG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,18,253,92 - LTEXT "Hard disks:",-1,7,7,34,8 - PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 - PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 - PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 - COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,118,24,8 - COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,131,118,38,8 - COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,118,38,8 - COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,118,38,8 - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,118,38,8 -END - -CONFIGUREDLG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, - 7,18,253,60 - LTEXT "Floppy drives:",-1,7,7,43,8 - CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 - LTEXT "CD-ROM drives:",-1,7,106,50,8 - COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Type:",1803,7,86,24,8 - COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,184,24,8 - COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,184,38,8 - COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,184,38,8 - COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,184,38,8 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// 24 -// - -1 24 MOVEABLE PURE "86Box.manifest" - -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// - -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -#ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" -#else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" -#endif -128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" -129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" -130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" -131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" -132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" -133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" -134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" -135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" -144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" -145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" -146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" -147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" -150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" -151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" -152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" -153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" -160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" -161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" -162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" -163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" -164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" -165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" -177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" -178 ICON DISCARDABLE "ICONS/hard_disk.ico" -179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" -256 ICON DISCARDABLE "ICONS/machine.ico" -257 ICON DISCARDABLE "ICONS/video.ico" -258 ICON DISCARDABLE "ICONS/input_devices.ico" -259 ICON DISCARDABLE "ICONS/sound.ico" -260 ICON DISCARDABLE "ICONS/network.ico" -261 ICON DISCARDABLE "ICONS/other_peripherals.ico" -262 ICON DISCARDABLE "ICONS/hard_disk.ico" -263 ICON DISCARDABLE "ICONS/removable_devices.ico" -384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" -385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" -386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" -387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" -388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" -389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" -390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" -391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" -400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" -401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" -402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" -403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" -406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" -407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" -408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" -409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" -416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" -417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" -418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" -419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" -420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" -421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" -512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" -514 ICON DISCARDABLE "ICONS/cdrom_disabled.ico" - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE DISCARDABLE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE DISCARDABLE -BEGIN - "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""windows.h""\r\n" - "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" - "#include ""resources.h""\r\n" - "\0" -END - -3 TEXTINCLUDE DISCARDABLE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE -BEGIN - CONFIGUREDLG_MAIN, DIALOG - BEGIN - RIGHTMARGIN, 365 - END - - ABOUTDLG, DIALOG - BEGIN - RIGHTMARGIN, 208 - END - - CONFIGUREDLG_MACHINE, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 105 - END - - CONFIGUREDLG_VIDEO, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 56 - END - - CONFIGUREDLG_INPUT, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 58 - END - - CONFIGUREDLG_SOUND, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 71 - END - - CONFIGUREDLG_NETWORK, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 56 - END - - CONFIGUREDLG_PERIPHERALS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 102 - END - - CONFIGUREDLG_HARD_DISKS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 137 - END - - CONFIGUREDLG_REMOVABLE_DEVICES, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 260 - TOPMARGIN, 7 - BOTTOMMARGIN, 195 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// String Table -// - -STRINGTABLE DISCARDABLE -BEGIN - 2048 "86Box" - IDS_STRING2049 "86Box Error" - IDS_STRING2050 "86Box Fatal Error" - IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" - IDS_STRING2052 "DirectDraw Screenshot Error" - IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" - IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" - IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" - IDS_STRING2056 "Please enter a valid file name" - IDS_STRING2057 "Unable to open the file for write" - IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" - IDS_STRING2059 "Remember to partition and format the new drive" - IDS_STRING2060 "Unable to open the file for read" - IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" - IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." - IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." -END - -STRINGTABLE DISCARDABLE -BEGIN - IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." - IDS_STRING2065 "Machine" - IDS_STRING2066 "Video" - IDS_STRING2067 "Input devices" - IDS_STRING2068 "Sound" - IDS_STRING2069 "Network" - IDS_STRING2070 "Other peripherals" - IDS_STRING2071 "Hard disks" - IDS_STRING2072 "Removable devices" - IDS_STRING2073 "%i"" floppy drive: %s" - IDS_STRING2074 "Disabled CD-ROM drive" - IDS_STRING2075 "%s CD-ROM drive: %s" - IDS_STRING2076 "Host CD/DVD Drive (%c:)" - IDS_STRING2077 "Click to capture mouse" - IDS_STRING2078 "Press F12-F8 to release mouse" - IDS_STRING2079 "Press F12-F8 or middle button to release mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2080 "Drive" - 2081 "Location" - 2082 "Bus" - 2083 "File" - 2084 "C" - 2085 "H" - 2086 "S" - 2087 "MB" - 2088 "%i" - 2089 "Enabled" - 2090 "Mute" - 2091 "Type" - 2092 "Bus" - 2093 "DMA" - 2094 "KB" - 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2096 "Slave" - 2097 "SCSI (ID %s, LUN %s)" - 2098 "Adapter Type" - 2099 "Base Address" - 2100 "IRQ" - 2101 "8-bit DMA" - 2102 "16-bit DMA" - 2103 "BIOS" - 2104 "Network Type" - 2105 "Surround Module" - 2106 "MPU-401 Base Address" - 2107 "No PCap devices found" - 2108 "On-board RAM" - 2109 "Memory Size" - 2110 "Display Type" - 2111 "RGB" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2112 "Composite" - 2113 "Composite Type" - 2114 "Old" - 2115 "New" - 2116 "RGB Type" - 2117 "Color" - 2118 "Monochrome (Green)" - 2119 "Monochrome (Amber)" - 2120 "Monochrome (Gray)" - 2121 "Color (no brown)" - 2122 "Monochrome (Default)" - 2123 "Snow Emulation" - 2124 "Bilinear Filtering" - 2125 "Dithering" - 2126 "Framebuffer Memory Size" - 2127 "Texture Memory Size" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2128 "Screen Filter" - 2129 "Render Threads" - 2130 "Recompiler" - 2131 "System Default" - 2132 "%i Wait state(s)" - 2133 "8-bit" - 2134 "Slow 16-bit" - 2135 "Fast 16-bit" - 2136 "Slow VLB/PCI" - 2137 "Mid VLB/PCI" - 2138 "Fast VLB/PCI" - 2139 "Microsoft 2-button mouse (serial)" - 2140 "Mouse Systems mouse (serial)" - 2141 "2-button mouse (PS/2)" - 2142 "Microsoft Intellimouse (PS/2)" - 2143 "Bus mouse" -END - -STRINGTABLE DISCARDABLE -BEGIN - 2144 "Standard 2-button joystick(s)" - 2145 "Standard 4-button joystick" - 2146 "Standard 6-button joystick" - 2147 "Standard 8-button joystick" - 2148 "CH Flightstick Pro" - 2149 "Microsoft SideWinder Pad" - 2150 "Thrustmaster Flight Control System" - 2151 "Disabled" - 2152 "None" - 2153 "AT Fixed Disk Adapter" - 2154 "Internal IDE" - 2155 "IRQ %i" - 2156 "MFM (%01i:%01i)" - 2157 "IDE (PIO+DMA) (%01i:%01i)" - 2158 "SCSI (%02i:%02i)" - 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" - 2160 "%" PRIu64 - 2161 "Genius Bus mouse" - 2162 "Amstrad mouse" - 2163 "Attempting to create a spuriously large hard disk image" - 2164 "Invalid number of sectors (valid values are between 1 and 99)" - 2165 "MFM" - 2166 "IDE (PIO-only)" - 2167 "IDE (PIO and DMA)" - 2168 "SCSI" - 2169 "%01i:%01i" - 2170 "Custom..." - 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" - 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" - 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" - 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2177 "Olivetti M24 mouse" - 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" - 2179 "Floppy %i (%s): %ws" - 2180 "CD-ROM %i: %ws" - 2181 "MFM hard disk" - 2182 "IDE hard disk (PIO-only)" - 2183 "IDE hard disk (PIO and DMA)" - 2184 "SCSI hard disk" - 2185 "(empty)" - 2186 "(host drive %c:)" - 2187 "Custom (large)..." - 2188 "Type" - 2189 "ATAPI (PIO-only)" - 2190 "ATAPI (PIO and DMA)" - 2191 "ATAPI (PIO-only) (%01i:%01i)" - 2192 "ATAPI (PIO and DMA) (%01i:%01i)" - 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2194 "Unable to create bitmap file: %s" - 2195 "IDE (PIO-only) (%01i:%01i)" - 2196 "Add New Hard Disk" - 2197 "Add Existing Hard Disk" - 2198 "Removable disk %i: %s" - 2199 "USB is not yet supported" - 2200 "Invalid PCap device" - 2201 "English (United States)" -END - - -#ifndef _MAC -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,20,0,0 - PRODUCTVERSION 1,20,0,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "IRC #SoftHistory\0" - VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" - VALUE "FileVersion", "1.20\0" - VALUE "InternalName", "pc_new\0" - VALUE "LegalCopyright", "Copyright © SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "86Box.exe\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "86Box Emulator\0" - VALUE "ProductVersion", "1.20\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ff573e673..d2cbc03e3 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.12 2017/05/12 +# Version: @(#)Makefile.mingw 1.0.13 2017/05/17 # # Authors: Kotori, # Fred N. van Kempen, @@ -33,16 +33,20 @@ DEBUG = n OPTIM = n X64 = n +# Where is the WinPcap DLL ? +PCAPDLL = C:\\Windows\\System32\\wpcap.dll + ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/resid-fp video lzf slirp +VPATH = . cpu sound sound/resid-fp video lzf slirp win +PLAT = win/ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -OPTS = -DWIN32 $(EXTRAS) $(STUFF) +OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) ifeq ($(VRAMDUMP), y) DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP @@ -129,7 +133,7 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ cdrom.o \ - cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o + cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o USBOBJ = usb.o NETOBJ = network.o \ net_pcap.o net_slirp.o \ @@ -173,12 +177,12 @@ VIDOBJ = video.o \ vid_pc1512.o vid_pc1640.o vid_pc200.o \ vid_tandy.o vid_tandysl.o WINOBJ = win.o \ - win-d3d.o win-d3d-fs.o \ - win-ddraw.o win-ddraw-fs.o win-ddraw-screenshot.o \ - win-language.o win-status.o win-opendir.o \ - win-video.o win-serial.o win-mouse.o \ - win-joystick.o win-midi.o \ - win-settings.o win-deviceconfig.o win-joystickconfig.o \ + win_d3d.o win_d3d-fs.o \ + win_ddraw.o win_ddraw-fs.o win_ddraw-screenshot.o \ + win_language.o win_status.o win_opendir.o \ + win_video.o win_serial.o win_mouse.o \ + win_joystick.o win_midi.o \ + win_settings.o win_deviceconfig.o win_joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) @@ -235,11 +239,15 @@ clean: 86Box.res: 86Box.rc @echo Processing $< - @$(WINDRES) $(RFLAGS) -i 86Box.rc -o 86Box.res + @$(WINDRES) $(RFLAGS) -i win/86Box.rc -o 86Box.res + +libwpcapdelay.a: $(PCAPDLL) + @dlltool --export-all-symbols --output-def wpcap.def $(PCAPDLL) + @dlltool --def wpcap.def --output-delaylib libwpcapdelay.a pcap_if.res: pcap_if.rc @echo Processing $< - @$(WINDRES) $(RFLAGS) -i pcap_if.rc -o pcap_if.res + @$(WINDRES) $(RFLAGS) -i win/pcap_if.rc -o pcap_if.res # End of Makefile.mingw. diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index eace343f3..474d717b9 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -2,7 +2,7 @@ #include "../io.h" #include "../pic.h" #include "../timer.h" -#include "../plat-midi.h" +#include "../win/plat_midi.h" /*YUCK*/ #include "snd_mpu401.h" #include diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 92f7cacd0..8c6f4a036 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -9,7 +9,7 @@ #include "../io.h" #include "../pic.h" #include "../dma.h" -#include "../plat-midi.h" +#include "../win/plat_midi.h" /*YUCK*/ #include "../timer.h" #include "sound.h" #include "snd_mpu401.h" diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index 41553f671..afae65439 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -13,7 +13,7 @@ #include "vid_cga.h" #include "vid_cga_comp.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/VIDEO/vid_hercules.c b/src/VIDEO/vid_hercules.c index a7c5ab73a..bbb8b57b6 100644 --- a/src/VIDEO/vid_hercules.c +++ b/src/VIDEO/vid_hercules.c @@ -11,7 +11,7 @@ #include "video.h" #include "vid_hercules.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/VIDEO/vid_mda.c b/src/VIDEO/vid_mda.c index 7180a4921..d9e254b3a 100644 --- a/src/VIDEO/vid_mda.c +++ b/src/VIDEO/vid_mda.c @@ -11,7 +11,7 @@ #include "video.h" #include "vid_mda.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index c7c1a31b8..f3deed5bc 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -17,7 +17,7 @@ #include "video.h" #include "vid_svga.h" #ifndef __unix -#include "../win-cgapal.h" +# include "../win/win_cgapal.h" /*YUCK*/ #endif diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp deleted file mode 100644 index 6f966cf1b..000000000 --- a/src/cdrom-dosbox.cpp +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Modified for use with PCem by bit */ - -#include -#include -#include -#include -#include -#include -#include //GCC 2.95 -#include -#include -#include -#include "cdrom-dosbox.h" - -#if !defined(WIN32) -#include -#else -#include -#endif - -using namespace std; - -#define MAX_LINE_LENGTH 512 -#define MAX_FILENAME_LENGTH 256 -#define CROSS_LEN 512 - -#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) - -CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) -{ - file = new ifstream(filename, ios::in | ios::binary); - error = (file == NULL) || (file->fail()); -} - -CDROM_Interface_Image::BinaryFile::~BinaryFile() -{ - delete file; -} - -bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) -{ - file->seekg(seek, ios::beg); - file->read((char*)buffer, count); - return !(file->fail()); -} - -int CDROM_Interface_Image::BinaryFile::getLength() -{ - file->seekg(0, ios::end); - int length = (int)file->tellg(); - if (file->fail()) return -1; - return length; -} - -CDROM_Interface_Image::CDROM_Interface_Image() -{ -} - -CDROM_Interface_Image::~CDROM_Interface_Image() -{ - ClearTracks(); -} - -void CDROM_Interface_Image::InitNewMedia() -{ -} - -bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) -{ - if (LoadCueSheet(path)) return true; - if (LoadIsoFile(path)) return true; - - // print error message on dosbox console - //printf("Could not load image file: %s\n", path); - return false; -} - -bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) -{ - attr = 0; - strcpy(upc, this->mcn.c_str()); - return true; -} - -bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) -{ - stTrack = 1; - end = (int)(tracks.size() - 1); - FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); - return true; -} - -bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) -{ - if (track < 1 || track > (int)tracks.size()) return false; - FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); - track_number = tracks[track - 1].track_number; - attr = tracks[track - 1].attr; - return true; -} - -bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) -{ - int cur_track = GetTrack(sector); - if (cur_track < 1) return false; - track = (unsigned char)cur_track; - attr = tracks[track - 1].attr; - index = 1; - FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); - FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); - return true; -} - -bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) -{ - mediaPresent = true; - mediaChanged = false; - trayOpen = false; - return true; -} - -bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) -{ - int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; - Bitu buflen = num * sectorSize; - Bit8u* buf = new Bit8u[buflen]; - - bool success = true; //Gobliiins reads 0 sectors - for(unsigned long i = 0; i < num; i++) { - success = ReadSector(&buf[i * sectorSize], raw, sector + i); - if (!success) break; - } - - memcpy((void*)buffer, buf, buflen); - delete[] buf; - - return success; -} - -bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) -{ - return true; -} - -int CDROM_Interface_Image::GetTrack(int sector) -{ - vector::iterator i = tracks.begin(); - vector::iterator end = tracks.end() - 1; - - while(i != end) { - Track &curr = *i; - Track &next = *(i + 1); - if (curr.start <= sector && sector < next.start) return curr.number; - i++; - } - return -1; -} - -bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; - int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); - if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; - if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; - if (tracks[track].mode2 && !raw) seek += 24; - - return tracks[track].file->read(buffer, seek, length); -} - -bool CDROM_Interface_Image::IsMode2(unsigned long sector) -{ - int track = GetTrack(sector) - 1; - if (track < 0) return false; - - if (tracks[track].mode2) - { - return true; - } - else - { - return false; - } -} - -bool CDROM_Interface_Image::LoadIsoFile(char* filename) -{ - int shift = 0; - int totalPregap = 0; - - tracks.clear(); - - // data track - Track track = {0, 0, 0, 0, 0, 0, false, NULL}; - bool error; - track.file = new BinaryFile(filename, error); - if (error) { - delete track.file; - return false; - } - track.number = 1; - track.track_number = 1;//IMPORTANT: This is needed. - track.attr = DATA_TRACK;//data - - // try to detect iso type - if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { - track.sectorSize = COOKED_SECTOR_SIZE; - track.mode2 = false; - } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { - track.sectorSize = RAW_SECTOR_SIZE; - track.mode2 = false; - } else if (CanReadPVD(track.file, 2336, true)) { - track.sectorSize = 2336; - track.mode2 = true; - } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { - track.sectorSize = RAW_SECTOR_SIZE; - track.mode2 = true; - } else return false; - - track.length = track.file->getLength() / track.sectorSize; - tracks.push_back(track); - - // leadout track - track.number = 2; - track.track_number = 0xAA; - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - track.start = track.length; - track.length = 0; - track.file = NULL; - tracks.push_back(track); - - return true; -} - -bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) -{ - Bit8u pvd[COOKED_SECTOR_SIZE]; - int seek = 16 * sectorSize; // first vd is located at sector 16 - if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; - if (mode2) seek += 24; - file->read(pvd, seek, COOKED_SECTOR_SIZE); - // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) - return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || - (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); -} - -#if defined(WIN32) -static string dirname(char * file) { - char * sep = strrchr(file, '\\'); - if (sep == NULL) - sep = strrchr(file, '/'); - if (sep == NULL) - return ""; - else { - int len = (int)(sep - file); - char tmp[MAX_FILENAME_LENGTH]; - safe_strncpy(tmp, file, len+1); - return tmp; - } -} -#endif - -bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) -{ - Track track = {0, 0, 0, 0, 0, 0, false, NULL}; - tracks.clear(); - int shift = 0; - int currPregap = 0; - int totalPregap = 0; - int prestart = 0; - bool success; - bool canAddTrack = false; - char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument - safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); - string pathname(dirname(tmp)); - ifstream in; - in.open(cuefile, ios::in); - if (in.fail()) return false; - - while(!in.eof()) { - // get next line - char buf[MAX_LINE_LENGTH]; - in.getline(buf, MAX_LINE_LENGTH); - if (in.fail() && !in.eof()) return false; // probably a binary file - istringstream line(buf); - - string command; - GetCueKeyword(command, line); - - if (command == "TRACK") { - if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); - else success = true; - - track.start = 0; - track.skip = 0; - currPregap = 0; - prestart = 0; - - line >> track.number; - track.track_number = track.number; - string type; - GetCueKeyword(type, line); - - if (type == "AUDIO") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = AUDIO_TRACK; - track.mode2 = false; - } else if (type == "MODE1/2048") { - track.sectorSize = COOKED_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = false; - } else if (type == "MODE1/2352") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = false; - } else if (type == "MODE2/2336") { - track.sectorSize = 2336; - track.attr = DATA_TRACK; - track.mode2 = true; - } else if (type == "MODE2/2352") { - track.sectorSize = RAW_SECTOR_SIZE; - track.attr = DATA_TRACK; - track.mode2 = true; - } else success = false; - - canAddTrack = true; - } - else if (command == "INDEX") { - int index; - line >> index; - int frame; - success = GetCueFrame(frame, line); - - if (index == 1) track.start = frame; - else if (index == 0) prestart = frame; - // ignore other indices - } - else if (command == "FILE") { - if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); - else success = true; - canAddTrack = false; - - string filename; - GetCueString(filename, line); - GetRealFileName(filename, pathname); - string type; - GetCueKeyword(type, line); - - track.file = NULL; - bool error = true; - if (type == "BINARY") { - track.file = new BinaryFile(filename.c_str(), error); - } - if (error) { - delete track.file; - success = false; - } - } - else if (command == "PREGAP") success = GetCueFrame(currPregap, line); - else if (command == "CATALOG") success = GetCueString(mcn, line); - // ignored commands - else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" - || command == "PERFORMER" || command == "POSTGAP" || command == "REM" - || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; - // failure - else success = false; - - if (!success) return false; - } - // add last track - if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; - - // add leadout track - track.number++; - track.track_number = 0xAA; - // track.attr = 0;//sync with load iso - track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ - track.start = 0; - track.length = 0; - track.file = NULL; - if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; - - return true; -} - -bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) -{ - // frames between index 0(prestart) and 1(curr.start) must be skipped - int skip; - if (prestart > 0) { - if (prestart > curr.start) return false; - skip = curr.start - prestart; - } else skip = 0; - - // first track (track number must be 1) - if (tracks.empty()) { - if (curr.number != 1) return false; - curr.skip = skip * curr.sectorSize; - curr.start += currPregap; - totalPregap = currPregap; - tracks.push_back(curr); - return true; - } - - Track &prev = *(tracks.end() - 1); - - // current track consumes data from the same file as the previous - if (prev.file == curr.file) { - curr.start += shift; - prev.length = curr.start + totalPregap - prev.start - skip; - curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; - totalPregap += currPregap; - curr.start += totalPregap; - // current track uses a different file as the previous track - } else { - int tmp = prev.file->getLength() - prev.skip; - prev.length = tmp / prev.sectorSize; - if (tmp % prev.sectorSize != 0) prev.length++; // padding - - curr.start += prev.start + prev.length + currPregap; - curr.skip = skip * curr.sectorSize; - shift += prev.start + prev.length; - totalPregap = currPregap; - } - - // error checks - if (curr.number <= 1) return false; - if (prev.number + 1 != curr.number) return false; - if (curr.start < prev.start + prev.length) return false; - if (curr.length < 0) return false; - - tracks.push_back(curr); - return true; -} - -bool CDROM_Interface_Image::HasDataTrack(void) -{ - //Data track has attribute 0x14 - for(track_it it = tracks.begin(); it != tracks.end(); it++) { - if ((*it).attr == DATA_TRACK) return true; - } - return false; -} - -bool CDROM_Interface_Image::HasAudioTracks(void) -{ - for(track_it it = tracks.begin(); it != tracks.end(); it++) { - if ((*it).attr == AUDIO_TRACK) return true; - } - return false; -} - - -bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) -{ - // check if file exists - struct stat test; - if (stat(filename.c_str(), &test) == 0) return true; - - // check if file with path relative to cue file exists - string tmpstr(pathname + "/" + filename); - if (stat(tmpstr.c_str(), &test) == 0) { - filename = tmpstr; - return true; - } -#if defined (WIN32) || defined(OS2) - //Nothing -#else - //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) - //which is common for some commercial rereleases of DOS games using DOSBox - - string copy = filename; - size_t l = copy.size(); - for (size_t i = 0; i < l;i++) { - if(copy[i] == '\\') copy[i] = '/'; - } - - if (stat(copy.c_str(), &test) == 0) { - filename = copy; - return true; - } - - tmpstr = pathname + "/" + copy; - if (stat(tmpstr.c_str(), &test) == 0) { - filename = tmpstr; - return true; - } - -#endif - return false; -} - -bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) -{ - in >> keyword; - for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); - - return true; -} - -bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) -{ - string msf; - in >> msf; - int min, sec, fr; - bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; - frames = MSF_TO_FRAMES(min, sec, fr); - - return success; -} - -bool CDROM_Interface_Image::GetCueString(string &str, istream &in) -{ - int pos = (int)in.tellg(); - in >> str; - if (str[0] == '\"') { - if (str[str.size() - 1] == '\"') { - str.assign(str, 1, str.size() - 2); - } else { - in.seekg(pos, ios::beg); - char buffer[MAX_FILENAME_LENGTH]; - in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip - in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); - str = buffer; - } - } - return true; -} - -void CDROM_Interface_Image::ClearTracks() -{ - vector::iterator i = tracks.begin(); - vector::iterator end = tracks.end(); - - TrackFile* last = NULL; - while(i != end) { - Track &curr = *i; - if (curr.file != last) { - delete curr.file; - last = curr.file; - } - i++; - } - tracks.clear(); -} diff --git a/src/cdrom-dosbox.h b/src/cdrom-dosbox.h deleted file mode 100644 index 39ed79bed..000000000 --- a/src/cdrom-dosbox.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2002-2015 The DOSBox Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Modified for use with PCem by bit */ - -#ifndef __CDROM_INTERFACE__ -#define __CDROM_INTERFACE__ - -#include -#include -#include -#include -#include -#include -//#include "dosbox.h" -//#include "mem.h" -//#include "mixer.h" -//#include "SDL.h" -//#include "SDL_thread.h" - -#include -typedef signed int Bits; -typedef unsigned int Bitu; -typedef int8_t Bit8s; -typedef uint8_t Bit8u; -typedef int16_t Bit16s; -typedef uint16_t Bit16u; -typedef int32_t Bit32s; -typedef uint32_t Bit32u; - -typedef size_t PhysPt; - -#define RAW_SECTOR_SIZE 2352 -#define COOKED_SECTOR_SIZE 2048 - -#define DATA_TRACK 0x14 -#define AUDIO_TRACK 0x10 - -#define CD_FPS 75 -#define FRAMES_TO_MSF(f, M,S,F) { \ - int value = f; \ - *(F) = value%CD_FPS; \ - value /= CD_FPS; \ - *(S) = value%60; \ - value /= 60; \ - *(M) = value; \ -} -#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) - - -typedef struct SMSF { - unsigned char min; - unsigned char sec; - unsigned char fr; -} TMSF; - -typedef struct SCtrl { - Bit8u out[4]; // output channel - Bit8u vol[4]; // channel volume -} TCtrl; - -extern int CDROM_GetMountType(char* path, int force); - -class CDROM_Interface -{ -public: -// CDROM_Interface (void); - virtual ~CDROM_Interface (void) {}; - - virtual bool SetDevice (char* path, int forceCD) = 0; - - virtual bool GetUPC (unsigned char& attr, char* upc) = 0; - - virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; - virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; - virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; - virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; - - virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; - - virtual bool LoadUnloadMedia (bool unload) = 0; - - virtual void InitNewMedia (void) {}; -}; - -class CDROM_Interface_Image : public CDROM_Interface -{ -private: - class TrackFile { - public: - virtual bool read(Bit8u *buffer, int seek, int count) = 0; - virtual int getLength() = 0; - virtual ~TrackFile() { }; - }; - - class BinaryFile : public TrackFile { - public: - BinaryFile(const char *filename, bool &error); - ~BinaryFile(); - bool read(Bit8u *buffer, int seek, int count); - int getLength(); - private: - BinaryFile(); - std::ifstream *file; - }; - - struct Track { - int number; - int track_number; - int attr; - int start; - int length; - int skip; - int sectorSize; - bool mode2; - TrackFile *file; - }; - -public: - CDROM_Interface_Image (); - virtual ~CDROM_Interface_Image (void); - void InitNewMedia (void); - bool SetDevice (char* path, int forceCD); - bool GetUPC (unsigned char& attr, char* upc); - bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); - bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); - bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); - bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); - bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); - bool LoadUnloadMedia (bool unload); - bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); - bool IsMode2 (unsigned long sector); - bool HasDataTrack (void); - bool HasAudioTracks (void); - - int GetTrack (int sector); - -private: - // player -static void CDAudioCallBack(Bitu len); - - void ClearTracks(); - bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); - // cue sheet processing - bool LoadCueSheet(char *cuefile); - bool GetRealFileName(std::string& filename, std::string& pathname); - bool GetCueKeyword(std::string &keyword, std::istream &in); - bool GetCueFrame(int &frames, std::istream &in); - bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); - - std::vector tracks; -typedef std::vector::iterator track_it; - std::string mcn; -}; - -#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc deleted file mode 100644 index 5ec185d65..000000000 --- a/src/cdrom-image.cc +++ /dev/null @@ -1,1045 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi, bit - see COPYING for more details -*/ -/*CD-ROM image support*/ - -#include - -#include "config.h" -#include "cdrom-dosbox.h" -#include "cdrom.h" -#include "cdrom-image.h" -#include "cdrom-null.h" - -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE - -#include - -#define CD_STATUS_EMPTY 0 -#define CD_STATUS_DATA_ONLY 1 -#define CD_STATUS_PLAYING 2 -#define CD_STATUS_PAUSED 3 -#define CD_STATUS_STOPPED 4 - -/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: - there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start - of the audio while audio still plays. With an absolute conversion, the counter is fine. */ -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -extern CDROM image_cdrom; - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - -int cdrom_image_do_log = 0; - -CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; - -void cdrom_image_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_IMAGE_LOG - if (cdrom_image_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void image_close(uint8_t id); - -void image_audio_callback(uint8_t id, int16_t *output, int len) -{ - if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) - { - memset(output, 0, len * 2); - return; - } - while (cdrom_image[id].cd_buflen < len) - { - if (cdrom[id].seek_pos < cdrom_image[id].cd_end) - { - if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) - { - memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; - } - else - { - cdrom[id].seek_pos++; - cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); - } - } - else - { - memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); - cdrom_image[id].cd_state = CD_STOPPED; - cdrom_image[id].cd_buflen = len; - } - } - memcpy(output, cdrom_image[id].cd_buffer, len * 2); - memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); - cdrom_image[id].cd_buflen -= len; -} - -void image_audio_stop(uint8_t id) -{ - cdrom_image[id].cd_state = CD_STOPPED; -} - -static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) -{ - if (!cdimg[id]) return; - int number; - unsigned char attr; - TMSF tmsf; - int m = 0, s = 0, f = 0; - uint32_t start_msf = 0, end_msf = 0; - cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); - if (attr == DATA_TRACK) - { - cdrom_image_log("Can't play data track\n"); - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_state = CD_STOPPED; - return; - } - cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf == 2) - { - cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); - pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); - cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); - len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); - } - else if (ismsf == 1) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - - if (pos == 0xffffff) - { - cdrom_image_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; - } - else - { - pos = MSFtoLBA(m, s, f); - } - - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); - - cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); - } - else if (ismsf == 0) - { - if (pos == 0xffffffff) - { - cdrom_image_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; - } - len += pos; - } - cdrom[id].seek_pos = pos; - cdrom_image[id].cd_end = len; - cdrom_image[id].cd_state = CD_PLAYING; - if (cdrom[id].seek_pos < 150) - cdrom[id].seek_pos = 150; - cdrom_image[id].cd_buflen = 0; -} - -static void image_pause(uint8_t id) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PLAYING) - cdrom_image[id].cd_state = CD_PAUSED; -} - -static void image_resume(uint8_t id) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - if (cdrom_image[id].cd_state == CD_PAUSED) - cdrom_image[id].cd_state = CD_PLAYING; -} - -static void image_stop(uint8_t id) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_state = CD_STOPPED; -} - -static void image_seek(uint8_t id, uint32_t pos) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_pos = pos; - cdrom_image[id].cd_state = CD_STOPPED; -} - -static int image_ready(uint8_t id) -{ - if (!cdimg[id]) - return 0; - - if (wcslen(cdrom_image[id].image_path) == 0) - return 0; - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - return 1; - } - - if (cdrom_image[id].image_changed) - { - cdrom_image[id].image_changed = 0; - return 1; - } - - return 1; -} - -static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) -{ - int c; - uint32_t lb=0; - - if (!cdimg[id]) return 0; - - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - for (c = 0; c <= last_track; c++) - { - uint32_t address; - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150 here as well. */ - if (address > lb) - lb = address; - } - return lb; -} - -static int image_medium_changed(uint8_t id) -{ - if (!cdimg[id]) - return 0; - - if (wcslen(cdrom_image[id].image_path) == 0) - { - return 0; - } - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - return 1; - } - - if (cdrom_image[id].image_changed) - { - cdrom_image[id].image_changed = 0; - return 1; - } - - return 0; -} - -static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - if (!cdimg[id]) return 0; - uint8_t ret; - int pos=0; - - uint32_t cdpos = cdrom[id].seek_pos; - if (cdpos >= 150) cdpos -= 150; - TMSF relPos, absPos; - unsigned char attr, track, index; - cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); - - if (cdrom_image[id].image_is_iso) - { - ret = 0x15; - } - else - { - if (cdrom_image[id].cd_state == CD_PLAYING) - ret = 0x11; - else if (cdrom_image[id].cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; - } - - b[pos++] = attr; - b[pos++] = track; - b[pos++] = index; - - if (msf) - { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos++] = (dat >> 24) & 0xff; - b[pos++] = (dat >> 16) & 0xff; - b[pos++] = (dat >> 8) & 0xff; - b[pos++] = dat & 0xff; - } - - return ret; -} - -static void image_eject(uint8_t id) -{ - return; -} - -static void image_load(uint8_t id) -{ - return; -} - -static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - int m, s, f; - unsigned char attr; - TMSF tmsf; - int number; - - if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; - - if (ismsf) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - else - { - pos += 150; - } - - cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); - - return attr == AUDIO_TRACK; -} - -typedef struct __attribute__((__packed__)) -{ - uint8_t user_data[2048]; - uint8_t ecc[288]; -} m1_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sub_header[8]; - uint8_t user_data[2328]; -} m2_data_t; - -typedef union __attribute__((__packed__)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2336]; -} sector_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; -} sector_raw_data_t; - -typedef union __attribute__((__packed__)) -{ - sector_raw_data_t sector_data; - uint8_t raw_data[2352]; -} sector_t; - -typedef struct __attribute__((__packed__)) -{ - sector_t sector; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((__packed__)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_size; -uint8_t raw_buffer[2352]; -uint8_t extra_buffer[296]; - -static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - uint8_t *b; - uint8_t *temp_b; - int real_pos; - int audio; - int mode2; - - if (!cdimg[id]) - { - return 0; - } - - if (!cdrom_drives[id].host_drive) - { - return 0; - } - - b = temp_b = buffer; - - *len = 0; - - if (ismsf) - { - real_pos = cdrom_lba_to_msf_accurate(sector); - } - else - { - real_pos = sector; - } - - if (cdrom_image[id].image_is_iso) - { - audio = 0; - mode2 = 0; - } - else - { - audio = image_is_track_audio(id, real_pos, 1); - mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; - } - - memset(raw_buffer, 0, 2352); - memset(extra_buffer, 0, 296); - - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) - { - if (cdrom_sector_type == 3) - { - cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); - } - if (cdrom_sector_type > 4) - { - cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); - } - return 0; - } - else if (cdrom_sector_type == 1) - { - if (!audio || cdrom_image[id].image_is_iso) - { - cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); - return 0; - } - -read_audio: - cdimg[id]->ReadSector(raw_buffer, true, real_pos); - memcpy(temp_b, raw_buffer, 2352); - } - else if (cdrom_sector_type == 2) - { - if (audio || mode2) - { - cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); - return 0; - } - -read_mode1: - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - if (cdrom_image[id].image_is_iso) - { - cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); - - uint8_t *bb = raw_buffer; - - /* sync bytes */ - bb[0] = 0; - memset(bb + 1, 0xff, 10); - bb[11] = 0; - bb += 12; - - bb[0] = (real_pos >> 16) & 0xff; - bb[1] = (real_pos >> 8) & 0xff; - bb[2] = real_pos & 0xff; - - bb[3] = 1; /* mode 1 data */ - bb += 4; - bb += 2048; - memset(bb, 0, 288); - } - else - { - cdimg[id]->ReadSector(raw_buffer, true, real_pos); - } - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); - memcpy(temp_b, raw_buffer, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); - memcpy(temp_b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); - memcpy(temp_b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); - memcpy(temp_b, raw_buffer + 16, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); - memcpy(temp_b, raw_buffer + 2064, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - } - else if (cdrom_sector_type == 4) - { - if (audio || !mode2 || cdrom_image[id].image_is_iso) - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); - return 0; - } - -read_mode2: - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); - memcpy(temp_b, raw_buffer, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); - memcpy(temp_b, raw_buffer + 12, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); - memcpy(temp_b, raw_buffer + 16, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); - memcpy(temp_b, raw_buffer + 24, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); - memcpy(temp_b, raw_buffer + 2072, 280); - cdrom_sector_size += 280; - temp_b += 280; - } - } - else - { - if (mode2) - { - goto read_mode2; - } - else - { - if (audio) - { - goto read_audio; - } - else - { - goto read_mode1; - } - } - } - - if ((cdrom_sector_flags & 0x06) == 0x02) - { - /* Add error flags. */ - cdrom_image_log("CD-ROM %i: Error flags\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 294); - cdrom_sector_size += 294; - } - else if ((cdrom_sector_flags & 0x06) == 0x04) - { - /* Add error flags. */ - cdrom_image_log("CD-ROM %i: Full error flags\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) - { - cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 96); - cdrom_sector_size += 96; - } - else if ((cdrom_sector_flags & 0x700) == 0x200) - { - cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 16); - cdrom_sector_size += 16; - } - else if ((cdrom_sector_flags & 0x700) == 0x400) - { - cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); - memcpy(b + cdrom_sector_size, extra_buffer, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; -} - - -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - -static uint32_t image_size(uint8_t id) -{ - return cdrom_image[id].cdrom_capacity; -} - -static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - if (!cdimg[id]) return 0; - int len=4; - int c,d; - uint32_t temp; - - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - b[2] = first_track; - b[3] = last_track; - - d = 0; - for (c = 0; c <= last_track; c++) - { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - if (number >= starttrack) - { - d=c; - break; - } - } - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - b[2] = number; - - for (c = d; c <= last_track; c++) - { - if ((len + 8) > maxlen) - break; - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ - - if (msf) - { - b[len++] = 0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - else - { - temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - if (single) - break; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); - /* - pclog("Table of Contents:\n"); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); - } - for (c = 0;c <= last_track; c++) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); - } - */ - return len; -} - -static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - int len = 4; - - int number; - TMSF tmsf; - unsigned char attr; - - if (!cdimg[id]) return 0; - - cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); - - if (number == 0) - { - number = 1; - } - - b[2] = 1; - b[3] = 1; - b[len++] = 0; /* reserved */ - b[len++] = attr; - b[len++] = number; /* track number */ - b[len++] = 0; /* reserved */ - if (msf) - { - b[len++] = 0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - else - { - uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150. */ - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - if (maxlen < len) - { - return maxlen; - } - - return len; -} - -static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - int track; - int len = 4; - - int first_track; - int last_track; - int number; - unsigned char attr; - TMSF tmsf; - int lb; - - if (!cdimg[id]) return 0; - - cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); - - b[2] = first_track; - b[3] = last_track; - - for (track = first_track; track <= last_track; track++) - { - if ((len + 11) > maxlen) - { - cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - return len; - } - - cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); - - b[len++] = track; - b[len++]= attr; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++] = tmsf.min; - b[len++] = tmsf.sec; - b[len++] = tmsf.fr; - } - return len; -} - -static int image_status(uint8_t id) -{ - if (!cdimg[id]) return CD_STATUS_EMPTY; - if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; - if (cdimg[id]->HasAudioTracks()) - { - switch(cdrom_image[id].cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - default: - return CD_STATUS_STOPPED; - } - } - return CD_STATUS_DATA_ONLY; -} - -void image_reset(uint8_t id) -{ -} - -void image_close(uint8_t id) -{ - cdrom_image[id].cd_state = CD_STOPPED; - if (cdimg[id]) - { - delete cdimg[id]; - cdimg[id] = NULL; - } - memset(cdrom_image[id].image_path, 0, 2048); -} - -static char afn[1024]; - -int image_open(uint8_t id, wchar_t *fn) -{ - if (wcscmp(fn, cdrom_image[id].image_path) != 0) - { - cdrom_image[id].image_changed = 1; - } - - /* Make sure image_changed stays when changing from an image to another image. */ - if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; - - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) - { - _swprintf(cdrom_image[id].image_path, L"%ws", fn); - } - - if (!wcsicmp(get_extension_w(fn), L"ISO")) - { - cdrom_image[id].image_is_iso = 1; - } - else - { - cdrom_image[id].image_is_iso = 0; - } - - cdimg[id] = new CDROM_Interface_Image(); - wcstombs(afn, fn, (wcslen(fn) << 1) + 2); - if (!cdimg[id]->SetDevice(afn, false)) - { - image_close(id); - cdrom_set_null_handler(id); - return 1; - } - cdrom_image[id].cd_state = CD_STOPPED; - cdrom[id].seek_pos = 0; - cdrom_image[id].cd_buflen = 0; - cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; - cdrom_drives[id].handler = &image_cdrom; - - if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) - { - if (!cdrom_image[id].image_inited) - cdrom_image[id].image_inited = 1; - } - - update_status_bar_icon_state(0x10 | id, 0); - return 0; -} - -static void image_exit(uint8_t id) -{ - cdrom_image[id].image_inited = 0; -} - -/* TODO: Check for what data type a mixed CD is. */ -static int image_media_type_id(uint8_t id) -{ - if (!cdrom_image[id].image_is_iso) - { - return 3; /* Mixed mode CD. */ - } - - if (image_size(id) <= 405000) - { - return 1; /* Data CD. */ - } - else - { - return 65; /* DVD. */ - } -} - -CDROM image_cdrom = -{ - image_ready, - image_medium_changed, - image_media_type_id, - image_audio_callback, - image_audio_stop, - image_readtoc, - image_readtoc_session, - image_readtoc_raw, - image_getcurrentsubchannel, - NULL, - image_readsector_raw, - image_playaudio, - image_load, - image_eject, - image_pause, - image_resume, - image_size, - image_status, - image_is_track_audio, - image_stop, - image_exit -}; diff --git a/src/cdrom-image.h b/src/cdrom-image.h deleted file mode 100644 index 4ea4cb78f..000000000 --- a/src/cdrom-image.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_IMAGE_H -#define CDROM_IMAGE_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int image_open(uint8_t id, wchar_t *fn); -extern void image_reset(uint8_t id); - -extern void image_close(uint8_t id); - -void update_status_bar_icon_state(int tag, int state); -extern void cdrom_set_null_handler(uint8_t id); - -void pclog(const char *format, ...); - -#ifdef __cplusplus -} -#endif - -#endif /* ! CDROM_IMAGE_H */ diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c deleted file mode 100644 index 5b993b612..000000000 --- a/src/cdrom-ioctl-linux.c +++ /dev/null @@ -1,725 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Linux CD-ROM support via IOCTL*/ - -#include -#include -#include -#include -#include "ibm.h" -#include "ide.h" -#include "cdrom-ioctl.h" - -static ATAPI ioctl_atapi; - -static uint32_t last_block = 0; -static uint32_t cdrom_capacity = 0; -static int ioctl_inited = 0; -static char ioctl_path[8]; -static int tocvalid = 0; -static struct cdrom_tocentry toc[100]; -static int first_track, last_track; - -int old_cdrom_drive; - -#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)-150) - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - -static int ioctl_cd_state = CD_STOPPED; -static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; -#define BUF_SIZE 32768 -static int16_t cd_buffer[BUF_SIZE]; -static int cd_buflen = 0; -void ioctl_audio_callback(int16_t *output, int len) -{ - int fd; - struct cdrom_read_audio read_audio; - -// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); - if (ioctl_cd_state != CD_PLAYING) - { - memset(output, 0, len * 2); - return; - } - fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - { - memset(output, 0, len * 2); - return; - } - - while (cd_buflen < len) - { - if (ioctl_cd_pos < ioctl_cd_end) - { - read_audio.addr.lba = ioctl_cd_pos - 150; - read_audio.addr_format = CDROM_LBA; - read_audio.nframes = 1; - read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; - - if (ioctl(fd, CDROMREADAUDIO, &read_audio) < 0) - { -// pclog("DeviceIoControl returned false\n"); - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - else - { -// pclog("DeviceIoControl returned true\n"); - ioctl_cd_pos++; - cd_buflen += (2352 / 2); - } - } - else - { - memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); - ioctl_cd_state = CD_STOPPED; - cd_buflen = len; - } - } - close(fd); - memcpy(output, cd_buffer, len * 2); -// for (c = 0; c < BUF_SIZE - len; c++) -// cd_buffer[c] = cd_buffer[c + cd_buflen]; - memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); - cd_buflen -= len; -// pclog("Done %i\n", GetTickCount()); -} - -void ioctl_audio_stop() -{ - ioctl_cd_state = CD_STOPPED; -} - -static int get_track_nr(uint32_t pos) -{ - int c; - int track = 0; - - if (!tocvalid) - return 0; - - for (c = first_track; c < last_track; c++) - { - uint32_t track_address = toc[c].cdte_addr.msf.frame + - (toc[c].cdte_addr.msf.second * 75) + - (toc[c].cdte_addr.msf.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - track = c; - } - return track; -} - -static int is_track_audio(uint32_t pos) -{ - int c; - int control = 0; - - if (!tocvalid) - return 0; - - for (c = first_track; c < last_track; c++) - { - uint32_t track_address = toc[c].cdte_addr.msf.frame + - (toc[c].cdte_addr.msf.second * 75) + - (toc[c].cdte_addr.msf.minute * 75 * 60); -//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); - if (track_address <= pos) - control = toc[c].cdte_ctrl; - } - return (control & 4) ? 0 : 1; -} - -static int ioctl_is_track_audio(uint32_t pos, int ismsf) -{ - if (ismsf) - { - int m = (pos >> 16) & 0xff; - int s = (pos >> 8) & 0xff; - int f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - return is_track_audio(pos); -} - -static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) -{ -// pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); - if (ismsf) - { - pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); - len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); -// pclog("MSF - pos = %08X len = %08X\n", pos, len); - } - else - len += pos; - ioctl_cd_pos = pos;// + 150; - ioctl_cd_end = pos+len;// + 150; - ioctl_cd_state = CD_PLAYING; - if (ioctl_cd_pos < 150) - ioctl_cd_pos = 150; -// pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); -} - -static void ioctl_pause(void) -{ - if (ioctl_cd_state == CD_PLAYING) - ioctl_cd_state = CD_PAUSED; -} - -static void ioctl_resume(void) -{ - if (ioctl_cd_state == CD_PAUSED) - ioctl_cd_state = CD_PLAYING; -} - -static void ioctl_stop(void) -{ - ioctl_cd_state = CD_STOPPED; -} - -static void ioctl_seek(uint32_t pos) -{ -// pclog("Seek %08X\n", pos); - ioctl_cd_pos = pos; - ioctl_cd_state = CD_STOPPED; -} - -static int read_toc(int fd, struct cdrom_tocentry *btoc) -{ - struct cdrom_tochdr toc_hdr; - int track, err; -//pclog("read_toc\n"); - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return 0; - } - - first_track = toc_hdr.cdth_trk0; - last_track = toc_hdr.cdth_trk1; -//pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(btoc, 0, sizeof(cdrom_tocentry)); - - for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) - { - btoc[track].cdte_track = track; - btoc[track].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &btoc[track]); - if (err == -1) - { -// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); - return 0; - } -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); - } - return 1; -} - -static int ioctl_ready(void) -{ - long size; - int temp; - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc_entry; - int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - close(fd); - return 0; - } -// pclog("CDROMREADTOCHDR: start track=%i end track=%i\n", toc_hdr.cdth_trk0, toc_hdr.cdth_trk1); - toc_entry.cdte_track = toc_hdr.cdth_trk1; - toc_entry.cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); - if (err == -1) - { - close(fd); - return 0; - } -// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); - if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || - (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || - (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame ) || - !tocvalid) - { - int track; - ioctl_cd_state = CD_STOPPED; - - tocvalid = read_toc(fd, toc); - close(fd); - return 1; - } - close(fd); - return 1; -} - -static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) -{ - int c; - int lb = 0; - int tv = 0; - struct cdrom_tocentry lbtoc[100]; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - ioctl_cd_state = CD_STOPPED; - - tv = read_toc(fd, lbtoc); - - close(fd); - - if (!tv) - return 0; - - last_block = 0; - for (c = 0; c <= last_track; c++) - { - uint32_t address; - address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - if (address > last_block) - lb = address; - } - return lb; -} - -static int ioctl_medium_changed(void) -{ - long size; - int temp; - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc_entry; - int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - close(fd); - return 0; - } - toc_entry.cdte_track = toc_hdr.cdth_trk1; - toc_entry.cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); - if (err == -1) - { - close(fd); - return 0; - } -// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); - if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || - (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || - (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame )) - { - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); - return 1; - } - return 0; -} - -static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) -{ - struct cdrom_subchnl sub; - uint32_t cdpos = ioctl_cd_pos; - int track = get_track_nr(cdpos); - uint32_t track_address = toc[track].cdte_addr.msf.frame + - (toc[track].cdte_addr.msf.second * 75) + - (toc[track].cdte_addr.msf.minute * 75 * 60); - long size; - int pos=0; - int err; - uint8_t ret; -//pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i\n", cdpos, track_address, track); - if (ioctl_cd_state == CD_PLAYING) - ret = 0x11; - else if (ioctl_cd_state == CD_PAUSED) - ret = 0x12; - else - ret = 0x13; - - b[pos++] = (toc[track].cdte_adr << 4) | toc[track].cdte_ctrl; - b[pos++] = track; - b[pos++] = 0; - - if (msf) - { - uint32_t dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } - - return ret; -} - -static void ioctl_eject(void) -{ - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return; - - ioctl(fd, CDROMEJECT); - - close(fd); -} - -static void ioctl_load(void) -{ - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return; - - ioctl(fd, CDROMEJECT); - - close(fd); - - cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); -} - -union -{ - struct cdrom_msf *msf; - char b[CD_FRAMESIZE_RAW]; -} raw_read_params; - -static int lba_to_msf(int lba) -{ - return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); -} - -static int ioctl_sector_data_type(int sector, int ismsf) -{ - return 2; /* Always Mode 1 */ -} - -static void ioctl_readsector_raw(uint8_t *b, int sector) -{ - int err; - int imsf = lba_to_msf(sector); - int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (cdrom <= 0) - return; - - raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); - raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; - raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; - raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; - - /* This will read the actual raw sectors from the disc. */ - err = ioctl(cdrom, CDROMREADRAW, (void *) &raw_read_params); - if (err == -1) - { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return; - } - - memcpy(b, raw_read_params.b, 2352); - - close(cdrom); - - free(raw_read_params.msf); -} - -static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - int len=4; - long size; - int c,d; - uint32_t temp; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - ioctl_cd_state = CD_STOPPED; - - tocvalid = read_toc(fd, toc); - - close(fd); - - if (!tocvalid) - return 4; - -// pclog("Read TOC done! %i\n",single); - b[2] = first_track; - b[3] = last_track; - d = 0; -//pclog("Read TOC starttrack=%i\n", starttrack); - for (c = 1; c <= last_track; c++) - { - if (toc[c].cdte_track >= starttrack) - { - d = c; - break; - } - } - b[2] = toc[c].cdte_track; - last_block = 0; - for (c = d; c <= last_track; c++) - { - uint32_t address; - if ((len + 8) > maxlen) - break; -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); - b[len++] = 0; /*Reserved*/ - b[len++] = (toc[c].cdte_adr << 4) | toc[c].cdte_ctrl; - b[len++] = toc[c].cdte_track; - b[len++] = 0; /*Reserved*/ - address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - if (address > last_block) - last_block = address; - - if (msf) - { - b[len++] = 0; - b[len++] = toc[c].cdte_addr.msf.minute; - b[len++] = toc[c].cdte_addr.msf.second; - b[len++] = toc[c].cdte_addr.msf.frame; - } - else - { - temp = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - if (single) - break; - } - b[0] = (uint8_t)(((len-2) >> 8) & 0xff); - b[1] = (uint8_t)((len-2) & 0xff); -/* pclog("Table of Contents (%i bytes) : \n", size); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); - for (c = 0;c <= last_track; c++) - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ - return len; -} - -static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) -{ - struct cdrom_multisession session; - int len = 4; - int err; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); - - if (fd <= 0) - return 0; - - session.addr_format = CDROM_MSF; - err = ioctl(fd, CDROMMULTISESSION, &session); - - if (err == -1) - { - close(fd); - return 0; - } - - b[2] = 0; - b[3] = 0; - b[len++] = 0; /*Reserved*/ - b[len++] = (toc[0].cdte_adr << 4) | toc[0].cdte_ctrl; - b[len++] = toc[0].cdte_track; - b[len++] = 0; /*Reserved*/ - if (msf) - { - b[len++] = 0; - b[len++] = session.addr.msf.minute; - b[len++] = session.addr.msf.second; - b[len++] = session.addr.msf.frame; - } - else - { - uint32_t temp = MSFtoLBA(session.addr.msf.minute, session.addr.msf.second, session.addr.msf.frame); - b[len++] = temp >> 24; - b[len++] = temp >> 16; - b[len++] = temp >> 8; - b[len++] = temp; - } - - return len; -} - -static int ioctl_readtoc_raw(unsigned char *b, int maxlen) -{ - struct cdrom_tochdr toc_hdr; - struct cdrom_tocentry toc2[100]; - int track, err; - int len = 4; - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); -//pclog("read_toc\n"); - if (fd <= 0) - return 0; - - err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); - if (err == -1) - { - pclog("read_toc: CDROMREADTOCHDR failed\n"); - return 0; - } - - b[2] = toc_hdr.cdth_trk0; - b[3] = toc_hdr.cdth_trk1; - - //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(toc, 0, sizeof(toc)); - - for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) - { - if ((len + 11) > maxlen) - { - pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); - close(fd); - return len; - } - - toc2[track].cdte_track = track; - toc2[track].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc2[track]); - if (err == -1) - { -// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); - close(fd); - return 0; - } -// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); - - b[len++] = toc2[track].cdte_track; - b[len++]= (toc2[track].cdte_adr << 4) | toc[track].cdte_ctrl; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++]=0; - b[len++] = toc2[track].cdte_addr.msf.minute; - b[len++] = toc2[track].cdte_addr.msf.second; - b[len++] = toc2[track].cdte_addr.msf.frame; - } - close(fd); - return len; -} - -static uint32_t ioctl_size() -{ - return cdrom_capacity; -} - -static int ioctl_status() -{ - if (!(ioctl_ready) && (cdrom_drive <= 0)) return CD_STATUS_EMPTY; - - switch(ioctl_cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - return CD_STATUS_STOPPED; - } -} -void ioctl_reset() -{ - int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); -//pclog("ioctl_reset: fd=%i\n", fd); - tocvalid = 0; - - if (fd <= 0) - return; - - tocvalid = read_toc(fd, toc); - - close(fd); -} - -int ioctl_open(char d) -{ - atapi=&ioctl_atapi; - return 0; -} - -void ioctl_close(void) -{ -} - -static void ioctl_exit(void) -{ - ioctl_stop(); - ioctl_inited = 0; - tocvalid=0; -} - -static ATAPI ioctl_atapi= -{ - ioctl_ready, - ioctl_medium_changed, - ioctl_readtoc, - ioctl_readtoc_session, - ioctl_readtoc_raw, - ioctl_getcurrentsubchannel, - NULL, - NULL, - NULL, - ioctl_sector_data_type, - ioctl_readsector_raw, - ioctl_playaudio, - ioctl_seek, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit -}; diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c deleted file mode 100644 index 98c7cc538..000000000 --- a/src/cdrom-ioctl.c +++ /dev/null @@ -1,1099 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Win32 CD-ROM support via IOCTL*/ - -#define WINVER 0x0600 -#include -#include -#include "ntddcdrm.h" -#include "ntddscsi.h" -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" -#include "scsi.h" - -#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) - -static CDROM ioctl_cdrom; - -typedef struct -{ - HANDLE hIOCTL; - CDROM_TOC toc; -} cdrom_ioctl_windows_t; - -cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; - -enum -{ - CD_STOPPED = 0, - CD_PLAYING, - CD_PAUSED -}; - -int cdrom_ioctl_do_log = 0; - -void cdrom_ioctl_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_LOG - if (cdrom_ioctl_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void ioctl_audio_callback(uint8_t id, int16_t *output, int len) -{ - RAW_READ_INFO in; - DWORD count; - - if (cdrom_ioctl[id].cd_state != CD_PLAYING) - { - memset(output, 0, len * 2); - return; - } - while (cdrom_ioctl[id].cd_buflen < len) - { - if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) - { - in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; - in.DiskOffset.HighPart = 0; - in.SectorCount = 1; - in.TrackMode = CDDA; - ioctl_open(id, 0); - if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) - { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; - } - else - { - cdrom[id].seek_pos++; - cdrom_ioctl[id].cd_buflen += (2352 / 2); - } - ioctl_close(id); - } - else - { - memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl[id].cd_buflen = len; - } - } - memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); - memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); - cdrom_ioctl[id].cd_buflen -= len; -} - -void ioctl_audio_stop(uint8_t id) -{ - cdrom_ioctl[id].cd_state = CD_STOPPED; -} - -static int get_track_nr(uint8_t id, uint32_t pos) -{ - int c; - int track = 0; - - if (!cdrom_ioctl[id].tocvalid) - { - return 0; - } - - if (cdrom_ioctl[id].last_track_pos == pos) - { - return cdrom_ioctl[id].last_track_nr; - } - - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + - (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); - - if (track_address <= pos) - { - track = c; - } - } - cdrom_ioctl[id].last_track_pos = pos; - cdrom_ioctl[id].last_track_nr = track; - - return track; -} - -static uint32_t get_track_msf(uint8_t id, uint32_t track_no) -{ - int c; - - if (!cdrom_ioctl[id].tocvalid) - { - return 0; - } - - for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - if (c == track_no) - { - return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); - } - } - return 0xffffffff; -} - -static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) -{ - int m = 0, s = 0, f = 0; - uint32_t start_msf = 0, end_msf = 0; - if (!cdrom_drives[id].host_drive) - { - return; - } - if (ismsf == 2) - { - start_msf = get_track_msf(id, pos); - end_msf = get_track_msf(id, len); - if (start_msf == 0xffffffff) - { - return; - } - if (end_msf == 0xffffffff) - { - return; - } - m = (start_msf >> 16) & 0xff; - s = (start_msf >> 8) & 0xff; - f = start_msf & 0xff; - pos = MSFtoLBA(m, s, f); - m = (end_msf >> 16) & 0xff; - s = (end_msf >> 8) & 0xff; - f = end_msf & 0xff; - len = MSFtoLBA(m, s, f); - } - else if (ismsf == 1) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - - if (pos == 0xffffff) - { - cdrom_ioctl_log("Playing from current position (MSF)\n"); - pos = cdrom[id].seek_pos; - } - else - { - pos = MSFtoLBA(m, s, f); - } - - m = (len >> 16) & 0xff; - s = (len >> 8) & 0xff; - f = len & 0xff; - len = MSFtoLBA(m, s, f); - } - else if (ismsf == 0) - { - if (pos == 0xffffffff) - { - cdrom_ioctl_log("Playing from current position\n"); - pos = cdrom[id].seek_pos; - } - len += pos; - } - cdrom[id].seek_pos = pos; - cdrom_ioctl[id].cd_end = len; - if (cdrom[id].seek_pos < 150) - { - /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ - cdrom[id].seek_pos = 150; - } - cdrom_ioctl[id].cd_state = CD_PLAYING; -} - -static void ioctl_pause(uint8_t id) -{ - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl[id].cd_state == CD_PLAYING) - { - cdrom_ioctl[id].cd_state = CD_PAUSED; - } -} - -static void ioctl_resume(uint8_t id) -{ - if (!cdrom_drives[id].host_drive) - { - return; - } - if (cdrom_ioctl[id].cd_state == CD_PAUSED) - { - cdrom_ioctl[id].cd_state = CD_PLAYING; - } -} - -static void ioctl_stop(uint8_t id) -{ - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; -} - -static int ioctl_ready(uint8_t id) -{ - unsigned long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); - if (!temp) - { - return 0; - } - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || - !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - } - return 1; - } - return 1; -} - -static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) -{ - unsigned long size; - int c, d = 0; - CDROM_TOC lbtoc; - int lb = 0; - if (!cdrom_drives[id].host_drive) - { - return 0; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); - ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; - for (c=d; c <= lbtoc.LastTrack; c++) - { - uint32_t address; - address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - if (address > lb) - { - lb = address; - } - } - return lb; -} - -static int ioctl_medium_changed(uint8_t id) -{ - unsigned long size; - int temp; - CDROM_TOC ltoc; - if (!cdrom_drives[id].host_drive) - { - return 0; /* This will be handled by the not ready handler instead. */ - } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); - ioctl_close(id); - if (!temp) - { - return 0; /* Drive empty, a not ready handler matter, not disc change. */ - } - if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; - if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - } - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; - } - else - { - if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || - (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || - (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) - { - cdrom_ioctl[id].cd_state = CD_STOPPED; - cdrom_ioctl_log("Setting TOC...\n"); - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); - return 1; /* TOC mismatches. */ - } - } - return 0; /* None of the above, return 0. */ -} - -static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - CDROM_SUB_Q_DATA_FORMAT insub; - SUB_Q_CHANNEL_DATA sub; - unsigned long size; - int pos = 0, track; - uint32_t cdpos, track_address, dat; - - if (!cdrom_drives[id].host_drive) return 0; - - cdpos = cdrom[id].seek_pos; - - if (cdrom_ioctl[id].last_subchannel_pos == cdpos) - { - memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); - memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); - } - else - { - insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); - ioctl_close(id); - memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); - memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); - memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); - memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); - cdrom_ioctl[id].last_subchannel_pos = cdpos; - } - - if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) - { - track = get_track_nr(id, cdpos); - track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); - - cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); - - b[pos++] = sub.CurrentPosition.Control; - b[pos++] = track + 1; - b[pos++] = sub.CurrentPosition.IndexNumber; - - if (msf) - { - dat = cdpos; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - dat = cdpos - track_address; - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; - b[pos] = 0; - pos += 4; - } - else - { - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - cdpos -= track_address; - b[pos++] = (cdpos >> 24) & 0xff; - b[pos++] = (cdpos >> 16) & 0xff; - b[pos++] = (cdpos >> 8) & 0xff; - b[pos++] = cdpos & 0xff; - } - - if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; - return 0x12; - } - - b[pos++]=sub.CurrentPosition.Control; - b[pos++]=sub.CurrentPosition.TrackNumber; - b[pos++]=sub.CurrentPosition.IndexNumber; - - cdrom_ioctl_log("cdpos = %i, track_address = %i\n", MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]), MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3])); - - if (msf) - { - int c; - for (c = 0; c < 4; c++) - { - b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; - } - for (c = 0; c < 4; c++) - { - b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; - } - } - else - { - uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } - - return 0x13; -} - -static void ioctl_eject(uint8_t id) -{ - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); -} - -static void ioctl_load(uint8_t id) -{ - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); - ioctl_close(id); - cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); -} - -static int is_track_audio(uint8_t id, uint32_t pos) -{ - int c; - int control = 0; - - uint32_t track_address = 0; - - if (!cdrom_ioctl[id].tocvalid) - { - return 0; - } - - for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) - { - track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); - - if (track_address <= pos) - { - control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; - } - } - - if ((control & 0xd) <= 1) - { - return 1; - } - else - { - return 0; - } -} - -static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - int m = 0, s = 0, f = 0; - - if (ismsf) - { - m = (pos >> 16) & 0xff; - s = (pos >> 8) & 0xff; - f = pos & 0xff; - pos = MSFtoLBA(m, s, f); - } - else - { - pos += 150; - } - return is_track_audio(id, pos); -} - -/* 00, 08, 10, 18, 20, 28, 30, 38 */ -int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ - 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ - { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ - 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ - -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ - -296, -296, 2048, 2048, 24, -296, 2064, 2352 }, /* C0-F8 */ - { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ - 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ - -296, -296, 2336, 2336, 24, -296, 2352, 2352 }, /* C0-F8 */ - { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ - 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ - -296, -296, -296, -296, 24, -296, 2072, 2352 }, /* C0-F8 */ - { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ - 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ - -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ - -296, -296, -296, -296, 24, -296, 2352, 2352 } /* C0-F8 */ - }; - -static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf); - -static void cdrom_illegal_mode(uint8_t id) -{ - cdrom_sense_key = SENSE_ILLEGAL_REQUEST; - cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; - cdrom_ascq = 0; -} - -struct sptd_with_sense -{ - SCSI_PASS_THROUGH s; - ULONG Filler; - UCHAR sense[32]; - UCHAR data[65536]; -} sptd; - -static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) -{ - int sector_type = 0; - int temp_len = 0; - - if (no_length_check) - { - switch (cdb[0]) - { - case 0x25: - /* READ CAPACITY */ - return 8; - case 0x42: /* READ SUBCHANNEL */ - case 0x43: /* READ TOC */ - case 0x51: /* READ DISC INFORMATION */ - case 0x52: /* READ TRACK INFORMATION */ - case 0x5A: /* MODE SENSE (10) */ - return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); - default: - return 65534; - } - } - - switch (cdb[0]) - { - case 0x25: - /* READ CAPACITY */ - return 8; - case 0x42: /* READ SUBCHANNEL */ - case 0x43: /* READ TOC */ - case 0x51: /* READ DISC INFORMATION */ - case 0x52: /* READ TRACK INFORMATION */ - case 0x5A: /* MODE SENSE (10) */ - return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); - case 0x08: - case 0x28: - case 0xa8: - /* READ (6), READ (10), READ (12) */ - return 2048 * number_of_blocks; - break; - case 0xb9: - sector_type = (cdb[1] >> 2) & 7; - if (sector_type == 0) - { - sector_type = ioctl_get_sector_data_type(id, 0, cdb[3], cdb[4], cdb[5], 1); - if (sector_type == 0) - { - cdrom_illegal_mode(id); - return -1; - } - } - goto common_handler; - case 0xbe: - /* READ CD MSF, READ CD */ - sector_type = (cdb[1] >> 2) & 7; - if (sector_type == 0) - { - sector_type = ioctl_get_sector_data_type(id, cdb[2], cdb[3], cdb[4], cdb[5], 0); - if (sector_type == 0) - { - cdrom_illegal_mode(id); - return -1; - } - } -common_handler: - temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; - if ((cdb[9] & 6) == 2) - { - temp_len += 294; - } - else if ((cdb[9] & 6) == 4) - { - temp_len += 296; - } - if ((cdb[10] & 7) == 1) - { - temp_len += 96; - } - else if ((cdb[10] & 7) == 2) - { - temp_len += 16; - } - else if ((cdb[10] & 7) == 4) - { - temp_len += 96; - } - if (temp_len <= 0) - { - cdrom_illegal_mode(id); - return -1; - } - return temp_len * cdrom[id].requested_blocks; - break; - default: - /* Other commands */ - return 65534; - break; - } - -} - -static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) -{ - DWORD ioctl_bytes; - int ioctl_rv = 0; - - SCSISense.SenseKey = 0; - SCSISense.Asc = 0; - SCSISense.Ascq = 0; - - *len = 0; - memset(&sptd, 0, sizeof(sptd)); - sptd.s.Length = sizeof(SCSI_PASS_THROUGH); - sptd.s.CdbLength = 12; - sptd.s.DataIn = SCSI_IOCTL_DATA_IN; - sptd.s.TimeOutValue = 80 * 60; - sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); - sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; - sptd.s.SenseInfoLength = 32; - sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; - - memcpy(sptd.s.Cdb, cdb, 12); - ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); - - if (sptd.s.SenseInfoLength) - { - cdrom_sense_key = sptd.sense[2]; - cdrom_asc = sptd.sense[12]; - cdrom_ascq = sptd.sense[13]; - } - - cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); - cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); - cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); - cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); - cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); - cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); - *len = sptd.s.DataTransferLength; - if (sptd.s.DataTransferLength != 0) - { - memcpy(buf, sptd.data, sptd.s.DataTransferLength); - } - - return ioctl_rv; -} - -static void ioctl_read_capacity(uint8_t id, uint8_t *b) -{ - uint32_t len = 0; - - const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - UCHAR buf[16]; - - if (!cdrom_ioctl[id].capacity_read) - { - ioctl_open(id, 0); - - SCSICommand(id, cdb, buf, &len, 1); - - memcpy(cdrom_ioctl[id].rcbuf, buf, len); - cdrom_ioctl[id].capacity_read = 1; - } - else - { - memcpy(b, cdrom_ioctl[id].rcbuf, 16); - } - - ioctl_close(id); -} - -static int ioctl_media_type_id(uint8_t id) -{ - uint8_t old_sense[3] = { 0, 0, 0 }; - - UCHAR msbuf[28]; - uint32_t len = 0; - int sense = 0; - - const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; - - old_sense[0] = cdrom_sense_key; - old_sense[1] = cdrom_asc; - old_sense[2] = cdrom_asc; - - ioctl_open(id, 0); - - SCSICommand(id, cdb, msbuf, &len, 1); - - ioctl_close(id); - - sense = cdrom_sense_key; - cdrom_sense_key = old_sense[0]; - cdrom_asc = old_sense[1]; - cdrom_asc = old_sense[2]; - - if (sense == 0) - { - return msbuf[2]; - } - else - { - return 3; - } -} - -static uint32_t msf_to_lba32(int lba) -{ - int m = (lba >> 16) & 0xff; - int s = (lba >> 8) & 0xff; - int f = lba & 0xff; - return (m * 60 * 75) + (s * 75) + f; -} - -static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) -{ - int i = 0; - int ioctl_rv = 0; - - uint32_t len = 0; - - for (i = 2; i <= 5; i++) - { - cdb[1] = i << 2; - ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ - if (ioctl_rv) - { - return i; - } - } - return 0; -} - -static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) -{ - int ioctl_rv = 0; - UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; - UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; - UCHAR buf[2352]; - - cdb_lba[2] = (sector >> 24); - cdb_lba[3] = ((sector >> 16) & 0xff); - cdb_lba[4] = ((sector >> 8) & 0xff); - cdb_lba[5] = (sector & 0xff); - - cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); - cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); - cdb_msf[5] = cdb_msf[8] = (sector & 0xff); - - ioctl_open(id, 0); - - if (ioctl_is_track_audio(id, sector, ismsf)) - { - return 1; - } - - if (ismsf) - { - ioctl_rv = ioctl_get_type(id, cdb_msf, buf); - } - else - { - ioctl_rv = ioctl_get_type(id, cdb_lba, buf); - } - - if (ioctl_rv) - { - ioctl_close(id); - return ioctl_rv; - } - - if (ismsf) - { - sector = msf_to_lba32(sector); - if (sector < 150) - { - ioctl_close(id); - return 0; - } - sector -= 150; - ioctl_rv = ioctl_get_type(id, (UCHAR *) cdb_lba, buf); - } - - ioctl_close(id); - return ioctl_rv; -} - -static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) -{ - int sector = b3; - sector |= ((uint32_t) b2) << 8; - sector |= ((uint32_t) b1) << 16; - sector |= ((uint32_t) b0) << 24; - return ioctl_sector_data_type(id, sector, ismsf); -} - -static void ioctl_validate_toc(uint8_t id) -{ - unsigned long size; - if (!cdrom_drives[id].host_drive) - { - return; - } - cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); - cdrom_ioctl_log("Validating TOC...\n"); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); - ioctl_close(id); - cdrom_ioctl[id].tocvalid=1; -} - -UCHAR buf[262144]; - -static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) -{ - const UCHAR cdb[12]; - - int ret = 0; - - int block_length = 0; - - int temp_block_length = 0; - int temp_pos = 0; - - int blocks_at_once = 0; - int buffer_pos = 0; - - int transferred_blocks = 0; - - uint32_t temp_len = 0; - int chunk = 0; - - if (in_cdb[0] == 0x43) - { - /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ - ioctl_validate_toc(id); - } - - ioctl_open(id, 0); - - memcpy((void *) cdb, in_cdb, 12); - - temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); - *len = 0; - if (temp_block_length != -1) - { - if (temp_block_length > 65534) - { - block_length = temp_block_length / cdrom[id].requested_blocks; - blocks_at_once = 32768 / block_length; - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer into chunks of %i blocks...\n", id, temp_block_length, blocks_at_once); - - buffer_pos = 0; - temp_pos = cdrom[id].sector_pos; - transferred_blocks = 0; - temp_len = 0; - -split_block_read_iterate: - chunk = (cdrom[id].requested_blocks - transferred_blocks); - if (chunk < blocks_at_once) - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is less than a complete split block\n", id, chunk); - cdrom_ioctl[id].actual_requested_blocks = chunk; - } - else - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is more or equal than a complete split block\n", id, chunk); - cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; - } - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); - cdrom_update_cdb((uint8_t *) cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); - ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); - *len += temp_len; - transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; - if (ret && (transferred_blocks < cdrom[id].requested_blocks)) - { - /* Return value was successful and there are still more blocks left to transfer. */ - temp_pos += cdrom_ioctl[id].actual_requested_blocks; - buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); - goto split_block_read_iterate; - } - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Split transfer done\n", id); - } - else - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length); - cdrom_ioctl[id].actual_requested_blocks = cdrom[id].requested_blocks; - ret = SCSICommand(id, cdb, buf, len, 0); - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id); - } - memcpy(b, buf, *len); - } - else - { - cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); - } - - cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); - - ioctl_close(id); - - cdrom_ioctl_log("IOCTL Returned value: %i\n", ret); - - return ret; -} - -static uint32_t ioctl_size(uint8_t id) -{ - uint8_t capacity_buffer[8]; - uint32_t capacity = 0; - ioctl_read_capacity(id, capacity_buffer); - capacity = ((uint32_t) capacity_buffer[0]) << 24; - capacity |= ((uint32_t) capacity_buffer[1]) << 16; - capacity |= ((uint32_t) capacity_buffer[2]) << 8; - capacity |= (uint32_t) capacity_buffer[3]; - return capacity + 1; -} - -static int ioctl_status(uint8_t id) -{ - if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) - { - return CD_STATUS_EMPTY; - } - - switch(cdrom_ioctl[id].cd_state) - { - case CD_PLAYING: - return CD_STATUS_PLAYING; - case CD_PAUSED: - return CD_STATUS_PAUSED; - case CD_STOPPED: - return CD_STATUS_STOPPED; - default: - return CD_STATUS_EMPTY; - } -} - -void ioctl_reset(uint8_t id) -{ - CDROM_TOC ltoc; - unsigned long size; - - if (!cdrom_drives[id].host_drive) - { - cdrom_ioctl[id].tocvalid = 0; - return; - } - - ioctl_open(id, 0); - DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); - - cdrom_ioctl_windows[id].toc = ltoc; - cdrom_ioctl[id].tocvalid = 1; -} - -int ioctl_open(uint8_t id, char d) -{ - if (!cdrom_ioctl[id].ioctl_inited) - { - sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - cdrom_ioctl[id].tocvalid=0; - } - cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); - cdrom_drives[id].handler = &ioctl_cdrom; - if (!cdrom_ioctl[id].ioctl_inited) - { - cdrom_ioctl[id].ioctl_inited=1; - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - update_status_bar_icon_state(0x10 | id, 0); - } - return 0; -} - -void ioctl_close(uint8_t id) -{ - if (cdrom_ioctl_windows[id].hIOCTL) - { - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - } -} - -static void ioctl_exit(uint8_t id) -{ - ioctl_stop(id); - cdrom_ioctl[id].ioctl_inited=0; - cdrom_ioctl[id].tocvalid=0; -} - -static CDROM ioctl_cdrom= -{ - ioctl_ready, - ioctl_medium_changed, - ioctl_media_type_id, - ioctl_audio_callback, - ioctl_audio_stop, - NULL, - NULL, - NULL, - ioctl_getcurrentsubchannel, - ioctl_pass_through, - NULL, - ioctl_playaudio, - ioctl_load, - ioctl_eject, - ioctl_pause, - ioctl_resume, - ioctl_size, - ioctl_status, - ioctl_is_track_audio, - ioctl_stop, - ioctl_exit -}; diff --git a/src/cdrom-ioctl.h b/src/cdrom-ioctl.h deleted file mode 100644 index e39f12ddf..000000000 --- a/src/cdrom-ioctl.h +++ /dev/null @@ -1,17 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_IOCTL_H -#define CDROM_IOCTL_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern uint32_t cdrom_capacity; - -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); - -extern void ioctl_close(uint8_t id); - -#endif /* ! CDROM_IOCTL_H */ diff --git a/src/cdrom-null.c b/src/cdrom-null.c deleted file mode 100644 index f7d117077..000000000 --- a/src/cdrom-null.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" - -static CDROM null_cdrom; - -static int null_ready(uint8_t id) -{ - return 0; -} - -/* Always return 0, the contents of a null CD-ROM drive never change. */ -static int null_medium_changed(uint8_t id) -{ - return 0; -} - -static uint8_t null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - return 0x13; -} - -static void null_eject(uint8_t id) -{ -} - -static void null_load(uint8_t id) -{ -} - -static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - *len = 0; - return 0; -} - -static int null_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) -{ - return 0; -} - -static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - return 0; -} - -static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) -{ - return 0; -} - -static uint32_t null_size(uint8_t id) -{ - return 0; -} - -static int null_status(uint8_t id) -{ - return CD_STATUS_EMPTY; -} - -void cdrom_null_reset(uint8_t id) -{ -} - -void cdrom_set_null_handler(uint8_t id); - -int cdrom_null_open(uint8_t id, char d) -{ - cdrom_set_null_handler(id); - return 0; -} - -void null_close(uint8_t id) -{ -} - -static void null_exit(uint8_t id) -{ -} - -static int null_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - return 0; -} - -static int null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) -{ - return 0; -} - -static int null_media_type_id(uint8_t id) -{ - return 0x70; -} - -void cdrom_set_null_handler(uint8_t id) -{ - cdrom_drives[id].handler = &null_cdrom; - cdrom_drives[id].host_drive = 0; - update_status_bar_icon_state(0x10 | id, 1); -} - -static CDROM null_cdrom = -{ - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, - null_readtoc, - null_readtoc_session, - null_readtoc_raw, - null_getcurrentsubchannel, - null_pass_through, - null_readsector_raw, - NULL, - null_load, - null_eject, - NULL, - NULL, - null_size, - null_status, - null_is_track_audio, - NULL, - null_exit -}; diff --git a/src/cdrom-null.h b/src/cdrom-null.h deleted file mode 100644 index 7217760ca..000000000 --- a/src/cdrom-null.h +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#ifndef CDROM_NULL_H -#define CDROM_NULL_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -int cdrom_null_open(uint8_t id, char d); -void cdrom_null_reset(uint8_t id); -void null_close(uint8_t id); - -#endif /* ! CDROM_NULL_H */ diff --git a/src/config.c b/src/config.c index 8796c7061..a24772e19 100644 --- a/src/config.c +++ b/src/config.c @@ -23,9 +23,9 @@ #include "mouse.h" #include "network.h" #include "nvr.h" -#include "plat-joystick.h" -#include "plat-midi.h" #include "scsi.h" +#include "plat_joystick.h" +#include "plat_midi.h" #include "sound/snd_dbopl.h" #include "sound/snd_opl.h" #include "sound/sound.h" @@ -37,7 +37,7 @@ #include #undef BITMAP #include "win.h" -#include "win-language.h" +#include "win_language.h" #endif @@ -82,6 +82,7 @@ typedef struct entry_t (new)->next = NULL; \ } + void config_dump(void) { section_t *current_section; @@ -109,7 +110,8 @@ void config_dump(void) } } -void config_free(void) + +static void config_free(void) { section_t *current_section; current_section = (section_t *)config_head.next; @@ -134,6 +136,7 @@ void config_free(void) } } + static wchar_t cfgbuffer[1024]; static char sname[256]; static char ename[256]; @@ -231,13 +234,13 @@ void config_load(wchar_t *fn) } - void config_new(void) { FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); fclose(f); } + static section_t *find_section(char *name) { section_t *current_section; @@ -257,6 +260,7 @@ static section_t *find_section(char *name) return NULL; } + static entry_t *find_entry(section_t *section, char *name) { entry_t *current_entry; @@ -273,6 +277,7 @@ static entry_t *find_entry(section_t *section, char *name) return NULL; } + static section_t *create_section(char *name) { section_t *new_section = malloc(sizeof(section_t)); @@ -284,6 +289,7 @@ static section_t *create_section(char *name) return new_section; } + static entry_t *create_entry(section_t *section, char *name) { entry_t *new_entry = malloc(sizeof(entry_t)); @@ -293,7 +299,8 @@ static entry_t *create_entry(section_t *section, char *name) return new_entry; } - + + int config_get_int(char *head, char *name, int def) { section_t *section; @@ -315,6 +322,7 @@ int config_get_int(char *head, char *name, int def) return value; } + int config_get_hex16(char *head, char *name, int def) { section_t *section; @@ -336,6 +344,7 @@ int config_get_hex16(char *head, char *name, int def) return value; } + char *config_get_string(char *head, char *name, char *def) { section_t *section; @@ -354,6 +363,7 @@ char *config_get_string(char *head, char *name, char *def) return entry->data; } + wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) { section_t *section; @@ -372,6 +382,7 @@ wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) return entry->wdata; } + void config_set_int(char *head, char *name, int val) { section_t *section; @@ -391,6 +402,7 @@ void config_set_int(char *head, char *name, int val) mbstowcs(entry->wdata, entry->data, 512); } + void config_set_hex16(char *head, char *name, int val) { section_t *section; @@ -410,6 +422,7 @@ void config_set_hex16(char *head, char *name, int val) mbstowcs(entry->wdata, entry->data, 512); } + void config_set_string(char *head, char *name, char *val) { section_t *section; @@ -429,6 +442,7 @@ void config_set_string(char *head, char *name, char *val) mbstowcs(entry->wdata, entry->data, 256); } + void config_set_wstring(char *head, char *name, wchar_t *val) { section_t *section; @@ -460,6 +474,7 @@ char *get_filename(char *s) return s; } + wchar_t *get_filename_w(wchar_t *s) { int c = wcslen(s) - 1; @@ -472,16 +487,19 @@ wchar_t *get_filename_w(wchar_t *s) return s; } + void append_filename(char *dest, char *s1, char *s2, int size) { sprintf(dest, "%s%s", s1, s2); } + void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size) { _swprintf(dest, L"%s%s", s1, s2); } + void put_backslash(char *s) { int c = strlen(s) - 1; @@ -489,6 +507,7 @@ void put_backslash(char *s) s[c] = '/'; } + void put_backslash_w(wchar_t *s) { int c = wcslen(s) - 1; @@ -496,6 +515,7 @@ void put_backslash_w(wchar_t *s) s[c] = L'/'; } + char *get_extension(char *s) { int c = strlen(s) - 1; @@ -512,6 +532,7 @@ char *get_extension(char *s) return &s[c+1]; } + wchar_t *get_extension_w(wchar_t *s) { int c = wcslen(s) - 1; @@ -528,8 +549,10 @@ wchar_t *get_extension_w(wchar_t *s) return &s[c+1]; } + static wchar_t wname[512]; + void config_save(wchar_t *fn) { FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); @@ -581,19 +604,21 @@ void config_save(wchar_t *fn) fclose(f); } -static char temps[512]; -void loadconfig_general(void) + +/* General */ +static void loadconfig_general(void) { + char *cat = "General"; + char temps[512]; wchar_t *wp; char *p; - /* General */ - vid_resize = !!config_get_int("General", "vid_resize", 0); + vid_resize = !!config_get_int(cat, "vid_resize", 0); - p = (char *)config_get_string("General", "vid_renderer", "d3d9"); - memset(temps, 0, 512); - if (p) + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "vid_renderer", "d3d9"); + if (p != NULL) { strcpy(temps, p); } @@ -606,27 +631,22 @@ void loadconfig_general(void) vid_api = 1; } - video_fullscreen_scale = config_get_int("General", "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int("General", "video_fullscreen_first", 1); + video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); - force_43 = !!config_get_int("General", "force_43", 0); - scale = !!config_get_int("General", "scale", 1); - enable_overscan = !!config_get_int("General", "enable_overscan", 0); + force_43 = !!config_get_int(cat, "force_43", 0); + scale = !!config_get_int(cat, "scale", 1); + enable_overscan = !!config_get_int(cat, "enable_overscan", 0); - p = config_get_string("General", "window_coordinates", "0, 0, 0, 0"); - if (p) - { - sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); - } - else - { - sscanf("0, 0, 0, 0", "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); - } - window_remember = config_get_int("General", "window_remember", 0); + p = config_get_string(cat, "window_coordinates", NULL); + if (p == NULL) + p = "0, 0, 0, 0"; + sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); + window_remember = config_get_int(cat, "window_remember", 0); - memset(nvr_path, 0, 2048); - wp = (wchar_t *)config_get_wstring("General", "nvr_path", L""); - if (wp) { + memset(nvr_path, 0x00, sizeof(nvr_path)); + wp = config_get_wstring(cat, "nvr_path", L""); + if (wp != NULL) { if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); else { @@ -649,31 +669,31 @@ void loadconfig_general(void) #ifndef __unix /* Currently, 86Box is English (US) only, but in the future (version 1.30 at the earliest) other languages will be added, therefore it is better to future-proof the code. */ - dwLanguage = config_get_hex16("General", "language", 0x0409); + dwLanguage = config_get_hex16(cat, "language", 0x0409); #endif } + +/* Machine */ static void loadconfig_machine(void) { + char *cat = "Machine"; char *p; - /* Machine */ - p = (char *)config_get_string("Machine", "model", ""); - if (p) + p = config_get_string(cat, "model", NULL); + if (p != NULL) model = model_get_model_from_internal_name(p); else model = 0; - if (model >= model_count()) model = model_count() - 1; romset = model_getromset(); - cpu_manufacturer = config_get_int("Machine", "cpu_manufacturer", 0); - cpu = config_get_int("Machine", "cpu", 0); + cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); + cpu = config_get_int(cat, "cpu", 0); + cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); - cpu_waitstates = config_get_int("Machine", "cpu_waitstates", 0); - - mem_size = config_get_int("Machine", "mem_size", 4096); + mem_size = config_get_int(cat, "mem_size", 4096); if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); if (mem_size > 1048576) @@ -681,66 +701,69 @@ static void loadconfig_machine(void) mem_size = 1048576; } - cpu_use_dynarec = !!config_get_int("Machine", "cpu_use_dynarec", 0); + cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); - enable_external_fpu = !!config_get_int("Machine", "cpu_enable_fpu", 0); + enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0); - enable_sync = !!config_get_int("Machine", "enable_sync", 1); + enable_sync = !!config_get_int(cat, "enable_sync", 1); } + +/* Video */ static void loadconfig_video(void) { + char *cat = "Video"; char *p; - /* Video */ - p = (char *)config_get_string("Video", "gfxcard", ""); - if (p) + p = config_get_string(cat, "gfxcard", NULL); + if (p != NULL) gfxcard = video_get_video_from_internal_name(p); else gfxcard = 0; - video_speed = config_get_int("Video", "video_speed", 3); + video_speed = config_get_int(cat, "video_speed", 3); - voodoo_enabled = !!config_get_int("Video", "voodoo", 0); + voodoo_enabled = !!config_get_int(cat, "voodoo", 0); } -static char s[512]; +/* Input devices */ static void loadconfig_input_devices(void) { + char *cat = "Input devices"; + char temps[512]; int c, d; char *p; - /* Input devices */ - p = (char *)config_get_string("Input devices", "mouse_type", ""); - if (p) + p = config_get_string(cat, "mouse_type", NULL); + if (p != NULL) mouse_type = mouse_get_from_internal_name(p); else mouse_type = 0; - joystick_type = config_get_int("Input devices", "joystick_type", 0); + joystick_type = config_get_int(cat, "joystick_type", 0); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int("Input devices", s, 0); + sprintf(temps, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int(cat, temps, 0); if (joystick_state[c].plat_joystick_nr) { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int("Input devices", s, d); + sprintf(temps, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int(cat, temps, d); } for (d = 0; d < joystick_get_button_count(joystick_type); d++) { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int("Input devices", s, d); + sprintf(temps, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int(cat, temps, d); } for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { - sprintf(s, "joystick_%i_pov_%i", c, d); - p = (char *)config_get_string("Input devices", s, "0, 0"); + sprintf(temps, "joystick_%i_pov_%i", c, d); + p = config_get_string(cat, temps, "0, 0"); joystick_state[c].pov_mapping[d][0] = joystick_state[c].pov_mapping[d][1] = 0; sscanf(p, "%i, %i", &joystick_state[c].pov_mapping[d][0], &joystick_state[c].pov_mapping[d][1]); } @@ -748,37 +771,41 @@ static void loadconfig_input_devices(void) } } + +/* Sound */ static void loadconfig_sound(void) { + char *cat = "Sound"; char *p; - /* Sound */ - p = (char *)config_get_string("Sound", "sndcard", ""); - if (p) + p = config_get_string(cat, "sndcard", NULL); + if (p != NULL) sound_card_current = sound_card_get_from_internal_name(p); else sound_card_current = 0; - midi_id = config_get_int("Sound", "midi_host_device", 0); + midi_id = config_get_int(cat, "midi_host_device", 0); - SSI2001 = !!config_get_int("Sound", "ssi2001", 0); - GAMEBLASTER = !!config_get_int("Sound", "gameblaster", 0); - GUS = !!config_get_int("Sound", "gus", 0); - opl3_type = !!config_get_int("Sound", "opl3_type", 1); + SSI2001 = !!config_get_int(cat, "ssi2001", 0); + GAMEBLASTER = !!config_get_int(cat, "gameblaster", 0); + GUS = !!config_get_int(cat, "gus", 0); + opl3_type = !!config_get_int(cat, "opl3_type", 1); } + +/* Network */ static void loadconfig_network(void) { + char *cat = "Network"; char *p; - /* Network */ - network_type = config_get_int("Network", "net_type", -1); - memset(pcap_dev, 0, 512); - p = (char *)config_get_string("Network", "net_pcap_device", "none"); - if (p) - if ((network_dev_to_id(p) == -1) || (netdev_num == 1)) + network_type = config_get_int(cat, "net_type", NET_TYPE_NONE); + memset(network_pcap, '\0', sizeof(network_pcap)); + p = config_get_string(cat, "net_pcap_device", "none"); + if (p != NULL) + if ((network_dev_to_id(p) == -1) || (network_ndev == 1)) { - if ((netdev_num == 1) && strcmp(pcap_dev, "none")) + if ((network_ndev == 1) && strcmp(network_pcap, "none")) { msgbox_error(ghwnd, 2107); } @@ -787,59 +814,59 @@ static void loadconfig_network(void) msgbox_error(ghwnd, 2200); } - strcpy(pcap_dev, "none"); + strcpy(network_pcap, "none"); } else { - strcpy(pcap_dev, p); + strcpy(network_pcap, p); } else - strcpy(pcap_dev, "none"); - p = (char *)config_get_string("Network", "net_card", NULL); - network_card = (p) ? network_card_get_from_internal_name(p) : 0; + strcpy(network_pcap, "none"); + p = config_get_string(cat, "net_card", NULL); + if (p != NULL) + network_card = network_card_get_from_internal_name(p); + else + network_card = 0; } + +/* Other peripherals */ static void loadconfig_other_peripherals(void) { - int c; + char *cat = "Other peripherals"; + char temps[512]; char *p; + int c; - /* Other peripherals */ - p = (char *)config_get_string("Other peripherals", "scsicard", ""); - if (p) + p = config_get_string(cat, "scsicard", NULL); + if (p != NULL) scsi_card_current = scsi_card_get_from_internal_name(p); else scsi_card_current = 0; - memset(hdd_controller_name, 0, 16); - p = (char *)config_get_string("Other peripherals", "hdd_controller", ""); - if (p) + memset(hdd_controller_name, '\0', sizeof(hdd_controller_name)); + p = config_get_string(cat, "hdd_controller", NULL); + if (p != NULL) strcpy(hdd_controller_name, p); else strcpy(hdd_controller_name, "none"); - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 2; c < 4; c++) { sprintf(temps, "ide_%02i", c + 1); - p = config_get_string("Other peripherals", temps, "0, 00"); - if (p) - { - sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]); - } - else - { - sscanf(p, "0, 00", &ide_enable[c], &ide_irq[c]); - } + p = config_get_string(cat, temps, NULL); + if (p == NULL) + p = "0, 00"; + sscanf(p, "%i, %02i", &ide_enable[c], &ide_irq[c]); } - serial_enabled[0] = !!config_get_int("Other peripherals", "serial1_enabled", 1); - serial_enabled[1] = !!config_get_int("Other peripherals", "serial2_enabled", 1); - lpt_enabled = !!config_get_int("Other peripherals", "lpt_enabled", 1); - bugger_enabled = !!config_get_int("Other peripherals", "bugger_enabled", 0); + serial_enabled[0] = !!config_get_int(cat, "serial1_enabled", 1); + serial_enabled[1] = !!config_get_int(cat, "serial2_enabled", 1); + lpt_enabled = !!config_get_int(cat, "lpt_enabled", 1); + bugger_enabled = !!config_get_int(cat, "bugger_enabled", 0); } -static char temps2[512]; static int config_string_to_bus(char *str, int cdrom) { @@ -917,26 +944,26 @@ no_mfm_cdrom: return 0; } + +/* Hard disks */ static void loadconfig_hard_disks(void) { + char *cat = "Hard disks"; + char temps[512]; + char temps2[512]; + char s[512]; int c; char *p; wchar_t *wp; - /* Hard disks */ - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < HDC_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); - p = (char *)config_get_string("Hard disks", temps, "0, 0, 0, none"); - if (p) - { - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); - } - else - { - sscanf("0, 0, 0, none", "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); - } + p = config_get_string(cat, temps, NULL); + if (p == NULL) + p = "0, 0, 0, none"; + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); hdc[c].bus = config_string_to_bus(s, 0); @@ -954,14 +981,14 @@ static void loadconfig_hard_disks(void) } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int("Hard disks", temps, 0); + hdc[c].mfm_channel = config_get_int(cat, temps, 0); if (hdc[c].mfm_channel > 1) { hdc[c].mfm_channel = 1; } sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int("Hard disks", temps, 0); + hdc[c].ide_channel = config_get_int(cat, temps, 0); if (hdc[c].ide_channel > 7) { hdc[c].ide_channel = 7; @@ -969,13 +996,14 @@ static void loadconfig_hard_disks(void) sprintf(temps, "hdd_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", c, 0); - p = (char *)config_get_string("Hard disks", temps, temps2); - if (p) + p = config_get_string(cat, temps, temps2); + if (p != NULL) { sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); } else { + /* FIXME: Can never happen, 'temps' above is non-NULL. */ sscanf(temps2, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); } @@ -990,7 +1018,8 @@ static void loadconfig_hard_disks(void) memset(hdd_fn[c], 0, 1024); sprintf(temps, "hdd_%02i_fn", c + 1); - wp = (wchar_t *)config_get_wstring("Hard disks", temps, L""); + wp = config_get_wstring(cat, temps, L""); + /*FIXME: wcslen(wp) instead of 512? */ if (wp) memcpy(hdd_fn[c], wp, 512); else { memcpy(hdd_fn[c], L"", 2); @@ -999,20 +1028,25 @@ static void loadconfig_hard_disks(void) } } + +/* Removable devices */ static void loadconfig_removable_devices(void) { + char *cat = "Removable devices"; + char temps[512]; + char temps2[512]; + char s[512]; int c; char *p; wchar_t *wp; - /* Removable devices */ for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - p = (char *)config_get_string("Removable devices", temps, (c < 2) ? "525_2dd" : "none"); + p = config_get_string(cat, temps, (c < 2) ? "525_2dd" : "none"); if (p) fdd_set_type(c, fdd_get_from_internal_name(p)); - else + else /*FIXME: never happens, "none" is non-NULL */ fdd_set_type(c, (c < 2) ? 2 : 0); if (fdd_get_type(c) > 13) { @@ -1020,7 +1054,8 @@ static void loadconfig_removable_devices(void) } sprintf(temps, "fdd_%02i_fn", c + 1); - wp = (wchar_t *)config_get_wstring("Removable devices", temps, L""); + wp = config_get_wstring(cat, temps, L""); + /*FIXME: see above, wcslen(wp) ? */ if (wp) memcpy(discfns[c], wp, 512); else { memcpy(discfns[c], L"", 2); @@ -1028,19 +1063,19 @@ static void loadconfig_removable_devices(void) } printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = !!config_get_int("Removable devices", temps, 0); + ui_writeprot[c] = !!config_get_int(cat, temps, 0); } memset(temps, 0, 512); for (c = 0; c < CDROM_NUM; c++) { sprintf(temps, "cdrom_%02i_host_drive", c + 1); - cdrom_drives[c].host_drive = config_get_int("Removable devices", temps, 0); + cdrom_drives[c].host_drive = config_get_int(cat, temps, 0); cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; sprintf(temps, "cdrom_%02i_parameters", c + 1); - p = (char *)config_get_string("Removable devices", temps, "0, none"); - if (p) + p = config_get_string(cat, temps, NULL); + if (p != NULL) { sscanf(p, "%u, %s", &cdrom_drives[c].sound_on, s); } @@ -1052,7 +1087,7 @@ static void loadconfig_removable_devices(void) cdrom_drives[c].bus_type = config_string_to_bus(s, 1); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int("Removable devices", temps, c + 2); + cdrom_drives[c].ide_channel = config_get_int(cat, temps, c + 2); if (cdrom_drives[c].ide_channel > 7) { cdrom_drives[c].ide_channel = 7; @@ -1060,12 +1095,12 @@ static void loadconfig_removable_devices(void) sprintf(temps, "cdrom_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", c + 2, 0); - p = (char *)config_get_string("Removable devices", temps, temps2); - if (p) + p = config_get_string(cat, temps, temps2); + if (p != NULL) { sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); } - else + else /*FIXME: never happens, 'temps2' is non-NULL */ { sscanf(temps2, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); } @@ -1081,8 +1116,9 @@ static void loadconfig_removable_devices(void) } sprintf(temps, "cdrom_%02i_image_path", c + 1); - wp = (wchar_t *)config_get_wstring("Removable devices", temps, L""); - if (wp) memcpy(cdrom_image[c].image_path, wp, 512); + wp = config_get_wstring(cat, temps, L""); + /*FIXME see above, wcslen(wp) */ + if (wp != NULL) memcpy(cdrom_image[c].image_path, wp, 512); else { memcpy(cdrom_image[c].image_path, L"", 2); cdrom_image[c].image_path[0] = L'\0'; @@ -1090,12 +1126,12 @@ static void loadconfig_removable_devices(void) } } + void loadconfig(wchar_t *fn) { - if (!fn) - config_load(config_file_default); - else - config_load(fn); + if (fn == NULL) + fn = config_file_default; + config_load(fn); /* General */ loadconfig_general(); @@ -1126,10 +1162,10 @@ void loadconfig(wchar_t *fn) } -wchar_t temp_nvr_path[1024]; wchar_t *nvr_concat(wchar_t *to_concat) { + static wchar_t temp_nvr_path[1024]; char *p; wchar_t *wp; @@ -1144,146 +1180,171 @@ wchar_t *nvr_concat(wchar_t *to_concat) return temp_nvr_path; } -void saveconfig_general(void) + +static void saveconfig_general(void) { - config_set_int("General", "vid_resize", vid_resize); + char *cat = "General"; + char temps[512]; + + config_set_int(cat, "vid_resize", vid_resize); switch(vid_api) { case 0: - config_set_string("General", "vid_renderer", "ddraw"); + config_set_string(cat, "vid_renderer", "ddraw"); break; case 1: default: - config_set_string("General", "vid_renderer", "d3d9"); + config_set_string(cat, "vid_renderer", "d3d9"); break; } - config_set_int("General", "video_fullscreen_scale", video_fullscreen_scale); - config_set_int("General", "video_fullscreen_first", video_fullscreen_first); + config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - config_set_int("General", "force_43", force_43); - config_set_int("General", "scale", scale); - config_set_int("General", "enable_overscan", enable_overscan); + config_set_int(cat, "force_43", force_43); + config_set_int(cat, "scale", scale); + config_set_int(cat, "enable_overscan", enable_overscan); sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); - config_set_string("General", "window_coordinates", temps); - config_set_int("General", "window_remember", window_remember); + config_set_string(cat, "window_coordinates", temps); + config_set_int(cat, "window_remember", window_remember); - config_set_wstring("General", "nvr_path", nvr_path); + config_set_wstring(cat, "nvr_path", nvr_path); #ifndef __unix - config_set_hex16("General", "language", dwLanguage); + config_set_hex16(cat, "language", dwLanguage); #endif } -void saveconfig_machine(void) -{ - /* Machine */ - config_set_string("Machine", "model", model_get_internal_name()); - config_set_int("Machine", "cpu_manufacturer", cpu_manufacturer); - config_set_int("Machine", "cpu", cpu); - config_set_int("Machine", "cpu_waitstates", cpu_waitstates); - config_set_int("Machine", "mem_size", mem_size); - config_set_int("Machine", "cpu_use_dynarec", cpu_use_dynarec); - config_set_int("Machine", "cpu_enable_fpu", enable_external_fpu); - config_set_int("Machine", "enable_sync", enable_sync); +/* Machine */ +static void saveconfig_machine(void) +{ + char *cat = "Machine"; + + config_set_string(cat, "model", model_get_internal_name()); + config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); + config_set_int(cat, "cpu", cpu); + config_set_int(cat, "cpu_waitstates", cpu_waitstates); + + config_set_int(cat, "mem_size", mem_size); + config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); + config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); + config_set_int(cat, "enable_sync", enable_sync); } -void saveconfig_video(void) + +/* Video */ +static void saveconfig_video(void) { - /* Video */ - config_set_string("Video", "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int("Video", "video_speed", video_speed); - config_set_int("Video", "voodoo", voodoo_enabled); + char *cat = "Video"; + + config_set_string(cat, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int(cat, "video_speed", video_speed); + config_set_int(cat, "voodoo", voodoo_enabled); } -void saveconfig_input_devices(void) + +/* Input devices */ +static void saveconfig_input_devices(void) { + char *cat = "Input devices"; + char temps[512]; + char s[512]; int c, d; - /* Input devices */ - config_set_string("Input devices", "mouse_type", mouse_get_internal_name(mouse_type)); + config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); - config_set_int("Input devices", "joystick_type", joystick_type); + config_set_int(cat, "joystick_type", joystick_type); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { sprintf(s, "joystick_%i_nr", c); - config_set_int("Input devices", s, joystick_state[c].plat_joystick_nr); + config_set_int(cat, s, joystick_state[c].plat_joystick_nr); if (joystick_state[c].plat_joystick_nr) { for (d = 0; d < joystick_get_axis_count(joystick_type); d++) { sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int("Input devices", s, joystick_state[c].axis_mapping[d]); + config_set_int(cat, s, joystick_state[c].axis_mapping[d]); } for (d = 0; d < joystick_get_button_count(joystick_type); d++) { sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int("Input devices", s, joystick_state[c].button_mapping[d]); + config_set_int(cat, s, joystick_state[c].button_mapping[d]); } for (d = 0; d < joystick_get_pov_count(joystick_type); d++) { sprintf(s, "joystick_%i_pov_%i", c, d); sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); - config_set_string("Input devices", s, temps); + config_set_string(cat, s, temps); } } } } -void saveconfig_sound(void) + +/* Sound */ +static void saveconfig_sound(void) { - /* Sound */ - config_set_string("Sound", "sndcard", sound_card_get_internal_name(sound_card_current)); + char *cat = "Sound"; - config_set_int("Sound", "midi_host_device", midi_id); + config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int("Sound", "gameblaster", GAMEBLASTER); - config_set_int("Sound", "gus", GUS); - config_set_int("Sound", "ssi2001", SSI2001); - config_set_int("Sound", "opl3_type", opl3_type); + config_set_int(cat, "midi_host_device", midi_id); + + config_set_int(cat, "gameblaster", GAMEBLASTER); + config_set_int(cat, "gus", GUS); + config_set_int(cat, "ssi2001", SSI2001); + config_set_int(cat, "opl3_type", opl3_type); } -void saveconfig_network(void) + +/* Network */ +static void saveconfig_network(void) { - /* Network */ - if (pcap_dev != NULL) + char *cat = "Network"; + + if (network_pcap[0] != '\0') { - config_set_string("Network", "net_pcap_device", pcap_dev); + config_set_string(cat, "net_pcap_device", network_pcap); } else { - config_set_string("Network", "net_pcap_device", "none"); + config_set_string(cat, "net_pcap_device", "none"); } - config_set_int("Network", "net_type", network_type); - config_set_string("Network", "net_card", network_card_get_internal_name(network_card)); + config_set_int(cat, "net_type", network_type); + config_set_string(cat, "net_card", network_card_get_internal_name(network_card)); } -void saveconfig_other_peripherals(void) + +/* Other peripherals */ +static void saveconfig_other_peripherals(void) { + char *cat = "Other peripherals"; + char temps[512]; + char temps2[512]; int c, d; - /* Other peripherals */ - config_set_string("Other peripherals", "scsicard", scsi_card_get_internal_name(scsi_card_current)); + config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - config_set_string("Other peripherals", "hdd_controller", hdd_controller_name); + config_set_string(cat, "hdd_controller", hdd_controller_name); - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 2; c < 4; c++) { sprintf(temps, "ide_%02i", c + 1); sprintf(temps2, "%i, %02i", !!ide_enable[c], ide_irq[c]); - config_set_string("Other peripherals", temps, temps2); + config_set_string(cat, temps, temps2); } - config_set_int("Other peripherals", "serial1_enabled", serial_enabled[0]); - config_set_int("Other peripherals", "serial2_enabled", serial_enabled[1]); - config_set_int("Other peripherals", "lpt_enabled", lpt_enabled); - config_set_int("Other peripherals", "bugger_enabled", bugger_enabled); + config_set_int(cat, "serial1_enabled", serial_enabled[0]); + config_set_int(cat, "serial2_enabled", serial_enabled[1]); + config_set_int(cat, "lpt_enabled", lpt_enabled); + config_set_int(cat, "bugger_enabled", bugger_enabled); } + static char *config_bus_to_string(int bus) { switch (bus) @@ -1307,74 +1368,84 @@ static char *config_bus_to_string(int bus) } } -void saveconfig_hard_disks(void) + +/* Hard disks */ +static void saveconfig_hard_disks(void) { + char *cat = "Hard disks"; + char temps[512]; + char temps2[512]; + char s[512]; int c, d; char *p; - /* Hard disks */ - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < HDC_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); - memset(s, 0, 512); + memset(s, '\0', sizeof(s)); p = config_bus_to_string(hdc[c].bus); sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, p); - config_set_string("Hard disks", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int("Hard disks", temps, hdc[c].mfm_channel); + config_set_int(cat, temps, hdc[c].mfm_channel); sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int("Hard disks", temps, hdc[c].ide_channel); + config_set_int(cat, temps, hdc[c].ide_channel); sprintf(temps, "hdd_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); - config_set_string("Hard disks", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring("Hard disks", temps, hdd_fn[c]); + config_set_wstring(cat, temps, hdd_fn[c]); } } -void saveconfig_removable_devices(void) + +/* Removable devices */ +static void saveconfig_removable_devices(void) { + char *cat = "Removable devices"; + char temps[512]; + char temps2[512]; int c, d; - /* Removable devices */ - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string("Removable devices", temps, fdd_get_internal_name(fdd_get_type(c))); + config_set_string(cat, temps, fdd_get_internal_name(fdd_get_type(c))); sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring("Removable devices", temps, discfns[c]); + config_set_wstring(cat, temps, discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int("Removable devices", temps, ui_writeprot[c]); + config_set_int(cat, temps, ui_writeprot[c]); } - memset(temps, 0, 512); + memset(temps, '\0', sizeof(temps)); for (c = 0; c < CDROM_NUM; c++) { sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int("Removable devices", temps, cdrom_drives[c].host_drive); + config_set_int(cat, temps, cdrom_drives[c].host_drive); sprintf(temps, "cdrom_%02i_parameters", c + 1); sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type)); - config_set_string("Removable devices", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int("Removable devices", temps, cdrom_drives[c].ide_channel); + config_set_int(cat, temps, cdrom_drives[c].ide_channel); sprintf(temps, "cdrom_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); - config_set_string("Removable devices", temps, temps2); + config_set_string(cat, temps, temps2); sprintf(temps, "cdrom_%02i_image_path", c + 1); - config_set_wstring("Removable devices", temps, cdrom_image[c].image_path); + config_set_wstring(cat, temps, cdrom_image[c].image_path); } } + void saveconfig(void) { int c, d; diff --git a/src/config.h b/src/config.h index 766257f37..fb33cd98d 100644 --- a/src/config.h +++ b/src/config.h @@ -1,37 +1,39 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -int config_get_int(char *head, char *name, int def); -char *config_get_string(char *head, char *name, char *def); -wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); -void config_set_int(char *head, char *name, int val); -void config_set_string(char *head, char *name, char *val); -void config_set_wstring(char *head, char *name, wchar_t *val); -char *get_filename(char *s); -wchar_t *get_filename_w(wchar_t *s); -void append_filename(char *dest, char *s1, char *s2, int size); -void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); -void put_backslash(char *s); -void put_backslash_w(wchar_t *s); -char *get_extension(char *s); + +extern wchar_t config_file_default[256]; + #ifdef __cplusplus extern "C" { #endif -wchar_t *get_extension_w(wchar_t *s); +extern int config_get_int(char *head, char *name, int def); +extern char *config_get_string(char *head, char *name, char *def); +extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); +extern void config_set_int(char *head, char *name, int val); +extern void config_set_string(char *head, char *name, char *val); +extern void config_set_wstring(char *head, char *name, wchar_t *val); + +extern char *get_filename(char *s); +extern wchar_t *get_filename_w(wchar_t *s); +extern void append_filename(char *dest, char *s1, char *s2, int size); +extern void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); +extern void put_backslash(char *s); +extern void put_backslash_w(wchar_t *s); +extern char *get_extension(char *s); + +extern wchar_t *get_extension_w(wchar_t *s); + +extern void config_load(wchar_t *fn); +extern void config_save(wchar_t *fn); +extern void config_dump(void); + +extern void loadconfig(wchar_t *fn); +extern void saveconfig(void); #ifdef __cplusplus } #endif - -void config_load(wchar_t *fn); -void config_save(wchar_t *fn); -void config_dump(void); -void config_free(void); - -extern wchar_t config_file_default[256]; - -void loadconfig(wchar_t *fn); -void saveconfig(void); diff --git a/src/gameport.c b/src/gameport.c index b75e9f6ce..a80d962b7 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -8,12 +8,12 @@ #include "device.h" #include "io.h" #include "timer.h" -#include "plat-joystick.h" #include "gameport.h" #include "joystick_ch_flightstick_pro.h" #include "joystick_standard.h" #include "joystick_sw_pad.h" #include "joystick_tm_fcs.h" +#include "plat_joystick.h" int joystick_type; diff --git a/src/joystick_ch_flightstick_pro.c b/src/joystick_ch_flightstick_pro.c index 9f0e97250..9697c1c6a 100644 --- a/src/joystick_ch_flightstick_pro.c +++ b/src/joystick_ch_flightstick_pro.c @@ -4,7 +4,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_standard.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + static void *ch_flightstick_pro_init() { diff --git a/src/joystick_standard.c b/src/joystick_standard.c index 7c8098ba7..c73260cac 100644 --- a/src/joystick_standard.c +++ b/src/joystick_standard.c @@ -4,7 +4,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_standard.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + static void *joystick_standard_init() { diff --git a/src/joystick_sw_pad.c b/src/joystick_sw_pad.c index 5fce2447a..d256c290f 100644 --- a/src/joystick_sw_pad.c +++ b/src/joystick_sw_pad.c @@ -26,7 +26,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_sw_pad.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + typedef struct { diff --git a/src/joystick_tm_fcs.c b/src/joystick_tm_fcs.c index a60e0ca5d..1380c052d 100644 --- a/src/joystick_tm_fcs.c +++ b/src/joystick_tm_fcs.c @@ -4,7 +4,8 @@ #include "timer.h" #include "gameport.h" #include "joystick_standard.h" -#include "plat-joystick.h" +#include "plat_joystick.h" + static void *tm_fcs_init() { diff --git a/src/keyboard.c b/src/keyboard.c index 22924f504..75ec25887 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2,7 +2,7 @@ see COPYING for more details */ #include "ibm.h" -#include "plat-keyboard.h" +#include "plat_keyboard.h" #include "keyboard.h" int keybsendcallback = 0; diff --git a/src/mouse_bus.c b/src/mouse_bus.c index ca2c4f80a..5d5d5e97e 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -32,7 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * Version: @(#)mouse_bus.c 1.0.4 2017/05/06 + * Version: @(#)mouse_bus.c 1.0.4 2017/05/17 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -44,7 +44,7 @@ #include "pic.h" #include "mouse.h" #include "mouse_bus.h" -#include "plat-mouse.h" +#include "plat_mouse.h" #define ENABLE_3BTN 1 /* enable 3-button mode */ diff --git a/src/mouse_ps2.c b/src/mouse_ps2.c index fa9eda980..d5627eda8 100644 --- a/src/mouse_ps2.c +++ b/src/mouse_ps2.c @@ -3,7 +3,8 @@ #include "keyboard_at.h" #include "mouse.h" #include "mouse_ps2.h" -#include "plat-mouse.h" +#include "plat_mouse.h" + int mouse_scan = 0; diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 0a4a66781..51fdd7b4e 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.3 2017/05/12 + * Version: @(#)net_ne2000.c 1.0.4 2017/05/17 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -49,9 +49,6 @@ typedef union { } bar_t; -/* This stuff should go into the struct. --FvK */ -static uint8_t maclocal[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; -static uint8_t maclocal_pci[6] = {0xac, 0xde, 0x48, 0x88, 0xbb, 0xaa}; #if ENABLE_NE2000_LOG static int nic_do_log = ENABLE_NE2000_LOG; #else @@ -216,6 +213,7 @@ typedef struct { int disable_netbios; int tx_timer_index; int tx_timer_active; + uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t pci_regs[256]; uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; @@ -1767,14 +1765,15 @@ nic_rom_init(nic_t *dev, wchar_t *s) } -uint32_t -ne2000_get_maclocal(void) +/* Return the 'local' part of our configured MAC address. */ +static uint32_t +nic_get_maclocal(nic_t *dev) { uint32_t temp; - temp = (((int) maclocal[3]) << 16); - temp |= (((int) maclocal[4]) << 8); - temp |= ((int) maclocal[5]); + temp = (((int) dev->maclocal[3]) << 16); + temp |= (((int) dev->maclocal[4]) << 8); + temp |= ((int) dev->maclocal[5]); return(temp); } @@ -1784,23 +1783,17 @@ static void * nic_init(int board) { uint32_t mac; - uint8_t *ptr; nic_t *dev; dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->board = board; dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; - if (board == NE2K_RTL8029AS) - { + if (board == NE2K_RTL8029AS) { strcpy(dev->name, "RTL8029AS"); - } - else if (board == NE2K_NE1000) - { + } else if (board == NE2K_NE1000) { strcpy(dev->name, "NE1000"); - } - else - { + } else { strcpy(dev->name, "NE2000"); } @@ -1812,32 +1805,35 @@ nic_init(int board) dev->base_address = device_get_config_int("addr"); } + /* See if we have a local MAC address configured. */ mac = device_get_config_int_ex("mac", -1); /* Set up our MAC address. */ if (dev->is_rtl8029as) { - maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - maclocal[1] = 0x20; - maclocal[2] = 0x18; + dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + dev->maclocal[1] = 0x20; + dev->maclocal[2] = 0x18; } else { - maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ - maclocal[1] = 0x00; - maclocal[2] = 0xD8; + dev->maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ + dev->maclocal[1] = 0x00; + dev->maclocal[2] = 0xD8; } - ptr = maclocal; -pclog(1, "MAClocal: mac=%08lx\n", mac); if (mac & 0xff000000) { /* Generating new MAC. */ - ptr[3] = disc_random_generate(); - ptr[4] = disc_random_generate(); - ptr[5] = disc_random_generate() | 1; - device_set_config_int("mac", ne2000_get_maclocal()); + dev->maclocal[3] = disc_random_generate(); + dev->maclocal[4] = disc_random_generate(); + dev->maclocal[5] = disc_random_generate() | 1; + device_set_config_int("mac", nic_get_maclocal(dev)); } else { - ptr[3] = (mac>>16) & 0xff; - ptr[4] = (mac>>8) & 0xff; - ptr[5] = (mac & 0xff) | 1; + dev->maclocal[3] = (mac>>16) & 0xff; + dev->maclocal[4] = (mac>>8) & 0xff; +#if 1 + dev->maclocal[5] = (mac & 0xfe); +#else + dev->maclocal[5] = (mac & 0xff) | 1; +#endif } - memcpy(dev->physaddr, ptr, 6); + memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); pclog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x BIOS=%d\n", dev->name, dev->base_address, dev->base_irq, diff --git a/src/net_ne2000.h b/src/net_ne2000.h index 4ff2fd0f6..44dcc3311 100644 --- a/src/net_ne2000.h +++ b/src/net_ne2000.h @@ -8,7 +8,7 @@ * * Definitions for the NE2000 ethernet controller. * - * Version: @(#)net_ne2000.h 1.0.2 2017/05/11 + * Version: @(#)net_ne2000.h 1.0.3 2017/05/17 * * Author: Fred N. van Kempen, */ @@ -26,11 +26,4 @@ extern device_t ne2000_device; extern device_t rtl8029as_device; -extern void ne2000_generate_maclocal(uint32_t mac); -extern uint32_t ne2000_get_maclocal(void); - -extern void ne2000_generate_maclocal_pci(uint32_t mac); -extern uint32_t ne2000_get_maclocal_pci(void); - - #endif /*NET_NE2000_H*/ diff --git a/src/net_pcap.c b/src/net_pcap.c index 459e04c71..5eb57bb4c 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.1 2017/05/11 + * Version: @(#)net_pcap.c 1.0.2 2017/05/17 * * Author: Fred N. van Kempen, */ @@ -29,9 +29,6 @@ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ - int netdev_num; - netdev_t netdev_list[512]; - #ifdef WALTJE int pcap_do_log = 1; @@ -108,8 +105,6 @@ poll_thread(void *arg) } -char pcap_dev[512]; - /* Initialize WinPcap for us. */ int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) @@ -135,11 +130,12 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) pclog("Initializing WinPcap, version %s\n", temp); /* Get the value of our capture interface. */ - if (pcap_dev == NULL) { + dev = network_pcap; + if ((dev[0] == '\0') || !strcmp(dev, "none")) { pclog(" No network device configured!\n"); return(-1); } - pclog(" Network interface: '%s'\n", pcap_dev); + pclog(" Network interface: '%s'\n", dev); pcap = pcap_open_live(dev, /* interface name */ 1518, /* maximum packet size */ @@ -227,16 +223,15 @@ network_devlist(netdev_t *list) pcap_if_t *devlist, *dev; int i = 0; - /* Note by Kotori: Add the first (and guaranteed to be always present) device - "None". */ + /* Create a first entry that's always there - needed by UI. */ strcpy(list->device, "none"); strcpy(list->description, "None"); - list++; - i++; + list++; i++; /* Retrieve the device list from the local machine */ if (pcap_findalldevs(&devlist, errbuf) == -1) { - pclog("NETWORK: error in pcap_findalldevs_ex: %s\n", errbuf); - return(i); /* Note by Kotori: The list will always have at least one entry - "None". */ + pclog("NETWORK: error in pcap_findalldevs: %s\n", errbuf); + return(i); } for (dev=devlist; dev!=NULL; dev=dev->next) { @@ -245,8 +240,7 @@ network_devlist(netdev_t *list) strcpy(list->description, dev->description); else memset(list->description, '\0', sizeof(list->description)); - list++; - i++; + list++; i++; } /* Release the memory. */ @@ -254,19 +248,3 @@ network_devlist(netdev_t *list) return(i); } - -int network_dev_to_id(char *dev) -{ - int i = 0; - - for (i = 0; i < netdev_num; i++) - { - if (!strcmp(netdev_list[i].device, dev)) - { - return i; - } - } - - /* If the device does not match the list, consider it as if it was set to "none". */ - return 0; -} \ No newline at end of file diff --git a/src/net_slirp.c b/src/net_slirp.c index 43574eccf..ca1d42869 100644 --- a/src/net_slirp.c +++ b/src/net_slirp.c @@ -8,7 +8,7 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.1 2017/05/11 + * Version: @(#)net_slirp.c 1.0.2 2017/05/17 * * Author: Fred N. van Kempen, */ @@ -29,7 +29,6 @@ static queueADT slirpq; /* SLiRP library handle */ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ -static int fizz; /* Instead of calling this and crashing some times @@ -38,27 +37,29 @@ static int fizz; static void slirp_tic(void) { - int ret2,nfds; + int ret2, nfds; struct timeval tv; fd_set rfds, wfds, xfds; int tmo; - nfds=-1; + /* Let SLiRP create a list of all open sockets. */ + nfds = -1; FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&xfds); tmo = slirp_select_fill(&nfds, &rfds, &wfds, &xfds); /* this can crash */ - if (tmo < 0) { + if (tmo < 0) tmo = 500; - } tv.tv_sec = 0; - tv.tv_usec = tmo; /* basilisk default 10000 */ + tv.tv_usec = tmo; + /* Now wait for something to happen, or at most 'tmo' usec. */ ret2 = select(nfds+1, &rfds, &wfds, &xfds, &tv); - if (ret2 >= 0) { + + /* If something happened, let SLiRP handle it. */ + if (ret2 >= 0) slirp_select_poll(&rfds, &wfds, &xfds); - } } @@ -77,10 +78,8 @@ poll_thread(void *arg) pclog("SLiRP: poll event is %08lx\n", evt); while (slirpq != NULL) { - if (++fizz > 1200) { - fizz = 0; - slirp_tic(); - } + /* See if there is any work. */ + slirp_tic(); /* Wait for the next packet to arrive. */ if (QueuePeek(slirpq) == 0) { @@ -124,8 +123,6 @@ network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) slirpq = QueueCreate(); pclog(" Packet queue is at %08lx\n", &slirpq); - fizz = 0; - /* Save the callback info. */ poll_rx = func; poll_arg = arg; diff --git a/src/network.c b/src/network.c index 7d1d6e98f..63a8c0f9d 100644 --- a/src/network.c +++ b/src/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.3 2017/05/12 + * Version: @(#)network.c 1.0.4 2017/05/17 * * Authors: Kotori, * Fred N. van Kempen, @@ -41,8 +41,12 @@ static netcard_t net_cards[] = { }; -int network_card; -int network_type; +/* Global variables. */ +int network_card; +int network_type; +int network_ndev; +netdev_t network_devs[32]; +char network_pcap[512]; /* @@ -55,8 +59,11 @@ int network_type; void network_init(void) { + network_type = NET_TYPE_NONE; network_card = 0; - network_type = -1; + + /* Initialize list of PCap devices. */ + network_ndev = network_devlist(network_devs); } @@ -80,11 +87,11 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) /* Start the platform module. */ switch(network_type) { - case 0: + case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); break; - case 1: + case NET_TYPE_SLIRP: ret = network_slirp_setup(mac, rx, dev); break; } @@ -98,11 +105,11 @@ void network_close(void) { switch(network_type) { - case 0: + case NET_TYPE_PCAP: network_pcap_close(); break; - case 1: + case NET_TYPE_SLIRP: network_slirp_close(); break; } @@ -127,10 +134,11 @@ network_reset(void) network_close(); /* If no active card, we're done. */ - if (!network_card || (network_type<0)) return; + if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; pclog("NETWORK: set up for %s, card=%s\n", - (network_type==1)?"SLiRP":"WinPcap", net_cards[network_card].name); + (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", + net_cards[network_card].name); pclog("NETWORK: reset (card=%d)\n", network_card); /* Add the (new?) card to the I/O system. */ @@ -147,11 +155,11 @@ void network_tx(uint8_t *bufp, int len) { switch(network_type) { - case 0: + case NET_TYPE_PCAP: network_pcap_in(bufp, len); break; - case 1: + case NET_TYPE_SLIRP: network_slirp_in(bufp, len); break; } @@ -217,3 +225,19 @@ network_card_get_from_internal_name(char *s) return(-1); } + + +int +network_dev_to_id(char *dev) +{ + int i = 0; + + for (i=0; i * Fred N. van Kempen, @@ -18,6 +18,12 @@ # include +/* Network provider types. */ +#define NET_TYPE_NONE 0 /* networking disabled */ +#define NET_TYPE_PCAP 1 /* use the (Win)Pcap API */ +#define NET_TYPE_SLIRP 2 /* use the SLiRP port forwarder */ + +/* Supported network cards. */ #define NE1000 1 #define NE2000 2 #define RTL8029AS 3 @@ -44,11 +50,9 @@ typedef struct { /* Global variables. */ extern int network_card; extern int network_type; - -extern char pcap_dev[512]; - -extern int netdev_num; -extern netdev_t netdev_list[512]; +extern int network_ndev; +extern netdev_t network_devs[32]; +extern char network_pcap[512]; /* Function prototypes. */ @@ -68,13 +72,13 @@ extern void network_slirp_close(void); extern void network_slirp_in(uint8_t *, int); extern int network_devlist(netdev_t *); +extern int network_dev_to_id(char *); extern int network_card_available(int); extern char *network_card_getname(int); extern int network_card_has_config(int); extern char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); -extern struct device_t *network_card_getdevice(int); +extern device_t *network_card_getdevice(int); - int network_dev_to_id(char *dev); #endif /*NETWORK_H*/ diff --git a/src/pc.c b/src/pc.c index 9fced90fb..7e05e9260 100644 --- a/src/pc.c +++ b/src/pc.c @@ -18,8 +18,6 @@ #include "device.h" #include "ali1429.h" -#include "cdrom.h" -#include "cdrom-ioctl.h" #include "disc.h" #include "disc_86f.h" #include "disc_fdi.h" @@ -31,20 +29,21 @@ #include "fdc.h" #include "fdd.h" #include "gameport.h" -#include "plat-joystick.h" -#include "plat-midi.h" +#include "plat_joystick.h" +#include "plat_midi.h" #include "hdd.h" #include "ide.h" #include "cdrom.h" -#include "cdrom-image.h" -#include "cdrom-null.h" +#include "cdrom_ioctl.h" +#include "cdrom_image.h" +#include "cdrom_null.h" #include "scsi.h" #include "keyboard.h" -#include "plat-keyboard.h" +#include "plat_keyboard.h" #include "keyboard_at.h" #include "model.h" #include "mouse.h" -#include "plat-mouse.h" +#include "plat_mouse.h" #include "network.h" #include "serial.h" #include "sound/sound.h" @@ -60,7 +59,7 @@ #include "amstrad.h" #ifdef WALTJE # define UNICODE -# include "plat-dir.h" +# include "plat_dir.h" #endif #ifndef __unix @@ -69,7 +68,7 @@ #include #undef BITMAP #include "win.h" -#include "win-language.h" +#include "win_language.h" #endif @@ -288,9 +287,6 @@ void initpc(int argc, wchar_t *argv[]) *p=L'\0'; pclog("path = %ws\n", pcempath); - /* Initialize list of PCap devices. */ - netdev_num = network_devlist(netdev_list); - for (c = 1; c < argc; c++) { if (!_wcsicmp(argv[c], L"--help")) diff --git a/src/pcap_if.rc b/src/pcap_if.rc deleted file mode 100644 index 57d78e657..000000000 --- a/src/pcap_if.rc +++ /dev/null @@ -1,52 +0,0 @@ -#ifdef _WIN32 -#include -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - - -#ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" -#else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" -#endif - - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,2,0 - PRODUCTVERSION 1,0,2,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "IRC #SoftHistory\0" - VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0" - VALUE "FileVersion", "1.0.2\0" - VALUE "InternalName", "pcap_if\0" - VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "pcap_if.exe\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "WinPcap Test Tool\0" - VALUE "ProductVersion", "1.0.2\0" - VALUE "SpecialBuild", "\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END diff --git a/src/plat-dinput.h b/src/plat-dinput.h deleted file mode 100644 index b5d7eca06..000000000 --- a/src/plat-dinput.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern LPDIRECTINPUT lpdi; diff --git a/src/plat-dir.h b/src/plat-dir.h deleted file mode 100644 index f9fbf2a9d..000000000 --- a/src/plat-dir.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the platform OpenDir module. - * - * Version: @(#)plat-dir.h 1.0.1 2017/05/12 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef PLAT_DIR_H -# define PLAT_DIR_H - - -#ifdef _MAX_FNAME -# define MAXNAMLEN _MAX_FNAME -#else -# define MAXNAMLEN 15 -#endif -# define MAXDIRLEN 127 - - -struct direct { - long d_ino; - unsigned short d_reclen; - unsigned short d_off; -#ifdef UNICODE - wchar_t d_name[MAXNAMLEN + 1]; -#else - char d_name[MAXNAMLEN + 1]; -#endif -}; -#define d_namlen d_reclen - - -typedef struct { - short flags; /* internal flags */ - short offset; /* offset of entry into dir */ - long handle; /* open handle to Win32 system */ - short sts; /* last known status code */ - char *dta; /* internal work data */ -#ifdef UNICODE - wchar_t dir[MAXDIRLEN+1]; /* open dir */ -#else - char dir[MAXDIRLEN+1]; /* open dir */ -#endif - struct direct dent; /* actual directory entry */ -} DIR; - - -/* Directory routine flags. */ -#define DIR_F_LOWER 0x0001 /* force to lowercase */ -#define DIR_F_SANE 0x0002 /* force this to sane path */ -#define DIR_F_ISROOT 0x0010 /* this is the root directory */ - - -/* Function prototypes. */ -#ifdef UNICODE -extern DIR *opendirw(const wchar_t *); -#else -extern DIR *opendir(const char *); -#endif -extern struct direct *readdir(DIR *); -extern long telldir(DIR *); -extern void seekdir(DIR *, long); -extern int closedir(DIR *); - -#define rewinddir(dirp) seekdir(dirp, 0L) - - -#endif /*PLAT_DIR_H*/ diff --git a/src/plat-joystick.h b/src/plat-joystick.h deleted file mode 100644 index aecb3537c..000000000 --- a/src/plat-joystick.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - void joystick_init(); - void joystick_close(); - void joystick_poll(); - - typedef struct plat_joystick_t - { - char name[64]; - - int a[8]; - int b[32]; - int p[4]; - - struct - { - char name[32]; - int id; - } axis[8]; - - struct - { - char name[32]; - int id; - } button[32]; - - struct - { - char name[32]; - int id; - } pov[4]; - - int nr_axes; - int nr_buttons; - int nr_povs; - } plat_joystick_t; - - #define MAX_PLAT_JOYSTICKS 8 - - extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; - extern int joysticks_present; - - #define POV_X 0x80000000 - #define POV_Y 0x40000000 - - typedef struct joystick_t - { - int axis[8]; - int button[32]; - int pov[4]; - - int plat_joystick_nr; - int axis_mapping[8]; - int button_mapping[32]; - int pov_mapping[4][2]; - } joystick_t; - - #define MAX_JOYSTICKS 4 - extern joystick_t joystick_state[MAX_JOYSTICKS]; - - #define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/src/plat-keyboard.h b/src/plat-keyboard.h deleted file mode 100644 index f062c5951..000000000 --- a/src/plat-keyboard.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - void keyboard_init(); - void keyboard_close(); - void keyboard_poll_host(); - extern int recv_key[272]; - extern int rawinputkey[272]; - -#ifndef __unix - #define KEY_LCONTROL 0x1d - #define KEY_RCONTROL (0x1d | 0x80) - #define KEY_END (0x4f | 0x80) -#endif - -#ifdef __cplusplus -} -#endif - diff --git a/src/plat-midi.h b/src/plat-midi.h deleted file mode 100644 index 87ed57306..000000000 --- a/src/plat-midi.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void midi_init(); -void midi_close(); -void midi_write(uint8_t val); -int midi_get_num_devs(); -void midi_get_dev_name(int num, char *s); - -extern int midi_id; diff --git a/src/plat-mouse.h b/src/plat-mouse.h deleted file mode 100644 index ff248f301..000000000 --- a/src/plat-mouse.h +++ /dev/null @@ -1,16 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - - void mouse_init(); - void mouse_close(); - extern int mouse_buttons; - void mouse_poll_host(); - void mouse_get_mickeys(int *x, int *y, int *z); - extern int mousecapture; -#ifdef __cplusplus -} -#endif diff --git a/src/plat-serial.h b/src/plat-serial.h deleted file mode 100644 index e11737a89..000000000 --- a/src/plat-serial.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Definitions for the Bottom Half of the SERIAL card. - * - * Version: @(#)plat-serial.h 1.0.3 2017/05/06 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#ifndef PLAT_SERIAL_H -# define PLAT_SERIAL_H - - -typedef struct { - char name[79]; /* name of open port */ - void (*rd_done)(void *, int); - void *rd_arg; -#ifdef BHTTY_C - HANDLE handle; - OVERLAPPED rov, /* READ and WRITE events */ - wov; - int tmo; /* current timeout value */ - DCB dcb, /* terminal settings */ - odcb; -#endif -} BHTTY; - - -extern BHTTY *bhtty_open(char *__port, int __tmo); -extern void bhtty_close(BHTTY *); -extern int bhtty_flush(BHTTY *); -extern void bhtty_raw(BHTTY *, void *__arg); -extern int bhtty_speed(BHTTY *, long __speed); -extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); -extern int bhtty_sstate(BHTTY *, void *__arg); -extern int bhtty_gstate(BHTTY *, void *__arg); -extern int bhtty_crtscts(BHTTY *, char __yesno); - -extern int bhtty_write(BHTTY *, unsigned char); -extern int bhtty_read(BHTTY *, unsigned char *, int); - - -#endif /*PLAT_SERIAL_H*/ diff --git a/src/ppi.c b/src/ppi.c index 0eb9f3a0f..e5d5a27ec 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -10,9 +10,8 @@ #include "ibm.h" #include "pit.h" - -#include "plat-keyboard.h" -#include "plat-mouse.h" +#include "plat_keyboard.h" +#include "plat_mouse.h" void ppi_reset() { diff --git a/src/resource.h b/src/resource.h deleted file mode 100644 index 5364bf674..000000000 --- a/src/resource.h +++ /dev/null @@ -1,432 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -/* {{NO_DEPENDENCIES}} - Microsoft Developer Studio generated include file. - Used by 86Box.rc -*/ -#define IDHDCONFIG 3 -#define IDCDCONFIG 4 -#define CONFIGUREDLG_MACHINE 101 -#define CONFIGUREDLG_VIDEO 102 -#define CONFIGUREDLG_INPUT 103 -#define CONFIGUREDLG_SOUND 104 -#define CONFIGUREDLG_NETWORK 105 -#define CONFIGUREDLG_PERIPHERALS 106 -#define CONFIGUREDLG_HARD_DISKS 107 -#define CONFIGUREDLG_REMOVABLE_DEVICES 108 -#define ABOUTDLG 109 -#define CONFIGUREDLG_HARD_DISKS_ADD 110 -#define CONFIGUREDLG_MAIN 117 -#define IDC_SETTINGSCATLIST 1004 -#define IDC_LIST_HARD_DISKS 1005 -#define IDC_COMBO_MACHINE 1006 -#define IDC_COMBO_CPU_TYPE 1007 -#define IDC_COMBO_CPU 1008 -#define IDC_COMBO_WS 1009 -#define IDC_CHECK_DYNAREC 1010 -#define IDC_CHECK_FPU 1011 -#define IDC_COMBO_SCSI 1012 -#define IDC_CONFIGURE_SCSI 1013 -#define IDC_COMBO_VIDEO 1014 -#define IDC_COMBO_VIDEO_SPEED 1015 -#define IDC_CHECK_VOODOO 1016 -#define IDC_CHECKCMS 1016 -#define IDC_CONFIGURE_VOODOO 1017 -#define IDC_CHECKNUKEDOPL 1018 -#define IDC_COMBO_JOYSTICK 1018 -#define IDC_CHECK_SYNC 1019 -#define IDC_LIST_FLOPPY_DRIVES 1020 -#define IDC_LIST_CDROM_DRIVES 1021 -#define IDC_CONFIGURE_MACHINE 1022 -#define IDC_COMBO_LANG 1023 -#define IDC_BUTTON_FDD_ADD 1024 -#define IDC_BUTTON_FDD_EDIT 1025 -#define IDC_BUTTON_FDD_REMOVE 1026 -#define IDC_BUTTON_CDROM_ADD 1027 -#define IDC_BUTTON_HDD_ADD_NEW 1027 -#define IDC_BUTTON_CDROM_EDIT 1028 -#define IDC_BUTTON_HDD_ADD 1028 -#define IDC_BUTTON_CDROM_REMOVE 1029 -#define IDC_BUTTON_HDD_REMOVE 1029 -#define IDC_HDIMAGE_NEW 1035 -#define IDC_HD_BUS 1036 -#define IDC_HDIMAGE_EXISTING 1037 -#define IDC_COMBO_HD_BUS 1038 -#define IDC_EDIT_HD_FILE_NAME 1039 -#define IDC_EDIT_HD_CYL 1040 -#define IDC_EDIT_HD_HPC 1041 -#define IDC_EDIT_HD_SPT 1042 -#define IDC_EDIT_HD_SIZE 1043 -#define IDC_COMBO_HD_TYPE 1044 -#define IDC_COMBO_HD_LOCATION 1045 -#define IDC_CHECKGUS 1046 -#define IDC_COMBO_HD_CHANNEL 1047 -#define IDC_COMBO_HD_CHANNEL_IDE 1048 -#define IDC_COMBO_HD_ID 1050 -#define IDC_COMBO_HD_LUN 1051 -#define IDC_CHECKBUGGER 1052 -#define IDC_CHECKSERIAL1 1053 -#define IDC_CHECKPARALLEL 1054 -#define IDC_CHECKSERIAL2 1055 -#define IDC_COMBO_HDC 1068 -#define IDC_COMBO_MOUSE 1069 -#define IDC_COMBO_IDE_TER 1069 -#define IDC_COMBO_IDE_QUA 1070 -#define IDC_COMBO_FD_TYPE 1071 -#define IDC_COMBO_CD_BUS 1072 -#define IDC_COMBO_CD_CHANNEL_IDE 1073 -#define IDC_COMBO_CD_ID 1074 -#define IDC_COMBO_CD_LUN 1075 -#define IDC_COMBO_MIDI 1076 -#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 -#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 -#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 -#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 -#define IDS_STRING2049 2049 -#define IDS_STRING2050 2050 -#define IDS_STRING2051 2051 -#define IDS_STRING2052 2052 -#define IDS_STRING2053 2053 -#define IDS_STRING2054 2054 -#define IDS_STRING2055 2055 -#define IDS_STRING2056 2056 -#define IDS_STRING2057 2057 -#define IDS_STRING2058 2058 -#define IDS_STRING2059 2059 -#define IDS_STRING2060 2060 -#define IDS_STRING2061 2061 -#define IDS_STRING2062 2062 -#define IDS_STRING2063 2063 -#define IDS_STRING2064 2064 -#define IDS_STRING2065 2065 -#define IDS_STRING2066 2066 -#define IDS_STRING2067 2067 -#define IDS_STRING2068 2068 -#define IDS_STRING2069 2069 -#define IDS_STRING2070 2070 -#define IDS_STRING2071 2071 -#define IDS_STRING2072 2072 -#define IDS_STRING2073 2073 -#define IDS_STRING2074 2074 -#define IDS_STRING2075 2075 -#define IDS_STRING2076 2076 -#define IDS_STRING2077 2077 -#define IDS_STRING2078 2078 -#define IDS_STRING2079 2079 -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 - -#define IDM_DISC_1 40000 -#define IDM_DISC_2 40001 -#define IDM_DISC_3 40002 -#define IDM_DISC_4 40003 -#define IDM_DISC_1_WP 40004 -#define IDM_DISC_2_WP 40005 -#define IDM_DISC_3_WP 40006 -#define IDM_DISC_4_WP 40007 -#define IDM_EJECT_1 40008 -#define IDM_EJECT_2 40009 -#define IDM_EJECT_3 40010 -#define IDM_EJECT_4 40011 - -#define IDM_FILE_RESET 40015 -#define IDM_FILE_HRESET 40016 -#define IDM_FILE_EXIT 40017 -#define IDM_FILE_RESET_CAD 40018 -#define IDM_HDCONF 40019 -#define IDM_CONFIG 40020 -#define IDM_CONFIG_LOAD 40021 -#define IDM_CONFIG_SAVE 40022 -#define IDM_USE_NUKEDOPL 40023 -#define IDM_STATUS 40030 -#define IDM_VID_RESIZE 40050 -#define IDM_VID_REMEMBER 40051 -#define IDM_VID_DDRAW 40060 -#define IDM_VID_D3D 40061 -#define IDM_VID_SCALE_1X 40064 -#define IDM_VID_SCALE_2X 40065 -#define IDM_VID_SCALE_3X 40066 -#define IDM_VID_SCALE_4X 40067 -#define IDM_VID_FULLSCREEN 40070 -#define IDM_VID_FS_FULL 40071 -#define IDM_VID_FS_43 40072 -#define IDM_VID_FS_SQ 40073 -#define IDM_VID_FS_INT 40074 -#define IDM_VID_FORCE43 40075 -#define IDM_VID_OVERSCAN 40076 -#define IDM_VID_FLASH 40077 -#define IDM_VID_SCREENSHOT 40078 -#define IDM_VID_INVERT 40079 - -#define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_IMAGE 40144 -#define IDM_CDROM_1_RELOAD 40160 -#define IDM_CDROM_1_EMPTY 40176 -#define IDM_CDROM_1_REAL 40192 -#define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_IMAGE 40145 -#define IDM_CDROM_2_RELOAD 40161 -#define IDM_CDROM_2_EMPTY 40177 -#define IDM_CDROM_2_REAL 40193 -#define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_IMAGE 40146 -#define IDM_CDROM_3_RELOAD 40162 -#define IDM_CDROM_3_EMPTY 40178 -#define IDM_CDROM_3_REAL 40194 -#define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_IMAGE 40147 -#define IDM_CDROM_4_RELOAD 40163 -#define IDM_CDROM_4_EMPTY 40179 -#define IDM_CDROM_4_REAL 40195 - -#define IDM_IDE_TER_ENABLED 44000 -#define IDM_IDE_TER_IRQ9 44009 -#define IDM_IDE_TER_IRQ10 44010 -#define IDM_IDE_TER_IRQ11 44011 -#define IDM_IDE_TER_IRQ12 44012 -#define IDM_IDE_TER_IRQ14 44014 -#define IDM_IDE_TER_IRQ15 44015 -#define IDM_IDE_QUA_ENABLED 44020 -#define IDM_IDE_QUA_IRQ9 44029 -#define IDM_IDE_QUA_IRQ10 44030 -#define IDM_IDE_QUA_IRQ11 44031 -#define IDM_IDE_QUA_IRQ12 44032 -#define IDM_IDE_QUA_IRQ14 44033 -#define IDM_IDE_QUA_IRQ15 44035 - -#ifdef ENABLE_LOG_TOGGLES -# ifdef ENABLE_BUSLOGIC_LOG -# define IDM_LOG_BUSLOGIC 51200 -# endif -# ifdef ENABLE_CDROM_LOG -# define IDM_LOG_CDROM 51201 -# endif -# ifdef ENABLE_D86F_LOG -# define IDM_LOG_D86F 51202 -# endif -# ifdef ENABLE_FDC_LOG -# define IDM_LOG_FDC 51203 -# endif -# ifdef ENABLE_IDE_LOG -# define IDM_LOG_IDE 51204 -# endif -# ifdef ENABLE_NE2000_LOG -# define IDM_LOG_NE2000 51205 -# endif -#endif -#ifdef ENABLE_LOG_BREAKPOINT -# define IDM_LOG_BREAKPOINT 51206 -#endif -#ifdef ENABLE_VRAM_DUMP -# define IDM_DUMP_VRAM 51207 -#endif - -#define IDC_COMBO1 1000 -#define IDC_COMBOVID 1001 -#define IDC_COMBO3 1002 -#define IDC_COMBO4 1003 -#define IDC_COMBO5 1004 -#define IDC_COMBO386 1005 -#define IDC_COMBO486 1006 -#define IDC_COMBOSND 1007 -#define IDC_COMBONETTYPE 1008 -#define IDC_COMBOPCAP 1009 -#define IDC_COMBONET 1010 -#define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODR1 1062 -#define IDC_COMBODR2 1063 -#define IDC_COMBODR3 1064 -#define IDC_COMBODR4 1065 -#define IDC_COMBOJOY 1066 -#define IDC_COMBOWS 1067 -#define IDC_COMBOMOUSE 1068 -#define IDC_COMBOHDD 1069 -#define IDC_CHECK1 1010 -#define IDC_CHECK2 1011 -#define IDC_CHECK3 1012 -#define IDC_CHECKSSI 1014 -#define IDC_CHECKVOODOO 1015 -#define IDC_CHECKDYNAREC 1016 -#define IDC_CHECKBUSLOGIC 1017 -#define IDC_CHECKSYNC 1024 -#define IDC_CHECKXTIDE 1025 -#define IDC_CHECKFPU 1026 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_COMBOHDT 1036 - -#define IDC_EJECTC 1040 -#define IDC_EDITC 1050 -#define IDC_CFILE 1060 -#define IDC_CNEW 1070 -#define IDC_EDIT_C_SPT 1200 -#define IDC_EDIT_C_HPC 1210 -#define IDC_EDIT_C_CYL 1220 -#define IDC_EDIT_C_FN 1230 -#define IDC_TEXT_C_SIZE 1240 - -#define IDC_EJECTD 1041 -#define IDC_EDITD 1051 -#define IDC_DFILE 1061 -#define IDC_DNEW 1071 -#define IDC_EDIT_D_SPT 1201 -#define IDC_EDIT_D_HPC 1211 -#define IDC_EDIT_D_CYL 1221 -#define IDC_EDIT_D_FN 1231 -#define IDC_TEXT_D_SIZE 1241 - -#define IDC_EJECTE 1042 -#define IDC_EDITE 1052 -#define IDC_EFILE 1062 -#define IDC_ENEW 1072 -#define IDC_EDIT_E_SPT 1202 -#define IDC_EDIT_E_HPC 1212 -#define IDC_EDIT_E_CYL 1222 -#define IDC_EDIT_E_FN 1232 -#define IDC_TEXT_E_SIZE 1242 - -#define IDC_EJECTF 1043 -#define IDC_EDITF 1053 -#define IDC_FFILE 1063 -#define IDC_FNEW 1073 -#define IDC_EDIT_F_SPT 1203 -#define IDC_EDIT_F_HPC 1213 -#define IDC_EDIT_F_CYL 1223 -#define IDC_EDIT_F_FN 1233 -#define IDC_TEXT_F_SIZE 1243 - -#define IDC_EJECTG 1044 -#define IDC_EDITG 1054 -#define IDC_GFILE 1064 -#define IDC_GNEW 1074 -#define IDC_EDIT_G_SPT 1204 -#define IDC_EDIT_G_HPC 1214 -#define IDC_EDIT_G_CYL 1224 -#define IDC_EDIT_G_FN 1234 -#define IDC_TEXT_G_SIZE 1244 - -#define IDC_EJECTH 1045 -#define IDC_EDITH 1055 -#define IDC_HFILE 1065 -#define IDC_HNEW 1075 -#define IDC_EDIT_H_SPT 1205 -#define IDC_EDIT_H_HPC 1215 -#define IDC_EDIT_H_CYL 1225 -#define IDC_EDIT_H_FN 1235 -#define IDC_TEXT_H_SIZE 1245 - -#define IDC_EJECTI 1046 -#define IDC_EDITI 1056 -#define IDC_IFILE 1066 -#define IDC_INEW 1076 -#define IDC_EDIT_I_SPT 1206 -#define IDC_EDIT_I_HPC 1216 -#define IDC_EDIT_I_CYL 1226 -#define IDC_EDIT_I_FN 1236 -#define IDC_TEXT_I_SIZE 1246 - -#define IDC_EJECTJ 1047 -#define IDC_EDITJ 1057 -#define IDC_JFILE 1067 -#define IDC_JNEW 1077 -#define IDC_EDIT_J_SPT 1207 -#define IDC_EDIT_J_HPC 1217 -#define IDC_EDIT_J_CYL 1227 -#define IDC_EDIT_J_FN 1237 -#define IDC_TEXT_J_SIZE 1247 - -#define IDC_HDTYPE 1280 - -#define IDC_RENDER 1281 -#define IDC_STATUS 1282 - -#define IDC_MEMSPIN 1100 -#define IDC_MEMTEXT 1101 -#define IDC_STEXT1 1102 -#define IDC_STEXT2 1103 -#define IDC_STEXT3 1104 -#define IDC_STEXT4 1105 -#define IDC_STEXT5 1106 -#define IDC_STEXT6 1107 -#define IDC_STEXT7 1108 -#define IDC_STEXT8 1109 -#define IDC_STEXT_DEVICE 1110 -#define IDC_TEXT_MB 1111 -#define IDC_TEXT1 1115 -#define IDC_TEXT2 1116 - -#define IDC_CONFIGUREVID 1200 -#define IDC_CONFIGURESND 1201 -#define IDC_CONFIGUREVOODOO 1202 -#define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENETTYPE 1204 -#define IDC_CONFIGUREBUSLOGIC 1205 -#define IDC_CONFIGUREPCAP 1206 -#define IDC_CONFIGURENET 1207 -#define IDC_JOY1 1210 -#define IDC_JOY2 1211 -#define IDC_JOY3 1212 -#define IDC_JOY4 1213 - -#define IDC_CONFIG_BASE 1200 - -#define WM_RESETD3D WM_USER -#define WM_LEAVEFULLSCREEN WM_USER + 1 - -#define C_BASE 6 -#define D_BASE 44 -#define E_BASE 82 -#define F_BASE 120 -#define G_BASE 158 -#define H_BASE 196 -#define I_BASE 234 -#define J_BASE 272 -#define CMD_BASE 314 -#define DLG_HEIGHT 346 - -#define IDC_CHECK_CDROM_1_ENABLED 1536 -#define IDC_COMBO_CDROM_1_BUS 1544 -#define IDC_COMBO_CDROM_1_CHANNEL 1552 -#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 -#define IDC_COMBO_CDROM_1_SCSI_ID 1568 -#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 - -#define IDC_CHECK_CDROM_2_ENABLED 1537 -#define IDC_COMBO_CDROM_2_BUS 1545 -#define IDC_COMBO_CDROM_2_CHANNEL 1553 -#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 -#define IDC_COMBO_CDROM_2_SCSI_ID 1569 -#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 - -#define IDC_CHECK_CDROM_3_ENABLED 1538 -#define IDC_COMBO_CDROM_3_BUS 1546 -#define IDC_COMBO_CDROM_3_CHANNEL 1554 -#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 -#define IDC_COMBO_CDROM_3_SCSI_ID 1570 -#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 - -#define IDC_CHECK_CDROM_4_ENABLED 1539 -#define IDC_COMBO_CDROM_4_BUS 1547 -#define IDC_COMBO_CDROM_4_CHANNEL 1555 -#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 -#define IDC_COMBO_CDROM_4_SCSI_ID 1571 -#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 - -#define IDC_STATIC 1792 - -/* Next default values for new objects */ -#ifdef APSTUDIO_INVOKED -# ifndef APSTUDIO_READONLY_SYMBOLS -# define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 111 -# define _APS_NEXT_COMMAND_VALUE 40002 -# define _APS_NEXT_CONTROL_VALUE 1055 -# define _APS_NEXT_SYMED_VALUE 101 -# endif -#endif diff --git a/src/serial.c b/src/serial.c index a2b896321..ae376960a 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,7 +33,7 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.5 2017/05/07 + * Version: @(#)serial.c 1.0.5 2017/05/17 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -43,7 +43,7 @@ #include "pic.h" #include "timer.h" #include "serial.h" -#include "plat-serial.h" +#include "plat_serial.h" enum { diff --git a/src/win-cgapal.h b/src/win-cgapal.h deleted file mode 100644 index d6ac7ffd8..000000000 --- a/src/win-cgapal.h +++ /dev/null @@ -1,13 +0,0 @@ -extern PALETTE cgapal; -extern PALETTE cgapal_mono[6]; - -extern uint32_t pal_lookup[256]; - -#ifdef __cplusplus -extern "C" { -#endif -void cgapal_rebuild(); -void destroy_bitmap(BITMAP *b); -#ifdef __cplusplus -} -#endif diff --git a/src/win-crashdump.c b/src/win-crashdump.c deleted file mode 100644 index b640c61ae..000000000 --- a/src/win-crashdump.c +++ /dev/null @@ -1,185 +0,0 @@ -/* Copyright holders: Riley - see COPYING for more details - - win-crashdump.c : Windows exception handler to make a crash dump just before a crash happens. -*/ -#define _WIN32_WINNT 0x0501 -#include -#include -#include -#include -#include -#include "86box.h" -#include "win-crashdump.h" - -PVOID hExceptionHandler; -char* ExceptionHandlerBuffer; -#define ExceptionHandlerBufferSize (10240) - - -LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { - // Win32-specific functions will be used wherever possible, just in case the C stdlib-equivalents try to allocate memory. - // (The Win32-specific functions are generally just wrappers over NT system calls anyway.) - - if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) { - // The exception code is not a fatal exception (highest 4 bits of ntstatus = 0xC) - // Not going to crash, let's not make a crash dump - return EXCEPTION_CONTINUE_SEARCH; - } - - // So, the program is about to crash. Oh no what do? - // Let's create a crash dump file as a debugging-aid. - - // First, get the path to 86Box.exe. - char* CurrentBufferPointer; - GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); - if (GetLastError() != ERROR_SUCCESS) { - // Could not get the full path of 86Box.exe. Just create the file in the current directory. - CurrentBufferPointer = ExceptionHandlerBuffer; - } else { - // Walk through the string backwards looking for the last backslash, so as to remove the "86Box.exe" filename from the string. - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - for (; CurrentBufferPointer > ExceptionHandlerBuffer; CurrentBufferPointer--) { - if (CurrentBufferPointer[0] == '\\') { - // Found the backslash, null terminate the string after it. - CurrentBufferPointer[1] = 0; - break; - } - } - - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - } - - // What would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. - SYSTEMTIME SystemTime; - GetSystemTime(&SystemTime); - sprintf(CurrentBufferPointer, - "86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp", - SystemTime.wYear, - SystemTime.wMonth, - SystemTime.wDay, - SystemTime.wHour, - SystemTime.wMinute, - SystemTime.wSecond, - SystemTime.wMilliseconds); - - DWORD Error; - - // Now the filename is in the buffer, the file can be created. - HANDLE hDumpFile = CreateFile( - ExceptionHandlerBuffer, // The filename of the file to open. - GENERIC_WRITE, // The permissions to request. - 0, // Make sure other processes can't touch the crash dump at all while it's open. - NULL, // Leave the security descriptor undefined, it doesn't matter. - OPEN_ALWAYS, // Opens the file if it exists, creates a new file if it doesn't. - FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter. - NULL); // A template file is not being used. - - // Check to make sure the file was actually created. - if (hDumpFile == INVALID_HANDLE_VALUE) { - // CreateFile() failed, so just do nothing more. - return EXCEPTION_CONTINUE_SEARCH; - } - - // Now the file is open, let's write the data we were passed out in a human-readable format. - - // Let's get the name of the module where the exception occured. - HMODULE hMods[1024]; - MODULEINFO modInfo; - HMODULE ipModule = 0; - DWORD cbNeeded; - // Try to get a list of all loaded modules. - if (EnumProcessModules(GetCurrentProcess(), hMods, sizeof(hMods), &cbNeeded)) { - // The list was obtained, walk through each of the modules. - for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { - // For each module, get the module information (base address, size, entry point) - GetModuleInformation(GetCurrentProcess(), hMods[i], &modInfo, sizeof(MODULEINFO)); - // If the exception address is located in the range of where this module is loaded... - if ( - (ExceptionInfo->ExceptionRecord->ExceptionAddress >= modInfo.lpBaseOfDll) && - (ExceptionInfo->ExceptionRecord->ExceptionAddress < (modInfo.lpBaseOfDll + modInfo.SizeOfImage)) - ) { - // ...this is the module we're looking for! - ipModule = hMods[i]; - break; - } - } - } - - // Start to put the crash-dump string into the buffer. - - sprintf(ExceptionHandlerBuffer, - "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" - "" - "Exception details:\r\n" - "Exception NTSTATUS code: 0x%08x\r\n" - "Occured at address: 0x%p", - emulator_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, - - ExceptionInfo->ExceptionRecord->ExceptionCode, - ExceptionInfo->ExceptionRecord->ExceptionAddress); - - - // If we found the module that the exception occured in, get the full path to the module the exception occured at and include it. - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - if (ipModule != 0) { - sprintf(CurrentBufferPointer," ["); - GetModuleFileName(ipModule,&CurrentBufferPointer[2],ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); - if (GetLastError() == ERROR_SUCCESS) { - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - sprintf(CurrentBufferPointer,"]"); - CurrentBufferPointer += 1; - } - } - - // Continue to create the crash-dump string. - sprintf(CurrentBufferPointer, - "\r\n" - "Number of parameters: %d\r\n" - "Exception parameters: ", - ExceptionInfo->ExceptionRecord->NumberParameters); - - // Add the exception parameters to the crash-dump string. - for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); - } - - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1]; - - PCONTEXT Registers = ExceptionInfo->ContextRecord; - - #if defined(__i386__) && !defined(__x86_64) - // This binary is being compiled for x86, include a register dump. - sprintf(CurrentBufferPointer, - "\r\n" - "Register dump:\r\n" - "eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n" - "\r\n", - Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip); - #else - // Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition. - sprintf(CurrentBufferPointer,"\r\n"); - #endif - - // The crash-dump string has been created, write it to disk. - WriteFile(hDumpFile, - ExceptionHandlerBuffer, - strlen(ExceptionHandlerBuffer), - NULL, - NULL); - - // Finally, close the file. - CloseHandle(hDumpFile); - - // And return, therefore causing the crash, but only after the crash dump has been created. - - return EXCEPTION_CONTINUE_SEARCH; -} - -void InitCrashDump() { - // An exception handler should not allocate memory, so allocate 10kb for it to use if it gets called, an amount which should be more than enough. - ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize); - // Register the exception handler. Zero first argument means this exception handler gets called last, therefore, crash dump is only made, when a crash is going to happen. - hExceptionHandler = AddVectoredExceptionHandler(0,MakeCrashDump); -} \ No newline at end of file diff --git a/src/win-crashdump.h b/src/win-crashdump.h deleted file mode 100644 index 8048cd7af..000000000 --- a/src/win-crashdump.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright holders: Riley - see COPYING for more details - - win-crashdump.c : Windows crash dump exception handler header file. -*/ - -void InitCrashDump(); \ No newline at end of file diff --git a/src/win-d3d-fs.cc b/src/win-d3d-fs.cc deleted file mode 100644 index dff2e0d6f..000000000 --- a/src/win-d3d-fs.cc +++ /dev/null @@ -1,587 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include -#include "86box.h" -#include "video/video.h" -#include "win-d3d-fs.h" -#include "win.h" -#include "win-cgapal.h" -#include "resource.h" - - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); - -static void d3d_fs_init_objects(void); -static void d3d_fs_close_objects(void); -static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h); - -extern "C" void video_blit_complete(void); - - -static LPDIRECT3D9 d3d = NULL; -static LPDIRECT3DDEVICE9 d3ddev = NULL; -static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; -static LPDIRECT3DTEXTURE9 d3dTexture = NULL; -static D3DPRESENT_PARAMETERS d3dpp; - -static HWND d3d_hwnd; -static HWND d3d_device_window; - -static int d3d_fs_w, d3d_fs_h; - -struct CUSTOMVERTEX -{ - FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag - FLOAT tu, tv; -}; - -PALETTE cgapal = -{ - {0,0,0},{0,42,0},{42,0,0},{42,21,0}, - {0,0,0},{0,42,42},{42,0,42},{42,42,42}, - {0,0,0},{21,63,21},{63,21,21},{63,63,21}, - {0,0,0},{21,63,63},{63,21,63},{63,63,63}, - - {0,0,0},{0,0,42},{0,42,0},{0,42,42}, - {42,0,0},{42,0,42},{42,21,00},{42,42,42}, - {21,21,21},{21,21,63},{21,63,21},{21,63,63}, - {63,21,21},{63,21,63},{63,63,21},{63,63,63}, - - {0,0,0},{0,21,0},{0,0,42},{0,42,42}, - {42,0,21},{21,10,21},{42,0,42},{42,0,63}, - {21,21,21},{21,63,21},{42,21,42},{21,63,63}, - {63,0,0},{42,42,0},{63,21,42},{41,41,41}, - - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,42,42},{42,0,0},{42,42,42}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, - {0,0,0},{0,63,63},{63,0,0},{63,63,63}, -}; - -PALETTE cgapal_mono[6] = -{ - { // 0 - green, 4-color-optimized contrast - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},{0x03,0x39,0x0d},{0x03,0x3c,0x0e}, - {0x00,0x07,0x01},{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, - }, - { // 1 - green, 16-color-optimized contrast - {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},{0x02,0x2e,0x0b},{0x02,0x31,0x0b}, - {0x01,0x22,0x08},{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, - }, - { // 2 - amber, 4-color-optimized contrast - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},{0x3f,0x26,0x01},{0x3f,0x2b,0x06}, - {0x0b,0x02,0x00},{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, - }, - { // 3 - amber, 16-color-optimized contrast - {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},{0x38,0x1c,0x00},{0x3b,0x1e,0x00}, - {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, - }, - { // 4 - grey, 4-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, - {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, - }, - { // 5 - grey, 16-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, - {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, - }, -}; - -uint32_t pal_lookup[256]; - -static CUSTOMVERTEX d3d_verts[] = -{ - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, -}; - -void cgapal_rebuild(void) -{ - int c; - for (c = 0; c < 256; c++) - { - pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); - } - if ((cga_palette > 1) && (cga_palette < 8)) - { - for (c = 0; c < 16; c++) - { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - } - } - if (cga_palette == 8) - { - pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); - } -} - -int d3d_fs_init(HWND h) -{ - HRESULT hr; - WCHAR emulator_title[200]; - - d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); - d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); - - cgapal_rebuild(); - - d3d_hwnd = h; - - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); - d3d_device_window = CreateWindowEx ( - 0, - szSubClassName, - emulator_title, - WS_POPUP, - CW_USEDEFAULT, - CW_USEDEFAULT, - 640, - 480, - HWND_DESKTOP, - NULL, - NULL, - NULL - ); - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (d3d == NULL) - { - return 0; - } - - memset(&d3dpp, 0, sizeof(d3dpp)); - - d3dpp.Flags = 0; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = d3d_device_window; - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp.MultiSampleQuality = 0; - d3dpp.EnableAutoDepthStencil = false; - d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - d3dpp.Windowed = false; - d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; - d3dpp.BackBufferWidth = d3d_fs_w; - d3dpp.BackBufferHeight = d3d_fs_h; - - hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); - if (FAILED(hr)) - { - return 0; - } - - d3d_fs_init_objects(); - - video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen; - video_blit_memtoscreen_8_func = d3d_fs_blit_memtoscreen_8; - - return 1; -} - -static void d3d_fs_close_objects(void) -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -static void d3d_fs_init_objects(void) -{ - D3DLOCKED_RECT dr; - RECT r; - - d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL); - - d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - - // r.top = r.left = 0; - r.bottom = 2047; - r.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - /* for (y = 0; y < 2048; y++) - { - uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); - memset(p, 0, 2048 * 4); - } */ - - d3dTexture->UnlockRect(0); - - d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); -} - -/*void d3d_resize(int x, int y) -{ - HRESULT hr; - - d3dpp.BackBufferWidth = x; - d3dpp.BackBufferHeight = y; - - d3d_reset(); -}*/ - -void d3d_fs_reset(void) -{ - HRESULT hr; - - memset(&d3dpp, 0, sizeof(d3dpp)); - - d3dpp.Flags = 0; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = d3d_device_window; - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp.MultiSampleQuality = 0; - d3dpp.EnableAutoDepthStencil = false; - d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - d3dpp.Windowed = false; - d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; - d3dpp.BackBufferWidth = d3d_fs_w; - d3dpp.BackBufferHeight = d3d_fs_h; - - hr = d3ddev->Reset(&d3dpp); - - if (hr == D3DERR_DEVICELOST) - return; - - d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - - device_force_redraw(); -} - -void d3d_fs_close(void) -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } - if (d3ddev) - { - d3ddev->Release(); - d3ddev = NULL; - } - if (d3d) - { - d3d->Release(); - d3d = NULL; - } - DestroyWindow(d3d_device_window); -} - -static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h) -{ - int ratio_w, ratio_h; - switch (video_fullscreen_scale) - { - case FULLSCR_SCALE_FULL: - *l = -0.5; - *t = -0.5; - *r = (window_rect.right - window_rect.left) - 0.5; - *b = (window_rect.bottom - window_rect.top) - 0.5; - break; - case FULLSCR_SCALE_43: - *t = -0.5; - *b = (window_rect.bottom - window_rect.top) - 0.5; - *l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5; - *r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5; - if (*l < -0.5) - { - *l = -0.5; - *r = (window_rect.right - window_rect.left) - 0.5; - *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5; - *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5; - } - break; - case FULLSCR_SCALE_SQ: - *t = -0.5; - *b = (window_rect.bottom - window_rect.top) - 0.5; - *l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5; - *r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5; - if (*l < -0.5) - { - *l = -0.5; - *r = (window_rect.right - window_rect.left) - 0.5; - *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5; - *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5; - } - break; - case FULLSCR_SCALE_INT: - ratio_w = (window_rect.right - window_rect.left) / w; - ratio_h = (window_rect.bottom - window_rect.top) / h; - if (ratio_h < ratio_w) - ratio_w = ratio_h; - *l = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2) - 0.5; - *r = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 0.5; - *t = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2) - 0.5; - *b = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 0.5; - break; - } -} - -static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - HRESULT hr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT window_rect; - int yy; - double l, t, r, b; - - if ((y1 == y2) || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) - { - RECT lock_rect; - - lock_rect.top = y1; - lock_rect.left = 0; - lock_rect.bottom = y2; - lock_rect.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - - GetClientRect(d3d_device_window, &window_rect); - d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = r; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = r; - d3d_verts[4].y = t; - d3d_verts[5].x = r; - d3d_verts[5].y = b; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); - if (hr == D3D_OK) - hr = v_buffer->Unlock(); - - if (hr == D3D_OK) - hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) - { - if (hr == D3D_OK) - d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK) - hr = d3ddev->EndScene(); - } - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(ghwnd, WM_RESETD3D, 0, 0); -} - -static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) -{ - HRESULT hr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT window_rect; - uint32_t *p; - int xx, yy; - double l, t, r, b; - - if (!h || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - if (hr == D3D_OK) - { - RECT lock_rect; - - lock_rect.top = 0; - lock_rect.left = 0; - lock_rect.bottom = 2047; - lock_rect.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = 0; yy < h; yy++) - { - p = (uint32_t *) &(((uint8_t *) dr.pBits)[yy * dr.Pitch]); - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - for (xx = 0; xx < w; xx++) - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - - video_blit_complete(); - - d3dTexture->UnlockRect(0); - } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - - GetClientRect(d3d_device_window, &window_rect); - d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = r; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = r; - d3d_verts[4].y = t; - d3d_verts[5].x = r; - d3d_verts[5].y = b; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); - if (hr == D3D_OK) - hr = v_buffer->Unlock(); - - if (hr == D3D_OK) - hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) - { - if (hr == D3D_OK) - d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK) - hr = d3ddev->EndScene(); - } - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(ghwnd, WM_RESETD3D, 0, 0); -} - -void d3d_fs_take_screenshot(wchar_t *fn) -{ - LPDIRECT3DSURFACE9 d3dSurface = NULL; - - if (!d3dTexture) return; - - d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); - - d3dSurface->Release(); - d3dSurface = NULL; -} diff --git a/src/win-d3d-fs.h b/src/win-d3d-fs.h deleted file mode 100644 index 41ca32e21..000000000 --- a/src/win-d3d-fs.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int d3d_fs_init(HWND h); - void d3d_fs_close(); - void d3d_fs_reset(); - void d3d_fs_resize(int x, int y); -#ifdef __cplusplus -} -#endif diff --git a/src/win-d3d.cc b/src/win-d3d.cc deleted file mode 100644 index abfce0bfb..000000000 --- a/src/win-d3d.cc +++ /dev/null @@ -1,397 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include -#include "resource.h" -#include "win-d3d.h" -#include "video/video.h" -#include "win-cgapal.h" - - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); -extern "C" void video_blit_complete(void); - - -void d3d_init_objects(void); -void d3d_close_objects(void); -void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -void d3d_blit_memtoscreen_8(int x, int y, int w, int h); - -static LPDIRECT3D9 d3d = NULL; -static LPDIRECT3DDEVICE9 d3ddev = NULL; -static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; -static LPDIRECT3DTEXTURE9 d3dTexture = NULL; -static D3DPRESENT_PARAMETERS d3dpp; - -static HWND d3d_hwnd; - -struct CUSTOMVERTEX -{ - FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag - FLOAT tu, tv; -}; - -static CUSTOMVERTEX d3d_verts[] = -{ - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, -}; - -int d3d_init(HWND h) -{ - HRESULT hr; - - cgapal_rebuild(); - - d3d_hwnd = h; - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (d3d == NULL) - { - return 0; - } - - memset(&d3dpp, 0, sizeof(d3dpp)); - - d3dpp.Flags = 0; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = h; - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp.MultiSampleQuality = 0; - d3dpp.EnableAutoDepthStencil = false; - d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - d3dpp.Windowed = true; - d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; - d3dpp.BackBufferWidth = 0; - d3dpp.BackBufferHeight = 0; - - hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); - if (FAILED(hr)) - { - return 0; - } - - d3d_init_objects(); - - video_blit_memtoscreen_func = d3d_blit_memtoscreen; - video_blit_memtoscreen_8_func = d3d_blit_memtoscreen_8; - - return 1; -} - -void d3d_close_objects(void) -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -void d3d_init_objects(void) -{ - D3DLOCKED_RECT dr; - RECT r; - - d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL); - - d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - - // r.top = r.left = 0; - r.bottom = r.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - /* for (y = 0; y < 2048; y++) - { - uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); - memset(p, 0, 2048 * 4); - } */ - - d3dTexture->UnlockRect(0); - - d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); -} - -void d3d_resize(int x, int y) -{ - d3dpp.BackBufferWidth = x; - d3dpp.BackBufferHeight = y; - - d3d_reset(); -} - -void d3d_reset(void) -{ - HRESULT hr; - - memset(&d3dpp, 0, sizeof(d3dpp)); - - d3dpp.Flags = 0; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = d3d_hwnd; - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp.MultiSampleQuality = 0; - d3dpp.EnableAutoDepthStencil = false; - d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - d3dpp.Windowed = true; - d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; - d3dpp.BackBufferWidth = 0; - d3dpp.BackBufferHeight = 0; - - hr = d3ddev->Reset(&d3dpp); - - if (hr == D3DERR_DEVICELOST) - return; - - d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - - device_force_redraw(); -} - -void d3d_close(void) -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } - if (d3ddev) - { - d3ddev->Release(); - d3ddev = NULL; - } - if (d3d) - { - d3d->Release(); - d3d = NULL; - } -} - -void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - HRESULT hr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r; - int yy; - - if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (y1 == y2) || (y1 < 0) || (y1 > 2048) || (y2 < 0) || (y2 > 2048) || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - if (hr == D3D_OK) - { - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - - GetClientRect(d3d_hwnd, &r); - d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; - d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; - d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; - d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) - hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) - { - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK) - hr = d3ddev->EndScene(); - } - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); -} - -void d3d_blit_memtoscreen_8(int x, int y, int w, int h) -{ - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r; - uint32_t *p; - int yy, xx; - HRESULT hr = D3D_OK; - - if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = 0; - r.left = 0; - r.bottom = h; - r.right = 2047; - - if (hr == D3D_OK) - { - if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) - fatal("LockRect failed\n"); - - for (yy = 0; yy < h; yy++) - { - p = (uint32_t *) &((((uint8_t *) dr.pBits)[yy * dr.Pitch])); - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - for (xx = 0; xx < w; xx++) - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - video_blit_complete(); - - d3dTexture->UnlockRect(0); - } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - - GetClientRect(d3d_hwnd, &r); - d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; - d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; - d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; - d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) - hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) - { - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK) - hr = d3ddev->EndScene(); - } - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); -} - -void d3d_take_screenshot(wchar_t *fn) -{ - LPDIRECT3DSURFACE9 d3dSurface = NULL; - - if (!d3dTexture) return; - - d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); - - d3dSurface->Release(); - d3dSurface = NULL; -} diff --git a/src/win-d3d.h b/src/win-d3d.h deleted file mode 100644 index 7210d454b..000000000 --- a/src/win-d3d.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int d3d_init(HWND h); - void d3d_close(); - void d3d_reset(); - void d3d_resize(int x, int y); -#ifdef __cplusplus -} -#endif diff --git a/src/win-ddraw-fs.cc b/src/win-ddraw-fs.cc deleted file mode 100644 index 9fc355c63..000000000 --- a/src/win-ddraw-fs.cc +++ /dev/null @@ -1,338 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win-ddraw-fs.h" -#include "win-ddraw-screenshot.h" -#include "video/video.h" -#include "win-cgapal.h" - - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); - -extern "C" int ddraw_fs_init(HWND h); -extern "C" void ddraw_fs_close(void); - -extern "C" void video_blit_complete(void); - -static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); - -static LPDIRECTDRAW lpdd = NULL; -static LPDIRECTDRAW7 lpdd7 = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; -static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; -static DDSURFACEDESC2 ddsd; - -static HWND ddraw_hwnd; -static int ddraw_w, ddraw_h; - -int ddraw_fs_init(HWND h) -{ - ddraw_w = GetSystemMetrics(SM_CXSCREEN); - ddraw_h = GetSystemMetrics(SM_CYSCREEN); - - cgapal_rebuild(); - - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - return 0; - - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) - return 0; - - lpdd->Release(); - lpdd = NULL; - - atexit(ddraw_fs_close); - - if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW | - DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT))) - return 0; - - if (FAILED(lpdd7->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) - return 0; - - // memset(&ddsd, 0, sizeof(ddsd)); - // ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; - ddsd.dwBackBufferCount = 1; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) - return 0; - - ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; - if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2))) - return 0; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) - return 0; - - pclog("DDRAW_INIT complete\n"); - ddraw_hwnd = h; - video_blit_memtoscreen_func = ddraw_fs_blit_memtoscreen; - video_blit_memtoscreen_8_func = ddraw_fs_blit_memtoscreen_8; - - return 1; -} - -void ddraw_fs_close(void) -{ - if (lpdds_back2) - { - lpdds_back2->Release(); - lpdds_back2 = NULL; - } - if (lpdds_back) - { - lpdds_back->Release(); - lpdds_back = NULL; - } - if (lpdds_pri) - { - lpdds_pri->Release(); - lpdds_pri = NULL; - } - if (lpdd_clipper) - { - lpdd_clipper->Release(); - lpdd_clipper = NULL; - } - if (lpdd7) - { - lpdd7->Release(); - lpdd7 = NULL; - } -} - -static void ddraw_fs_size(RECT window_rect, RECT *r_dest, int w, int h) -{ - int ratio_w, ratio_h; - switch (video_fullscreen_scale) - { - case FULLSCR_SCALE_FULL: - r_dest->left = 0; - r_dest->top = 0; - r_dest->right = (window_rect.right - window_rect.left) - 1; - r_dest->bottom = (window_rect.bottom - window_rect.top) - 1; - break; - case FULLSCR_SCALE_43: - r_dest->top = 0; - r_dest->bottom = (window_rect.bottom - window_rect.top) - 1; - r_dest->left = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)); - r_dest->right = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 1; - if (r_dest->left < 0) - { - r_dest->left = 0; - r_dest->right = (window_rect.right - window_rect.left) - 1; - r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)); - r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 1; - } - break; - case FULLSCR_SCALE_SQ: - r_dest->top = 0; - r_dest->bottom = (window_rect.bottom - window_rect.top) - 1; - r_dest->left = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)); - r_dest->right = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 1; - if (r_dest->left < 0) - { - r_dest->left = 0; - r_dest->right = (window_rect.right - window_rect.left) - 1; - r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)); - r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 1; - } - break; - case FULLSCR_SCALE_INT: - ratio_w = (window_rect.right - window_rect.left) / w; - ratio_h = (window_rect.bottom - window_rect.top) / h; - if (ratio_h < ratio_w) - ratio_w = ratio_h; - r_dest->left = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2); - r_dest->right = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 1; - r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2); - r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 1; - break; - } -} - -static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - RECT r_src; - RECT r_dest; - RECT window_rect; - int yy; - HRESULT hr; - DDBLTFX ddbltfx; - - if (lpdds_back == NULL) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) - { - video_blit_complete(); - return; - } - for (yy = y1; yy < y2; yy++) - { - if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); - } - video_blit_complete(); - lpdds_back->Unlock(NULL); - - window_rect.left = 0; - window_rect.top = 0; - window_rect.right = ddraw_w; - window_rect.bottom = ddraw_h; - ddraw_fs_size(window_rect, &r_dest, w, h); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwFillColor = 0; - - lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - - hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - - hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); - if (hr == DDERR_SURFACELOST) - { - lpdds_pri->Restore(); - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); - } -} - -static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) -{ - RECT r_src; - RECT r_dest; - RECT window_rect; - int xx, yy; - HRESULT hr; - DDBLTFX ddbltfx; - - if (lpdds_back == NULL) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - - if (hr == DDERR_SURFACELOST) - { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) - { - video_blit_complete(); - return; - } - for (yy = 0; yy < h; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - uint32_t *p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = 0; xx < w; xx++) - { - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - } - video_blit_complete(); - lpdds_back->Unlock(NULL); - - window_rect.left = 0; - window_rect.top = 0; - window_rect.right = ddraw_w; - window_rect.bottom = ddraw_h; - ddraw_fs_size(window_rect, &r_dest, w, h); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwFillColor = 0; - - lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - - hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); -} - -void ddraw_fs_take_screenshot(wchar_t *fn) -{ - ddraw_common_take_screenshot(fn, lpdds_back2); -} diff --git a/src/win-ddraw-fs.h b/src/win-ddraw-fs.h deleted file mode 100644 index 048c9c160..000000000 --- a/src/win-ddraw-fs.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int ddraw_fs_init(HWND h); - void ddraw_fs_close(); -#ifdef __cplusplus -} -#endif diff --git a/src/win-ddraw-screenshot.cc b/src/win-ddraw-screenshot.cc deleted file mode 100644 index e8a891fe9..000000000 --- a/src/win-ddraw-screenshot.cc +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win.h" -#include "win-ddraw-screenshot.h" -#include "win-language.h" -#include "video/video.h" - - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); - -extern "C" void ddraw_init(HWND h); -extern "C" void ddraw_close(void); - -HBITMAP hbitmap; - -int xs, ys, ys2; - -void CopySurface(IDirectDrawSurface7 *pDDSurface) -{ - HDC hdc, hmemdc; - - HBITMAP hprevbitmap; - - DDSURFACEDESC2 ddsd2; - - pDDSurface->GetDC(&hdc); - - hmemdc = CreateCompatibleDC(hdc); - - ZeroMemory(&ddsd2 ,sizeof( ddsd2 )); // better to clear before using - - ddsd2.dwSize = sizeof( ddsd2 ); //initialize with size - - pDDSurface->GetSurfaceDesc(&ddsd2); - - hbitmap = CreateCompatibleBitmap( hdc ,xs ,ys); - - hprevbitmap = (HBITMAP) SelectObject( hmemdc, hbitmap ); - - BitBlt(hmemdc,0 ,0 ,xs ,ys ,hdc ,0 ,0,SRCCOPY); - - SelectObject(hmemdc,hprevbitmap); // restore the old bitmap - - DeleteDC(hmemdc); - - pDDSurface->ReleaseDC(hdc); - - return ; -} - -void DoubleLines(uint8_t *dst, uint8_t *src) -{ - int i = 0; - for (i = 0; i < ys; i++) - { - memcpy(dst + (i * xs * 8), src + (i * xs * 4), xs * 4); - memcpy(dst + ((i * xs * 8) + (xs * 4)), src + (i * xs * 4), xs * 4); - } -} - -static WCHAR szMessage[2048]; - -void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap) -{ - HDC hdc=NULL; - FILE* fp=NULL; - LPVOID pBuf=NULL; - LPVOID pBuf2=NULL; - BITMAPINFO bmpInfo; - BITMAPFILEHEADER bmpFileHeader; - - do{ - - hdc=GetDC(NULL); - - ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); - - bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); - - GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); - - if(bmpInfo.bmiHeader.biSizeImage<=0) - bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; - - if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) - { - // pclog("ERROR: Unable to Allocate Bitmap Memory"); - break; - } - - if (ys2 <= 250) - { - pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage * 2); - } - - bmpInfo.bmiHeader.biCompression=BI_RGB; - - GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS); - - if((fp = _wfopen(szFilename,L"wb"))==NULL) - { - _swprintf(szMessage, win_language_get_string_from_id(2194), szFilename); - msgbox_error_wstr(ghwnd, szMessage); - break; - } - - bmpFileHeader.bfReserved1=0; - - bmpFileHeader.bfReserved2=0; - - if (pBuf2) - { - bmpInfo.bmiHeader.biSizeImage <<= 1; - bmpInfo.bmiHeader.biHeight <<= 1; - } - - bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; - - bmpFileHeader.bfType=0x4D42; - - bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); - - fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); - - fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); - - if (pBuf2) - { - DoubleLines((uint8_t *) pBuf2, (uint8_t *) pBuf); - fwrite(pBuf2,bmpInfo.bmiHeader.biSizeImage,1,fp); - } - else - { - fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); - } - - }while(false); - - if(hdc) ReleaseDC(NULL,hdc); - - if(pBuf2) free(pBuf2); - - if(pBuf) free(pBuf); - - if(fp) fclose(fp); -} - -void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface) -{ - xs = xsize; - ys = ys2 = ysize; - /* For EGA/(S)VGA, the size is NOT adjusted for overscan. */ - if ((overscan_y > 16) && enable_overscan) - { - xs += overscan_x; - ys += overscan_y; - } - /* For CGA, the width is adjusted for overscan, but the height is not. */ - if (overscan_y == 16) - { - if (ys2 <= 250) - ys += (overscan_y >> 1); - else - ys += overscan_y; - } - CopySurface(pDDSurface); - SaveBitmap(fn, hbitmap); -} diff --git a/src/win-ddraw-screenshot.h b/src/win-ddraw-screenshot.h deleted file mode 100644 index 4739174a1..000000000 --- a/src/win-ddraw-screenshot.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/win-ddraw.cc b/src/win-ddraw.cc deleted file mode 100644 index 509124205..000000000 --- a/src/win-ddraw.cc +++ /dev/null @@ -1,318 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include "win-ddraw.h" -#include "win-ddraw-screenshot.h" -#include "video/video.h" -#include "win-cgapal.h" - - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); - -extern "C" int ddraw_init(HWND h); -extern "C" void ddraw_close(void); - -extern "C" void video_blit_complete(void); - -static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h); - -static LPDIRECTDRAW lpdd = NULL; -static LPDIRECTDRAW7 lpdd7 = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; -static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; -static DDSURFACEDESC2 ddsd; - -static HWND ddraw_hwnd; - -int ddraw_init(HWND h) -{ - cgapal_rebuild(); - - if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) - return 0; - - if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) - return 0; - - lpdd->Release(); - lpdd = NULL; - - atexit(ddraw_close); - - if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_NORMAL))) - return 0; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS; - ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) - return 0; - - // memset(&ddsd, 0, sizeof(ddsd)); - // ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) - return 0; - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; - ddsd.dwWidth = 2048; - ddsd.dwHeight = 2048; - ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; - if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) - return 0; - - if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL))) - return 0; - if (FAILED(lpdd_clipper->SetHWnd(0, h))) - return 0; - if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) - return 0; - - pclog("DDRAW_INIT complete\n"); - ddraw_hwnd = h; - video_blit_memtoscreen_func = ddraw_blit_memtoscreen; - video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8; - - return 1; -} - -void ddraw_close(void) -{ - if (lpdds_back2) - { - lpdds_back2->Release(); - lpdds_back2 = NULL; - } - if (lpdds_back) - { - lpdds_back->Release(); - lpdds_back = NULL; - } - if (lpdds_pri) - { - lpdds_pri->Release(); - lpdds_pri = NULL; - } - if (lpdd_clipper) - { - lpdd_clipper->Release(); - lpdd_clipper = NULL; - } - if (lpdd7) - { - lpdd7->Release(); - lpdd7 = NULL; - } -} - -static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - RECT r_src; - RECT r_dest; - int xx, yy; - POINT po; - uint32_t *p; - HRESULT hr; -// pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); - - if (lpdds_back == NULL) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) - { - video_blit_complete(); - return; - } - for (yy = y1; yy < y2; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer->h) - memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); - } - video_blit_complete(); - lpdds_back->Unlock(NULL); - - po.x = po.y = 0; - - ClientToScreen(ddraw_hwnd, &po); - GetClientRect(ddraw_hwnd, &r_dest); - OffsetRect(&r_dest, po.x, po.y); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - if (readflash) - { - readflash = 0; -#ifdef LEGACY_READ_FLASH - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - } -#endif - } - lpdds_back2->Unlock(NULL); - -// pclog("Blit from %i,%i %i,%i to %i,%i %i,%i\n", r_src.left, r_src.top, r_src.right, r_src.bottom, r_dest.left, r_dest.top, r_dest.right, r_dest.bottom); - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_pri->Restore(); - lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); - } -} - -static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) -{ - RECT r_src; - RECT r_dest; - int xx, yy; - POINT po; - uint32_t *p; - HRESULT hr; - - if (lpdds_back == NULL) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - - if (hr == DDERR_SURFACELOST) - { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) - { - video_blit_complete(); - return; - } - for (yy = 0; yy < h; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = 0; xx < w; xx++) - { - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - } - p = &(((uint32_t *) ddsd.lpSurface)[4 * ddsd.lPitch]); - lpdds_back->Unlock(NULL); - video_blit_complete(); - - po.x = po.y = 0; - - ClientToScreen(ddraw_hwnd, &po); - GetClientRect(ddraw_hwnd, &r_dest); - OffsetRect(&r_dest, po.x, po.y); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - if (readflash) - { - readflash = 0; - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - lpdds_back2->Unlock(NULL); - } - } - - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_pri->Restore(); - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); - } -} - -void ddraw_take_screenshot(wchar_t *fn) -{ - ddraw_common_take_screenshot(fn, lpdds_back2); -} diff --git a/src/win-ddraw.h b/src/win-ddraw.h deleted file mode 100644 index a4044899d..000000000 --- a/src/win-ddraw.h +++ /dev/null @@ -1,12 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int ddraw_init(HWND h); - void ddraw_close(); -#ifdef __cplusplus -} -#endif - diff --git a/src/win-deviceconfig.c b/src/win-deviceconfig.c deleted file mode 100644 index 196845359..000000000 --- a/src/win-deviceconfig.c +++ /dev/null @@ -1,317 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "resource.h" -#include "win.h" - -static device_t *config_device; - -static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int val_int; - int num; - char s[80]; - - switch (message) - { - case WM_INITDIALOG: - { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; - - while (config->type != -1) - { - device_config_selection_t *selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) - { - case CONFIG_BINARY: - val_int = config_get_int(config_device->name, config->name, config->default_int); - - SendMessage(h, BM_SETCHECK, val_int, 0); - - id++; - break; - - case CONFIG_SELECTION: - val_int = config_get_int(config_device->name, config->name, config->default_int); - - c = 0; - while (selection->description[0]) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); - if (val_int == selection->value) - SendMessage(h, CB_SETCURSEL, c, 0); - selection++; - c++; - } - - id += 2; - break; - } - config++; - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; - int changed = 0; - - while (config->type != -1) - { - device_config_selection_t *selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) - { - case CONFIG_BINARY: - val_int = config_get_int(config_device->name, config->name, config->default_int); - - if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) - changed = 1; - - id++; - break; - - case CONFIG_SELECTION: - val_int = config_get_int(config_device->name, config->name, config->default_int); - - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (; c > 0; c--) - selection++; - - if (val_int != selection->value) - changed = 1; - - id += 2; - break; - } - config++; - } - - if (!changed) - { - EndDialog(hdlg, 0); - return TRUE; - } - - if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) != IDOK) - { - EndDialog(hdlg, 0); - return TRUE; - } - - id = IDC_CONFIG_BASE; - config = config_device->config; - - while (config->type != -1) - { - device_config_selection_t *selection = config->selection; - h = GetDlgItem(hdlg, id); - - switch (config->type) - { - case CONFIG_BINARY: - config_set_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0)); - - id++; - break; - - case CONFIG_SELECTION: - c = SendMessage(h, CB_GETCURSEL, 0, 0); - for (; c > 0; c--) - selection++; - config_set_int(config_device->name, config->name, selection->value); - - id += 2; - break; - } - config++; - } - - saveconfig(); - - resetpchard(); - - EndDialog(hdlg, 0); - return TRUE; - } - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; -} - -void deviceconfig_open(HWND hwnd, device_t *device) -{ - device_config_t *config = device->config; - uint16_t *data_block = malloc(16384); - uint16_t *data; - DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block; - DLGITEMTEMPLATE *item; - int y = 10; - int id = IDC_CONFIG_BASE; - - memset(data_block, 0, 4096); - - dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; - dlg->x = 10; - dlg->y = 10; - dlg->cx = 220; - dlg->cy = 70; - - data = (uint16_t *)(dlg + 1); - - *data++ = 0; /*no menu*/ - *data++ = 0; /*predefined dialog box class*/ - data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50); - - *data++ = 8; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); - - if (((unsigned long)data) & 2) - data++; - - while (config->type != -1) - { - switch (config->type) - { - case CONFIG_BINARY: - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 80; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - y += 20; - break; - - case CONFIG_SELECTION: - /*Combo box*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - y += 20; - break; - } - - if (((unsigned long)data) & 2) - data++; - - config++; - } - - dlg->cdit = (id - IDC_CONFIG_BASE) + 2; - - item = (DLGITEMTEMPLATE *)data; - item->x = 20; - item->y = y; - item->cx = 50; - item->cy = 14; - item->id = IDOK; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - item = (DLGITEMTEMPLATE *)data; - item->x = 80; - item->y = y; - item->cx = 50; - item->cy = 14; - item->id = IDCANCEL; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; /* no creation data */ - - dlg->cy = y + 20; - - config_device = device; - - DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc); - - free(data_block); -} diff --git a/src/win-joystick.cc b/src/win-joystick.cc deleted file mode 100644 index 13cc3c1ff..000000000 --- a/src/win-joystick.cc +++ /dev/null @@ -1,281 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define DIRECTINPUT_VERSION 0x0800 -#include -#include -#include -extern "C" { -#include "device.h" -#include "gameport.h" -} -#include "plat-joystick.h" -#include "win.h" - -extern "C" int video_fullscreen; - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void joystick_init(); -extern "C" void joystick_close(); -extern "C" void poll_joystick(); - -plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; -joystick_t joystick_state[MAX_JOYSTICKS]; - -static LPDIRECTINPUT8 lpdi; -static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = {NULL, NULL}; - -int joysticks_present = 0; -static GUID joystick_guids[MAX_JOYSTICKS]; - -static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID data) -{ - if (joysticks_present >= MAX_JOYSTICKS) - return DIENUM_STOP; - - pclog("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName); - - joystick_guids[joysticks_present++] = lpddi->guidInstance; - - if (joysticks_present >= MAX_JOYSTICKS) - return DIENUM_STOP; - - return DIENUM_CONTINUE; -} - -BOOL CALLBACK DIEnumDeviceObjectsCallback( - LPCDIDEVICEOBJECTINSTANCE lpddoi, - LPVOID pvRef) -{ - plat_joystick_t *state = (plat_joystick_t *)pvRef; - - if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || - lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis || - lpddoi->guidType == GUID_Slider) - { - strncpy(state->axis[state->nr_axes].name, lpddoi->tszName, sizeof(state->axis[state->nr_axes].name)); - pclog("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); - if (lpddoi->guidType == GUID_XAxis) - state->axis[state->nr_axes].id = 0; - else if (lpddoi->guidType == GUID_YAxis) - state->axis[state->nr_axes].id = 1; - else if (lpddoi->guidType == GUID_ZAxis) - state->axis[state->nr_axes].id = 2; - else if (lpddoi->guidType == GUID_RxAxis) - state->axis[state->nr_axes].id = 3; - else if (lpddoi->guidType == GUID_RyAxis) - state->axis[state->nr_axes].id = 4; - else if (lpddoi->guidType == GUID_RzAxis) - state->axis[state->nr_axes].id = 5; - state->nr_axes++; - } - else if (lpddoi->guidType == GUID_Button) - { - strncpy(state->button[state->nr_buttons].name, lpddoi->tszName, sizeof(state->button[state->nr_buttons].name)); - pclog("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_buttons++; - } - else if (lpddoi->guidType == GUID_POV) - { - strncpy(state->pov[state->nr_povs].name, lpddoi->tszName, sizeof(state->pov[state->nr_povs].name)); - pclog("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); - state->nr_povs++; - } - - return DIENUM_CONTINUE; -} - -void joystick_init() -{ - int c; - - if (joystick_type == 7) return; - - atexit(joystick_close); - - joysticks_present = 0; - - if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL))) - fatal("joystick_init : DirectInputCreate failed\n"); - - if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY))) - fatal("joystick_init : EnumDevices failed\n"); - - pclog("joystick_init: joysticks_present=%i\n", joysticks_present); - - for (c = 0; c < joysticks_present; c++) - { - LPDIRECTINPUTDEVICE8 lpdi_joystick_temp = NULL; - DIPROPRANGE joy_axis_range; - DIDEVICEINSTANCE device_instance; - DIDEVCAPS devcaps; - - if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL))) - fatal("joystick_init : CreateDevice failed\n"); - if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice8, (void **)&lpdi_joystick[c]))) - fatal("joystick_init : CreateDevice failed\n"); - lpdi_joystick_temp->Release(); - - memset(&device_instance, 0, sizeof(device_instance)); - device_instance.dwSize = sizeof(device_instance); - if (FAILED(lpdi_joystick[c]->GetDeviceInfo(&device_instance))) - fatal("joystick_init : GetDeviceInfo failed\n"); - pclog("Joystick %i :\n", c); - pclog(" tszInstanceName = %s\n", device_instance.tszInstanceName); - pclog(" tszProductName = %s\n", device_instance.tszProductName); - strncpy(plat_joystick_state[c].name, device_instance.tszInstanceName, 64); - - memset(&devcaps, 0, sizeof(devcaps)); - devcaps.dwSize = sizeof(devcaps); - if (FAILED(lpdi_joystick[c]->GetCapabilities(&devcaps))) - fatal("joystick_init : GetCapabilities failed\n"); - pclog(" Axes = %i\n", devcaps.dwAxes); - pclog(" Buttons = %i\n", devcaps.dwButtons); - pclog(" POVs = %i\n", devcaps.dwPOVs); - - lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); - - if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(ghwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) - fatal("joystick_init : SetCooperativeLevel failed\n"); - if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick))) - fatal("joystick_init : SetDataFormat failed\n"); - - joy_axis_range.lMin = -32768; - joy_axis_range.lMax = 32767; - joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); - joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); - joy_axis_range.diph.dwHow = DIPH_BYOFFSET; - joy_axis_range.diph.dwObj = DIJOFS_X; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_Y; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_Z; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RX; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RY; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - joy_axis_range.diph.dwObj = DIJOFS_RZ; - lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); - - if (FAILED(lpdi_joystick[c]->Acquire())) - fatal("joystick_init : Acquire failed\n"); - } -} - -void joystick_close() -{ - if (lpdi_joystick[1]) - { - lpdi_joystick[1]->Release(); - lpdi_joystick[1] = NULL; - } - if (lpdi_joystick[0]) - { - lpdi_joystick[0]->Release(); - lpdi_joystick[0] = NULL; - } -} - -static int joystick_get_axis(int joystick_nr, int mapping) -{ - if (mapping & POV_X) - { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return sin((2*M_PI * (double)pov) / 36000.0) * 32767; - } - else if (mapping & POV_Y) - { - int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; - - if (LOWORD(pov) == 0xFFFF) - return 0; - else - return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; - } - else - return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; -} - -void joystick_poll() -{ - int c, d; - - for (c = 0; c < joysticks_present; c++) - { - DIJOYSTATE joystate; - int b; - - if (FAILED(lpdi_joystick[c]->Poll())) - { - lpdi_joystick[c]->Acquire(); - lpdi_joystick[c]->Poll(); - } - if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate))) - { - lpdi_joystick[c]->Acquire(); - lpdi_joystick[c]->Poll(); - lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate); - } - - plat_joystick_state[c].a[0] = joystate.lX; - plat_joystick_state[c].a[1] = joystate.lY; - plat_joystick_state[c].a[2] = joystate.lZ; - plat_joystick_state[c].a[3] = joystate.lRx; - plat_joystick_state[c].a[4] = joystate.lRy; - plat_joystick_state[c].a[5] = joystate.lRz; - - for (b = 0; b < 16; b++) - plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; - - for (b = 0; b < 4; b++) - plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; -// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); - } - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - if (joystick_state[c].plat_joystick_nr) - { - int joystick_nr = joystick_state[c].plat_joystick_nr - 1; - - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; - - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - int x, y; - double angle, magnitude; - - x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); - y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); - - angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); - magnitude = sqrt((double)x*(double)x + (double)y*(double)y); - - if (magnitude < 16384) - joystick_state[c].pov[d] = -1; - else - joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; - } - } - else - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - joystick_state[c].axis[d] = 0; - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - joystick_state[c].button[d] = 0; - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - joystick_state[c].pov[d] = -1; - } - } -} - diff --git a/src/win-joystickconfig.c b/src/win-joystickconfig.c deleted file mode 100644 index 1432379ff..000000000 --- a/src/win-joystickconfig.c +++ /dev/null @@ -1,541 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "config.h" -#include "device.h" -#include "gameport.h" -#include "plat-joystick.h" -#include "resource.h" -#include "win.h" - -static int joystick_nr; -static int joystick_config_type; -#define AXIS_STRINGS_MAX 3 -static char *axis_strings[AXIS_STRINGS_MAX] = {"X Axis", "Y Axis", "Z Axis"}; - -static void rebuild_axis_button_selections(HWND hdlg) -{ - int id = IDC_CONFIG_BASE + 2; - HWND h; - int joystick; - int c, d; - - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) - { - int sel = c; - - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) - { - for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); - if (c < AXIS_STRINGS_MAX) - { - if (!stricmp(axis_strings[c], plat_joystick_state[joystick-1].axis[d].name)) - sel = d; - } - } - for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++) - { - char s[80]; - - sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - } - SendMessage(h, CB_SETCURSEL, sel, 0); - EnableWindow(h, TRUE); - } - else - EnableWindow(h, FALSE); - - id += 2; - } - - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) - { - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) - { - for (d = 0; d < plat_joystick_state[joystick-1].nr_buttons; d++) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].button[d].name); - SendMessage(h, CB_SETCURSEL, c, 0); - EnableWindow(h, TRUE); - } - else - EnableWindow(h, FALSE); - - id += 2; - } - - for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++) - { - int sel = c; - - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_RESETCONTENT, 0, 0); - - if (joystick) - { - for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++) - { - char s[80]; - - sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); - } - for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); - } - SendMessage(h, CB_SETCURSEL, sel, 0); - EnableWindow(h, TRUE); - } - else - EnableWindow(h, FALSE); - - id += 2; - } - -} - -static int get_axis(HWND hdlg, int id) -{ - HWND h = GetDlgItem(hdlg, id); - int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); - int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_axes; - - if (axis_sel < nr_axes) - return axis_sel; - - axis_sel -= nr_axes; - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); -} - -static int get_pov(HWND hdlg, int id) -{ - HWND h = GetDlgItem(hdlg, id); - int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); - int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2; - - if (axis_sel < nr_povs) - { - if (axis_sel & 1) - return POV_Y | (axis_sel >> 1); - else - return POV_X | (axis_sel >> 1); - } - - return axis_sel - nr_povs; -} - -static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c; - int id; - int joystick; - int nr_axes; - int nr_povs; - int mapping; - - switch (message) - { - case WM_INITDIALOG: - { - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - id = IDC_CONFIG_BASE + 2; - joystick = joystick_state[joystick_nr].plat_joystick_nr; - - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); - - for (c = 0; c < joysticks_present; c++) - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[c].name); - - SendMessage(h, CB_SETCURSEL, joystick, 0); - - rebuild_axis_button_selections(hdlg); - - if (joystick_state[joystick_nr].plat_joystick_nr) - { - nr_axes = plat_joystick_state[joystick-1].nr_axes; - nr_povs = plat_joystick_state[joystick-1].nr_povs; - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) - { - int mapping = joystick_state[joystick_nr].axis_mapping[c]; - - h = GetDlgItem(hdlg, id); - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping, 0); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) - { - h = GetDlgItem(hdlg, id); - SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); - id += 2; - } - for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) - { - h = GetDlgItem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][0]; - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0); - id += 2; - h = GetDlgItem(hdlg, id); - mapping = joystick_state[joystick_nr].pov_mapping[c][1]; - if (mapping & POV_X) - SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0); - else if (mapping & POV_Y) - SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0); - else - SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0); - id += 2; - } - } - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_CONFIG_BASE: - if (HIWORD(wParam) == CBN_SELCHANGE) - rebuild_axis_button_selections(hdlg); - break; - - case IDOK: - { - id = IDC_CONFIG_BASE + 2; - - h = GetDlgItem(hdlg, IDC_CONFIG_BASE); - joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (joystick_state[joystick_nr].plat_joystick_nr) - { - for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) - { - joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) - { - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); - id += 2; - } - for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) - { - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); - id += 2; - h = GetDlgItem(hdlg, id); - joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); - id += 2; - } - } - } - case IDCANCEL: - EndDialog(hdlg, 0); - return TRUE; - } - break; - } - return FALSE; -} - -void joystickconfig_open(HWND hwnd, int joy_nr, int type) -{ - uint16_t *data_block = malloc(16384); - uint16_t *data; - DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block; - DLGITEMTEMPLATE *item; - int y = 10; - int id = IDC_CONFIG_BASE; - int c; - - joystick_nr = joy_nr; - joystick_config_type = type; - - memset(data_block, 0, 4096); - - dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; - dlg->x = 10; - dlg->y = 10; - dlg->cx = 220; - dlg->cy = 70; - - data = (uint16_t *)(dlg + 1); - - *data++ = 0; /*no menu*/ - *data++ = 0; /*predefined dialog box class*/ - data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50); - - *data++ = 8; /*Point*/ - data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); - - if (((unsigned long)data) & 2) - data++; - - - /*Combo box*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Device :", -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - y += 20; - - - for (c = 0; c < joystick_get_axis_count(type); c++) - { - /*Combo box*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - y += 20; - } - - for (c = 0; c < joystick_get_button_count(type); c++) - { - /*Combo box*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - y += 20; - } - - for (c = 0; c < joystick_get_pov_count(type)*2; c++) - { - char s[80]; - - /*Combo box*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 70; - item->y = y; - item->id = id++; - - item->cx = 140; - item->cy = 150; - - item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0085; /* combo box class */ - - if (c & 1) - sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2)); - else - sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2)); - data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - /*Static text*/ - item = (DLGITEMTEMPLATE *)data; - item->x = 10; - item->y = y; - item->id = id++; - - item->cx = 60; - item->cy = 15; - - item->style = WS_CHILD | WS_VISIBLE; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0082; /* static class */ - - data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - y += 20; - } - - dlg->cdit = (id - IDC_CONFIG_BASE) + 2; - - item = (DLGITEMTEMPLATE *)data; - item->x = 20; - item->y = y; - item->cx = 50; - item->cy = 14; - item->id = IDOK; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); - *data++ = 0; /* no creation data */ - - if (((unsigned long)data) & 2) - data++; - - item = (DLGITEMTEMPLATE *)data; - item->x = 80; - item->y = y; - item->cx = 50; - item->cy = 14; - item->id = IDCANCEL; /* OK button identifier */ - item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - data = (uint16_t *)(item + 1); - *data++ = 0xFFFF; - *data++ = 0x0080; /* button class */ - - data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); - *data++ = 0; /* no creation data */ - - dlg->cy = y + 20; - - DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc); - - free(data_block); -} diff --git a/src/win-language.c b/src/win-language.c deleted file mode 100644 index c2525db48..000000000 --- a/src/win-language.c +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include - -#include "ibm.h" -#include "device.h" -#include "ide.h" -#include "resource.h" -#include "win.h" -#include "win-language.h" - -LCID dwLanguage; - -uint32_t dwLangID, dwSubLangID; - -#define STRINGS_NUM 154 - -WCHAR lpResourceString[STRINGS_NUM][512]; - -char openfilestring[260]; -WCHAR wopenfilestring[260]; - -void win_language_set() -{ - SetThreadLocale(dwLanguage); -} - -void win_language_load_common_strings() -{ - int i = 0; - - for (i = 0; i < STRINGS_NUM; i++) - { - LoadString(hinstance, 2048 + i, lpResourceString[i], 512); - } -} - -LPTSTR win_language_get_settings_category(int i) -{ - return lpResourceString[17 + i]; -} - -void win_language_update() -{ - win_language_set(); - win_menu_update(); - win_language_load_common_strings(); -} - -void win_language_check() -{ - LCID dwLanguageNew = MAKELCID(dwLangID, dwSubLangID); - if (dwLanguageNew != dwLanguage) - { - dwLanguage = dwLanguageNew; - win_language_update(); - } -} - -LPTSTR win_language_get_string_from_id(int i) -{ - return lpResourceString[i - 2048]; -} - -LPTSTR win_language_get_string_from_string(char *str) -{ - return lpResourceString[atoi(str) - 2048]; -} - -int msgbox_reset(HWND hwndParent) -{ - return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION); -} - -int msgbox_reset_yn(HWND hwndParent) -{ - return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION); -} - -int msgbox_question(HWND hwndParent, int i) -{ - return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION); -} - -void msgbox_info(HWND hwndParent, int i) -{ - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); -} - -void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) -{ - MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); -} - -void msgbox_error(HWND hwndParent, int i) -{ - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); -} - -void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) -{ - MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); -} - -void msgbox_critical(HWND hwndParent, int i) -{ - MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR); -} - -void msgbox_fatal(HWND hwndParent, char *string) -{ - LPTSTR lptsTemp; - lptsTemp = (LPTSTR) malloc(512); - - mbstowcs(lptsTemp, string, strlen(string) + 1); - - MessageBox(hwndParent, lptsTemp, lpResourceString[2], MB_OK | MB_ICONERROR); - - free(lptsTemp); -} - -int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save) -{ - OPENFILENAME ofn; /* common dialog box structure */ - BOOL r; - DWORD err; - - /* Initialize OPENFILENAME */ - ZeroMemory(&ofn, sizeof(ofn)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hwnd; - ofn.lpstrFile = wopenfilestring; - /* - Set lpstrFile[0] to '\0' so that GetOpenFileName does not - use the contents of szFile to initialize itself. - */ - memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); - ofn.nMaxFile = 259; - ofn.lpstrFilter = f; - ofn.nFilterIndex = 1; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.Flags = OFN_PATHMUSTEXIST; - if (!save) - { - ofn.Flags |= OFN_FILEMUSTEXIST; - } - - /* Display the Open dialog box. */ - - if (save) - { - pclog("GetSaveFileName - lpstrFile = %s\n", ofn.lpstrFile); - r = GetSaveFileName(&ofn); - } - else - { - pclog("GetOpenFileName - lpstrFile = %s\n", ofn.lpstrFile); - r = GetOpenFileName(&ofn); - } - if (r) - { - wcstombs(openfilestring, wopenfilestring, 520); - pclog("File dialog return true\n"); - return 0; - } - pclog("File dialog return false\n"); - err = CommDlgExtendedError(); - pclog("CommDlgExtendedError return %04X\n", err); - return 1; -} - -int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) -{ - WCHAR ufn[512]; - mbstowcs(ufn, fn, strlen(fn) + 1); - return file_dlg_w(hwnd, f, ufn, save); -} - -int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save) -{ - return file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); -} - -int file_dlg_st(HWND hwnd, int i, char *fn, int save) -{ - return file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); -} diff --git a/src/win-language.h b/src/win-language.h deleted file mode 100644 index 5c4237249..000000000 --- a/src/win-language.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifdef __cplusplus -extern "C" { -#endif - -LCID dwLanguage; - -int msgbox_reset(HWND hwndParent); -int msgbox_reset_yn(HWND hwndParent); -int msgbox_question(HWND hwndParent, int i); -void msgbox_info(HWND hwndParent, int i); -void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr); -void msgbox_error(HWND hwndParent, int i); -void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr); -void msgbox_fatal(HWND hwndParent, char *string); -void msgbox_critical(HWND hwndParent, int i); - -int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save); -int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save); -int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save); -int file_dlg_st(HWND hwnd, int i, char *fn, int save); - -void win_language_load_common_strings(); -LPTSTR win_language_get_settings_category(int i); - -void win_language_update(); -void win_language_check(); - -LPTSTR win_language_get_string_from_id(int i); -LPTSTR win_language_get_string_from_string(char *str); - -#ifdef __cplusplus -} -#endif diff --git a/src/win-midi.c b/src/win-midi.c deleted file mode 100644 index a11c7bfea..000000000 --- a/src/win-midi.c +++ /dev/null @@ -1,279 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include "ibm.h" -#include "config.h" -#include "plat-midi.h" - -int midi_id; -static HMIDIOUT midi_out_device = NULL; - -HANDLE m_event; - -void midi_close(); - -static uint8_t midi_rt_buf[1024]; -static uint8_t midi_cmd_buf[1024]; -static int midi_cmd_pos = 0; -static int midi_cmd_len = 0; -static uint8_t midi_status = 0; -static unsigned int midi_sysex_start = 0; -static unsigned int midi_sysex_delay = 0; - -uint8_t MIDI_evt_len[256] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 - - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 -}; - -void midi_init() -{ - MMRESULT hr = MMSYSERR_NOERROR; - - memset(midi_rt_buf, 0, 1024); - memset(midi_cmd_buf, 0, 1024); - - midi_cmd_pos = midi_cmd_len = 0; - midi_status = 0; - - midi_sysex_start = midi_sysex_delay = 0; - - midi_id = config_get_int(NULL, "midi", 0); - - m_event = CreateEvent(NULL, TRUE, TRUE, NULL); - - hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, - 0, CALLBACK_EVENT); - if (hr != MMSYSERR_NOERROR) { - printf("midiOutOpen error - %08X\n",hr); - midi_id = 0; - hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, - 0, CALLBACK_EVENT); - if (hr != MMSYSERR_NOERROR) { - printf("midiOutOpen error - %08X\n",hr); - return; - } - } - - midiOutReset(midi_out_device); -} - -void midi_close() -{ - if (midi_out_device != NULL) - { - midiOutReset(midi_out_device); - midiOutClose(midi_out_device); - midi_out_device = NULL; - CloseHandle(m_event); - } -} - -int midi_get_num_devs() -{ - return midiOutGetNumDevs(); -} -void midi_get_dev_name(int num, char *s) -{ - MIDIOUTCAPS caps; - - midiOutGetDevCaps(num, &caps, sizeof(caps)); - strcpy(s, caps.szPname); -} - -static int midi_pos, midi_len; -static uint32_t midi_command; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; -static int midi_insysex; -static char midi_sysex_data[1024+2]; - -static void midi_send_sysex() -{ - MIDIHDR hdr; - - hdr.lpData = midi_sysex_data; - hdr.dwBufferLength = midi_pos; - hdr.dwFlags = 0; - - midiOutPrepareHeader(midi_out_device, &hdr, sizeof(MIDIHDR)); - midiOutLongMsg(midi_out_device, &hdr, sizeof(MIDIHDR)); - - midi_insysex = 0; -} - -void PlayMsg(uint8_t *msg) -{ - midiOutShortMsg(midi_out_device, *(uint32_t *) msg); -} - -MIDIHDR m_hdr; - -void PlaySysex(uint8_t *sysex, unsigned int len) -{ - MMRESULT result; - - if (WaitForSingleObject(m_event, 2000) == WAIT_TIMEOUT) - { - pclog("Can't send MIDI message\n"); - return; - } - - midiOutUnprepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); - - m_hdr.lpData = (char *) sysex; - m_hdr.dwBufferLength = len; - m_hdr.dwBytesRecorded = len; - m_hdr.dwUser = 0; - - result = midiOutPrepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); - - if (result != MMSYSERR_NOERROR) return; - ResetEvent(m_event); - result = midiOutLongMsg(midi_out_device, &m_hdr, sizeof(m_hdr)); - if (result != MMSYSERR_NOERROR) - { - SetEvent(m_event); - return; - } -} - -#define SYSEX_SIZE 1024 -#define RAWBUF 1024 - -void midi_write(uint8_t val) -{ - uint32_t passed_ticks; - - if (midi_sysex_start) - { - passed_ticks = GetTickCount() - midi_sysex_start; - if (passed_ticks < midi_sysex_delay) - { - Sleep(midi_sysex_delay - passed_ticks); - } - } - - /* Test for a realtime MIDI message */ - if (val >= 0xf8) - { - midi_rt_buf[0] = val; - PlayMsg(midi_rt_buf); - return; - } - - /* Test for a active sysex transfer */ - - if (midi_status == 0xf0) - { - if (!(val & 0x80)) - { - if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; - return; - } - else - { - midi_sysex_data[midi_pos++] = 0xf7; - - if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) - { - /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ - } - else - { - PlaySysex(midi_sysex_data, midi_pos); - if (midi_sysex_start) - { - if (midi_sysex_data[5] == 0x7f) - { - midi_sysex_delay = 290; /* All parameters reset */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) - { - midi_sysex_delay = 145; /* Viking Child */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) - { - midi_sysex_delay = 30; /* Dark Sun 1 */ - } - else - midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; - - midi_sysex_start = GetTickCount(); - } - } - } - } - - - if (val & 0x80) - { - midi_status = val; - midi_cmd_pos = 0; - midi_cmd_len = MIDI_evt_len[val]; - if (midi_status == 0xf0) - { - midi_sysex_data[0] = 0xf0; - midi_pos = 1; - } - } - - if (midi_cmd_len) - { - midi_cmd_buf[midi_cmd_pos++] = val; - if (midi_cmd_pos >= midi_cmd_len) - { - PlayMsg(midi_cmd_buf); - midi_cmd_pos = 1; - } - } -} - -void midi_reset() -{ - uint8_t buf[64], used; - - /* Flush buffers */ - midiOutReset(midi_out_device); - - /* GM1 reset */ - buf[0] = 0xf0; - buf[1] = 0x7e; - buf[2] = 0x7f; - buf[3] = 0x09; - buf[4] = 0x01; - buf[5] = 0xf7; - PlaySysex((uint8_t *) buf, 6); - - /* GS1 reset */ - buf[0] = 0xf0; - buf[1] = 0x41; - buf[2] = 0x10; - buf[3] = 0x42; - buf[4] = 0x12; - buf[5] = 0x40; - buf[6] = 0x00; - buf[7] = 0x7f; - buf[8] = 0x00; - buf[9] = 0x41; - buf[10] = 0xf7; - PlaySysex((uint8_t *) buf, 11); -} diff --git a/src/win-mouse.cc b/src/win-mouse.cc deleted file mode 100644 index 0eacdee78..000000000 --- a/src/win-mouse.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define DIRECTINPUT_VERSION 0x0800 -#include -#include "plat-mouse.h" -#include "win.h" - -extern "C" int video_fullscreen; - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void mouse_init(); -extern "C" void mouse_close(); -extern "C" void mouse_poll_host(); -extern "C" void mouse_get_mickeys(int *x, int *y, int *z); - -static LPDIRECTINPUT8 lpdi; -static LPDIRECTINPUTDEVICE8 lpdi_mouse = NULL; -static DIMOUSESTATE mousestate; -static int mouse_x = 0, mouse_y = 0, mouse_z = 0; -int mouse_buttons = 0; - -void mouse_init() -{ - atexit(mouse_close); - - if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL))) - fatal("mouse_init : DirectInputCreate failed\n"); - if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdi_mouse, NULL))) - fatal("mouse_init : CreateDevice failed\n"); - if (FAILED(lpdi_mouse->SetCooperativeLevel(ghwnd, DISCL_FOREGROUND | (video_fullscreen ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE)))) - fatal("mouse_init : SetCooperativeLevel failed\n"); - if (FAILED(lpdi_mouse->SetDataFormat(&c_dfDIMouse))) - fatal("mouse_init : SetDataFormat failed\n"); -} - -void mouse_close() -{ - if (lpdi_mouse) - { - lpdi_mouse->Release(); - lpdi_mouse = NULL; - } -} - -void mouse_poll_host() -{ - if (FAILED(lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate))) - { - lpdi_mouse->Acquire(); - lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate); - } - mouse_buttons = 0; - if (mousestate.rgbButtons[0] & 0x80) - mouse_buttons |= 1; - if (mousestate.rgbButtons[1] & 0x80) - mouse_buttons |= 2; - if (mousestate.rgbButtons[2] & 0x80) - mouse_buttons |= 4; - mouse_x += mousestate.lX; - mouse_y += mousestate.lY; - mouse_z += mousestate.lZ/120; - if (!mousecapture && !video_fullscreen) - mouse_x = mouse_y = mouse_buttons = 0; -} - -void mouse_get_mickeys(int *x, int *y, int *z) -{ - *x = mouse_x; - *y = mouse_y; - *z = mouse_z; - mouse_x = mouse_y = mouse_z = 0; -} diff --git a/src/win-opendir.c b/src/win-opendir.c deleted file mode 100644 index 847265582..000000000 --- a/src/win-opendir.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation POSIX OpenDir(3) and friends for Win32 API. - * - * Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19 - * - * Version: @(#)win-opendir.c 1.0.1 2017/05/12 - * - * Author: Fred N. van Kempen, - * Copyright 1998-2007 MicroWalt Corporation - * Copyright 2017 Fred N. van Kempen - */ -#define UNICODE -#include -#include -#include -#include -#include -#include -#include "ibm.h" -#include "plat-dir.h" - - -#ifdef UNICODE -# define SUFFIX L"\\*" -# define FINDATA struct _wfinddata_t -# define FINDFIRST _wfindfirst -# define FINDNEXT _wfindnext -#else -# define SUFFIX "\\*" -# define FINDATA struct _finddata_t -# define FINDFIRST _findfirst -# define FINDNEXT _findnext -#endif - - -/* Open a directory. */ -DIR * -#ifdef UNICODE -opendirw(const wchar_t *name) -#else -opendir(const char *name) -#endif -{ - DIR *p; - - /* Create a new control structure. */ - p = (DIR *) malloc(sizeof(DIR)); - if (p == NULL) - return(NULL); - memset(p, 0x00, sizeof(DIR)); - p->flags = (DIR_F_LOWER | DIR_F_SANE); - p->offset = 0; - p->sts = 0; - - /* Create a work area. */ - p->dta = (char *)malloc(sizeof(FINDATA)); - if (p->dta == NULL) { - free(p); - return(NULL); - } - memset(p->dta, 0x00, sizeof(struct _finddata_t)); - - /* Add search filespec. */ -#ifdef UNICODE - wcscpy(p->dir, name); - wcscat(p->dir, SUFFIX); -#else - strcpy(p->dir, name); - strcat(p->dir, SUFFIX); -#endif - - /* Special case: flag if we are in the root directory. */ -#ifdef UNICODE - if (wcslen(p->dir) == 3) -#else - if (strlen(p->dir) == 3) -#endif - p->flags |= DIR_F_ISROOT; - - /* Start the searching by doing a FindFirst. */ - p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); - if (p->handle < 0L) { - free(p->dta); - free(p); - return(NULL); - } - - /* All OK. */ - return(p); -} - - -/* Close an open directory. */ -int -closedir(DIR *p) -{ - if (p == NULL) - return(0); - - _findclose(p->handle); - - if (p->dta != NULL) - free(p->dta); - free(p); - - return(0); -} - - -/* - * Read the next entry from a directory. - * Note that the DOS (FAT), Windows (FAT, FAT32) and Windows NTFS - * file systems do not have a root directory containing the UNIX- - * standard "." and ".." entries. Many applications do assume - * this anyway, so we simply fake these entries. - */ -struct direct * -readdir(DIR *p) -{ - FINDATA *ffp; - - if (p == NULL || p->sts == 1) - return(NULL); - - /* Format structure with current data. */ - ffp = (FINDATA *)p->dta; - p->dent.d_ino = 1L; - p->dent.d_off = p->offset++; - switch(p->offset) { - case 1: /* . */ -#ifdef UNICODE - wcsncpy(p->dent.d_name, L".", MAXNAMLEN+1); -#else - strncpy(p->dent.d_name, ".", MAXNAMLEN+1); -#endif - p->dent.d_reclen = 1; - break; - - case 2: /* .. */ -#ifdef UNICODE - wcsncpy(p->dent.d_name, L"..", MAXNAMLEN+1); -#else - strncpy(p->dent.d_name, "..", MAXNAMLEN+1); -#endif - p->dent.d_reclen = 2; - break; - - default: /* regular entry. */ -#ifdef UNICODE - wcsncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); -#else - strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); -#endif - p->dent.d_reclen = (char) wcslen(p->dent.d_name); - } - - /* Read next entry. */ - p->sts = 0; - - /* Fake the "." and ".." entries here.. */ - if ((p->flags & DIR_F_ISROOT) && (p->offset <= 2)) - return(&(p->dent)); - - /* Get the next entry if we did not fake the above. */ - if (FINDNEXT(p->handle, ffp) < 0) - p->sts = 1; - - return(&(p->dent)); -} - - -/* Report current position within the directory. */ -long -telldir(DIR *p) -{ - return(p->offset); -} - - -void -seekdir(DIR *p, long newpos) -{ - short pos; - - /* First off, rewind to start of directory. */ - p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); - if (p->handle < 0L) { - p->sts = 1; - return; - } - p->offset = 0; - p->sts = 0; - - /* If we are rewinding, that's all... */ - if (newpos == 0L) return; - - /* Nope.. read entries until we hit the right spot. */ - pos = (short) newpos; - while (p->offset != pos) { - p->offset++; - if (FINDNEXT(p->handle, (FINDATA *)p->dta) < 0) { - p->sts = 1; - return; - } - } -} diff --git a/src/win-serial.c b/src/win-serial.c deleted file mode 100644 index fb92b8bea..000000000 --- a/src/win-serial.c +++ /dev/null @@ -1,606 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of host serial port services for Win32. - * - * This code is based on a universal serial port driver for - * Windows and UNIX systems, with support for FTDI and Prolific - * USB ports. Support for these has been removed. - * - * Version: @(#)win-serial.c 1.0.2 2017/05/05 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#define _WIN32_WINNT 0x0501 -#include -#include -#include -#define BHTTY_C -#include "plat-serial.h" - - -extern void pclog(char *__fmt, ...); - - -/* Set the state of a port. */ -int -bhtty_sstate(BHTTY *pp, void *arg) -{ - int i = 0; - - /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid argument\n"); - return(-1); - } - - if (SetCommState(pp->handle, (DCB *)arg) == FALSE) { - /* Mark an error. */ - pclog("%s: set state: %d\n", pp->name, GetLastError()); - return(-1); - } - - return(0); -} - - -/* Fetch the state of a port. */ -int -bhtty_gstate(BHTTY *pp, void *arg) -{ - int i = 0; - - /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("BHTTY: invalid argument\n"); - return(-1); - } - - if (GetCommState(pp->handle, (DCB *)arg) == FALSE) { - /* Mark an error. */ - pclog("%s: get state: %d\n", pp->name, GetLastError()); - return(-1); - } - - return(0); -} - - -/* Enable or disable RTS/CTS mode (hardware handshaking.) */ -int -bhtty_crtscts(BHTTY *pp, char yesno) -{ - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* Get the current mode. */ - if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); - - switch(yesno) { - case 0: /* disable CRTSCTS */ - pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ - pp->dcb.fDsrSensitivity = 0; - - pp->dcb.fOutxCtsFlow = 0; /* disable RTS/CTS mode */ - - pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ - pp->dcb.fOutX = 0; - pp->dcb.fInX = 0; - break; - - case 1: /* enable CRTSCTS */ - pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ - pp->dcb.fDsrSensitivity = 0; - - pp->dcb.fOutxCtsFlow = 1; /* enable RTS/CTS mode */ - - pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ - pp->dcb.fOutX = 0; - pp->dcb.fInX = 0; - break; - - default: - pclog("%s: invalid parameter '%d'!\n", pp->name, yesno); - return(-1); - } - - /* Set new mode. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); - - return(0); -} - - -/* Set the port parameters. */ -int -bhtty_params(BHTTY *pp, char dbit, char par, char sbit) -{ - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* Get the current mode. */ - if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); - - /* Set the desired word length. */ - switch((int)dbit) { - case -1: /* no change */ - break; - - case 5: /* FTDI doesnt like these */ - case 6: - case 9: - break; - - case 7: - case 8: - pp->dcb.ByteSize = dbit; - break; - - default: - pclog("%s: invalid parameter '%d'!\n", pp->name, dbit); - return(-1); - } - - /* Set the type of parity encoding. */ - switch((int)par) { - case -1: /* no change */ - case ' ': - break; - - case 0: - case 'N': - pp->dcb.fParity = FALSE; - pp->dcb.Parity = NOPARITY; - break; - - case 1: - case 'O': - pp->dcb.fParity = TRUE; - pp->dcb.Parity = ODDPARITY; - break; - - case 2: - case 'E': - pp->dcb.fParity = TRUE; - pp->dcb.Parity = EVENPARITY; - break; - - case 3: - case 'M': - case 4: - case 'S': - break; - - default: - pclog("%s: invalid parameter '%c'!\n", pp->name, par); - return(-1); - } - - /* Set the number of stop bits. */ - switch((int)sbit) { - case -1: /* no change */ - break; - - case 1: - pp->dcb.StopBits = ONESTOPBIT; - break; - - case 2: - pp->dcb.StopBits = TWOSTOPBITS; - break; - - default: - pclog("%s: invalid parameter '%d'!\n", pp->name, sbit); - return(-1); - } - - /* Set new mode. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); - - return(0); -} - - -/* Put a port in transparent ("raw") state. */ -void -bhtty_raw(BHTTY *pp, void *arg) -{ - DCB *dcb = (DCB *)arg; - - /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid parameter\n"); - return; - } - - /* Enable BINARY transparent mode. */ - dcb->fBinary = 1; - dcb->fErrorChar = 0; /* disable Error Replacement */ - dcb->fNull = 0; /* disable NUL stripping */ - - /* Disable the DTR and RTS lines. */ - dcb->fDtrControl = DTR_CONTROL_DISABLE; /* DTR line */ - dcb->fRtsControl = RTS_CONTROL_DISABLE; /* RTS line */ - - /* Disable DSR/DCD handshaking. */ - dcb->fOutxDsrFlow = 0; /* DSR handshaking */ - dcb->fDsrSensitivity = 0; /* DSR Sensitivity */ - - /* Disable RTS/CTS handshaking. */ - dcb->fOutxCtsFlow = 0; /* CTS handshaking */ - - /* Disable XON/XOFF handshaking. */ - dcb->fTXContinueOnXoff = 0; /* continue TX after Xoff */ - dcb->fOutX = 0; /* enable output X-ON/X-OFF */ - dcb->fInX = 0; /* enable input X-ON/X-OFF */ - dcb->XonChar = 0x11; /* ASCII XON */ - dcb->XoffChar = 0x13; /* ASCII XOFF */ - dcb->XonLim = 100; - dcb->XoffLim = 100; - - dcb->fParity = FALSE; - dcb->Parity = NOPARITY; - dcb->StopBits = ONESTOPBIT; - dcb->BaudRate = CBR_1200; -} - - -/* Set the port speed. */ -int -bhtty_speed(BHTTY *pp, long speed) -{ - int i; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* Get the current mode and speed. */ - if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); - - /* - * Set speed. - * - * This is not entirely correct, we should use a table - * with DCB_xxx speed values here, but we removed that - * and just hardcode the speed value into DCB. --FvK - */ - pp->dcb.BaudRate = speed; - - /* Set new speed. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); - - return(0); -} - - -/* Clean up and flush. */ -int -bhtty_flush(BHTTY *pp) -{ - DWORD dwErrs; - COMSTAT cs; - int i = 0; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - - /* First, clear any errors. */ - (void)ClearCommError(pp->handle, &dwErrs, &cs); - - /* Now flush all buffers. */ - if (PurgeComm(pp->handle, - (PURGE_RXABORT | PURGE_TXABORT | \ - PURGE_RXCLEAR | PURGE_TXCLEAR)) == FALSE) { - pclog("%s: flush: %d\n", pp->name, GetLastError()); - return(-1); - } - - /* Re-clear any errors. */ - if (ClearCommError(pp->handle, &dwErrs, &cs) == FALSE) { - pclog("%s: clear errors: %d\n", pp->name, GetLastError()); - return(-1); - } - - return(0); -} - - -/* Close an open serial port. */ -void -bhtty_close(BHTTY *pp) -{ - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("BHTTY: invalid handle\n"); - return; - } - - if (pp->handle != INVALID_HANDLE_VALUE) { - /* Restore the previous port state, if any. */ - (void)bhtty_sstate(pp, &pp->odcb); - - /* Close the port. */ - CloseHandle(pp->handle); - pp->handle = INVALID_HANDLE_VALUE; - } - - /* Release the control block. */ - free(pp); -} - - -/* Open a host serial port for I/O. */ -BHTTY * -bhtty_open(char *port, int tmo) -{ - char buff[64]; - COMMTIMEOUTS to; -#if 0 - COMMCONFIG conf; - DWORD d; -#endif - BHTTY *pp; - int i = 0; - - /* Make sure we can do this. */ - if (port == NULL) { - pclog("invalid argument!\n"); - return(NULL); - } - - /* First things first... create a control block. */ - if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) { - pclog("%s: out of memory!\n", port); - return(NULL); - } - memset(pp, 0x00, sizeof(BHTTY)); - strncpy(pp->name, port, sizeof(pp->name)-1); - - /* Try a regular Win32 serial port. */ - sprintf(buff, "\\\\.\\%s", pp->name); - pp->handle = CreateFile(buff, - (GENERIC_READ|GENERIC_WRITE), - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0); - if (pp->handle == INVALID_HANDLE_VALUE) { - pclog("%s: open port: %d\n", pp->name, GetLastError()); - free(pp); - return(NULL); - } - -#if 0 - /* Set up buffer size of the port. */ - if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { - /* This fails on FTDI-based devices. */ - pclog("%s: set buffers: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); - } - - /* Grab default config for the driver and set it. */ - d = sizeof(COMMCONFIG); - memset(&conf, 0x00, d); - conf.dwSize = d; - if (GetDefaultCommConfig(pp->name, &conf, &d) == TRUE) { - /* Change config here... */ - - /* Set new configuration. */ - if (SetCommConfig(pp->handle, &conf, d) == FALSE) { - /* This fails on FTDI-based devices. */ - pclog("%s: set configuration: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); - } - } -#endif - - /* - * We now have an open port. To allow for clean exit - * of the application, we first retrieve the port's - * current settings, and save these for later. - */ - if (bhtty_gstate(pp, &pp->odcb) < 0) { - (void)bhtty_close(pp); - return(NULL); - } - memcpy(&pp->dcb, &pp->odcb, sizeof(DCB)); - - /* Force the port to BINARY mode. */ - bhtty_raw(pp, &pp->dcb); - - /* Set new state of this port. */ - if (bhtty_sstate(pp, &pp->dcb) < 0) { - (void)bhtty_close(pp); - return(NULL); - } - - /* Just to make sure.. disable RTS/CTS mode. */ - (void)bhtty_crtscts(pp, 0); - - /* Set new timeout values. */ - if (GetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while getting current TO\n", - pp->name, GetLastError()); - (void)bhtty_close(pp); - return(NULL); - } - if (tmo < 0) { - /* No timeout, immediate return. */ - to.ReadIntervalTimeout = MAXDWORD; - to.ReadTotalTimeoutMultiplier = 0; - to.ReadTotalTimeoutConstant = 0; - } else if (tmo == 0) { - /* No timeout, wait for data. */ - memset(&to, 0x00, sizeof(to)); - } else { - /* Timeout specified. */ - to.ReadIntervalTimeout = MAXDWORD; - to.ReadTotalTimeoutMultiplier = MAXDWORD; - to.ReadTotalTimeoutConstant = tmo; - } - if (SetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while setting TO\n", - pp->name, GetLastError()); - (void)bhtty_close(pp); - return(NULL); - } - - /* Clear all errors and flush all buffers. */ - if (bhtty_flush(pp) < 0) { - (void)bhtty_close(pp); - return(NULL); - } - - return(pp); -} - - -/* A pending WRITE has finished, handle it. */ -static VOID CALLBACK -bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - -//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); -#if 0 - if ( - if (GetOverlappedResult(p->handle, - &p->rov, &mst, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - sprintf(serial_errmsg, - "%s: I/O read error!", p->name); - return(-1); - } -#endif -} - - -/* Try to write data to an open port. */ -int -bhtty_write(BHTTY *pp, unsigned char val) -{ - DWORD n; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } -//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); - - /* Save the control pointer for later use. */ - pp->wov.hEvent = (HANDLE)pp; - - if (WriteFileEx(pp->handle, - &val, 1, - &pp->wov, - bhtty_write_comp) == FALSE) { - n = GetLastError(); - pclog("%s: I/O error %d in write!\n", pp->name, n); - return(-1); - } - - /* Its pending, so handled in the completion routine. */ - SleepEx(1, TRUE); - - return(0); -} - - -/* - * A pending READ has finished, handle it. - */ -static VOID CALLBACK -bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - DWORD r; -//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); - - if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - pclog("%s: I/O read error!", pp->name); - return; - } -//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); - - /* Do a callback to let them know. */ - if (pp->rd_done != NULL) - pp->rd_done(pp->rd_arg, num); -} - - -/* - * Try to read data from an open port. - * - * For now, we will use one byte per call. Eventually, - * we should go back to loading a buffer full of data, - * just to speed things up a bit. --FvK - * - * Also, not that we do not wait here. We just POST a - * read operation, and the completion routine will do - * the clean-up and notify the caller. - */ -int -bhtty_read(BHTTY *pp, unsigned char *bufp, int max) -{ - DWORD r; - - /* Just one byte. */ - max = 1; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } - - /* Save the control pointer for later use. */ - pp->rov.hEvent = (HANDLE)pp; -//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); - - /* Post a READ on the device. */ - if (ReadFileEx(pp->handle, - bufp, (DWORD)max, - &pp->rov, - bhtty_read_comp) == FALSE) { - r = GetLastError(); - if (r != ERROR_IO_PENDING) { - /* OK, we're being shut down. */ - if (r != ERROR_INVALID_HANDLE) - pclog("%s: I/O read error!\n", pp->name); - return(-1); - } - } - - /* Make ourself alertable. */ - SleepEx(1, TRUE); - - /* OK, it's pending, so we are good for now. */ - return(0); -} diff --git a/src/win-settings.c b/src/win-settings.c deleted file mode 100644 index 308477b70..000000000 --- a/src/win-settings.c +++ /dev/null @@ -1,3674 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include -#include "ibm.h" -#include "mem.h" -#include "cpu/cpu.h" -#include "nvr.h" -#include "model.h" -#include "device.h" -#include "cdrom.h" -#include "disc.h" -#include "fdd.h" -#include "hdd.h" -#include "ide.h" -#include "scsi.h" -#include "scsi_buslogic.h" -#include "network.h" -#include "plat-midi.h" -#include "sound/sound.h" -#include "sound/snd_dbopl.h" -#include "video/video.h" -#include "video/vid_voodoo.h" -#include "gameport.h" -#include "mouse.h" -#include "win.h" -#include "win-language.h" -#include "resource.h" - - -#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ - - -/* Machine category */ -int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; - -/* Video category */ -int temp_gfxcard, temp_video_speed, temp_voodoo; - -/* Input devices category */ -int temp_mouse, temp_joystick; - -/* Sound category */ -int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; - -/* Network category */ -int temp_net_type, temp_net_card; -char temp_pcap_dev[520]; - -/* Peripherals category */ -int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; -int temp_serial[2], temp_lpt, temp_bugger; - -char temp_hdc_name[16]; - -/* Hard disks category */ -hard_disk_t temp_hdc[HDC_NUM]; -wchar_t temp_hdd_fn[HDC_NUM][512]; - -/* Removable devices category */ -int temp_fdd_types[FDD_NUM]; -cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; - -static HWND hwndParentDialog, hwndChildDialog; - -int hdd_controller_current; - -int displayed_category = 0; - -extern int is486; -static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; -static int settings_sound_to_list[20], settings_list_to_sound[20]; -static int settings_mouse_to_list[20], settings_list_to_mouse[20]; -static int settings_scsi_to_list[20], settings_list_to_scsi[20]; -static int settings_network_to_list[20], settings_list_to_network[20]; -static char *hdd_names[16]; - -/* This does the initial read of global variables into the temporary ones. */ -static void win_settings_init() -{ - int i = 0; - - /* Machine category */ - temp_model = model; - temp_cpu_m = cpu_manufacturer; - temp_cpu = cpu; - temp_mem_size = mem_size; - temp_dynarec = cpu_use_dynarec; - temp_fpu = enable_external_fpu; - temp_sync = enable_sync; - - /* Video category */ - temp_gfxcard = gfxcard; - temp_video_speed = video_speed; - temp_voodoo = voodoo_enabled; - - /* Input devices category */ - temp_mouse = mouse_type; - temp_joystick = joystick_type; - - /* Sound category */ - temp_sound_card = sound_card_current; - temp_midi_id = midi_id; - temp_SSI2001 = SSI2001; - temp_GAMEBLASTER = GAMEBLASTER; - temp_GUS = GUS; - temp_opl3_type = opl3_type; - - /* Network category */ - temp_net_type = network_type; - memset(temp_pcap_dev, 0, 520); - strcpy(temp_pcap_dev, pcap_dev); - temp_net_card = network_card; - - /* Peripherals category */ - temp_scsi_card = scsi_card_current; - strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); - temp_ide_ter = ide_enable[2]; - temp_ide_ter_irq = ide_irq[2]; - temp_ide_qua = ide_enable[3]; - temp_ide_qua_irq = ide_irq[3]; - temp_serial[0] = serial_enabled[0]; - temp_serial[1] = serial_enabled[1]; - temp_lpt = lpt_enabled; - temp_bugger = bugger_enabled; - - /* Hard disks category */ - memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); - } - - /* Removable devices category */ - for (i = 0; i < FDD_NUM; i++) - { - temp_fdd_types[i] = fdd_get_type(i); - } - memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); -} - -/* This returns 1 if any variable has changed, 0 if not. */ -static int win_settings_changed() -{ - int i = 0; - int j = 0; - - /* Machine category */ - i = i || (model != temp_model); - i = i || (cpu_manufacturer != temp_cpu_m); - i = i || (cpu != temp_cpu); - i = i || (mem_size != temp_mem_size); - i = i || (temp_dynarec != cpu_use_dynarec); - i = i || (temp_fpu != enable_external_fpu); - i = i || (temp_sync != enable_sync); - - /* Video category */ - i = i || (gfxcard != temp_gfxcard); - i = i || (video_speed != temp_video_speed); - i = i || (voodoo_enabled != temp_voodoo); - - /* Input devices category */ - i = i || (mouse_type != temp_mouse); - i = i || (joystick_type != temp_joystick); - - /* Sound category */ - i = i || (sound_card_current != temp_sound_card); - i = i || (midi_id != temp_midi_id); - i = i || (SSI2001 != temp_SSI2001); - i = i || (GAMEBLASTER != temp_GAMEBLASTER); - i = i || (GUS != temp_GUS); - i = i || (opl3_type != temp_opl3_type); - - /* Network category */ - i = i || (network_type != temp_net_type); - i = i || strcmp(temp_pcap_dev, pcap_dev); - i = i || (network_card != temp_net_card); - - /* Peripherals category */ - i = i || (scsi_card_current != temp_scsi_card); - i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); - i = i || (temp_ide_ter != ide_enable[2]); - i = i || (temp_ide_ter_irq != ide_irq[2]); - i = i || (temp_ide_qua != ide_enable[3]); - i = i || (temp_ide_qua_irq != ide_irq[3]); - i = i || (temp_serial[0] != serial_enabled[0]); - i = i || (temp_serial[1] != serial_enabled[1]); - i = i || (temp_lpt != lpt_enabled); - i = i || (temp_bugger != bugger_enabled); - - /* Hard disks category */ - i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (j = 0; j < HDC_NUM; j++) - { - i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); - } - - /* Removable devices category */ - for (j = 0; j < FDD_NUM; j++) - { - i = i || (temp_fdd_types[j] != fdd_get_type(j)); - } - i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - - return i; -} - -static int settings_msgbox_reset() -{ - int i = 0; - int changed = 0; - - changed = win_settings_changed(); - - if (changed) - { - i = msgbox_reset(hwndParentDialog); - - if (i == IDNO) - { - return 1; - } - else if (i == IDCANCEL) - { - return 0; - } - else - { - return 2; - } - } - else -{ - return 1; - } -} - -/* This saves the settings back to the global variables. */ -static void win_settings_save() -{ - int i = 0; - - /* Machine category */ - model = temp_model; - romset = model_getromset(); - cpu_manufacturer = temp_cpu_m; - cpu = temp_cpu; - mem_size = temp_mem_size; - cpu_use_dynarec = temp_dynarec; - enable_external_fpu = temp_fpu; - enable_sync = temp_sync; - - /* Video category */ - gfxcard = temp_gfxcard; - video_speed = temp_video_speed; - voodoo_enabled = temp_voodoo; - - /* Input devices category */ - mouse_type = temp_mouse; - joystick_type = temp_joystick; - - /* Sound category */ - sound_card_current = temp_sound_card; - midi_id = temp_midi_id; - SSI2001 = temp_SSI2001; - GAMEBLASTER = temp_GAMEBLASTER; - GUS = temp_GUS; - opl3_type = temp_opl3_type; - - /* Network category */ - network_type = temp_net_type; - memset(pcap_dev, 0, 512); - strcpy(pcap_dev, temp_pcap_dev); - network_card = temp_net_card; - - /* Peripherals category */ - scsi_card_current = temp_scsi_card; - strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); - ide_enable[2] = temp_ide_ter; - ide_irq[2] = temp_ide_ter_irq; - ide_enable[3] = temp_ide_qua; - ide_irq[3] = temp_ide_qua_irq; - serial_enabled[0] = temp_serial[0]; - serial_enabled[1] = temp_serial[1]; - lpt_enabled = temp_lpt; - bugger_enabled = temp_bugger; - - /* Hard disks category */ - memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); - } - - /* Removable devices category */ - for (i = 0; i < FDD_NUM; i++) - { - fdd_set_type(i, temp_fdd_types[i]); - } - memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); - - mem_resize(); - loadbios(); - - resetpchard(); - - cpu_set(); - - cpu_update_waitstates(); - - saveconfig(); - - speedchanged(); - - if (joystick_type != 7) gameport_update_joystick_type(); - - update_status_bar_panes(hwndStatus); -} - -static void win_settings_machine_recalc_cpu(HWND hdlg) -{ - HWND h; - int temp_romset = 0; - int cpu_flags; - int cpu_type; - - temp_romset = model_getromset_ex(temp_model); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - cpu_flags = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) - { - fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); - } - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) - { - if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) - { - temp_dynarec = 0; - } - if (cpu_flags & CPU_REQUIRES_DYNAREC) - { - temp_dynarec = 1; - } - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } - - h = GetDlgItem(hdlg, IDC_CHECK_FPU); - cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; - if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) - { - EnableWindow(h, TRUE); - } - else if (cpu_type < CPU_286) - { - temp_fpu = 0; - EnableWindow(h, FALSE); - } - else - { - temp_fpu = 1; - EnableWindow(h, FALSE); - } - SendMessage(h, BM_SETCHECK, temp_fpu, 0); -} - -static void win_settings_machine_recalc_cpu_m(HWND hdlg) -{ - HWND h; - int c = 0; - int temp_romset = 0; - LPTSTR lptsTemp; - char *stransi; - - temp_romset = model_getromset_ex(temp_model); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) - { - stransi = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cpu, 0); - - win_settings_machine_recalc_cpu(hdlg); - - free(lptsTemp); -} - -static void win_settings_machine_recalc_model(HWND hdlg) -{ - HWND h; - int c = 0; - int temp_romset = 0; - LPTSTR lptsTemp; - char *stransi; - UDACCEL accel; - - temp_romset = model_getromset_ex(temp_model); - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); - if (model_getdevice(temp_model)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = 0; - while (models[romstomodel[temp_romset]].cpu[c].cpus != NULL && c < 4) - { - stransi = models[romstomodel[temp_romset]].cpu[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); - if (c == 1) - { - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } - - win_settings_machine_recalc_cpu_m(hdlg); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[temp_romset]].min_ram << 16) | models[romstomodel[temp_romset]].max_ram); - accel.nSec = 0; - accel.nInc = models[romstomodel[temp_romset]].ram_granularity; - SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - if (!(models[romstomodel[temp_romset]].flags & MODEL_AT)) - { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); - } - else - { - SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); - h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); - } - - free(lptsTemp); -} - -static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - char *stransi; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - for (c = 0; c < ROM_MAX; c++) - { - romstolist[c] = 0; - } - c = d = 0; - while (models[c].id != -1) - { - if (romspresent[models[c].id]) - { - stransi = models[c].name; - mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - modeltolist[c] = d; - listtomodel[d] = c; - romstolist[models[c].id] = d; - romstomodel[models[c].id] = c; - d++; - } - c++; - } - SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); - - for (c = 0; c < 8; c++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2132), c); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - SendMessage(h, BM_SETCHECK, temp_dynarec, 0); - - h = GetDlgItem(hdlg, IDC_MEMSPIN); - SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - SendMessage(h, BM_SETCHECK, temp_sync, 0); - - win_settings_machine_recalc_model(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_MACHINE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_model = listtomodel[SendMessage(h,CB_GETCURSEL,0,0)]; - - win_settings_machine_recalc_model(hdlg); - } - break; - case IDC_COMBO_CPU_TYPE: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); - temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); - - temp_cpu = 0; - win_settings_machine_recalc_cpu_m(hdlg); - } - break; - case IDC_COMBO_CPU: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_CPU); - temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); - - win_settings_machine_recalc_cpu(hdlg); - } - break; - case IDC_CONFIGURE_MACHINE: - h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); - temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); - break; - } - - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); - temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_SYNC); - temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_FPU); - temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_WS); - temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_MEMTEXT); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - sscanf(stransi, "%i", &temp_mem_size); - temp_mem_size &= ~(models[temp_model].ram_granularity - 1); - if (temp_mem_size < models[temp_model].min_ram) - { - temp_mem_size = models[temp_model].min_ram; - } - else if (temp_mem_size > models[temp_model].max_ram) - { - temp_mem_size = models[temp_model].max_ram; - } - if (models[temp_model].flags & MODEL_AT) - { - temp_mem_size *= 1024; - } - - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - - return FALSE; -} - -static void recalc_vid_list(HWND hdlg) -{ - HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - int c = 0, d = 0; - int found_card = 0; - WCHAR szText[512]; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_SETCURSEL, 0, 0); - - while (1) - { - char *s = video_card_getname(c); - - if (!s[0]) - break; - - if (video_card_available(c) && gfx_present[video_new_to_old(c)] && - ((models[temp_model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) - { - mbstowcs(szText, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == gfxcard) - { - - SendMessage(h, CB_SETCURSEL, d, 0); - found_card = 1; - } - - d++; - } - - c++; - } - if (!found_card) - SendMessage(h, CB_SETCURSEL, 0, 0); - EnableWindow(h, models[temp_model].fixed_gfxcard ? FALSE : TRUE); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); - EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); -} - -static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - char *stransi; - char *s; - int gfx = 0; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - recalc_vid_list(hdlg); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); - SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); - - h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); - SendMessage(h, BM_SETCHECK, temp_voodoo, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - gfx = video_card_getid(stransi); - - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); - if (video_card_has_config(gfx)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - free(stransi); - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_VIDEO: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - gfx = video_card_getid(stransi); - temp_gfxcard = video_new_to_old(gfx); - - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); - if (video_card_has_config(gfx)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - free(stransi); - free(lptsTemp); - break; - - case IDC_CHECK_VOODOO: - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); - EnableWindow(h, temp_voodoo ? TRUE : FALSE); - break; - - case IDC_CONFIGURE_VOODOO: - deviceconfig_open(hdlg, (void *)&voodoo_device); - break; - - case IDC_CONFIGUREVID: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); - - free(stransi); - free(lptsTemp); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - lptsTemp = (LPTSTR) malloc(512); - stransi = (char *) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); - SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); - wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); - temp_gfxcard = video_new_to_old(video_card_getid(stransi)); - - h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); - temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - - free(stransi); - free(lptsTemp); - - default: - return FALSE; - } - return FALSE; -} - - -static int mouse_valid(int type, int model) -{ - type &= MOUSE_TYPE_MASK; - - if ((type == MOUSE_TYPE_PS2) && - !(models[model].flags & MODEL_PS2)) return(0); - - if ((type == MOUSE_TYPE_AMSTRAD) && - !(models[model].flags & MODEL_AMSTRAD)) return(0); - - if ((type == MOUSE_TYPE_OLIM24) && - !(models[model].flags & MODEL_OLIM24)) return(0); - - return(1); -} - - -static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - int type; - int str_id = 0; - - switch (message) - { - case WM_INITDIALOG: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - c = d = 0; - for (c = 0; c < mouse_get_ndev(); c++) - { - type = mouse_get_type(c); - - settings_mouse_to_list[c] = d; - - if (mouse_valid(type, temp_model)) - { - switch(c) - { - case 0: /* MS Serial */ - default: - str_id = 2139; - break; - case 1: /* PS2 2b */ - str_id = 2141; - break; - case 2: /* PS2 intelli 3b */ - str_id = 2142; - break; - case 3: /* MS/logi bus 2b */ - str_id = 2143; - break; - case 4: /* Amstrad */ - str_id = 2162; - break; - case 5: /* Olivetti M24 */ - str_id = 2177; - break; - case 6: /* MouseSystems */ - str_id = 2140; - break; - case 7: /* Genius Bus */ - str_id = 2161; - break; - } - - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id)); - - settings_list_to_mouse[d] = c; - d++; - } - } - - SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse], 0); - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - c = 0; - while (joystick_get_name(c)) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2144 + c)); - c++; - } - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_joystick, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_JOYSTICK: - if (HIWORD(wParam) == CBN_SELCHANGE) - { - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_JOY1); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY2); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY3); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_JOY4); - EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); - } - break; - - case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 0, temp_joystick); - break; - - case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 1, temp_joystick); - break; - - case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 2, temp_joystick); - break; - - case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBOJOY); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - joystickconfig_open(hdlg, 3, temp_joystick); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); - temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); - temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - -static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) -{ - HWND h; - - char *s; - int valid = 0; - char old_name[16]; - int c, d; - - LPTSTR lptsTemp; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - - if (models[model].flags & MODEL_HAS_IDE) - { - hdc_ignore = 1; - - SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); - EnableWindow(h, FALSE); - SendMessage(h, CB_SETCURSEL, 0, 0); - } - else - { - hdc_ignore = 0; - - valid = 0; - - if (use_selected_hdd) - { - c = SendMessage(h, CB_GETCURSEL, 0, 0); - - if (c != -1 && hdd_names[c]) - { - strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); - } - else - { - strcpy(old_name, "none"); - } - } - else - { - strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); - } - - SendMessage(h, CB_RESETCONTENT, 0, 0); - c = d = 0; - while (1) - { - s = hdd_controller_get_name(c); - if (s[0] == 0) - { - break; - } - if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) - { - c++; - continue; - } - if ((hdd_controller_get_flags(c) & DEVICE_PS2) && !(models[model].flags & MODEL_PS2_HDD)) - { - c++; - continue; - } - if ((hdd_controller_get_flags(c) & DEVICE_MCA) && !(models[model].flags & MODEL_MCA)) - { - c++; - continue; - } - if (!hdd_controller_available(c)) - { - c++; - continue; - } - if (c < 2) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152 + c)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - hdd_names[d] = hdd_controller_get_internal_name(c); - if (!strcmp(old_name, hdd_names[d])) - { - SendMessage(h, CB_SETCURSEL, d, 0); - valid = 1; - } - c++; - d++; - } - - if (!valid) - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - - EnableWindow(h, TRUE); - } - - free(lptsTemp); -} - -int valid_ide_irqs[11] = { 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 }; - -int find_irq_in_array(int irq, int def) -{ - int i = 0; - - for (i = 0; i < 11; i++) - { - if (valid_ide_irqs[i] == irq) - { - return i + 1; - } - } - - return 7 + def; -} - -static char midi_dev_name_buf[512]; - -static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - device_t *sound_dev; - int num = 0; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBOSND); - c = d = 0; - while (1) - { - char *s = sound_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_sound_to_list[c] = d; - - if (sound_card_available(c)) - { - sound_dev = sound_card_getdevice(c); - - if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_sound[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURESND); - if (sound_card_has_config(temp_sound_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - num = midi_get_num_devs(); - for (c = 0; c < num; c++) - { - memset(midi_dev_name_buf, 0, 512); - midi_get_dev_name(c, midi_dev_name_buf); - mbstowcs(lptsTemp, midi_dev_name_buf, strlen(midi_dev_name_buf) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - if (c == temp_midi_id) - SendMessage(h, CB_SETCURSEL, c, 0); - } - - h=GetDlgItem(hdlg, IDC_CHECKCMS); - SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); - - h=GetDlgItem(hdlg, IDC_CHECKGUS); - SendMessage(h, BM_SETCHECK, temp_GUS, 0); - - h=GetDlgItem(hdlg, IDC_CHECKSSI); - SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); - - h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); - SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_CONFIGURESND: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); - break; - - case IDC_COMBOSND: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURESND); - if (sound_card_has_config(temp_sound_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBOSND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKCMS); - temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKGUS); - temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKSSI); - temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); - temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - -static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - device_t *scsi_dev; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - /*SCSI config*/ - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - c = d = 0; - while (1) - { - char *s = scsi_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_scsi_to_list[c] = d; - - if (scsi_card_available(c)) - { - scsi_dev = scsi_card_getdevice(c); - - if (!scsi_dev || (scsi_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_scsi[d] = c; - d++; - } - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_scsi_to_list[temp_scsi_card], 0); - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - recalc_hdd_list(hdlg, temp_model, 0); - - h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); - - for (c = 0; c < 11; c++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - if (temp_ide_ter) - { - SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_ter_irq, 0), 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - - h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); - - for (c = 0; c < 11; c++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - if (temp_ide_qua) - { - SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_qua_irq, 1), 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - - h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); - SendMessage(h, BM_SETCHECK, temp_serial[0], 0); - - h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); - SendMessage(h, BM_SETCHECK, temp_serial[1], 0); - - h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); - SendMessage(h, BM_SETCHECK, temp_lpt, 0); - - h=GetDlgItem(hdlg, IDC_CHECKBUGGER); - SendMessage(h, BM_SETCHECK, temp_bugger, 0); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_CONFIGURE_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); - break; - - case IDC_COMBO_SCSI: - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); - if (scsi_card_has_config(temp_scsi_card)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - break; - } - return FALSE; - - case WM_SAVESETTINGS: - if (hdc_ignore == 0) - { - h = GetDlgItem(hdlg, IDC_COMBO_HDC); - c = SendMessage(h, CB_GETCURSEL, 0, 0); - if (hdd_names[c]) - { - strncpy(temp_hdc_name, hdd_names[c], sizeof(temp_hdc_name) - 1); - } - else - { - strcpy(temp_hdc_name, "none"); - } - } - else - { - strcpy(temp_hdc_name, "none"); - } - - h = GetDlgItem(hdlg, IDC_COMBO_SCSI); - temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER); - temp_ide_ter = SendMessage(h, CB_GETCURSEL, 0, 0); - if (temp_ide_ter > 1) - { - temp_ide_ter_irq = valid_ide_irqs[temp_ide_ter - 1]; - temp_ide_ter = 1; - } - - h = GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - temp_ide_qua = SendMessage(h, CB_GETCURSEL, 0, 0); - if (temp_ide_qua > 1) - { - temp_ide_qua_irq = valid_ide_irqs[temp_ide_qua - 1]; - temp_ide_qua = 1; - } - - h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); - temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); - temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); - temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); - - h = GetDlgItem(hdlg, IDC_CHECKBUGGER); - temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); - - default: - return FALSE; - } - return FALSE; -} - -int net_ignore_message = 0; - -static void network_recalc_combos(HWND hdlg) -{ - HWND h; - - net_ignore_message = 1; - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - if (temp_net_type == 1) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBONET); - if (temp_net_type == 0) - { - EnableWindow(h, TRUE); - } - else if ((temp_net_type == 1) && (network_dev_to_id(temp_pcap_dev) > 0)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_CONFIGURENET); - if (network_card_has_config(temp_net_card) && (temp_net_type == 0)) - { - EnableWindow(h, TRUE); - } - else if (network_card_has_config(temp_net_card) && (temp_net_type == 1) && (network_dev_to_id(temp_pcap_dev) > 0)) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - net_ignore_message = 0; -} - -static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int c = 0; - int d = 0; - LPTSTR lptsTemp; - device_t *scsi_dev; - - switch (message) - { - case WM_INITDIALOG: - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); - SendMessage(h, CB_SETCURSEL, temp_net_type + 1, 0); - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - if (temp_net_type == 0) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - for (c = 0; c < netdev_num; c++) - { - mbstowcs(lptsTemp, netdev_list[c].description, strlen(netdev_list[c].description) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); - - /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBONET); - c = d = 0; - while (1) - { - char *s = network_card_getname(c); - - if (!s[0]) - { - break; - } - - settings_network_to_list[c] = d; - - if (network_card_available(c)) - { - if (c == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); - } - else - { - mbstowcs(lptsTemp, s, strlen(s) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - settings_list_to_network[d] = c; - d++; - } - - c++; - } - SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); - - network_recalc_combos(hdlg); - - free(lptsTemp); - - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBONETTYPE: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; - - network_recalc_combos(hdlg); - break; - - case IDC_COMBOPCAP: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - memset(temp_pcap_dev, 0, 520); - strcpy(temp_pcap_dev, netdev_list[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - network_recalc_combos(hdlg); - break; - - case IDC_COMBONET: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - network_recalc_combos(hdlg); - break; - - case IDC_CONFIGURENET: - if (net_ignore_message) - { - return FALSE; - } - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); - break; - } - return FALSE; - - case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); - temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0) - 1; - - h = GetDlgItem(hdlg, IDC_COMBOPCAP); - memset(temp_pcap_dev, 0, 520); - strcpy(temp_pcap_dev, netdev_list[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - - h = GetDlgItem(hdlg, IDC_COMBONET); - temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - default: - return FALSE; - } - - return FALSE; -} - -static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 8; i += 2) - { - hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -int next_free_id = 0; - -wchar_t ifn[HDC_NUM][512]; - -static void normalize_hd_list() -{ - hard_disk_t ihdc[HDC_NUM]; - int i, j; - - j = 0; - memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memset(ifn[i], 0, 1024); - } - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus > 0) - { - memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); - memcpy(ifn[j], temp_hdd_fn[i], 1024); - j++; - } - } - - memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], ifn[i], 1024); - } -} - -int hdc_id_to_listview_index[HDC_NUM]; -int hd_listview_items; - -hard_disk_t new_hdc; -int hdlv_current_sel; - -static int get_selected_hard_disk(HWND hdlg) -{ - int hard_disk = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - hard_disk = i; - } - } - - return hard_disk; -} - -static void add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - for (i = 0; i < 4; i++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} - -static void recalc_location_controls(HWND hdlg, int is_add_dlg) -{ - int i = 0; - HWND h; - - int bus = 0; - - for (i = 1799; i < 1803; i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - if ((hd_listview_items > 0) || is_add_dlg) - { - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - - switch(bus) - { - case 0: /* MFM/RLL */ - h = GetDlgItem(hdlg, 1799); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); - break; - case 1: /* IDE (PIO-only) */ - case 2: /* IDE (PIO and DMA) */ - h = GetDlgItem(hdlg, 1802); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); - break; - case 3: /* SCSI */ - h = GetDlgItem(hdlg, 1800); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, 1801); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_id : temp_hdc[hdlv_current_sel].scsi_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_lun : temp_hdc[hdlv_current_sel].scsi_lun, 0); - break; - } - } - - if ((hd_listview_items == 0) && !is_add_dlg) - { - h = GetDlgItem(hdlg, 1798); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); - } - else - { - h = GetDlgItem(hdlg, 1798); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - } -} - -static void recalc_next_free_id(HWND hdlg) -{ - HWND h; - int i; - - int c_mfm = 0; - int c_ide_pio = 0; - int c_ide_dma = 0; - int c_scsi = 0; - int enable_add = 0; - - next_free_id = -1; - - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus == 1) - { - c_mfm++; - } - else if (temp_hdc[i].bus == 2) - { - c_ide_pio++; - } - else if (temp_hdc[i].bus == 3) - { - c_ide_dma++; - } - else if (temp_hdc[i].bus == 4) - { - c_scsi++; - } - } - - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus == 0) - { - next_free_id = i; - break; - } - } - - /* pclog("Next free ID: %i\n", next_free_id); */ - - enable_add = enable_add || (next_free_id >= 0); - /* pclog("Enable add: %i\n", enable_add); */ - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); - /* pclog("Enable add: %i\n", enable_add); */ - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); - - if (enable_add) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); - - if (enable_add) - { - EnableWindow(h, TRUE); - } - else - { - EnableWindow(h, FALSE); - } - - h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - - if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) - { - EnableWindow(h, FALSE); - } - else - { - EnableWindow(h, TRUE); - } -} - -static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column) -{ - LVITEM lvI; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = column; - lvI.iItem = i; - - if (column == 0) - { - switch(temp_hdc[i].bus) - { - case 1: - wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); - break; - case 2: - wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 3: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iImage = temp_hdc[i].bus - 1; - } - else if (column == 1) - { - lvI.pszText = temp_hdd_fn[i]; - lvI.iImage = 0; - } - else if (column == 2) - { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); - lvI.pszText = szText; - lvI.iImage = 0; - } - else if (column == 3) - { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); - lvI.pszText = szText; - lvI.iImage = 0; - } - else if (column == 4) - { - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); - lvI.pszText = szText; - lvI.iImage = 0; - } - else if (column == 5) - { - wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); - lvI.pszText = szText; - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - int j = 0; - WCHAR szText[256]; - - hd_listview_items = 0; - hdlv_current_sel = -1; - - ListView_DeleteAllItems(hwndList); - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus > 0) - { - hdc_id_to_listview_index[i] = j; - lvI.iSubItem = 0; - switch(temp_hdc[i].bus) - { - case 1: - wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); - break; - case 2: - wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 3: - wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); - break; - } - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = temp_hdc[i].bus - 1; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 1; - lvI.pszText = temp_hdd_fn[i]; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 2; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 3; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 4; - wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - lvI.iSubItem = 5; - wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); - lvI.pszText = szText; - lvI.iItem = j; - lvI.iImage = 0; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return FALSE; - } - - j++; - } - else - { - hdc_id_to_listview_index[i] = -1; - } - } - - hd_listview_items = j; - - return TRUE; -} - -/* Icon, Bus, File, C, H, S, Size */ -#define C_COLUMNS_HARD_DISKS 6 - -static BOOL win_settings_hard_disks_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - int iCol; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) - { - lvc.iSubItem = iCol; - lvc.pszText = win_language_get_string_from_id(2082 + iCol); - - switch(iCol) - { - - case 0: /* Bus */ - lvc.cx = 135; - lvc.fmt = LVCFMT_LEFT; - break; - case 2: /* Cylinders */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - case 3: /* Heads */ - case 4: /* Sectors */ - lvc.cx = 25; - lvc.fmt = LVCFMT_RIGHT; - break; - case 1: /* File */ - lvc.cx = 150; - lvc.fmt = LVCFMT_LEFT; - break; - case 5: /* Size (MB) 8 */ - lvc.cx = 41; - lvc.fmt = LVCFMT_RIGHT; - break; - } - - if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) - { - return FALSE; - } - } - - return TRUE; -} - -static void get_edit_box_contents(HWND hdlg, int id, uint64_t *val) -{ - HWND h; - WCHAR szText[256]; - char stransi[256]; - - h = GetDlgItem(hdlg, id); - SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); - wcstombs(stransi, szText, (wcslen(szText) * 2) + 2); - sscanf(stransi, "%" PRIu64, val); -} - -static void get_combo_box_selection(HWND hdlg, int id, uint64_t *val) -{ - HWND h; - - h = GetDlgItem(hdlg, id); - *val = SendMessage(h, CB_GETCURSEL, 0, 0); -} - -static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) -{ - HWND h; - WCHAR szText[256]; - - h = GetDlgItem(hdlg, id); - wsprintf(szText, win_language_get_string_from_id(2160), val); - SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); -} - -int hard_disk_added = 0; -int max_spt = 63; - -int no_update = 0; - -int existing = 0; -uint64_t selection = 127; - -uint64_t spt, hpc, tracks, size; -wchar_t hd_file_name[512]; - -static int hdconf_initialize_hdt_combo(HWND hdlg) -{ - HWND h; - int i = 0; - uint64_t temp_size = 0; - uint64_t size_mb = 0; - WCHAR szText[256]; - - selection = 127; - - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) - { - temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; - size_mb = temp_size >> 11; - wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) - { - selection = i; - } - } - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187)); - SendMessage(h, CB_SETCURSEL, selection, 0); - return selection; -} - -static void recalc_selection(HWND hdlg) -{ - HWND h; - int i = 0; - - selection = 127; - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - for (i = 0; i < 127; i++) - { - if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) - { - selection = i; - } - } - if ((selection == 127) && (hpc == 16) && (spt == 63)) - { - selection = 128; - } - SendMessage(h, CB_SETCURSEL, selection, 0); -} - -static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int64_t i = 0; - int bus; - uint64_t temp; - WCHAR szText[256]; - FILE *f; - uint32_t sector_size = 512; - uint32_t zero = 0; - uint32_t base = 0x1000; - uint64_t signature = 0xD778A82044445459ll; - char buf[512]; - - switch (message) - { - case WM_INITDIALOG: - memset(hd_file_name, 0, 512); - - SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); - - no_update = 1; - spt = existing ? 0 : 17; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = existing ? 0 : 15; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = existing ? 0 : 1023; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - hdconf_initialize_hdt_combo(hdlg); - if (existing) - { - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, FALSE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, FALSE); - } - add_locations(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, 1, 0); - recalc_location_controls(hdlg, 1); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - EnableWindow(h, FALSE); - no_update = 0; - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - if (wcslen(hd_file_name) == 0) - { - msgbox_error(hwndParentDialog, 2056); - return TRUE; - } - - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(temp_hdc[next_free_id].spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(temp_hdc[next_free_id].hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(temp_hdc[next_free_id].tracks)); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - temp_hdc[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - memset(temp_hdd_fn[next_free_id], 0, 1024); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); - - sector_size = 512; - - if (!existing && (wcslen(hd_file_name) > 0)) - { - f = _wfopen(hd_file_name, L"wb"); - - if (image_is_hdi(hd_file_name)) - { - if (size >= 0x100000000ll) - { - fclose(f); - msgbox_error(hwndParentDialog, 2058); - return TRUE; - } - - fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ - fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ - fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ - fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - - for (i = 0; i < 0x3f8; i++) - { - fwrite(&zero, 1, 4, f); - } - } - else if (image_is_hdx(hd_file_name, 0)) - { - if (size > 0xffffffffffffffffll) - { - fclose(f); - msgbox_error(hwndParentDialog, 2163); - return TRUE; - } - - fwrite(&signature, 1, 8, f); /* 00000000: Signature */ - fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ - fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ - fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ - fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ - fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ - fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ - fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ - } - - memset(buf, 0, 512); - size >>= 9; - for (i = 0; i < size; i++) - { - fwrite(buf, 512, 1, f); - } - - fclose(f); - msgbox_info(hwndParentDialog, 2059); - } - - hard_disk_added = 1; - EndDialog(hdlg, 0); - return TRUE; - - case IDCANCEL: - hard_disk_added = 0; - EndDialog(hdlg, 0); - return TRUE; - - case IDC_CFILE: - if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) - { - if (!existing) - { - f = _wfopen(wopenfilestring, L"rb"); - if (f != NULL) - { - fclose(f); - if (msgbox_question(ghwnd, 2178) != IDYES) - { - return FALSE; - } - } - } - - f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); - if (f == NULL) - { - msgbox_error(hwndParentDialog, existing ? 2060 : 2057); - return TRUE; - } - if (existing) - { - if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) - { - fseeko64(f, 0x10, SEEK_SET); - fread(§or_size, 1, 4, f); - if (sector_size != 512) - { - msgbox_error(hwndParentDialog, 2061); - fclose(f); - return TRUE; - } - spt = hpc = tracks = 0; - fread(&spt, 1, 4, f); - fread(&hpc, 1, 4, f); - fread(&tracks, 1, 4, f); - } - else - { - fseeko64(f, 0, SEEK_END); - size = ftello64(f); - fclose(f); - if (((size % 17) == 0) && (size <= 133693440)) - { - spt = 17; - if (size <= 26738688) - { - hpc = 4; - } - else if (size <= 53477376) - { - hpc = 6; - } - else if (size <= 71303168) - { - hpc = 8; - } - else - { - hpc = 15; - } - } - else - { - spt = 63; - hpc = 16; - } - - tracks = ((size >> 9) / hpc) / spt; - } - - no_update = 1; - - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - - h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); - EnableWindow(h, TRUE); - - no_update = 0; - } - else - { - fclose(f); - } - } - - h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); - - return TRUE; - - case IDC_EDIT_HD_CYL: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); - if (temp != tracks) - { - tracks = temp; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_EDIT_HD_HPC: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); - if (temp != hpc) - { - hpc = temp; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_EDIT_HD_SPT: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); - if (temp != spt) - { - spt = temp; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_EDIT_HD_SIZE: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); - if (temp != (size >> 20)) - { - size = temp << 20; - tracks = ((size >> 9) / hpc) / spt; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - recalc_selection(hdlg); - } - no_update = 0; - break; - - case IDC_COMBO_HD_TYPE: - if (no_update) - { - return FALSE; - } - - no_update = 1; - get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); - if ((temp != selection) && (temp != 127) && (temp != 128)) - { - selection = temp; - tracks = hdt[selection][0]; - hpc = hdt[selection][1]; - spt = hdt[selection][2]; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - } - else if ((temp != selection) && (temp == 127)) - { - selection = temp; - } - else if ((temp != selection) && (temp == 128)) - { - selection = temp; - hpc = 16; - spt = 63; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); - } - no_update = 0; - break; - - case IDC_COMBO_HD_BUS: - if (no_update) - { - return FALSE; - } - - no_update = 1; - recalc_location_controls(hdlg, 1); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); - max_spt = (bus == 2) ? 99 : 63; - if (spt > max_spt) - { - spt = max_spt; - size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); - set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); - recalc_selection(hdlg); - } - no_update = 0; - break; - } - - return FALSE; - } - - return FALSE; -} - -void hard_disk_add_open(HWND hwnd, int is_existing) -{ - BOOL ret; - - existing = !!is_existing; - hard_disk_added = 0; - ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); -} - -int ignore_change = 0; - -static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int old_sel = 0; - - switch (message) - { - case WM_INITDIALOG: - ignore_change = 1; - - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. - This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list - (which can only happen by manually editing the configuration file). */ - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_init_columns(h); - win_settings_hard_disks_image_list_init(h); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - add_locations(hdlg); - if (hd_listview_items > 0) - { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); - } - else - { - hdlv_current_sel = -1; - } - recalc_location_controls(hdlg, 0); - - ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if ((hd_listview_items == 0) || ignore_change) - { - return FALSE; - } - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) - { - old_sel = hdlv_current_sel; - hdlv_current_sel = get_selected_hard_disk(hdlg); - if (hdlv_current_sel == old_sel) - { - return FALSE; - } - else if (hdlv_current_sel == -1) - { - ignore_change = 1; - hdlv_current_sel = old_sel; - ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - ignore_change = 0; - return FALSE; - } - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[hdlv_current_sel].bus - 1, 0); - recalc_location_controls(hdlg, 0); - ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_HD_BUS: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - recalc_location_controls(hdlg, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_CHANNEL_IDE: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - temp_hdc[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_ID: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - temp_hdc[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_COMBO_HD_LUN: - if (ignore_change) - { - return FALSE; - } - - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - temp_hdc[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); - ignore_change = 0; - return FALSE; - - case IDC_BUTTON_HDD_ADD: - hard_disk_add_open(hdlg, 1); - if (hard_disk_added) - { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_ADD_NEW: - hard_disk_add_open(hdlg, 0); - if (hard_disk_added) - { - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - ignore_change = 0; - } - return FALSE; - - case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); - temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ - normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ - ignore_change = 1; - h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); - win_settings_hard_disks_recalc_list(h); - recalc_next_free_id(hdlg); - if (hd_listview_items > 0) - { - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - hdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); - } - else - { - hdlv_current_sel = -1; - } - recalc_location_controls(hdlg, 0); - ignore_change = 0; - return FALSE; - } - - default: - return FALSE; - } - - return FALSE; -} - -int fdlv_current_sel; -int cdlv_current_sel; - -static int combo_id_to_string_id(int combo_id) -{ - switch (combo_id) - { - case 0: /* Disabled */ - default: - return 2151; - break; - case 2: /* Atapi (PIO-only) */ - return 2189; - break; - case 3: /* Atapi (PIA and DMA) */ - return 2190; - break; - case 4: /* SCSI */ - return 2168; - break; - } -} - -static int combo_id_to_format_string_id(int combo_id) -{ - switch (combo_id) - { - case 0: /* Disabled */ - default: - return 2151; - break; - case 2: /* Atapi (PIO-only) */ - return 2191; - break; - case 3: /* Atapi (PIA and DMA) */ - return 2192; - break; - case 4: /* SCSI */ - return 2158; - break; - } -} - -static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 14; i++) - { - hiconItem = LoadIcon(hinstance, (LPCWSTR) fdd_type_to_icon(i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - int j = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 514); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 160); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 162); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - hiconItem = LoadIcon(hinstance, (LPCWSTR) 164); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - if (temp_fdd_types[i] > 0) - { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } - else - { - lvI.pszText = win_language_get_string_from_id(2151); - } - lvI.iItem = i; - lvI.iImage = temp_fdd_types[i]; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - char s[256]; - WCHAR szText[256]; - int bid = 0; - int fsid = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 4; i++) - { - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - switch (temp_cdrom_drives[i].bus_type) - { - case 0: - default: - lvI.pszText = win_language_get_string_from_id(fsid); - break; - case 2: - case 3: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - break; - } - - lvI.iItem = i; - - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = win_language_get_string_from_id(2188); - - lvc.cx = 392; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { - return FALSE; - } - - return TRUE; -} - -static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) -{ - LVCOLUMN lvc; - - lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; - - lvc.iSubItem = 0; - lvc.pszText = win_language_get_string_from_id(2082); - - lvc.cx = 392; - lvc.fmt = LVCFMT_LEFT; - - if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) - { - return FALSE; - } - - return TRUE; -} - -static int get_selected_floppy_drive(HWND hdlg) -{ - int floppy_drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - floppy_drive = i; - } - } - - return floppy_drive; -} - -static int get_selected_cdrom_drive(HWND hdlg) -{ - int cd_drive = -1; - int i, j = 0; - HWND h; - - for (i = 0; i < 6; i++) - { - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - cd_drive = i; - } - } - - return cd_drive; -} - -static void win_settings_floppy_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - char s[256]; - WCHAR szText[256]; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - if (temp_fdd_types[i] > 0) - { - strcpy(s, fdd_getname(temp_fdd_types[i])); - mbstowcs(szText, s, strlen(s) + 1); - lvI.pszText = szText; - } - else - { - lvI.pszText = win_language_get_string_from_id(2151); - } - lvI.iImage = temp_fdd_types[i]; - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) -{ - LVITEM lvI; - char s[256]; - WCHAR szText[256]; - int bid; - int fsid; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - lvI.iSubItem = 0; - lvI.iItem = i; - - fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); - - switch (temp_cdrom_drives[i].bus_type) - { - case 0: - default: - lvI.pszText = win_language_get_string_from_id(fsid); - break; - case 2: - case 3: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); - lvI.pszText = szText; - break; - case 4: - wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); - lvI.pszText = szText; - break; - } - - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - - if (ListView_SetItem(hwndList, &lvI) == -1) - { - return; - } -} - -static void cdrom_add_locations(HWND hdlg) -{ - LPTSTR lptsTemp; - HWND h; - int i = 0; - - lptsTemp = (LPTSTR) malloc(512); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = 1; i < 5; i++) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - for (i = 0; i < 16; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - for (i = 0; i < 8; i++) - { - wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - } - - free(lptsTemp); -} -static void cdrom_recalc_location_controls(HWND hdlg) -{ - int i = 0; - HWND h; - - int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; - - for (i = 1800; i < 1803; i++) - { - h = GetDlgItem(hdlg, i); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - } - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - - switch(bus) - { - case 2: /* ATAPI (PIO-only) */ - case 3: /* ATAPI (PIO and DMA) */ - h = GetDlgItem(hdlg, 1802); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); - break; - case 4: /* SCSI */ - h = GetDlgItem(hdlg, 1800); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, 1801); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); - - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - ShowWindow(h, SW_SHOW); - EnableWindow(h, TRUE); - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); - break; - } -} - - -int rd_ignore_change = 0; - -static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int i = 0; - int old_sel = 0; - int cid = 0; - WCHAR szText[256]; - - switch (message) - { - case WM_INITDIALOG: - rd_ignore_change = 1; - - fdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_init_columns(h); - win_settings_floppy_drives_image_list_init(h); - win_settings_floppy_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - for (i = 0; i < 14; i++) - { - if (i == 0) - { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); - } - else - { - mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - } - } - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - - cdlv_current_sel = 0; - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_init_columns(h); - win_settings_cdrom_drives_image_list_init(h); - win_settings_cdrom_drives_recalc_list(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - cdrom_add_locations(hdlg); - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) - { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - cdrom_recalc_location_controls(hdlg); - - rd_ignore_change = 0; - return TRUE; - - case WM_NOTIFY: - if (rd_ignore_change) - { - return FALSE; - } - - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) - { - old_sel = fdlv_current_sel; - fdlv_current_sel = get_selected_floppy_drive(hdlg); - if (fdlv_current_sel == old_sel) - { - return FALSE; - } - else if (fdlv_current_sel == -1) - { - rd_ignore_change = 1; - fdlv_current_sel = old_sel; - ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); - rd_ignore_change = 0; - } - else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) - { - old_sel = cdlv_current_sel; - cdlv_current_sel = get_selected_cdrom_drive(hdlg); - if (cdlv_current_sel == old_sel) - { - return FALSE; - } - else if (cdlv_current_sel == -1) - { - rd_ignore_change = 1; - cdlv_current_sel = old_sel; - ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - rd_ignore_change = 0; - return FALSE; - } - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) - { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); - } - cdrom_recalc_location_controls(hdlg); - rd_ignore_change = 0; - } - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_COMBO_FD_TYPE: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); - temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); - win_settings_floppy_drives_update_item(h, fdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_BUS: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) - { - temp_cdrom_drives[cdlv_current_sel].bus_type = 0; - } - cdrom_recalc_location_controls(hdlg); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_ID: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); - temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_LUN: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); - temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - - case IDC_COMBO_CD_CHANNEL_IDE: - if (rd_ignore_change) - { - return FALSE; - } - - rd_ignore_change = 1; - h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); - temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); - win_settings_cdrom_drives_update_item(h, cdlv_current_sel); - rd_ignore_change = 0; - return FALSE; - } - - default: - return FALSE; - } - - return FALSE; -} - -void win_settings_show_child(HWND hwndParent, DWORD child_id) -{ - if (child_id == displayed_category) - { - return; - } - else - { - displayed_category = child_id; - } - - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - - DestroyWindow(hwndChildDialog); - - switch(child_id) - { - case 0: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); - break; - case 1: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); - break; - case 2: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); - break; - case 3: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); - break; - case 4: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); - break; - case 5: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); - break; - case 6: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); - break; - case 7: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); - break; - default: - fatal("Invalid child dialog ID\n"); - return; - } - - ShowWindow(hwndChildDialog, SW_SHOWNORMAL); -} - -static BOOL win_settings_main_image_list_init(HWND hwndList) -{ - HICON hiconItem; - HIMAGELIST hSmall; - - int i = 0; - - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - ILC_MASK | ILC_COLOR32, 1, 1); - - for (i = 0; i < 8; i++) - { - hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + i)); - ImageList_AddIcon(hSmall, hiconItem); - DestroyIcon(hiconItem); - } - - ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); - - return TRUE; -} - -static BOOL win_settings_main_insert_categories(HWND hwndList) -{ - LVITEM lvI; - int i = 0; - - lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; - - for (i = 0; i < 8; i++) - { - lvI.pszText = win_language_get_settings_category(i); - lvI.iItem = i; - lvI.iImage = i; - - if (ListView_InsertItem(hwndList, &lvI) == -1) - return FALSE; - } - - return TRUE; -} - -static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - int category; - int i = 0; - int j = 0; - - hwndParentDialog = hdlg; - - switch (message) - { - case WM_INITDIALOG: - pause = 1; - win_settings_init(); - displayed_category = -1; - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - win_settings_main_image_list_init(h); - win_settings_main_insert_categories(h); - ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); - h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, 2047); - EnableWindow(h, FALSE); - ShowWindow(h, SW_HIDE); - return TRUE; - case WM_NOTIFY: - if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) - { - category = -1; - for (i = 0; i < 8; i++) - { - h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); - j = ListView_GetItemState(h, i, LVIS_SELECTED); - if (j) - { - category = i; - /* pclog("Category %i selected\n", i); */ - } - } - if (category != -1) - { - /* pclog("Showing child: %i\n", category); */ - win_settings_show_child(hdlg, category); - } - } - break; - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - /* pclog("Saving settings...\n"); */ - SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); - i = settings_msgbox_reset(); - if (i > 0) - { - if (i == 2) - { - win_settings_save(); - } - - /* pclog("Destroying window...\n"); */ - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - } - else - { - return FALSE; - } - case IDCANCEL: - DestroyWindow(hwndChildDialog); - EndDialog(hdlg, 0); - pause=0; - return TRUE; - } - break; - default: - return FALSE; - } - - return FALSE; -} - -void win_settings_open(HWND hwnd) -{ - DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); -} diff --git a/src/win-status.c b/src/win-status.c deleted file mode 100644 index a39d38700..000000000 --- a/src/win-status.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include "ibm.h" -#include "mem.h" -#include "cpu/x86_ops.h" -#include "cpu/codegen.h" -#include "device.h" -#include "resource.h" -#include "win.h" - - -HWND status_hwnd; -int status_is_open = 0; - - -extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; - -extern uint64_t main_time; -static uint64_t status_time; - - -static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - char device_s[4096]; - switch (message) - { - case WM_INITDIALOG: - status_is_open = 1; - case WM_USER: - { - uint64_t new_time = timer_read(); - uint64_t status_diff = new_time - status_time; - status_time = new_time; - sprintf(device_s, - "CPU speed : %f MIPS\n" - "FPU speed : %f MFLOPS\n\n" - - "Video throughput (read) : %i bytes/sec\n" - "Video throughput (write) : %i bytes/sec\n\n" - "Effective clockspeed : %iHz\n\n" - "Timer 0 frequency : %fHz\n\n" - "CPU time : %f%% (%f%%)\n" - - "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" - "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS" - ,mips, - flops, - segareads, - segawrites, - clockrate - scycles_lost, - pit_timer0_freq(), - ((double)main_time * 100.0) / status_diff, - ((double)main_time * 100.0) / timer_freq - - , cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched/cpu_recomp_blocks_latched, - cpu_recomp_flushes_latched, cpu_recomp_evicted_latched, - cpu_recomp_reuse_latched, cpu_recomp_removed_latched, - - ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq) - ); - main_time = 0; - SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); - - device_s[0] = 0; - device_add_status_info(device_s, 4096); - SendDlgItemMessage(hdlg, IDC_STEXT1, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - case IDCANCEL: - status_is_open = 0; - EndDialog(hdlg, 0); - return TRUE; - } - break; - } - - return FALSE; -} - -void status_open(HWND hwnd) -{ - status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); - ShowWindow(status_hwnd, SW_SHOW); -} diff --git a/src/win-video.c b/src/win-video.c deleted file mode 100644 index 15aec3785..000000000 --- a/src/win-video.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include "video/video.h" -#include "win-cgapal.h" - - -BITMAP *screen; - - -void hline(BITMAP *b, int x1, int y, int x2, uint32_t col) -{ - if (y < 0 || y >= buffer->h) - return; - - if (b == buffer) - memset(&b->line[y][x1], col, x2 - x1); - else - memset(&((uint32_t *)b->line[y])[x1], col, (x2 - x1) * 4); -} - -void blit(BITMAP *src, BITMAP *dst, int x1, int y1, int x2, int y2, int xs, int ys) -{ -} - -void stretch_blit(BITMAP *src, BITMAP *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) -{ -} - -void rectfill(BITMAP *b, int x1, int y1, int x2, int y2, uint32_t col) -{ -} - -void set_palette(PALETTE p) -{ -} - -void destroy_bitmap(BITMAP *b) -{ -} - -BITMAP *create_bitmap(int x, int y) -{ - BITMAP *b = malloc(sizeof(BITMAP) + (y * sizeof(uint8_t *))); - int c; - b->dat = malloc(x * y * 4); - for (c = 0; c < y; c++) - { - b->line[c] = b->dat + (c * x * 4); - } - b->w = x; - b->h = y; - return b; -} diff --git a/src/win.c b/src/win.c deleted file mode 100644 index f5e5a96eb..000000000 --- a/src/win.c +++ /dev/null @@ -1,2427 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#define UNICODE -#define _WIN32_WINNT 0x0501 -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include -#include -#include -#include -#include -#include -#include -#include "86box.h" -#include "device.h" -#include "disc.h" -#include "fdd.h" -#include "hdd.h" -#include "ibm.h" -#include "cpu/cpu.h" -#include "mem.h" -#include "rom.h" -#include "nvr.h" -#include "thread.h" -#include "config.h" -#include "model.h" -#include "ide.h" -#include "cdrom.h" -#include "cdrom-null.h" -#include "cdrom-ioctl.h" -#include "cdrom-image.h" -#include "video/video.h" -#include "video/vid_ega.h" -#include "plat-keyboard.h" -#include "plat-mouse.h" -#include "plat-midi.h" -#include "mouse.h" -#include "sound/sound.h" -#include "sound/snd_dbopl.h" - -#include "win.h" -#include "win-ddraw.h" -#include "win-ddraw-fs.h" -#include "win-d3d.h" -#include "win-d3d-fs.h" -#include "win-language.h" -#include "resource.h" - - -#ifndef MAPVK_VK_TO_VSC -#define MAPVK_VK_TO_VSC 0 -#endif - -static int save_window_pos = 0; -uint64_t timer_freq; - -int rawinputkey[272]; - -static RAWINPUTDEVICE device; -static uint16_t scancode_map[65536]; - -static struct -{ - int (*init)(HWND h); - void (*close)(); - void (*resize)(int x, int y); -} vid_apis[2][2] = -{ - { - ddraw_init, ddraw_close, NULL, - d3d_init, d3d_close, d3d_resize - }, - { - ddraw_fs_init, ddraw_fs_close, NULL, - d3d_fs_init, d3d_fs_close, NULL - }, -}; - -#define TIMER_1SEC 1 - -int winsizex=640,winsizey=480; -int efwinsizey=480; -int gfx_present[GFX_MAX]; - -HANDLE ghMutex; - -HANDLE mainthreadh; - -int infocus=1; - -int drawits=0; - -int romspresent[ROM_MAX]; -int quited=0; - -RECT oldclip; -int mousecapture=0; - -/* Declare Windows procedure */ -LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); - -LONG OriginalStatusBarProcedure; - -HWND ghwnd; - -HINSTANCE hinstance; - -HMENU menu; - -extern int updatestatus; - -int pause=0; - -static int win_doresize = 0; - -static int leave_fullscreen_flag = 0; - -static int unscaled_size_x = 0; -static int unscaled_size_y = 0; - -int scale = 0; - -HWND hwndRender, hwndStatus; - -void updatewindowsize(int x, int y) -{ - int owsx = winsizex; - int owsy = winsizey; - - int temp_overscan_x = overscan_x; - int temp_overscan_y = overscan_y; - - if (vid_resize) return; - - if (x < 160) x = 160; - if (y < 100) y = 100; - - if (x > 2048) x = 2048; - if (y > 2048) y = 2048; - - if (suppress_overscan) - { - temp_overscan_x = temp_overscan_y = 0; - } - - unscaled_size_x=x; efwinsizey=y; - - if (force_43) - { - /* Account for possible overscan. */ - if (temp_overscan_y == 16) - { - /* CGA */ - unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; - } - else if (temp_overscan_y < 16) - { - /* MDA/Hercules */ - unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); - } - else - { - if (enable_overscan) - { - /* EGA/(S)VGA with overscan */ - unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; - } - else - { - /* EGA/(S)VGA without overscan */ - unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); - } - } - } - else - { - unscaled_size_y = efwinsizey; - } - - switch(scale) - { - case 0: - winsizex = unscaled_size_x >> 1; - winsizey = unscaled_size_y >> 1; - break; - case 1: - winsizex = unscaled_size_x; - winsizey = unscaled_size_y; - break; - case 2: - winsizex = (unscaled_size_x * 3) >> 1; - winsizey = (unscaled_size_y * 3) >> 1; - break; - case 3: - winsizex = unscaled_size_x << 1; - winsizey = unscaled_size_y << 1; - break; - } - - if ((owsx != winsizex) || (owsy != winsizey)) - { - win_doresize = 1; - } - else - { - win_doresize = 0; - } -} - -void uws_natural() -{ - updatewindowsize(unscaled_size_x, efwinsizey); -} - -void releasemouse() -{ - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture = 0; - } -} - -void startblit() -{ - WaitForSingleObject(ghMutex, INFINITE); -} - -void endblit() -{ - ReleaseMutex(ghMutex); -} - -void leave_fullscreen() -{ - leave_fullscreen_flag = 1; -} - -uint64_t main_time; - -uint64_t start_time; -uint64_t end_time; - -void mainthread(LPVOID param) -{ - int frames = 0; - DWORD old_time, new_time; - - RECT r; - int sb_borders[3]; - - drawits=0; - old_time = GetTickCount(); - while (!quited) - { - if (updatestatus) - { - updatestatus = 0; - if (status_is_open) - SendMessage(status_hwnd, WM_USER, 0, 0); - } - new_time = GetTickCount(); - drawits += new_time - old_time; - old_time = new_time; - if (drawits > 0 && !pause) - { - start_time = timer_read(); - drawits-=10; if (drawits>50) drawits=0; - runpc(); - frames++; - if (frames >= 200 && nvr_dosave) - { - frames = 0; - nvr_dosave = 0; - savenvr(); - } - end_time = timer_read(); - main_time += end_time - start_time; - } - else - Sleep(1); - - if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) - { - video_wait_for_blit(); - SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); - GetWindowRect(ghwnd, &r); - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - GetWindowRect(hwndRender, &r); - MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), - winsizex, - 17, - TRUE); - GetWindowRect(ghwnd, &r); - - MoveWindow(ghwnd, r.left, r.top, - winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, - TRUE); - - win_doresize = 0; - } - - if (leave_fullscreen_flag) - { - leave_fullscreen_flag = 0; - SendMessage(ghwnd, WM_LEAVEFULLSCREEN, 0, 0); - } - if (video_fullscreen && infocus) - { - SetCursorPos(9999, 9999); - } - } -} - -void *thread_create(void (*thread_rout)(void *param), void *param) -{ - return (void *)_beginthread(thread_rout, 0, param); -} - -void thread_kill(void *handle) -{ - TerminateThread(handle, 0); -} - -void thread_sleep(int t) -{ - Sleep(t); -} - -typedef struct win_event_t -{ - HANDLE handle; -} win_event_t; - -event_t *thread_create_event() -{ - win_event_t *event = malloc(sizeof(win_event_t)); - - event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); - - return (event_t *)event; -} - -void thread_set_event(event_t *_event) -{ - win_event_t *event = (win_event_t *)_event; - - SetEvent(event->handle); -} - -void thread_reset_event(event_t *_event) -{ - win_event_t *event = (win_event_t *)_event; - - ResetEvent(event->handle); -} - -int thread_wait_event(event_t *_event, int timeout) -{ - win_event_t *event = (win_event_t *)_event; - - if (timeout == -1) - timeout = INFINITE; - - if (WaitForSingleObject(event->handle, timeout)) - return 1; - return 0; -} - -void thread_destroy_event(event_t *_event) -{ - win_event_t *event = (win_event_t *)_event; - - CloseHandle(event->handle); - - free(event); -} - -HMENU smenu; - -static void initmenu(void) -{ - int i, c; - HMENU m; - WCHAR s[64]; - - for (i = 0; i < CDROM_NUM; i++) - { - m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ - - /* Loop through each Windows drive letter and test to see if - it's a CDROM */ - for (c='A';c<='Z';c++) - { - _swprintf(s,L"%c:\\",c); - if (GetDriveType(s)==DRIVE_CDROM) - { - _swprintf(s, win_language_get_string_from_id(2076), c); - AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); - } - } - } -} - -void get_executable_name(WCHAR *s, int size) -{ - GetModuleFileName(hinstance, s, size); -} - -void set_window_title(WCHAR *s) -{ - if (video_fullscreen) - return; - SetWindowText(ghwnd, s); -} - -uint64_t timer_read() -{ - LARGE_INTEGER qpc_time; - QueryPerformanceCounter(&qpc_time); - return qpc_time.QuadPart; -} - -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -UINT16 convert_scan_code(UINT16 scan_code) -{ - switch (scan_code) - { - case 0xE001: - return 0xF001; - case 0xE002: - return 0xF002; - case 0xE0AA: - return 0xF003; - case 0xE005: - return 0xF005; - case 0xE006: - return 0xF006; - case 0xE007: - return 0xF007; - case 0xE071: - return 0xF008; - case 0xE072: - return 0xF009; - case 0xE07F: - return 0xF00A; - case 0xE0E1: - return 0xF00B; - case 0xE0EE: - return 0xF00C; - case 0xE0F1: - return 0xF00D; - case 0xE0FE: - return 0xF00E; - case 0xE0EF: - return 0xF00F; - - default: - return scan_code; - } -} - -void get_registry_key_map() -{ - WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - WCHAR *valueName = L"Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - - /* First, prepare the default scan code map list which is 1:1. - Remappings will be inserted directly into it. - 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, - since each array element is a scan code and provides for E0, etc. ones too. */ - for (j = 0; j < 65536; j++) - scancode_map[j] = convert_scan_code(j); - - bufSize = 32768; - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) - { - if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) - { - UINT32 *bufEx2 = (UINT32 *) buf; - int scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) - { - UINT16 *bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount*2; j += 2) - { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - int scancode_unmapped = bufEx[j + 1]; - int scancode_mapped = bufEx[j]; - - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Fixes scan code map logging. */ - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - -static wchar_t **argv; -static int argc; -static wchar_t *argbuf; - -static void process_command_line() -{ - WCHAR *cmdline; - int argc_max; - int i, q; - - cmdline = GetCommandLine(); - i = wcslen(cmdline) + 1; - argbuf = malloc(i * 2); - memcpy(argbuf, cmdline, i * 2); - - argc = 0; - argc_max = 64; - argv = malloc(sizeof(wchar_t *) * argc_max); - if (!argv) - { - free(argbuf); - return; - } - - i = 0; - - /* parse commandline into argc/argv format */ - while (argbuf[i]) - { - while (argbuf[i] == L' ') - i++; - - if (argbuf[i]) - { - if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) - { - q = argbuf[i++]; - if (!argbuf[i]) - break; - } - else - q = 0; - - argv[argc++] = &argbuf[i]; - - if (argc >= argc_max) - { - argc_max += 64; - argv = realloc(argv, sizeof(wchar_t *) * argc_max); - if (!argv) - { - free(argbuf); - return; - } - } - - while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != L' '))) - i++; - - if (argbuf[i]) - { - argbuf[i] = 0; - i++; - } - } - } - - argv[argc] = NULL; -} - -int valid_models[2] = { 0, 1 }; -int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; -int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; -int valid_dma_channels[3] = { 5, 6, 7 }; -int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; -int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - -int find_in_array(int *array, int val, int len, int menu_base) -{ - int i = 0; - int temp = 0; - for (i = 0; i < len; i++) - { - CheckMenuItem(menu, menu_base + array[i], MF_UNCHECKED); - if (array[i] == val) - { - temp = 1; - } - } - return temp; -} - -HANDLE hinstAcc; - -HICON LoadIconEx(PCTSTR pszIconName) -{ - return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); -} - -HICON LoadIconBig(PCTSTR pszIconName) -{ - return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 64, 64, 0); -} - -int fdd_type_to_icon(int type) -{ - switch(type) - { - default: - case 0: - return 512; - case 1: - return 128; - case 2: - return 130; - case 3: - return 132; - case 4: - case 5: - case 6: - return 134; - case 7: - return 144; - case 8: - return 146; - case 9: - case 10: - case 11: - case 12: - return 150; - case 13: - return 152; - } -} - -int sb_parts = 10; - -int sb_part_meanings[12]; -int sb_part_icons[12]; - -int sb_icon_width = 24; - -int count_hard_disks(int bus) -{ - int i = 0; - - int c = 0; - - for (i = 0; i < HDC_NUM; i++) - { - if (hdc[i].bus == bus) - { - c++; - } - } - - return c; -} - -HICON hIcon[512]; - -int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; - -#define SBI_FLAG_ACTIVE 1 -#define SBI_FLAG_EMPTY 256 - -int sb_icon_flags[512]; - -/* This is for the disk activity indicator. */ -void update_status_bar_icon(int tag, int active) -{ - int i = 0; - int found = -1; - int temp_flags = 0; - - if ((tag & 0xf0) >= 0x30) - { - return; - } - - temp_flags |= active; - - for (i = 0; i < 12; i++) - { - if (sb_part_meanings[i] == tag) - { - found = i; - break; - } - } - - if (found != -1) - { - if (temp_flags != (sb_icon_flags[found] & 1)) - { - sb_icon_flags[found] &= ~1; - sb_icon_flags[found] |= active; - - sb_part_icons[found] &= ~257; - sb_part_icons[found] |= sb_icon_flags[found]; - - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); - } - } -} - -/* This is for the drive state indicator. */ -void update_status_bar_icon_state(int tag, int state) -{ - int i = 0; - int found = -1; - - if ((tag & 0xf0) >= 0x20) - { - return; - } - - for (i = 0; i < 12; i++) - { - if (sb_part_meanings[i] == tag) - { - found = i; - break; - } - } - - if (found != -1) - { - sb_icon_flags[found] &= ~256; - sb_icon_flags[found] |= state ? 256 : 0; - - sb_part_icons[found] &= ~257; - sb_part_icons[found] |= sb_icon_flags[found]; - - SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); - } -} - -WCHAR sbTips[24][512]; - -void create_floppy_tip(int part) -{ - WCHAR *szText; - WCHAR wtext[512]; - - int drive = sb_part_meanings[part] & 0xf; - - mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); - if (wcslen(discfns[drive]) == 0) - { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); - } - else - { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); - } -} - -void create_cdrom_tip(int part) -{ - WCHAR *szText; - char ansi_text[3][512]; - WCHAR wtext[512]; - - int drive = sb_part_meanings[part] & 0xf; - - if (cdrom_drives[drive].host_drive == 200) - { - if (wcslen(cdrom_image[drive].image_path) == 0) - { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); - } - else - { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); - } - } - else if (cdrom_drives[drive].host_drive < 0x41) - { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); - } - else - { - _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); - } -} - -void create_hd_tip(int part) -{ - WCHAR *szText; - - int bus = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); - memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); -} - -void update_tip(int meaning) -{ - int i = 0; - int part = -1; - - for (i = 0; i < sb_parts; i++) - { - if (sb_part_meanings[i] == meaning) - { - part = i; - } - } - - if (part != -1) - { - switch(meaning & 0x30) - { - case 0x00: - create_floppy_tip(part); - break; - case 0x10: - create_cdrom_tip(part); - break; - case 0x20: - create_hd_tip(part); - break; - default: - break; - } - - SendMessage(hwndStatus, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); - } -} - -static int get_floppy_state(int id) -{ - return (wcslen(discfns[id]) == 0) ? 1 : 0; -} - -static int get_cd_state(int id) -{ - if (cdrom_drives[id].host_drive < 0x41) - { - return 1; - } - else - { - if (cdrom_drives[id].host_drive == 0x200) - { - return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; - } - else - { - return 0; - } - } -} - -void status_settextw(wchar_t *wstr) -{ - int i = 0; - int part = -1; - - for (i = 0; i < sb_parts; i++) - { - if (sb_part_meanings[i] == 0x30) - { - part = i; - } - } - - if (part != -1) - { - SendMessage(hwndStatus, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) wstr); - } -} - -static wchar_t cwstr[512]; - -void status_settext(char *str) -{ - memset(cwstr, 0, 1024); - mbstowcs(cwstr, str, strlen(str) + 1); - status_settextw(cwstr); -} - -void update_status_bar_panes(HWND hwnds) -{ - int i, j, id; - int edge = 0; - - int c_rll = 0; - int c_mfm = 0; - int c_ide_pio = 0; - int c_ide_dma = 0; - int c_scsi = 0; - - c_mfm = count_hard_disks(1); - c_ide_pio = count_hard_disks(2); - c_ide_dma = count_hard_disks(3); - c_scsi = count_hard_disks(4); - - for (i = 0; i < sb_parts; i++) - { - SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); - } - - sb_parts = 0; - memset(iStatusWidths, 0, 48); - memset(sb_part_meanings, 0, 48); - for (i = 0; i < 4; i++) - { - if (fdd_get_type(i) != 0) - { - /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x00 | i; - sb_parts++; - } - } - for (i = 0; i < 4; i++) - { - if (cdrom_drives[i].bus_type != 0) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x10 | i; - sb_parts++; - } - } - if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x20; - sb_parts++; - } - if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x21; - sb_parts++; - } - if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x22; - sb_parts++; - } - if (c_scsi) - { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x23; - sb_parts++; - } - if (sb_parts) - { - iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); - } - iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = 0x30; - sb_parts++; - - SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); - - for (i = 0; i < sb_parts; i++) - { - switch (sb_part_meanings[i] & 0x30) - { - case 0x00: - /* Floppy */ - sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; - sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; - create_floppy_tip(i); - break; - case 0x10: - /* CD-ROM */ - id = sb_part_meanings[i] & 0xf; - if (cdrom_drives[id].host_drive < 0x41) - { - sb_icon_flags[i] = 256; - } - else - { - if (cdrom_drives[id].host_drive == 0x200) - { - sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; - } - else - { - sb_icon_flags[i] = 0; - } - } - if (cdrom_drives[id].bus_type == 4) - { - j = 164; - } - else if (cdrom_drives[id].bus_type == 3) - { - j = 162; - } - else - { - j = 160; - } - sb_part_icons[i] = j | sb_icon_flags[i]; - create_cdrom_tip(i); - break; - case 0x20: - /* Hard disk */ - sb_part_icons[i] = 176 + ((sb_part_meanings[i] & 0xf) << 1); - create_hd_tip(i); - break; - case 0x30: - /* Status text */ - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); - sb_part_icons[i] = -1; - break; - } - if (sb_part_icons[i] != -1) - { - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); - SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); - SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); - /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ - } - else - { - SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); - } - } -} - -HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) -{ - HWND hwndStatus; - int i; - RECT rectDialog; - int dw, dh; - - for (i = 128; i < 136; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 144; i < 148; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 150; i < 154; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 160; i < 166; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 176; i < 184; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 384; i < 392; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 400; i < 404; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 406; i < 410; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - for (i = 416; i < 422; i++) - { - hIcon[i] = LoadIconEx((PCTSTR) i); - } - - GetWindowRect(hwndParent, &rectDialog); - dw = rectDialog.right - rectDialog.left; - dh = rectDialog.bottom - rectDialog.top; - - InitCommonControls(); - - hwndStatus = CreateWindowEx( - 0, - STATUSCLASSNAME, - (PCTSTR) NULL, - SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, - 0, dh - 17, dw, 17, - hwndParent, - (HMENU) idStatus, - hinst, - NULL); - - GetWindowRect(hwndStatus, &rectDialog); - - SetWindowPos( - hwndStatus, - HWND_TOPMOST, - rectDialog.left, - rectDialog.top, - rectDialog.right - rectDialog.left, - rectDialog.bottom - rectDialog.top, - SWP_SHOWWINDOW); - - SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); - - update_status_bar_panes(hwndStatus); - - return hwndStatus; -} - -void win_menu_update() -{ -#if 0 - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); - - SetMenu(ghwnd, menu); - - win_title_update = 1; -#endif -} - -int recv_key[272]; - -int WINAPI WinMain (HINSTANCE hThisInstance, - HINSTANCE hPrevInstance, - LPSTR lpszArgument, - int nFunsterStil) - -{ - HWND hwnd; /* This is the handle for our window */ - MSG messages; /* Here messages to the application are saved */ - WNDCLASSEX wincl; /* Data structure for the windowclass */ - int c, d, e, bRet; - WCHAR emulator_title[200]; - LARGE_INTEGER qpc_freq; - HACCEL haccel; /* Handle to accelerator table */ - - memset(recv_key, 0, sizeof(recv_key)); - - process_command_line(); - - win_language_load_common_strings(); - - hinstance=hThisInstance; - /* The Window structure */ - wincl.hInstance = hThisInstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof (WNDCLASSEX); - - /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hCursor = NULL; - wincl.lpszMenuName = NULL; /* No menu */ - wincl.cbClsExtra = 0; /* No extra bytes after the window class */ - wincl.cbWndExtra = 0; /* structure or the window instance */ - /* Use Windows's default color as the background of the window */ - wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; - - /* Register the window class, and if it fails quit the program */ - if (!RegisterClassEx(&wincl)) - return 0; - - wincl.lpszClassName = szSubClassName; - wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ - - if (!RegisterClassEx(&wincl)) - return 0; - - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); - - /* The class is registered, let's create the program*/ - hwnd = CreateWindowEx ( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - emulator_title, /* Title Text */ - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where the window ends up on the screen */ - 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ - 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ - HWND_DESKTOP, /* The window is a child-window to desktop */ - menu, /* Menu */ - hThisInstance, /* Program Instance handler */ - NULL /* No Window Creation data */ - ); - - /* Make the window visible on the screen */ - ShowWindow (hwnd, nFunsterStil); - - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstAcc, L"MainAccel"); - if (haccel == NULL) - fatal("haccel is null\n"); - - memset(rawinputkey, 0, sizeof(rawinputkey)); - device.usUsagePage = 0x01; - device.usUsage = 0x06; - device.dwFlags = RIDEV_NOHOTKEYS; - device.hwndTarget = hwnd; - - if (RegisterRawInputDevices(&device, 1, sizeof(device))) - pclog("Raw input registered!\n"); - else - pclog("Raw input registration failed!\n"); - - get_registry_key_map(); - - ghwnd=hwnd; - - initpc(argc, argv); - - hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); - - hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); - - OriginalStatusBarProcedure = GetWindowLong(hwndStatus, GWL_WNDPROC); - SetWindowLong(hwndStatus, GWL_WNDPROC, (LONG) &StatusBarProcedure); - - smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); - - if (vid_apis[0][vid_api].init(hwndRender) == 0) - { - if (vid_apis[0][vid_api ^ 1].init(hwndRender) == 0) - { - fatal("Both DirectDraw and Direct3D renderers failed to initialize\n"); - } - else - { - vid_api ^= 1; - } - } - - if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); - else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); - - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); - - /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ - for (e = 0; e < CDROM_NUM; e++) - { - if (!cdrom_drives[e].sound_on) - { - CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); - } - - if (cdrom_drives[e].host_drive == 200) - { - CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); - } - else if (cdrom_drives[e].host_drive >= 65) - { - CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); - } - else - { - CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); - } - } - -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_CDROM_LOG - CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_D86F_LOG - CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_FDC_LOG - CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_IDE_LOG - CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_NE2000_LOG - CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#endif - - CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); - - if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); - CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - - d=romset; - for (c=0;c= 0; c--) - { - if (gfx_present[c]) - { - gfxcard = c; - saveconfig(); - resetpchard(); - break; - } - } - } - - loadbios(); - resetpchard(); - - timeBeginPeriod(1); - - atexit(releasemouse); - - ghMutex = CreateMutex(NULL, FALSE, NULL); - mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); - SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); - - - updatewindowsize(640, 480); - - QueryPerformanceFrequency(&qpc_freq); - timer_freq = qpc_freq.QuadPart; - - if (start_in_fullscreen) - { - startblit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(hwndRender); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - } - if (window_remember) - { - MoveWindow(hwnd, window_x, window_y, - window_w, - window_h, - TRUE); - } - else - { - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - MoveWindow(hwndStatus, 0, winsizey + 6, - winsizex, - 17, - TRUE); - } - - /* Run the message loop. It will run until GetMessage() returns 0 */ - while (!quited) - { - while (((bRet = GetMessage(&messages,NULL,0,0)) != 0) && !quited) - { - if (bRet == -1) - { - fatal("bRet is -1\n"); - } - - if (messages.message==WM_QUIT) quited=1; - if (!TranslateAccelerator(hwnd, haccel, &messages)) - { - TranslateMessage(&messages); - DispatchMessage(&messages); - } - - if (recv_key[0x58] && recv_key[0x42] && mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - - if ((recv_key[0x1D] || recv_key[0x9D]) && - (recv_key[0x38] || recv_key[0xB8]) && - (recv_key[0x51] || recv_key[0xD1]) && - video_fullscreen) - { - leave_fullscreen(); - } - } - - quited=1; - } - - startblit(); - Sleep(200); - TerminateThread(mainthreadh,0); - savenvr(); - saveconfig(); - closepc(); - - vid_apis[video_fullscreen][vid_api].close(); - - timeEndPeriod(1); - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - } - - UnregisterClass(szSubClassName, hinstance); - UnregisterClass(szClassName, hinstance); - - return messages.wParam; -} - -HHOOK hKeyboardHook; -int hook_enabled = 0; - -LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) -{ - BOOL bControlKeyDown; - KBDLLHOOKSTRUCT* p; - - if (nCode < 0 || nCode != HC_ACTION) - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); - - p = (KBDLLHOOKSTRUCT*)lParam; - - if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ - if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ - if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1; /* disable windows keys */ - if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-escape */ - bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); /* checks ctrl key pressed */ - if (p->vkCode == VK_ESCAPE && bControlKeyDown) return 1; /* disable ctrl-escape */ - - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); -} - -void cdrom_close(uint8_t id) -{ - switch (cdrom_drives[id].host_drive) - { - case 0: - null_close(id); - break; - default: - ioctl_close(id); - break; - case 200: - image_close(id); - break; - } -} - -int ide_ter_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[2] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[2] = irq; - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int ide_qua_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[3] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[3] = irq; - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -void video_toggle_option(HMENU hmenu, int *val, int id) -{ - *val ^= 1; - CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); -} - -void win_cdrom_eject(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - if (cdrom_drives[id].host_drive == 0) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - cdrom_drives[id].handler->exit(id); - cdrom_close(id); - cdrom_null_open(id, 0); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); - if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_drives[id].host_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - -void win_cdrom_reload(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - int new_cdrom_drive; - if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - cdrom_close(id); - if (cdrom_drives[id].prev_host_drive == 200) - { - image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); - } - else - { - new_cdrom_drive = cdrom_drives[id].prev_host_drive; - ioctl_open(id, new_cdrom_drive); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); - } - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - -static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - HWND h; - - switch (message) - { - case WM_INITDIALOG: - pause = 1; - h = GetDlgItem(hdlg, IDC_ABOUT_ICON); - SendMessage(h, STM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) LoadIconBig((PCTSTR) 100)); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDOK: - EndDialog(hdlg, 0); - pause = 0; - return TRUE; - default: - break; - } - break; - } - - return FALSE; -} - -void about_open(HWND hwnd) -{ - DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); -} - -LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - HMENU hmenu; - RECT rect; - uint32_t ri_size = 0; - int edgex, edgey; - int sb_borders[3]; - - switch (message) - { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - break; - - case WM_COMMAND: - hmenu=GetMenu(hwnd); - switch (LOWORD(wParam)) - { - case IDM_FILE_HRESET: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpchard(); - pause=0; - break; - case IDM_FILE_RESET_CAD: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpc_cad(); - pause=0; - break; - case IDM_FILE_EXIT: - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - case IDM_CONFIG: - win_settings_open(hwnd); - break; - case IDM_ABOUT: - about_open(hwnd); - break; - case IDM_STATUS: - status_open(hwnd); - break; - - case IDM_VID_RESIZE: - vid_resize=!vid_resize; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); - if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); - else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); - GetWindowRect(hwnd,&rect); - SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - GetWindowRect(hwndStatus,&rect); - SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - if (vid_resize) - { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - win_doresize = 1; - saveconfig(); - break; - case IDM_VID_REMEMBER: - window_remember = !window_remember; - CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); - if (window_remember) - { - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - } - saveconfig(); - break; - - case IDM_VID_DDRAW: case IDM_VID_D3D: - startblit(); - video_wait_for_blit(); - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); - vid_apis[0][vid_api].close(); - vid_api = LOWORD(wParam) - IDM_VID_DDRAW; - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - vid_apis[0][vid_api].init(hwndRender); - endblit(); - saveconfig(); - device_force_redraw(); - break; - - case IDM_VID_FULLSCREEN: - - if(video_fullscreen!=1){ - - if (video_fullscreen_first) - { - video_fullscreen_first = 0; - msgbox_info(ghwnd, 2193); - } - startblit(); - video_wait_for_blit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(ghwnd); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - } - break; - - case IDM_VID_FS_FULL: - case IDM_VID_FS_43: - case IDM_VID_FS_SQ: - case IDM_VID_FS_INT: - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); - video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - saveconfig(); - break; - - case IDM_VID_SCALE_1X: - case IDM_VID_SCALE_2X: - case IDM_VID_SCALE_3X: - case IDM_VID_SCALE_4X: - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - scale = LOWORD(wParam) - IDM_VID_SCALE_1X; - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - saveconfig(); - break; - - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - break; - - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - break; - - case IDM_VID_OVERSCAN: - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - update_overscan = 1; - break; - - case IDM_VID_FLASH: - video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); - break; - - case IDM_VID_SCREENSHOT: - take_screenshot(); - break; - -#ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - case IDM_LOG_BUSLOGIC: - buslogic_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_CDROM_LOG - case IDM_LOG_CDROM: - cdrom_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_D86F_LOG - case IDM_LOG_D86F: - d86f_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_FDC_LOG - case IDM_LOG_FDC: - fdc_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_IDE_LOG - case IDM_LOG_IDE: - ide_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif - -#ifdef ENABLE_NE2000_LOG - case IDM_LOG_NE2000: - ne2000_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); - break; -#endif -#endif - -#ifdef ENABLE_LOG_BREAKPOINT - case IDM_LOG_BREAKPOINT: - pclog("---- LOG BREAKPOINT ----\n"); - break; -#endif - -#ifdef ENABLE_VRAM_DUMP - case IDM_DUMP_VRAM: - svga_dump_vram(); - break; -#endif - - case IDM_CONFIG_LOAD: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 0)) - { - if (msgbox_reset_yn(ghwnd) == IDYES) - { - config_save(config_file_default); - loadconfig(wopenfilestring); - pclog_w(L"NVR path: %s\n", nvr_path); - mem_resize(); - loadbios(); - resetpchard(); - } - } - pause = 0; - break; - - case IDM_CONFIG_SAVE: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 1)) - config_save(wopenfilestring); - pause = 0; - break; - } - return 0; - - case WM_INPUT: - { - UINT size; - RAWINPUT *raw; - - if (!infocus) - break; - - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - - raw = malloc(size); - - if (raw == NULL) - { - return 0; - } - - /* Here we read the raw input data for the keyboard */ - ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); - - if(ri_size != size) - { - return 0; - } - - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) - { - const RAWKEYBOARD rawKB = raw->data.keyboard; - USHORT scancode = rawKB.MakeCode; - - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) - { - if (rawKB.Flags & RI_KEY_E0) - scancode |= (0xE0 << 8); - - /* Remap it according to the list from the Registry */ - scancode = scancode_map[scancode]; - - if ((scancode >> 8) == 0xF0) - scancode |= 0x100; /* Extended key code in disambiguated format */ - else if ((scancode >> 8) == 0xE0) - scancode |= 0x80; /* Normal extended key code */ - - /* If it's not 0 (therefore not 0xE1, 0xE2, etc), - then pass it on to the rawinputkey array */ - if (!(scancode & 0xf00)) - { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; - } - } - else - { - if (rawKB.MakeCode == 0x1D) - scancode = 0xFF; - if (!(scancode & 0xf00)) - { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; - } - } - } - free(raw); - - } - break; - - case WM_SETFOCUS: - infocus=1; - if (!hook_enabled) - { - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - } - break; - - case WM_KILLFOCUS: - infocus=0; - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - memset(rawinputkey, 0, sizeof(rawinputkey)); - if (video_fullscreen) - leave_fullscreen_flag = 1; - if (hook_enabled) - { - UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } - break; - - case WM_LBUTTONUP: - if (!mousecapture && !video_fullscreen) - { - RECT pcclip; - - GetClipCursor(&oldclip); - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - mousecapture = 1; - while (1) - { - if (ShowCursor(FALSE) < 0) break; - } - } - break; - - case WM_MBUTTONUP: - if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - releasemouse(); - break; - - case WM_ENTERMENULOOP: - break; - - case WM_SIZE: - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) - { - startblit(); - video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } - - MoveWindow(hwndStatus, 0, winsizey + 6, - winsizex, - 17, - TRUE); - - if (mousecapture) - { - RECT pcclip; - - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - } - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_MOVE: - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_TIMER: - if (wParam == TIMER_1SEC) - onesec(); - break; - - case WM_RESETD3D: - startblit(); - if (video_fullscreen) - d3d_fs_reset(); - else - d3d_reset(); - endblit(); - break; - - case WM_LEAVEFULLSCREEN: - startblit(); - mouse_close(); - vid_apis[1][vid_api].close(); - video_fullscreen = 0; - vid_apis[0][vid_api].init(ghwnd); - mouse_init(); - endblit(); - device_force_redraw(); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - return 0; - - case WM_DESTROY: - UnhookWindowsHookEx( hKeyboardHook ); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - - case WM_SYSCOMMAND: - /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) - return 0; /*disable ALT key for menu*/ - - default: - return DefWindowProc (hwnd, message, wParam, lParam); - } - return 0; -} - -LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - switch (message) - { - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; -} - -VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) -{ - HMENU pmenu; - int menu_id = -1; - if (id >= (sb_parts - 1)) - { - return; - } - pt.x = id * sb_icon_width; /* Justify to the left. */ - pt.y = 0; /* Justify to the top. */ - ClientToScreen(hwnd, (LPPOINT) &pt); - if ((sb_part_meanings[id] & 0x30) == 0x00) - { - menu_id = sb_part_meanings[id] & 0xf; - } - else if ((sb_part_meanings[id] & 0x30) == 0x10) - { - menu_id = (sb_part_meanings[id] & 0xf) + 4; - } - if (menu_id != -1) - { - pmenu = GetSubMenu(smenu, menu_id); - TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); - } -} - -LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - RECT rc; - POINT pt; - - WCHAR temp_image_path[1024]; - int new_cdrom_drive; - int cdrom_id = 0; - int menu_sub_param = 0; - int menu_super_param = 0; - int ret = 0; - - HMENU hmenu; - - switch (message) - { - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDM_DISC_1: - case IDM_DISC_1_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); - if (!ret) - { - disc_close(0); - ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, wopenfilestring); - update_status_bar_icon_state(0x00, 0); - update_tip(0x00); - saveconfig(); - } - break; - case IDM_DISC_2: - case IDM_DISC_2_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); - if (!ret) - { - disc_close(1); - ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, wopenfilestring); - update_status_bar_icon_state(0x01, 0); - update_tip(0x01); - saveconfig(); - } - break; - case IDM_DISC_3: - case IDM_DISC_3_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); - if (!ret) - { - disc_close(2); - ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, wopenfilestring); - update_status_bar_icon_state(0x02, 0); - update_tip(0x02); - saveconfig(); - } - break; - case IDM_DISC_4: - case IDM_DISC_4_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); - if (!ret) - { - disc_close(3); - ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, wopenfilestring); - update_status_bar_icon_state(0x03, 0); - update_tip(0x03); - saveconfig(); - } - break; - case IDM_EJECT_1: - disc_close(0); - update_status_bar_icon_state(0x00, 1); - update_tip(0x00); - saveconfig(); - break; - case IDM_EJECT_2: - disc_close(1); - update_status_bar_icon_state(0x01, 1); - update_tip(0x01); - saveconfig(); - break; - case IDM_EJECT_3: - disc_close(2); - update_status_bar_icon_state(0x02, 1); - update_tip(0x02); - saveconfig(); - break; - case IDM_EJECT_4: - disc_close(3); - update_status_bar_icon_state(0x03, 1); - update_tip(0x03); - saveconfig(); - break; - - case IDM_CDROM_1_MUTE: - case IDM_CDROM_2_MUTE: - case IDM_CDROM_3_MUTE: - case IDM_CDROM_4_MUTE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - Sleep(100); - cdrom_drives[cdrom_id].sound_on ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); - saveconfig(); - sound_cd_thread_reset(); - break; - - case IDM_CDROM_1_EMPTY: - case IDM_CDROM_2_EMPTY: - case IDM_CDROM_3_EMPTY: - case IDM_CDROM_4_EMPTY: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_eject(cdrom_id); - break; - - case IDM_CDROM_1_RELOAD: - case IDM_CDROM_2_RELOAD: - case IDM_CDROM_3_RELOAD: - case IDM_CDROM_4_RELOAD: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_reload(cdrom_id); - break; - - case IDM_CDROM_1_IMAGE: - case IDM_CDROM_2_IMAGE: - case IDM_CDROM_3_IMAGE: - case IDM_CDROM_4_IMAGE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) - { - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - wcscpy(temp_image_path, wopenfilestring); - if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) - { - /* Switching from image to the same image. Do nothing. */ - break; - } - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - image_open(cdrom_id, temp_image_path); - if (cdrom_drives[cdrom_id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - - default: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; - /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ - if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) - { - new_cdrom_drive = menu_sub_param; - if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) - { - /* Switching to the same drive. Do nothing. */ - break; - } - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - ioctl_open(cdrom_id, new_cdrom_drive); - if (cdrom_drives[cdrom_id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); - cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - } - return 0; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - GetClientRect(hwnd, (LPRECT)& rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect((LPRECT) &rc, pt)) - { - HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); - } - break; - - default: - return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); - } - return 0; -} diff --git a/src/win.h b/src/win.h deleted file mode 100644 index 0e09db88f..000000000 --- a/src/win.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -extern HINSTANCE hinstance; -extern HWND ghwnd; -extern int mousecapture; - -#ifdef __cplusplus -extern "C" { -#endif - -#define szClassName L"86BoxMainWnd" -#define szSubClassName L"86BoxSubWnd" -#define szStatusBarClassName L"86BoxStatusBar" - -void leave_fullscreen(); - -#ifdef __cplusplus -} -#endif - - -void status_open(HWND hwnd); -extern HWND status_hwnd; -extern int status_is_open; - -void deviceconfig_open(HWND hwnd, struct device_t *device); -void joystickconfig_open(HWND hwnd, int joy_nr, int type); - -extern char openfilestring[260]; -extern WCHAR wopenfilestring[260]; - -int getfile(HWND hwnd, char *f, char *fn); -int getsfile(HWND hwnd, char *f, char *fn); - -void get_executable_name(WCHAR *s, int size); -void set_window_title(WCHAR *s); - -void startblit(); -void endblit(); - -extern int pause; - -void win_settings_open(HWND hwnd); -void win_menu_update(); - -void update_status_bar_panes(HWND hwnds); - -int fdd_type_to_icon(int type); - -extern HWND hwndStatus; From a4a69f71eb774ab07adc790202c45a02f71ea886 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 18 May 2017 14:03:43 -0400 Subject: [PATCH 229/392] The, uhh, missing stufff......... --- src/86box.cfg | Bin 0 -> 7452 bytes src/CPU/codegen_x86-64.c | 6 +- src/Makefile.mingw | 4 +- src/WIN/86Box.manifest | 22 + src/WIN/86Box.rc | 941 ++++++++ src/WIN/pcap_if.rc | 52 + src/WIN/plat_dinput.h | 4 + src/WIN/plat_dir.h | 76 + src/WIN/plat_joystick.h | 69 + src/WIN/plat_keyboard.h | 22 + src/WIN/plat_midi.h | 10 + src/WIN/plat_mouse.h | 16 + src/WIN/plat_serial.h | 49 + src/WIN/resource.h | 432 ++++ src/WIN/win.c | 2427 ++++++++++++++++++++ src/WIN/win.h | 51 + src/WIN/win_cgapal.h | 13 + src/WIN/win_crashdump.c | 185 ++ src/WIN/win_crashdump.h | 7 + src/WIN/win_d3d-fs.cc | 587 +++++ src/WIN/win_d3d-fs.h | 13 + src/WIN/win_d3d.cc | 398 ++++ src/WIN/win_d3d.h | 13 + src/WIN/win_ddraw-fs.cc | 338 +++ src/WIN/win_ddraw-fs.h | 11 + src/WIN/win_ddraw-screenshot.cc | 178 ++ src/WIN/win_ddraw-screenshot.h | 4 + src/WIN/win_ddraw.cc | 318 +++ src/WIN/win_ddraw.h | 12 + src/WIN/win_deviceconfig.c | 317 +++ src/WIN/win_joystick.cc | 281 +++ src/WIN/win_joystickconfig.c | 541 +++++ src/WIN/win_language.c | 197 ++ src/WIN/win_language.h | 33 + src/WIN/win_midi.c | 279 +++ src/WIN/win_mouse.cc | 75 + src/WIN/win_opendir.c | 213 ++ src/WIN/win_serial.c | 606 +++++ src/WIN/win_settings.c | 3694 +++++++++++++++++++++++++++++++ src/WIN/win_status.c | 95 + src/WIN/win_video.c | 57 + src/cdrom_dosbox.cpp | 565 +++++ src/cdrom_dosbox.h | 173 ++ src/cdrom_image.cc | 1045 +++++++++ src/cdrom_image.h | 28 + src/cdrom_ioctl.c | 1099 +++++++++ src/cdrom_ioctl.h | 17 + src/cdrom_ioctl_linux.c | 725 ++++++ src/cdrom_null.c | 130 ++ src/cdrom_null.h | 14 + 50 files changed, 16436 insertions(+), 6 deletions(-) create mode 100644 src/86box.cfg create mode 100644 src/WIN/86Box.manifest create mode 100644 src/WIN/86Box.rc create mode 100644 src/WIN/pcap_if.rc create mode 100644 src/WIN/plat_dinput.h create mode 100644 src/WIN/plat_dir.h create mode 100644 src/WIN/plat_joystick.h create mode 100644 src/WIN/plat_keyboard.h create mode 100644 src/WIN/plat_midi.h create mode 100644 src/WIN/plat_mouse.h create mode 100644 src/WIN/plat_serial.h create mode 100644 src/WIN/resource.h create mode 100644 src/WIN/win.c create mode 100644 src/WIN/win.h create mode 100644 src/WIN/win_cgapal.h create mode 100644 src/WIN/win_crashdump.c create mode 100644 src/WIN/win_crashdump.h create mode 100644 src/WIN/win_d3d-fs.cc create mode 100644 src/WIN/win_d3d-fs.h create mode 100644 src/WIN/win_d3d.cc create mode 100644 src/WIN/win_d3d.h create mode 100644 src/WIN/win_ddraw-fs.cc create mode 100644 src/WIN/win_ddraw-fs.h create mode 100644 src/WIN/win_ddraw-screenshot.cc create mode 100644 src/WIN/win_ddraw-screenshot.h create mode 100644 src/WIN/win_ddraw.cc create mode 100644 src/WIN/win_ddraw.h create mode 100644 src/WIN/win_deviceconfig.c create mode 100644 src/WIN/win_joystick.cc create mode 100644 src/WIN/win_joystickconfig.c create mode 100644 src/WIN/win_language.c create mode 100644 src/WIN/win_language.h create mode 100644 src/WIN/win_midi.c create mode 100644 src/WIN/win_mouse.cc create mode 100644 src/WIN/win_opendir.c create mode 100644 src/WIN/win_serial.c create mode 100644 src/WIN/win_settings.c create mode 100644 src/WIN/win_status.c create mode 100644 src/WIN/win_video.c create mode 100644 src/cdrom_dosbox.cpp create mode 100644 src/cdrom_dosbox.h create mode 100644 src/cdrom_image.cc create mode 100644 src/cdrom_image.h create mode 100644 src/cdrom_ioctl.c create mode 100644 src/cdrom_ioctl.h create mode 100644 src/cdrom_ioctl_linux.c create mode 100644 src/cdrom_null.c create mode 100644 src/cdrom_null.h diff --git a/src/86box.cfg b/src/86box.cfg new file mode 100644 index 0000000000000000000000000000000000000000..ad83f0d3556b0b9f3477aa51f21bf2a4a3740c75 GIT binary patch literal 7452 zcmb`M+iu%N6h-H`K>wj1P@tkLJ9dG-6e!w0v?6F2U=C}zSh;i zh2Q8JdqA_b|J?eRl`Y7P^4KZL2jzBf_od(8+_&zXd*gm^f9U(QuCLvd`(Al`)b-vo ze^=Um{6ya;jYrDPDnzum?iY1s&nfoLT6Q9NO zsUG;MV#XC;cphPH@%Y~Rt2|lHm}Y+}C-m8tdfiEbkBUOfnJZBBi!sz0$0I&L*tduZniiOl0o9FBy?JS<>4ReW&sb8CLj|X4P1; zKBnqxMZ8yBR!wR}bv~4Ls8Ur|RwDQ|`@5IAtk$eZ8+qO7mv#1}WSG14>{!~JR!3W> zOz+e9=t6Ga zm70}SbdIgAJoo58)^DCCRdx{aW5wKUr<*fYp;9svYAig}dUb4j9Yp z*7pIkmReW24)k1LHq>J+o>1`^_2Ajkk3C*;*n`hu55Ap!kz|i;6MI&O{_OFR!ybGN zd+_b-he`I>HnAURtUr6ay!ybG)`->!dY@66$YOFtdyyUP4pTiz}JNr?RJ+@8k zuQb-5JzjFygU?|PzMcJLl0CLf>|bfDKYP67um_*R9(+6dt0a4Do7i7#tUr6ay z!ybG)`&UW!*fz1h(O7@>c*$W8K8HQ{cJ|jv_SmM`7up;2XK!A*vp0Nq_J(g~f0JNu zwoU9m$6l}SJH{OLM9pCjzKuOR>w7)Rt%*H5p}w78=zS}v^9`TFzRO+@o+U`6Y5`kyyUP4 zpTiz}JNwjLuW;Blv1cdLpFLi3*n`hu55Ap!YOh!5?DIK$J6n09H*iibAM}Q6C%fr0 zvqgDwVy6M|Y0jl)8|n@{2EQ>nRy`hj)O$6jnse#TX-suSZExr&EbCVHsP$DY_S7{h z>qQ(jJli<=tgkEaSl4*W?k@4bHL1$j`FK;+39UJav3iE5kJN*c{p!Sode$x4W=p73 z-TGYD5B=Fp-KMSc2ho~ew_l2{o$T9OKmDzs&XE4e(*%o`Yl8JTP3+V==7deVCgGEy zZl9wGJ)Wlt7BANX>vNin5`BVAyC&iDA=boVcJCABTAn6Yyj&Bk&uMa*&;*-yO~R)} Ktck@ur^)}H>w5zL literal 0 HcmV?d00001 diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index 7673a08e4..e591adc95 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -1,16 +1,14 @@ #ifdef __amd64__ #include -#include "ibm.h" +#include "../ibm.h" +#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" -#include "mem.h" - #include "386_common.h" - #include "codegen.h" #include "codegen_ops.h" #include "codegen_ops_x86-64.h" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d2cbc03e3..39caf693b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -29,7 +29,7 @@ STUFF = EXTRAS = # Do we want a debugging build? -DEBUG = n +DEBUG = y OPTIM = n X64 = n @@ -200,7 +200,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ # Build rules. %.o: %.c @echo $< - @$(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< diff --git a/src/WIN/86Box.manifest b/src/WIN/86Box.manifest new file mode 100644 index 000000000..be8c16756 --- /dev/null +++ b/src/WIN/86Box.manifest @@ -0,0 +1,22 @@ + + + +Emulator for X86-based systems. + + + + + + diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc new file mode 100644 index 000000000..fb5d56296 --- /dev/null +++ b/src/WIN/86Box.rc @@ -0,0 +1,941 @@ +#include + +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +STATUSBARMENU MENU DISCARDABLE +BEGIN + POPUP "FDD 1" + BEGIN + MENUITEM "&Change...", IDM_DISC_1 + MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP + MENUITEM "&Eject FDD 1", IDM_EJECT_1 + END + POPUP "FDD 2" + BEGIN + MENUITEM "&Change...", IDM_DISC_2 + MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP + MENUITEM "&Eject FDD 2", IDM_EJECT_2 + END + POPUP "FDD 3" + BEGIN + MENUITEM "&Change...", IDM_DISC_3 + MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP + MENUITEM "&Eject FDD 3", IDM_EJECT_3 + END + POPUP "FDD 4" + BEGIN + MENUITEM "&Change...", IDM_DISC_4 + MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP + MENUITEM "&Eject FDD 4", IDM_EJECT_4 + END + POPUP "CD-ROM 1" + BEGIN + MENUITEM "&Mute", IDM_CDROM_1_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_1_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_1_IMAGE + END + POPUP "CD-ROM 2" + BEGIN + MENUITEM "&Mute", IDM_CDROM_2_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_2_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_2_IMAGE + END + POPUP "CD-ROM 3" + BEGIN + MENUITEM "&Mute", IDM_CDROM_3_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_3_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_3_IMAGE + END + POPUP "CD-ROM 4" + BEGIN + MENUITEM "&Mute", IDM_CDROM_4_MUTE + MENUITEM SEPARATOR + MENUITEM "E&mpty", IDM_CDROM_4_EMPTY + MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_CDROM_4_IMAGE + END +END + +MAINMENU MENU DISCARDABLE +BEGIN + POPUP "&Action" + BEGIN + MENUITEM "&Hard Reset", IDM_FILE_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD + MENUITEM SEPARATOR + MENUITEM "E&xit", IDM_FILE_EXIT + END + POPUP "&Tools" + BEGIN + MENUITEM "&Settings...", IDM_CONFIG + MENUITEM SEPARATOR + MENUITEM "&Load configuration...", IDM_CONFIG_LOAD + MENUITEM "&Save configuration...", IDM_CONFIG_SAVE + MENUITEM SEPARATOR + POPUP "&Video" + BEGIN + MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "R&emember size && position", IDM_VID_REMEMBER + MENUITEM SEPARATOR + MENUITEM "&DirectDraw", IDM_VID_DDRAW + MENUITEM "Direct&3D 9", IDM_VID_D3D + MENUITEM SEPARATOR + POPUP "&Window scale factor" + BEGIN + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + END + MENUITEM SEPARATOR + MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN + POPUP "Fullscreen &stretch mode" + BEGIN + MENUITEM "&Full screen stretch", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Square pixels", IDM_VID_FS_SQ + MENUITEM "&Integer scale", IDM_VID_FS_INT + END + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT + MENUITEM SEPARATOR + MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 + MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + MENUITEM SEPARATOR + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT + END + MENUITEM "S&tatus", IDM_STATUS +#ifdef ENABLE_LOG_TOGGLES +#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG + MENUITEM SEPARATOR +#endif +#ifdef ENABLE_BUSLOGIC_LOG + MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC +#endif +#ifdef ENABLE_CDROM_LOG + MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM +#endif +#ifdef ENABLE_D86F_LOG + MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F +#endif +#ifdef ENABLE_FDC_LOG + MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC +#endif +#ifdef ENABLE_IDE_LOG + MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE +#endif +#ifdef ENABLE_NE2000_LOG + MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + MENUITEM SEPARATOR + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +#ifdef ENABLE_VRAM_DUMP + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#else +#ifdef ENABLE_VRAM_DUMP + MENUITEM SEPARATOR + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +#endif +#endif + END + POPUP "&Help" + BEGIN + MENUITEM "&About 86Box...", IDM_ABOUT + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +MAINACCEL ACCELERATORS MOVEABLE PURE +BEGIN +#ifdef ENABLE_VRAM_DUMP + VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_CDROM_LOG + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_D86F_LOG + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_FDC_LOG + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_IDE_LOG + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_NE2000_LOG + VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY +#endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY +#endif + VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL + VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +CONFIGUREDLG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "86Box Settings" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,246,220,50,14 + PUSHBUTTON "Cancel",IDCANCEL,307,220,50,14 + CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,90,197 + CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 + LTEXT "Language:",2047,7,222,41,10 + COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP +END + +CONFIGUREDLG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Add Hard Disk" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,55,89,50,14 + PUSHBUTTON "Cancel",IDCANCEL,112,89,50,14 + EDITTEXT IDC_EDIT_HD_FILE_NAME,7,16,153,12 + PUSHBUTTON "&Specify...",IDC_CFILE,167,16,44,12 + EDITTEXT IDC_EDIT_HD_SPT,183,34,28,12 + EDITTEXT IDC_EDIT_HD_HPC,112,34,28,12 + EDITTEXT IDC_EDIT_HD_CYL,42,34,28,12 + EDITTEXT IDC_EDIT_HD_SIZE,42,52,28,12 + COMBOBOX IDC_COMBO_HD_TYPE,113,52,98,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Sectors:",IDC_STATIC,154,35,27,10 + LTEXT "Heads:",1793,81,35,29,8 + LTEXT "Cylinders:",1794,7,35,32,12 + LTEXT "Size (MB):",1795,7,54,33,8 + LTEXT "Type:",1797,86,54,24,8 + LTEXT "File name:",-1,7,7,204,9 + COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,72,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,99,72,34,8 + COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,117,72,15,8 + COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,168,72,15,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,99,72,34,8 +END + +STATUSDLG DIALOG DISCARDABLE 0, 0, 186, 386 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Status" +FONT 9, "Segoe UI" +BEGIN + LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 + LTEXT "1",IDC_STEXT1,16,186,180,1000 +END + +ABOUTDLG DIALOG DISCARDABLE 0, 0, 209, 114 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About 86Box" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,94,71,12 + ICON 100,IDC_ABOUT_ICON,7,7,20,20 + LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + IDC_ABOUT_ICON,54,7,146,73 + CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, + 86,208,1 +END + +CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Machine:",1794,7,8,60,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 + COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU type:",1796,7,26,59,10 + COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",1798,7,45,60,10 + COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU:",1797,124,26,18,10 + CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,147,80,113,10 + EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, + 12,12 + LTEXT "MB",IDC_TEXT_MB,123,64,10,10 + LTEXT "Memory:",1802,7,64,30,10 + CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 +END + +CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video:",1795,7,8,55,10 + COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video speed:",1800,7,26,58,10 + CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 + PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 +END + +CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Mouse :",IDC_STATIC,7,8,57,10 + COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Joystick :",1793,7,26,58,10 + COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 + PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 + PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 +END + +CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Sound card:",1800,7,8,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 + COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "MIDI Out Device:",1801,7,26,59,10 + CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 + CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 +END + +CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Network type:",1800,7,8,59,10 + COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "PCap device:",1801,7,26,59,10 + COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "Network adapter:",1802,7,44,59,10 + COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 +END + +CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "SCSI Controller:",1804,7,8,59,10 + COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 + + LTEXT "HD Controller:",1799,7,26,61,10 + COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Tertiary IDE:",1802,7,44,61,10 + COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Quaternary IDE:",1803,7,62,61,10 + COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + + CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 + CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 +END + +CONFIGUREDLG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,18,253,92 + LTEXT "Hard disks:",-1,7,7,34,8 + PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 + PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 + PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 + COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,118,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,131,118,38,8 + COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,118,38,8 + COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,118,38,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,131,118,38,8 +END + +CONFIGUREDLG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32", + LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, + 7,18,253,60 + LTEXT "Floppy drives:",-1,7,7,43,8 + CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 + LTEXT "CD-ROM drives:",-1,7,106,50,8 + COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Type:",1803,7,86,24,8 + COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,184,24,8 + COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,184,38,8 + COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,184,38,8 + COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,131,184,38,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// 24 +// + +1 24 MOVEABLE PURE "86Box.manifest" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box.ico" +#endif +128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" +129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" +130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" +131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" +132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" +133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" +134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" +135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" +144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" +145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" +146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" +147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" +150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" +151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" +152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" +153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" +160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" +161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" +162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" +163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" +164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" +165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" +176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" +177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" +178 ICON DISCARDABLE "ICONS/hard_disk.ico" +179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +256 ICON DISCARDABLE "ICONS/machine.ico" +257 ICON DISCARDABLE "ICONS/video.ico" +258 ICON DISCARDABLE "ICONS/input_devices.ico" +259 ICON DISCARDABLE "ICONS/sound.ico" +260 ICON DISCARDABLE "ICONS/network.ico" +261 ICON DISCARDABLE "ICONS/other_peripherals.ico" +262 ICON DISCARDABLE "ICONS/hard_disk.ico" +263 ICON DISCARDABLE "ICONS/removable_devices.ico" +384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" +385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" +386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" +387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" +388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" +389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" +390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" +391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" +400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" +401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" +402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" +403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" +406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" +407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" +408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" +409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" +416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" +417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" +418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" +419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" +420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" +421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" +512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" +514 ICON DISCARDABLE "ICONS/cdrom_disabled.ico" + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resources.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + CONFIGUREDLG_MAIN, DIALOG + BEGIN + RIGHTMARGIN, 365 + END + + ABOUTDLG, DIALOG + BEGIN + RIGHTMARGIN, 208 + END + + CONFIGUREDLG_MACHINE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 105 + END + + CONFIGUREDLG_VIDEO, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + + CONFIGUREDLG_INPUT, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END + + CONFIGUREDLG_SOUND, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 71 + END + + CONFIGUREDLG_NETWORK, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + + CONFIGUREDLG_PERIPHERALS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 102 + END + + CONFIGUREDLG_HARD_DISKS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 137 + END + + CONFIGUREDLG_REMOVABLE_DEVICES, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 260 + TOPMARGIN, 7 + BOTTOMMARGIN, 195 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + 2048 "86Box" + IDS_STRING2049 "86Box Error" + IDS_STRING2050 "86Box Fatal Error" + IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" + IDS_STRING2052 "DirectDraw Screenshot Error" + IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" + IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" + IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" + IDS_STRING2056 "Please enter a valid file name" + IDS_STRING2057 "Unable to open the file for write" + IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" + IDS_STRING2059 "Remember to partition and format the new drive" + IDS_STRING2060 "Unable to open the file for read" + IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." + IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." +END + +STRINGTABLE DISCARDABLE +BEGIN + IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." + IDS_STRING2065 "Machine" + IDS_STRING2066 "Video" + IDS_STRING2067 "Input devices" + IDS_STRING2068 "Sound" + IDS_STRING2069 "Network" + IDS_STRING2070 "Other peripherals" + IDS_STRING2071 "Hard disks" + IDS_STRING2072 "Removable devices" + IDS_STRING2073 "%i"" floppy drive: %s" + IDS_STRING2074 "Disabled CD-ROM drive" + IDS_STRING2075 "%s CD-ROM drive: %s" + IDS_STRING2076 "Host CD/DVD Drive (%c:)" + IDS_STRING2077 "Click to capture mouse" + IDS_STRING2078 "Press F12-F8 to release mouse" + IDS_STRING2079 "Press F12-F8 or middle button to release mouse" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2080 "Drive" + 2081 "Location" + 2082 "Bus" + 2083 "File" + 2084 "C" + 2085 "H" + 2086 "S" + 2087 "MB" + 2088 "%i" + 2089 "Enabled" + 2090 "Mute" + 2091 "Type" + 2092 "Bus" + 2093 "DMA" + 2094 "KB" + 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2096 "Slave" + 2097 "SCSI (ID %s, LUN %s)" + 2098 "Adapter Type" + 2099 "Base Address" + 2100 "IRQ" + 2101 "8-bit DMA" + 2102 "16-bit DMA" + 2103 "BIOS" + 2104 "Network Type" + 2105 "Surround Module" + 2106 "MPU-401 Base Address" + 2107 "No PCap devices found" + 2108 "On-board RAM" + 2109 "Memory Size" + 2110 "Display Type" + 2111 "RGB" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2112 "Composite" + 2113 "Composite Type" + 2114 "Old" + 2115 "New" + 2116 "RGB Type" + 2117 "Color" + 2118 "Monochrome (Green)" + 2119 "Monochrome (Amber)" + 2120 "Monochrome (Gray)" + 2121 "Color (no brown)" + 2122 "Monochrome (Default)" + 2123 "Snow Emulation" + 2124 "Bilinear Filtering" + 2125 "Dithering" + 2126 "Framebuffer Memory Size" + 2127 "Texture Memory Size" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2128 "Screen Filter" + 2129 "Render Threads" + 2130 "Recompiler" + 2131 "System Default" + 2132 "%i Wait state(s)" + 2133 "8-bit" + 2134 "Slow 16-bit" + 2135 "Fast 16-bit" + 2136 "Slow VLB/PCI" + 2137 "Mid VLB/PCI" + 2138 "Fast VLB/PCI" + 2139 "Microsoft 2-button mouse (serial)" + 2140 "Mouse Systems mouse (serial)" + 2141 "2-button mouse (PS/2)" + 2142 "Microsoft Intellimouse (PS/2)" + 2143 "Bus mouse" +END + +STRINGTABLE DISCARDABLE +BEGIN + 2144 "Standard 2-button joystick(s)" + 2145 "Standard 4-button joystick" + 2146 "Standard 6-button joystick" + 2147 "Standard 8-button joystick" + 2148 "CH Flightstick Pro" + 2149 "Microsoft SideWinder Pad" + 2150 "Thrustmaster Flight Control System" + 2151 "Disabled" + 2152 "None" + 2153 "AT Fixed Disk Adapter" + 2154 "Internal IDE" + 2155 "IRQ %i" + 2156 "MFM (%01i:%01i)" + 2157 "IDE (PIO+DMA) (%01i:%01i)" + 2158 "SCSI (%02i:%02i)" + 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" + 2160 "%" PRIu64 + 2161 "Genius Bus mouse" + 2162 "Amstrad mouse" + 2163 "Attempting to create a spuriously large hard disk image" + 2164 "Invalid number of sectors (valid values are between 1 and 99)" + 2165 "MFM" + 2166 "IDE (PIO-only)" + 2167 "IDE (PIO and DMA)" + 2168 "SCSI" + 2169 "%01i:%01i" + 2170 "Custom..." + 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" + 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" + 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" + 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + 2177 "Olivetti M24 mouse" + 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" + 2179 "Floppy %i (%s): %ws" + 2180 "CD-ROM %i: %ws" + 2181 "MFM hard disk" + 2182 "IDE hard disk (PIO-only)" + 2183 "IDE hard disk (PIO and DMA)" + 2184 "SCSI hard disk" + 2185 "(empty)" + 2186 "(host drive %c:)" + 2187 "Custom (large)..." + 2188 "Type" + 2189 "ATAPI (PIO-only)" + 2190 "ATAPI (PIO and DMA)" + 2191 "ATAPI (PIO-only) (%01i:%01i)" + 2192 "ATAPI (PIO and DMA) (%01i:%01i)" + 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + 2194 "Unable to create bitmap file: %s" + 2195 "IDE (PIO-only) (%01i:%01i)" + 2196 "Add New Hard Disk" + 2197 "Add Existing Hard Disk" + 2198 "Removable disk %i: %s" + 2199 "USB is not yet supported" + 2200 "Invalid PCap device" + 2201 "English (United States)" +END + + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,20,0,0 + PRODUCTVERSION 1,20,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "IRC #SoftHistory\0" + VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" + VALUE "FileVersion", "1.20\0" + VALUE "InternalName", "pc_new\0" + VALUE "LegalCopyright", "Copyright © SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "86Box.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "86Box Emulator\0" + VALUE "ProductVersion", "1.20\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/src/WIN/pcap_if.rc b/src/WIN/pcap_if.rc new file mode 100644 index 000000000..57d78e657 --- /dev/null +++ b/src/WIN/pcap_if.rc @@ -0,0 +1,52 @@ +#ifdef _WIN32 +#include +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + + +#ifdef RELEASE_BUILD +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +#else +/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ +100 ICON DISCARDABLE "ICONS/86Box.ico" +#endif + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,2,0 + PRODUCTVERSION 1,0,2,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "IRC #SoftHistory\0" + VALUE "FileDescription", "PCap_IF - test tool for WinPcap\0" + VALUE "FileVersion", "1.0.2\0" + VALUE "InternalName", "pcap_if\0" + VALUE "LegalCopyright", "Copyright 2017 Fred N. van Kempen\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "pcap_if.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "WinPcap Test Tool\0" + VALUE "ProductVersion", "1.0.2\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/src/WIN/plat_dinput.h b/src/WIN/plat_dinput.h new file mode 100644 index 000000000..b5d7eca06 --- /dev/null +++ b/src/WIN/plat_dinput.h @@ -0,0 +1,4 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +extern LPDIRECTINPUT lpdi; diff --git a/src/WIN/plat_dir.h b/src/WIN/plat_dir.h new file mode 100644 index 000000000..6eb372aa0 --- /dev/null +++ b/src/WIN/plat_dir.h @@ -0,0 +1,76 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the platform OpenDir module. + * + * Version: @(#)plat_dir.h 1.0.1 2017/05/17 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef PLAT_DIR_H +# define PLAT_DIR_H + + +#ifdef _MAX_FNAME +# define MAXNAMLEN _MAX_FNAME +#else +# define MAXNAMLEN 15 +#endif +# define MAXDIRLEN 127 + + +struct direct { + long d_ino; + unsigned short d_reclen; + unsigned short d_off; +#ifdef UNICODE + wchar_t d_name[MAXNAMLEN + 1]; +#else + char d_name[MAXNAMLEN + 1]; +#endif +}; +#define d_namlen d_reclen + + +typedef struct { + short flags; /* internal flags */ + short offset; /* offset of entry into dir */ + long handle; /* open handle to Win32 system */ + short sts; /* last known status code */ + char *dta; /* internal work data */ +#ifdef UNICODE + wchar_t dir[MAXDIRLEN+1]; /* open dir */ +#else + char dir[MAXDIRLEN+1]; /* open dir */ +#endif + struct direct dent; /* actual directory entry */ +} DIR; + + +/* Directory routine flags. */ +#define DIR_F_LOWER 0x0001 /* force to lowercase */ +#define DIR_F_SANE 0x0002 /* force this to sane path */ +#define DIR_F_ISROOT 0x0010 /* this is the root directory */ + + +/* Function prototypes. */ +#ifdef UNICODE +extern DIR *opendirw(const wchar_t *); +#else +extern DIR *opendir(const char *); +#endif +extern struct direct *readdir(DIR *); +extern long telldir(DIR *); +extern void seekdir(DIR *, long); +extern int closedir(DIR *); + +#define rewinddir(dirp) seekdir(dirp, 0L) + + +#endif /*PLAT_DIR_H*/ diff --git a/src/WIN/plat_joystick.h b/src/WIN/plat_joystick.h new file mode 100644 index 000000000..aecb3537c --- /dev/null +++ b/src/WIN/plat_joystick.h @@ -0,0 +1,69 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + void joystick_init(); + void joystick_close(); + void joystick_poll(); + + typedef struct plat_joystick_t + { + char name[64]; + + int a[8]; + int b[32]; + int p[4]; + + struct + { + char name[32]; + int id; + } axis[8]; + + struct + { + char name[32]; + int id; + } button[32]; + + struct + { + char name[32]; + int id; + } pov[4]; + + int nr_axes; + int nr_buttons; + int nr_povs; + } plat_joystick_t; + + #define MAX_PLAT_JOYSTICKS 8 + + extern plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; + extern int joysticks_present; + + #define POV_X 0x80000000 + #define POV_Y 0x40000000 + + typedef struct joystick_t + { + int axis[8]; + int button[32]; + int pov[4]; + + int plat_joystick_nr; + int axis_mapping[8]; + int button_mapping[32]; + int pov_mapping[4][2]; + } joystick_t; + + #define MAX_JOYSTICKS 4 + extern joystick_t joystick_state[MAX_JOYSTICKS]; + + #define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0) + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/WIN/plat_keyboard.h b/src/WIN/plat_keyboard.h new file mode 100644 index 000000000..f062c5951 --- /dev/null +++ b/src/WIN/plat_keyboard.h @@ -0,0 +1,22 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + void keyboard_init(); + void keyboard_close(); + void keyboard_poll_host(); + extern int recv_key[272]; + extern int rawinputkey[272]; + +#ifndef __unix + #define KEY_LCONTROL 0x1d + #define KEY_RCONTROL (0x1d | 0x80) + #define KEY_END (0x4f | 0x80) +#endif + +#ifdef __cplusplus +} +#endif + diff --git a/src/WIN/plat_midi.h b/src/WIN/plat_midi.h new file mode 100644 index 000000000..87ed57306 --- /dev/null +++ b/src/WIN/plat_midi.h @@ -0,0 +1,10 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +void midi_init(); +void midi_close(); +void midi_write(uint8_t val); +int midi_get_num_devs(); +void midi_get_dev_name(int num, char *s); + +extern int midi_id; diff --git a/src/WIN/plat_mouse.h b/src/WIN/plat_mouse.h new file mode 100644 index 000000000..ff248f301 --- /dev/null +++ b/src/WIN/plat_mouse.h @@ -0,0 +1,16 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + + void mouse_init(); + void mouse_close(); + extern int mouse_buttons; + void mouse_poll_host(); + void mouse_get_mickeys(int *x, int *y, int *z); + extern int mousecapture; +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/plat_serial.h b/src/WIN/plat_serial.h new file mode 100644 index 000000000..cf87192c0 --- /dev/null +++ b/src/WIN/plat_serial.h @@ -0,0 +1,49 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the Bottom Half of the SERIAL card. + * + * Version: @(#)plat_serial.h 1.0.3 2017/05/17 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#ifndef PLAT_SERIAL_H +# define PLAT_SERIAL_H + + +typedef struct { + char name[79]; /* name of open port */ + void (*rd_done)(void *, int); + void *rd_arg; +#ifdef BHTTY_C + HANDLE handle; + OVERLAPPED rov, /* READ and WRITE events */ + wov; + int tmo; /* current timeout value */ + DCB dcb, /* terminal settings */ + odcb; +#endif +} BHTTY; + + +extern BHTTY *bhtty_open(char *__port, int __tmo); +extern void bhtty_close(BHTTY *); +extern int bhtty_flush(BHTTY *); +extern void bhtty_raw(BHTTY *, void *__arg); +extern int bhtty_speed(BHTTY *, long __speed); +extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); +extern int bhtty_sstate(BHTTY *, void *__arg); +extern int bhtty_gstate(BHTTY *, void *__arg); +extern int bhtty_crtscts(BHTTY *, char __yesno); + +extern int bhtty_write(BHTTY *, unsigned char); +extern int bhtty_read(BHTTY *, unsigned char *, int); + + +#endif /*PLAT_SERIAL_H*/ diff --git a/src/WIN/resource.h b/src/WIN/resource.h new file mode 100644 index 000000000..5364bf674 --- /dev/null +++ b/src/WIN/resource.h @@ -0,0 +1,432 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ +/* {{NO_DEPENDENCIES}} + Microsoft Developer Studio generated include file. + Used by 86Box.rc +*/ +#define IDHDCONFIG 3 +#define IDCDCONFIG 4 +#define CONFIGUREDLG_MACHINE 101 +#define CONFIGUREDLG_VIDEO 102 +#define CONFIGUREDLG_INPUT 103 +#define CONFIGUREDLG_SOUND 104 +#define CONFIGUREDLG_NETWORK 105 +#define CONFIGUREDLG_PERIPHERALS 106 +#define CONFIGUREDLG_HARD_DISKS 107 +#define CONFIGUREDLG_REMOVABLE_DEVICES 108 +#define ABOUTDLG 109 +#define CONFIGUREDLG_HARD_DISKS_ADD 110 +#define CONFIGUREDLG_MAIN 117 +#define IDC_SETTINGSCATLIST 1004 +#define IDC_LIST_HARD_DISKS 1005 +#define IDC_COMBO_MACHINE 1006 +#define IDC_COMBO_CPU_TYPE 1007 +#define IDC_COMBO_CPU 1008 +#define IDC_COMBO_WS 1009 +#define IDC_CHECK_DYNAREC 1010 +#define IDC_CHECK_FPU 1011 +#define IDC_COMBO_SCSI 1012 +#define IDC_CONFIGURE_SCSI 1013 +#define IDC_COMBO_VIDEO 1014 +#define IDC_COMBO_VIDEO_SPEED 1015 +#define IDC_CHECK_VOODOO 1016 +#define IDC_CHECKCMS 1016 +#define IDC_CONFIGURE_VOODOO 1017 +#define IDC_CHECKNUKEDOPL 1018 +#define IDC_COMBO_JOYSTICK 1018 +#define IDC_CHECK_SYNC 1019 +#define IDC_LIST_FLOPPY_DRIVES 1020 +#define IDC_LIST_CDROM_DRIVES 1021 +#define IDC_CONFIGURE_MACHINE 1022 +#define IDC_COMBO_LANG 1023 +#define IDC_BUTTON_FDD_ADD 1024 +#define IDC_BUTTON_FDD_EDIT 1025 +#define IDC_BUTTON_FDD_REMOVE 1026 +#define IDC_BUTTON_CDROM_ADD 1027 +#define IDC_BUTTON_HDD_ADD_NEW 1027 +#define IDC_BUTTON_CDROM_EDIT 1028 +#define IDC_BUTTON_HDD_ADD 1028 +#define IDC_BUTTON_CDROM_REMOVE 1029 +#define IDC_BUTTON_HDD_REMOVE 1029 +#define IDC_HDIMAGE_NEW 1035 +#define IDC_HD_BUS 1036 +#define IDC_HDIMAGE_EXISTING 1037 +#define IDC_COMBO_HD_BUS 1038 +#define IDC_EDIT_HD_FILE_NAME 1039 +#define IDC_EDIT_HD_CYL 1040 +#define IDC_EDIT_HD_HPC 1041 +#define IDC_EDIT_HD_SPT 1042 +#define IDC_EDIT_HD_SIZE 1043 +#define IDC_COMBO_HD_TYPE 1044 +#define IDC_COMBO_HD_LOCATION 1045 +#define IDC_CHECKGUS 1046 +#define IDC_COMBO_HD_CHANNEL 1047 +#define IDC_COMBO_HD_CHANNEL_IDE 1048 +#define IDC_COMBO_HD_ID 1050 +#define IDC_COMBO_HD_LUN 1051 +#define IDC_CHECKBUGGER 1052 +#define IDC_CHECKSERIAL1 1053 +#define IDC_CHECKPARALLEL 1054 +#define IDC_CHECKSERIAL2 1055 +#define IDC_COMBO_HDC 1068 +#define IDC_COMBO_MOUSE 1069 +#define IDC_COMBO_IDE_TER 1069 +#define IDC_COMBO_IDE_QUA 1070 +#define IDC_COMBO_FD_TYPE 1071 +#define IDC_COMBO_CD_BUS 1072 +#define IDC_COMBO_CD_CHANNEL_IDE 1073 +#define IDC_COMBO_CD_ID 1074 +#define IDC_COMBO_CD_LUN 1075 +#define IDC_COMBO_MIDI 1076 +#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 +#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 +#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 +#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 +#define IDS_STRING2049 2049 +#define IDS_STRING2050 2050 +#define IDS_STRING2051 2051 +#define IDS_STRING2052 2052 +#define IDS_STRING2053 2053 +#define IDS_STRING2054 2054 +#define IDS_STRING2055 2055 +#define IDS_STRING2056 2056 +#define IDS_STRING2057 2057 +#define IDS_STRING2058 2058 +#define IDS_STRING2059 2059 +#define IDS_STRING2060 2060 +#define IDS_STRING2061 2061 +#define IDS_STRING2062 2062 +#define IDS_STRING2063 2063 +#define IDS_STRING2064 2064 +#define IDS_STRING2065 2065 +#define IDS_STRING2066 2066 +#define IDS_STRING2067 2067 +#define IDS_STRING2068 2068 +#define IDS_STRING2069 2069 +#define IDS_STRING2070 2070 +#define IDS_STRING2071 2071 +#define IDS_STRING2072 2072 +#define IDS_STRING2073 2073 +#define IDS_STRING2074 2074 +#define IDS_STRING2075 2075 +#define IDS_STRING2076 2076 +#define IDS_STRING2077 2077 +#define IDS_STRING2078 2078 +#define IDS_STRING2079 2079 +#define IDM_ABOUT 40001 +#define IDC_ABOUT_ICON 65535 + +#define IDM_DISC_1 40000 +#define IDM_DISC_2 40001 +#define IDM_DISC_3 40002 +#define IDM_DISC_4 40003 +#define IDM_DISC_1_WP 40004 +#define IDM_DISC_2_WP 40005 +#define IDM_DISC_3_WP 40006 +#define IDM_DISC_4_WP 40007 +#define IDM_EJECT_1 40008 +#define IDM_EJECT_2 40009 +#define IDM_EJECT_3 40010 +#define IDM_EJECT_4 40011 + +#define IDM_FILE_RESET 40015 +#define IDM_FILE_HRESET 40016 +#define IDM_FILE_EXIT 40017 +#define IDM_FILE_RESET_CAD 40018 +#define IDM_HDCONF 40019 +#define IDM_CONFIG 40020 +#define IDM_CONFIG_LOAD 40021 +#define IDM_CONFIG_SAVE 40022 +#define IDM_USE_NUKEDOPL 40023 +#define IDM_STATUS 40030 +#define IDM_VID_RESIZE 40050 +#define IDM_VID_REMEMBER 40051 +#define IDM_VID_DDRAW 40060 +#define IDM_VID_D3D 40061 +#define IDM_VID_SCALE_1X 40064 +#define IDM_VID_SCALE_2X 40065 +#define IDM_VID_SCALE_3X 40066 +#define IDM_VID_SCALE_4X 40067 +#define IDM_VID_FULLSCREEN 40070 +#define IDM_VID_FS_FULL 40071 +#define IDM_VID_FS_43 40072 +#define IDM_VID_FS_SQ 40073 +#define IDM_VID_FS_INT 40074 +#define IDM_VID_FORCE43 40075 +#define IDM_VID_OVERSCAN 40076 +#define IDM_VID_FLASH 40077 +#define IDM_VID_SCREENSHOT 40078 +#define IDM_VID_INVERT 40079 + +#define IDM_CDROM_1_MUTE 40128 +#define IDM_CDROM_1_IMAGE 40144 +#define IDM_CDROM_1_RELOAD 40160 +#define IDM_CDROM_1_EMPTY 40176 +#define IDM_CDROM_1_REAL 40192 +#define IDM_CDROM_2_MUTE 40129 +#define IDM_CDROM_2_IMAGE 40145 +#define IDM_CDROM_2_RELOAD 40161 +#define IDM_CDROM_2_EMPTY 40177 +#define IDM_CDROM_2_REAL 40193 +#define IDM_CDROM_3_MUTE 40130 +#define IDM_CDROM_3_IMAGE 40146 +#define IDM_CDROM_3_RELOAD 40162 +#define IDM_CDROM_3_EMPTY 40178 +#define IDM_CDROM_3_REAL 40194 +#define IDM_CDROM_4_MUTE 40131 +#define IDM_CDROM_4_IMAGE 40147 +#define IDM_CDROM_4_RELOAD 40163 +#define IDM_CDROM_4_EMPTY 40179 +#define IDM_CDROM_4_REAL 40195 + +#define IDM_IDE_TER_ENABLED 44000 +#define IDM_IDE_TER_IRQ9 44009 +#define IDM_IDE_TER_IRQ10 44010 +#define IDM_IDE_TER_IRQ11 44011 +#define IDM_IDE_TER_IRQ12 44012 +#define IDM_IDE_TER_IRQ14 44014 +#define IDM_IDE_TER_IRQ15 44015 +#define IDM_IDE_QUA_ENABLED 44020 +#define IDM_IDE_QUA_IRQ9 44029 +#define IDM_IDE_QUA_IRQ10 44030 +#define IDM_IDE_QUA_IRQ11 44031 +#define IDM_IDE_QUA_IRQ12 44032 +#define IDM_IDE_QUA_IRQ14 44033 +#define IDM_IDE_QUA_IRQ15 44035 + +#ifdef ENABLE_LOG_TOGGLES +# ifdef ENABLE_BUSLOGIC_LOG +# define IDM_LOG_BUSLOGIC 51200 +# endif +# ifdef ENABLE_CDROM_LOG +# define IDM_LOG_CDROM 51201 +# endif +# ifdef ENABLE_D86F_LOG +# define IDM_LOG_D86F 51202 +# endif +# ifdef ENABLE_FDC_LOG +# define IDM_LOG_FDC 51203 +# endif +# ifdef ENABLE_IDE_LOG +# define IDM_LOG_IDE 51204 +# endif +# ifdef ENABLE_NE2000_LOG +# define IDM_LOG_NE2000 51205 +# endif +#endif +#ifdef ENABLE_LOG_BREAKPOINT +# define IDM_LOG_BREAKPOINT 51206 +#endif +#ifdef ENABLE_VRAM_DUMP +# define IDM_DUMP_VRAM 51207 +#endif + +#define IDC_COMBO1 1000 +#define IDC_COMBOVID 1001 +#define IDC_COMBO3 1002 +#define IDC_COMBO4 1003 +#define IDC_COMBO5 1004 +#define IDC_COMBO386 1005 +#define IDC_COMBO486 1006 +#define IDC_COMBOSND 1007 +#define IDC_COMBONETTYPE 1008 +#define IDC_COMBOPCAP 1009 +#define IDC_COMBONET 1010 +#define IDC_COMBOCPUM 1060 +#define IDC_COMBOSPD 1061 +#define IDC_COMBODR1 1062 +#define IDC_COMBODR2 1063 +#define IDC_COMBODR3 1064 +#define IDC_COMBODR4 1065 +#define IDC_COMBOJOY 1066 +#define IDC_COMBOWS 1067 +#define IDC_COMBOMOUSE 1068 +#define IDC_COMBOHDD 1069 +#define IDC_CHECK1 1010 +#define IDC_CHECK2 1011 +#define IDC_CHECK3 1012 +#define IDC_CHECKSSI 1014 +#define IDC_CHECKVOODOO 1015 +#define IDC_CHECKDYNAREC 1016 +#define IDC_CHECKBUSLOGIC 1017 +#define IDC_CHECKSYNC 1024 +#define IDC_CHECKXTIDE 1025 +#define IDC_CHECKFPU 1026 +#define IDC_EDIT1 1030 +#define IDC_EDIT2 1031 +#define IDC_EDIT3 1032 +#define IDC_EDIT4 1033 +#define IDC_EDIT5 1034 +#define IDC_EDIT6 1035 +#define IDC_COMBOHDT 1036 + +#define IDC_EJECTC 1040 +#define IDC_EDITC 1050 +#define IDC_CFILE 1060 +#define IDC_CNEW 1070 +#define IDC_EDIT_C_SPT 1200 +#define IDC_EDIT_C_HPC 1210 +#define IDC_EDIT_C_CYL 1220 +#define IDC_EDIT_C_FN 1230 +#define IDC_TEXT_C_SIZE 1240 + +#define IDC_EJECTD 1041 +#define IDC_EDITD 1051 +#define IDC_DFILE 1061 +#define IDC_DNEW 1071 +#define IDC_EDIT_D_SPT 1201 +#define IDC_EDIT_D_HPC 1211 +#define IDC_EDIT_D_CYL 1221 +#define IDC_EDIT_D_FN 1231 +#define IDC_TEXT_D_SIZE 1241 + +#define IDC_EJECTE 1042 +#define IDC_EDITE 1052 +#define IDC_EFILE 1062 +#define IDC_ENEW 1072 +#define IDC_EDIT_E_SPT 1202 +#define IDC_EDIT_E_HPC 1212 +#define IDC_EDIT_E_CYL 1222 +#define IDC_EDIT_E_FN 1232 +#define IDC_TEXT_E_SIZE 1242 + +#define IDC_EJECTF 1043 +#define IDC_EDITF 1053 +#define IDC_FFILE 1063 +#define IDC_FNEW 1073 +#define IDC_EDIT_F_SPT 1203 +#define IDC_EDIT_F_HPC 1213 +#define IDC_EDIT_F_CYL 1223 +#define IDC_EDIT_F_FN 1233 +#define IDC_TEXT_F_SIZE 1243 + +#define IDC_EJECTG 1044 +#define IDC_EDITG 1054 +#define IDC_GFILE 1064 +#define IDC_GNEW 1074 +#define IDC_EDIT_G_SPT 1204 +#define IDC_EDIT_G_HPC 1214 +#define IDC_EDIT_G_CYL 1224 +#define IDC_EDIT_G_FN 1234 +#define IDC_TEXT_G_SIZE 1244 + +#define IDC_EJECTH 1045 +#define IDC_EDITH 1055 +#define IDC_HFILE 1065 +#define IDC_HNEW 1075 +#define IDC_EDIT_H_SPT 1205 +#define IDC_EDIT_H_HPC 1215 +#define IDC_EDIT_H_CYL 1225 +#define IDC_EDIT_H_FN 1235 +#define IDC_TEXT_H_SIZE 1245 + +#define IDC_EJECTI 1046 +#define IDC_EDITI 1056 +#define IDC_IFILE 1066 +#define IDC_INEW 1076 +#define IDC_EDIT_I_SPT 1206 +#define IDC_EDIT_I_HPC 1216 +#define IDC_EDIT_I_CYL 1226 +#define IDC_EDIT_I_FN 1236 +#define IDC_TEXT_I_SIZE 1246 + +#define IDC_EJECTJ 1047 +#define IDC_EDITJ 1057 +#define IDC_JFILE 1067 +#define IDC_JNEW 1077 +#define IDC_EDIT_J_SPT 1207 +#define IDC_EDIT_J_HPC 1217 +#define IDC_EDIT_J_CYL 1227 +#define IDC_EDIT_J_FN 1237 +#define IDC_TEXT_J_SIZE 1247 + +#define IDC_HDTYPE 1280 + +#define IDC_RENDER 1281 +#define IDC_STATUS 1282 + +#define IDC_MEMSPIN 1100 +#define IDC_MEMTEXT 1101 +#define IDC_STEXT1 1102 +#define IDC_STEXT2 1103 +#define IDC_STEXT3 1104 +#define IDC_STEXT4 1105 +#define IDC_STEXT5 1106 +#define IDC_STEXT6 1107 +#define IDC_STEXT7 1108 +#define IDC_STEXT8 1109 +#define IDC_STEXT_DEVICE 1110 +#define IDC_TEXT_MB 1111 +#define IDC_TEXT1 1115 +#define IDC_TEXT2 1116 + +#define IDC_CONFIGUREVID 1200 +#define IDC_CONFIGURESND 1201 +#define IDC_CONFIGUREVOODOO 1202 +#define IDC_CONFIGUREMOD 1203 +#define IDC_CONFIGURENETTYPE 1204 +#define IDC_CONFIGUREBUSLOGIC 1205 +#define IDC_CONFIGUREPCAP 1206 +#define IDC_CONFIGURENET 1207 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 + +#define IDC_CONFIG_BASE 1200 + +#define WM_RESETD3D WM_USER +#define WM_LEAVEFULLSCREEN WM_USER + 1 + +#define C_BASE 6 +#define D_BASE 44 +#define E_BASE 82 +#define F_BASE 120 +#define G_BASE 158 +#define H_BASE 196 +#define I_BASE 234 +#define J_BASE 272 +#define CMD_BASE 314 +#define DLG_HEIGHT 346 + +#define IDC_CHECK_CDROM_1_ENABLED 1536 +#define IDC_COMBO_CDROM_1_BUS 1544 +#define IDC_COMBO_CDROM_1_CHANNEL 1552 +#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 +#define IDC_COMBO_CDROM_1_SCSI_ID 1568 +#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 + +#define IDC_CHECK_CDROM_2_ENABLED 1537 +#define IDC_COMBO_CDROM_2_BUS 1545 +#define IDC_COMBO_CDROM_2_CHANNEL 1553 +#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 +#define IDC_COMBO_CDROM_2_SCSI_ID 1569 +#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 + +#define IDC_CHECK_CDROM_3_ENABLED 1538 +#define IDC_COMBO_CDROM_3_BUS 1546 +#define IDC_COMBO_CDROM_3_CHANNEL 1554 +#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 +#define IDC_COMBO_CDROM_3_SCSI_ID 1570 +#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 + +#define IDC_CHECK_CDROM_4_ENABLED 1539 +#define IDC_COMBO_CDROM_4_BUS 1547 +#define IDC_COMBO_CDROM_4_CHANNEL 1555 +#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 +#define IDC_COMBO_CDROM_4_SCSI_ID 1571 +#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 + +#define IDC_STATIC 1792 + +/* Next default values for new objects */ +#ifdef APSTUDIO_INVOKED +# ifndef APSTUDIO_READONLY_SYMBOLS +# define _APS_NO_MFC 1 +# define _APS_NEXT_RESOURCE_VALUE 111 +# define _APS_NEXT_COMMAND_VALUE 40002 +# define _APS_NEXT_CONTROL_VALUE 1055 +# define _APS_NEXT_SYMED_VALUE 101 +# endif +#endif diff --git a/src/WIN/win.c b/src/WIN/win.c new file mode 100644 index 000000000..a56660e20 --- /dev/null +++ b/src/WIN/win.c @@ -0,0 +1,2427 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define UNICODE +#define _WIN32_WINNT 0x0501 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../86box.h" +#include "../device.h" +#include "../disc.h" +#include "../fdd.h" +#include "../hdd.h" +#include "../ibm.h" +#include "../cpu/cpu.h" +#include "../mem.h" +#include "../rom.h" +#include "../nvr.h" +#include "../thread.h" +#include "../config.h" +#include "../model.h" +#include "../ide.h" +#include "../cdrom.h" +#include "../cdrom_null.h" +#include "../cdrom_ioctl.h" +#include "../cdrom_image.h" +#include "../video/video.h" +#include "../video/vid_ega.h" +#include "../mouse.h" +#include "../sound/sound.h" +#include "../sound/snd_dbopl.h" +#include "plat_keyboard.h" +#include "plat_mouse.h" +#include "plat_midi.h" + +#include "win.h" +#include "win_ddraw.h" +#include "win_ddraw-fs.h" +#include "win_d3d.h" +#include "win_d3d-fs.h" +#include "win_language.h" +#include "resource.h" + + +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#endif + +static int save_window_pos = 0; +uint64_t timer_freq; + +int rawinputkey[272]; + +static RAWINPUTDEVICE device; +static uint16_t scancode_map[65536]; + +static struct +{ + int (*init)(HWND h); + void (*close)(); + void (*resize)(int x, int y); +} vid_apis[2][2] = +{ + { + ddraw_init, ddraw_close, NULL, + d3d_init, d3d_close, d3d_resize + }, + { + ddraw_fs_init, ddraw_fs_close, NULL, + d3d_fs_init, d3d_fs_close, NULL + }, +}; + +#define TIMER_1SEC 1 + +int winsizex=640,winsizey=480; +int efwinsizey=480; +int gfx_present[GFX_MAX]; + +HANDLE ghMutex; + +HANDLE mainthreadh; + +int infocus=1; + +int drawits=0; + +int romspresent[ROM_MAX]; +int quited=0; + +RECT oldclip; +int mousecapture=0; + +/* Declare Windows procedure */ +LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +LONG OriginalStatusBarProcedure; + +HWND ghwnd; + +HINSTANCE hinstance; + +HMENU menu; + +extern int updatestatus; + +int pause=0; + +static int win_doresize = 0; + +static int leave_fullscreen_flag = 0; + +static int unscaled_size_x = 0; +static int unscaled_size_y = 0; + +int scale = 0; + +HWND hwndRender, hwndStatus; + +void updatewindowsize(int x, int y) +{ + int owsx = winsizex; + int owsy = winsizey; + + int temp_overscan_x = overscan_x; + int temp_overscan_y = overscan_y; + + if (vid_resize) return; + + if (x < 160) x = 160; + if (y < 100) y = 100; + + if (x > 2048) x = 2048; + if (y > 2048) y = 2048; + + if (suppress_overscan) + { + temp_overscan_x = temp_overscan_y = 0; + } + + unscaled_size_x=x; efwinsizey=y; + + if (force_43) + { + /* Account for possible overscan. */ + if (temp_overscan_y == 16) + { + /* CGA */ + unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; + } + else if (temp_overscan_y < 16) + { + /* MDA/Hercules */ + unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); + } + else + { + if (enable_overscan) + { + /* EGA/(S)VGA with overscan */ + unscaled_size_y = ((int) (((double) (x - temp_overscan_x) / 4.0) * 3.0)) + temp_overscan_y; + } + else + { + /* EGA/(S)VGA without overscan */ + unscaled_size_y = ((int) (((double) (x) / 4.0) * 3.0)); + } + } + } + else + { + unscaled_size_y = efwinsizey; + } + + switch(scale) + { + case 0: + winsizex = unscaled_size_x >> 1; + winsizey = unscaled_size_y >> 1; + break; + case 1: + winsizex = unscaled_size_x; + winsizey = unscaled_size_y; + break; + case 2: + winsizex = (unscaled_size_x * 3) >> 1; + winsizey = (unscaled_size_y * 3) >> 1; + break; + case 3: + winsizex = unscaled_size_x << 1; + winsizey = unscaled_size_y << 1; + break; + } + + if ((owsx != winsizex) || (owsy != winsizey)) + { + win_doresize = 1; + } + else + { + win_doresize = 0; + } +} + +void uws_natural() +{ + updatewindowsize(unscaled_size_x, efwinsizey); +} + +void releasemouse() +{ + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture = 0; + } +} + +void startblit() +{ + WaitForSingleObject(ghMutex, INFINITE); +} + +void endblit() +{ + ReleaseMutex(ghMutex); +} + +void leave_fullscreen() +{ + leave_fullscreen_flag = 1; +} + +uint64_t main_time; + +uint64_t start_time; +uint64_t end_time; + +void mainthread(LPVOID param) +{ + int frames = 0; + DWORD old_time, new_time; + + RECT r; + int sb_borders[3]; + + drawits=0; + old_time = GetTickCount(); + while (!quited) + { + if (updatestatus) + { + updatestatus = 0; + if (status_is_open) + SendMessage(status_hwnd, WM_USER, 0, 0); + } + new_time = GetTickCount(); + drawits += new_time - old_time; + old_time = new_time; + if (drawits > 0 && !pause) + { + start_time = timer_read(); + drawits-=10; if (drawits>50) drawits=0; + runpc(); + frames++; + if (frames >= 200 && nvr_dosave) + { + frames = 0; + nvr_dosave = 0; + savenvr(); + } + end_time = timer_read(); + main_time += end_time - start_time; + } + else + Sleep(1); + + if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) + { + video_wait_for_blit(); + SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); + GetWindowRect(ghwnd, &r); + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + GetWindowRect(hwndRender, &r); + MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), + winsizex, + 17, + TRUE); + GetWindowRect(ghwnd, &r); + + MoveWindow(ghwnd, r.left, r.top, + winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), + winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, + TRUE); + + win_doresize = 0; + } + + if (leave_fullscreen_flag) + { + leave_fullscreen_flag = 0; + SendMessage(ghwnd, WM_LEAVEFULLSCREEN, 0, 0); + } + if (video_fullscreen && infocus) + { + SetCursorPos(9999, 9999); + } + } +} + +void *thread_create(void (*thread_rout)(void *param), void *param) +{ + return (void *)_beginthread(thread_rout, 0, param); +} + +void thread_kill(void *handle) +{ + TerminateThread(handle, 0); +} + +void thread_sleep(int t) +{ + Sleep(t); +} + +typedef struct win_event_t +{ + HANDLE handle; +} win_event_t; + +event_t *thread_create_event() +{ + win_event_t *event = malloc(sizeof(win_event_t)); + + event->handle = CreateEvent(NULL, FALSE, FALSE, NULL); + + return (event_t *)event; +} + +void thread_set_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + SetEvent(event->handle); +} + +void thread_reset_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + ResetEvent(event->handle); +} + +int thread_wait_event(event_t *_event, int timeout) +{ + win_event_t *event = (win_event_t *)_event; + + if (timeout == -1) + timeout = INFINITE; + + if (WaitForSingleObject(event->handle, timeout)) + return 1; + return 0; +} + +void thread_destroy_event(event_t *_event) +{ + win_event_t *event = (win_event_t *)_event; + + CloseHandle(event->handle); + + free(event); +} + +HMENU smenu; + +static void initmenu(void) +{ + int i, c; + HMENU m; + WCHAR s[64]; + + for (i = 0; i < CDROM_NUM; i++) + { + m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ + + /* Loop through each Windows drive letter and test to see if + it's a CDROM */ + for (c='A';c<='Z';c++) + { + _swprintf(s,L"%c:\\",c); + if (GetDriveType(s)==DRIVE_CDROM) + { + _swprintf(s, win_language_get_string_from_id(2076), c); + AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); + } + } + } +} + +void get_executable_name(WCHAR *s, int size) +{ + GetModuleFileName(hinstance, s, size); +} + +void set_window_title(WCHAR *s) +{ + if (video_fullscreen) + return; + SetWindowText(ghwnd, s); +} + +uint64_t timer_read() +{ + LARGE_INTEGER qpc_time; + QueryPerformanceCounter(&qpc_time); + return qpc_time.QuadPart; +} + +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +UINT16 convert_scan_code(UINT16 scan_code) +{ + switch (scan_code) + { + case 0xE001: + return 0xF001; + case 0xE002: + return 0xF002; + case 0xE0AA: + return 0xF003; + case 0xE005: + return 0xF005; + case 0xE006: + return 0xF006; + case 0xE007: + return 0xF007; + case 0xE071: + return 0xF008; + case 0xE072: + return 0xF009; + case 0xE07F: + return 0xF00A; + case 0xE0E1: + return 0xF00B; + case 0xE0EE: + return 0xF00C; + case 0xE0F1: + return 0xF00D; + case 0xE0FE: + return 0xF00E; + case 0xE0EF: + return 0xF00F; + + default: + return scan_code; + } +} + +void get_registry_key_map() +{ + WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + WCHAR *valueName = L"Scancode Map"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; + + /* First, prepare the default scan code map list which is 1:1. + Remappings will be inserted directly into it. + 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, + since each array element is a scan code and provides for E0, etc. ones too. */ + for (j = 0; j < 65536; j++) + scancode_map[j] = convert_scan_code(j); + + bufSize = 32768; + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) + { + if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) + { + UINT32 *bufEx2 = (UINT32 *) buf; + int scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) + { + UINT16 *bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount*2; j += 2) + { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + int scancode_unmapped = bufEx[j + 1]; + int scancode_mapped = bufEx[j]; + + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Fixes scan code map logging. */ + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +static wchar_t **argv; +static int argc; +static wchar_t *argbuf; + +static void process_command_line() +{ + WCHAR *cmdline; + int argc_max; + int i, q; + + cmdline = GetCommandLine(); + i = wcslen(cmdline) + 1; + argbuf = malloc(i * 2); + memcpy(argbuf, cmdline, i * 2); + + argc = 0; + argc_max = 64; + argv = malloc(sizeof(wchar_t *) * argc_max); + if (!argv) + { + free(argbuf); + return; + } + + i = 0; + + /* parse commandline into argc/argv format */ + while (argbuf[i]) + { + while (argbuf[i] == L' ') + i++; + + if (argbuf[i]) + { + if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) + { + q = argbuf[i++]; + if (!argbuf[i]) + break; + } + else + q = 0; + + argv[argc++] = &argbuf[i]; + + if (argc >= argc_max) + { + argc_max += 64; + argv = realloc(argv, sizeof(wchar_t *) * argc_max); + if (!argv) + { + free(argbuf); + return; + } + } + + while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (argbuf[i] != L' '))) + i++; + + if (argbuf[i]) + { + argbuf[i] = 0; + i++; + } + } + } + + argv[argc] = NULL; +} + +int valid_models[2] = { 0, 1 }; +int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; +int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; +int valid_dma_channels[3] = { 5, 6, 7 }; +int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; +int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +int find_in_array(int *array, int val, int len, int menu_base) +{ + int i = 0; + int temp = 0; + for (i = 0; i < len; i++) + { + CheckMenuItem(menu, menu_base + array[i], MF_UNCHECKED); + if (array[i] == val) + { + temp = 1; + } + } + return temp; +} + +HANDLE hinstAcc; + +HICON LoadIconEx(PCTSTR pszIconName) +{ + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); +} + +HICON LoadIconBig(PCTSTR pszIconName) +{ + return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 64, 64, 0); +} + +int fdd_type_to_icon(int type) +{ + switch(type) + { + default: + case 0: + return 512; + case 1: + return 128; + case 2: + return 130; + case 3: + return 132; + case 4: + case 5: + case 6: + return 134; + case 7: + return 144; + case 8: + return 146; + case 9: + case 10: + case 11: + case 12: + return 150; + case 13: + return 152; + } +} + +int sb_parts = 10; + +int sb_part_meanings[12]; +int sb_part_icons[12]; + +int sb_icon_width = 24; + +int count_hard_disks(int bus) +{ + int i = 0; + + int c = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == bus) + { + c++; + } + } + + return c; +} + +HICON hIcon[512]; + +int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; + +#define SBI_FLAG_ACTIVE 1 +#define SBI_FLAG_EMPTY 256 + +int sb_icon_flags[512]; + +/* This is for the disk activity indicator. */ +void update_status_bar_icon(int tag, int active) +{ + int i = 0; + int found = -1; + int temp_flags = 0; + + if ((tag & 0xf0) >= 0x30) + { + return; + } + + temp_flags |= active; + + for (i = 0; i < 12; i++) + { + if (sb_part_meanings[i] == tag) + { + found = i; + break; + } + } + + if (found != -1) + { + if (temp_flags != (sb_icon_flags[found] & 1)) + { + sb_icon_flags[found] &= ~1; + sb_icon_flags[found] |= active; + + sb_part_icons[found] &= ~257; + sb_part_icons[found] |= sb_icon_flags[found]; + + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); + } + } +} + +/* This is for the drive state indicator. */ +void update_status_bar_icon_state(int tag, int state) +{ + int i = 0; + int found = -1; + + if ((tag & 0xf0) >= 0x20) + { + return; + } + + for (i = 0; i < 12; i++) + { + if (sb_part_meanings[i] == tag) + { + found = i; + break; + } + } + + if (found != -1) + { + sb_icon_flags[found] &= ~256; + sb_icon_flags[found] |= state ? 256 : 0; + + sb_part_icons[found] &= ~257; + sb_part_icons[found] |= sb_icon_flags[found]; + + SendMessage(hwndStatus, SB_SETICON, found, (LPARAM) hIcon[sb_part_icons[found]]); + } +} + +WCHAR sbTips[24][512]; + +void create_floppy_tip(int part) +{ + WCHAR *szText; + WCHAR wtext[512]; + + int drive = sb_part_meanings[part] & 0xf; + + mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); + if (wcslen(discfns[drive]) == 0) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); + } + else + { + _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); + } +} + +void create_cdrom_tip(int part) +{ + WCHAR *szText; + char ansi_text[3][512]; + WCHAR wtext[512]; + + int drive = sb_part_meanings[part] & 0xf; + + if (cdrom_drives[drive].host_drive == 200) + { + if (wcslen(cdrom_image[drive].image_path) == 0) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + } + else + { + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); + } + } + else if (cdrom_drives[drive].host_drive < 0x41) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + } + else + { + _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); + } +} + +void create_hd_tip(int part) +{ + WCHAR *szText; + + int bus = sb_part_meanings[part] & 0xf; + szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); + memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); +} + +void update_tip(int meaning) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == meaning) + { + part = i; + } + } + + if (part != -1) + { + switch(meaning & 0x30) + { + case 0x00: + create_floppy_tip(part); + break; + case 0x10: + create_cdrom_tip(part); + break; + case 0x20: + create_hd_tip(part); + break; + default: + break; + } + + SendMessage(hwndStatus, SB_SETTIPTEXT, part, (LPARAM) sbTips[part]); + } +} + +static int get_floppy_state(int id) +{ + return (wcslen(discfns[id]) == 0) ? 1 : 0; +} + +static int get_cd_state(int id) +{ + if (cdrom_drives[id].host_drive < 0x41) + { + return 1; + } + else + { + if (cdrom_drives[id].host_drive == 0x200) + { + return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; + } + else + { + return 0; + } + } +} + +void status_settextw(wchar_t *wstr) +{ + int i = 0; + int part = -1; + + for (i = 0; i < sb_parts; i++) + { + if (sb_part_meanings[i] == 0x30) + { + part = i; + } + } + + if (part != -1) + { + SendMessage(hwndStatus, SB_SETTEXT, part | SBT_NOBORDERS, (LPARAM) wstr); + } +} + +static wchar_t cwstr[512]; + +void status_settext(char *str) +{ + memset(cwstr, 0, 1024); + mbstowcs(cwstr, str, strlen(str) + 1); + status_settextw(cwstr); +} + +void update_status_bar_panes(HWND hwnds) +{ + int i, j, id; + int edge = 0; + + int c_rll = 0; + int c_mfm = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; + int c_scsi = 0; + + c_mfm = count_hard_disks(1); + c_ide_pio = count_hard_disks(2); + c_ide_dma = count_hard_disks(3); + c_scsi = count_hard_disks(4); + + for (i = 0; i < sb_parts; i++) + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + + sb_parts = 0; + memset(iStatusWidths, 0, 48); + memset(sb_part_meanings, 0, 48); + for (i = 0; i < 4; i++) + { + if (fdd_get_type(i) != 0) + { + /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x00 | i; + sb_parts++; + } + } + for (i = 0; i < 4; i++) + { + if (cdrom_drives[i].bus_type != 0) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x10 | i; + sb_parts++; + } + } + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x20; + sb_parts++; + } + if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x21; + sb_parts++; + } + if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x22; + sb_parts++; + } + if (c_scsi) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x23; + sb_parts++; + } + if (sb_parts) + { + iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); + } + iStatusWidths[sb_parts] = -1; + sb_part_meanings[sb_parts] = 0x30; + sb_parts++; + + SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); + + for (i = 0; i < sb_parts; i++) + { + switch (sb_part_meanings[i] & 0x30) + { + case 0x00: + /* Floppy */ + sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; + create_floppy_tip(i); + break; + case 0x10: + /* CD-ROM */ + id = sb_part_meanings[i] & 0xf; + if (cdrom_drives[id].host_drive < 0x41) + { + sb_icon_flags[i] = 256; + } + else + { + if (cdrom_drives[id].host_drive == 0x200) + { + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; + } + else + { + sb_icon_flags[i] = 0; + } + } + if (cdrom_drives[id].bus_type == 4) + { + j = 164; + } + else if (cdrom_drives[id].bus_type == 3) + { + j = 162; + } + else + { + j = 160; + } + sb_part_icons[i] = j | sb_icon_flags[i]; + create_cdrom_tip(i); + break; + case 0x20: + /* Hard disk */ + sb_part_icons[i] = 176 + ((sb_part_meanings[i] & 0xf) << 1); + create_hd_tip(i); + break; + case 0x30: + /* Status text */ + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); + sb_part_icons[i] = -1; + break; + } + if (sb_part_icons[i] != -1) + { + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) ""); + SendMessage(hwnds, SB_SETICON, i, (LPARAM) hIcon[sb_part_icons[i]]); + SendMessage(hwnds, SB_SETTIPTEXT, i, (LPARAM) sbTips[i]); + /* pclog("Status bar part found: %02X (%i)\n", sb_part_meanings[i], sb_part_icons[i]); */ + } + else + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + } +} + +HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) +{ + HWND hwndStatus; + int i; + RECT rectDialog; + int dw, dh; + + for (i = 128; i < 136; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 144; i < 148; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 150; i < 154; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 160; i < 166; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 176; i < 184; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 384; i < 392; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 400; i < 404; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 406; i < 410; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + for (i = 416; i < 422; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } + + GetWindowRect(hwndParent, &rectDialog); + dw = rectDialog.right - rectDialog.left; + dh = rectDialog.bottom - rectDialog.top; + + InitCommonControls(); + + hwndStatus = CreateWindowEx( + 0, + STATUSCLASSNAME, + (PCTSTR) NULL, + SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, + 0, dh - 17, dw, 17, + hwndParent, + (HMENU) idStatus, + hinst, + NULL); + + GetWindowRect(hwndStatus, &rectDialog); + + SetWindowPos( + hwndStatus, + HWND_TOPMOST, + rectDialog.left, + rectDialog.top, + rectDialog.right - rectDialog.left, + rectDialog.bottom - rectDialog.top, + SWP_SHOWWINDOW); + + SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); + + update_status_bar_panes(hwndStatus); + + return hwndStatus; +} + +void win_menu_update() +{ +#if 0 + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); + initmenu(); + + SetMenu(ghwnd, menu); + + win_title_update = 1; +#endif +} + +int recv_key[272]; + +int WINAPI WinMain (HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpszArgument, + int nFunsterStil) + +{ + HWND hwnd; /* This is the handle for our window */ + MSG messages; /* Here messages to the application are saved */ + WNDCLASSEX wincl; /* Data structure for the windowclass */ + int c, d, e, bRet; + WCHAR emulator_title[200]; + LARGE_INTEGER qpc_freq; + HACCEL haccel; /* Handle to accelerator table */ + + memset(recv_key, 0, sizeof(recv_key)); + + process_command_line(); + + win_language_load_common_strings(); + + hinstance=hThisInstance; + /* The Window structure */ + wincl.hInstance = hThisInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ + wincl.style = CS_DBLCLKS; /* Catch double-clicks */ + wincl.cbSize = sizeof (WNDCLASSEX); + + /* Use default icon and mouse-pointer */ + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hCursor = NULL; + wincl.lpszMenuName = NULL; /* No menu */ + wincl.cbClsExtra = 0; /* No extra bytes after the window class */ + wincl.cbWndExtra = 0; /* structure or the window instance */ + /* Use Windows's default color as the background of the window */ + wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; + + /* Register the window class, and if it fails quit the program */ + if (!RegisterClassEx(&wincl)) + return 0; + + wincl.lpszClassName = szSubClassName; + wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ + + if (!RegisterClassEx(&wincl)) + return 0; + + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + + /* The class is registered, let's create the program*/ + hwnd = CreateWindowEx ( + 0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + emulator_title, /* Title Text */ + (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ + CW_USEDEFAULT, /* Windows decides the position */ + CW_USEDEFAULT, /* where the window ends up on the screen */ + 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ + 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ + HWND_DESKTOP, /* The window is a child-window to desktop */ + menu, /* Menu */ + hThisInstance, /* Program Instance handler */ + NULL /* No Window Creation data */ + ); + + /* Make the window visible on the screen */ + ShowWindow (hwnd, nFunsterStil); + + /* Load the accelerator table */ + haccel = LoadAccelerators(hinstAcc, L"MainAccel"); + if (haccel == NULL) + fatal("haccel is null\n"); + + memset(rawinputkey, 0, sizeof(rawinputkey)); + device.usUsagePage = 0x01; + device.usUsage = 0x06; + device.dwFlags = RIDEV_NOHOTKEYS; + device.hwndTarget = hwnd; + + if (RegisterRawInputDevices(&device, 1, sizeof(device))) + pclog("Raw input registered!\n"); + else + pclog("Raw input registration failed!\n"); + + get_registry_key_map(); + + ghwnd=hwnd; + + initpc(argc, argv); + + hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); + + hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); + + OriginalStatusBarProcedure = GetWindowLong(hwndStatus, GWL_WNDPROC); + SetWindowLong(hwndStatus, GWL_WNDPROC, (LONG) &StatusBarProcedure); + + smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); + initmenu(); + + if (vid_apis[0][vid_api].init(hwndRender) == 0) + { + if (vid_apis[0][vid_api ^ 1].init(hwndRender) == 0) + { + fatal("Both DirectDraw and Direct3D renderers failed to initialize\n"); + } + else + { + vid_api ^= 1; + } + } + + if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); + else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); + + SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); + + /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ + for (e = 0; e < CDROM_NUM; e++) + { + if (!cdrom_drives[e].sound_on) + { + CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); + } + + if (cdrom_drives[e].host_drive == 200) + { + CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); + } + else if (cdrom_drives[e].host_drive >= 65) + { + CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); + } + else + { + CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); + } + } + +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_CDROM_LOG + CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_D86F_LOG + CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_FDC_LOG + CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_IDE_LOG + CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#ifdef ENABLE_NE2000_LOG + CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); +#endif +#endif + + CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_OVERSCAN, enable_overscan ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_INVERT, invert_display ? MF_CHECKED : MF_UNCHECKED); + + if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + + d=romset; + for (c=0;c= 0; c--) + { + if (gfx_present[c]) + { + gfxcard = c; + saveconfig(); + resetpchard(); + break; + } + } + } + + loadbios(); + resetpchard(); + + timeBeginPeriod(1); + + atexit(releasemouse); + + ghMutex = CreateMutex(NULL, FALSE, NULL); + mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); + SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); + + + updatewindowsize(640, 480); + + QueryPerformanceFrequency(&qpc_freq); + timer_freq = qpc_freq.QuadPart; + + if (start_in_fullscreen) + { + startblit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(hwndRender); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + device_force_redraw(); + } + if (window_remember) + { + MoveWindow(hwnd, window_x, window_y, + window_w, + window_h, + TRUE); + } + else + { + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + MoveWindow(hwndStatus, 0, winsizey + 6, + winsizex, + 17, + TRUE); + } + + /* Run the message loop. It will run until GetMessage() returns 0 */ + while (!quited) + { + while (((bRet = GetMessage(&messages,NULL,0,0)) != 0) && !quited) + { + if (bRet == -1) + { + fatal("bRet is -1\n"); + } + + if (messages.message==WM_QUIT) quited=1; + if (!TranslateAccelerator(hwnd, haccel, &messages)) + { + TranslateMessage(&messages); + DispatchMessage(&messages); + } + + if (recv_key[0x58] && recv_key[0x42] && mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture=0; + } + + if ((recv_key[0x1D] || recv_key[0x9D]) && + (recv_key[0x38] || recv_key[0xB8]) && + (recv_key[0x51] || recv_key[0xD1]) && + video_fullscreen) + { + leave_fullscreen(); + } + } + + quited=1; + } + + startblit(); + Sleep(200); + TerminateThread(mainthreadh,0); + savenvr(); + saveconfig(); + closepc(); + + vid_apis[video_fullscreen][vid_api].close(); + + timeEndPeriod(1); + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + } + + UnregisterClass(szSubClassName, hinstance); + UnregisterClass(szClassName, hinstance); + + return messages.wParam; +} + +HHOOK hKeyboardHook; +int hook_enabled = 0; + +LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +{ + BOOL bControlKeyDown; + KBDLLHOOKSTRUCT* p; + + if (nCode < 0 || nCode != HC_ACTION) + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + + p = (KBDLLHOOKSTRUCT*)lParam; + + if (p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ + if (p->vkCode == VK_SPACE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-tab */ + if((p->vkCode == VK_LWIN) || (p->vkCode == VK_RWIN)) return 1; /* disable windows keys */ + if (p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN) return 1; /* disable alt-escape */ + bControlKeyDown = GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1); /* checks ctrl key pressed */ + if (p->vkCode == VK_ESCAPE && bControlKeyDown) return 1; /* disable ctrl-escape */ + + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam ); +} + +void cdrom_close(uint8_t id) +{ + switch (cdrom_drives[id].host_drive) + { + case 0: + null_close(id); + break; + default: + ioctl_close(id); + break; + case 200: + image_close(id); + break; + } +} + +int ide_ter_set_irq(HMENU hmenu, int irq, int id) +{ + if (ide_irq[2] == irq) + { + return 0; + } + if (msgbox_reset_yn(ghwnd) != IDYES) + { + return 0; + } + pause = 1; + Sleep(100); + ide_irq[2] = irq; + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); + CheckMenuItem(hmenu, id, MF_CHECKED); + saveconfig(); + resetpchard(); + pause = 0; + return 1; +} + +int ide_qua_set_irq(HMENU hmenu, int irq, int id) +{ + if (ide_irq[3] == irq) + { + return 0; + } + if (msgbox_reset_yn(ghwnd) != IDYES) + { + return 0; + } + pause = 1; + Sleep(100); + ide_irq[3] = irq; + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); + CheckMenuItem(hmenu, id, MF_CHECKED); + saveconfig(); + resetpchard(); + pause = 0; + return 1; +} + +void video_toggle_option(HMENU hmenu, int *val, int id) +{ + *val ^= 1; + CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); + saveconfig(); +} + +void win_cdrom_eject(uint8_t id) +{ + HMENU hmenu; + hmenu = GetSubMenu(smenu, id + 4); + if (cdrom_drives[id].host_drive == 0) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + cdrom_null_open(id, 0); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].host_drive=0; + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); + update_status_bar_icon_state(0x10 | id, get_cd_state(id)); + update_tip(0x10 | id); + saveconfig(); +} + +void win_cdrom_reload(uint8_t id) +{ + HMENU hmenu; + hmenu = GetSubMenu(smenu, id + 4); + int new_cdrom_drive; + if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + cdrom_close(id); + if (cdrom_drives[id].prev_host_drive == 200) + { + image_open(id, cdrom_image[id].image_path); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); + } + else + { + new_cdrom_drive = cdrom_drives[id].prev_host_drive; + ioctl_open(id, new_cdrom_drive); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); + cdrom_drive = new_cdrom_drive; + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); + } + update_status_bar_icon_state(0x10 | id, get_cd_state(id)); + update_tip(0x10 | id); + saveconfig(); +} + +static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + + switch (message) + { + case WM_INITDIALOG: + pause = 1; + h = GetDlgItem(hdlg, IDC_ABOUT_ICON); + SendMessage(h, STM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM) LoadIconBig((PCTSTR) 100)); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + default: + break; + } + break; + } + + return FALSE; +} + +void about_open(HWND hwnd) +{ + DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); +} + +LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + HMENU hmenu; + RECT rect; + uint32_t ri_size = 0; + int edgex, edgey; + int sb_borders[3]; + + switch (message) + { + case WM_CREATE: + SetTimer(hwnd, TIMER_1SEC, 1000, NULL); + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + break; + + case WM_COMMAND: + hmenu=GetMenu(hwnd); + switch (LOWORD(wParam)) + { + case IDM_FILE_HRESET: + pause=1; + Sleep(100); + savenvr(); + saveconfig(); + resetpchard(); + pause=0; + break; + case IDM_FILE_RESET_CAD: + pause=1; + Sleep(100); + savenvr(); + saveconfig(); + resetpc_cad(); + pause=0; + break; + case IDM_FILE_EXIT: + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; + case IDM_CONFIG: + win_settings_open(hwnd); + break; + case IDM_ABOUT: + about_open(hwnd); + break; + case IDM_STATUS: + status_open(hwnd); + break; + + case IDM_VID_RESIZE: + vid_resize=!vid_resize; + CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); + if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); + else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); + SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); + GetWindowRect(hwnd,&rect); + SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + GetWindowRect(hwndStatus,&rect); + SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + if (vid_resize) + { + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + } + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + win_doresize = 1; + saveconfig(); + break; + case IDM_VID_REMEMBER: + window_remember = !window_remember; + CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); + GetWindowRect(hwnd, &rect); + if (window_remember) + { + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + } + saveconfig(); + break; + + case IDM_VID_DDRAW: case IDM_VID_D3D: + startblit(); + video_wait_for_blit(); + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); + vid_apis[0][vid_api].close(); + vid_api = LOWORD(wParam) - IDM_VID_DDRAW; + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); + vid_apis[0][vid_api].init(hwndRender); + endblit(); + saveconfig(); + device_force_redraw(); + break; + + case IDM_VID_FULLSCREEN: + + if(video_fullscreen!=1){ + + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + msgbox_info(ghwnd, 2193); + } + startblit(); + video_wait_for_blit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(ghwnd); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + device_force_redraw(); + } + break; + + case IDM_VID_FS_FULL: + case IDM_VID_FS_43: + case IDM_VID_FS_SQ: + case IDM_VID_FS_INT: + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); + video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); + saveconfig(); + break; + + case IDM_VID_SCALE_1X: + case IDM_VID_SCALE_2X: + case IDM_VID_SCALE_3X: + case IDM_VID_SCALE_4X: + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + scale = LOWORD(wParam) - IDM_VID_SCALE_1X; + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + saveconfig(); + break; + + case IDM_VID_FORCE43: + video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); + break; + + case IDM_VID_INVERT: + video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); + break; + + case IDM_VID_OVERSCAN: + video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); + update_overscan = 1; + break; + + case IDM_VID_FLASH: + video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); + break; + + case IDM_VID_SCREENSHOT: + take_screenshot(); + break; + +#ifdef ENABLE_LOG_TOGGLES +#ifdef ENABLE_BUSLOGIC_LOG + case IDM_LOG_BUSLOGIC: + buslogic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_CDROM_LOG + case IDM_LOG_CDROM: + cdrom_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_D86F_LOG + case IDM_LOG_D86F: + d86f_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_FDC_LOG + case IDM_LOG_FDC: + fdc_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_IDE_LOG + case IDM_LOG_IDE: + ide_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_NE2000_LOG + case IDM_LOG_NE2000: + ne2000_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif +#endif + +#ifdef ENABLE_LOG_BREAKPOINT + case IDM_LOG_BREAKPOINT: + pclog("---- LOG BREAKPOINT ----\n"); + break; +#endif + +#ifdef ENABLE_VRAM_DUMP + case IDM_DUMP_VRAM: + svga_dump_vram(); + break; +#endif + + case IDM_CONFIG_LOAD: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 0)) + { + if (msgbox_reset_yn(ghwnd) == IDYES) + { + config_save(config_file_default); + loadconfig(wopenfilestring); + pclog_w(L"NVR path: %s\n", nvr_path); + mem_resize(); + loadbios(); + resetpchard(); + } + } + pause = 0; + break; + + case IDM_CONFIG_SAVE: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 1)) + config_save(wopenfilestring); + pause = 0; + break; + } + return 0; + + case WM_INPUT: + { + UINT size; + RAWINPUT *raw; + + if (!infocus) + break; + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + + raw = malloc(size); + + if (raw == NULL) + { + return 0; + } + + /* Here we read the raw input data for the keyboard */ + ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); + + if(ri_size != size) + { + return 0; + } + + /* If the input is keyboard, we process it */ + if (raw->header.dwType == RIM_TYPEKEYBOARD) + { + const RAWKEYBOARD rawKB = raw->data.keyboard; + USHORT scancode = rawKB.MakeCode; + + /* If it's not a scan code that starts with 0xE1 */ + if (!(rawKB.Flags & RI_KEY_E1)) + { + if (rawKB.Flags & RI_KEY_E0) + scancode |= (0xE0 << 8); + + /* Remap it according to the list from the Registry */ + scancode = scancode_map[scancode]; + + if ((scancode >> 8) == 0xF0) + scancode |= 0x100; /* Extended key code in disambiguated format */ + else if ((scancode >> 8) == 0xE0) + scancode |= 0x80; /* Normal extended key code */ + + /* If it's not 0 (therefore not 0xE1, 0xE2, etc), + then pass it on to the rawinputkey array */ + if (!(scancode & 0xf00)) + { + rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + } + } + else + { + if (rawKB.MakeCode == 0x1D) + scancode = 0xFF; + if (!(scancode & 0xf00)) + { + rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + } + } + } + free(raw); + + } + break; + + case WM_SETFOCUS: + infocus=1; + if (!hook_enabled) + { + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: + infocus=0; + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture=0; + } + memset(rawinputkey, 0, sizeof(rawinputkey)); + if (video_fullscreen) + leave_fullscreen_flag = 1; + if (hook_enabled) + { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; + + case WM_LBUTTONUP: + if (!mousecapture && !video_fullscreen) + { + RECT pcclip; + + GetClipCursor(&oldclip); + GetWindowRect(hwnd, &pcclip); + pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; + pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + ClipCursor(&pcclip); + mousecapture = 1; + while (1) + { + if (ShowCursor(FALSE) < 0) break; + } + } + break; + + case WM_MBUTTONUP: + if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + releasemouse(); + break; + + case WM_ENTERMENULOOP: + break; + + case WM_SIZE: + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + MoveWindow(hwndRender, 0, 0, + winsizex, + winsizey, + TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) + { + startblit(); + video_wait_for_blit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + endblit(); + } + + MoveWindow(hwndStatus, 0, winsizey + 6, + winsizex, + 17, + TRUE); + + if (mousecapture) + { + RECT pcclip; + + GetWindowRect(hwnd, &pcclip); + pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; + pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; + ClipCursor(&pcclip); + } + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_MOVE: + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_TIMER: + if (wParam == TIMER_1SEC) + onesec(); + break; + + case WM_RESETD3D: + startblit(); + if (video_fullscreen) + d3d_fs_reset(); + else + d3d_reset(); + endblit(); + break; + + case WM_LEAVEFULLSCREEN: + startblit(); + mouse_close(); + vid_apis[1][vid_api].close(); + video_fullscreen = 0; + vid_apis[0][vid_api].init(ghwnd); + mouse_init(); + endblit(); + device_force_redraw(); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + return 0; + + case WM_DESTROY: + UnhookWindowsHookEx( hKeyboardHook ); + KillTimer(hwnd, TIMER_1SEC); + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; + + case WM_SYSCOMMAND: + /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) + return 0; /*disable ALT key for menu*/ + + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } + return 0; +} + +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; +} + +VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) +{ + HMENU pmenu; + int menu_id = -1; + if (id >= (sb_parts - 1)) + { + return; + } + pt.x = id * sb_icon_width; /* Justify to the left. */ + pt.y = 0; /* Justify to the top. */ + ClientToScreen(hwnd, (LPPOINT) &pt); + if ((sb_part_meanings[id] & 0x30) == 0x00) + { + menu_id = sb_part_meanings[id] & 0xf; + } + else if ((sb_part_meanings[id] & 0x30) == 0x10) + { + menu_id = (sb_part_meanings[id] & 0xf) + 4; + } + if (menu_id != -1) + { + pmenu = GetSubMenu(smenu, menu_id); + TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); + } +} + +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + RECT rc; + POINT pt; + + WCHAR temp_image_path[1024]; + int new_cdrom_drive; + int cdrom_id = 0; + int menu_sub_param = 0; + int menu_super_param = 0; + int ret = 0; + + HMENU hmenu; + + switch (message) + { + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDM_DISC_1: + case IDM_DISC_1_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); + if (!ret) + { + disc_close(0); + ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; + disc_load(0, wopenfilestring); + update_status_bar_icon_state(0x00, 0); + update_tip(0x00); + saveconfig(); + } + break; + case IDM_DISC_2: + case IDM_DISC_2_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); + if (!ret) + { + disc_close(1); + ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; + disc_load(1, wopenfilestring); + update_status_bar_icon_state(0x01, 0); + update_tip(0x01); + saveconfig(); + } + break; + case IDM_DISC_3: + case IDM_DISC_3_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); + if (!ret) + { + disc_close(2); + ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; + disc_load(2, wopenfilestring); + update_status_bar_icon_state(0x02, 0); + update_tip(0x02); + saveconfig(); + } + break; + case IDM_DISC_4: + case IDM_DISC_4_WP: + ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); + if (!ret) + { + disc_close(3); + ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; + disc_load(3, wopenfilestring); + update_status_bar_icon_state(0x03, 0); + update_tip(0x03); + saveconfig(); + } + break; + case IDM_EJECT_1: + disc_close(0); + update_status_bar_icon_state(0x00, 1); + update_tip(0x00); + saveconfig(); + break; + case IDM_EJECT_2: + disc_close(1); + update_status_bar_icon_state(0x01, 1); + update_tip(0x01); + saveconfig(); + break; + case IDM_EJECT_3: + disc_close(2); + update_status_bar_icon_state(0x02, 1); + update_tip(0x02); + saveconfig(); + break; + case IDM_EJECT_4: + disc_close(3); + update_status_bar_icon_state(0x03, 1); + update_tip(0x03); + saveconfig(); + break; + + case IDM_CDROM_1_MUTE: + case IDM_CDROM_2_MUTE: + case IDM_CDROM_3_MUTE: + case IDM_CDROM_4_MUTE: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + Sleep(100); + cdrom_drives[cdrom_id].sound_on ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); + saveconfig(); + sound_cd_thread_reset(); + break; + + case IDM_CDROM_1_EMPTY: + case IDM_CDROM_2_EMPTY: + case IDM_CDROM_3_EMPTY: + case IDM_CDROM_4_EMPTY: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + win_cdrom_eject(cdrom_id); + break; + + case IDM_CDROM_1_RELOAD: + case IDM_CDROM_2_RELOAD: + case IDM_CDROM_3_RELOAD: + case IDM_CDROM_4_RELOAD: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + win_cdrom_reload(cdrom_id); + break; + + case IDM_CDROM_1_IMAGE: + case IDM_CDROM_2_IMAGE: + case IDM_CDROM_3_IMAGE: + case IDM_CDROM_4_IMAGE: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) + { + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + { + /* Switching from image to the same image. Do nothing. */ + break; + } + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + image_open(cdrom_id, temp_image_path); + if (cdrom_drives[cdrom_id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(cdrom_id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); + } + cdrom_drives[cdrom_id].host_drive = 200; + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); + update_tip(0x10 | cdrom_id); + saveconfig(); + } + break; + + default: + cdrom_id = LOWORD(wParam) & 3; + hmenu = GetSubMenu(smenu, cdrom_id + 4); + menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; + /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ + if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) + { + new_cdrom_drive = menu_sub_param; + if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) + { + /* Switching to the same drive. Do nothing. */ + break; + } + cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; + cdrom_drives[cdrom_id].handler->exit(cdrom_id); + cdrom_close(cdrom_id); + ioctl_open(cdrom_id, new_cdrom_drive); + if (cdrom_drives[cdrom_id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(cdrom_id); + } + CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); + if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) + { + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); + } + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); + cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; + CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); + update_tip(0x10 | cdrom_id); + saveconfig(); + } + break; + } + return 0; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + GetClientRect(hwnd, (LPRECT)& rc); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + if (PtInRect((LPRECT) &rc, pt)) + { + HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); + } + break; + + default: + return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); + } + return 0; +} diff --git a/src/WIN/win.h b/src/WIN/win.h new file mode 100644 index 000000000..0e09db88f --- /dev/null +++ b/src/WIN/win.h @@ -0,0 +1,51 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +extern HINSTANCE hinstance; +extern HWND ghwnd; +extern int mousecapture; + +#ifdef __cplusplus +extern "C" { +#endif + +#define szClassName L"86BoxMainWnd" +#define szSubClassName L"86BoxSubWnd" +#define szStatusBarClassName L"86BoxStatusBar" + +void leave_fullscreen(); + +#ifdef __cplusplus +} +#endif + + +void status_open(HWND hwnd); +extern HWND status_hwnd; +extern int status_is_open; + +void deviceconfig_open(HWND hwnd, struct device_t *device); +void joystickconfig_open(HWND hwnd, int joy_nr, int type); + +extern char openfilestring[260]; +extern WCHAR wopenfilestring[260]; + +int getfile(HWND hwnd, char *f, char *fn); +int getsfile(HWND hwnd, char *f, char *fn); + +void get_executable_name(WCHAR *s, int size); +void set_window_title(WCHAR *s); + +void startblit(); +void endblit(); + +extern int pause; + +void win_settings_open(HWND hwnd); +void win_menu_update(); + +void update_status_bar_panes(HWND hwnds); + +int fdd_type_to_icon(int type); + +extern HWND hwndStatus; diff --git a/src/WIN/win_cgapal.h b/src/WIN/win_cgapal.h new file mode 100644 index 000000000..d6ac7ffd8 --- /dev/null +++ b/src/WIN/win_cgapal.h @@ -0,0 +1,13 @@ +extern PALETTE cgapal; +extern PALETTE cgapal_mono[6]; + +extern uint32_t pal_lookup[256]; + +#ifdef __cplusplus +extern "C" { +#endif +void cgapal_rebuild(); +void destroy_bitmap(BITMAP *b); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_crashdump.c b/src/WIN/win_crashdump.c new file mode 100644 index 000000000..3fee061b3 --- /dev/null +++ b/src/WIN/win_crashdump.c @@ -0,0 +1,185 @@ +/* Copyright holders: Riley + see COPYING for more details + + win_crashdump.c : Windows exception handler to make a crash dump just before a crash happens. +*/ +#define _WIN32_WINNT 0x0501 +#include +#include +#include +#include +#include +#include "../86box.h" +#include "win_crashdump.h" + +PVOID hExceptionHandler; +char* ExceptionHandlerBuffer; +#define ExceptionHandlerBufferSize (10240) + + +LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { + // Win32-specific functions will be used wherever possible, just in case the C stdlib-equivalents try to allocate memory. + // (The Win32-specific functions are generally just wrappers over NT system calls anyway.) + + if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) { + // The exception code is not a fatal exception (highest 4 bits of ntstatus = 0xC) + // Not going to crash, let's not make a crash dump + return EXCEPTION_CONTINUE_SEARCH; + } + + // So, the program is about to crash. Oh no what do? + // Let's create a crash dump file as a debugging-aid. + + // First, get the path to 86Box.exe. + char* CurrentBufferPointer; + GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); + if (GetLastError() != ERROR_SUCCESS) { + // Could not get the full path of 86Box.exe. Just create the file in the current directory. + CurrentBufferPointer = ExceptionHandlerBuffer; + } else { + // Walk through the string backwards looking for the last backslash, so as to remove the "86Box.exe" filename from the string. + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + for (; CurrentBufferPointer > ExceptionHandlerBuffer; CurrentBufferPointer--) { + if (CurrentBufferPointer[0] == '\\') { + // Found the backslash, null terminate the string after it. + CurrentBufferPointer[1] = 0; + break; + } + } + + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + } + + // What would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. + SYSTEMTIME SystemTime; + GetSystemTime(&SystemTime); + sprintf(CurrentBufferPointer, + "86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp", + SystemTime.wYear, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond, + SystemTime.wMilliseconds); + + DWORD Error; + + // Now the filename is in the buffer, the file can be created. + HANDLE hDumpFile = CreateFile( + ExceptionHandlerBuffer, // The filename of the file to open. + GENERIC_WRITE, // The permissions to request. + 0, // Make sure other processes can't touch the crash dump at all while it's open. + NULL, // Leave the security descriptor undefined, it doesn't matter. + OPEN_ALWAYS, // Opens the file if it exists, creates a new file if it doesn't. + FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter. + NULL); // A template file is not being used. + + // Check to make sure the file was actually created. + if (hDumpFile == INVALID_HANDLE_VALUE) { + // CreateFile() failed, so just do nothing more. + return EXCEPTION_CONTINUE_SEARCH; + } + + // Now the file is open, let's write the data we were passed out in a human-readable format. + + // Let's get the name of the module where the exception occured. + HMODULE hMods[1024]; + MODULEINFO modInfo; + HMODULE ipModule = 0; + DWORD cbNeeded; + // Try to get a list of all loaded modules. + if (EnumProcessModules(GetCurrentProcess(), hMods, sizeof(hMods), &cbNeeded)) { + // The list was obtained, walk through each of the modules. + for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { + // For each module, get the module information (base address, size, entry point) + GetModuleInformation(GetCurrentProcess(), hMods[i], &modInfo, sizeof(MODULEINFO)); + // If the exception address is located in the range of where this module is loaded... + if ( + (ExceptionInfo->ExceptionRecord->ExceptionAddress >= modInfo.lpBaseOfDll) && + (ExceptionInfo->ExceptionRecord->ExceptionAddress < (modInfo.lpBaseOfDll + modInfo.SizeOfImage)) + ) { + // ...this is the module we're looking for! + ipModule = hMods[i]; + break; + } + } + } + + // Start to put the crash-dump string into the buffer. + + sprintf(ExceptionHandlerBuffer, + "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" + "" + "Exception details:\r\n" + "Exception NTSTATUS code: 0x%08x\r\n" + "Occured at address: 0x%p", + emulator_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, + + ExceptionInfo->ExceptionRecord->ExceptionCode, + ExceptionInfo->ExceptionRecord->ExceptionAddress); + + + // If we found the module that the exception occured in, get the full path to the module the exception occured at and include it. + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + if (ipModule != 0) { + sprintf(CurrentBufferPointer," ["); + GetModuleFileName(ipModule,&CurrentBufferPointer[2],ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); + if (GetLastError() == ERROR_SUCCESS) { + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(CurrentBufferPointer,"]"); + CurrentBufferPointer += 1; + } + } + + // Continue to create the crash-dump string. + sprintf(CurrentBufferPointer, + "\r\n" + "Number of parameters: %d\r\n" + "Exception parameters: ", + ExceptionInfo->ExceptionRecord->NumberParameters); + + // Add the exception parameters to the crash-dump string. + for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); + } + + CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1]; + + PCONTEXT Registers = ExceptionInfo->ContextRecord; + + #if defined(__i386__) && !defined(__x86_64) + // This binary is being compiled for x86, include a register dump. + sprintf(CurrentBufferPointer, + "\r\n" + "Register dump:\r\n" + "eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n" + "\r\n", + Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip); + #else + // Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition. + sprintf(CurrentBufferPointer,"\r\n"); + #endif + + // The crash-dump string has been created, write it to disk. + WriteFile(hDumpFile, + ExceptionHandlerBuffer, + strlen(ExceptionHandlerBuffer), + NULL, + NULL); + + // Finally, close the file. + CloseHandle(hDumpFile); + + // And return, therefore causing the crash, but only after the crash dump has been created. + + return EXCEPTION_CONTINUE_SEARCH; +} + +void InitCrashDump() { + // An exception handler should not allocate memory, so allocate 10kb for it to use if it gets called, an amount which should be more than enough. + ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize); + // Register the exception handler. Zero first argument means this exception handler gets called last, therefore, crash dump is only made, when a crash is going to happen. + hExceptionHandler = AddVectoredExceptionHandler(0,MakeCrashDump); +} diff --git a/src/WIN/win_crashdump.h b/src/WIN/win_crashdump.h new file mode 100644 index 000000000..8048cd7af --- /dev/null +++ b/src/WIN/win_crashdump.h @@ -0,0 +1,7 @@ +/* Copyright holders: Riley + see COPYING for more details + + win-crashdump.c : Windows crash dump exception handler header file. +*/ + +void InitCrashDump(); \ No newline at end of file diff --git a/src/WIN/win_d3d-fs.cc b/src/WIN/win_d3d-fs.cc new file mode 100644 index 000000000..4e6a367cb --- /dev/null +++ b/src/WIN/win_d3d-fs.cc @@ -0,0 +1,587 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include +#include "../86box.h" +#include "../video/video.h" +#include "win.h" +#include "win_d3d-fs.h" +#include "win_cgapal.h" +#include "resource.h" + + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void device_force_redraw(void); + +static void d3d_fs_init_objects(void); +static void d3d_fs_close_objects(void); +static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h); + +extern "C" void video_blit_complete(void); + + +static LPDIRECT3D9 d3d = NULL; +static LPDIRECT3DDEVICE9 d3ddev = NULL; +static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; +static LPDIRECT3DTEXTURE9 d3dTexture = NULL; +static D3DPRESENT_PARAMETERS d3dpp; + +static HWND d3d_hwnd; +static HWND d3d_device_window; + +static int d3d_fs_w, d3d_fs_h; + +struct CUSTOMVERTEX +{ + FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag + FLOAT tu, tv; +}; + +PALETTE cgapal = +{ + {0,0,0},{0,42,0},{42,0,0},{42,21,0}, + {0,0,0},{0,42,42},{42,0,42},{42,42,42}, + {0,0,0},{21,63,21},{63,21,21},{63,63,21}, + {0,0,0},{21,63,63},{63,21,63},{63,63,63}, + + {0,0,0},{0,0,42},{0,42,0},{0,42,42}, + {42,0,0},{42,0,42},{42,21,00},{42,42,42}, + {21,21,21},{21,21,63},{21,63,21},{21,63,63}, + {63,21,21},{63,21,63},{63,63,21},{63,63,63}, + + {0,0,0},{0,21,0},{0,0,42},{0,42,42}, + {42,0,21},{21,10,21},{42,0,42},{42,0,63}, + {21,21,21},{21,63,21},{42,21,42},{21,63,63}, + {63,0,0},{42,42,0},{63,21,42},{41,41,41}, + + {0,0,0},{0,42,42},{42,0,0},{42,42,42}, + {0,0,0},{0,42,42},{42,0,0},{42,42,42}, + {0,0,0},{0,63,63},{63,0,0},{63,63,63}, + {0,0,0},{0,63,63},{63,0,0},{63,63,63}, +}; + +PALETTE cgapal_mono[6] = +{ + { // 0 - green, 4-color-optimized contrast + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},{0x03,0x39,0x0d},{0x03,0x3c,0x0e}, + {0x00,0x07,0x01},{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, + }, + { // 1 - green, 16-color-optimized contrast + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},{0x02,0x2e,0x0b},{0x02,0x31,0x0b}, + {0x01,0x22,0x08},{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, + }, + { // 2 - amber, 4-color-optimized contrast + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},{0x3f,0x26,0x01},{0x3f,0x2b,0x06}, + {0x0b,0x02,0x00},{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, + }, + { // 3 - amber, 16-color-optimized contrast + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},{0x38,0x1c,0x00},{0x3b,0x1e,0x00}, + {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, + }, + { // 4 - grey, 4-color-optimized contrast + {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, + {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, + }, + { // 5 - grey, 16-color-optimized contrast + {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, + {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, + }, +}; + +uint32_t pal_lookup[256]; + +static CUSTOMVERTEX d3d_verts[] = +{ + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, +}; + +void cgapal_rebuild(void) +{ + int c; + for (c = 0; c < 256; c++) + { + pal_lookup[c] = makecol(video_6to8[cgapal[c].r], video_6to8[cgapal[c].g], video_6to8[cgapal[c].b]); + } + if ((cga_palette > 1) && (cga_palette < 8)) + { + for (c = 0; c < 16; c++) + { + pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + } + } + if (cga_palette == 8) + { + pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); + } +} + +int d3d_fs_init(HWND h) +{ + HRESULT hr; + WCHAR emulator_title[200]; + + d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); + d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); + + cgapal_rebuild(); + + d3d_hwnd = h; + + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + d3d_device_window = CreateWindowEx ( + 0, + szSubClassName, + emulator_title, + WS_POPUP, + CW_USEDEFAULT, + CW_USEDEFAULT, + 640, + 480, + HWND_DESKTOP, + NULL, + NULL, + NULL + ); + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (d3d == NULL) + { + return 0; + } + + memset(&d3dpp, 0, sizeof(d3dpp)); + + d3dpp.Flags = 0; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = d3d_device_window; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.MultiSampleQuality = 0; + d3dpp.EnableAutoDepthStencil = false; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.Windowed = false; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; + d3dpp.BackBufferWidth = d3d_fs_w; + d3dpp.BackBufferHeight = d3d_fs_h; + + hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(hr)) + { + return 0; + } + + d3d_fs_init_objects(); + + video_blit_memtoscreen_func = d3d_fs_blit_memtoscreen; + video_blit_memtoscreen_8_func = d3d_fs_blit_memtoscreen_8; + + return 1; +} + +static void d3d_fs_close_objects(void) +{ + if (d3dTexture) + { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) + { + v_buffer->Release(); + v_buffer = NULL; + } +} + +static void d3d_fs_init_objects(void) +{ + D3DLOCKED_RECT dr; + RECT r; + + d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + 0, + D3DFVF_XYZRHW | D3DFVF_TEX1, + D3DPOOL_MANAGED, + &v_buffer, + NULL); + + d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + + // r.top = r.left = 0; + r.bottom = 2047; + r.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + /* for (y = 0; y < 2048; y++) + { + uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); + memset(p, 0, 2048 * 4); + } */ + + d3dTexture->UnlockRect(0); + + d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); +} + +/*void d3d_resize(int x, int y) +{ + HRESULT hr; + + d3dpp.BackBufferWidth = x; + d3dpp.BackBufferHeight = y; + + d3d_reset(); +}*/ + +void d3d_fs_reset(void) +{ + HRESULT hr; + + memset(&d3dpp, 0, sizeof(d3dpp)); + + d3dpp.Flags = 0; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = d3d_device_window; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.MultiSampleQuality = 0; + d3dpp.EnableAutoDepthStencil = false; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.Windowed = false; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; + d3dpp.BackBufferWidth = d3d_fs_w; + d3dpp.BackBufferHeight = d3d_fs_h; + + hr = d3ddev->Reset(&d3dpp); + + if (hr == D3DERR_DEVICELOST) + return; + + d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + + device_force_redraw(); +} + +void d3d_fs_close(void) +{ + if (d3dTexture) + { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) + { + v_buffer->Release(); + v_buffer = NULL; + } + if (d3ddev) + { + d3ddev->Release(); + d3ddev = NULL; + } + if (d3d) + { + d3d->Release(); + d3d = NULL; + } + DestroyWindow(d3d_device_window); +} + +static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h) +{ + int ratio_w, ratio_h; + switch (video_fullscreen_scale) + { + case FULLSCR_SCALE_FULL: + *l = -0.5; + *t = -0.5; + *r = (window_rect.right - window_rect.left) - 0.5; + *b = (window_rect.bottom - window_rect.top) - 0.5; + break; + case FULLSCR_SCALE_43: + *t = -0.5; + *b = (window_rect.bottom - window_rect.top) - 0.5; + *l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5; + *r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5; + if (*l < -0.5) + { + *l = -0.5; + *r = (window_rect.right - window_rect.left) - 0.5; + *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5; + *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5; + } + break; + case FULLSCR_SCALE_SQ: + *t = -0.5; + *b = (window_rect.bottom - window_rect.top) - 0.5; + *l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5; + *r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5; + if (*l < -0.5) + { + *l = -0.5; + *r = (window_rect.right - window_rect.left) - 0.5; + *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5; + *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5; + } + break; + case FULLSCR_SCALE_INT: + ratio_w = (window_rect.right - window_rect.left) / w; + ratio_h = (window_rect.bottom - window_rect.top) / h; + if (ratio_h < ratio_w) + ratio_w = ratio_h; + *l = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2) - 0.5; + *r = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 0.5; + *t = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2) - 0.5; + *b = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 0.5; + break; + } +} + +static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + HRESULT hr = D3D_OK; + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT window_rect; + int yy; + double l, t, r, b; + + if ((y1 == y2) || (d3dTexture == NULL)) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) + { + RECT lock_rect; + + lock_rect.top = y1; + lock_rect.left = 0; + lock_rect.bottom = y2; + lock_rect.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = y1; yy < y2; yy++) + memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + + video_blit_complete(); + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); + + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + + GetClientRect(d3d_device_window, &window_rect); + d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); + + d3d_verts[0].x = l; + d3d_verts[0].y = t; + d3d_verts[1].x = r; + d3d_verts[1].y = b; + d3d_verts[2].x = l; + d3d_verts[2].y = b; + d3d_verts[3].x = l; + d3d_verts[3].y = t; + d3d_verts[4].x = r; + d3d_verts[4].y = t; + d3d_verts[5].x = r; + d3d_verts[5].y = b; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); + if (hr == D3D_OK) + hr = v_buffer->Unlock(); + + if (hr == D3D_OK) + hr = d3ddev->BeginScene(); + + if (hr == D3D_OK) + { + if (hr == D3D_OK) + d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, d3dTexture); + + if (hr == D3D_OK) + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + if (hr == D3D_OK) + hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); + + if (hr == D3D_OK) + hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, NULL); + + if (hr == D3D_OK) + hr = d3ddev->EndScene(); + } + + if (hr == D3D_OK) + hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) + PostMessage(ghwnd, WM_RESETD3D, 0, 0); +} + +static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) +{ + HRESULT hr = D3D_OK; + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT window_rect; + uint32_t *p; + int xx, yy; + double l, t, r, b; + + if (!h || (d3dTexture == NULL)) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + if (hr == D3D_OK) + { + RECT lock_rect; + + lock_rect.top = 0; + lock_rect.left = 0; + lock_rect.bottom = 2047; + lock_rect.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = 0; yy < h; yy++) + { + p = (uint32_t *) &(((uint8_t *) dr.pBits)[yy * dr.Pitch]); + if ((y + yy) >= 0 && (y + yy) < buffer->h) + { + for (xx = 0; xx < w; xx++) + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + + video_blit_complete(); + + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); + + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + + GetClientRect(d3d_device_window, &window_rect); + d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); + + d3d_verts[0].x = l; + d3d_verts[0].y = t; + d3d_verts[1].x = r; + d3d_verts[1].y = b; + d3d_verts[2].x = l; + d3d_verts[2].y = b; + d3d_verts[3].x = l; + d3d_verts[3].y = t; + d3d_verts[4].x = r; + d3d_verts[4].y = t; + d3d_verts[5].x = r; + d3d_verts[5].y = b; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); + if (hr == D3D_OK) + hr = v_buffer->Unlock(); + + if (hr == D3D_OK) + hr = d3ddev->BeginScene(); + + if (hr == D3D_OK) + { + if (hr == D3D_OK) + d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, d3dTexture); + + if (hr == D3D_OK) + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + if (hr == D3D_OK) + hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); + + if (hr == D3D_OK) + hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, NULL); + + if (hr == D3D_OK) + hr = d3ddev->EndScene(); + } + + if (hr == D3D_OK) + hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) + PostMessage(ghwnd, WM_RESETD3D, 0, 0); +} + +void d3d_fs_take_screenshot(wchar_t *fn) +{ + LPDIRECT3DSURFACE9 d3dSurface = NULL; + + if (!d3dTexture) return; + + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + + d3dSurface->Release(); + d3dSurface = NULL; +} diff --git a/src/WIN/win_d3d-fs.h b/src/WIN/win_d3d-fs.h new file mode 100644 index 000000000..41ca32e21 --- /dev/null +++ b/src/WIN/win_d3d-fs.h @@ -0,0 +1,13 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int d3d_fs_init(HWND h); + void d3d_fs_close(); + void d3d_fs_reset(); + void d3d_fs_resize(int x, int y); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc new file mode 100644 index 000000000..258bcd4f8 --- /dev/null +++ b/src/WIN/win_d3d.cc @@ -0,0 +1,398 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include +#include "win.h" +#include "win_d3d.h" +#include "../video/video.h" +#include "win_cgapal.h" +#include "resource.h" + + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void device_force_redraw(void); +extern "C" void video_blit_complete(void); + + +void d3d_init_objects(void); +void d3d_close_objects(void); +void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +void d3d_blit_memtoscreen_8(int x, int y, int w, int h); + +static LPDIRECT3D9 d3d = NULL; +static LPDIRECT3DDEVICE9 d3ddev = NULL; +static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; +static LPDIRECT3DTEXTURE9 d3dTexture = NULL; +static D3DPRESENT_PARAMETERS d3dpp; + +static HWND d3d_hwnd; + +struct CUSTOMVERTEX +{ + FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag + FLOAT tu, tv; +}; + +static CUSTOMVERTEX d3d_verts[] = +{ + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, +}; + +int d3d_init(HWND h) +{ + HRESULT hr; + + cgapal_rebuild(); + + d3d_hwnd = h; + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + if (d3d == NULL) + { + return 0; + } + + memset(&d3dpp, 0, sizeof(d3dpp)); + + d3dpp.Flags = 0; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = h; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.MultiSampleQuality = 0; + d3dpp.EnableAutoDepthStencil = false; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.Windowed = true; + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + d3dpp.BackBufferWidth = 0; + d3dpp.BackBufferHeight = 0; + + hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); + if (FAILED(hr)) + { + return 0; + } + + d3d_init_objects(); + + video_blit_memtoscreen_func = d3d_blit_memtoscreen; + video_blit_memtoscreen_8_func = d3d_blit_memtoscreen_8; + + return 1; +} + +void d3d_close_objects(void) +{ + if (d3dTexture) + { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) + { + v_buffer->Release(); + v_buffer = NULL; + } +} + +void d3d_init_objects(void) +{ + D3DLOCKED_RECT dr; + RECT r; + + d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + 0, + D3DFVF_XYZRHW | D3DFVF_TEX1, + D3DPOOL_MANAGED, + &v_buffer, + NULL); + + d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); + + // r.top = r.left = 0; + r.bottom = r.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + /* for (y = 0; y < 2048; y++) + { + uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); + memset(p, 0, 2048 * 4); + } */ + + d3dTexture->UnlockRect(0); + + d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); +} + +void d3d_resize(int x, int y) +{ + d3dpp.BackBufferWidth = x; + d3dpp.BackBufferHeight = y; + + d3d_reset(); +} + +void d3d_reset(void) +{ + HRESULT hr; + + memset(&d3dpp, 0, sizeof(d3dpp)); + + d3dpp.Flags = 0; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = d3d_hwnd; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.MultiSampleQuality = 0; + d3dpp.EnableAutoDepthStencil = false; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.Windowed = true; + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; + d3dpp.BackBufferWidth = 0; + d3dpp.BackBufferHeight = 0; + + hr = d3ddev->Reset(&d3dpp); + + if (hr == D3DERR_DEVICELOST) + return; + + d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); + + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + + device_force_redraw(); +} + +void d3d_close(void) +{ + if (d3dTexture) + { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) + { + v_buffer->Release(); + v_buffer = NULL; + } + if (d3ddev) + { + d3ddev->Release(); + d3ddev = NULL; + } + if (d3d) + { + d3d->Release(); + d3d = NULL; + } +} + +void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + HRESULT hr = D3D_OK; + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT r; + int yy; + + if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (y1 == y2) || (y1 < 0) || (y1 > 2048) || (y2 < 0) || (y2 > 2048) || (d3dTexture == NULL)) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + r.top = y1; + r.left = 0; + r.bottom = y2; + r.right = 2047; + + if (hr == D3D_OK) + { + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + for (yy = y1; yy < y2; yy++) + memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + + video_blit_complete(); + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); + + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + + GetClientRect(d3d_hwnd, &r); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer + if (hr == D3D_OK) + hr = v_buffer->Unlock(); // unlock the vertex buffer + + if (hr == D3D_OK) + hr = d3ddev->BeginScene(); + + if (hr == D3D_OK) + { + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, d3dTexture); + + if (hr == D3D_OK) + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + if (hr == D3D_OK) + hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); + + if (hr == D3D_OK) + hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, NULL); + + if (hr == D3D_OK) + hr = d3ddev->EndScene(); + } + + if (hr == D3D_OK) + hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) + PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); +} + +void d3d_blit_memtoscreen_8(int x, int y, int w, int h) +{ + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT r; + uint32_t *p; + int yy, xx; + HRESULT hr = D3D_OK; + + if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (d3dTexture == NULL)) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + r.top = 0; + r.left = 0; + r.bottom = h; + r.right = 2047; + + if (hr == D3D_OK) + { + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); + + for (yy = 0; yy < h; yy++) + { + p = (uint32_t *) &((((uint8_t *) dr.pBits)[yy * dr.Pitch])); + if ((y + yy) >= 0 && (y + yy) < buffer->h) + { + for (xx = 0; xx < w; xx++) + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + video_blit_complete(); + + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); + + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + + GetClientRect(d3d_hwnd, &r); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer + if (hr == D3D_OK) + hr = v_buffer->Unlock(); // unlock the vertex buffer + + if (hr == D3D_OK) + hr = d3ddev->BeginScene(); + + if (hr == D3D_OK) + { + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, d3dTexture); + + if (hr == D3D_OK) + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + if (hr == D3D_OK) + hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); + + if (hr == D3D_OK) + hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, NULL); + + if (hr == D3D_OK) + hr = d3ddev->EndScene(); + } + + if (hr == D3D_OK) + hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) + PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); +} + +void d3d_take_screenshot(wchar_t *fn) +{ + LPDIRECT3DSURFACE9 d3dSurface = NULL; + + if (!d3dTexture) return; + + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + + d3dSurface->Release(); + d3dSurface = NULL; +} diff --git a/src/WIN/win_d3d.h b/src/WIN/win_d3d.h new file mode 100644 index 000000000..7210d454b --- /dev/null +++ b/src/WIN/win_d3d.h @@ -0,0 +1,13 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int d3d_init(HWND h); + void d3d_close(); + void d3d_reset(); + void d3d_resize(int x, int y); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_ddraw-fs.cc b/src/WIN/win_ddraw-fs.cc new file mode 100644 index 000000000..42fd984ed --- /dev/null +++ b/src/WIN/win_ddraw-fs.cc @@ -0,0 +1,338 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "../video/video.h" +#include "win_ddraw-fs.h" +#include "win_ddraw-screenshot.h" +#include "win_cgapal.h" + + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void device_force_redraw(void); + +extern "C" int ddraw_fs_init(HWND h); +extern "C" void ddraw_fs_close(void); + +extern "C" void video_blit_complete(void); + +static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); + +static LPDIRECTDRAW lpdd = NULL; +static LPDIRECTDRAW7 lpdd7 = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; +static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; +static DDSURFACEDESC2 ddsd; + +static HWND ddraw_hwnd; +static int ddraw_w, ddraw_h; + +int ddraw_fs_init(HWND h) +{ + ddraw_w = GetSystemMetrics(SM_CXSCREEN); + ddraw_h = GetSystemMetrics(SM_CYSCREEN); + + cgapal_rebuild(); + + if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) + return 0; + + if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) + return 0; + + lpdd->Release(); + lpdd = NULL; + + atexit(ddraw_fs_close); + + if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_SETFOCUSWINDOW | + DDSCL_CREATEDEVICEWINDOW | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT))) + return 0; + + if (FAILED(lpdd7->SetDisplayMode(ddraw_w, ddraw_h, 32, 0 ,0))) + return 0; + + // memset(&ddsd, 0, sizeof(ddsd)); + // ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd.dwBackBufferCount = 1; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) + return 0; + + ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; + if (FAILED(lpdds_pri->GetAttachedSurface(&ddsd.ddsCaps, &lpdds_back2))) + return 0; + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) + return 0; + + pclog("DDRAW_INIT complete\n"); + ddraw_hwnd = h; + video_blit_memtoscreen_func = ddraw_fs_blit_memtoscreen; + video_blit_memtoscreen_8_func = ddraw_fs_blit_memtoscreen_8; + + return 1; +} + +void ddraw_fs_close(void) +{ + if (lpdds_back2) + { + lpdds_back2->Release(); + lpdds_back2 = NULL; + } + if (lpdds_back) + { + lpdds_back->Release(); + lpdds_back = NULL; + } + if (lpdds_pri) + { + lpdds_pri->Release(); + lpdds_pri = NULL; + } + if (lpdd_clipper) + { + lpdd_clipper->Release(); + lpdd_clipper = NULL; + } + if (lpdd7) + { + lpdd7->Release(); + lpdd7 = NULL; + } +} + +static void ddraw_fs_size(RECT window_rect, RECT *r_dest, int w, int h) +{ + int ratio_w, ratio_h; + switch (video_fullscreen_scale) + { + case FULLSCR_SCALE_FULL: + r_dest->left = 0; + r_dest->top = 0; + r_dest->right = (window_rect.right - window_rect.left) - 1; + r_dest->bottom = (window_rect.bottom - window_rect.top) - 1; + break; + case FULLSCR_SCALE_43: + r_dest->top = 0; + r_dest->bottom = (window_rect.bottom - window_rect.top) - 1; + r_dest->left = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)); + r_dest->right = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 1; + if (r_dest->left < 0) + { + r_dest->left = 0; + r_dest->right = (window_rect.right - window_rect.left) - 1; + r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)); + r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 1; + } + break; + case FULLSCR_SCALE_SQ: + r_dest->top = 0; + r_dest->bottom = (window_rect.bottom - window_rect.top) - 1; + r_dest->left = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)); + r_dest->right = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 1; + if (r_dest->left < 0) + { + r_dest->left = 0; + r_dest->right = (window_rect.right - window_rect.left) - 1; + r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)); + r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 1; + } + break; + case FULLSCR_SCALE_INT: + ratio_w = (window_rect.right - window_rect.left) / w; + ratio_h = (window_rect.bottom - window_rect.top) / h; + if (ratio_h < ratio_w) + ratio_w = ratio_h; + r_dest->left = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2); + r_dest->right = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 1; + r_dest->top = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2); + r_dest->bottom = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 1; + break; + } +} + +static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + RECT r_src; + RECT r_dest; + RECT window_rect; + int yy; + HRESULT hr; + DDBLTFX ddbltfx; + + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back->Restore(); + lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } + for (yy = y1; yy < y2; yy++) + { + if ((y + yy) >= 0) memcpy((unsigned char*)ddsd.lpSurface + (yy * ddsd.lPitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + video_blit_complete(); + lpdds_back->Unlock(NULL); + + window_rect.left = 0; + window_rect.top = 0; + window_rect.right = ddraw_w; + window_rect.bottom = ddraw_h; + ddraw_fs_size(window_rect, &r_dest, w, h); + + r_src.left = 0; + r_src.top = 0; + r_src.right = w; + r_src.bottom = h; + + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = 0; + + lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + + hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + if (readflash && enable_flash) + { + RECT r; + r.left = window_rect.right - 40; + r.right = window_rect.right - 8; + r.top = 8; + r.bottom = 14; + ddbltfx.dwFillColor = 0xffffff; + lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + } + + hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); + if (hr == DDERR_SURFACELOST) + { + lpdds_pri->Restore(); + lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); + } +} + +static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) +{ + RECT r_src; + RECT r_dest; + RECT window_rect; + int xx, yy; + HRESULT hr; + DDBLTFX ddbltfx; + + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + + if (hr == DDERR_SURFACELOST) + { + lpdds_back->Restore(); + lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } + for (yy = 0; yy < h; yy++) + { + if ((y + yy) >= 0 && (y + yy) < buffer->h) + { + uint32_t *p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = 0; xx < w; xx++) + { + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + } + video_blit_complete(); + lpdds_back->Unlock(NULL); + + window_rect.left = 0; + window_rect.top = 0; + window_rect.right = ddraw_w; + window_rect.bottom = ddraw_h; + ddraw_fs_size(window_rect, &r_dest, w, h); + + r_src.left = 0; + r_src.top = 0; + r_src.right = w; + r_src.bottom = h; + + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = 0; + + lpdds_back2->Blt(&window_rect, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + + hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + if (readflash && enable_flash) + { + RECT r; + r.left = window_rect.right - 40; + r.right = window_rect.right - 8; + r.top = 8; + r.bottom = 14; + ddbltfx.dwFillColor = 0xffffff; + lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + } + + lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); +} + +void ddraw_fs_take_screenshot(wchar_t *fn) +{ + ddraw_common_take_screenshot(fn, lpdds_back2); +} diff --git a/src/WIN/win_ddraw-fs.h b/src/WIN/win_ddraw-fs.h new file mode 100644 index 000000000..048c9c160 --- /dev/null +++ b/src/WIN/win_ddraw-fs.h @@ -0,0 +1,11 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int ddraw_fs_init(HWND h); + void ddraw_fs_close(); +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_ddraw-screenshot.cc b/src/WIN/win_ddraw-screenshot.cc new file mode 100644 index 000000000..bb3cb6660 --- /dev/null +++ b/src/WIN/win_ddraw-screenshot.cc @@ -0,0 +1,178 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ +#include +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "../video/video.h" +#include "win.h" +#include "win_ddraw-screenshot.h" +#include "win_language.h" + + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void device_force_redraw(void); + +extern "C" void ddraw_init(HWND h); +extern "C" void ddraw_close(void); + +HBITMAP hbitmap; + +int xs, ys, ys2; + +void CopySurface(IDirectDrawSurface7 *pDDSurface) +{ + HDC hdc, hmemdc; + + HBITMAP hprevbitmap; + + DDSURFACEDESC2 ddsd2; + + pDDSurface->GetDC(&hdc); + + hmemdc = CreateCompatibleDC(hdc); + + ZeroMemory(&ddsd2 ,sizeof( ddsd2 )); // better to clear before using + + ddsd2.dwSize = sizeof( ddsd2 ); //initialize with size + + pDDSurface->GetSurfaceDesc(&ddsd2); + + hbitmap = CreateCompatibleBitmap( hdc ,xs ,ys); + + hprevbitmap = (HBITMAP) SelectObject( hmemdc, hbitmap ); + + BitBlt(hmemdc,0 ,0 ,xs ,ys ,hdc ,0 ,0,SRCCOPY); + + SelectObject(hmemdc,hprevbitmap); // restore the old bitmap + + DeleteDC(hmemdc); + + pDDSurface->ReleaseDC(hdc); + + return ; +} + +void DoubleLines(uint8_t *dst, uint8_t *src) +{ + int i = 0; + for (i = 0; i < ys; i++) + { + memcpy(dst + (i * xs * 8), src + (i * xs * 4), xs * 4); + memcpy(dst + ((i * xs * 8) + (xs * 4)), src + (i * xs * 4), xs * 4); + } +} + +static WCHAR szMessage[2048]; + +void SaveBitmap(wchar_t *szFilename,HBITMAP hBitmap) +{ + HDC hdc=NULL; + FILE* fp=NULL; + LPVOID pBuf=NULL; + LPVOID pBuf2=NULL; + BITMAPINFO bmpInfo; + BITMAPFILEHEADER bmpFileHeader; + + do{ + + hdc=GetDC(NULL); + + ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); + + bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); + + GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); + + if(bmpInfo.bmiHeader.biSizeImage<=0) + bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8; + + if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL) + { + // pclog("ERROR: Unable to Allocate Bitmap Memory"); + break; + } + + if (ys2 <= 250) + { + pBuf2 = malloc(bmpInfo.bmiHeader.biSizeImage * 2); + } + + bmpInfo.bmiHeader.biCompression=BI_RGB; + + GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS); + + if((fp = _wfopen(szFilename,L"wb"))==NULL) + { + _swprintf(szMessage, win_language_get_string_from_id(2194), szFilename); + msgbox_error_wstr(ghwnd, szMessage); + break; + } + + bmpFileHeader.bfReserved1=0; + + bmpFileHeader.bfReserved2=0; + + if (pBuf2) + { + bmpInfo.bmiHeader.biSizeImage <<= 1; + bmpInfo.bmiHeader.biHeight <<= 1; + } + + bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage; + + bmpFileHeader.bfType=0x4D42; + + bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); + + fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp); + + fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp); + + if (pBuf2) + { + DoubleLines((uint8_t *) pBuf2, (uint8_t *) pBuf); + fwrite(pBuf2,bmpInfo.bmiHeader.biSizeImage,1,fp); + } + else + { + fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); + } + + }while(false); + + if(hdc) ReleaseDC(NULL,hdc); + + if(pBuf2) free(pBuf2); + + if(pBuf) free(pBuf); + + if(fp) fclose(fp); +} + +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface) +{ + xs = xsize; + ys = ys2 = ysize; + /* For EGA/(S)VGA, the size is NOT adjusted for overscan. */ + if ((overscan_y > 16) && enable_overscan) + { + xs += overscan_x; + ys += overscan_y; + } + /* For CGA, the width is adjusted for overscan, but the height is not. */ + if (overscan_y == 16) + { + if (ys2 <= 250) + ys += (overscan_y >> 1); + else + ys += overscan_y; + } + CopySurface(pDDSurface); + SaveBitmap(fn, hbitmap); +} diff --git a/src/WIN/win_ddraw-screenshot.h b/src/WIN/win_ddraw-screenshot.h new file mode 100644 index 000000000..4739174a1 --- /dev/null +++ b/src/WIN/win_ddraw-screenshot.h @@ -0,0 +1,4 @@ +/* Copyright holders: Tenshi + see COPYING for more details +*/ +void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc new file mode 100644 index 000000000..af329eb29 --- /dev/null +++ b/src/WIN/win_ddraw.cc @@ -0,0 +1,318 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#undef BITMAP +#include "../video/video.h" +#include "win_ddraw.h" +#include "win_ddraw-screenshot.h" +#include "win_cgapal.h" + + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void device_force_redraw(void); + +extern "C" int ddraw_init(HWND h); +extern "C" void ddraw_close(void); + +extern "C" void video_blit_complete(void); + +static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); +static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h); + +static LPDIRECTDRAW lpdd = NULL; +static LPDIRECTDRAW7 lpdd7 = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; +static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; +static DDSURFACEDESC2 ddsd; + +static HWND ddraw_hwnd; + +int ddraw_init(HWND h) +{ + cgapal_rebuild(); + + if (FAILED(DirectDrawCreate(NULL, &lpdd, NULL))) + return 0; + + if (FAILED(lpdd->QueryInterface(IID_IDirectDraw7, (LPVOID *)&lpdd7))) + return 0; + + lpdd->Release(); + lpdd = NULL; + + atexit(ddraw_close); + + if (FAILED(lpdd7->SetCooperativeLevel(h, DDSCL_NORMAL))) + return 0; + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_pri, NULL))) + return 0; + + // memset(&ddsd, 0, sizeof(ddsd)); + // ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) + return 0; + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) + return 0; + + if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL))) + return 0; + if (FAILED(lpdd_clipper->SetHWnd(0, h))) + return 0; + if (FAILED(lpdds_pri->SetClipper(lpdd_clipper))) + return 0; + + pclog("DDRAW_INIT complete\n"); + ddraw_hwnd = h; + video_blit_memtoscreen_func = ddraw_blit_memtoscreen; + video_blit_memtoscreen_8_func = ddraw_blit_memtoscreen_8; + + return 1; +} + +void ddraw_close(void) +{ + if (lpdds_back2) + { + lpdds_back2->Release(); + lpdds_back2 = NULL; + } + if (lpdds_back) + { + lpdds_back->Release(); + lpdds_back = NULL; + } + if (lpdds_pri) + { + lpdds_pri->Release(); + lpdds_pri = NULL; + } + if (lpdd_clipper) + { + lpdd_clipper->Release(); + lpdd_clipper = NULL; + } + if (lpdd7) + { + lpdd7->Release(); + lpdd7 = NULL; + } +} + +static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) +{ + RECT r_src; + RECT r_dest; + int xx, yy; + POINT po; + uint32_t *p; + HRESULT hr; +// pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); + + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back->Restore(); + lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } + for (yy = y1; yy < y2; yy++) + { + if ((y + yy) >= 0 && (y + yy) < buffer->h) + memcpy((uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4); + } + video_blit_complete(); + lpdds_back->Unlock(NULL); + + po.x = po.y = 0; + + ClientToScreen(ddraw_hwnd, &po); + GetClientRect(ddraw_hwnd, &r_dest); + OffsetRect(&r_dest, po.x, po.y); + + r_src.left = 0; + r_src.top = 0; + r_src.right = w; + r_src.bottom = h; + + hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + if (readflash) + { + readflash = 0; +#ifdef LEGACY_READ_FLASH + if (enable_flash) + { + hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) return; + for (yy = 8; yy < 14; yy++) + { + p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = (w - 40); xx < (w - 8); xx++) + p[xx] = 0xffffffff; + } + } +#endif + } + lpdds_back2->Unlock(NULL); + +// pclog("Blit from %i,%i %i,%i to %i,%i %i,%i\n", r_src.left, r_src.top, r_src.right, r_src.bottom, r_dest.left, r_dest.top, r_dest.right, r_dest.bottom); + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_pri->Restore(); + lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + } +} + +static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) +{ + RECT r_src; + RECT r_dest; + int xx, yy; + POINT po; + uint32_t *p; + HRESULT hr; + + if (lpdds_back == NULL) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + hr = lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + + if (hr == DDERR_SURFACELOST) + { + lpdds_back->Restore(); + lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) + { + video_blit_complete(); + return; + } + for (yy = 0; yy < h; yy++) + { + if ((y + yy) >= 0 && (y + yy) < buffer->h) + { + p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = 0; xx < w; xx++) + { + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + } + p = &(((uint32_t *) ddsd.lpSurface)[4 * ddsd.lPitch]); + lpdds_back->Unlock(NULL); + video_blit_complete(); + + po.x = po.y = 0; + + ClientToScreen(ddraw_hwnd, &po); + GetClientRect(ddraw_hwnd, &r_dest); + OffsetRect(&r_dest, po.x, po.y); + + r_src.left = 0; + r_src.top = 0; + r_src.right = w; + r_src.bottom = h; + + hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + if (readflash) + { + readflash = 0; + if (enable_flash) + { + hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_back2->Restore(); + lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); + device_force_redraw(); + } + if (!ddsd.lpSurface) return; + for (yy = 8; yy < 14; yy++) + { + p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); + for (xx = (w - 40); xx < (w - 8); xx++) + p[xx] = 0xffffffff; + } + lpdds_back2->Unlock(NULL); + } + } + + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) + { + lpdds_pri->Restore(); + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + } +} + +void ddraw_take_screenshot(wchar_t *fn) +{ + ddraw_common_take_screenshot(fn, lpdds_back2); +} diff --git a/src/WIN/win_ddraw.h b/src/WIN/win_ddraw.h new file mode 100644 index 000000000..a4044899d --- /dev/null +++ b/src/WIN/win_ddraw.h @@ -0,0 +1,12 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifdef __cplusplus +extern "C" { +#endif + int ddraw_init(HWND h); + void ddraw_close(); +#ifdef __cplusplus +} +#endif + diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c new file mode 100644 index 000000000..457a38f75 --- /dev/null +++ b/src/WIN/win_deviceconfig.c @@ -0,0 +1,317 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include "../ibm.h" +#include "../config.h" +#include "../device.h" +#include "resource.h" +#include "win.h" + +static device_t *config_device; + +static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int val_int; + int num; + char s[80]; + + switch (message) + { + case WM_INITDIALOG: + { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + + while (config->type != -1) + { + device_config_selection_t *selection = config->selection; + h = GetDlgItem(hdlg, id); + + switch (config->type) + { + case CONFIG_BINARY: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + SendMessage(h, BM_SETCHECK, val_int, 0); + + id++; + break; + + case CONFIG_SELECTION: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + c = 0; + while (selection->description[0]) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); + if (val_int == selection->value) + SendMessage(h, CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; + } + config++; + } + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + { + int id = IDC_CONFIG_BASE; + device_config_t *config = config_device->config; + int c; + int changed = 0; + + while (config->type != -1) + { + device_config_selection_t *selection = config->selection; + h = GetDlgItem(hdlg, id); + + switch (config->type) + { + case CONFIG_BINARY: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) + changed = 1; + + id++; + break; + + case CONFIG_SELECTION: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; + } + config++; + } + + if (!changed) + { + EndDialog(hdlg, 0); + return TRUE; + } + + if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) != IDOK) + { + EndDialog(hdlg, 0); + return TRUE; + } + + id = IDC_CONFIG_BASE; + config = config_device->config; + + while (config->type != -1) + { + device_config_selection_t *selection = config->selection; + h = GetDlgItem(hdlg, id); + + switch (config->type) + { + case CONFIG_BINARY: + config_set_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0)); + + id++; + break; + + case CONFIG_SELECTION: + c = SendMessage(h, CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_int(config_device->name, config->name, selection->value); + + id += 2; + break; + } + config++; + } + + saveconfig(); + + resetpchard(); + + EndDialog(hdlg, 0); + return TRUE; + } + case IDCANCEL: + EndDialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + +void deviceconfig_open(HWND hwnd, device_t *device) +{ + device_config_t *config = device->config; + uint16_t *data_block = malloc(16384); + uint16_t *data; + DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block; + DLGITEMTEMPLATE *item; + int y = 10; + int id = IDC_CONFIG_BASE; + + memset(data_block, 0, 4096); + + dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; + dlg->x = 10; + dlg->y = 10; + dlg->cx = 220; + dlg->cy = 70; + + data = (uint16_t *)(dlg + 1); + + *data++ = 0; /*no menu*/ + *data++ = 0; /*predefined dialog box class*/ + data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50); + + *data++ = 8; /*Point*/ + data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); + + if (((unsigned long)data) & 2) + data++; + + while (config->type != -1) + { + switch (config->type) + { + case CONFIG_BINARY: + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 80; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); + *data++ = 0; /* no creation data */ + + y += 20; + break; + + case CONFIG_SELECTION: + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 150; + + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0085; /* combo box class */ + + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, config->description, -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + y += 20; + break; + } + + if (((unsigned long)data) & 2) + data++; + + config++; + } + + dlg->cdit = (id - IDC_CONFIG_BASE) + 2; + + item = (DLGITEMTEMPLATE *)data; + item->x = 20; + item->y = y; + item->cx = 50; + item->cy = 14; + item->id = IDOK; /* OK button identifier */ + item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + item = (DLGITEMTEMPLATE *)data; + item->x = 80; + item->y = y; + item->cx = 50; + item->cy = 14; + item->id = IDCANCEL; /* OK button identifier */ + item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); + *data++ = 0; /* no creation data */ + + dlg->cy = y + 20; + + config_device = device; + + DialogBoxIndirect(hinstance, dlg, hwnd, deviceconfig_dlgproc); + + free(data_block); +} diff --git a/src/WIN/win_joystick.cc b/src/WIN/win_joystick.cc new file mode 100644 index 000000000..63d970eaa --- /dev/null +++ b/src/WIN/win_joystick.cc @@ -0,0 +1,281 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define DIRECTINPUT_VERSION 0x0800 +#include +#include +#include +extern "C" { +#include "../device.h" +#include "../gameport.h" +} +#include "plat_joystick.h" +#include "win.h" + +extern "C" int video_fullscreen; + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void joystick_init(); +extern "C" void joystick_close(); +extern "C" void poll_joystick(); + +plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS]; +joystick_t joystick_state[MAX_JOYSTICKS]; + +static LPDIRECTINPUT8 lpdi; +static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = {NULL, NULL}; + +int joysticks_present = 0; +static GUID joystick_guids[MAX_JOYSTICKS]; + +static BOOL CALLBACK joystick_enum_callback(LPCDIDEVICEINSTANCE lpddi, LPVOID data) +{ + if (joysticks_present >= MAX_JOYSTICKS) + return DIENUM_STOP; + + pclog("joystick_enum_callback : found joystick %i : %s\n", joysticks_present, lpddi->tszProductName); + + joystick_guids[joysticks_present++] = lpddi->guidInstance; + + if (joysticks_present >= MAX_JOYSTICKS) + return DIENUM_STOP; + + return DIENUM_CONTINUE; +} + +BOOL CALLBACK DIEnumDeviceObjectsCallback( + LPCDIDEVICEOBJECTINSTANCE lpddoi, + LPVOID pvRef) +{ + plat_joystick_t *state = (plat_joystick_t *)pvRef; + + if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis || + lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis || + lpddoi->guidType == GUID_Slider) + { + strncpy(state->axis[state->nr_axes].name, lpddoi->tszName, sizeof(state->axis[state->nr_axes].name)); + pclog("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType); + if (lpddoi->guidType == GUID_XAxis) + state->axis[state->nr_axes].id = 0; + else if (lpddoi->guidType == GUID_YAxis) + state->axis[state->nr_axes].id = 1; + else if (lpddoi->guidType == GUID_ZAxis) + state->axis[state->nr_axes].id = 2; + else if (lpddoi->guidType == GUID_RxAxis) + state->axis[state->nr_axes].id = 3; + else if (lpddoi->guidType == GUID_RyAxis) + state->axis[state->nr_axes].id = 4; + else if (lpddoi->guidType == GUID_RzAxis) + state->axis[state->nr_axes].id = 5; + state->nr_axes++; + } + else if (lpddoi->guidType == GUID_Button) + { + strncpy(state->button[state->nr_buttons].name, lpddoi->tszName, sizeof(state->button[state->nr_buttons].name)); + pclog("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType); + state->nr_buttons++; + } + else if (lpddoi->guidType == GUID_POV) + { + strncpy(state->pov[state->nr_povs].name, lpddoi->tszName, sizeof(state->pov[state->nr_povs].name)); + pclog("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType); + state->nr_povs++; + } + + return DIENUM_CONTINUE; +} + +void joystick_init() +{ + int c; + + if (joystick_type == 7) return; + + atexit(joystick_close); + + joysticks_present = 0; + + if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL))) + fatal("joystick_init : DirectInputCreate failed\n"); + + if (FAILED(lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, joystick_enum_callback, NULL, DIEDFL_ATTACHEDONLY))) + fatal("joystick_init : EnumDevices failed\n"); + + pclog("joystick_init: joysticks_present=%i\n", joysticks_present); + + for (c = 0; c < joysticks_present; c++) + { + LPDIRECTINPUTDEVICE8 lpdi_joystick_temp = NULL; + DIPROPRANGE joy_axis_range; + DIDEVICEINSTANCE device_instance; + DIDEVCAPS devcaps; + + if (FAILED(lpdi->CreateDevice(joystick_guids[c], &lpdi_joystick_temp, NULL))) + fatal("joystick_init : CreateDevice failed\n"); + if (FAILED(lpdi_joystick_temp->QueryInterface(IID_IDirectInputDevice8, (void **)&lpdi_joystick[c]))) + fatal("joystick_init : CreateDevice failed\n"); + lpdi_joystick_temp->Release(); + + memset(&device_instance, 0, sizeof(device_instance)); + device_instance.dwSize = sizeof(device_instance); + if (FAILED(lpdi_joystick[c]->GetDeviceInfo(&device_instance))) + fatal("joystick_init : GetDeviceInfo failed\n"); + pclog("Joystick %i :\n", c); + pclog(" tszInstanceName = %s\n", device_instance.tszInstanceName); + pclog(" tszProductName = %s\n", device_instance.tszProductName); + strncpy(plat_joystick_state[c].name, device_instance.tszInstanceName, 64); + + memset(&devcaps, 0, sizeof(devcaps)); + devcaps.dwSize = sizeof(devcaps); + if (FAILED(lpdi_joystick[c]->GetCapabilities(&devcaps))) + fatal("joystick_init : GetCapabilities failed\n"); + pclog(" Axes = %i\n", devcaps.dwAxes); + pclog(" Buttons = %i\n", devcaps.dwButtons); + pclog(" POVs = %i\n", devcaps.dwPOVs); + + lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL); + + if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(ghwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE))) + fatal("joystick_init : SetCooperativeLevel failed\n"); + if (FAILED(lpdi_joystick[c]->SetDataFormat(&c_dfDIJoystick))) + fatal("joystick_init : SetDataFormat failed\n"); + + joy_axis_range.lMin = -32768; + joy_axis_range.lMax = 32767; + joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE); + joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); + joy_axis_range.diph.dwHow = DIPH_BYOFFSET; + joy_axis_range.diph.dwObj = DIJOFS_X; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_Y; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_Z; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_RX; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_RY; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + joy_axis_range.diph.dwObj = DIJOFS_RZ; + lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph); + + if (FAILED(lpdi_joystick[c]->Acquire())) + fatal("joystick_init : Acquire failed\n"); + } +} + +void joystick_close() +{ + if (lpdi_joystick[1]) + { + lpdi_joystick[1]->Release(); + lpdi_joystick[1] = NULL; + } + if (lpdi_joystick[0]) + { + lpdi_joystick[0]->Release(); + lpdi_joystick[0] = NULL; + } +} + +static int joystick_get_axis(int joystick_nr, int mapping) +{ + if (mapping & POV_X) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return sin((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else if (mapping & POV_Y) + { + int pov = plat_joystick_state[joystick_nr].p[mapping & 3]; + + if (LOWORD(pov) == 0xFFFF) + return 0; + else + return -cos((2*M_PI * (double)pov) / 36000.0) * 32767; + } + else + return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id]; +} + +void joystick_poll() +{ + int c, d; + + for (c = 0; c < joysticks_present; c++) + { + DIJOYSTATE joystate; + int b; + + if (FAILED(lpdi_joystick[c]->Poll())) + { + lpdi_joystick[c]->Acquire(); + lpdi_joystick[c]->Poll(); + } + if (FAILED(lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate))) + { + lpdi_joystick[c]->Acquire(); + lpdi_joystick[c]->Poll(); + lpdi_joystick[c]->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joystate); + } + + plat_joystick_state[c].a[0] = joystate.lX; + plat_joystick_state[c].a[1] = joystate.lY; + plat_joystick_state[c].a[2] = joystate.lZ; + plat_joystick_state[c].a[3] = joystate.lRx; + plat_joystick_state[c].a[4] = joystate.lRy; + plat_joystick_state[c].a[5] = joystate.lRz; + + for (b = 0; b < 16; b++) + plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80; + + for (b = 0; b < 4; b++) + plat_joystick_state[c].p[b] = joystate.rgdwPOV[b]; +// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present); + } + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + if (joystick_state[c].plat_joystick_nr) + { + int joystick_nr = joystick_state[c].plat_joystick_nr - 1; + + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]); + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]]; + + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + int x, y; + double angle, magnitude; + + x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]); + y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]); + + angle = (atan2((double)y, (double)x) * 360.0) / (2*M_PI); + magnitude = sqrt((double)x*(double)x + (double)y*(double)y); + + if (magnitude < 16384) + joystick_state[c].pov[d] = -1; + else + joystick_state[c].pov[d] = ((int)angle + 90 + 360) % 360; + } + } + else + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + joystick_state[c].axis[d] = 0; + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + joystick_state[c].button[d] = 0; + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + joystick_state[c].pov[d] = -1; + } + } +} + diff --git a/src/WIN/win_joystickconfig.c b/src/WIN/win_joystickconfig.c new file mode 100644 index 000000000..8962366d6 --- /dev/null +++ b/src/WIN/win_joystickconfig.c @@ -0,0 +1,541 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include "../ibm.h" +#include "../config.h" +#include "../device.h" +#include "../gameport.h" +#include "plat_joystick.h" +#include "resource.h" +#include "win.h" + +static int joystick_nr; +static int joystick_config_type; +#define AXIS_STRINGS_MAX 3 +static char *axis_strings[AXIS_STRINGS_MAX] = {"X Axis", "Y Axis", "Z Axis"}; + +static void rebuild_axis_button_selections(HWND hdlg) +{ + int id = IDC_CONFIG_BASE + 2; + HWND h; + int joystick; + int c, d; + + h = GetDlgItem(hdlg, IDC_CONFIG_BASE); + joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) + { + int sel = c; + + h = GetDlgItem(hdlg, id); + SendMessage(h, CB_RESETCONTENT, 0, 0); + + if (joystick) + { + for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); + if (c < AXIS_STRINGS_MAX) + { + if (!stricmp(axis_strings[c], plat_joystick_state[joystick-1].axis[d].name)) + sel = d; + } + } + for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++) + { + char s[80]; + + sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + SendMessage(h, CB_SETCURSEL, sel, 0); + EnableWindow(h, TRUE); + } + else + EnableWindow(h, FALSE); + + id += 2; + } + + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = GetDlgItem(hdlg, id); + SendMessage(h, CB_RESETCONTENT, 0, 0); + + if (joystick) + { + for (d = 0; d < plat_joystick_state[joystick-1].nr_buttons; d++) + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].button[d].name); + SendMessage(h, CB_SETCURSEL, c, 0); + EnableWindow(h, TRUE); + } + else + EnableWindow(h, FALSE); + + id += 2; + } + + for (c = 0; c < joystick_get_pov_count(joystick_config_type)*2; c++) + { + int sel = c; + + h = GetDlgItem(hdlg, id); + SendMessage(h, CB_RESETCONTENT, 0, 0); + + if (joystick) + { + for (d = 0; d < plat_joystick_state[joystick-1].nr_povs; d++) + { + char s[80]; + + sprintf(s, "%s (X axis)", plat_joystick_state[joystick-1].pov[d].name); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + } + for (d = 0; d < plat_joystick_state[joystick-1].nr_axes; d++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick-1].axis[d].name); + } + SendMessage(h, CB_SETCURSEL, sel, 0); + EnableWindow(h, TRUE); + } + else + EnableWindow(h, FALSE); + + id += 2; + } + +} + +static int get_axis(HWND hdlg, int id) +{ + HWND h = GetDlgItem(hdlg, id); + int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); + int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_axes; + + if (axis_sel < nr_axes) + return axis_sel; + + axis_sel -= nr_axes; + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); +} + +static int get_pov(HWND hdlg, int id) +{ + HWND h = GetDlgItem(hdlg, id); + int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0); + int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_povs*2; + + if (axis_sel < nr_povs) + { + if (axis_sel & 1) + return POV_Y | (axis_sel >> 1); + else + return POV_X | (axis_sel >> 1); + } + + return axis_sel - nr_povs; +} + +static BOOL CALLBACK joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c; + int id; + int joystick; + int nr_axes; + int nr_povs; + int mapping; + + switch (message) + { + case WM_INITDIALOG: + { + h = GetDlgItem(hdlg, IDC_CONFIG_BASE); + id = IDC_CONFIG_BASE + 2; + joystick = joystick_state[joystick_nr].plat_joystick_nr; + + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)"None"); + + for (c = 0; c < joysticks_present; c++) + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[c].name); + + SendMessage(h, CB_SETCURSEL, joystick, 0); + + rebuild_axis_button_selections(hdlg); + + if (joystick_state[joystick_nr].plat_joystick_nr) + { + nr_axes = plat_joystick_state[joystick-1].nr_axes; + nr_povs = plat_joystick_state[joystick-1].nr_povs; + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) + { + int mapping = joystick_state[joystick_nr].axis_mapping[c]; + + h = GetDlgItem(hdlg, id); + if (mapping & POV_X) + SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2, 0); + else if (mapping & POV_Y) + SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0); + else + SendMessage(h, CB_SETCURSEL, mapping, 0); + id += 2; + } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = GetDlgItem(hdlg, id); + SendMessage(h, CB_SETCURSEL, joystick_state[joystick_nr].button_mapping[c], 0); + id += 2; + } + for (c = 0; c < joystick_get_pov_count(joystick_config_type); c++) + { + h = GetDlgItem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][0]; + if (mapping & POV_X) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0); + else if (mapping & POV_Y) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0); + else + SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0); + id += 2; + h = GetDlgItem(hdlg, id); + mapping = joystick_state[joystick_nr].pov_mapping[c][1]; + if (mapping & POV_X) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2, 0); + else if (mapping & POV_Y) + SendMessage(h, CB_SETCURSEL, (mapping & 3)*2 + 1, 0); + else + SendMessage(h, CB_SETCURSEL, mapping + nr_povs*2, 0); + id += 2; + } + } + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIG_BASE: + if (HIWORD(wParam) == CBN_SELCHANGE) + rebuild_axis_button_selections(hdlg); + break; + + case IDOK: + { + id = IDC_CONFIG_BASE + 2; + + h = GetDlgItem(hdlg, IDC_CONFIG_BASE); + joystick_state[joystick_nr].plat_joystick_nr = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (joystick_state[joystick_nr].plat_joystick_nr) + { + for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++) + { + joystick_state[joystick_nr].axis_mapping[c] = get_axis(hdlg, id); + id += 2; + } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = GetDlgItem(hdlg, id); + joystick_state[joystick_nr].button_mapping[c] = SendMessage(h, CB_GETCURSEL, 0, 0); + id += 2; + } + for (c = 0; c < joystick_get_button_count(joystick_config_type); c++) + { + h = GetDlgItem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][0] = get_pov(hdlg, id); + id += 2; + h = GetDlgItem(hdlg, id); + joystick_state[joystick_nr].pov_mapping[c][1] = get_pov(hdlg, id); + id += 2; + } + } + } + case IDCANCEL: + EndDialog(hdlg, 0); + return TRUE; + } + break; + } + return FALSE; +} + +void joystickconfig_open(HWND hwnd, int joy_nr, int type) +{ + uint16_t *data_block = malloc(16384); + uint16_t *data; + DLGTEMPLATE *dlg = (DLGTEMPLATE *)data_block; + DLGITEMTEMPLATE *item; + int y = 10; + int id = IDC_CONFIG_BASE; + int c; + + joystick_nr = joy_nr; + joystick_config_type = type; + + memset(data_block, 0, 4096); + + dlg->style = DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU; + dlg->x = 10; + dlg->y = 10; + dlg->cx = 220; + dlg->cy = 70; + + data = (uint16_t *)(dlg + 1); + + *data++ = 0; /*no menu*/ + *data++ = 0; /*predefined dialog box class*/ + data += MultiByteToWideChar(CP_ACP, 0, "Device Configuration", -1, data, 50); + + *data++ = 8; /*Point*/ + data += MultiByteToWideChar(CP_ACP, 0, "MS Sans Serif", -1, data, 50); + + if (((unsigned long)data) & 2) + data++; + + + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 150; + + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0085; /* combo box class */ + + data += MultiByteToWideChar(CP_ACP, 0, "Device", -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, "Device :", -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + y += 20; + + + for (c = 0; c < joystick_get_axis_count(type); c++) + { + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 150; + + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0085; /* combo box class */ + + data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, joystick_get_axis_name(type, c), -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + y += 20; + } + + for (c = 0; c < joystick_get_button_count(type); c++) + { + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 150; + + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0085; /* combo box class */ + + data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, joystick_get_button_name(type, c), -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + y += 20; + } + + for (c = 0; c < joystick_get_pov_count(type)*2; c++) + { + char s[80]; + + /*Combo box*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 70; + item->y = y; + item->id = id++; + + item->cx = 140; + item->cy = 150; + + item->style = WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | WS_VSCROLL; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0085; /* combo box class */ + + if (c & 1) + sprintf(s, "%s (Y axis)", joystick_get_pov_name(type, c/2)); + else + sprintf(s, "%s (X axis)", joystick_get_pov_name(type, c/2)); + data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + /*Static text*/ + item = (DLGITEMTEMPLATE *)data; + item->x = 10; + item->y = y; + item->id = id++; + + item->cx = 60; + item->cy = 15; + + item->style = WS_CHILD | WS_VISIBLE; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0082; /* static class */ + + data += MultiByteToWideChar(CP_ACP, 0, s, -1, data, 256); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + y += 20; + } + + dlg->cdit = (id - IDC_CONFIG_BASE) + 2; + + item = (DLGITEMTEMPLATE *)data; + item->x = 20; + item->y = y; + item->cx = 50; + item->cy = 14; + item->id = IDOK; /* OK button identifier */ + item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, "OK", -1, data, 50); + *data++ = 0; /* no creation data */ + + if (((unsigned long)data) & 2) + data++; + + item = (DLGITEMTEMPLATE *)data; + item->x = 80; + item->y = y; + item->cx = 50; + item->cy = 14; + item->id = IDCANCEL; /* OK button identifier */ + item->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + data = (uint16_t *)(item + 1); + *data++ = 0xFFFF; + *data++ = 0x0080; /* button class */ + + data += MultiByteToWideChar(CP_ACP, 0, "Cancel", -1, data, 50); + *data++ = 0; /* no creation data */ + + dlg->cy = y + 20; + + DialogBoxIndirect(hinstance, dlg, hwnd, joystickconfig_dlgproc); + + free(data_block); +} diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c new file mode 100644 index 000000000..e87964d37 --- /dev/null +++ b/src/WIN/win_language.c @@ -0,0 +1,197 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#include +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include + +#include "../ibm.h" +#include "../device.h" +#include "../ide.h" +#include "resource.h" +#include "win.h" +#include "win_language.h" + +LCID dwLanguage; + +uint32_t dwLangID, dwSubLangID; + +#define STRINGS_NUM 154 + +WCHAR lpResourceString[STRINGS_NUM][512]; + +char openfilestring[260]; +WCHAR wopenfilestring[260]; + +void win_language_set() +{ + SetThreadLocale(dwLanguage); +} + +void win_language_load_common_strings() +{ + int i = 0; + + for (i = 0; i < STRINGS_NUM; i++) + { + LoadString(hinstance, 2048 + i, lpResourceString[i], 512); + } +} + +LPTSTR win_language_get_settings_category(int i) +{ + return lpResourceString[17 + i]; +} + +void win_language_update() +{ + win_language_set(); + win_menu_update(); + win_language_load_common_strings(); +} + +void win_language_check() +{ + LCID dwLanguageNew = MAKELCID(dwLangID, dwSubLangID); + if (dwLanguageNew != dwLanguage) + { + dwLanguage = dwLanguageNew; + win_language_update(); + } +} + +LPTSTR win_language_get_string_from_id(int i) +{ + return lpResourceString[i - 2048]; +} + +LPTSTR win_language_get_string_from_string(char *str) +{ + return lpResourceString[atoi(str) - 2048]; +} + +int msgbox_reset(HWND hwndParent) +{ + return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNOCANCEL | MB_ICONQUESTION); +} + +int msgbox_reset_yn(HWND hwndParent) +{ + return MessageBox(hwndParent, lpResourceString[3], lpResourceString[0], MB_YESNO | MB_ICONQUESTION); +} + +int msgbox_question(HWND hwndParent, int i) +{ + return MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_YESNO | MB_ICONQUESTION); +} + +void msgbox_info(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[0], MB_OK | MB_ICONINFORMATION); +} + +void msgbox_error(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); +} + +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) +{ + MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); +} + +void msgbox_critical(HWND hwndParent, int i) +{ + MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[2], MB_OK | MB_ICONERROR); +} + +void msgbox_fatal(HWND hwndParent, char *string) +{ + LPTSTR lptsTemp; + lptsTemp = (LPTSTR) malloc(512); + + mbstowcs(lptsTemp, string, strlen(string) + 1); + + MessageBox(hwndParent, lptsTemp, lpResourceString[2], MB_OK | MB_ICONERROR); + + free(lptsTemp); +} + +int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save) +{ + OPENFILENAME ofn; /* common dialog box structure */ + BOOL r; + DWORD err; + + /* Initialize OPENFILENAME */ + ZeroMemory(&ofn, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFile = wopenfilestring; + /* + Set lpstrFile[0] to '\0' so that GetOpenFileName does not + use the contents of szFile to initialize itself. + */ + memcpy(ofn.lpstrFile, fn, (wcslen(fn) << 1) + 2); + ofn.nMaxFile = 259; + ofn.lpstrFilter = f; + ofn.nFilterIndex = 1; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.Flags = OFN_PATHMUSTEXIST; + if (!save) + { + ofn.Flags |= OFN_FILEMUSTEXIST; + } + + /* Display the Open dialog box. */ + + if (save) + { + pclog("GetSaveFileName - lpstrFile = %s\n", ofn.lpstrFile); + r = GetSaveFileName(&ofn); + } + else + { + pclog("GetOpenFileName - lpstrFile = %s\n", ofn.lpstrFile); + r = GetOpenFileName(&ofn); + } + if (r) + { + wcstombs(openfilestring, wopenfilestring, 520); + pclog("File dialog return true\n"); + return 0; + } + pclog("File dialog return false\n"); + err = CommDlgExtendedError(); + pclog("CommDlgExtendedError return %04X\n", err); + return 1; +} + +int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save) +{ + WCHAR ufn[512]; + mbstowcs(ufn, fn, strlen(fn) + 1); + return file_dlg_w(hwnd, f, ufn, save); +} + +int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save) +{ + return file_dlg_w(hwnd, win_language_get_string_from_id(i), fn, save); +} + +int file_dlg_st(HWND hwnd, int i, char *fn, int save) +{ + return file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); +} diff --git a/src/WIN/win_language.h b/src/WIN/win_language.h new file mode 100644 index 000000000..5c4237249 --- /dev/null +++ b/src/WIN/win_language.h @@ -0,0 +1,33 @@ +#ifdef __cplusplus +extern "C" { +#endif + +LCID dwLanguage; + +int msgbox_reset(HWND hwndParent); +int msgbox_reset_yn(HWND hwndParent); +int msgbox_question(HWND hwndParent, int i); +void msgbox_info(HWND hwndParent, int i); +void msgbox_info_wstr(HWND hwndParent, WCHAR *wstr); +void msgbox_error(HWND hwndParent, int i); +void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr); +void msgbox_fatal(HWND hwndParent, char *string); +void msgbox_critical(HWND hwndParent, int i); + +int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save); +int file_dlg(HWND hwnd, WCHAR *f, char *fn, int save); +int file_dlg_w_st(HWND hwnd, int i, WCHAR *fn, int save); +int file_dlg_st(HWND hwnd, int i, char *fn, int save); + +void win_language_load_common_strings(); +LPTSTR win_language_get_settings_category(int i); + +void win_language_update(); +void win_language_check(); + +LPTSTR win_language_get_string_from_id(int i); +LPTSTR win_language_get_string_from_string(char *str); + +#ifdef __cplusplus +} +#endif diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c new file mode 100644 index 000000000..2fdf58bec --- /dev/null +++ b/src/WIN/win_midi.c @@ -0,0 +1,279 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include "../ibm.h" +#include "../config.h" +#include "plat_midi.h" + +int midi_id; +static HMIDIOUT midi_out_device = NULL; + +HANDLE m_event; + +void midi_close(); + +static uint8_t midi_rt_buf[1024]; +static uint8_t midi_cmd_buf[1024]; +static int midi_cmd_pos = 0; +static int midi_cmd_len = 0; +static uint8_t midi_status = 0; +static unsigned int midi_sysex_start = 0; +static unsigned int midi_sysex_delay = 0; + +uint8_t MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 +}; + +void midi_init() +{ + MMRESULT hr = MMSYSERR_NOERROR; + + memset(midi_rt_buf, 0, 1024); + memset(midi_cmd_buf, 0, 1024); + + midi_cmd_pos = midi_cmd_len = 0; + midi_status = 0; + + midi_sysex_start = midi_sysex_delay = 0; + + midi_id = config_get_int(NULL, "midi", 0); + + m_event = CreateEvent(NULL, TRUE, TRUE, NULL); + + hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, + 0, CALLBACK_EVENT); + if (hr != MMSYSERR_NOERROR) { + printf("midiOutOpen error - %08X\n",hr); + midi_id = 0; + hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, + 0, CALLBACK_EVENT); + if (hr != MMSYSERR_NOERROR) { + printf("midiOutOpen error - %08X\n",hr); + return; + } + } + + midiOutReset(midi_out_device); +} + +void midi_close() +{ + if (midi_out_device != NULL) + { + midiOutReset(midi_out_device); + midiOutClose(midi_out_device); + midi_out_device = NULL; + CloseHandle(m_event); + } +} + +int midi_get_num_devs() +{ + return midiOutGetNumDevs(); +} +void midi_get_dev_name(int num, char *s) +{ + MIDIOUTCAPS caps; + + midiOutGetDevCaps(num, &caps, sizeof(caps)); + strcpy(s, caps.szPname); +} + +static int midi_pos, midi_len; +static uint32_t midi_command; +static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; +static int midi_insysex; +static char midi_sysex_data[1024+2]; + +static void midi_send_sysex() +{ + MIDIHDR hdr; + + hdr.lpData = midi_sysex_data; + hdr.dwBufferLength = midi_pos; + hdr.dwFlags = 0; + + midiOutPrepareHeader(midi_out_device, &hdr, sizeof(MIDIHDR)); + midiOutLongMsg(midi_out_device, &hdr, sizeof(MIDIHDR)); + + midi_insysex = 0; +} + +void PlayMsg(uint8_t *msg) +{ + midiOutShortMsg(midi_out_device, *(uint32_t *) msg); +} + +MIDIHDR m_hdr; + +void PlaySysex(uint8_t *sysex, unsigned int len) +{ + MMRESULT result; + + if (WaitForSingleObject(m_event, 2000) == WAIT_TIMEOUT) + { + pclog("Can't send MIDI message\n"); + return; + } + + midiOutUnprepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); + + m_hdr.lpData = (char *) sysex; + m_hdr.dwBufferLength = len; + m_hdr.dwBytesRecorded = len; + m_hdr.dwUser = 0; + + result = midiOutPrepareHeader(midi_out_device, &m_hdr, sizeof(m_hdr)); + + if (result != MMSYSERR_NOERROR) return; + ResetEvent(m_event); + result = midiOutLongMsg(midi_out_device, &m_hdr, sizeof(m_hdr)); + if (result != MMSYSERR_NOERROR) + { + SetEvent(m_event); + return; + } +} + +#define SYSEX_SIZE 1024 +#define RAWBUF 1024 + +void midi_write(uint8_t val) +{ + uint32_t passed_ticks; + + if (midi_sysex_start) + { + passed_ticks = GetTickCount() - midi_sysex_start; + if (passed_ticks < midi_sysex_delay) + { + Sleep(midi_sysex_delay - passed_ticks); + } + } + + /* Test for a realtime MIDI message */ + if (val >= 0xf8) + { + midi_rt_buf[0] = val; + PlayMsg(midi_rt_buf); + return; + } + + /* Test for a active sysex transfer */ + + if (midi_status == 0xf0) + { + if (!(val & 0x80)) + { + if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; + return; + } + else + { + midi_sysex_data[midi_pos++] = 0xf7; + + if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) + { + /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ + } + else + { + PlaySysex(midi_sysex_data, midi_pos); + if (midi_sysex_start) + { + if (midi_sysex_data[5] == 0x7f) + { + midi_sysex_delay = 290; /* All parameters reset */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) + { + midi_sysex_delay = 145; /* Viking Child */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) + { + midi_sysex_delay = 30; /* Dark Sun 1 */ + } + else + midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; + + midi_sysex_start = GetTickCount(); + } + } + } + } + + + if (val & 0x80) + { + midi_status = val; + midi_cmd_pos = 0; + midi_cmd_len = MIDI_evt_len[val]; + if (midi_status == 0xf0) + { + midi_sysex_data[0] = 0xf0; + midi_pos = 1; + } + } + + if (midi_cmd_len) + { + midi_cmd_buf[midi_cmd_pos++] = val; + if (midi_cmd_pos >= midi_cmd_len) + { + PlayMsg(midi_cmd_buf); + midi_cmd_pos = 1; + } + } +} + +void midi_reset() +{ + uint8_t buf[64], used; + + /* Flush buffers */ + midiOutReset(midi_out_device); + + /* GM1 reset */ + buf[0] = 0xf0; + buf[1] = 0x7e; + buf[2] = 0x7f; + buf[3] = 0x09; + buf[4] = 0x01; + buf[5] = 0xf7; + PlaySysex((uint8_t *) buf, 6); + + /* GS1 reset */ + buf[0] = 0xf0; + buf[1] = 0x41; + buf[2] = 0x10; + buf[3] = 0x42; + buf[4] = 0x12; + buf[5] = 0x40; + buf[6] = 0x00; + buf[7] = 0x7f; + buf[8] = 0x00; + buf[9] = 0x41; + buf[10] = 0xf7; + PlaySysex((uint8_t *) buf, 11); +} diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc new file mode 100644 index 000000000..f64b714a0 --- /dev/null +++ b/src/WIN/win_mouse.cc @@ -0,0 +1,75 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define DIRECTINPUT_VERSION 0x0800 +#include +#include "plat_mouse.h" +#include "win.h" + +extern "C" int video_fullscreen; + +extern "C" void fatal(const char *format, ...); +extern "C" void pclog(const char *format, ...); + +extern "C" void mouse_init(); +extern "C" void mouse_close(); +extern "C" void mouse_poll_host(); +extern "C" void mouse_get_mickeys(int *x, int *y, int *z); + +static LPDIRECTINPUT8 lpdi; +static LPDIRECTINPUTDEVICE8 lpdi_mouse = NULL; +static DIMOUSESTATE mousestate; +static int mouse_x = 0, mouse_y = 0, mouse_z = 0; +int mouse_buttons = 0; + +void mouse_init() +{ + atexit(mouse_close); + + if (FAILED(DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (void **) &lpdi, NULL))) + fatal("mouse_init : DirectInputCreate failed\n"); + if (FAILED(lpdi->CreateDevice(GUID_SysMouse, &lpdi_mouse, NULL))) + fatal("mouse_init : CreateDevice failed\n"); + if (FAILED(lpdi_mouse->SetCooperativeLevel(ghwnd, DISCL_FOREGROUND | (video_fullscreen ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE)))) + fatal("mouse_init : SetCooperativeLevel failed\n"); + if (FAILED(lpdi_mouse->SetDataFormat(&c_dfDIMouse))) + fatal("mouse_init : SetDataFormat failed\n"); +} + +void mouse_close() +{ + if (lpdi_mouse) + { + lpdi_mouse->Release(); + lpdi_mouse = NULL; + } +} + +void mouse_poll_host() +{ + if (FAILED(lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate))) + { + lpdi_mouse->Acquire(); + lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate); + } + mouse_buttons = 0; + if (mousestate.rgbButtons[0] & 0x80) + mouse_buttons |= 1; + if (mousestate.rgbButtons[1] & 0x80) + mouse_buttons |= 2; + if (mousestate.rgbButtons[2] & 0x80) + mouse_buttons |= 4; + mouse_x += mousestate.lX; + mouse_y += mousestate.lY; + mouse_z += mousestate.lZ/120; + if (!mousecapture && !video_fullscreen) + mouse_x = mouse_y = mouse_buttons = 0; +} + +void mouse_get_mickeys(int *x, int *y, int *z) +{ + *x = mouse_x; + *y = mouse_y; + *z = mouse_z; + mouse_x = mouse_y = mouse_z = 0; +} diff --git a/src/WIN/win_opendir.c b/src/WIN/win_opendir.c new file mode 100644 index 000000000..00347a365 --- /dev/null +++ b/src/WIN/win_opendir.c @@ -0,0 +1,213 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation POSIX OpenDir(3) and friends for Win32 API. + * + * Based on old original code @(#)dir_win32.c 1.2.0 2007/04/19 + * + * Version: @(#)win_opendir.c 1.0.1 2017/05/17 + * + * Author: Fred N. van Kempen, + * Copyright 1998-2007 MicroWalt Corporation + * Copyright 2017 Fred N. van Kempen + */ +#define UNICODE +#include +#include +#include +#include +#include +#include +#include "../ibm.h" +#include "plat_dir.h" + + +#ifdef UNICODE +# define SUFFIX L"\\*" +# define FINDATA struct _wfinddata_t +# define FINDFIRST _wfindfirst +# define FINDNEXT _wfindnext +#else +# define SUFFIX "\\*" +# define FINDATA struct _finddata_t +# define FINDFIRST _findfirst +# define FINDNEXT _findnext +#endif + + +/* Open a directory. */ +DIR * +#ifdef UNICODE +opendirw(const wchar_t *name) +#else +opendir(const char *name) +#endif +{ + DIR *p; + + /* Create a new control structure. */ + p = (DIR *) malloc(sizeof(DIR)); + if (p == NULL) + return(NULL); + memset(p, 0x00, sizeof(DIR)); + p->flags = (DIR_F_LOWER | DIR_F_SANE); + p->offset = 0; + p->sts = 0; + + /* Create a work area. */ + p->dta = (char *)malloc(sizeof(FINDATA)); + if (p->dta == NULL) { + free(p); + return(NULL); + } + memset(p->dta, 0x00, sizeof(struct _finddata_t)); + + /* Add search filespec. */ +#ifdef UNICODE + wcscpy(p->dir, name); + wcscat(p->dir, SUFFIX); +#else + strcpy(p->dir, name); + strcat(p->dir, SUFFIX); +#endif + + /* Special case: flag if we are in the root directory. */ +#ifdef UNICODE + if (wcslen(p->dir) == 3) +#else + if (strlen(p->dir) == 3) +#endif + p->flags |= DIR_F_ISROOT; + + /* Start the searching by doing a FindFirst. */ + p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); + if (p->handle < 0L) { + free(p->dta); + free(p); + return(NULL); + } + + /* All OK. */ + return(p); +} + + +/* Close an open directory. */ +int +closedir(DIR *p) +{ + if (p == NULL) + return(0); + + _findclose(p->handle); + + if (p->dta != NULL) + free(p->dta); + free(p); + + return(0); +} + + +/* + * Read the next entry from a directory. + * Note that the DOS (FAT), Windows (FAT, FAT32) and Windows NTFS + * file systems do not have a root directory containing the UNIX- + * standard "." and ".." entries. Many applications do assume + * this anyway, so we simply fake these entries. + */ +struct direct * +readdir(DIR *p) +{ + FINDATA *ffp; + + if (p == NULL || p->sts == 1) + return(NULL); + + /* Format structure with current data. */ + ffp = (FINDATA *)p->dta; + p->dent.d_ino = 1L; + p->dent.d_off = p->offset++; + switch(p->offset) { + case 1: /* . */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, L".", MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, ".", MAXNAMLEN+1); +#endif + p->dent.d_reclen = 1; + break; + + case 2: /* .. */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, L"..", MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, "..", MAXNAMLEN+1); +#endif + p->dent.d_reclen = 2; + break; + + default: /* regular entry. */ +#ifdef UNICODE + wcsncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); +#else + strncpy(p->dent.d_name, ffp->name, MAXNAMLEN+1); +#endif + p->dent.d_reclen = (char) wcslen(p->dent.d_name); + } + + /* Read next entry. */ + p->sts = 0; + + /* Fake the "." and ".." entries here.. */ + if ((p->flags & DIR_F_ISROOT) && (p->offset <= 2)) + return(&(p->dent)); + + /* Get the next entry if we did not fake the above. */ + if (FINDNEXT(p->handle, ffp) < 0) + p->sts = 1; + + return(&(p->dent)); +} + + +/* Report current position within the directory. */ +long +telldir(DIR *p) +{ + return(p->offset); +} + + +void +seekdir(DIR *p, long newpos) +{ + short pos; + + /* First off, rewind to start of directory. */ + p->handle = FINDFIRST(p->dir, (FINDATA *)p->dta); + if (p->handle < 0L) { + p->sts = 1; + return; + } + p->offset = 0; + p->sts = 0; + + /* If we are rewinding, that's all... */ + if (newpos == 0L) return; + + /* Nope.. read entries until we hit the right spot. */ + pos = (short) newpos; + while (p->offset != pos) { + p->offset++; + if (FINDNEXT(p->handle, (FINDATA *)p->dta) < 0) { + p->sts = 1; + return; + } + } +} diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c new file mode 100644 index 000000000..cfe8f0b43 --- /dev/null +++ b/src/WIN/win_serial.c @@ -0,0 +1,606 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of host serial port services for Win32. + * + * This code is based on a universal serial port driver for + * Windows and UNIX systems, with support for FTDI and Prolific + * USB ports. Support for these has been removed. + * + * Version: @(#)win_serial.c 1.0.2 2017/05/17 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#define _WIN32_WINNT 0x0501 +#include +#include +#include +#define BHTTY_C +#include "plat_serial.h" + + +extern void pclog(char *__fmt, ...); + + +/* Set the state of a port. */ +int +bhtty_sstate(BHTTY *pp, void *arg) +{ + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("invalid argument\n"); + return(-1); + } + + if (SetCommState(pp->handle, (DCB *)arg) == FALSE) { + /* Mark an error. */ + pclog("%s: set state: %d\n", pp->name, GetLastError()); + return(-1); + } + + return(0); +} + + +/* Fetch the state of a port. */ +int +bhtty_gstate(BHTTY *pp, void *arg) +{ + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("BHTTY: invalid argument\n"); + return(-1); + } + + if (GetCommState(pp->handle, (DCB *)arg) == FALSE) { + /* Mark an error. */ + pclog("%s: get state: %d\n", pp->name, GetLastError()); + return(-1); + } + + return(0); +} + + +/* Enable or disable RTS/CTS mode (hardware handshaking.) */ +int +bhtty_crtscts(BHTTY *pp, char yesno) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* Get the current mode. */ + if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + + switch(yesno) { + case 0: /* disable CRTSCTS */ + pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ + pp->dcb.fDsrSensitivity = 0; + + pp->dcb.fOutxCtsFlow = 0; /* disable RTS/CTS mode */ + + pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ + pp->dcb.fOutX = 0; + pp->dcb.fInX = 0; + break; + + case 1: /* enable CRTSCTS */ + pp->dcb.fOutxDsrFlow = 0; /* disable DSR/DCD mode */ + pp->dcb.fDsrSensitivity = 0; + + pp->dcb.fOutxCtsFlow = 1; /* enable RTS/CTS mode */ + + pp->dcb.fTXContinueOnXoff = 0; /* disable XON/XOFF mode */ + pp->dcb.fOutX = 0; + pp->dcb.fInX = 0; + break; + + default: + pclog("%s: invalid parameter '%d'!\n", pp->name, yesno); + return(-1); + } + + /* Set new mode. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + + return(0); +} + + +/* Set the port parameters. */ +int +bhtty_params(BHTTY *pp, char dbit, char par, char sbit) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* Get the current mode. */ + if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + + /* Set the desired word length. */ + switch((int)dbit) { + case -1: /* no change */ + break; + + case 5: /* FTDI doesnt like these */ + case 6: + case 9: + break; + + case 7: + case 8: + pp->dcb.ByteSize = dbit; + break; + + default: + pclog("%s: invalid parameter '%d'!\n", pp->name, dbit); + return(-1); + } + + /* Set the type of parity encoding. */ + switch((int)par) { + case -1: /* no change */ + case ' ': + break; + + case 0: + case 'N': + pp->dcb.fParity = FALSE; + pp->dcb.Parity = NOPARITY; + break; + + case 1: + case 'O': + pp->dcb.fParity = TRUE; + pp->dcb.Parity = ODDPARITY; + break; + + case 2: + case 'E': + pp->dcb.fParity = TRUE; + pp->dcb.Parity = EVENPARITY; + break; + + case 3: + case 'M': + case 4: + case 'S': + break; + + default: + pclog("%s: invalid parameter '%c'!\n", pp->name, par); + return(-1); + } + + /* Set the number of stop bits. */ + switch((int)sbit) { + case -1: /* no change */ + break; + + case 1: + pp->dcb.StopBits = ONESTOPBIT; + break; + + case 2: + pp->dcb.StopBits = TWOSTOPBITS; + break; + + default: + pclog("%s: invalid parameter '%d'!\n", pp->name, sbit); + return(-1); + } + + /* Set new mode. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + + return(0); +} + + +/* Put a port in transparent ("raw") state. */ +void +bhtty_raw(BHTTY *pp, void *arg) +{ + DCB *dcb = (DCB *)arg; + + /* Make sure we can do this. */ + if (pp == NULL || arg == NULL) { + pclog("invalid parameter\n"); + return; + } + + /* Enable BINARY transparent mode. */ + dcb->fBinary = 1; + dcb->fErrorChar = 0; /* disable Error Replacement */ + dcb->fNull = 0; /* disable NUL stripping */ + + /* Disable the DTR and RTS lines. */ + dcb->fDtrControl = DTR_CONTROL_DISABLE; /* DTR line */ + dcb->fRtsControl = RTS_CONTROL_DISABLE; /* RTS line */ + + /* Disable DSR/DCD handshaking. */ + dcb->fOutxDsrFlow = 0; /* DSR handshaking */ + dcb->fDsrSensitivity = 0; /* DSR Sensitivity */ + + /* Disable RTS/CTS handshaking. */ + dcb->fOutxCtsFlow = 0; /* CTS handshaking */ + + /* Disable XON/XOFF handshaking. */ + dcb->fTXContinueOnXoff = 0; /* continue TX after Xoff */ + dcb->fOutX = 0; /* enable output X-ON/X-OFF */ + dcb->fInX = 0; /* enable input X-ON/X-OFF */ + dcb->XonChar = 0x11; /* ASCII XON */ + dcb->XoffChar = 0x13; /* ASCII XOFF */ + dcb->XonLim = 100; + dcb->XoffLim = 100; + + dcb->fParity = FALSE; + dcb->Parity = NOPARITY; + dcb->StopBits = ONESTOPBIT; + dcb->BaudRate = CBR_1200; +} + + +/* Set the port speed. */ +int +bhtty_speed(BHTTY *pp, long speed) +{ + int i; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* Get the current mode and speed. */ + if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); + + /* + * Set speed. + * + * This is not entirely correct, we should use a table + * with DCB_xxx speed values here, but we removed that + * and just hardcode the speed value into DCB. --FvK + */ + pp->dcb.BaudRate = speed; + + /* Set new speed. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) return(-1); + + return(0); +} + + +/* Clean up and flush. */ +int +bhtty_flush(BHTTY *pp) +{ + DWORD dwErrs; + COMSTAT cs; + int i = 0; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid handle\n"); + return(-1); + } + + /* First, clear any errors. */ + (void)ClearCommError(pp->handle, &dwErrs, &cs); + + /* Now flush all buffers. */ + if (PurgeComm(pp->handle, + (PURGE_RXABORT | PURGE_TXABORT | \ + PURGE_RXCLEAR | PURGE_TXCLEAR)) == FALSE) { + pclog("%s: flush: %d\n", pp->name, GetLastError()); + return(-1); + } + + /* Re-clear any errors. */ + if (ClearCommError(pp->handle, &dwErrs, &cs) == FALSE) { + pclog("%s: clear errors: %d\n", pp->name, GetLastError()); + return(-1); + } + + return(0); +} + + +/* Close an open serial port. */ +void +bhtty_close(BHTTY *pp) +{ + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("BHTTY: invalid handle\n"); + return; + } + + if (pp->handle != INVALID_HANDLE_VALUE) { + /* Restore the previous port state, if any. */ + (void)bhtty_sstate(pp, &pp->odcb); + + /* Close the port. */ + CloseHandle(pp->handle); + pp->handle = INVALID_HANDLE_VALUE; + } + + /* Release the control block. */ + free(pp); +} + + +/* Open a host serial port for I/O. */ +BHTTY * +bhtty_open(char *port, int tmo) +{ + char buff[64]; + COMMTIMEOUTS to; +#if 0 + COMMCONFIG conf; + DWORD d; +#endif + BHTTY *pp; + int i = 0; + + /* Make sure we can do this. */ + if (port == NULL) { + pclog("invalid argument!\n"); + return(NULL); + } + + /* First things first... create a control block. */ + if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) { + pclog("%s: out of memory!\n", port); + return(NULL); + } + memset(pp, 0x00, sizeof(BHTTY)); + strncpy(pp->name, port, sizeof(pp->name)-1); + + /* Try a regular Win32 serial port. */ + sprintf(buff, "\\\\.\\%s", pp->name); + pp->handle = CreateFile(buff, + (GENERIC_READ|GENERIC_WRITE), + 0, NULL, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0); + if (pp->handle == INVALID_HANDLE_VALUE) { + pclog("%s: open port: %d\n", pp->name, GetLastError()); + free(pp); + return(NULL); + } + +#if 0 + /* Set up buffer size of the port. */ + if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { + /* This fails on FTDI-based devices. */ + pclog("%s: set buffers: %d\n", pp->name, GetLastError()); +// CloseHandle(pp->handle); +// free(pp); +// return(NULL); + } + + /* Grab default config for the driver and set it. */ + d = sizeof(COMMCONFIG); + memset(&conf, 0x00, d); + conf.dwSize = d; + if (GetDefaultCommConfig(pp->name, &conf, &d) == TRUE) { + /* Change config here... */ + + /* Set new configuration. */ + if (SetCommConfig(pp->handle, &conf, d) == FALSE) { + /* This fails on FTDI-based devices. */ + pclog("%s: set configuration: %d\n", pp->name, GetLastError()); +// CloseHandle(pp->handle); +// free(pp); +// return(NULL); + } + } +#endif + + /* + * We now have an open port. To allow for clean exit + * of the application, we first retrieve the port's + * current settings, and save these for later. + */ + if (bhtty_gstate(pp, &pp->odcb) < 0) { + (void)bhtty_close(pp); + return(NULL); + } + memcpy(&pp->dcb, &pp->odcb, sizeof(DCB)); + + /* Force the port to BINARY mode. */ + bhtty_raw(pp, &pp->dcb); + + /* Set new state of this port. */ + if (bhtty_sstate(pp, &pp->dcb) < 0) { + (void)bhtty_close(pp); + return(NULL); + } + + /* Just to make sure.. disable RTS/CTS mode. */ + (void)bhtty_crtscts(pp, 0); + + /* Set new timeout values. */ + if (GetCommTimeouts(pp->handle, &to) == FALSE) { + pclog("%s: error %d while getting current TO\n", + pp->name, GetLastError()); + (void)bhtty_close(pp); + return(NULL); + } + if (tmo < 0) { + /* No timeout, immediate return. */ + to.ReadIntervalTimeout = MAXDWORD; + to.ReadTotalTimeoutMultiplier = 0; + to.ReadTotalTimeoutConstant = 0; + } else if (tmo == 0) { + /* No timeout, wait for data. */ + memset(&to, 0x00, sizeof(to)); + } else { + /* Timeout specified. */ + to.ReadIntervalTimeout = MAXDWORD; + to.ReadTotalTimeoutMultiplier = MAXDWORD; + to.ReadTotalTimeoutConstant = tmo; + } + if (SetCommTimeouts(pp->handle, &to) == FALSE) { + pclog("%s: error %d while setting TO\n", + pp->name, GetLastError()); + (void)bhtty_close(pp); + return(NULL); + } + + /* Clear all errors and flush all buffers. */ + if (bhtty_flush(pp) < 0) { + (void)bhtty_close(pp); + return(NULL); + } + + return(pp); +} + + +/* A pending WRITE has finished, handle it. */ +static VOID CALLBACK +bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) +{ + BHTTY *pp = (BHTTY *)priv->hEvent; + +//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); +#if 0 + if ( + if (GetOverlappedResult(p->handle, + &p->rov, &mst, TRUE) == FALSE) { + r = GetLastError(); + if (r != ERROR_OPERATION_ABORTED) + /* OK, we're being shut down. */ + sprintf(serial_errmsg, + "%s: I/O read error!", p->name); + return(-1); + } +#endif +} + + +/* Try to write data to an open port. */ +int +bhtty_write(BHTTY *pp, unsigned char val) +{ + DWORD n; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid parameter\n"); + return(-1); + } +//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); + + /* Save the control pointer for later use. */ + pp->wov.hEvent = (HANDLE)pp; + + if (WriteFileEx(pp->handle, + &val, 1, + &pp->wov, + bhtty_write_comp) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } + + /* Its pending, so handled in the completion routine. */ + SleepEx(1, TRUE); + + return(0); +} + + +/* + * A pending READ has finished, handle it. + */ +static VOID CALLBACK +bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) +{ + BHTTY *pp = (BHTTY *)priv->hEvent; + DWORD r; +//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); + + if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { + r = GetLastError(); + if (r != ERROR_OPERATION_ABORTED) + /* OK, we're being shut down. */ + pclog("%s: I/O read error!", pp->name); + return; + } +//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); + + /* Do a callback to let them know. */ + if (pp->rd_done != NULL) + pp->rd_done(pp->rd_arg, num); +} + + +/* + * Try to read data from an open port. + * + * For now, we will use one byte per call. Eventually, + * we should go back to loading a buffer full of data, + * just to speed things up a bit. --FvK + * + * Also, not that we do not wait here. We just POST a + * read operation, and the completion routine will do + * the clean-up and notify the caller. + */ +int +bhtty_read(BHTTY *pp, unsigned char *bufp, int max) +{ + DWORD r; + + /* Just one byte. */ + max = 1; + + /* Make sure we can do this. */ + if (pp == NULL) { + pclog("invalid parameter\n"); + return(-1); + } + + /* Save the control pointer for later use. */ + pp->rov.hEvent = (HANDLE)pp; +//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); + + /* Post a READ on the device. */ + if (ReadFileEx(pp->handle, + bufp, (DWORD)max, + &pp->rov, + bhtty_read_comp) == FALSE) { + r = GetLastError(); + if (r != ERROR_IO_PENDING) { + /* OK, we're being shut down. */ + if (r != ERROR_INVALID_HANDLE) + pclog("%s: I/O read error!\n", pp->name); + return(-1); + } + } + + /* Make ourself alertable. */ + SleepEx(1, TRUE); + + /* OK, it's pending, so we are good for now. */ + return(0); +} diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c new file mode 100644 index 000000000..6916bca28 --- /dev/null +++ b/src/WIN/win_settings.c @@ -0,0 +1,3694 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#define UNICODE +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include "../ibm.h" +#include "../mem.h" +#include "../cpu/cpu.h" +#include "../nvr.h" +#include "../model.h" +#include "../device.h" +#include "../cdrom.h" +#include "../disc.h" +#include "../fdd.h" +#include "../hdd.h" +#include "../ide.h" +#include "../scsi.h" +#include "../scsi_buslogic.h" +#include "../network.h" +#include "../sound/sound.h" +#include "../sound/snd_dbopl.h" +#include "../video/video.h" +#include "../video/vid_voodoo.h" +#include "../gameport.h" +#include "../mouse.h" +#include "plat_midi.h" +#include "win.h" +#include "win_language.h" +#include "resource.h" + + +#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + + +/* Machine category */ +int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; + +/* Video category */ +int temp_gfxcard, temp_video_speed, temp_voodoo; + +/* Input devices category */ +int temp_mouse, temp_joystick; + +/* Sound category */ +int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; + +/* Network category */ +int temp_net_type, temp_net_card; +char temp_pcap_dev[520]; + +/* Peripherals category */ +int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; +int temp_serial[2], temp_lpt, temp_bugger; + +char temp_hdc_name[16]; + +/* Hard disks category */ +hard_disk_t temp_hdc[HDC_NUM]; +wchar_t temp_hdd_fn[HDC_NUM][512]; + +/* Removable devices category */ +int temp_fdd_types[FDD_NUM]; +cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; + +static HWND hwndParentDialog, hwndChildDialog; + +int hdd_controller_current; + +int displayed_category = 0; + +extern int is486; +static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; +static int settings_sound_to_list[20], settings_list_to_sound[20]; +static int settings_mouse_to_list[20], settings_list_to_mouse[20]; +static int settings_scsi_to_list[20], settings_list_to_scsi[20]; +static int settings_network_to_list[20], settings_list_to_network[20]; +static char *hdd_names[16]; + + +/* This does the initial read of global variables into the temporary ones. */ +static void win_settings_init(void) +{ + int i = 0; + + /* Machine category */ + temp_model = model; + temp_cpu_m = cpu_manufacturer; + temp_cpu = cpu; + temp_mem_size = mem_size; + temp_dynarec = cpu_use_dynarec; + temp_fpu = enable_external_fpu; + temp_sync = enable_sync; + + /* Video category */ + temp_gfxcard = gfxcard; + temp_video_speed = video_speed; + temp_voodoo = voodoo_enabled; + + /* Input devices category */ + temp_mouse = mouse_type; + temp_joystick = joystick_type; + + /* Sound category */ + temp_sound_card = sound_card_current; + temp_midi_id = midi_id; + temp_SSI2001 = SSI2001; + temp_GAMEBLASTER = GAMEBLASTER; + temp_GUS = GUS; + temp_opl3_type = opl3_type; + + /* Network category */ + temp_net_type = network_type; + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_pcap); + temp_net_card = network_card; + + /* Peripherals category */ + temp_scsi_card = scsi_card_current; + strncpy(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + temp_ide_ter = ide_enable[2]; + temp_ide_ter_irq = ide_irq[2]; + temp_ide_qua = ide_enable[3]; + temp_ide_qua_irq = ide_irq[3]; + temp_serial[0] = serial_enabled[0]; + temp_serial[1] = serial_enabled[1]; + temp_lpt = lpt_enabled; + temp_bugger = bugger_enabled; + + /* Hard disks category */ + memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); + } + + /* Removable devices category */ + for (i = 0; i < FDD_NUM; i++) + { + temp_fdd_types[i] = fdd_get_type(i); + } + memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); +} + + +/* This returns 1 if any variable has changed, 0 if not. */ +static int win_settings_changed(void) +{ + int i = 0; + int j = 0; + + /* Machine category */ + i = i || (model != temp_model); + i = i || (cpu_manufacturer != temp_cpu_m); + i = i || (cpu != temp_cpu); + i = i || (mem_size != temp_mem_size); + i = i || (temp_dynarec != cpu_use_dynarec); + i = i || (temp_fpu != enable_external_fpu); + i = i || (temp_sync != enable_sync); + + /* Video category */ + i = i || (gfxcard != temp_gfxcard); + i = i || (video_speed != temp_video_speed); + i = i || (voodoo_enabled != temp_voodoo); + + /* Input devices category */ + i = i || (mouse_type != temp_mouse); + i = i || (joystick_type != temp_joystick); + + /* Sound category */ + i = i || (sound_card_current != temp_sound_card); + i = i || (midi_id != temp_midi_id); + i = i || (SSI2001 != temp_SSI2001); + i = i || (GAMEBLASTER != temp_GAMEBLASTER); + i = i || (GUS != temp_GUS); + i = i || (opl3_type != temp_opl3_type); + + /* Network category */ + i = i || (network_type != temp_net_type); + i = i || strcmp(temp_pcap_dev, network_pcap); + i = i || (network_card != temp_net_card); + + /* Peripherals category */ + i = i || (scsi_card_current != temp_scsi_card); + i = i || strncmp(temp_hdc_name, hdd_controller_name, sizeof(temp_hdc_name) - 1); + i = i || (temp_ide_ter != ide_enable[2]); + i = i || (temp_ide_ter_irq != ide_irq[2]); + i = i || (temp_ide_qua != ide_enable[3]); + i = i || (temp_ide_qua_irq != ide_irq[3]); + i = i || (temp_serial[0] != serial_enabled[0]); + i = i || (temp_serial[1] != serial_enabled[1]); + i = i || (temp_lpt != lpt_enabled); + i = i || (temp_bugger != bugger_enabled); + + /* Hard disks category */ + i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + for (j = 0; j < HDC_NUM; j++) + { + i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); + } + + /* Removable devices category */ + for (j = 0; j < FDD_NUM; j++) + { + i = i || (temp_fdd_types[j] != fdd_get_type(j)); + } + i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + + return i; +} + + +static int settings_msgbox_reset(void) +{ + int i = 0; + int changed = 0; + + changed = win_settings_changed(); + + if (changed) + { + i = msgbox_reset(hwndParentDialog); + + if (i == IDNO) + { + return 1; + } + else if (i == IDCANCEL) + { + return 0; + } + else + { + return 2; + } + } + else +{ + return 1; + } +} + + +/* This saves the settings back to the global variables. */ +static void win_settings_save(void) +{ + int i = 0; + + /* Machine category */ + model = temp_model; + romset = model_getromset(); + cpu_manufacturer = temp_cpu_m; + cpu = temp_cpu; + mem_size = temp_mem_size; + cpu_use_dynarec = temp_dynarec; + enable_external_fpu = temp_fpu; + enable_sync = temp_sync; + + /* Video category */ + gfxcard = temp_gfxcard; + video_speed = temp_video_speed; + voodoo_enabled = temp_voodoo; + + /* Input devices category */ + mouse_type = temp_mouse; + joystick_type = temp_joystick; + + /* Sound category */ + sound_card_current = temp_sound_card; + midi_id = temp_midi_id; + SSI2001 = temp_SSI2001; + GAMEBLASTER = temp_GAMEBLASTER; + GUS = temp_GUS; + opl3_type = temp_opl3_type; + + /* Network category */ + network_type = temp_net_type; + memset(network_pcap, '\0', sizeof(network_pcap)); + strcpy(network_pcap, temp_pcap_dev); + network_card = temp_net_card; + + /* Peripherals category */ + scsi_card_current = temp_scsi_card; + strncpy(hdd_controller_name, temp_hdc_name, sizeof(temp_hdc_name) - 1); + ide_enable[2] = temp_ide_ter; + ide_irq[2] = temp_ide_ter_irq; + ide_enable[3] = temp_ide_qua; + ide_irq[3] = temp_ide_qua_irq; + serial_enabled[0] = temp_serial[0]; + serial_enabled[1] = temp_serial[1]; + lpt_enabled = temp_lpt; + bugger_enabled = temp_bugger; + + /* Hard disks category */ + memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); + } + + /* Removable devices category */ + for (i = 0; i < FDD_NUM; i++) + { + fdd_set_type(i, temp_fdd_types[i]); + } + memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); + + mem_resize(); + loadbios(); + + resetpchard(); + + cpu_set(); + + cpu_update_waitstates(); + + saveconfig(); + + speedchanged(); + + if (joystick_type != 7) gameport_update_joystick_type(); + + update_status_bar_panes(hwndStatus); +} + + +static void win_settings_machine_recalc_cpu(HWND hdlg) +{ + HWND h; + int temp_romset = 0; + int cpu_flags; + int cpu_type; + + temp_romset = model_getromset_ex(temp_model); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type >= CPU_286) && (cpu_type <= CPU_386DX)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + cpu_flags = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_flags; + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) && (cpu_flags & CPU_REQUIRES_DYNAREC)) + { + fatal("Attempting to select a CPU that requires the recompiler and does not support it at the same time\n"); + } + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC) || (cpu_flags & CPU_REQUIRES_DYNAREC)) + { + if (!(cpu_flags & CPU_SUPPORTS_DYNAREC)) + { + temp_dynarec = 0; + } + if (cpu_flags & CPU_REQUIRES_DYNAREC) + { + temp_dynarec = 1; + } + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } + + h = GetDlgItem(hdlg, IDC_CHECK_FPU); + cpu_type = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[temp_cpu].cpu_type; + if ((cpu_type < CPU_i486DX) && (cpu_type >= CPU_286)) + { + EnableWindow(h, TRUE); + } + else if (cpu_type < CPU_286) + { + temp_fpu = 0; + EnableWindow(h, FALSE); + } + else + { + temp_fpu = 1; + EnableWindow(h, FALSE); + } + SendMessage(h, BM_SETCHECK, temp_fpu, 0); +} + + +static void win_settings_machine_recalc_cpu_m(HWND hdlg) +{ + HWND h; + int c = 0; + int temp_romset = 0; + LPTSTR lptsTemp; + char *stransi; + + temp_romset = model_getromset_ex(temp_model); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) + { + stransi = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cpu, 0); + + win_settings_machine_recalc_cpu(hdlg); + + free(lptsTemp); +} + + +static void win_settings_machine_recalc_model(HWND hdlg) +{ + HWND h; + int c = 0; + int temp_romset = 0; + LPTSTR lptsTemp; + char *stransi; + UDACCEL accel; + + temp_romset = model_getromset_ex(temp_model); + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MACHINE); + if (model_getdevice(temp_model)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = 0; + while (models[romstomodel[temp_romset]].cpu[c].cpus != NULL && c < 4) + { + stransi = models[romstomodel[temp_romset]].cpu[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); + if (c == 1) + { + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } + + win_settings_machine_recalc_cpu_m(hdlg); + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETRANGE, 0, (models[romstomodel[temp_romset]].min_ram << 16) | models[romstomodel[temp_romset]].max_ram); + accel.nSec = 0; + accel.nInc = models[romstomodel[temp_romset]].ram_granularity; + SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); + if (!(models[romstomodel[temp_romset]].flags & MODEL_AT)) + { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); + } + else + { + SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); + h = GetDlgItem(hdlg, IDC_TEXT_MB); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); + } + + free(lptsTemp); +} + + +static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + char *stransi; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + for (c = 0; c < ROM_MAX; c++) + { + romstolist[c] = 0; + } + c = d = 0; + while (models[c].id != -1) + { + if (romspresent[models[c].id]) + { + stransi = models[c].name; + mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + modeltolist[c] = d; + listtomodel[d] = c; + romstolist[models[c].id] = d; + romstomodel[models[c].id] = c; + d++; + } + c++; + } + SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); + + for (c = 0; c < 8; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2132), c); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + SendMessage(h, BM_SETCHECK, temp_dynarec, 0); + + h = GetDlgItem(hdlg, IDC_MEMSPIN); + SendMessage(h, UDM_SETBUDDY, (WPARAM)GetDlgItem(hdlg, IDC_MEMTEXT), 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + SendMessage(h, BM_SETCHECK, temp_sync, 0); + + win_settings_machine_recalc_model(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_MACHINE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_model = listtomodel[SendMessage(h,CB_GETCURSEL,0,0)]; + + win_settings_machine_recalc_model(hdlg); + } + break; + case IDC_COMBO_CPU_TYPE: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_CPU_TYPE); + temp_cpu_m = SendMessage(h, CB_GETCURSEL, 0, 0); + + temp_cpu = 0; + win_settings_machine_recalc_cpu_m(hdlg); + } + break; + case IDC_COMBO_CPU: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_CPU); + temp_cpu = SendMessage(h, CB_GETCURSEL, 0, 0); + + win_settings_machine_recalc_cpu(hdlg); + } + break; + case IDC_CONFIGURE_MACHINE: + h = GetDlgItem(hdlg, IDC_COMBO_MACHINE); + temp_model = listtomodel[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); + break; + } + + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); + temp_dynarec = SendMessage(h, BM_GETCHECK, 0, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_SYNC); + temp_sync = SendMessage(h, BM_GETCHECK, 0, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_FPU); + temp_fpu = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_WS); + temp_wait_states = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_MEMTEXT); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + sscanf(stransi, "%i", &temp_mem_size); + temp_mem_size &= ~(models[temp_model].ram_granularity - 1); + if (temp_mem_size < models[temp_model].min_ram) + { + temp_mem_size = models[temp_model].min_ram; + } + else if (temp_mem_size > models[temp_model].max_ram) + { + temp_mem_size = models[temp_model].max_ram; + } + if (models[temp_model].flags & MODEL_AT) + { + temp_mem_size *= 1024; + } + + free(stransi); + free(lptsTemp); + + default: + return FALSE; + } + + return FALSE; +} + + +static void recalc_vid_list(HWND hdlg) +{ + HWND h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + int c = 0, d = 0; + int found_card = 0; + WCHAR szText[512]; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_SETCURSEL, 0, 0); + + while (1) + { + char *s = video_card_getname(c); + + if (!s[0]) + break; + + if (video_card_available(c) && gfx_present[video_new_to_old(c)] && + ((models[temp_model].flags & MODEL_PCI) || !(video_card_getdevice(c)->flags & DEVICE_PCI))) + { + mbstowcs(szText, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if (video_new_to_old(c) == gfxcard) + { + + SendMessage(h, CB_SETCURSEL, d, 0); + found_card = 1; + } + + d++; + } + + c++; + } + if (!found_card) + SendMessage(h, CB_SETCURSEL, 0, 0); + EnableWindow(h, models[temp_model].fixed_gfxcard ? FALSE : TRUE); + + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); +} + + +static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + char *stransi; + char *s; + int gfx = 0; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + recalc_vid_list(hdlg); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); + SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); + + h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); + SendMessage(h, BM_SETCHECK, temp_voodoo, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + gfx = video_card_getid(stransi); + + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + if (video_card_has_config(gfx)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + free(stransi); + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_VIDEO: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + gfx = video_card_getid(stransi); + temp_gfxcard = video_new_to_old(gfx); + + h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + if (video_card_has_config(gfx)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + free(stransi); + free(lptsTemp); + break; + + case IDC_CHECK_VOODOO: + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + EnableWindow(h, temp_voodoo ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_VOODOO: + deviceconfig_open(hdlg, (void *)&voodoo_device); + break; + + case IDC_CONFIGUREVID: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + deviceconfig_open(hdlg, (void *)video_card_getdevice(video_card_getid(stransi))); + + free(stransi); + free(lptsTemp); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + lptsTemp = (LPTSTR) malloc(512); + stransi = (char *) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO); + SendMessage(h, CB_GETLBTEXT, SendMessage(h, CB_GETCURSEL, 0, 0), (LPARAM) lptsTemp); + wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); + temp_gfxcard = video_new_to_old(video_card_getid(stransi)); + + h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); + temp_video_speed = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); + temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); + + free(stransi); + free(lptsTemp); + + default: + return FALSE; + } + return FALSE; +} + + +static int mouse_valid(int type, int model) +{ + type &= MOUSE_TYPE_MASK; + + if ((type == MOUSE_TYPE_PS2) && + !(models[model].flags & MODEL_PS2)) return(0); + + if ((type == MOUSE_TYPE_AMSTRAD) && + !(models[model].flags & MODEL_AMSTRAD)) return(0); + + if ((type == MOUSE_TYPE_OLIM24) && + !(models[model].flags & MODEL_OLIM24)) return(0); + + return(1); +} + + +static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + int type; + int str_id = 0; + + switch (message) + { + case WM_INITDIALOG: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + c = d = 0; + for (c = 0; c < mouse_get_ndev(); c++) + { + type = mouse_get_type(c); + + settings_mouse_to_list[c] = d; + + if (mouse_valid(type, temp_model)) + { + switch(c) + { + case 0: /* MS Serial */ + default: + str_id = 2139; + break; + case 1: /* PS2 2b */ + str_id = 2141; + break; + case 2: /* PS2 intelli 3b */ + str_id = 2142; + break; + case 3: /* MS/logi bus 2b */ + str_id = 2143; + break; + case 4: /* Amstrad */ + str_id = 2162; + break; + case 5: /* Olivetti M24 */ + str_id = 2177; + break; + case 6: /* MouseSystems */ + str_id = 2140; + break; + case 7: /* Genius Bus */ + str_id = 2161; + break; + } + + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(str_id)); + + settings_list_to_mouse[d] = c; + d++; + } + } + + SendMessage(h, CB_SETCURSEL, settings_mouse_to_list[temp_mouse], 0); + + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + c = 0; + while (joystick_get_name(c)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2144 + c)); + c++; + } + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_joystick, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_JOYSTICK: + if (HIWORD(wParam) == CBN_SELCHANGE) + { + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_JOY1); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 1) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY2); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 2) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY3); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 3) ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_JOY4); + EnableWindow(h, (joystick_get_max_joysticks(temp_joystick) >= 4) ? TRUE : FALSE); + } + break; + + case IDC_JOY1: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 0, temp_joystick); + break; + + case IDC_JOY2: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 1, temp_joystick); + break; + + case IDC_JOY3: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 2, temp_joystick); + break; + + case IDC_JOY4: + h = GetDlgItem(hdlg, IDC_COMBOJOY); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + joystickconfig_open(hdlg, 3, temp_joystick); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBO_MOUSE); + temp_mouse = settings_list_to_mouse[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK); + temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + + +static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) +{ + HWND h; + + char *s; + int valid = 0; + char old_name[16]; + int c, d; + + LPTSTR lptsTemp; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + + if (models[model].flags & MODEL_HAS_IDE) + { + hdc_ignore = 1; + + SendMessage(h, CB_RESETCONTENT, 0, 0); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); + EnableWindow(h, FALSE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } + else + { + hdc_ignore = 0; + + valid = 0; + + if (use_selected_hdd) + { + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (c != -1 && hdd_names[c]) + { + strncpy(old_name, hdd_names[c], sizeof(old_name) - 1); + } + else + { + strcpy(old_name, "none"); + } + } + else + { + strncpy(old_name, temp_hdc_name, sizeof(old_name) - 1); + } + + SendMessage(h, CB_RESETCONTENT, 0, 0); + c = d = 0; + while (1) + { + s = hdd_controller_get_name(c); + if (s[0] == 0) + { + break; + } + if ((hdd_controller_get_flags(c) & DEVICE_AT) && !(models[model].flags & MODEL_AT)) + { + c++; + continue; + } + if ((hdd_controller_get_flags(c) & DEVICE_PS2) && !(models[model].flags & MODEL_PS2_HDD)) + { + c++; + continue; + } + if ((hdd_controller_get_flags(c) & DEVICE_MCA) && !(models[model].flags & MODEL_MCA)) + { + c++; + continue; + } + if (!hdd_controller_available(c)) + { + c++; + continue; + } + if (c < 2) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152 + c)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + hdd_names[d] = hdd_controller_get_internal_name(c); + if (!strcmp(old_name, hdd_names[d])) + { + SendMessage(h, CB_SETCURSEL, d, 0); + valid = 1; + } + c++; + d++; + } + + if (!valid) + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + EnableWindow(h, TRUE); + } + + free(lptsTemp); +} + + +int valid_ide_irqs[11] = { 2, 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 }; + + +int find_irq_in_array(int irq, int def) +{ + int i = 0; + + for (i = 0; i < 11; i++) + { + if (valid_ide_irqs[i] == irq) + { + return i + 1; + } + } + + return 7 + def; +} + + +static char midi_dev_name_buf[512]; + +static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *sound_dev; + int num = 0; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBOSND); + c = d = 0; + while (1) + { + char *s = sound_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_sound_to_list[c] = d; + + if (sound_card_available(c)) + { + sound_dev = sound_card_getdevice(c); + + if (!sound_dev || (sound_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_sound[d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURESND); + if (sound_card_has_config(temp_sound_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + num = midi_get_num_devs(); + for (c = 0; c < num; c++) + { + memset(midi_dev_name_buf, 0, 512); + midi_get_dev_name(c, midi_dev_name_buf); + mbstowcs(lptsTemp, midi_dev_name_buf, strlen(midi_dev_name_buf) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + if (c == temp_midi_id) + SendMessage(h, CB_SETCURSEL, c, 0); + } + + h=GetDlgItem(hdlg, IDC_CHECKCMS); + SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); + + h=GetDlgItem(hdlg, IDC_CHECKGUS); + SendMessage(h, BM_SETCHECK, temp_GUS, 0); + + h=GetDlgItem(hdlg, IDC_CHECKSSI); + SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); + + h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIGURESND: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); + break; + + case IDC_COMBOSND: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURESND); + if (sound_card_has_config(temp_sound_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBOSND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKCMS); + temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKGUS); + temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKSSI); + temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + + +static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *scsi_dev; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + /*SCSI config*/ + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + c = d = 0; + while (1) + { + char *s = scsi_card_getname(c); + + if (!s[0]) + { + break; + } + + settings_scsi_to_list[c] = d; + + if (scsi_card_available(c)) + { + scsi_dev = scsi_card_getdevice(c); + + if (!scsi_dev || (scsi_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_scsi[d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_scsi_to_list[temp_scsi_card], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + recalc_hdd_list(hdlg, temp_model, 0); + + h=GetDlgItem(hdlg, IDC_COMBO_IDE_TER); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + + for (c = 0; c < 11; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + if (temp_ide_ter) + { + SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_ter_irq, 0), 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + + for (c = 0; c < 11; c++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + if (temp_ide_qua) + { + SendMessage(h, CB_SETCURSEL, find_irq_in_array(temp_ide_qua_irq, 1), 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + + h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); + SendMessage(h, BM_SETCHECK, temp_serial[0], 0); + + h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); + SendMessage(h, BM_SETCHECK, temp_serial[1], 0); + + h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); + SendMessage(h, BM_SETCHECK, temp_lpt, 0); + + h=GetDlgItem(hdlg, IDC_CHECKBUGGER); + SendMessage(h, BM_SETCHECK, temp_bugger, 0); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CONFIGURE_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)scsi_card_getdevice(temp_scsi_card)); + break; + + case IDC_COMBO_SCSI: + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_SCSI); + if (scsi_card_has_config(temp_scsi_card)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + break; + } + return FALSE; + + case WM_SAVESETTINGS: + if (hdc_ignore == 0) + { + h = GetDlgItem(hdlg, IDC_COMBO_HDC); + c = SendMessage(h, CB_GETCURSEL, 0, 0); + if (hdd_names[c]) + { + strncpy(temp_hdc_name, hdd_names[c], sizeof(temp_hdc_name) - 1); + } + else + { + strcpy(temp_hdc_name, "none"); + } + } + else + { + strcpy(temp_hdc_name, "none"); + } + + h = GetDlgItem(hdlg, IDC_COMBO_SCSI); + temp_scsi_card = settings_list_to_scsi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_COMBO_IDE_TER); + temp_ide_ter = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_ide_ter > 1) + { + temp_ide_ter_irq = valid_ide_irqs[temp_ide_ter - 1]; + temp_ide_ter = 1; + } + + h = GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); + temp_ide_qua = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_ide_qua > 1) + { + temp_ide_qua_irq = valid_ide_irqs[temp_ide_qua - 1]; + temp_ide_qua = 1; + } + + h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); + temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); + temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); + temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CHECKBUGGER); + temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); + + default: + return FALSE; + } + return FALSE; +} + + +int net_ignore_message = 0; + +static void network_recalc_combos(HWND hdlg) +{ + HWND h; + + net_ignore_message = 1; + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + if (temp_net_type == NET_TYPE_PCAP) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + if (temp_net_type == NET_TYPE_SLIRP) + { + EnableWindow(h, TRUE); + } + else if ((temp_net_type == NET_TYPE_PCAP) && + (network_dev_to_id(temp_pcap_dev) > 0)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_CONFIGURENET); + if (network_card_has_config(temp_net_card) && + (temp_net_type == NET_TYPE_SLIRP)) + { + EnableWindow(h, TRUE); + } + else if (network_card_has_config(temp_net_card) && + (temp_net_type == NET_TYPE_PCAP) && + (network_dev_to_id(temp_pcap_dev) > 0)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + net_ignore_message = 0; +} + +static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int c = 0; + int d = 0; + LPTSTR lptsTemp; + device_t *scsi_dev; + + switch (message) + { + case WM_INITDIALOG: + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); + SendMessage(h, CB_SETCURSEL, temp_net_type, 0); + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + if (temp_net_type == NET_TYPE_PCAP) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + for (c = 0; c < network_ndev; c++) + { + mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); + + /*NIC config*/ + h = GetDlgItem(hdlg, IDC_COMBONET); + c = d = 0; + while (1) + { + char *s = network_card_getname(c); + + if (s[0] == '\0') + { + break; + } + + settings_network_to_list[c] = d; + + if (network_card_available(c)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_network[d] = c; + d++; + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_network_to_list[temp_net_card], 0); + + network_recalc_combos(hdlg); + + free(lptsTemp); + + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBONETTYPE: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBOPCAP: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + network_recalc_combos(hdlg); + break; + + case IDC_COMBONET: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + network_recalc_combos(hdlg); + break; + + case IDC_CONFIGURENET: + if (net_ignore_message) + { + return FALSE; + } + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); + break; + } + return FALSE; + + case WM_SAVESETTINGS: + h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); + + h = GetDlgItem(hdlg, IDC_COMBOPCAP); + memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); + strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); + + h = GetDlgItem(hdlg, IDC_COMBONET); + temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + default: + return FALSE; + } + + return FALSE; +} + +static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 8; i += 2) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +int next_free_id = 0; + +wchar_t ifn[HDC_NUM][512]; + +static void normalize_hd_list() +{ + hard_disk_t ihdc[HDC_NUM]; + int i, j; + + j = 0; + memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memset(ifn[i], 0, 1024); + } + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus > 0) + { + memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); + memcpy(ifn[j], temp_hdd_fn[i], 1024); + j++; + } + } + + memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) + { + memcpy(temp_hdd_fn[i], ifn[i], 1024); + } +} + +int hdc_id_to_listview_index[HDC_NUM]; +int hd_listview_items; + +hard_disk_t new_hdc; +int hdlv_current_sel; + +static int get_selected_hard_disk(HWND hdlg) +{ + int hard_disk = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + hard_disk = i; + } + } + + return hard_disk; +} + +static void add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + for (i = 0; i < 4; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + for (i = 0; i < 16; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} + +static void recalc_location_controls(HWND hdlg, int is_add_dlg) +{ + int i = 0; + HWND h; + + int bus = 0; + + for (i = 1799; i < 1803; i++) + { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + if ((hd_listview_items > 0) || is_add_dlg) + { + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + + switch(bus) + { + case 0: /* MFM/RLL */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); + break; + case 1: /* IDE (PIO-only) */ + case 2: /* IDE (PIO and DMA) */ + h = GetDlgItem(hdlg, 1802); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); + break; + case 3: /* SCSI */ + h = GetDlgItem(hdlg, 1800); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, 1801); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_id : temp_hdc[hdlv_current_sel].scsi_id, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.scsi_lun : temp_hdc[hdlv_current_sel].scsi_lun, 0); + break; + } + } + + if ((hd_listview_items == 0) && !is_add_dlg) + { + h = GetDlgItem(hdlg, 1798); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); + } + else + { + h = GetDlgItem(hdlg, 1798); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + } +} + +static void recalc_next_free_id(HWND hdlg) +{ + HWND h; + int i; + + int c_mfm = 0; + int c_ide_pio = 0; + int c_ide_dma = 0; + int c_scsi = 0; + int enable_add = 0; + + next_free_id = -1; + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus == 1) + { + c_mfm++; + } + else if (temp_hdc[i].bus == 2) + { + c_ide_pio++; + } + else if (temp_hdc[i].bus == 3) + { + c_ide_dma++; + } + else if (temp_hdc[i].bus == 4) + { + c_scsi++; + } + } + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus == 0) + { + next_free_id = i; + break; + } + } + + /* pclog("Next free ID: %i\n", next_free_id); */ + + enable_add = enable_add || (next_free_id >= 0); + /* pclog("Enable add: %i\n", enable_add); */ + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); + /* pclog("Enable add: %i\n", enable_add); */ + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); + + if (enable_add) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD); + + if (enable_add) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); + + if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) + { + EnableWindow(h, FALSE); + } + else + { + EnableWindow(h, TRUE); + } +} + +static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column) +{ + LVITEM lvI; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = column; + lvI.iItem = i; + + if (column == 0) + { + switch(temp_hdc[i].bus) + { + case 1: + wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + break; + case 2: + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; + } + lvI.pszText = szText; + lvI.iImage = temp_hdc[i].bus - 1; + } + else if (column == 1) + { + lvI.pszText = temp_hdd_fn[i]; + lvI.iImage = 0; + } + else if (column == 2) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 3) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 4) + { + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + lvI.pszText = szText; + lvI.iImage = 0; + } + else if (column == 5) + { + wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + lvI.pszText = szText; + lvI.iImage = 0; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + int j = 0; + WCHAR szText[256]; + + hd_listview_items = 0; + hdlv_current_sel = -1; + + ListView_DeleteAllItems(hwndList); + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < HDC_NUM; i++) + { + if (temp_hdc[i].bus > 0) + { + hdc_id_to_listview_index[i] = j; + lvI.iSubItem = 0; + switch(temp_hdc[i].bus) + { + case 1: + wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); + break; + case 2: + wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 3: + wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; + } + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = temp_hdc[i].bus - 1; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 1; + lvI.pszText = temp_hdd_fn[i]; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 2; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].tracks); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 3; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].hpc); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 4; + wsprintf(szText, win_language_get_string_from_id(2088), temp_hdc[i].spt); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + lvI.iSubItem = 5; + wsprintf(szText, win_language_get_string_from_id(2088), (temp_hdc[i].tracks * temp_hdc[i].hpc * temp_hdc[i].spt) >> 11); + lvI.pszText = szText; + lvI.iItem = j; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } + + j++; + } + else + { + hdc_id_to_listview_index[i] = -1; + } + } + + hd_listview_items = j; + + return TRUE; +} + +/* Icon, Bus, File, C, H, S, Size */ +#define C_COLUMNS_HARD_DISKS 6 + +static BOOL win_settings_hard_disks_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + int iCol; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + for (iCol = 0; iCol < C_COLUMNS_HARD_DISKS; iCol++) + { + lvc.iSubItem = iCol; + lvc.pszText = win_language_get_string_from_id(2082 + iCol); + + switch(iCol) + { + + case 0: /* Bus */ + lvc.cx = 135; + lvc.fmt = LVCFMT_LEFT; + break; + case 2: /* Cylinders */ + lvc.cx = 41; + lvc.fmt = LVCFMT_RIGHT; + break; + case 3: /* Heads */ + case 4: /* Sectors */ + lvc.cx = 25; + lvc.fmt = LVCFMT_RIGHT; + break; + case 1: /* File */ + lvc.cx = 150; + lvc.fmt = LVCFMT_LEFT; + break; + case 5: /* Size (MB) 8 */ + lvc.cx = 41; + lvc.fmt = LVCFMT_RIGHT; + break; + } + + if (ListView_InsertColumn(hwndList, iCol, &lvc) == -1) + { + return FALSE; + } + } + + return TRUE; +} + +static void get_edit_box_contents(HWND hdlg, int id, uint64_t *val) +{ + HWND h; + WCHAR szText[256]; + char stransi[256]; + + h = GetDlgItem(hdlg, id); + SendMessage(h, WM_GETTEXT, 255, (LPARAM) szText); + wcstombs(stransi, szText, (wcslen(szText) * 2) + 2); + sscanf(stransi, "%" PRIu64, val); +} + +static void get_combo_box_selection(HWND hdlg, int id, uint64_t *val) +{ + HWND h; + + h = GetDlgItem(hdlg, id); + *val = SendMessage(h, CB_GETCURSEL, 0, 0); +} + +static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) +{ + HWND h; + WCHAR szText[256]; + + h = GetDlgItem(hdlg, id); + wsprintf(szText, win_language_get_string_from_id(2160), val); + SendMessage(h, WM_SETTEXT, (WPARAM) wcslen(szText), (LPARAM) szText); +} + +int hard_disk_added = 0; +int max_spt = 63; + +int no_update = 0; + +int existing = 0; +uint64_t selection = 127; + +uint64_t spt, hpc, tracks, size; +wchar_t hd_file_name[512]; + +static int hdconf_initialize_hdt_combo(HWND hdlg) +{ + HWND h; + int i = 0; + uint64_t temp_size = 0; + uint64_t size_mb = 0; + WCHAR szText[256]; + + selection = 127; + + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) + { + temp_size = hdt[i][0] * hdt[i][1] * hdt[i][2]; + size_mb = temp_size >> 11; + wsprintf(szText, win_language_get_string_from_id(2171), size_mb, hdt[i][0], hdt[i][1], hdt[i][2]); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + { + selection = i; + } + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2170)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2187)); + SendMessage(h, CB_SETCURSEL, selection, 0); + return selection; +} + +static void recalc_selection(HWND hdlg) +{ + HWND h; + int i = 0; + + selection = 127; + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + for (i = 0; i < 127; i++) + { + if ((tracks == hdt[i][0]) && (hpc == hdt[i][1]) && (spt == hdt[i][2])) + { + selection = i; + } + } + if ((selection == 127) && (hpc == 16) && (spt == 63)) + { + selection = 128; + } + SendMessage(h, CB_SETCURSEL, selection, 0); +} + +static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int64_t i = 0; + int bus; + uint64_t temp; + WCHAR szText[256]; + FILE *f; + uint32_t sector_size = 512; + uint32_t zero = 0; + uint32_t base = 0x1000; + uint64_t signature = 0xD778A82044445459ll; + char buf[512]; + + switch (message) + { + case WM_INITDIALOG: + memset(hd_file_name, 0, 512); + + SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); + + no_update = 1; + spt = existing ? 0 : 17; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + hpc = existing ? 0 : 15; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + tracks = existing ? 0 : 1023; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + hdconf_initialize_hdt_combo(hdlg); + if (existing) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + } + add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, 1, 0); + recalc_location_controls(hdlg, 1); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + EnableWindow(h, FALSE); + no_update = 0; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + if (wcslen(hd_file_name) == 0) + { + msgbox_error(hwndParentDialog, 2056); + return TRUE; + } + + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(temp_hdc[next_free_id].spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(temp_hdc[next_free_id].hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(temp_hdc[next_free_id].tracks)); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + temp_hdc[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + temp_hdc[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + temp_hdc[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + memset(temp_hdd_fn[next_free_id], 0, 1024); + memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + + sector_size = 512; + + if (!existing && (wcslen(hd_file_name) > 0)) + { + f = _wfopen(hd_file_name, L"wb"); + + if (image_is_hdi(hd_file_name)) + { + if (size >= 0x100000000ll) + { + fclose(f); + msgbox_error(hwndParentDialog, 2058); + return TRUE; + } + + fwrite(&zero, 1, 4, f); /* 00000000: Zero/unknown */ + fwrite(&zero, 1, 4, f); /* 00000004: Zero/unknown */ + fwrite(&base, 1, 4, f); /* 00000008: Offset at which data starts */ + fwrite(&size, 1, 4, f); /* 0000000C: Full size of the data (32-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + + for (i = 0; i < 0x3f8; i++) + { + fwrite(&zero, 1, 4, f); + } + } + else if (image_is_hdx(hd_file_name, 0)) + { + if (size > 0xffffffffffffffffll) + { + fclose(f); + msgbox_error(hwndParentDialog, 2163); + return TRUE; + } + + fwrite(&signature, 1, 8, f); /* 00000000: Signature */ + fwrite(&size, 1, 8, f); /* 00000008: Full size of the data (64-bit) */ + fwrite(§or_size, 1, 4, f); /* 00000010: Sector size in bytes */ + fwrite(&spt, 1, 4, f); /* 00000014: Sectors per cylinder */ + fwrite(&hpc, 1, 4, f); /* 00000018: Heads per cylinder */ + fwrite(&tracks, 1, 4, f); /* 0000001C: Cylinders */ + fwrite(&zero, 1, 4, f); /* 00000020: [Translation] Sectors per cylinder */ + fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ + } + + memset(buf, 0, 512); + size >>= 9; + for (i = 0; i < size; i++) + { + fwrite(buf, 512, 1, f); + } + + fclose(f); + msgbox_info(hwndParentDialog, 2059); + } + + hard_disk_added = 1; + EndDialog(hdlg, 0); + return TRUE; + + case IDCANCEL: + hard_disk_added = 0; + EndDialog(hdlg, 0); + return TRUE; + + case IDC_CFILE: + if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) + { + if (!existing) + { + f = _wfopen(wopenfilestring, L"rb"); + if (f != NULL) + { + fclose(f); + if (msgbox_question(ghwnd, 2178) != IDYES) + { + return FALSE; + } + } + } + + f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); + if (f == NULL) + { + msgbox_error(hwndParentDialog, existing ? 2060 : 2057); + return TRUE; + } + if (existing) + { + if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) + { + fseeko64(f, 0x10, SEEK_SET); + fread(§or_size, 1, 4, f); + if (sector_size != 512) + { + msgbox_error(hwndParentDialog, 2061); + fclose(f); + return TRUE; + } + spt = hpc = tracks = 0; + fread(&spt, 1, 4, f); + fread(&hpc, 1, 4, f); + fread(&tracks, 1, 4, f); + } + else + { + fseeko64(f, 0, SEEK_END); + size = ftello64(f); + fclose(f); + if (((size % 17) == 0) && (size <= 133693440)) + { + spt = 17; + if (size <= 26738688) + { + hpc = 4; + } + else if (size <= 53477376) + { + hpc = 6; + } + else if (size <= 71303168) + { + hpc = 8; + } + else + { + hpc = 15; + } + } + else + { + spt = 63; + hpc = 16; + } + + tracks = ((size >> 9) / hpc) / spt; + } + + no_update = 1; + + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, TRUE); + + no_update = 0; + } + else + { + fclose(f); + } + } + + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); + memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); + + return TRUE; + + case IDC_EDIT_HD_CYL: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &temp); + if (temp != tracks) + { + tracks = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_HPC: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &temp); + if (temp != hpc) + { + hpc = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_SPT: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &temp); + if (temp != spt) + { + spt = temp; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_EDIT_HD_SIZE: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, &temp); + if (temp != (size >> 20)) + { + size = temp << 20; + tracks = ((size >> 9) / hpc) / spt; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + recalc_selection(hdlg); + } + no_update = 0; + break; + + case IDC_COMBO_HD_TYPE: + if (no_update) + { + return FALSE; + } + + no_update = 1; + get_combo_box_selection(hdlg, IDC_COMBO_HD_TYPE, &temp); + if ((temp != selection) && (temp != 127) && (temp != 128)) + { + selection = temp; + tracks = hdt[selection][0]; + hpc = hdt[selection][1]; + spt = hdt[selection][2]; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + } + else if ((temp != selection) && (temp == 127)) + { + selection = temp; + } + else if ((temp != selection) && (temp == 128)) + { + selection = temp; + hpc = 16; + spt = 63; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); + } + no_update = 0; + break; + + case IDC_COMBO_HD_BUS: + if (no_update) + { + return FALSE; + } + + no_update = 1; + recalc_location_controls(hdlg, 1); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + bus = SendMessage(h, CB_GETCURSEL, 0, 0); + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); + max_spt = (bus == 2) ? 99 : 63; + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; + break; + } + + return FALSE; + } + + return FALSE; +} + +void hard_disk_add_open(HWND hwnd, int is_existing) +{ + BOOL ret; + + existing = !!is_existing; + hard_disk_added = 0; + ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); +} + +int ignore_change = 0; + +static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int old_sel = 0; + + switch (message) + { + case WM_INITDIALOG: + ignore_change = 1; + + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. + This will cause an emulator reset prompt on the first opening of this category with a messy hard disk list + (which can only happen by manually editing the configuration file). */ + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_init_columns(h); + win_settings_hard_disks_image_list_init(h); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + add_locations(hdlg); + if (hd_listview_items > 0) + { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + hdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + } + else + { + hdlv_current_sel = -1; + } + recalc_location_controls(hdlg, 0); + + ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if ((hd_listview_items == 0) || ignore_change) + { + return FALSE; + } + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_HARD_DISKS)) + { + old_sel = hdlv_current_sel; + hdlv_current_sel = get_selected_hard_disk(hdlg); + if (hdlv_current_sel == old_sel) + { + return FALSE; + } + else if (hdlv_current_sel == -1) + { + ignore_change = 1; + hdlv_current_sel = old_sel; + ListView_SetItemState(h, hdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + ignore_change = 0; + return FALSE; + } + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[hdlv_current_sel].bus - 1, 0); + recalc_location_controls(hdlg, 0); + ignore_change = 0; + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_HD_BUS: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + recalc_location_controls(hdlg, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_CHANNEL: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_CHANNEL_IDE: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + temp_hdc[hdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_ID: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + temp_hdc[hdlv_current_sel].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_COMBO_HD_LUN: + if (ignore_change) + { + return FALSE; + } + + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + temp_hdc[hdlv_current_sel].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); + ignore_change = 0; + return FALSE; + + case IDC_BUTTON_HDD_ADD: + hard_disk_add_open(hdlg, 1); + if (hard_disk_added) + { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + ignore_change = 0; + } + return FALSE; + + case IDC_BUTTON_HDD_ADD_NEW: + hard_disk_add_open(hdlg, 0); + if (hard_disk_added) + { + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + ignore_change = 0; + } + return FALSE; + + case IDC_BUTTON_HDD_REMOVE: + memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); + temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ + ignore_change = 1; + h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); + win_settings_hard_disks_recalc_list(h); + recalc_next_free_id(hdlg); + if (hd_listview_items > 0) + { + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + hdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + SendMessage(h, CB_SETCURSEL, temp_hdc[0].bus - 1, 0); + } + else + { + hdlv_current_sel = -1; + } + recalc_location_controls(hdlg, 0); + ignore_change = 0; + return FALSE; + } + + default: + return FALSE; + } + + return FALSE; +} + +int fdlv_current_sel; +int cdlv_current_sel; + +static int combo_id_to_string_id(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + return 2151; + break; + case 2: /* Atapi (PIO-only) */ + return 2189; + break; + case 3: /* Atapi (PIA and DMA) */ + return 2190; + break; + case 4: /* SCSI */ + return 2168; + break; + } +} + +static int combo_id_to_format_string_id(int combo_id) +{ + switch (combo_id) + { + case 0: /* Disabled */ + default: + return 2151; + break; + case 2: /* Atapi (PIO-only) */ + return 2191; + break; + case 3: /* Atapi (PIA and DMA) */ + return 2192; + break; + case 4: /* SCSI */ + return 2158; + break; + } +} + +static BOOL win_settings_floppy_drives_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 14; i++) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) fdd_type_to_icon(i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + int j = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 514); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 160); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 162); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + hiconItem = LoadIcon(hinstance, (LPCWSTR) 164); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 4; i++) + { + if (temp_fdd_types[i] > 0) + { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } + else + { + lvI.pszText = win_language_get_string_from_id(2151); + } + lvI.iItem = i; + lvI.iImage = temp_fdd_types[i]; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + char s[256]; + WCHAR szText[256]; + int bid = 0; + int fsid = 0; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 4; i++) + { + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); + + switch (temp_cdrom_drives[i].bus_type) + { + case 0: + default: + lvI.pszText = win_language_get_string_from_id(fsid); + break; + case 2: + case 3: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + lvI.pszText = szText; + break; + } + + lvI.iItem = i; + + if (temp_cdrom_drives[i].bus_type) + { + lvI.iImage = temp_cdrom_drives[i].bus_type - 1; + } + else + { + lvI.iImage = 0; + } + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = win_language_get_string_from_id(2188); + + lvc.cx = 392; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + { + return FALSE; + } + + return TRUE; +} + +static BOOL win_settings_cdrom_drives_init_columns(HWND hwndList) +{ + LVCOLUMN lvc; + + lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; + + lvc.iSubItem = 0; + lvc.pszText = win_language_get_string_from_id(2082); + + lvc.cx = 392; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) + { + return FALSE; + } + + return TRUE; +} + +static int get_selected_floppy_drive(HWND hdlg) +{ + int floppy_drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + floppy_drive = i; + } + } + + return floppy_drive; +} + +static int get_selected_cdrom_drive(HWND hdlg) +{ + int cd_drive = -1; + int i, j = 0; + HWND h; + + for (i = 0; i < 6; i++) + { + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + cd_drive = i; + } + } + + return cd_drive; +} + +static void win_settings_floppy_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + if (temp_fdd_types[i] > 0) + { + strcpy(s, fdd_getname(temp_fdd_types[i])); + mbstowcs(szText, s, strlen(s) + 1); + lvI.pszText = szText; + } + else + { + lvI.pszText = win_language_get_string_from_id(2151); + } + lvI.iImage = temp_fdd_types[i]; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) +{ + LVITEM lvI; + char s[256]; + WCHAR szText[256]; + int bid; + int fsid; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + lvI.iSubItem = 0; + lvI.iItem = i; + + fsid = combo_id_to_format_string_id(temp_cdrom_drives[i].bus_type); + + switch (temp_cdrom_drives[i].bus_type) + { + case 0: + default: + lvI.pszText = win_language_get_string_from_id(fsid); + break; + case 2: + case 3: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + break; + case 4: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); + lvI.pszText = szText; + break; + } + + if (temp_cdrom_drives[i].bus_type) + { + lvI.iImage = temp_cdrom_drives[i].bus_type - 1; + } + else + { + lvI.iImage = 0; + } + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } +} + +static void cdrom_add_locations(HWND hdlg) +{ + LPTSTR lptsTemp; + HWND h; + int i = 0; + + lptsTemp = (LPTSTR) malloc(512); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + for (i = 1; i < 5; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + for (i = 0; i < 16; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2088), i); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + for (i = 0; i < 8; i++) + { + wsprintf(lptsTemp, win_language_get_string_from_id(2169), i >> 1, i & 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + + free(lptsTemp); +} +static void cdrom_recalc_location_controls(HWND hdlg) +{ + int i = 0; + HWND h; + + int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; + + for (i = 1800; i < 1803; i++) + { + h = GetDlgItem(hdlg, i); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + switch(bus) + { + case 2: /* ATAPI (PIO-only) */ + case 3: /* ATAPI (PIO and DMA) */ + h = GetDlgItem(hdlg, 1802); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); + break; + case 4: /* SCSI */ + h = GetDlgItem(hdlg, 1800); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, 1801); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); + + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_lun, 0); + break; + } +} + + +int rd_ignore_change = 0; + +static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int i = 0; + int old_sel = 0; + int cid = 0; + WCHAR szText[256]; + + switch (message) + { + case WM_INITDIALOG: + rd_ignore_change = 1; + + fdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_init_columns(h); + win_settings_floppy_drives_image_list_init(h); + win_settings_floppy_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + for (i = 0; i < 14; i++) + { + if (i == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + } + else + { + mbstowcs(szText, fdd_getname(i), strlen(fdd_getname(i)) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); + } + } + SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + + cdlv_current_sel = 0; + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_init_columns(h); + win_settings_cdrom_drives_image_list_init(h); + win_settings_cdrom_drives_recalc_list(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + cdrom_add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + { + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + cdrom_recalc_location_controls(hdlg); + + rd_ignore_change = 0; + return TRUE; + + case WM_NOTIFY: + if (rd_ignore_change) + { + return FALSE; + } + + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_FLOPPY_DRIVES)) + { + old_sel = fdlv_current_sel; + fdlv_current_sel = get_selected_floppy_drive(hdlg); + if (fdlv_current_sel == old_sel) + { + return FALSE; + } + else if (fdlv_current_sel == -1) + { + rd_ignore_change = 1; + fdlv_current_sel = old_sel; + ListView_SetItemState(h, fdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + rd_ignore_change = 0; + return FALSE; + } + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + rd_ignore_change = 0; + } + else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) + { + old_sel = cdlv_current_sel; + cdlv_current_sel = get_selected_cdrom_drive(hdlg); + if (cdlv_current_sel == old_sel) + { + return FALSE; + } + else if (cdlv_current_sel == -1) + { + rd_ignore_change = 1; + cdlv_current_sel = old_sel; + ListView_SetItemState(h, cdlv_current_sel, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + rd_ignore_change = 0; + return FALSE; + } + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + { + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + } + else + { + SendMessage(h, CB_SETCURSEL, 0, 0); + } + cdrom_recalc_location_controls(hdlg); + rd_ignore_change = 0; + } + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_COMBO_FD_TYPE: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); + temp_fdd_types[fdlv_current_sel] = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, fdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_BUS: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); + temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) + { + temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + } + cdrom_recalc_location_controls(hdlg); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_ID: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + temp_cdrom_drives[cdlv_current_sel].scsi_device_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_LUN: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_LUN); + temp_cdrom_drives[cdlv_current_sel].scsi_device_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + + case IDC_COMBO_CD_CHANNEL_IDE: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_CHANNEL_IDE); + temp_cdrom_drives[cdlv_current_sel].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); + win_settings_cdrom_drives_update_item(h, cdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + } + + default: + return FALSE; + } + + return FALSE; +} + +void win_settings_show_child(HWND hwndParent, DWORD child_id) +{ + if (child_id == displayed_category) + { + return; + } + else + { + displayed_category = child_id; + } + + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + + DestroyWindow(hwndChildDialog); + + switch(child_id) + { + case 0: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); + break; + case 1: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); + break; + case 2: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); + break; + case 3: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); + break; + case 4: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); + break; + case 5: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + break; + case 6: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + break; + case 7: + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); + break; + default: + fatal("Invalid child dialog ID\n"); + return; + } + + ShowWindow(hwndChildDialog, SW_SHOWNORMAL); +} + +static BOOL win_settings_main_image_list_init(HWND hwndList) +{ + HICON hiconItem; + HIMAGELIST hSmall; + + int i = 0; + + hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + ILC_MASK | ILC_COLOR32, 1, 1); + + for (i = 0; i < 8; i++) + { + hiconItem = LoadIcon(hinstance, (LPCWSTR) (256 + i)); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + } + + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); + + return TRUE; +} + +static BOOL win_settings_main_insert_categories(HWND hwndList) +{ + LVITEM lvI; + int i = 0; + + lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; + lvI.stateMask = lvI.iSubItem = lvI.state = 0; + + for (i = 0; i < 8; i++) + { + lvI.pszText = win_language_get_settings_category(i); + lvI.iItem = i; + lvI.iImage = i; + + if (ListView_InsertItem(hwndList, &lvI) == -1) + return FALSE; + } + + return TRUE; +} + +static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + HWND h; + int category; + int i = 0; + int j = 0; + + hwndParentDialog = hdlg; + + switch (message) + { + case WM_INITDIALOG: + pause = 1; + win_settings_init(); + displayed_category = -1; + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + win_settings_main_image_list_init(h); + win_settings_main_insert_categories(h); + ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); + h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + h = GetDlgItem(hdlg, 2047); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + return TRUE; + case WM_NOTIFY: + if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) + { + category = -1; + for (i = 0; i < 8; i++) + { + h = GetDlgItem(hdlg, IDC_SETTINGSCATLIST); + j = ListView_GetItemState(h, i, LVIS_SELECTED); + if (j) + { + category = i; + /* pclog("Category %i selected\n", i); */ + } + } + if (category != -1) + { + /* pclog("Showing child: %i\n", category); */ + win_settings_show_child(hdlg, category); + } + } + break; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + /* pclog("Saving settings...\n"); */ + SendMessage(hwndChildDialog, WM_SAVESETTINGS, 0, 0); + i = settings_msgbox_reset(); + if (i > 0) + { + if (i == 2) + { + win_settings_save(); + } + + /* pclog("Destroying window...\n"); */ + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + pause = 0; + return TRUE; + } + else + { + return FALSE; + } + case IDCANCEL: + DestroyWindow(hwndChildDialog); + EndDialog(hdlg, 0); + pause=0; + return TRUE; + } + break; + default: + return FALSE; + } + + return FALSE; +} + +void win_settings_open(HWND hwnd) +{ + DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); +} diff --git a/src/WIN/win_status.c b/src/WIN/win_status.c new file mode 100644 index 000000000..59a7a5947 --- /dev/null +++ b/src/WIN/win_status.c @@ -0,0 +1,95 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include "../ibm.h" +#include "../mem.h" +#include "../cpu/x86_ops.h" +#include "../cpu/codegen.h" +#include "../device.h" +#include "resource.h" +#include "win.h" + + +HWND status_hwnd; +int status_is_open = 0; + + +extern int sreadlnum, swritelnum, segareads, segawrites, scycles_lost; + +extern uint64_t main_time; +static uint64_t status_time; + + +static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + char device_s[4096]; + switch (message) + { + case WM_INITDIALOG: + status_is_open = 1; + case WM_USER: + { + uint64_t new_time = timer_read(); + uint64_t status_diff = new_time - status_time; + status_time = new_time; + sprintf(device_s, + "CPU speed : %f MIPS\n" + "FPU speed : %f MFLOPS\n\n" + + "Video throughput (read) : %i bytes/sec\n" + "Video throughput (write) : %i bytes/sec\n\n" + "Effective clockspeed : %iHz\n\n" + "Timer 0 frequency : %fHz\n\n" + "CPU time : %f%% (%f%%)\n" + + "New blocks : %i\nOld blocks : %i\nRecompiled speed : %f MIPS\nAverage size : %f\n" + "Flushes : %i\nEvicted : %i\nReused : %i\nRemoved : %i\nReal speed : %f MIPS" + ,mips, + flops, + segareads, + segawrites, + clockrate - scycles_lost, + pit_timer0_freq(), + ((double)main_time * 100.0) / status_diff, + ((double)main_time * 100.0) / timer_freq + + , cpu_new_blocks_latched, cpu_recomp_blocks_latched, (double)cpu_recomp_ins_latched / 1000000.0, (double)cpu_recomp_ins_latched/cpu_recomp_blocks_latched, + cpu_recomp_flushes_latched, cpu_recomp_evicted_latched, + cpu_recomp_reuse_latched, cpu_recomp_removed_latched, + + ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq) + ); + main_time = 0; + SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + + device_s[0] = 0; + device_add_status_info(device_s, 4096); + SendDlgItemMessage(hdlg, IDC_STEXT1, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + } + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + status_is_open = 0; + EndDialog(hdlg, 0); + return TRUE; + } + break; + } + + return FALSE; +} + +void status_open(HWND hwnd) +{ + status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); + ShowWindow(status_hwnd, SW_SHOW); +} diff --git a/src/WIN/win_video.c b/src/WIN/win_video.c new file mode 100644 index 000000000..3a50f7b9f --- /dev/null +++ b/src/WIN/win_video.c @@ -0,0 +1,57 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include +#include "../video/video.h" +#include "win_cgapal.h" + + +BITMAP *screen; + + +void hline(BITMAP *b, int x1, int y, int x2, uint32_t col) +{ + if (y < 0 || y >= buffer->h) + return; + + if (b == buffer) + memset(&b->line[y][x1], col, x2 - x1); + else + memset(&((uint32_t *)b->line[y])[x1], col, (x2 - x1) * 4); +} + +void blit(BITMAP *src, BITMAP *dst, int x1, int y1, int x2, int y2, int xs, int ys) +{ +} + +void stretch_blit(BITMAP *src, BITMAP *dst, int x1, int y1, int xs1, int ys1, int x2, int y2, int xs2, int ys2) +{ +} + +void rectfill(BITMAP *b, int x1, int y1, int x2, int y2, uint32_t col) +{ +} + +void set_palette(PALETTE p) +{ +} + +void destroy_bitmap(BITMAP *b) +{ +} + +BITMAP *create_bitmap(int x, int y) +{ + BITMAP *b = malloc(sizeof(BITMAP) + (y * sizeof(uint8_t *))); + int c; + b->dat = malloc(x * y * 4); + for (c = 0; c < y; c++) + { + b->line[c] = b->dat + (c * x * 4); + } + b->w = x; + b->h = y; + return b; +} diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp new file mode 100644 index 000000000..e076fb9b1 --- /dev/null +++ b/src/cdrom_dosbox.cpp @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#include +#include +#include +#include +#include +#include +#include //GCC 2.95 +#include +#include +#include +#include "cdrom_dosbox.h" + +#if !defined(WIN32) +#include +#else +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = (int)file->tellg(); + if (file->fail()) return -1; + return length; +} + +CDROM_Interface_Image::CDROM_Interface_Image() +{ +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + ClearTracks(); +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + //printf("Could not load image file: %s\n", path); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = (int)(tracks.size() - 1); + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > (int)tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + track_number = tracks[track - 1].track_number; + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + int cur_track = GetTrack(sector); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success = true; //Gobliiins reads 0 sectors + for(unsigned long i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector + i); + if (!success) break; + } + + memcpy((void*)buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +bool CDROM_Interface_Image::IsMode2(unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + if (tracks[track].mode2) + { + return true; + } + else + { + return false; + } +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + int shift = 0; + int totalPregap = 0; + + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.track_number = 1;//IMPORTANT: This is needed. + track.attr = DATA_TRACK;//data + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.track_number = 0xAA; + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); +} + +#if defined(WIN32) +static string dirname(char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + safe_strncpy(tmp, file, len+1); + return tmp; + } +} +#endif + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + string pathname(dirname(tmp)); + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + track.track_number = track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = AUDIO_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = DATA_TRACK; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.track_number = 0xAA; + // track.attr = 0;//sync with load iso + track.attr = 0x16; /* Was 0x00 but I believe 0x16 is appropriate. */ + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x14 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == DATA_TRACK) return true; + } + return false; +} + +bool CDROM_Interface_Image::HasAudioTracks(void) +{ + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == AUDIO_TRACK) return true; + } + return false; +} + + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = (int)in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h new file mode 100644 index 000000000..39ed79bed --- /dev/null +++ b/src/cdrom_dosbox.h @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#include +#include +#include +#include +#include +#include +//#include "dosbox.h" +//#include "mem.h" +//#include "mixer.h" +//#include "SDL.h" +//#include "SDL_thread.h" + +#include +typedef signed int Bits; +typedef unsigned int Bitu; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; +typedef uint16_t Bit16u; +typedef int32_t Bit32s; +typedef uint32_t Bit32u; + +typedef size_t PhysPt; + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + +extern int CDROM_GetMountType(char* path, int force); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path, int forceCD) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; +}; + +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile() { }; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); + bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool IsMode2 (unsigned long sector); + bool HasDataTrack (void); + bool HasAudioTracks (void); + + int GetTrack (int sector); + +private: + // player +static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; +typedef std::vector::iterator track_it; + std::string mcn; +}; + +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc new file mode 100644 index 000000000..831255db8 --- /dev/null +++ b/src/cdrom_image.cc @@ -0,0 +1,1045 @@ +/* Copyright holders: RichardG867, Tenshi, bit + see COPYING for more details +*/ +/*CD-ROM image support*/ + +#include + +#include "config.h" +#include "cdrom_dosbox.h" +#include "cdrom.h" +#include "cdrom_image.h" +#include "cdrom_null.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include + +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +extern CDROM image_cdrom; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_image_do_log = 0; + +CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; + +void cdrom_image_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_IMAGE_LOG + if (cdrom_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void image_close(uint8_t id); + +void image_audio_callback(uint8_t id, int16_t *output, int len) +{ + if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_image[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + { + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + } + memcpy(output, cdrom_image[id].cd_buffer, len * 2); + memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + cdrom_image[id].cd_buflen -= len; +} + +void image_audio_stop(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdimg[id]) return; + int number; + unsigned char attr; + TMSF tmsf; + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + cdrom_image_log("Can't play data track\n"); + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_state = CD_STOPPED; + return; + } + cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); + pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); + len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_image_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_image_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_image[id].cd_end = len; + cdrom_image[id].cd_state = CD_PLAYING; + if (cdrom[id].seek_pos < 150) + cdrom[id].seek_pos = 150; + cdrom_image[id].cd_buflen = 0; +} + +static void image_pause(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PLAYING) + cdrom_image[id].cd_state = CD_PAUSED; +} + +static void image_resume(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PAUSED) + cdrom_image[id].cd_state = CD_PLAYING; +} + +static void image_stop(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_seek(uint8_t id, uint32_t pos) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_pos = pos; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static int image_ready(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + return 0; + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 1; +} + +static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdimg[id]) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150 here as well. */ + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + { + return 0; + } + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + if (!cdimg[id]) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = cdrom[id].seek_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (cdrom_image[id].image_is_iso) + { + ret = 0x15; + } + else + { + if (cdrom_image[id].cd_state == CD_PLAYING) + ret = 0x11; + else if (cdrom_image[id].cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + } + + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; + + if (msf) + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + } + + return ret; +} + +static void image_eject(uint8_t id) +{ + return; +} + +static void image_load(uint8_t id) +{ + return; +} + +static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m, s, f; + unsigned char attr; + TMSF tmsf; + int number; + + if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +typedef struct __attribute__((__packed__)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((__packed__)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2336]; +} sector_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; +} sector_raw_data_t; + +typedef union __attribute__((__packed__)) +{ + sector_raw_data_t sector_data; + uint8_t raw_data[2352]; +} sector_t; + +typedef struct __attribute__((__packed__)) +{ + sector_t sector; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((__packed__)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; +uint8_t raw_buffer[2352]; +uint8_t extra_buffer[296]; + +static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + uint8_t *b; + uint8_t *temp_b; + int real_pos; + int audio; + int mode2; + + if (!cdimg[id]) + { + return 0; + } + + if (!cdrom_drives[id].host_drive) + { + return 0; + } + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + if (cdrom_image[id].image_is_iso) + { + audio = 0; + mode2 = 0; + } + else + { + audio = image_is_track_audio(id, real_pos, 1); + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; + } + + memset(raw_buffer, 0, 2352); + memset(extra_buffer, 0, 296); + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + { + if (cdrom_sector_type == 3) + { + cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); + } + if (cdrom_sector_type > 4) + { + cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); + } + return 0; + } + else if (cdrom_sector_type == 1) + { + if (!audio || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); + return 0; + } + +read_audio: + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + memcpy(temp_b, raw_buffer, 2352); + } + else if (cdrom_sector_type == 2) + { + if (audio || mode2) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); + return 0; + } + +read_mode1: + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 4; + bb += 2048; + memset(bb, 0, 288); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); + memcpy(temp_b, raw_buffer + 16, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2064, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + } + else if (cdrom_sector_type == 4) + { + if (audio || !mode2 || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); + return 0; + } + +read_mode2: + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); + memcpy(temp_b, raw_buffer + 24, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2072, 280); + cdrom_sector_size += 280; + temp_b += 280; + } + } + else + { + if (mode2) + { + goto read_mode2; + } + else + { + if (audio) + { + goto read_audio; + } + else + { + goto read_mode1; + } + } + } + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Full error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + + *len = cdrom_sector_size; + + return 1; +} + + +static void lba_to_msf(uint8_t *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + +static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdimg[id]) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + +// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + /* + pclog("Table of Contents:\n"); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); + } + for (c = 0;c <= last_track; c++) { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); + } + */ + return len; +} + +static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + + if (!cdimg[id]) return 0; + + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + + if (number == 0) + { + number = 1; + } + + b[2] = 1; + b[3] = 1; + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; /* Do the - 150. */ + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + if (maxlen < len) + { + return maxlen; + } + + return len; +} + +static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + int lb; + + if (!cdimg[id]) return 0; + + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + for (track = first_track; track <= last_track; track++) + { + if ((len + 11) > maxlen) + { + cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + return len; +} + +static int image_status(uint8_t id) +{ + if (!cdimg[id]) return CD_STATUS_EMPTY; + if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; + if (cdimg[id]->HasAudioTracks()) + { + switch(cdrom_image[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } + } + return CD_STATUS_DATA_ONLY; +} + +void image_reset(uint8_t id) +{ +} + +void image_close(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; + if (cdimg[id]) + { + delete cdimg[id]; + cdimg[id] = NULL; + } + memset(cdrom_image[id].image_path, 0, 2048); +} + +static char afn[1024]; + +int image_open(uint8_t id, wchar_t *fn) +{ + if (wcscmp(fn, cdrom_image[id].image_path) != 0) + { + cdrom_image[id].image_changed = 1; + } + + /* Make sure image_changed stays when changing from an image to another image. */ + if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + _swprintf(cdrom_image[id].image_path, L"%ws", fn); + } + + if (!wcsicmp(get_extension_w(fn), L"ISO")) + { + cdrom_image[id].image_is_iso = 1; + } + else + { + cdrom_image[id].image_is_iso = 0; + } + + cdimg[id] = new CDROM_Interface_Image(); + wcstombs(afn, fn, (wcslen(fn) << 1) + 2); + if (!cdimg[id]->SetDevice(afn, false)) + { + image_close(id); + cdrom_set_null_handler(id); + return 1; + } + cdrom_image[id].cd_state = CD_STOPPED; + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_buflen = 0; + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0) + 1; + cdrom_drives[id].handler = &image_cdrom; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + if (!cdrom_image[id].image_inited) + cdrom_image[id].image_inited = 1; + } + + update_status_bar_icon_state(0x10 | id, 0); + return 0; +} + +static void image_exit(uint8_t id) +{ + cdrom_image[id].image_inited = 0; +} + +/* TODO: Check for what data type a mixed CD is. */ +static int image_media_type_id(uint8_t id) +{ + if (!cdrom_image[id].image_is_iso) + { + return 3; /* Mixed mode CD. */ + } + + if (image_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + +CDROM image_cdrom = +{ + image_ready, + image_medium_changed, + image_media_type_id, + image_audio_callback, + image_audio_stop, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + NULL, + image_readsector_raw, + image_playaudio, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit +}; diff --git a/src/cdrom_image.h b/src/cdrom_image.h new file mode 100644 index 000000000..4ea4cb78f --- /dev/null +++ b/src/cdrom_image.h @@ -0,0 +1,28 @@ +/* Copyright holders: RichardG867, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IMAGE_H +#define CDROM_IMAGE_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int image_open(uint8_t id, wchar_t *fn); +extern void image_reset(uint8_t id); + +extern void image_close(uint8_t id); + +void update_status_bar_icon_state(int tag, int state); +extern void cdrom_set_null_handler(uint8_t id); + +void pclog(const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_IMAGE_H */ diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c new file mode 100644 index 000000000..8d8e28612 --- /dev/null +++ b/src/cdrom_ioctl.c @@ -0,0 +1,1099 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +/*Win32 CD-ROM support via IOCTL*/ + +#define WINVER 0x0600 +#include +#include +#include "ntddcdrm.h" +#include "ntddscsi.h" +#include "ibm.h" +#include "cdrom.h" +#include "cdrom_ioctl.h" +#include "scsi.h" + +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +static CDROM ioctl_cdrom; + +typedef struct +{ + HANDLE hIOCTL; + CDROM_TOC toc; +} cdrom_ioctl_windows_t; + +cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_ioctl_do_log = 0; + +void cdrom_ioctl_log(const char *format, ...) +{ +#ifdef ENABLE_CDROM_LOG + if (cdrom_ioctl_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +void ioctl_audio_callback(uint8_t id, int16_t *output, int len) +{ + RAW_READ_INFO in; + DWORD count; + + if (cdrom_ioctl[id].cd_state != CD_PLAYING) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_ioctl[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_ioctl[id].cd_end) + { + in.DiskOffset.LowPart = (cdrom[id].seek_pos - 150) * 2048; + in.DiskOffset.HighPart = 0; + in.SectorCount = 1; + in.TrackMode = CDDA; + ioctl_open(id, 0); + if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) + { + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_ioctl[id].cd_buflen += (2352 / 2); + } + ioctl_close(id); + } + else + { + memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl[id].cd_buflen = len; + } + } + memcpy(output, cdrom_ioctl[id].cd_buffer, len * 2); + memcpy(&cdrom_ioctl[id].cd_buffer[0], &(cdrom_ioctl[id].cd_buffer[len]), (BUF_SIZE - len) * 2); + cdrom_ioctl[id].cd_buflen -= len; +} + +void ioctl_audio_stop(uint8_t id) +{ + cdrom_ioctl[id].cd_state = CD_STOPPED; +} + +static int get_track_nr(uint8_t id, uint32_t pos) +{ + int c; + int track = 0; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + if (cdrom_ioctl[id].last_track_pos == pos) + { + return cdrom_ioctl[id].last_track_nr; + } + + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + uint32_t track_address = cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] * 75) + + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] * 75 * 60); + + if (track_address <= pos) + { + track = c; + } + } + cdrom_ioctl[id].last_track_pos = pos; + cdrom_ioctl[id].last_track_nr = track; + + return track; +} + +static uint32_t get_track_msf(uint8_t id, uint32_t track_no) +{ + int c; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + for (c = cdrom_ioctl_windows[id].toc.FirstTrack; c < cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + if (c == track_no) + { + return cdrom_ioctl_windows[id].toc.TrackData[c].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[2] << 8) + (cdrom_ioctl_windows[id].toc.TrackData[c].Address[1] << 16); + } + } + return 0xffffffff; +} + +static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + if (!cdrom_drives[id].host_drive) + { + return; + } + if (ismsf == 2) + { + start_msf = get_track_msf(id, pos); + end_msf = get_track_msf(id, len); + if (start_msf == 0xffffffff) + { + return; + } + if (end_msf == 0xffffffff) + { + return; + } + m = (start_msf >> 16) & 0xff; + s = (start_msf >> 8) & 0xff; + f = start_msf & 0xff; + pos = MSFtoLBA(m, s, f); + m = (end_msf >> 16) & 0xff; + s = (end_msf >> 8) & 0xff; + f = end_msf & 0xff; + len = MSFtoLBA(m, s, f); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_ioctl_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_ioctl_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_ioctl[id].cd_end = len; + if (cdrom[id].seek_pos < 150) + { + /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ + cdrom[id].seek_pos = 150; + } + cdrom_ioctl[id].cd_state = CD_PLAYING; +} + +static void ioctl_pause(uint8_t id) +{ + if (!cdrom_drives[id].host_drive) + { + return; + } + if (cdrom_ioctl[id].cd_state == CD_PLAYING) + { + cdrom_ioctl[id].cd_state = CD_PAUSED; + } +} + +static void ioctl_resume(uint8_t id) +{ + if (!cdrom_drives[id].host_drive) + { + return; + } + if (cdrom_ioctl[id].cd_state == CD_PAUSED) + { + cdrom_ioctl[id].cd_state = CD_PLAYING; + } +} + +static void ioctl_stop(uint8_t id) +{ + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; +} + +static int ioctl_ready(uint8_t id) +{ + unsigned long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + if (!temp) + { + return 0; + } + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3]) || + !cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + } + return 1; + } + return 1; +} + +static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, int maxlen, int single) +{ + unsigned long size; + int c, d = 0; + CDROM_TOC lbtoc; + int lb = 0; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; + for (c=d; c <= lbtoc.LastTrack; c++) + { + uint32_t address; + address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1], cdrom_ioctl_windows[id].toc.TrackData[c].Address[2], cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + if (address > lb) + { + lb = address; + } + } + return lb; +} + +static int ioctl_medium_changed(uint8_t id) +{ + unsigned long size; + int temp; + CDROM_TOC ltoc; + if (!cdrom_drives[id].host_drive) + { + return 0; /* This will be handled by the not ready handler instead. */ + } + ioctl_open(id, 0); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); + ioctl_close(id); + if (!temp) + { + return 0; /* Drive empty, a not ready handler matter, not disc change. */ + } + if (!cdrom_ioctl[id].tocvalid || (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive)) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; + if (cdrom_drives[id].host_drive != cdrom_drives[id].prev_host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + } + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; + } + else + { + if ((ltoc.TrackData[ltoc.LastTrack].Address[1] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[1]) || + (ltoc.TrackData[ltoc.LastTrack].Address[2] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[2]) || + (ltoc.TrackData[ltoc.LastTrack].Address[3] != cdrom_ioctl_windows[id].toc.TrackData[cdrom_ioctl_windows[id].toc.LastTrack].Address[3])) + { + cdrom_ioctl[id].cd_state = CD_STOPPED; + cdrom_ioctl_log("Setting TOC...\n"); + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); + return 1; /* TOC mismatches. */ + } + } + return 0; /* None of the above, return 0. */ +} + +static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + CDROM_SUB_Q_DATA_FORMAT insub; + SUB_Q_CHANNEL_DATA sub; + unsigned long size; + int pos = 0, track; + uint32_t cdpos, track_address, dat; + + if (!cdrom_drives[id].host_drive) return 0; + + cdpos = cdrom[id].seek_pos; + + if (cdrom_ioctl[id].last_subchannel_pos == cdpos) + { + memcpy(&insub, cdrom_ioctl[id].sub_q_data_format, sizeof(insub)); + memcpy(&sub, cdrom_ioctl[id].sub_q_channel_data, sizeof(sub)); + } + else + { + insub.Format = IOCTL_CDROM_CURRENT_POSITION; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); + ioctl_close(id); + memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); + memcpy(cdrom_ioctl[id].sub_q_data_format, &insub, sizeof(insub)); + memset(cdrom_ioctl[id].sub_q_channel_data, 0, 256); + memcpy(cdrom_ioctl[id].sub_q_channel_data, &sub, sizeof(sub)); + cdrom_ioctl[id].last_subchannel_pos = cdpos; + } + + if (cdrom_ioctl[id].cd_state == CD_PLAYING || cdrom_ioctl[id].cd_state == CD_PAUSED) + { + track = get_track_nr(id, cdpos); + track_address = cdrom_ioctl_windows[id].toc.TrackData[track].Address[3] + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[2] * 75) + (cdrom_ioctl_windows[id].toc.TrackData[track].Address[1] * 75 * 60); + + cdrom_ioctl_log("cdpos = %i, track = %i, track_address = %i\n", cdpos, track, track_address); + + b[pos++] = sub.CurrentPosition.Control; + b[pos++] = track + 1; + b[pos++] = sub.CurrentPosition.IndexNumber; + + if (msf) + { + dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } + + if (cdrom_ioctl[id].cd_state == CD_PLAYING) return 0x11; + return 0x12; + } + + b[pos++]=sub.CurrentPosition.Control; + b[pos++]=sub.CurrentPosition.TrackNumber; + b[pos++]=sub.CurrentPosition.IndexNumber; + + cdrom_ioctl_log("cdpos = %i, track_address = %i\n", MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]), MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3])); + + if (msf) + { + int c; + for (c = 0; c < 4; c++) + { + b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; + } + for (c = 0; c < 4; c++) + { + b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; + } + } + else + { + uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); + b[pos++] = temp >> 24; + b[pos++] = temp >> 16; + b[pos++] = temp >> 8; + b[pos++] = temp; + } + + return 0x13; +} + +static void ioctl_eject(uint8_t id) +{ + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); +} + +static void ioctl_load(uint8_t id) +{ + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); +} + +static int is_track_audio(uint8_t id, uint32_t pos) +{ + int c; + int control = 0; + + uint32_t track_address = 0; + + if (!cdrom_ioctl[id].tocvalid) + { + return 0; + } + + for (c = 0; c <= cdrom_ioctl_windows[id].toc.LastTrack; c++) + { + track_address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + + if (track_address <= pos) + { + control = cdrom_ioctl_windows[id].toc.TrackData[c].Control; + } + } + + if ((control & 0xd) <= 1) + { + return 1; + } + else + { + return 0; + } +} + +static int ioctl_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m = 0, s = 0, f = 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + return is_track_audio(id, pos); +} + +/* 00, 08, 10, 18, 20, 28, 30, 38 */ +int flags_to_size[5][32] = { { 0, 0, 2352, 2352, 2352, 2352, 2352, 2352, /* 00-38 (CD-DA) */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 40-78 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352, /* 80-B8 */ + 2352, 2352, 2352, 2352, 2352, 2352, 2352, 2352 }, /* C0-F8 */ + { 0, 0, 2048, 2336, 4, -296, 2052, 2344, /* 00-38 (Mode 1) */ + 8, -296, 2048, 2048, 12, -296, 2052, 2052, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2064, 2344, /* 80-B8 */ + -296, -296, 2048, 2048, 24, -296, 2064, 2352 }, /* C0-F8 */ + { 0, 0, 2336, 2336, 4, -296, 2340, 2340, /* 00-38 (Mode 2 non-XA) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, 2352, 2340, /* 80-B8 */ + -296, -296, 2336, 2336, 24, -296, 2352, 2352 }, /* C0-F8 */ + { 0, 0, 2048, 2336, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 1) */ + 8, -296, 2056, 2344, 12, -296, 2060, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2072, 2352 }, /* C0-F8 */ + { 0, 0, 2328, 2328, 4, -296, -296, -296, /* 00-38 (Mode 2 Form 2) */ + 8, -296, 2336, 2336, 12, -296, 2340, 2340, /* 40-78 */ + -296, -296, -296, -296, 16, -296, -296, -296, /* 80-B8 */ + -296, -296, -296, -296, 24, -296, 2352, 2352 } /* C0-F8 */ + }; + +static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf); + +static void cdrom_illegal_mode(uint8_t id) +{ + cdrom_sense_key = SENSE_ILLEGAL_REQUEST; + cdrom_asc = ASC_ILLEGAL_MODE_FOR_THIS_TRACK; + cdrom_ascq = 0; +} + +struct sptd_with_sense +{ + SCSI_PASS_THROUGH s; + ULONG Filler; + UCHAR sense[32]; + UCHAR data[65536]; +} sptd; + +static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) +{ + int sector_type = 0; + int temp_len = 0; + + if (no_length_check) + { + switch (cdb[0]) + { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); + default: + return 65534; + } + } + + switch (cdb[0]) + { + case 0x25: + /* READ CAPACITY */ + return 8; + case 0x42: /* READ SUBCHANNEL */ + case 0x43: /* READ TOC */ + case 0x51: /* READ DISC INFORMATION */ + case 0x52: /* READ TRACK INFORMATION */ + case 0x5A: /* MODE SENSE (10) */ + return ((uint16_t) cdb[8]) + (((uint16_t) cdb[7]) << 8); + case 0x08: + case 0x28: + case 0xa8: + /* READ (6), READ (10), READ (12) */ + return 2048 * number_of_blocks; + break; + case 0xb9: + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) + { + sector_type = ioctl_get_sector_data_type(id, 0, cdb[3], cdb[4], cdb[5], 1); + if (sector_type == 0) + { + cdrom_illegal_mode(id); + return -1; + } + } + goto common_handler; + case 0xbe: + /* READ CD MSF, READ CD */ + sector_type = (cdb[1] >> 2) & 7; + if (sector_type == 0) + { + sector_type = ioctl_get_sector_data_type(id, cdb[2], cdb[3], cdb[4], cdb[5], 0); + if (sector_type == 0) + { + cdrom_illegal_mode(id); + return -1; + } + } +common_handler: + temp_len = flags_to_size[sector_type - 1][cdb[9] >> 3]; + if ((cdb[9] & 6) == 2) + { + temp_len += 294; + } + else if ((cdb[9] & 6) == 4) + { + temp_len += 296; + } + if ((cdb[10] & 7) == 1) + { + temp_len += 96; + } + else if ((cdb[10] & 7) == 2) + { + temp_len += 16; + } + else if ((cdb[10] & 7) == 4) + { + temp_len += 96; + } + if (temp_len <= 0) + { + cdrom_illegal_mode(id); + return -1; + } + return temp_len * cdrom[id].requested_blocks; + break; + default: + /* Other commands */ + return 65534; + break; + } + +} + +static int SCSICommand(uint8_t id, const UCHAR *cdb, UCHAR *buf, uint32_t *len, int no_length_check) +{ + DWORD ioctl_bytes; + int ioctl_rv = 0; + + SCSISense.SenseKey = 0; + SCSISense.Asc = 0; + SCSISense.Ascq = 0; + + *len = 0; + memset(&sptd, 0, sizeof(sptd)); + sptd.s.Length = sizeof(SCSI_PASS_THROUGH); + sptd.s.CdbLength = 12; + sptd.s.DataIn = SCSI_IOCTL_DATA_IN; + sptd.s.TimeOutValue = 80 * 60; + sptd.s.DataTransferLength = ioctl_get_block_length(id, cdb, cdrom_ioctl[id].actual_requested_blocks, no_length_check); + sptd.s.SenseInfoOffset = (uintptr_t)&sptd.sense - (uintptr_t)&sptd; + sptd.s.SenseInfoLength = 32; + sptd.s.DataBufferOffset = (uintptr_t)&sptd.data - (uintptr_t)&sptd; + + memcpy(sptd.s.Cdb, cdb, 12); + ioctl_rv = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_SCSI_PASS_THROUGH, &sptd, sizeof(sptd), &sptd, sizeof(sptd), &ioctl_bytes, NULL); + + if (sptd.s.SenseInfoLength) + { + cdrom_sense_key = sptd.sense[2]; + cdrom_asc = sptd.sense[12]; + cdrom_ascq = sptd.sense[13]; + } + + cdrom_ioctl_log("Transferred length: %i (command: %02X)\n", sptd.s.DataTransferLength, cdb[0]); + cdrom_ioctl_log("Sense length: %i (%02X %02X %02X %02X %02X)\n", sptd.s.SenseInfoLength, sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[12], sptd.sense[13]); + cdrom_ioctl_log("IOCTL bytes: %i; SCSI status: %i, status: %i, LastError: %08X\n", ioctl_bytes, sptd.s.ScsiStatus, ioctl_rv, GetLastError()); + cdrom_ioctl_log("DATA: %02X %02X %02X %02X %02X %02X\n", sptd.data[0], sptd.data[1], sptd.data[2], sptd.data[3], sptd.data[4], sptd.data[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[6], sptd.data[7], sptd.data[8], sptd.data[9], sptd.data[10], sptd.data[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.data[12], sptd.data[13], sptd.data[14], sptd.data[15], sptd.data[16], sptd.data[17]); + cdrom_ioctl_log("SENSE: %02X %02X %02X %02X %02X %02X\n", sptd.sense[0], sptd.sense[1], sptd.sense[2], sptd.sense[3], sptd.sense[4], sptd.sense[5]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[6], sptd.sense[7], sptd.sense[8], sptd.sense[9], sptd.sense[10], sptd.sense[11]); + cdrom_ioctl_log(" %02X %02X %02X %02X %02X %02X\n", sptd.sense[12], sptd.sense[13], sptd.sense[14], sptd.sense[15], sptd.sense[16], sptd.sense[17]); + *len = sptd.s.DataTransferLength; + if (sptd.s.DataTransferLength != 0) + { + memcpy(buf, sptd.data, sptd.s.DataTransferLength); + } + + return ioctl_rv; +} + +static void ioctl_read_capacity(uint8_t id, uint8_t *b) +{ + uint32_t len = 0; + + const UCHAR cdb[] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + UCHAR buf[16]; + + if (!cdrom_ioctl[id].capacity_read) + { + ioctl_open(id, 0); + + SCSICommand(id, cdb, buf, &len, 1); + + memcpy(cdrom_ioctl[id].rcbuf, buf, len); + cdrom_ioctl[id].capacity_read = 1; + } + else + { + memcpy(b, cdrom_ioctl[id].rcbuf, 16); + } + + ioctl_close(id); +} + +static int ioctl_media_type_id(uint8_t id) +{ + uint8_t old_sense[3] = { 0, 0, 0 }; + + UCHAR msbuf[28]; + uint32_t len = 0; + int sense = 0; + + const UCHAR cdb[] = { 0x5A, 0x00, 0x2A, 0, 0, 0, 0, 0, 28, 0, 0, 0 }; + + old_sense[0] = cdrom_sense_key; + old_sense[1] = cdrom_asc; + old_sense[2] = cdrom_asc; + + ioctl_open(id, 0); + + SCSICommand(id, cdb, msbuf, &len, 1); + + ioctl_close(id); + + sense = cdrom_sense_key; + cdrom_sense_key = old_sense[0]; + cdrom_asc = old_sense[1]; + cdrom_asc = old_sense[2]; + + if (sense == 0) + { + return msbuf[2]; + } + else + { + return 3; + } +} + +static uint32_t msf_to_lba32(int lba) +{ + int m = (lba >> 16) & 0xff; + int s = (lba >> 8) & 0xff; + int f = lba & 0xff; + return (m * 60 * 75) + (s * 75) + f; +} + +static int ioctl_get_type(uint8_t id, UCHAR *cdb, UCHAR *buf) +{ + int i = 0; + int ioctl_rv = 0; + + uint32_t len = 0; + + for (i = 2; i <= 5; i++) + { + cdb[1] = i << 2; + ioctl_rv = SCSICommand(id, cdb, buf, &len, 1); /* Bypass length check so we don't risk calling this again and getting stuck in an endless up. */ + if (ioctl_rv) + { + return i; + } + } + return 0; +} + +static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) +{ + int ioctl_rv = 0; + UCHAR cdb_lba[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 1, 0x10, 0, 0 }; + UCHAR cdb_msf[] = { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0, 0 }; + UCHAR buf[2352]; + + cdb_lba[2] = (sector >> 24); + cdb_lba[3] = ((sector >> 16) & 0xff); + cdb_lba[4] = ((sector >> 8) & 0xff); + cdb_lba[5] = (sector & 0xff); + + cdb_msf[3] = cdb_msf[6] = ((sector >> 16) & 0xff); + cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); + cdb_msf[5] = cdb_msf[8] = (sector & 0xff); + + ioctl_open(id, 0); + + if (ioctl_is_track_audio(id, sector, ismsf)) + { + return 1; + } + + if (ismsf) + { + ioctl_rv = ioctl_get_type(id, cdb_msf, buf); + } + else + { + ioctl_rv = ioctl_get_type(id, cdb_lba, buf); + } + + if (ioctl_rv) + { + ioctl_close(id); + return ioctl_rv; + } + + if (ismsf) + { + sector = msf_to_lba32(sector); + if (sector < 150) + { + ioctl_close(id); + return 0; + } + sector -= 150; + ioctl_rv = ioctl_get_type(id, (UCHAR *) cdb_lba, buf); + } + + ioctl_close(id); + return ioctl_rv; +} + +static int ioctl_get_sector_data_type(uint8_t id, uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3, int ismsf) +{ + int sector = b3; + sector |= ((uint32_t) b2) << 8; + sector |= ((uint32_t) b1) << 16; + sector |= ((uint32_t) b0) << 24; + return ioctl_sector_data_type(id, sector, ismsf); +} + +static void ioctl_validate_toc(uint8_t id) +{ + unsigned long size; + if (!cdrom_drives[id].host_drive) + { + return; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_open(id, 0); + cdrom_ioctl_log("Validating TOC...\n"); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid=1; +} + +UCHAR buf[262144]; + +static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) +{ + const UCHAR cdb[12]; + + int ret = 0; + + int block_length = 0; + + int temp_block_length = 0; + int temp_pos = 0; + + int blocks_at_once = 0; + int buffer_pos = 0; + + int transferred_blocks = 0; + + uint32_t temp_len = 0; + int chunk = 0; + + if (in_cdb[0] == 0x43) + { + /* This is a read TOC, so we have to validate the TOC to make the rest of the emulator happy. */ + ioctl_validate_toc(id); + } + + ioctl_open(id, 0); + + memcpy((void *) cdb, in_cdb, 12); + + temp_block_length = ioctl_get_block_length(id, cdb, cdrom[id].requested_blocks, 0); + *len = 0; + if (temp_block_length != -1) + { + if (temp_block_length > 65534) + { + block_length = temp_block_length / cdrom[id].requested_blocks; + blocks_at_once = 32768 / block_length; + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is bigger than 65534, splitting the transfer into chunks of %i blocks...\n", id, temp_block_length, blocks_at_once); + + buffer_pos = 0; + temp_pos = cdrom[id].sector_pos; + transferred_blocks = 0; + temp_len = 0; + +split_block_read_iterate: + chunk = (cdrom[id].requested_blocks - transferred_blocks); + if (chunk < blocks_at_once) + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is less than a complete split block\n", id, chunk); + cdrom_ioctl[id].actual_requested_blocks = chunk; + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): The remaining chunk (%i blocks) is more or equal than a complete split block\n", id, chunk); + cdrom_ioctl[id].actual_requested_blocks = blocks_at_once; + } + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Transferring %i blocks...\n", id, cdrom_ioctl[id].actual_requested_blocks); + cdrom_update_cdb((uint8_t *) cdb, temp_pos, cdrom_ioctl[id].actual_requested_blocks); + ret = SCSICommand(id, cdb, buf + buffer_pos, &temp_len, 0); + *len += temp_len; + transferred_blocks += cdrom_ioctl[id].actual_requested_blocks; + if (ret && (transferred_blocks < cdrom[id].requested_blocks)) + { + /* Return value was successful and there are still more blocks left to transfer. */ + temp_pos += cdrom_ioctl[id].actual_requested_blocks; + buffer_pos += (cdrom_ioctl[id].actual_requested_blocks * block_length); + goto split_block_read_iterate; + } + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Split transfer done\n", id); + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is smaller than 65534, transferring all at once...\n", id, temp_block_length); + cdrom_ioctl[id].actual_requested_blocks = cdrom[id].requested_blocks; + ret = SCSICommand(id, cdb, buf, len, 0); + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Single transfer done\n", id); + } + memcpy(b, buf, *len); + } + else + { + cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); + } + + cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + + ioctl_close(id); + + cdrom_ioctl_log("IOCTL Returned value: %i\n", ret); + + return ret; +} + +static uint32_t ioctl_size(uint8_t id) +{ + uint8_t capacity_buffer[8]; + uint32_t capacity = 0; + ioctl_read_capacity(id, capacity_buffer); + capacity = ((uint32_t) capacity_buffer[0]) << 24; + capacity |= ((uint32_t) capacity_buffer[1]) << 16; + capacity |= ((uint32_t) capacity_buffer[2]) << 8; + capacity |= (uint32_t) capacity_buffer[3]; + return capacity + 1; +} + +static int ioctl_status(uint8_t id) +{ + if (!(ioctl_ready(id)) && (cdrom_drives[id].host_drive <= 0)) + { + return CD_STATUS_EMPTY; + } + + switch(cdrom_ioctl[id].cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + return CD_STATUS_STOPPED; + default: + return CD_STATUS_EMPTY; + } +} + +void ioctl_reset(uint8_t id) +{ + CDROM_TOC ltoc; + unsigned long size; + + if (!cdrom_drives[id].host_drive) + { + cdrom_ioctl[id].tocvalid = 0; + return; + } + + ioctl_open(id, 0); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + + cdrom_ioctl_windows[id].toc = ltoc; + cdrom_ioctl[id].tocvalid = 1; +} + +int ioctl_open(uint8_t id, char d) +{ + if (!cdrom_ioctl[id].ioctl_inited) + { + sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); + cdrom_ioctl[id].tocvalid=0; + } + cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + cdrom_drives[id].handler = &ioctl_cdrom; + if (!cdrom_ioctl[id].ioctl_inited) + { + cdrom_ioctl[id].ioctl_inited=1; + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; + update_status_bar_icon_state(0x10 | id, 0); + } + return 0; +} + +void ioctl_close(uint8_t id) +{ + if (cdrom_ioctl_windows[id].hIOCTL) + { + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; + } +} + +static void ioctl_exit(uint8_t id) +{ + ioctl_stop(id); + cdrom_ioctl[id].ioctl_inited=0; + cdrom_ioctl[id].tocvalid=0; +} + +static CDROM ioctl_cdrom= +{ + ioctl_ready, + ioctl_medium_changed, + ioctl_media_type_id, + ioctl_audio_callback, + ioctl_audio_stop, + NULL, + NULL, + NULL, + ioctl_getcurrentsubchannel, + ioctl_pass_through, + NULL, + ioctl_playaudio, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit +}; diff --git a/src/cdrom_ioctl.h b/src/cdrom_ioctl.h new file mode 100644 index 000000000..e39f12ddf --- /dev/null +++ b/src/cdrom_ioctl.h @@ -0,0 +1,17 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IOCTL_H +#define CDROM_IOCTL_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +extern uint32_t cdrom_capacity; + +extern int ioctl_open(uint8_t id, char d); +extern void ioctl_reset(uint8_t id); + +extern void ioctl_close(uint8_t id); + +#endif /* ! CDROM_IOCTL_H */ diff --git a/src/cdrom_ioctl_linux.c b/src/cdrom_ioctl_linux.c new file mode 100644 index 000000000..bf1f73994 --- /dev/null +++ b/src/cdrom_ioctl_linux.c @@ -0,0 +1,725 @@ +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ +/*Linux CD-ROM support via IOCTL*/ + +#include +#include +#include +#include +#include "ibm.h" +#include "ide.h" +#include "cdrom_ioctl.h" + +static ATAPI ioctl_atapi; + +static uint32_t last_block = 0; +static uint32_t cdrom_capacity = 0; +static int ioctl_inited = 0; +static char ioctl_path[8]; +static int tocvalid = 0; +static struct cdrom_tocentry toc[100]; +static int first_track, last_track; + +int old_cdrom_drive; + +#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)-150) + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +static int ioctl_cd_state = CD_STOPPED; +static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; +#define BUF_SIZE 32768 +static int16_t cd_buffer[BUF_SIZE]; +static int cd_buflen = 0; +void ioctl_audio_callback(int16_t *output, int len) +{ + int fd; + struct cdrom_read_audio read_audio; + +// pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); + if (ioctl_cd_state != CD_PLAYING) + { + memset(output, 0, len * 2); + return; + } + fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + { + memset(output, 0, len * 2); + return; + } + + while (cd_buflen < len) + { + if (ioctl_cd_pos < ioctl_cd_end) + { + read_audio.addr.lba = ioctl_cd_pos - 150; + read_audio.addr_format = CDROM_LBA; + read_audio.nframes = 1; + read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; + + if (ioctl(fd, CDROMREADAUDIO, &read_audio) < 0) + { +// pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + else + { +// pclog("DeviceIoControl returned true\n"); + ioctl_cd_pos++; + cd_buflen += (2352 / 2); + } + } + else + { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + ioctl_cd_state = CD_STOPPED; + cd_buflen = len; + } + } + close(fd); + memcpy(output, cd_buffer, len * 2); +// for (c = 0; c < BUF_SIZE - len; c++) +// cd_buffer[c] = cd_buffer[c + cd_buflen]; + memcpy(&cd_buffer[0], &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; +// pclog("Done %i\n", GetTickCount()); +} + +void ioctl_audio_stop() +{ + ioctl_cd_state = CD_STOPPED; +} + +static int get_track_nr(uint32_t pos) +{ + int c; + int track = 0; + + if (!tocvalid) + return 0; + + for (c = first_track; c < last_track; c++) + { + uint32_t track_address = toc[c].cdte_addr.msf.frame + + (toc[c].cdte_addr.msf.second * 75) + + (toc[c].cdte_addr.msf.minute * 75 * 60); +//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + track = c; + } + return track; +} + +static int is_track_audio(uint32_t pos) +{ + int c; + int control = 0; + + if (!tocvalid) + return 0; + + for (c = first_track; c < last_track; c++) + { + uint32_t track_address = toc[c].cdte_addr.msf.frame + + (toc[c].cdte_addr.msf.second * 75) + + (toc[c].cdte_addr.msf.minute * 75 * 60); +//pclog("get_track_nr: track=%i pos=%x track_address=%x\n", c, pos, track_address); + if (track_address <= pos) + control = toc[c].cdte_ctrl; + } + return (control & 4) ? 0 : 1; +} + +static int ioctl_is_track_audio(uint32_t pos, int ismsf) +{ + if (ismsf) + { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + return is_track_audio(pos); +} + +static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) +{ +// pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) + { + pos = (pos & 0xff) + (((pos >> 8) & 0xff) * 75) + (((pos >> 16) & 0xff) * 75 * 60); + len = (len & 0xff) + (((len >> 8) & 0xff) * 75) + (((len >> 16) & 0xff) * 75 * 60); +// pclog("MSF - pos = %08X len = %08X\n", pos, len); + } + else + len += pos; + ioctl_cd_pos = pos;// + 150; + ioctl_cd_end = pos+len;// + 150; + ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_pos < 150) + ioctl_cd_pos = 150; +// pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); +} + +static void ioctl_pause(void) +{ + if (ioctl_cd_state == CD_PLAYING) + ioctl_cd_state = CD_PAUSED; +} + +static void ioctl_resume(void) +{ + if (ioctl_cd_state == CD_PAUSED) + ioctl_cd_state = CD_PLAYING; +} + +static void ioctl_stop(void) +{ + ioctl_cd_state = CD_STOPPED; +} + +static void ioctl_seek(uint32_t pos) +{ +// pclog("Seek %08X\n", pos); + ioctl_cd_pos = pos; + ioctl_cd_state = CD_STOPPED; +} + +static int read_toc(int fd, struct cdrom_tocentry *btoc) +{ + struct cdrom_tochdr toc_hdr; + int track, err; +//pclog("read_toc\n"); + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return 0; + } + + first_track = toc_hdr.cdth_trk0; + last_track = toc_hdr.cdth_trk1; +//pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); + memset(btoc, 0, sizeof(cdrom_tocentry)); + + for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) + { + btoc[track].cdte_track = track; + btoc[track].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &btoc[track]); + if (err == -1) + { +// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); + return 0; + } +// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + } + return 1; +} + +static int ioctl_ready(void) +{ + long size; + int temp; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc_entry; + int err; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + close(fd); + return 0; + } +// pclog("CDROMREADTOCHDR: start track=%i end track=%i\n", toc_hdr.cdth_trk0, toc_hdr.cdth_trk1); + toc_entry.cdte_track = toc_hdr.cdth_trk1; + toc_entry.cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); + if (err == -1) + { + close(fd); + return 0; + } +// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); + if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || + (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || + (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame ) || + !tocvalid) + { + int track; + ioctl_cd_state = CD_STOPPED; + + tocvalid = read_toc(fd, toc); + close(fd); + return 1; + } + close(fd); + return 1; +} + +static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + int c; + int lb = 0; + int tv = 0; + struct cdrom_tocentry lbtoc[100]; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + ioctl_cd_state = CD_STOPPED; + + tv = read_toc(fd, lbtoc); + + close(fd); + + if (!tv) + return 0; + + last_block = 0; + for (c = 0; c <= last_track; c++) + { + uint32_t address; + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address > last_block) + lb = address; + } + return lb; +} + +static int ioctl_medium_changed(void) +{ + long size; + int temp; + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc_entry; + int err; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + close(fd); + return 0; + } + toc_entry.cdte_track = toc_hdr.cdth_trk1; + toc_entry.cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &toc_entry); + if (err == -1) + { + close(fd); + return 0; + } +// pclog("CDROMREADTOCENTRY: addr=%02i:%02i:%02i\n", toc_entry.cdte_addr.msf.minute, toc_entry.cdte_addr.msf.second, toc_entry.cdte_addr.msf.frame); + if ((toc_entry.cdte_addr.msf.minute != toc[toc_hdr.cdth_trk1].cdte_addr.msf.minute) || + (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || + (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame )) + { + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); + return 1; + } + return 0; +} + +static uint8_t ioctl_getcurrentsubchannel(uint8_t *b, int msf) +{ + struct cdrom_subchnl sub; + uint32_t cdpos = ioctl_cd_pos; + int track = get_track_nr(cdpos); + uint32_t track_address = toc[track].cdte_addr.msf.frame + + (toc[track].cdte_addr.msf.second * 75) + + (toc[track].cdte_addr.msf.minute * 75 * 60); + long size; + int pos=0; + int err; + uint8_t ret; +//pclog("ioctl_getsubchannel: cdpos=%x track_address=%x track=%i\n", cdpos, track_address, track); + if (ioctl_cd_state == CD_PLAYING) + ret = 0x11; + else if (ioctl_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + + b[pos++] = (toc[track].cdte_adr << 4) | toc[track].cdte_ctrl; + b[pos++] = track; + b[pos++] = 0; + + if (msf) + { + uint32_t dat = cdpos; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = cdpos - track_address; + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + cdpos -= track_address; + b[pos++] = (cdpos >> 24) & 0xff; + b[pos++] = (cdpos >> 16) & 0xff; + b[pos++] = (cdpos >> 8) & 0xff; + b[pos++] = cdpos & 0xff; + } + + return ret; +} + +static void ioctl_eject(void) +{ + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return; + + ioctl(fd, CDROMEJECT); + + close(fd); +} + +static void ioctl_load(void) +{ + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return; + + ioctl(fd, CDROMEJECT); + + close(fd); + + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); +} + +union +{ + struct cdrom_msf *msf; + char b[CD_FRAMESIZE_RAW]; +} raw_read_params; + +static int lba_to_msf(int lba) +{ + return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); +} + +static int ioctl_sector_data_type(int sector, int ismsf) +{ + return 2; /* Always Mode 1 */ +} + +static void ioctl_readsector_raw(uint8_t *b, int sector) +{ + int err; + int imsf = lba_to_msf(sector); + int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (cdrom <= 0) + return; + + raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); + raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; + raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; + raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; + + /* This will read the actual raw sectors from the disc. */ + err = ioctl(cdrom, CDROMREADRAW, (void *) &raw_read_params); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return; + } + + memcpy(b, raw_read_params.b, 2352); + + close(cdrom); + + free(raw_read_params.msf); +} + +static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + int len=4; + long size; + int c,d; + uint32_t temp; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + ioctl_cd_state = CD_STOPPED; + + tocvalid = read_toc(fd, toc); + + close(fd); + + if (!tocvalid) + return 4; + +// pclog("Read TOC done! %i\n",single); + b[2] = first_track; + b[3] = last_track; + d = 0; +//pclog("Read TOC starttrack=%i\n", starttrack); + for (c = 1; c <= last_track; c++) + { + if (toc[c].cdte_track >= starttrack) + { + d = c; + break; + } + } + b[2] = toc[c].cdte_track; + last_block = 0; + for (c = d; c <= last_track; c++) + { + uint32_t address; + if ((len + 8) > maxlen) + break; +// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + b[len++] = 0; /*Reserved*/ + b[len++] = (toc[c].cdte_adr << 4) | toc[c].cdte_ctrl; + b[len++] = toc[c].cdte_track; + b[len++] = 0; /*Reserved*/ + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address > last_block) + last_block = address; + + if (msf) + { + b[len++] = 0; + b[len++] = toc[c].cdte_addr.msf.minute; + b[len++] = toc[c].cdte_addr.msf.second; + b[len++] = toc[c].cdte_addr.msf.frame; + } + else + { + temp = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); +/* pclog("Table of Contents (%i bytes) : \n", size); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, 0, toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + for (c = 0;c <= last_track; c++) + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, toc[c].cdte_track, toc[c].cdte_ctrl, toc[c].cdte_adr, MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame));*/ + return len; +} + +static int ioctl_readtoc_session(unsigned char *b, int msf, int maxlen) +{ + struct cdrom_multisession session; + int len = 4; + int err; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + session.addr_format = CDROM_MSF; + err = ioctl(fd, CDROMMULTISESSION, &session); + + if (err == -1) + { + close(fd); + return 0; + } + + b[2] = 0; + b[3] = 0; + b[len++] = 0; /*Reserved*/ + b[len++] = (toc[0].cdte_adr << 4) | toc[0].cdte_ctrl; + b[len++] = toc[0].cdte_track; + b[len++] = 0; /*Reserved*/ + if (msf) + { + b[len++] = 0; + b[len++] = session.addr.msf.minute; + b[len++] = session.addr.msf.second; + b[len++] = session.addr.msf.frame; + } + else + { + uint32_t temp = MSFtoLBA(session.addr.msf.minute, session.addr.msf.second, session.addr.msf.frame); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int ioctl_readtoc_raw(unsigned char *b, int maxlen) +{ + struct cdrom_tochdr toc_hdr; + struct cdrom_tocentry toc2[100]; + int track, err; + int len = 4; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); +//pclog("read_toc\n"); + if (fd <= 0) + return 0; + + err = ioctl(fd, CDROMREADTOCHDR, &toc_hdr); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return 0; + } + + b[2] = toc_hdr.cdth_trk0; + b[3] = toc_hdr.cdth_trk1; + + //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); + memset(toc, 0, sizeof(toc)); + + for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) + { + if ((len + 11) > maxlen) + { + pclog("ioctl_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + close(fd); + return len; + } + + toc2[track].cdte_track = track; + toc2[track].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &toc2[track]); + if (err == -1) + { +// pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); + close(fd); + return 0; + } +// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + + b[len++] = toc2[track].cdte_track; + b[len++]= (toc2[track].cdte_adr << 4) | toc[track].cdte_ctrl; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++] = toc2[track].cdte_addr.msf.minute; + b[len++] = toc2[track].cdte_addr.msf.second; + b[len++] = toc2[track].cdte_addr.msf.frame; + } + close(fd); + return len; +} + +static uint32_t ioctl_size() +{ + return cdrom_capacity; +} + +static int ioctl_status() +{ + if (!(ioctl_ready) && (cdrom_drive <= 0)) return CD_STATUS_EMPTY; + + switch(ioctl_cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + return CD_STATUS_STOPPED; + } +} +void ioctl_reset() +{ + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); +//pclog("ioctl_reset: fd=%i\n", fd); + tocvalid = 0; + + if (fd <= 0) + return; + + tocvalid = read_toc(fd, toc); + + close(fd); +} + +int ioctl_open(char d) +{ + atapi=&ioctl_atapi; + return 0; +} + +void ioctl_close(void) +{ +} + +static void ioctl_exit(void) +{ + ioctl_stop(); + ioctl_inited = 0; + tocvalid=0; +} + +static ATAPI ioctl_atapi= +{ + ioctl_ready, + ioctl_medium_changed, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, + ioctl_getcurrentsubchannel, + NULL, + NULL, + NULL, + ioctl_sector_data_type, + ioctl_readsector_raw, + ioctl_playaudio, + ioctl_seek, + ioctl_load, + ioctl_eject, + ioctl_pause, + ioctl_resume, + ioctl_size, + ioctl_status, + ioctl_is_track_audio, + ioctl_stop, + ioctl_exit +}; diff --git a/src/cdrom_null.c b/src/cdrom_null.c new file mode 100644 index 000000000..5d86b7992 --- /dev/null +++ b/src/cdrom_null.c @@ -0,0 +1,130 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include "ibm.h" +#include "cdrom.h" +#include "cdrom_ioctl.h" + +static CDROM null_cdrom; + +static int null_ready(uint8_t id) +{ + return 0; +} + +/* Always return 0, the contents of a null CD-ROM drive never change. */ +static int null_medium_changed(uint8_t id) +{ + return 0; +} + +static uint8_t null_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + return 0x13; +} + +static void null_eject(uint8_t id) +{ +} + +static void null_load(uint8_t id) +{ +} + +static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + *len = 0; + return 0; +} + +static int null_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + return 0; +} + +static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + return 0; +} + +static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + return 0; +} + +static uint32_t null_size(uint8_t id) +{ + return 0; +} + +static int null_status(uint8_t id) +{ + return CD_STATUS_EMPTY; +} + +void cdrom_null_reset(uint8_t id) +{ +} + +void cdrom_set_null_handler(uint8_t id); + +int cdrom_null_open(uint8_t id, char d) +{ + cdrom_set_null_handler(id); + return 0; +} + +void null_close(uint8_t id) +{ +} + +static void null_exit(uint8_t id) +{ +} + +static int null_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + return 0; +} + +static int null_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len) +{ + return 0; +} + +static int null_media_type_id(uint8_t id) +{ + return 0x70; +} + +void cdrom_set_null_handler(uint8_t id) +{ + cdrom_drives[id].handler = &null_cdrom; + cdrom_drives[id].host_drive = 0; + update_status_bar_icon_state(0x10 | id, 1); +} + +static CDROM null_cdrom = +{ + null_ready, + null_medium_changed, + null_media_type_id, + NULL, + NULL, + null_readtoc, + null_readtoc_session, + null_readtoc_raw, + null_getcurrentsubchannel, + null_pass_through, + null_readsector_raw, + NULL, + null_load, + null_eject, + NULL, + NULL, + null_size, + null_status, + null_is_track_audio, + NULL, + null_exit +}; diff --git a/src/cdrom_null.h b/src/cdrom_null.h new file mode 100644 index 000000000..7217760ca --- /dev/null +++ b/src/cdrom_null.h @@ -0,0 +1,14 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifndef CDROM_NULL_H +#define CDROM_NULL_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +int cdrom_null_open(uint8_t id, char d); +void cdrom_null_reset(uint8_t id); +void null_close(uint8_t id); + +#endif /* ! CDROM_NULL_H */ From 8d1ef28e86bd37dc42d3d64e9f924b8dda18461b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 21:07:45 +0200 Subject: [PATCH 230/392] Changed GetWindowLong and SetWindowLong to GetWindowLongPtr and SetWindowLongPtr, this should allow the emulator to compile for Win64 again. --- src/WIN/win.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index a56660e20..cec80f549 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -107,7 +107,7 @@ LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -LONG OriginalStatusBarProcedure; +LONG_PTR OriginalStatusBarProcedure; HWND ghwnd; @@ -1255,8 +1255,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); - OriginalStatusBarProcedure = GetWindowLong(hwndStatus, GWL_WNDPROC); - SetWindowLong(hwndStatus, GWL_WNDPROC, (LONG) &StatusBarProcedure); + OriginalStatusBarProcedure = GetWindowLongPtr(hwndStatus, GWL_WNDPROC); + SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); initmenu(); From 69292b62ae8ff83e67893710753a41cefc76b24a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 21:15:37 +0200 Subject: [PATCH 231/392] More such WindowLong fixes in win.c; Fixed CD-ROM Bus setting in Settings. --- src/WIN/win.c | 13 +++++-------- src/WIN/win_settings.c | 4 ++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index cec80f549..39d31d071 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1255,7 +1255,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); - OriginalStatusBarProcedure = GetWindowLongPtr(hwndStatus, GWL_WNDPROC); + OriginalStatusBarProcedure = GetWindowLongPtr(hwndStatus, GWLP_WNDPROC); SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); @@ -1273,10 +1273,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } } - if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); - else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); - - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); + if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)|WS_VISIBLE); + else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ for (e = 0; e < CDROM_NUM; e++) @@ -1754,9 +1752,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_VID_RESIZE: vid_resize=!vid_resize; CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); - if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE); - else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE); - SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX); + if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)|WS_VISIBLE); + else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); GetWindowRect(hwnd,&rect); SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); GetWindowRect(hwndStatus,&rect); diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 6916bca28..522fd7b19 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -3355,7 +3355,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type - 1, 0); } else { @@ -3413,7 +3413,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type, 0); + SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type - 1, 0); } else { From d7676794d2833ca086912b42c483df198ad220fd Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 21:22:15 +0200 Subject: [PATCH 232/392] The code in win-midi.c no longer messes with the host MIDI device ID, should fix the bug where it did not get saved correctly; All the temporary variables in win_settings.c are now static. --- src/WIN/win_midi.c | 4 +--- src/WIN/win_settings.c | 28 ++++++++++++++-------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c index 2fdf58bec..5ce523a0a 100644 --- a/src/WIN/win_midi.c +++ b/src/WIN/win_midi.c @@ -7,7 +7,7 @@ #include "../config.h" #include "plat_midi.h" -int midi_id; +int midi_id = 0; static HMIDIOUT midi_out_device = NULL; HANDLE m_event; @@ -57,8 +57,6 @@ void midi_init() midi_sysex_start = midi_sysex_delay = 0; - midi_id = config_get_int(NULL, "midi", 0); - m_event = CreateEvent(NULL, TRUE, TRUE, NULL); hr = midiOutOpen(&midi_out_device, midi_id, (DWORD) m_event, diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 522fd7b19..e889d2849 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -39,40 +39,40 @@ /* Machine category */ -int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; +static int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; /* Video category */ -int temp_gfxcard, temp_video_speed, temp_voodoo; +static int temp_gfxcard, temp_video_speed, temp_voodoo; /* Input devices category */ -int temp_mouse, temp_joystick; +static int temp_mouse, temp_joystick; /* Sound category */ -int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; +static int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; /* Network category */ -int temp_net_type, temp_net_card; -char temp_pcap_dev[520]; +static int temp_net_type, temp_net_card; +static char temp_pcap_dev[520]; /* Peripherals category */ -int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; -int temp_serial[2], temp_lpt, temp_bugger; +static int temp_scsi_card, hdc_ignore, temp_ide_ter, temp_ide_ter_irq, temp_ide_qua, temp_ide_qua_irq; +static int temp_serial[2], temp_lpt, temp_bugger; -char temp_hdc_name[16]; +static char temp_hdc_name[16]; /* Hard disks category */ -hard_disk_t temp_hdc[HDC_NUM]; -wchar_t temp_hdd_fn[HDC_NUM][512]; +static hard_disk_t temp_hdc[HDC_NUM]; +static wchar_t temp_hdd_fn[HDC_NUM][512]; /* Removable devices category */ -int temp_fdd_types[FDD_NUM]; -cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; +static int temp_fdd_types[FDD_NUM]; +static cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; static HWND hwndParentDialog, hwndChildDialog; int hdd_controller_current; -int displayed_category = 0; +static int displayed_category = 0; extern int is486; static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; From c669a05662002a1ed1b8cc1904fce962bce6c8d0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 21:51:11 +0200 Subject: [PATCH 233/392] Fixed Host MIDI Out Device ID saving; Did the UI-related preparations for adding removable hard disks. --- src/WIN/86Box.rc | 128 ++++++++++++++++++++++++++++++++++++++++++--- src/WIN/resource.h | 49 +++++++++++++++++ src/WIN/win.c | 73 +++++++++++++++++++++----- src/config.c | 46 +++------------- src/hdd_esdi.c | 6 +-- src/ide.c | 26 ++++----- src/mfm_at.c | 12 ++--- src/mfm_xebec.c | 10 ++-- src/scsi_disk.c | 14 ++--- 9 files changed, 268 insertions(+), 96 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index fb5d56296..f8f59b460 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -92,6 +92,118 @@ BEGIN MENUITEM SEPARATOR MENUITEM "&Image...", IDM_CDROM_4_IMAGE END + POPUP "Removable disk 01" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_01_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_01_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_01_IMAGE + END + POPUP "Removable disk 02" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_02_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_02_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_02_IMAGE + END + POPUP "Removable disk 03" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_03_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_03_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_03_IMAGE + END + POPUP "Removable disk 04" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_04_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_04_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_04_IMAGE + END + POPUP "Removable disk 05" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_05_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_05_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_05_IMAGE + END + POPUP "Removable disk 06" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_06_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_06_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_06_IMAGE + END + POPUP "Removable disk 07" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_07_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_07_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_07_IMAGE + END + POPUP "Removable disk 08" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_08_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_08_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_08_IMAGE + END + POPUP "Removable disk 09" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_09_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_09_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_09_IMAGE + END + POPUP "Removable disk 10" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_10_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_10_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_10_IMAGE + END + POPUP "Removable disk 11" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_11_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_11_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_11_IMAGE + END + POPUP "Removable disk 12" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_12_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_12_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_12_IMAGE + END + POPUP "Removable disk 13" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_13_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_13_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_13_IMAGE + END + POPUP "Removable disk 14" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_14_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_14_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_14_IMAGE + END + POPUP "Removable disk 15" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_15_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_15_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_15_IMAGE + END + POPUP "Removable disk 16" + BEGIN + MENUITEM "E&mpty", IDM_RDISK_16_EMPTY + MENUITEM "&Reload previous disc", IDM_RDISK_16_RELOAD + MENUITEM SEPARATOR + MENUITEM "&Image...", IDM_RDISK_16_IMAGE + END END MAINMENU MENU DISCARDABLE @@ -536,14 +648,14 @@ END 163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" 164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" 165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" -177 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" -178 ICON DISCARDABLE "ICONS/hard_disk.ico" -179 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -180 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -181 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -182 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -183 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +192 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" +193 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" +194 ICON DISCARDABLE "ICONS/hard_disk.ico" +195 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +196 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +197 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +198 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +199 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" 256 ICON DISCARDABLE "ICONS/machine.ico" 257 ICON DISCARDABLE "ICONS/video.ico" 258 ICON DISCARDABLE "ICONS/input_devices.ico" diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 5364bf674..5342c8b5b 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -180,6 +180,55 @@ #define IDM_CDROM_4_EMPTY 40179 #define IDM_CDROM_4_REAL 40195 +#define IDM_RDISK_01_IMAGE 3200 +#define IDM_RDISK_01_RELOAD 3216 +#define IDM_RDISK_01_EMPTY 3232 +#define IDM_RDISK_02_IMAGE 3201 +#define IDM_RDISK_02_RELOAD 3217 +#define IDM_RDISK_02_EMPTY 3233 +#define IDM_RDISK_03_IMAGE 3202 +#define IDM_RDISK_03_RELOAD 3218 +#define IDM_RDISK_03_EMPTY 3234 +#define IDM_RDISK_04_IMAGE 3203 +#define IDM_RDISK_04_RELOAD 3219 +#define IDM_RDISK_04_EMPTY 3235 +#define IDM_RDISK_05_IMAGE 3204 +#define IDM_RDISK_05_RELOAD 3220 +#define IDM_RDISK_05_EMPTY 3236 +#define IDM_RDISK_06_IMAGE 3205 +#define IDM_RDISK_06_RELOAD 3221 +#define IDM_RDISK_06_EMPTY 3237 +#define IDM_RDISK_07_IMAGE 3206 +#define IDM_RDISK_07_RELOAD 3222 +#define IDM_RDISK_07_EMPTY 3238 +#define IDM_RDISK_08_IMAGE 3207 +#define IDM_RDISK_08_RELOAD 3223 +#define IDM_RDISK_08_EMPTY 3239 +#define IDM_RDISK_09_IMAGE 3208 +#define IDM_RDISK_09_RELOAD 3224 +#define IDM_RDISK_09_EMPTY 3240 +#define IDM_RDISK_10_IMAGE 3209 +#define IDM_RDISK_10_RELOAD 3225 +#define IDM_RDISK_10_EMPTY 3241 +#define IDM_RDISK_11_IMAGE 3210 +#define IDM_RDISK_11_RELOAD 3226 +#define IDM_RDISK_11_EMPTY 3242 +#define IDM_RDISK_12_IMAGE 3211 +#define IDM_RDISK_12_RELOAD 3227 +#define IDM_RDISK_12_EMPTY 3243 +#define IDM_RDISK_13_IMAGE 3212 +#define IDM_RDISK_13_RELOAD 3228 +#define IDM_RDISK_13_EMPTY 3244 +#define IDM_RDISK_14_IMAGE 3213 +#define IDM_RDISK_14_RELOAD 3229 +#define IDM_RDISK_14_EMPTY 3245 +#define IDM_RDISK_15_IMAGE 3214 +#define IDM_RDISK_15_RELOAD 3230 +#define IDM_RDISK_15_EMPTY 3246 +#define IDM_RDISK_16_IMAGE 3215 +#define IDM_RDISK_16_RELOAD 3231 +#define IDM_RDISK_16_EMPTY 3247 + #define IDM_IDE_TER_ENABLED 44000 #define IDM_IDE_TER_IRQ9 44009 #define IDM_IDE_TER_IRQ10 44010 diff --git a/src/WIN/win.c b/src/WIN/win.c index 39d31d071..010b67f61 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -696,7 +696,7 @@ void update_status_bar_icon(int tag, int active) int found = -1; int temp_flags = 0; - if ((tag & 0xf0) >= 0x30) + if ((tag & 0xf0) >= 0x40) { return; } @@ -833,7 +833,7 @@ void update_tip(int meaning) if (part != -1) { - switch(meaning & 0x30) + switch(meaning & 0xf0) { case 0x00: create_floppy_tip(part); @@ -841,7 +841,12 @@ void update_tip(int meaning) case 0x10: create_cdrom_tip(part); break; +#if 0 case 0x20: + create_removable_hd_tip(part); + break; +#endif + case 0x30: create_hd_tip(part); break; default: @@ -883,7 +888,7 @@ void status_settextw(wchar_t *wstr) for (i = 0; i < sb_parts; i++) { - if (sb_part_meanings[i] == 0x30) + if (sb_part_meanings[i] == 0x40) { part = i; } @@ -949,32 +954,44 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } +#if 0 + for (i = 0; i < 16; i++) + { + if (hdc[i].bus == 5) + { + edge += sb_icon_width; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = 0x20 | i; + sb_parts++; + } + } +#endif if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x20; + sb_part_meanings[sb_parts] = 0x30; sb_parts++; } if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x21; + sb_part_meanings[sb_parts] = 0x31; sb_parts++; } if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x22; + sb_part_meanings[sb_parts] = 0x32; sb_parts++; } if (c_scsi) { edge += sb_icon_width; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x23; + sb_part_meanings[sb_parts] = 0x33; sb_parts++; } if (sb_parts) @@ -982,14 +999,14 @@ void update_status_bar_panes(HWND hwnds) iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); } iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = 0x30; + sb_part_meanings[sb_parts] = 0x40; sb_parts++; SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); for (i = 0; i < sb_parts; i++) { - switch (sb_part_meanings[i] & 0x30) + switch (sb_part_meanings[i] & 0xf0) { case 0x00: /* Floppy */ @@ -1030,12 +1047,20 @@ void update_status_bar_panes(HWND hwnds) sb_part_icons[i] = j | sb_icon_flags[i]; create_cdrom_tip(i); break; +#if 0 case 0x20: + /* Removable hard disk */ + sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_part_icons[i] = 176 + sb_icon_flags[i]; + create_floppy_tip(i); + break; +#endif + case 0x30: /* Hard disk */ - sb_part_icons[i] = 176 + ((sb_part_meanings[i] & 0xf) << 1); + sb_part_icons[i] = 192 + ((sb_part_meanings[i] & 0xf) << 1); create_hd_tip(i); break; - case 0x30: + case 0x40: /* Status text */ SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); sb_part_icons[i] = -1; @@ -1082,7 +1107,14 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) hIcon[i] = LoadIconEx((PCTSTR) i); } - for (i = 176; i < 184; i++) +#if 0 + for (i = 176; i < 178; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } +#endif + + for (i = 192; i < 200; i++) { hIcon[i] = LoadIconEx((PCTSTR) i); } @@ -1107,6 +1139,13 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) hIcon[i] = LoadIconEx((PCTSTR) i); } +#if 0 + for (i = 432; i < 434; i++) + { + hIcon[i] = LoadIconEx((PCTSTR) i); + } +#endif + GetWindowRect(hwndParent, &rectDialog); dw = rectDialog.right - rectDialog.left; dh = rectDialog.bottom - rectDialog.top; @@ -2192,14 +2231,20 @@ VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) pt.x = id * sb_icon_width; /* Justify to the left. */ pt.y = 0; /* Justify to the top. */ ClientToScreen(hwnd, (LPPOINT) &pt); - if ((sb_part_meanings[id] & 0x30) == 0x00) + if ((sb_part_meanings[id] & 0xf0) == 0x00) { menu_id = sb_part_meanings[id] & 0xf; } - else if ((sb_part_meanings[id] & 0x30) == 0x10) + else if ((sb_part_meanings[id] & 0xf0) == 0x10) { menu_id = (sb_part_meanings[id] & 0xf) + 4; } +#if 0 + else if ((sb_part_meanings[id] & 0xf0) == 0x20) + { + menu_id = (sb_part_meanings[id] & 0xf) + 8; + } +#endif if (menu_id != -1) { pmenu = GetSubMenu(smenu, menu_id); diff --git a/src/config.c b/src/config.c index a24772e19..a335ab55a 100644 --- a/src/config.c +++ b/src/config.c @@ -997,15 +997,7 @@ static void loadconfig_hard_disks(void) sprintf(temps, "hdd_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", c, 0); p = config_get_string(cat, temps, temps2); - if (p != NULL) - { - sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); - } - else - { - /* FIXME: Can never happen, 'temps' above is non-NULL. */ - sscanf(temps2, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); - } + sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); if (hdc[c].scsi_id > 15) { @@ -1019,12 +1011,7 @@ static void loadconfig_hard_disks(void) memset(hdd_fn[c], 0, 1024); sprintf(temps, "hdd_%02i_fn", c + 1); wp = config_get_wstring(cat, temps, L""); - /*FIXME: wcslen(wp) instead of 512? */ - if (wp) memcpy(hdd_fn[c], wp, 512); - else { - memcpy(hdd_fn[c], L"", 2); - hdd_fn[c][0] = L'\0'; - } + memcpy(hdd_fn[c], wp, (wcslen(wp) << 1) + 2); } } @@ -1044,10 +1031,7 @@ static void loadconfig_removable_devices(void) { sprintf(temps, "fdd_%02i_type", c + 1); p = config_get_string(cat, temps, (c < 2) ? "525_2dd" : "none"); - if (p) - fdd_set_type(c, fdd_get_from_internal_name(p)); - else /*FIXME: never happens, "none" is non-NULL */ - fdd_set_type(c, (c < 2) ? 2 : 0); + fdd_set_type(c, fdd_get_from_internal_name(p)); if (fdd_get_type(c) > 13) { fdd_set_type(c, 13); @@ -1055,12 +1039,7 @@ static void loadconfig_removable_devices(void) sprintf(temps, "fdd_%02i_fn", c + 1); wp = config_get_wstring(cat, temps, L""); - /*FIXME: see above, wcslen(wp) ? */ - if (wp) memcpy(discfns[c], wp, 512); - else { - memcpy(discfns[c], L"", 2); - discfns[c][0] = L'\0'; - } + memcpy(discfns[c], wp, (wcslen(wp) << 1) + 2); printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); ui_writeprot[c] = !!config_get_int(cat, temps, 0); @@ -1096,15 +1075,7 @@ static void loadconfig_removable_devices(void) sprintf(temps, "cdrom_%02i_scsi_location", c + 1); sprintf(temps2, "%02u:%02u", c + 2, 0); p = config_get_string(cat, temps, temps2); - if (p != NULL) - { - sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); - } - else /*FIXME: never happens, 'temps2' is non-NULL */ - { - sscanf(temps2, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); - } - + sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); if (cdrom_drives[c].scsi_device_id > 15) { @@ -1117,12 +1088,7 @@ static void loadconfig_removable_devices(void) sprintf(temps, "cdrom_%02i_image_path", c + 1); wp = config_get_wstring(cat, temps, L""); - /*FIXME see above, wcslen(wp) */ - if (wp != NULL) memcpy(cdrom_image[c].image_path, wp, 512); - else { - memcpy(cdrom_image[c].image_path, L"", 2); - cdrom_image[c].image_path[0] = L'\0'; - } + memcpy(cdrom_image[c].image_path, wp, (wcslen(wp) << 1) + 2); } } diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index f40345933..a6f5ce466 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -433,7 +433,7 @@ static void esdi_callback(void *p) fatal("Read past end of drive\n"); fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); fread(esdi->data, 512, 1, drive->hdfile); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); } while (esdi->data_pos < 256) { @@ -522,11 +522,11 @@ static void esdi_callback(void *p) fwrite(esdi->data, 512, 1, drive->hdfile); esdi->rba++; esdi->sector_pos++; - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); esdi->data_pos = 0; } - update_status_bar_icon(0x20, 0); + update_status_bar_icon(0x30, 0); esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; diff --git a/src/ide.c b/src/ide.c index 18db7d4d6..1308fcf89 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1399,7 +1399,7 @@ uint32_t ide_read_data(int ide_board, int length) } else { - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); } } } @@ -1722,7 +1722,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); return; case WIN_READ_DMA: @@ -1756,12 +1756,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); } else { ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); } } } @@ -1799,7 +1799,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); return; case WIN_WRITE: @@ -1822,12 +1822,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); } return; @@ -1863,12 +1863,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); } else { ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); } } } @@ -1899,12 +1899,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 0); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); } return; @@ -1921,7 +1921,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); + update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); return; case WIN_FORMAT: @@ -1943,7 +1943,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x22 : 0x21, 1); */ + /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: diff --git a/src/mfm_at.c b/src/mfm_at.c index c4c1be484..f0dd98ed1 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -439,7 +439,7 @@ uint16_t mfm_readw(uint16_t port, void *p) } else { - update_status_bar_icon(0x20, 0); + update_status_bar_icon(0x30, 0); } } } @@ -505,7 +505,7 @@ void mfm_callback(void *p) mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); break; case CMD_WRITE: @@ -526,12 +526,12 @@ void mfm_callback(void *p) mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm->pos = 0; mfm_next_sector(mfm); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); } else { mfm->status = STAT_READY | STAT_DSC; - update_status_bar_icon(0x20, 0); + update_status_bar_icon(0x30, 0); } break; @@ -540,7 +540,7 @@ void mfm_callback(void *p) mfm->pos = 0; mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); break; case CMD_FORMAT: @@ -560,7 +560,7 @@ void mfm_callback(void *p) } mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); break; case CMD_DIAGNOSE: diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index fdbe7e7b3..d7b80d831 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -374,7 +374,7 @@ static void xebec_callback(void *p) xebec_complete(xebec); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); break; default: @@ -431,7 +431,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); } if (xebec->irq_dma_mask & DMA_ENA) xebec->callback = XEBEC_TIME; @@ -485,7 +485,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); xebec->state = STATE_SEND_DATA; @@ -500,7 +500,7 @@ static void xebec_callback(void *p) else { xebec_complete(xebec); - update_status_bar_icon(0x20, 0); + update_status_bar_icon(0x30, 0); } break; @@ -572,7 +572,7 @@ static void xebec_callback(void *p) fwrite(xebec->sector_buf, 512, 1, drive->hdfile); } - update_status_bar_icon(0x20, 1); + update_status_bar_icon(0x30, 1); xebec_next_sector(xebec); xebec->data_pos = 0; diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 31623fbed..859a9fbbd 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -852,11 +852,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x23, 1); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 1); } else { - update_status_bar_icon(0x23, 0); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); } return; @@ -913,11 +913,11 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x23, 1); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 1); } else { - update_status_bar_icon(0x23, 0); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); } return; @@ -1129,7 +1129,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].status = READY_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0xFF; - update_status_bar_icon(0x23, 0); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); return; case CDROM_PHASE_DATA_OUT: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); @@ -1142,7 +1142,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon(0x23, 0); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); return; case CDROM_PHASE_DATA_IN: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); @@ -1155,7 +1155,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon(0x23, 0); + update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); return; case CDROM_PHASE_ERROR: scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); From c3c1b3eba13801e4ca44c7644bcd89f17f32ed73 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 18 May 2017 23:21:56 +0200 Subject: [PATCH 234/392] Applied the mainline PCem S3 fix. --- src/VIDEO/vid_s3.c | 190 +++++++++++++++++++++++++-------------------- 1 file changed, 105 insertions(+), 85 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index ae5c8c701..de67496d7 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -407,11 +407,19 @@ static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); } else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } } } @@ -421,38 +429,40 @@ static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - if ((s3->accel.cmd & 0x600) == 0x400) + if (s3->accel.cmd & 0x400) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); s3_accel_start(32, 1, val, 0, s3); + } else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(16, 1, val >> 16, 0, s3); + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); } - else if (!(s3->accel.cmd & 0x600)) + else { - s3_accel_start(8, 1, val >> 24, 0, s3); + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); s3_accel_start(8, 1, val >> 16, 0, s3); - s3_accel_start(8, 1, val >> 8, 0, s3); - s3_accel_start(8, 1, val, 0, s3); } } else { - if ((s3->accel.cmd & 0x600) == 0x400) + if (s3->accel.cmd & 0x400) s3_accel_start(4, 1, 0xffffffff, val, s3); else if ((s3->accel.cmd & 0x600) == 0x200) { - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); } - else if (!(s3->accel.cmd & 0x600)) + else { - s3_accel_start(1, 1, 0xffffffff, val >> 24, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 8, s3); s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); } } } @@ -565,78 +575,88 @@ static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { - if (addr & 0x8000) - { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } + if (addr & 0x8000) + { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } + else + { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + } } static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { - if (addr & 0x8000) - { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - if ((s3->accel.cmd & 0x600) == 0x400) - s3_accel_start(32, 1, val, 0, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(16, 1, val >> 16, 0, s3); - s3_accel_start(16, 1, val, 0, s3); - } - else if (!(s3->accel.cmd & 0x600)) - { - s3_accel_start(8, 1, val >> 24, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - s3_accel_start(8, 1, val >> 8, 0, s3); - s3_accel_start(8, 1, val, 0, s3); - } - } - else - { - if ((s3->accel.cmd & 0x600) == 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else if (!(s3->accel.cmd & 0x600)) - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 8, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 24, s3); - } - } - } - } + if (addr & 0x8000) + { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x400) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } + else if ((s3->accel.cmd & 0x600) == 0x200) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } + else + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } + else + { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) + { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + else + { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } + } } static void fifo_thread(void *param) From 03587514bbc15e80ef1b81ddc98cb3f495a13cc6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 19 May 2017 00:25:16 +0200 Subject: [PATCH 235/392] Fixed a bug in the DOSBox track position return code to no longer incorrectly offset the relative position by 150 sectors (2 frames), fixes track time counters in Sony CD Player for DOS and DOS Navigator. --- src/SOUND/sound.c | 12 ------------ src/cdrom.c | 2 +- src/cdrom_dosbox.cpp | 4 +++- src/cdrom_image.cc | 22 ++++++++++++---------- src/cdrom_ioctl.c | 8 ++++++-- 5 files changed, 22 insertions(+), 26 deletions(-) diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index c3086b8e1..24cf2c1c1 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -143,18 +143,6 @@ static void sound_cd_thread(void *param) cd_out_buffer[c] = 0.0; cd_out_buffer[c+1] = 0.0; } - has_audio = 0; - for (i = 0; i < CDROM_NUM; i++) - { - if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) - { - has_audio++; - } - } - if (!has_audio) - { - return; - } for (i = 0; i < CDROM_NUM; i++) { has_audio = 0; diff --git a/src/cdrom.c b/src/cdrom.c index 60ad3afe5..b40e9248f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2920,7 +2920,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) max_len |= cdb[8]; msf = (cdb[1] >> 1) & 1; - cdrom_log("CD-ROM %i: Getting page %i\n", id, cdb[3]); + cdrom_log("CD-ROM %i: Getting page %i (%s)\n", id, cdb[3], msf ? "MSF" : "LBA"); if ((cdrom_drives[id].handler->pass_through) && (cdb[3] != 1)) { ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index e076fb9b1..53223a775 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -125,7 +125,9 @@ bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigne attr = tracks[track - 1].attr; index = 1; FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); - FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + /* FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); */ + /* Note by Kotori: Yes, the absolute position should be adjusted by 150, but not the relative position. */ + FRAMES_TO_MSF(sector - tracks[track - 1].start, &relPos.min, &relPos.sec, &relPos.fr); return true; } diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 831255db8..6c14bf2c2 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -59,8 +59,12 @@ void image_close(uint8_t id); void image_audio_callback(uint8_t id, int16_t *output, int len) { - if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + if (!cdrom_drives[id].sound_on || (cdrom_image[id].cd_state != CD_PLAYING) || cdrom_image[id].image_is_iso) { + if (cdrom_ioctl[id].cd_state == CD_PLAYING) + { + cdrom[id].seek_pos += (len >> 11); + } memset(output, 0, len * 2); return; } @@ -292,22 +296,20 @@ static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (msf) { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; + b[pos + 3] = (uint8_t) absPos.fr; + b[pos + 2] = (uint8_t) absPos.sec; + b[pos + 1] = (uint8_t) absPos.min; b[pos] = 0; pos += 4; - dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); - b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; - b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; - b[pos + 1] = (uint8_t)dat; + b[pos + 3] = (uint8_t) relPos.fr; + b[pos + 2] = (uint8_t) relPos.sec; + b[pos + 1] = (uint8_t) relPos.min; b[pos] = 0; pos += 4; } else { - uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr) - 150; b[pos++] = (dat >> 24) & 0xff; b[pos++] = (dat >> 16) & 0xff; b[pos++] = (dat >> 8) & 0xff; diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index 8d8e28612..5da98bda6 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -53,8 +53,12 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) RAW_READ_INFO in; DWORD count; - if (cdrom_ioctl[id].cd_state != CD_PLAYING) + if (!cdrom_drives[id].sound_on || (cdrom_ioctl[id].cd_state != CD_PLAYING)) { + if (cdrom_ioctl[id].cd_state == CD_PLAYING) + { + cdrom[id].seek_pos += (len >> 11); + } memset(output, 0, len * 2); return; } @@ -395,7 +399,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) if (msf) { - dat = cdpos; + dat = cdpos + 150; b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; b[pos + 1] = (uint8_t)dat; From d5a65e6e578f40c8a611048ea6b1ef4b8e8a1e88 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 19 May 2017 01:16:04 +0200 Subject: [PATCH 236/392] Added more code for SCSI removable hard disk emulation, only the UI parts (and testing) are left now. --- src/WIN/86Box.rc | 88 ++++++++++++--------- src/WIN/resource.h | 80 +++++++++++-------- src/scsi_disk.c | 186 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 284 insertions(+), 70 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index f8f59b460..a593212e4 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -61,7 +61,7 @@ BEGIN MENUITEM "&Mute", IDM_CDROM_1_MUTE MENUITEM SEPARATOR MENUITEM "E&mpty", IDM_CDROM_1_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD + MENUITEM "&Reload previous image", IDM_CDROM_1_RELOAD MENUITEM SEPARATOR MENUITEM "&Image...", IDM_CDROM_1_IMAGE END @@ -70,7 +70,7 @@ BEGIN MENUITEM "&Mute", IDM_CDROM_2_MUTE MENUITEM SEPARATOR MENUITEM "E&mpty", IDM_CDROM_2_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD + MENUITEM "&Reload previous image", IDM_CDROM_2_RELOAD MENUITEM SEPARATOR MENUITEM "&Image...", IDM_CDROM_2_IMAGE END @@ -79,7 +79,7 @@ BEGIN MENUITEM "&Mute", IDM_CDROM_3_MUTE MENUITEM SEPARATOR MENUITEM "E&mpty", IDM_CDROM_3_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD + MENUITEM "&Reload previous image", IDM_CDROM_3_RELOAD MENUITEM SEPARATOR MENUITEM "&Image...", IDM_CDROM_3_IMAGE END @@ -88,121 +88,137 @@ BEGIN MENUITEM "&Mute", IDM_CDROM_4_MUTE MENUITEM SEPARATOR MENUITEM "E&mpty", IDM_CDROM_4_EMPTY - MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD + MENUITEM "&Reload previous image", IDM_CDROM_4_RELOAD MENUITEM SEPARATOR MENUITEM "&Image...", IDM_CDROM_4_IMAGE END POPUP "Removable disk 01" BEGIN MENUITEM "E&mpty", IDM_RDISK_01_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_01_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_01_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_01_IMAGE + MENUITEM "&New image...", IDM_RDISK_01_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_01_EIMAGE END POPUP "Removable disk 02" BEGIN MENUITEM "E&mpty", IDM_RDISK_02_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_02_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_02_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_02_IMAGE + MENUITEM "&New image...", IDM_RDISK_02_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_02_EIMAGE END POPUP "Removable disk 03" BEGIN MENUITEM "E&mpty", IDM_RDISK_03_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_03_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_03_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_03_IMAGE + MENUITEM "&New image...", IDM_RDISK_03_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_03_EIMAGE END POPUP "Removable disk 04" BEGIN MENUITEM "E&mpty", IDM_RDISK_04_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_04_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_04_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_04_IMAGE + MENUITEM "&New image...", IDM_RDISK_04_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_04_EIMAGE END POPUP "Removable disk 05" BEGIN MENUITEM "E&mpty", IDM_RDISK_05_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_05_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_05_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_05_IMAGE + MENUITEM "&New image...", IDM_RDISK_05_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_05_EIMAGE END POPUP "Removable disk 06" BEGIN MENUITEM "E&mpty", IDM_RDISK_06_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_06_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_06_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_06_IMAGE + MENUITEM "&New image...", IDM_RDISK_06_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_06_EIMAGE END POPUP "Removable disk 07" BEGIN MENUITEM "E&mpty", IDM_RDISK_07_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_07_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_07_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_07_IMAGE + MENUITEM "&New image...", IDM_RDISK_07_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_07_EIMAGE END POPUP "Removable disk 08" BEGIN MENUITEM "E&mpty", IDM_RDISK_08_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_08_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_08_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_08_IMAGE + MENUITEM "&New image...", IDM_RDISK_08_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_08_EIMAGE END POPUP "Removable disk 09" BEGIN MENUITEM "E&mpty", IDM_RDISK_09_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_09_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_09_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_09_IMAGE + MENUITEM "&New image...", IDM_RDISK_09_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_09_EIMAGE END POPUP "Removable disk 10" BEGIN MENUITEM "E&mpty", IDM_RDISK_10_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_10_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_10_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_10_IMAGE + MENUITEM "&New image...", IDM_RDISK_10_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_10_EIMAGE END POPUP "Removable disk 11" BEGIN MENUITEM "E&mpty", IDM_RDISK_11_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_11_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_11_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_11_IMAGE + MENUITEM "&New image...", IDM_RDISK_11_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_11_EIMAGE END POPUP "Removable disk 12" BEGIN MENUITEM "E&mpty", IDM_RDISK_12_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_12_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_12_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_12_IMAGE + MENUITEM "&New image...", IDM_RDISK_12_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_12_EIMAGE END POPUP "Removable disk 13" BEGIN MENUITEM "E&mpty", IDM_RDISK_13_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_13_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_13_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_13_IMAGE + MENUITEM "&New image...", IDM_RDISK_13_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_13_EIMAGE END POPUP "Removable disk 14" BEGIN MENUITEM "E&mpty", IDM_RDISK_14_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_14_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_14_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_14_IMAGE + MENUITEM "&New image...", IDM_RDISK_14_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_14_EIMAGE END POPUP "Removable disk 15" BEGIN MENUITEM "E&mpty", IDM_RDISK_15_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_15_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_15_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_15_IMAGE + MENUITEM "&New image...", IDM_RDISK_15_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_15_EIMAGE END POPUP "Removable disk 16" BEGIN MENUITEM "E&mpty", IDM_RDISK_16_EMPTY - MENUITEM "&Reload previous disc", IDM_RDISK_16_RELOAD + MENUITEM "&Reload previous image", IDM_RDISK_16_RELOAD MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_RDISK_16_IMAGE + MENUITEM "&New image...", IDM_RDISK_16_IMAGE + MENUITEM "&Existing image...", IDM_RDISK_16_EIMAGE END END diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 5342c8b5b..d70d84a2d 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -181,53 +181,69 @@ #define IDM_CDROM_4_REAL 40195 #define IDM_RDISK_01_IMAGE 3200 -#define IDM_RDISK_01_RELOAD 3216 -#define IDM_RDISK_01_EMPTY 3232 +#define IDM_RDISK_01_EIMAGE 3216 +#define IDM_RDISK_01_RELOAD 3232 +#define IDM_RDISK_01_EMPTY 3248 #define IDM_RDISK_02_IMAGE 3201 -#define IDM_RDISK_02_RELOAD 3217 -#define IDM_RDISK_02_EMPTY 3233 +#define IDM_RDISK_02_EIMAGE 3217 +#define IDM_RDISK_02_RELOAD 3233 +#define IDM_RDISK_02_EMPTY 3249 #define IDM_RDISK_03_IMAGE 3202 -#define IDM_RDISK_03_RELOAD 3218 -#define IDM_RDISK_03_EMPTY 3234 +#define IDM_RDISK_03_EIMAGE 3218 +#define IDM_RDISK_03_RELOAD 3234 +#define IDM_RDISK_03_EMPTY 3250 #define IDM_RDISK_04_IMAGE 3203 -#define IDM_RDISK_04_RELOAD 3219 -#define IDM_RDISK_04_EMPTY 3235 +#define IDM_RDISK_04_EIMAGE 3219 +#define IDM_RDISK_04_RELOAD 3235 +#define IDM_RDISK_04_EMPTY 3251 #define IDM_RDISK_05_IMAGE 3204 -#define IDM_RDISK_05_RELOAD 3220 -#define IDM_RDISK_05_EMPTY 3236 +#define IDM_RDISK_05_EIMAGE 3220 +#define IDM_RDISK_05_RELOAD 3236 +#define IDM_RDISK_05_EMPTY 3252 #define IDM_RDISK_06_IMAGE 3205 -#define IDM_RDISK_06_RELOAD 3221 -#define IDM_RDISK_06_EMPTY 3237 +#define IDM_RDISK_06_EIMAGE 3221 +#define IDM_RDISK_06_RELOAD 3237 +#define IDM_RDISK_06_EMPTY 3253 #define IDM_RDISK_07_IMAGE 3206 -#define IDM_RDISK_07_RELOAD 3222 -#define IDM_RDISK_07_EMPTY 3238 +#define IDM_RDISK_07_EIMAGE 3222 +#define IDM_RDISK_07_RELOAD 3238 +#define IDM_RDISK_07_EMPTY 3254 #define IDM_RDISK_08_IMAGE 3207 -#define IDM_RDISK_08_RELOAD 3223 -#define IDM_RDISK_08_EMPTY 3239 +#define IDM_RDISK_08_EIMAGE 3223 +#define IDM_RDISK_08_RELOAD 3239 +#define IDM_RDISK_08_EMPTY 3255 #define IDM_RDISK_09_IMAGE 3208 -#define IDM_RDISK_09_RELOAD 3224 -#define IDM_RDISK_09_EMPTY 3240 +#define IDM_RDISK_09_EIMAGE 3224 +#define IDM_RDISK_09_RELOAD 3240 +#define IDM_RDISK_09_EMPTY 3256 #define IDM_RDISK_10_IMAGE 3209 -#define IDM_RDISK_10_RELOAD 3225 -#define IDM_RDISK_10_EMPTY 3241 +#define IDM_RDISK_10_EIMAGE 3225 +#define IDM_RDISK_10_RELOAD 3241 +#define IDM_RDISK_10_EMPTY 3257 #define IDM_RDISK_11_IMAGE 3210 -#define IDM_RDISK_11_RELOAD 3226 -#define IDM_RDISK_11_EMPTY 3242 +#define IDM_RDISK_11_EIMAGE 3226 +#define IDM_RDISK_11_RELOAD 3242 +#define IDM_RDISK_11_EMPTY 3258 #define IDM_RDISK_12_IMAGE 3211 -#define IDM_RDISK_12_RELOAD 3227 -#define IDM_RDISK_12_EMPTY 3243 +#define IDM_RDISK_12_EIMAGE 3227 +#define IDM_RDISK_12_RELOAD 3243 +#define IDM_RDISK_12_EMPTY 3259 #define IDM_RDISK_13_IMAGE 3212 -#define IDM_RDISK_13_RELOAD 3228 -#define IDM_RDISK_13_EMPTY 3244 +#define IDM_RDISK_13_EIMAGE 3228 +#define IDM_RDISK_13_RELOAD 3244 +#define IDM_RDISK_13_EMPTY 3260 #define IDM_RDISK_14_IMAGE 3213 -#define IDM_RDISK_14_RELOAD 3229 -#define IDM_RDISK_14_EMPTY 3245 +#define IDM_RDISK_14_EIMAGE 3229 +#define IDM_RDISK_14_RELOAD 3245 +#define IDM_RDISK_14_EMPTY 3261 #define IDM_RDISK_15_IMAGE 3214 -#define IDM_RDISK_15_RELOAD 3230 -#define IDM_RDISK_15_EMPTY 3246 +#define IDM_RDISK_15_EIMAGE 3230 +#define IDM_RDISK_15_RELOAD 3246 +#define IDM_RDISK_15_EMPTY 3262 #define IDM_RDISK_16_IMAGE 3215 -#define IDM_RDISK_16_RELOAD 3231 -#define IDM_RDISK_16_EMPTY 3247 +#define IDM_RDISK_16_EIMAGE 3231 +#define IDM_RDISK_16_RELOAD 3247 +#define IDM_RDISK_16_EMPTY 3263 #define IDM_IDE_TER_ENABLED 44000 #define IDM_IDE_TER_IRQ9 44009 diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 859a9fbbd..624172d00 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -73,7 +73,9 @@ uint8_t scsi_hd_command_flags[0x100] = 0, 0, 0, 0, 0, 0, 0, IMPLEMENTED | ALLOW_UA, /* 0x12 */ IMPLEMENTED | CHECK_READY | NONDATA | SCSI_ONLY, /* 0x13 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, + IMPLEMENTED | CHECK_READY, /* 0x1B */ + 0, 0, IMPLEMENTED | CHECK_READY, /* 0x1E */ 0, 0, 0, 0, 0, 0, IMPLEMENTED | CHECK_READY, /* 0x25 */ @@ -475,6 +477,10 @@ static void scsi_hd_sense_clear(int id, int command) static void scsi_hd_cmd_error(uint8_t id) { shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; + if (shdc[id].unit_attention) + { + shdc[id].error |= MCR_ERR; + } shdc[id].status = READY_STAT | ERR_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0x80; @@ -482,6 +488,28 @@ static void scsi_hd_cmd_error(uint8_t id) scsi_hd_log("SCSI HD %i: ERROR: %02X/%02X/%02X\n", id, scsi_hd_sense_key, scsi_hd_asc, scsi_hd_ascq); } +static void scsi_hd_unit_attention(uint8_t id) +{ + shdc[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; + if (cdrom[id].unit_attention) + { + shdc[id].error |= MCR_ERR; + } + shdc[id].status = READY_STAT | ERR_STAT; + shdc[id].phase = 3; + shdc[id].packet_status = 0x80; + shdc[id].callback = 50 * CDROM_TIME; + scsi_hd_log("SCSI HD %i: UNIT ATTENTION\n", id); +} + +static void scsi_hd_not_ready(uint8_t id) +{ + scsi_hd_sense_key = SENSE_NOT_READY; + scsi_hd_asc = ASC_MEDIUM_NOT_PRESENT; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + static void scsi_hd_invalid_lun(uint8_t id) { scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; @@ -625,6 +653,11 @@ int scsi_hd_read_blocks(uint8_t id, uint32_t *len, int first_batch) return 1; } +void scsi_disk_insert(uint8_t id) +{ + shdc[id].unit_attention = (hdc[id].bus == 5) ? 1 : 0; +} + /*SCSI Sense Initialization*/ void scsi_hd_sense_code_ok(uint8_t id) { @@ -635,6 +668,8 @@ void scsi_hd_sense_code_ok(uint8_t id) int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) { + int ready = 1; + if (((shdc[id].request_length >> 5) & 7) != hdc[id].scsi_lun) { scsi_hd_log("SCSI HD %i: Attempting to execute a unknown command targeted at SCSI LUN %i\n", id, ((shdc[id].request_length >> 5) & 7)); @@ -649,6 +684,55 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) return 0; } + if (hdc[id].bus == 5) + { + /* Removable disk, set ready state. */ + if (wcslen(hdd_fn[id]) > 0) + { + ready = 1; + } + else + { + ready = 0; + } + } + else + { + /* Fixed disk, clear UNIT ATTENTION, just in case it might have been set when the disk was removable). */ + shdc[id].unit_attention = 0; + } + + if (!ready && shdc[id].unit_attention) + { + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + shdc[id].unit_attention = 0; + } + + /* If the UNIT ATTENTION condition is set and the command does not allow + execution under it, error out and report the condition. */ + if (shdc[id].unit_attention == 1) + { + /* Only increment the unit attention phase if the command can not pass through it. */ + if (!(scsi_hd_command_flags[cdb[0]] & ALLOW_UA)) + { + /* scsi_hd_log("SCSI HD %i: Unit attention now 2\n", id); */ + shdc[id].unit_attention = 2; + scsi_hd_log("SCSI HD %i: UNIT ATTENTION: Command %02X not allowed to pass through\n", id, cdb[0]); + scsi_hd_unit_attention(id); + return 0; + } + } + else if (shdc[id].unit_attention == 2) + { + if (cdb[0] != GPCMD_REQUEST_SENSE) + { + /* scsi_hd_log("SCSI HD %i: Unit attention now 0\n", id); */ + shdc[id].unit_attention = 0; + } + } + /* Unless the command is REQUEST SENSE, clear the sense. This will *NOT* the UNIT ATTENTION condition if it's set. */ if (cdb[0] != GPCMD_REQUEST_SENSE) @@ -656,6 +740,14 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) scsi_hd_sense_clear(id, cdb[0]); } + /* Next it's time for NOT READY. */ + if ((scsi_hd_command_flags[cdb[0]] & CHECK_READY) && !ready) + { + scsi_hd_log("SCSI HD %i: Not ready (%02X)\n", id, cdb[0]); + scsi_hd_not_ready(id); + return 0; + } + scsi_hd_log("SCSI HD %i: Continuing with command\n", id); return 1; @@ -692,14 +784,56 @@ void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) buffer[0] = 0x70; + if (shdc[id].unit_attention && (scsi_hd_sense_key == 0)) + { + buffer[2]=SENSE_UNIT_ATTENTION; + buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; + buffer[13]=0; + } + /* scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, hdbufferb[2], hdbufferb[12], hdbufferb[13]); */ + if (buffer[2] == SENSE_UNIT_ATTENTION) + { + /* If the last remaining sense is unit attention, clear + that condition. */ + shdc[id].unit_attention = 0; + } + /* Clear the sense stuff as per the spec. */ scsi_hd_sense_clear(id, GPCMD_REQUEST_SENSE); } void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { + int ready = 1; + + if (hdc[id].bus == 5) + { + /* Removable disk, set ready state. */ + if (wcslen(hdd_fn[id]) > 0) + { + ready = 1; + } + else + { + ready = 0; + } + } + else + { + /* Fixed disk, clear UNIT ATTENTION, just in case it might have been set when the disk was removable). */ + shdc[id].unit_attention = 0; + } + + if (!ready && shdc[id].unit_attention) + { + /* If the drive is not ready, there is no reason to keep the + UNIT ATTENTION condition present, as we only use it to mark + disc changes. */ + shdc[id].unit_attention = 0; + } + /* Do *NOT* advance the unit attention phase. */ scsi_hd_request_sense(id, buffer, alloc_length); @@ -772,6 +906,16 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) scsi_hd_command_complete(id); break; + case GPCMD_PREVENT_REMOVAL: + if (hdc[id].bus != 5) + { + scsi_hd_illegal_opcode(id); + break; + } + + scsi_hd_command_complete(id); + break; + case GPCMD_REZERO_UNIT: shdc[id].sector_pos = shdc[id].sector_len = 0; scsi_hd_seek(id, 0); @@ -921,6 +1065,37 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) } return; + case GPCMD_START_STOP_UNIT: + if (hdc[id].bus != 5) + { + scsi_hd_illegal_opcode(id); + break; + } + + switch(cdbufferb[4] & 3) + { + case 0: /* Stop the disc. */ + case 1: /* Start the disc and read the TOC. */ + break; + case 2: /* Eject the disc if possible. */ +#ifndef __unix +#if 0 + win_removable_disk_eject(id); +#endif +#endif + break; + case 3: /* Load the disc (close tray). */ +#ifndef __unix +#if 0 + win_removable_disk_reload(id); +#endif +#endif + break; + } + + scsi_hd_command_complete(id); + break; + case GPCMD_INQUIRY: max_len = cdb[3]; max_len <<= 8; @@ -985,7 +1160,14 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) memset(hdbufferb, 0, 8); hdbufferb[0] = 0; /*SCSI HD*/ - hdbufferb[1] = 0; /*Fixed*/ + if (hdc[id].bus == 5) + { + hdbufferb[1] = 0x80; /*Removable*/ + } + else + { + hdbufferb[1] = 0; /*Fixed*/ + } hdbufferb[2] = 0x02; /*SCSI-2 compliant*/ hdbufferb[3] = 0x02; hdbufferb[4] = 31; From 1ad94224ca88278ddb866dc178d0f7362128c297 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 19 May 2017 04:35:59 +0200 Subject: [PATCH 237/392] Tentatively implemented the vertical scrolling part of EGA and (S)VGA CRTC register 8; PCap devices list generator now aborts if WinPcap is not present; Fixed the CD-ROM START STOP UNIT command; More preparations for SCSI removable hard disks. --- src/VIDEO/vid_ega.c | 152 +++++++++++++++++++++++------------- src/VIDEO/vid_svga.c | 62 +++++++++++++-- src/VIDEO/vid_svga_render.c | 88 +++++++++++++++------ src/WIN/win.h | 2 + src/WIN/win_settings.c | 78 +++++++++++++----- src/cdrom.c | 2 +- src/net_pcap.c | 9 +++ src/scsi_disk.c | 12 +-- 8 files changed, 286 insertions(+), 119 deletions(-) diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index d97f13ba1..b64f30324 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -243,6 +243,8 @@ void ega_recalctimings(ega_t *ega) ega->hdisp++; ega->rowoffset = ega->crtc[0x13]; + ega->rowcount = ega->crtc[9] & 0x1f; + overscan_y = (ega->rowcount + 1) << 1; if (ega->vidclock) crtcconst = (ega->seqregs[1] & 1) ? MDACONST : (MDACONST * (9.0 / 8.0)); else crtcconst = (ega->seqregs[1] & 1) ? CGACONST : (CGACONST * (9.0 / 8.0)); @@ -253,8 +255,13 @@ void ega_recalctimings(ega_t *ega) if (ega->seqregs[1] & 8) { disptime*=2; - _dispontime*=2; + _dispontime*=2; + overscan_y <<= 1; } + if (overscan_y < 16) + { + overscan_y = 16; + } _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; _dispofftime *= crtcconst; @@ -263,6 +270,19 @@ void ega_recalctimings(ega_t *ega) ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } +int ega_display_line(ega_t *ega) +{ + int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; + unsigned int dl = ega->displine; + if (ega->crtc[9] & 0x1f) + { + dl -= (ega->crtc[8] & 0x1f); + } + dl += y_add; + dl &= 0x7ff; + return dl; +} + void ega_poll(void *p) { ega_t *ega = (ega_t *)p; @@ -273,12 +293,13 @@ void ega_poll(void *p) int offset; uint8_t edat[4]; int drawcursor = 0; - int y_add = enable_overscan ? 14 : 0; + int y_add = enable_overscan ? (overscan_y >> 1) : 0; int x_add = enable_overscan ? 8 : 0; - int y_add_ex = enable_overscan ? 28 : 0; + int y_add_ex = enable_overscan ? overscan_y : 0; int x_add_ex = enable_overscan ? 16 : 0; - uint32_t *q, *r, i, j; + uint32_t *q, i, j; int wx = 640, wy = 350; + int dl = ega_display_line(ega); if (!ega->linepos) { @@ -302,16 +323,16 @@ void ega_poll(void *p) switch (ega->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[ega->displine + y_add])[(x * 9) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = 0; break; case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[ega->displine + y_add])[(x * 8) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = 0; break; case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[ega->displine + y_add])[(x * 18) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = 0; break; case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[ega->displine + y_add])[(x * 16) + xx + 32 + x_add] = 0; + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = 0; break; } } @@ -352,20 +373,20 @@ void ega_poll(void *p) if (ega->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + ((uint32_t *)buffer32->line[dl])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; } else { for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; else - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; } } else @@ -373,16 +394,16 @@ void ega_poll(void *p) if (ega->seqregs[1] & 1) { for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + ((uint32_t *)buffer32->line[dl])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; } else { for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; else - ((uint32_t *)buffer32->line[ega->displine + y_add])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; } } ega->ma += 4; @@ -418,17 +439,17 @@ void ega_poll(void *p) ega->ma &= ega->vrammask; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; } } else @@ -454,17 +475,17 @@ void ega_poll(void *p) ega->ma &= ega->vrammask; dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; } } break; @@ -485,14 +506,14 @@ void ega_poll(void *p) ega->ma += 4; ega->ma &= ega->vrammask; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[ega->displine + y_add])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; } break; } @@ -570,7 +591,7 @@ void ega_poll(void *p) y_add_ex = enable_overscan ? 28 : 0; x_add_ex = enable_overscan ? 16 : 0; - if ((xsize > 2032) || (ysize > 2032)) + if ((xsize > 2032) || ((ysize + y_add_ex) > 2048)) { x_add = x_add_ex = 0; y_add = y_add_ex = 0; @@ -591,21 +612,31 @@ void ega_poll(void *p) { if ((x >= 160) && ((ega->lastline - ega->firstline) >= 120)) { - for (i = 0; i < y_add; i++) + /* Draw (overscan_size - scroll size) lines of overscan on top. */ + for (i = 0; i < (y_add - (ega->crtc[8] & 0x1f)); i++) { - q = &((uint32_t *)buffer32->line[i])[32]; - r = &((uint32_t *)buffer32->line[ysize + y_add + i])[32]; + q = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < (xsize + x_add_ex); j++) { q[j] = ega->pallook[ega->attrregs[0x11]]; - r[j] = ega->pallook[ega->attrregs[0x11]]; } } - for (i = y_add; i < (ysize + y_add); i ++) + /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ + for (i = 0; i < (y_add + (ega->crtc[8] & 0x1f)); i++) { - q = &((uint32_t *)buffer32->line[i])[32]; + q = &((uint32_t *)buffer32->line[(ysize + y_add + i - (ega->crtc[8] & 0x1f)) & 0x7ff])[32]; + + for (j = 0; j < (xsize + x_add_ex); j++) + { + q[j] = ega->pallook[ega->attrregs[0x11]]; + } + } + + for (i = (y_add - (ega->crtc[8] & 0x1f)); i < (ysize + y_add - (ega->crtc[8] & 0x1f)); i ++) + { + q = &((uint32_t *)buffer32->line[(i - (ega->crtc[8] & 0x1f)) & 0x7ff])[32]; for (j = 0; j < x_add; j++) { @@ -615,6 +646,22 @@ void ega_poll(void *p) } } } + else + { + if (ega->crtc[8] & 0x1f) + { + /* Draw (scroll size) lines of overscan on the bottom. */ + for (i = 0; i < (ega->crtc[8] & 0x1f); i++) + { + q = &((uint32_t *)buffer32->line[(ysize + i - (ega->crtc[8] & 0x1f)) & 0x7ff])[32]; + + for (j = 0; j < xsize; j++) + { + q[j] = ega->pallook[ega->attrregs[0x11]]; + } + } + } + } video_blit_memtoscreen(32, 0, ega->firstline, ega->lastline + y_add_ex, xsize + x_add_ex, ega->lastline - ega->firstline + y_add_ex); @@ -631,8 +678,7 @@ void ega_poll(void *p) else { if (ega->crtc[9] & 0x80) - ega->video_res_y /= 2; - if (!(ega->crtc[0x17] & 1)) + ega->video_res_y /= 2; if (!(ega->crtc[0x17] & 1)) ega->video_res_y *= 2; ega->video_res_y /= (ega->crtc[9] & 31) + 1; if (ega->seqregs[1] & 8) diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 6da19608d..69c954bc9 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -542,6 +542,7 @@ void svga_recalctimings(svga_t *svga) { if (svga->seqregs[1] & 8) /*40 column*/ { +#if 0 if (svga->hdisp == 120) { svga->render = svga_render_text_40_12; @@ -549,12 +550,16 @@ void svga_recalctimings(svga_t *svga) } else { +#endif svga->render = svga_render_text_40; svga->hdisp *= (svga->seqregs[1] & 1) ? 16 : 18; +#if 0 } +#endif } else { +#if 0 if (svga->hdisp == 120) { svga->render = svga_render_text_80_12; @@ -562,9 +567,12 @@ void svga_recalctimings(svga_t *svga) } else { +#endif svga->render = svga_render_text_80; svga->hdisp *= (svga->seqregs[1] & 1) ? 8 : 9; +#if 0 } +#endif } svga->hdisp_old = svga->hdisp; } @@ -628,6 +636,16 @@ void svga_recalctimings(svga_t *svga) svga->linedbl = svga->crtc[9] & 0x80; svga->rowcount = svga->crtc[9] & 31; + overscan_y = (svga->rowcount + 1) << 1; + if (svga->seqregs[1] & 8) /*Low res (320)*/ + { + overscan_y <<= 1; + } + if (overscan_y < 16) + { + overscan_y = 16; + } + /* pclog("SVGA row count: %i (scroll: %i)\n", svga->rowcount, svga->crtc[8] & 0x1f); */ if (svga->recalctimings_ex) svga->recalctimings_ex(svga); @@ -1210,12 +1228,14 @@ void svga_write(uint32_t addr, uint8_t val, void *p) break; } +#if 0 if (svga->render == svga_render_text_80_12) { FILE *f = fopen("hecon.dmp", "wb"); fwrite(svga->vram, 1, svga->vram_limit, f); fclose(f); } +#endif } uint8_t svga_read(uint32_t addr, void *p) @@ -1555,9 +1575,9 @@ uint8_t svga_read_linear(uint32_t addr, void *p) void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { - int y_add = (enable_overscan) ? 32 : 0; + int y_add = (enable_overscan) ? overscan_y : 0; int x_add = (enable_overscan) ? 16 : 0; - uint32_t *p, *q, i, j; + uint32_t *p, i, j; svga->frames++; @@ -1619,21 +1639,31 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) { if ((wx >= 160) && ((wy + 1) >= 120)) { - for (i = 0; i < (y_add >> 1); i++) + /* Draw (overscan_size - scroll size) lines of overscan on top. */ + for (i = 0; i < ((y_add >> 1) - (svga->crtc[8] & 0x1f)); i++) { - p = &((uint32_t *)buffer32->line[i])[32]; - q = &((uint32_t *)buffer32->line[ysize + (y_add >> 1) + i])[32]; + p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < (xsize + x_add); j++) { p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); - q[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); } } - for (i = (y_add >> 1); i < (ysize + (y_add >> 1)); i ++) + /* Draw (overscan_size + scroll size) lines of overscan on the bottom. */ + for (i = 0; i < ((y_add >> 1) + (svga->crtc[8] & 0x1f)); i++) { - p = &((uint32_t *)buffer32->line[i])[32]; + p = &((uint32_t *)buffer32->line[(ysize + (y_add >> 1) + i - (svga->crtc[8] & 0x1f)) & 0x7ff])[32]; + + for (j = 0; j < (xsize + x_add); j++) + { + p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + } + } + + for (i = ((y_add >> 1) - (svga->crtc[8] & 0x1f)); i < (ysize + (y_add >> 1) - (svga->crtc[8] & 0x1f)); i ++) + { + p = &((uint32_t *)buffer32->line[i & 0x7ff])[32]; for (j = 0; j < 8; j++) { @@ -1643,6 +1673,22 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) } } } + else + { + if ((wx >= 160) && ((wy + 1) >= 120) && (svga->crtc[8] & 0x1f)) + { + /* Draw (scroll size) lines of overscan on the bottom. */ + for (i = 0; i < (svga->crtc[8] & 0x1f); i++) + { + p = &((uint32_t *)buffer32->line[(ysize + i - (svga->crtc[8] & 0x1f)) & 0x7ff])[32]; + + for (j = 0; j < xsize; j++) + { + p[j] = svga_color_transform(svga->pallook[svga->attrregs[0x11]]); + } + } + } + } video_blit_memtoscreen(32, 0, y1, y2 + y_add, xsize + x_add, ysize + y_add); } diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index fb8845a75..d51d6d249 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -28,11 +28,25 @@ uint32_t svga_color_transform(uint32_t color) return temp; } +int svga_display_line(svga_t *svga) +{ + int y_add = (enable_overscan) ? 16 : 0; + unsigned int dl = svga->displine; + if (svga->crtc[9] & 0x1f) + { + dl -= (svga->crtc[8] & 0x1f); + } + dl += y_add; + dl &= 0x7ff; + return dl; +} + void svga_render_blank(svga_t *svga) { int x, xx; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -43,16 +57,16 @@ void svga_render_blank(svga_t *svga) switch (svga->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); break; case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); break; case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); break; case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); break; } } @@ -62,6 +76,7 @@ void svga_render_text_40(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -69,7 +84,7 @@ void svga_render_text_40(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[32 + x_add]; int x, xx; int drawcursor; uint8_t chr, attr, dat; @@ -124,10 +139,12 @@ void svga_render_text_40(svga_t *svga) } } +#if 0 void svga_render_text_40_12(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = (enable_overscan) ? 12 : 0; + int dl = svga_display_line(svga); if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -135,7 +152,7 @@ void svga_render_text_40_12(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[32 + x_add]; int x, xx; int drawcursor; uint8_t chr, attr; @@ -178,11 +195,13 @@ void svga_render_text_40_12(svga_t *svga) } } } +#endif void svga_render_text_80(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -190,7 +209,7 @@ void svga_render_text_80(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[32 + x_add]; int x, xx; int drawcursor; uint8_t chr, attr, dat; @@ -245,10 +264,12 @@ void svga_render_text_80(svga_t *svga) } } +#if 0 void svga_render_text_80_12(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = (enable_overscan) ? 12 : 0; + int dl = svga_display_line(svga); if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -256,7 +277,7 @@ void svga_render_text_80_12(svga_t *svga) if (svga->fullchange) { - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[32 + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[32 + x_add]; int x, xx; int drawcursor; uint8_t chr, attr; @@ -300,12 +321,14 @@ void svga_render_text_80_12(svga_t *svga) } } } +#endif void svga_render_2bpp_lowres(svga_t *svga) { int changed_offset; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) changed_offset = (svga->ma << 1) >> 12; @@ -316,7 +339,7 @@ void svga_render_2bpp_lowres(svga_t *svga) { int x; int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -358,7 +381,8 @@ void svga_render_2bpp_highres(svga_t *svga) int changed_offset; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; - + int dl = svga_display_line(svga); + if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) changed_offset = ((svga->ma << 1) | 0x8000) >> 12; else @@ -368,7 +392,7 @@ void svga_render_2bpp_highres(svga_t *svga) { int x; int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -409,12 +433,13 @@ void svga_render_4bpp_lowres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { int x; int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -453,6 +478,7 @@ void svga_render_4bpp_highres(svga_t *svga) int changed_offset2; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) changed_offset = svga_mask_addr(svga->ma | 0x8000, svga) >> 12; @@ -468,7 +494,7 @@ void svga_render_4bpp_highres(svga_t *svga) { int x; int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -508,12 +534,13 @@ void svga_render_8bpp_lowres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -539,12 +566,13 @@ void svga_render_8bpp_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -576,12 +604,13 @@ void svga_render_15bpp_lowres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -608,12 +637,13 @@ void svga_render_15bpp_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -646,12 +676,13 @@ void svga_render_16bpp_lowres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - (svga->scrollcache & 6)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -678,12 +709,13 @@ void svga_render_16bpp_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -718,6 +750,7 @@ void svga_render_24bpp_lowres(svga_t *svga) uint32_t fg; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { @@ -732,7 +765,7 @@ void svga_render_24bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga_mask_addr(svga->ma + 1, svga)] << 8) | (svga->vram[svga_mask_addr(svga->ma + 2, svga)] << 16); svga->ma += 3; svga->ma = svga_mask_addr(svga->ma, svga); - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); + ((uint32_t *)buffer32->line[dl])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); } } } @@ -741,12 +774,13 @@ void svga_render_24bpp_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -778,6 +812,7 @@ void svga_render_32bpp_lowres(svga_t *svga) uint32_t fg; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->fullchange) { @@ -792,7 +827,7 @@ void svga_render_32bpp_lowres(svga_t *svga) fg = svga->vram[svga->ma] | (svga->vram[svga_mask_addr(svga->ma + 1, svga)] << 8) | (svga->vram[svga_mask_addr(svga->ma + 2, svga)] << 16); svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); - ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[svga->displine + y_add])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); + ((uint32_t *)buffer32->line[dl])[(x << 1) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 1) + 1 + offset + x_add] = svga_color_transform(fg); } } } @@ -803,12 +838,13 @@ void svga_render_32bpp_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -828,12 +864,13 @@ void svga_render_ABGR8888_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -853,12 +890,13 @@ void svga_render_RGBA8888_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; + int dl = svga_display_line(svga); if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2, svga)] || svga->fullchange) { int x; int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[svga->displine + y_add])[offset + x_add]; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; diff --git a/src/WIN/win.h b/src/WIN/win.h index 0e09db88f..ffe8fea2f 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -49,3 +49,5 @@ void update_status_bar_panes(HWND hwnds); int fdd_type_to_icon(int type); extern HWND hwndStatus; + +void hard_disk_add_open(HWND hwnd, int is_existing); diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index e889d2849..db4f7da46 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -2219,6 +2219,8 @@ uint64_t selection = 127; uint64_t spt, hpc, tracks, size; wchar_t hd_file_name[512]; +static hard_disk_t *hdc_ptr; + static int hdconf_initialize_hdt_combo(HWND hdlg) { HWND h; @@ -2287,19 +2289,26 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W case WM_INITDIALOG: memset(hd_file_name, 0, 512); - SetWindowText(hdlg, win_language_get_string_from_id(existing ? 2197 : 2196)); + hdc_ptr = (existing & 2) ? hdc : temp_hdc; + + if (existing & 2) + { + next_free_id = (existing & 0xf0) >> 4; + } + + SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? 2197 : 2196)); no_update = 1; - spt = existing ? 0 : 17; + spt = (existing & 1) ? 0 : 17; set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); - hpc = existing ? 0 : 15; + hpc = (existing & 1) ? 0 : 15; set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); - tracks = existing ? 0 : 1023; + tracks = (existing & 1) ? 0 : 1023; set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); size = (tracks * hpc * spt) << 9; set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); hdconf_initialize_hdt_combo(hdlg); - if (existing) + if (existing & 1) { h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); EnableWindow(h, FALSE); @@ -2339,25 +2348,44 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W return TRUE; } - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(temp_hdc[next_free_id].spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(temp_hdc[next_free_id].hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(temp_hdc[next_free_id].tracks)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdc_ptr[next_free_id].spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdc_ptr[next_free_id].hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdc_ptr[next_free_id].tracks)); + spt = hdc_ptr[next_free_id].spt; + hpc = hdc_ptr[next_free_id].hpc; + tracks = hdc_ptr[next_free_id].tracks; h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + hdc_ptr[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + hdc_ptr[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - temp_hdc[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + hdc_ptr[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - temp_hdc[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + hdc_ptr[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - temp_hdc[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - memset(temp_hdd_fn[next_free_id], 0, 1024); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + hdc_ptr[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + if (existing & 2) + { +#if 0 + if (hdc[next_free_id].bus == 5) + { + memset(prev_hdd_fn[next_free_id], 0, 1024); + memcpy(prev_hdd_fn[next_free_id], hdd_fn[next_free_id], (wcslen(hdd_fn[next_free_id]) << 1) + 2); + } +#endif + + memset(hdd_fn[next_free_id], 0, 1024); + memcpy(hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + } + else + { + memset(temp_hdd_fn[next_free_id], 0, 1024); + memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + } sector_size = 512; - if (!existing && (wcslen(hd_file_name) > 0)) + if (!(existing & 1) && (wcslen(hd_file_name) > 0)) { f = _wfopen(hd_file_name, L"wb"); @@ -2414,6 +2442,14 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W msgbox_info(hwndParentDialog, 2059); } +#if 0 + if ((existing & 2) && (hdc[next_free_id].bus == 5)) + { + scsi_hd_insert(id); + update_status_bar_icon_state(0x20 | next_free_id, 0); + } +#endif + hard_disk_added = 1; EndDialog(hdlg, 0); return TRUE; @@ -2424,7 +2460,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W return TRUE; case IDC_CFILE: - if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !existing)) + if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !(existing & 1))) { if (!existing) { @@ -2439,13 +2475,13 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } } - f = _wfopen(wopenfilestring, existing ? L"rb" : L"wb"); + f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); if (f == NULL) { - msgbox_error(hwndParentDialog, existing ? 2060 : 2057); + msgbox_error(hwndParentDialog, (existing & 1) ? 2060 : 2057); return TRUE; } - if (existing) + if (existing & 1) { if (image_is_hdi(wopenfilestring) || image_is_hdx(wopenfilestring, 1)) { @@ -2672,7 +2708,7 @@ void hard_disk_add_open(HWND hwnd, int is_existing) { BOOL ret; - existing = !!is_existing; + existing = is_existing; hard_disk_added = 0; ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); } diff --git a/src/cdrom.c b/src/cdrom.c index b40e9248f..6540846ba 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -3100,7 +3100,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; case GPCMD_START_STOP_UNIT: - switch(cdbufferb[4] & 3) + switch(cdb[4] & 3) { case 0: /* Stop the disc. */ if (cdrom_drives[id].handler->stop) diff --git a/src/net_pcap.c b/src/net_pcap.c index 5eb57bb4c..3ca2e9089 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -220,6 +220,7 @@ int network_devlist(netdev_t *list) { char errbuf[PCAP_ERRBUF_SIZE]; + char *temp_dev; pcap_if_t *devlist, *dev; int i = 0; @@ -228,6 +229,14 @@ network_devlist(netdev_t *list) strcpy(list->description, "None"); list++; i++; + /* See if WinPcap is even present, and get out of here if it's not. */ + temp_dev = (char *)pcap_lib_version(); + if (temp_dev == NULL) { + /* Hmm, WinPcap doesn't seem to be alive.. */ + pclog("PCAP: WinPcap library not found, not processing the networks list further!\n"); + return(i); + } + /* Retrieve the device list from the local machine */ if (pcap_findalldevs(&devlist, errbuf) == -1) { pclog("NETWORK: error in pcap_findalldevs: %s\n", errbuf); diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 624172d00..26f900e55 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -906,16 +906,6 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) scsi_hd_command_complete(id); break; - case GPCMD_PREVENT_REMOVAL: - if (hdc[id].bus != 5) - { - scsi_hd_illegal_opcode(id); - break; - } - - scsi_hd_command_complete(id); - break; - case GPCMD_REZERO_UNIT: shdc[id].sector_pos = shdc[id].sector_len = 0; scsi_hd_seek(id, 0); @@ -1072,7 +1062,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - switch(cdbufferb[4] & 3) + switch(cdb[4] & 3) { case 0: /* Stop the disc. */ case 1: /* Start the disc and read the TOC. */ From 2c7b6f004a525b9223e3975a20ee0d70d1ba34c6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 20 May 2017 22:23:54 +0200 Subject: [PATCH 238/392] The WinPcap handler now forces non-blocking mode again. --- src/net_ne2000.c | 13 +++++++++++-- src/net_pcap.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 51fdd7b4e..9ea48215c 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1809,12 +1809,13 @@ nic_init(int board) mac = device_get_config_int_ex("mac", -1); /* Set up our MAC address. */ +#if 0 if (dev->is_rtl8029as) { - dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ + dev->maclocal[0] = 0xDE /* 0x00 */; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ dev->maclocal[1] = 0x20; dev->maclocal[2] = 0x18; } else { - dev->maclocal[0] = 0x00; /* 00:00:D8 (NE2000 ISA vendor prefix). */ + dev->maclocal[0] = 0xDE /* 0x00 */; /* 00:00:D8 (NE2000 ISA vendor prefix). */ dev->maclocal[1] = 0x00; dev->maclocal[2] = 0xD8; } @@ -1833,6 +1834,14 @@ nic_init(int board) dev->maclocal[5] = (mac & 0xff) | 1; #endif } +#else + dev->maclocal[0] = 0xac; + dev->maclocal[1] = 0xde; + dev->maclocal[2] = 0x48; + dev->maclocal[3] = 0x88; + dev->maclocal[4] = 0xbb; + dev->maclocal[5] = 0xaa; +#endif memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); pclog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x BIOS=%d\n", diff --git a/src/net_pcap.c b/src/net_pcap.c index 3ca2e9089..1a7eef1fa 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -109,6 +109,7 @@ poll_thread(void *arg) int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) { + int rc; char temp[PCAP_ERRBUF_SIZE]; char filter_exp[255]; struct bpf_program fp; @@ -147,6 +148,43 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) return(-1); } + /* Time to check that we are in non-blocking mode. */ + rc=pcap_getnonblock(pcap,temp); + pclog("pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); + + switch(rc) + { + case 0: + pclog("Setting interface to non-blocking mode.."); + rc = pcap_setnonblock(pcap,1,temp); + if (rc==0) + { /* no errors! */ + pclog(".."); + rc=pcap_getnonblock(pcap,temp); + if(rc == 1) + { + pclog("..!",rc); + } + else + { + pclog("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); + return(-1); + } + } /* end set nonblock */ + else + { + pclog("There was an unexpected error of [%s]\n\nexiting.\n",temp);return(-1);} + pclog("\n"); + break; + case 1: + pclog("non blocking\n"); + break; + default: + pclog("this isn't right!!!\n"); + return(-1); + break; + } + /* Create a MAC address based packet filter. */ pclog("Building packet filter ..."); sprintf(filter_exp, From 598fd2ffd88bd23520c8e5c9acb091f97741afbe Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 20 May 2017 22:38:30 +0200 Subject: [PATCH 239/392] SVGA now again always returns 0xFF where no VRAM is found. --- src/VIDEO/vid_svga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 69c954bc9..39a72ae15 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -1256,7 +1256,7 @@ uint8_t svga_read(uint32_t addr, void *p) if (svga->chain4 || svga->fb_only) { if (addr >= svga->vram_limit) - return 0x00; + return 0xff; return svga->vram[svga_mask_addr(addr, svga)]; } else if (svga->chain2_read) @@ -1274,7 +1274,7 @@ uint8_t svga_read(uint32_t addr, void *p) addr<<=2; if (addr >= svga->vram_limit) - return 0x00; + return 0xff; addr = svga_mask_addr(addr, svga); From 785cb4b421648eff5759e4e1552bafd0650161af Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 May 2017 02:37:22 +0200 Subject: [PATCH 240/392] PCap is now initialized with timeout 15 rather than 10; Generated MAC addresses are back, with 0xDE as first byte rather than 0x00, SLiRP DHCP still works (seems it did not like the first byte being 0x00); The FDC Read and Write commands now return the correct sector ID in the result phase when the last transferred sector equals EOT and DMA is over, fixes floppies on Windows 2000; Fixed floppy FIFO threshold handling. --- src/fdc.c | 78 +++++++++++++++++++++++++++++++++++++++++++----- src/net_ne2000.c | 2 +- src/net_pcap.c | 2 +- 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/fdc.c b/src/fdc.c index 9e5b66cce..7a640096b 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -626,6 +626,8 @@ void fdc_implied_seek() } } +int fifo_count = 0; + void fdc_write(uint16_t addr, uint8_t val, void *priv) { int drive, i, drive_num; @@ -805,6 +807,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) case 0x19: /*Scan low or equal*/ case 0x16: /*Verify*/ case 0x1D: /*Scan high or equal*/ + fifo_count = 0; fdc.satisfying_sectors=0; fdc.sc=0; fdc.wrong_am=0; @@ -1261,11 +1264,10 @@ uint8_t fdc_read(uint16_t addr, void *priv) { uint8_t temp; int drive; - fdc_log("Read FDC %04X\n",addr); switch (addr&7) { case 0: /* STA */ - return 0xff; + temp = 0xff; break; case 1: /* STB */ if (is486) @@ -1274,7 +1276,9 @@ uint8_t fdc_read(uint16_t addr, void *priv) } drive = real_drive(fdc.dor & 3); if (!fdc.enable_3f1) - return 0xff; + { + temp = 0xff; + } temp = 0x70; if (drive) temp &= ~0x40; @@ -1314,7 +1318,8 @@ uint8_t fdc_read(uint16_t addr, void *priv) case 4: /*Status*/ if (!(fdc.dor & 4) & !fdc.pcjr) { - return 0; + temp = 0; + break; } temp=fdc.stat; break; @@ -1373,6 +1378,7 @@ uint8_t fdc_read(uint16_t addr, void *priv) default: temp=0xFF; } + fdc_log("Read FDC %04X %02X\n",addr, temp); return temp; } @@ -1430,6 +1436,7 @@ void fdc_poll_common_finish(int compare, int st5) fdc.res[8]=fdc.head; fdc.res[9]=fdc.sector; fdc.res[10]=fdc.params[4]; + fdc_log("Read/write finish (%02X %02X %02X %02X %02X %02X %02X)\n" , fdc.res[4], fdc.res[5], fdc.res[6], fdc.res[7], fdc.res[8], fdc.res[9], fdc.res[10]); update_status_bar_icon(fdc.drive, 0); paramstogo=7; } @@ -1541,7 +1548,31 @@ void fdc_callback() old_sector = fdc.sector; if (fdc.tc) { - fdc.sector++; + /* This is needed so that the correct results are returned + in case of TC. */ + if (fdc.sector == fdc.params[5]) + { + if (!(fdc.command & 0x80)) + { + fdc.rw_track++; + fdc.sector = 1; + } + else + { + if (fdc.head) + { + fdc.rw_track++; + } + + fdc.head ^= 1; + fdd_set_head(fdc.drive, fdc.head); + fdc.sector = 1; + } + } + else + { + fdc.sector++; + } fdc_poll_readwrite_finish(compare); return; } @@ -1777,7 +1808,7 @@ void fdc_callback() fdc.config = fdc.params[1]; fdc.pretrk = fdc.params[2]; fdc.fifo = (fdc.params[1] & 0x20) ? 0 : 1; - fdc.tfifo = (fdc.params[1] & 0xF) + 1; + fdc.tfifo = (fdc.params[1] & 0xF); fdc.stat = 0x80; disctime = 0; return; @@ -1889,7 +1920,7 @@ int fdc_data(uint8_t data) return -1; } - if (fdc.pcjr || !fdc.fifo || (fdc.tfifo <= 1)) + if (fdc.pcjr || !fdc.fifo || (fdc.tfifo < 1)) { fdc.dat = data; fdc.data_ready = 1; @@ -1909,6 +1940,36 @@ int fdc_data(uint8_t data) } else { + if (fdc.tc) + { + fdc_log("FDC read: TC\n"); + return 0; + } + + if (dma_channel_write(2, data) & DMA_OVER) + { + fdc_log("FDC read: DMA over\n"); + fdc.tc = 1; + } + + if (!fdc.fifo) + { + fdc.data_ready = 1; + fdc.stat = 0xd0; + } + else + { + fdc_fifo_buf_advance(); + if (fdc.fifobufpos == 0) + { + /* We have wrapped around, means FIFO is over */ + fifo_count++; + fdc_log("%04X: FIFO wrap around (threshold == %02X), DRQ sent\n", fifo_count, fdc.tfifo); + fdc.data_ready = 1; + fdc.stat = 0xd0; + } + } +#if 0 result = dma_channel_write(2, data); if (fdc.tc) @@ -1922,7 +1983,7 @@ int fdc_data(uint8_t data) return -1; } - if (!fdc.fifo || (fdc.tfifo <= 1)) + if (!fdc.fifo || (fdc.tfifo < 1)) { fdc.data_ready = 1; fdc.stat = 0xd0; @@ -1937,6 +1998,7 @@ int fdc_data(uint8_t data) fdc.stat = 0xd0; } } +#endif } return 0; diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 9ea48215c..b0262dafc 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1809,7 +1809,7 @@ nic_init(int board) mac = device_get_config_int_ex("mac", -1); /* Set up our MAC address. */ -#if 0 +#if 1 if (dev->is_rtl8029as) { dev->maclocal[0] = 0xDE /* 0x00 */; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ dev->maclocal[1] = 0x20; diff --git a/src/net_pcap.c b/src/net_pcap.c index 1a7eef1fa..d765e93c6 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -141,7 +141,7 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) pcap = pcap_open_live(dev, /* interface name */ 1518, /* maximum packet size */ 1, /* promiscuous mode? */ - 10, /* timeout in msec */ + 15, /* timeout in msec */ temp); /* error buffer */ if (pcap == NULL) { pclog("Unable to open WinPcap: %s!\n", temp); From e8d047d0d0c6ec50e327897deb86b38d724129cf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 May 2017 03:52:18 +0200 Subject: [PATCH 241/392] The icons and status bar handling code for the SCSI removable hard disks is now there. --- src/ICONS/hard_disk_removable_scsi.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_removable_scsi_active.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_removable_scsi_empty.ico | Bin 0 -> 1150 bytes .../hard_disk_removable_scsi_empty_active.ico | Bin 0 -> 1150 bytes src/WIN/86Box.rc | 8 ++++- src/WIN/win.c | 29 +++++++++++------- 6 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 src/ICONS/hard_disk_removable_scsi.ico create mode 100644 src/ICONS/hard_disk_removable_scsi_active.ico create mode 100644 src/ICONS/hard_disk_removable_scsi_empty.ico create mode 100644 src/ICONS/hard_disk_removable_scsi_empty_active.ico diff --git a/src/ICONS/hard_disk_removable_scsi.ico b/src/ICONS/hard_disk_removable_scsi.ico new file mode 100644 index 0000000000000000000000000000000000000000..59f80a96b3fd5aedcc1df78d25bed544c4c0381b GIT binary patch literal 1150 zcmd5)O-~b16n&^`!^)*`=`V2O0yh}lxpC#j7-P^F6p_$z8&el{Su^u#z)&N0a2qezYoBQauuWF3Gs)Q|W;FJk>Yh+F!r`KGQ) zac%Ycmtq0GkjHUBMGnV#LN1G=Yz9Xe1xHE>hiMsysU$wj38YE8?DIx4)LYs+L2y;! zb|OVOWS1SX&|*VU(_^zDF=`PY{n4#Ew;J|Wm#cb-mn>$)%qHxax)ABoA>8ox>kH>eT1Fn zMuDKd{p-w?3#Zi)+_enMmzEcy)==+9^)E>}g%M!z<` zOII(~A8c-jJI?w&P}~m44jXwtggE&g?KNW8*zvQM7;%gBmo94g2F6aL{N8dd;1e4D z)Q9@-NS{&Ba<%xn>3%c$pw1I$CXpg9WV(l>(+2r8$UM2l>{`8@IK*e;onF SRQ&DftYJ*xBxCOgTHX(`q8=vz literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_removable_scsi_active.ico b/src/ICONS/hard_disk_removable_scsi_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..de29795390f51c819fdd6436ef59b97bc27c7450 GIT binary patch literal 1150 zcmc&yNl#N@6#Y=whLua>(qG`l1#U2!uyEtbjqNi8NmChYDh;$y0U6o?rL?6`N(E%J zAQadbBUo#J4)k>{gYCktxG=7GJ>K_fMKp0(nV0k3eD}*a_uTs~V`cP}moqvqv6^#? zU0{q|CQynp#XJSZ=xyU-5z_r14w*w%C0~@sIWGsfM;;gNe@mCSWmTMy0~h%LbeB10 zRerrT!jIU6sKYAk+ATuFY8E1vej#i&386lN5HxlR${FQp?l+zL?&{@+@gvX+V)PJ__girm?8q|fo zCC~Avy(~_U!BJL38b=vII)#s^Bz(SQXjZ8{&A-X3!kdjn#K}89HoBD@cOpJIOt2T> zupvf1c)JC>oTNID%-|GcFik-lDpdpe6ct<8AXtj1e) z1AL8234X2S^TdrS=fxe`HugN*pPzxKk)R&L`9;a6C#AYvInm}VO^^&n*G71r?LTqB-ap`Ww&Oyh3tbo!7n+#KFoQD#g;Gk(M}f8s z3=Cw(OuueR%U~1}FUNClsm8?UQXy|oIpw^4&bfz>E&S$k1h02U{stkp2qAY-n8Hk& z$3O@^tK3c{e*Xs-N0yARXE56BFlw|J?X(zeH(AiqS)gmo*Hq>=>daFW<|#6BYgOjT z5~|ED3cFfl_1DYk8C;!BU@;lPVtfk8=@6392_z>2hzB;rwh6J-hq>8>sAs@j-1h)| z){$kdmouzKkL7GC;%~i%1N1|$frb7f;p5gS>&WKyQ<3N1QMUu3(T1?o1lrbtHZ`ES z3RJ5@pehj5YY^Z)|F5f5*U4o3?Q4?2PsOlGHi|LEb6Cx}B3MOXs*u7L6lV|3p2qu$ zdTDPdg8^a2Ay`^KGoIFl3AvEJHGBUqzZj2FUe2nig40*3;8n}uO2^Um@fg&hb39%yc*Y)Ca!XtIKv)o5hQRy@xmlzE5~AeF)Jb>>7YO ojeF3909kz8gFtVv+1ob{vbujA0SMvx+vm|1Awt&)kx*IPcgJOa761SM literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_removable_scsi_empty_active.ico b/src/ICONS/hard_disk_removable_scsi_empty_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..8c08338ba50069a50b687c7cae2133063b3438f7 GIT binary patch literal 1150 zcmc(d%TE(g6vi*=+H~d8xb%N;?XLesJ1#I1Vlc)KV#3xfE;JaUCSYU%#weu~=o`vR zAJfMa=!4cr`kZMyrN&^w^z+;q2CODNR%Y_e$vu;E&hNW(7#pL<;b8Q>!p1K!c8M`| zl|(7ZSa}MJ(YMfLOXm3>UaonU)BW152=4^ASKJCe|82SJh07^K1qkvFqOE zWi2BcYC2`8a?(&!2}4cBjdnsZ+LCCr#F#PpYI3ypq|dE|o5vj`I~-IFaClHgzg$AU zRD@pKhhEr&zPF3sZXSY%=GN~2+Jo{PB{v*Ysh)ZasueT-+-qui3c`nb5Gr>^dQ2=% zpp)nI6`G@A!gUte*S_e2YW9Tsr=y>o`*nNBW6+ z6nkA9b-Re?Bbf0`gWvy*cN&rsHrcgYM(iqCnw_@hn+!5Eo5N&DK(%=i78B=cL_>+{ zo0ai?sbKL^P8DNl$F|Vg3Zoegpb^|eee*r)>uacaS5aGgYl?p>FFYU5&CNNwyUJJ2 z(9IG9pPMA_(#~j~zy|6YKGc04OF{pa{QQH9e21E1?4@4VhvkFViCN{GoMk(TRwRT* z$d9^z-Q?g*pM9QZ_Wl)~JidO&{{d&nWh{mic_u$?ahtqE(2N96z3|-rqlee*`VeF1 z=pH}zl$^=%TOTyLxgE*dwRZgEUA;s1Fr" + 2203 "English (United States)" END diff --git a/src/WIN/win.c b/src/WIN/win.c index 010b67f61..af72b0ef1 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -809,6 +809,23 @@ void create_cdrom_tip(int part) } } +void create_removable_hd_tip(int part) +{ + WCHAR *szText; + WCHAR wtext[512]; + + int drive = sb_part_meanings[part] & 0xf; + + if (wcslen(hdd_fn[drive]) == 0) + { + _swprintf(sbTips[part], win_language_get_string_from_id(2201), win_language_get_string_from_id(2185)); + } + else + { + _swprintf(sbTips[part], win_language_get_string_from_id(2179), hdd_fn[drive]); + } +} + void create_hd_tip(int part) { WCHAR *szText; @@ -841,11 +858,9 @@ void update_tip(int meaning) case 0x10: create_cdrom_tip(part); break; -#if 0 case 0x20: create_removable_hd_tip(part); break; -#endif case 0x30: create_hd_tip(part); break; @@ -954,7 +969,6 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } -#if 0 for (i = 0; i < 16; i++) { if (hdc[i].bus == 5) @@ -965,7 +979,6 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } -#endif if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) { edge += sb_icon_width; @@ -1047,14 +1060,12 @@ void update_status_bar_panes(HWND hwnds) sb_part_icons[i] = j | sb_icon_flags[i]; create_cdrom_tip(i); break; -#if 0 case 0x20: /* Removable hard disk */ sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; sb_part_icons[i] = 176 + sb_icon_flags[i]; - create_floppy_tip(i); + create_removable_hd_tip(i); break; -#endif case 0x30: /* Hard disk */ sb_part_icons[i] = 192 + ((sb_part_meanings[i] & 0xf) << 1); @@ -1107,12 +1118,10 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) hIcon[i] = LoadIconEx((PCTSTR) i); } -#if 0 for (i = 176; i < 178; i++) { hIcon[i] = LoadIconEx((PCTSTR) i); } -#endif for (i = 192; i < 200; i++) { @@ -1139,12 +1148,10 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) hIcon[i] = LoadIconEx((PCTSTR) i); } -#if 0 for (i = 432; i < 434; i++) { hIcon[i] = LoadIconEx((PCTSTR) i); } -#endif GetWindowRect(hwndParent, &rectDialog); dw = rectDialog.right - rectDialog.left; From bf47a5493a14812be446526c6e7d3e63960e0b20 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 May 2017 04:39:21 +0200 Subject: [PATCH 242/392] The WinPcap handler no longer forces non-blocking mode, DHCP still works with Win10Pcap. --- src/net_pcap.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/src/net_pcap.c b/src/net_pcap.c index d765e93c6..68fafb6d2 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -148,43 +148,6 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) return(-1); } - /* Time to check that we are in non-blocking mode. */ - rc=pcap_getnonblock(pcap,temp); - pclog("pcap is currently in %s mode\n",rc? "non-blocking":"blocking"); - - switch(rc) - { - case 0: - pclog("Setting interface to non-blocking mode.."); - rc = pcap_setnonblock(pcap,1,temp); - if (rc==0) - { /* no errors! */ - pclog(".."); - rc=pcap_getnonblock(pcap,temp); - if(rc == 1) - { - pclog("..!",rc); - } - else - { - pclog("\tunable to set pcap into non-blocking mode!\nContinuining without pcap.\n"); - return(-1); - } - } /* end set nonblock */ - else - { - pclog("There was an unexpected error of [%s]\n\nexiting.\n",temp);return(-1);} - pclog("\n"); - break; - case 1: - pclog("non blocking\n"); - break; - default: - pclog("this isn't right!!!\n"); - return(-1); - break; - } - /* Create a MAC address based packet filter. */ pclog("Building packet filter ..."); sprintf(filter_exp, From 182c737921d961d876382ceb7308a6fd2547b912 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 21 May 2017 19:16:23 +0200 Subject: [PATCH 243/392] Improved emulation of the SiS 496 chip; The SMC FDC37C665 Super I/O chip's IDE handler is now disabled for the Rise Computer R418 (the real board by passes that chip's IDE and uses the SiS 496B IDE controller so this is correct and not a hack), fixes hard disks disappearing on soft reset. --- src/fdc37c665.c | 6 +--- src/i430fx.c | 2 +- src/i430hx.c | 2 +- src/i430lx.c | 2 +- src/i430nx.c | 2 +- src/i430vx.c | 2 +- src/i440fx.c | 2 +- src/model.c | 3 +- src/sio.c | 2 +- src/sio.h | 1 + src/sis496.c | 93 ++++++++++++++++++++++++------------------------- src/sis496.h | 4 +-- 12 files changed, 59 insertions(+), 62 deletions(-) diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 1b6904a1a..bbcf157b5 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -31,7 +31,7 @@ static void write_lock(uint8_t val) static void ide_handler() { uint16_t or_value = 0; - if (romset == ROM_440FX) + if ((romset == ROM_440FX) || (romset == ROM_R418)) { return; } @@ -50,10 +50,6 @@ static void ide_handler() ide_set_side(0, 0x376 | or_value); ide_pri_enable_ex(); } - else - { - pclog("Disabling IDE...\n"); - } } static void set_com34_addr() diff --git a/src/i430fx.c b/src/i430fx.c index 34420f75f..a0324c3ce 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -137,7 +137,7 @@ void i430fx_reset(void) void i430fx_pci_reset(void) { - i430fx_write(0, 0x59, 0xf, NULL); + i430fx_write(0, 0x59, 0x00, NULL); } void i430fx_init() diff --git a/src/i430hx.c b/src/i430hx.c index e13da7606..80c52c02f 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -124,7 +124,7 @@ void i430hx_reset(void) void i430hx_pci_reset(void) { - i430hx_write(0, 0x59, 0xf, NULL); + i430hx_write(0, 0x59, 0x00, NULL); } void i430hx_init() diff --git a/src/i430lx.c b/src/i430lx.c index 624d3f8d0..7494b6c76 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -122,7 +122,7 @@ void i430lx_reset(void) void i430lx_pci_reset(void) { - i430lx_write(0, 0x59, 0xf, NULL); + i430lx_write(0, 0x59, 0x00, NULL); } void i430lx_init() diff --git a/src/i430nx.c b/src/i430nx.c index 9b58d4000..da7b1a5fe 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -120,7 +120,7 @@ void i430nx_reset(void) void i430nx_pci_reset(void) { - i430nx_write(0, 0x59, 0xf, NULL); + i430nx_write(0, 0x59, 0x00, NULL); } void i430nx_init() diff --git a/src/i430vx.c b/src/i430vx.c index ae9aec90e..2eef17d33 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -127,7 +127,7 @@ void i430vx_reset(void) void i430vx_pci_reset(void) { - i430vx_write(0, 0x59, 0xf, NULL); + i430vx_write(0, 0x59, 0x00, NULL); } void i430vx_init() diff --git a/src/i440fx.c b/src/i440fx.c index 3481adfab..9074e2e7a 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -131,7 +131,7 @@ void i440fx_reset(void) void i440fx_pci_reset(void) { - i440fx_write(0, 0x59, 0xf, NULL); + i440fx_write(0, 0x59, 0x00, NULL); } void i440fx_init() diff --git a/src/model.c b/src/model.c index 5be1bab9c..8b36ce114 100644 --- a/src/model.c +++ b/src/model.c @@ -581,7 +581,8 @@ void at_sis496_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); - device_add(&sis496_device); + sis496_init(); + trc_init(); } void at_r418_init() diff --git a/src/sio.c b/src/sio.c index 9092e0c2e..9ad476e38 100644 --- a/src/sio.c +++ b/src/sio.c @@ -142,7 +142,7 @@ void trc_write(uint16_t port, uint8_t val, void *priv) trc_reg = val & 0xfd; } -void trc_init() +void trc_init(void) { trc_reg = 0; diff --git a/src/sio.h b/src/sio.h index 9b705a6b3..38b0ff468 100644 --- a/src/sio.h +++ b/src/sio.h @@ -1,4 +1,5 @@ /* Copyright holders: Tenshi see COPYING for more details */ +void trc_init(void); void sio_init(int card); diff --git a/src/sis496.c b/src/sis496.c index 8cdb87a95..a858102a3 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -15,16 +15,18 @@ typedef struct sis496_t uint8_t pci_conf[256]; } sis496_t; -void sis496_recalcmapping(sis496_t *sis496) +sis496_t sis496; + +void sis496_recalcmapping(void) { int c; for (c = 0; c < 8; c++) { uint32_t base = 0xc0000 + (c << 15); - if (sis496->pci_conf[0x44] & (1 << c)) + if (sis496.pci_conf[0x44] & (1 << c)) { - switch (sis496->pci_conf[0x45] & 3) + switch (sis496.pci_conf[0x45] & 3) { case 0: mem_set_mem_state(base, 0x8000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); @@ -45,68 +47,77 @@ void sis496_recalcmapping(sis496_t *sis496) } flushmmucache(); - shadowbios = (sis496->pci_conf[0x44] & 0xf0); + shadowbios = (sis496.pci_conf[0x44] & 0xf0); } void sis496_write(int func, int addr, uint8_t val, void *p) { - sis496_t *sis496 = (sis496_t *)p; switch (addr) { case 0x44: /*Shadow configure*/ - if ((sis496->pci_conf[0x44] & val) ^ 0xf0) + if ((sis496.pci_conf[0x44] & val) ^ 0xf0) { - sis496->pci_conf[0x44] = val; - sis496_recalcmapping(sis496); + sis496.pci_conf[0x44] = val; + sis496_recalcmapping(); } break; case 0x45: /*Shadow configure*/ - if ((sis496->pci_conf[0x45] & val) ^ 0x01) + if ((sis496.pci_conf[0x45] & val) ^ 0x01) { - sis496->pci_conf[0x45] = val; - sis496_recalcmapping(sis496); + sis496.pci_conf[0x45] = val; + sis496_recalcmapping(); } break; } if ((addr >= 4 && addr < 8) || addr >= 0x40) - sis496->pci_conf[addr] = val; + sis496.pci_conf[addr] = val; } uint8_t sis496_read(int func, int addr, void *p) { - sis496_t *sis496 = (sis496_t *)p; - - return sis496->pci_conf[addr]; + return sis496.pci_conf[addr]; } -void *sis496_init() +void sis496_reset(void) { - sis496_t *sis496 = malloc(sizeof(sis496_t)); - memset(sis496, 0, sizeof(sis496_t)); + memset(&sis496, 0, sizeof(sis496_t)); - pci_add_specific(5, sis496_read, sis496_write, sis496); + sis496.pci_conf[0x00] = 0x39; /*SiS*/ + sis496.pci_conf[0x01] = 0x10; + sis496.pci_conf[0x02] = 0x96; /*496/497*/ + sis496.pci_conf[0x03] = 0x04; + + sis496.pci_conf[0x04] = 7; + sis496.pci_conf[0x05] = 0; + + sis496.pci_conf[0x06] = 0x80; + sis496.pci_conf[0x07] = 0x02; - sis496->pci_conf[0x00] = 0x39; /*SiS*/ - sis496->pci_conf[0x01] = 0x10; - sis496->pci_conf[0x02] = 0x96; /*496/497*/ - sis496->pci_conf[0x03] = 0x04; + sis496.pci_conf[0x08] = 2; /*Device revision*/ - sis496->pci_conf[0x04] = 7; - sis496->pci_conf[0x05] = 0; + sis496.pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ + sis496.pci_conf[0x0a] = 0x00; + sis496.pci_conf[0x0b] = 0x06; - sis496->pci_conf[0x06] = 0x80; - sis496->pci_conf[0x07] = 0x02; - - sis496->pci_conf[0x08] = 2; /*Device revision*/ + sis496.pci_conf[0x0e] = 0x00; /*Single function device*/ +} - sis496->pci_conf[0x09] = 0x00; /*Device class (PCI bridge)*/ - sis496->pci_conf[0x0a] = 0x00; - sis496->pci_conf[0x0b] = 0x06; - - sis496->pci_conf[0x0e] = 0x00; /*Single function device*/ +void sis496_pci_reset(void) +{ + uint8_t val = 0; - return sis496; + val = sis496_read(0, 0x44, NULL); /* Read current value of 0x44. */ + sis496_write(0, 0x44, val & 0xf, NULL); /* Turn off shadow BIOS but keep the lower 4 bits. */ +} + +void sis496_init(void) +{ + pci_add_specific(5, sis496_read, sis496_write, NULL); + + sis496_reset(); + + pci_reset_handler.pci_master_reset = sis496_pci_reset; } void sis496_close(void *p) @@ -115,15 +126,3 @@ void sis496_close(void *p) free(sis496); } - -device_t sis496_device = -{ - "SiS 496/497", - 0, - sis496_init, - sis496_close, - NULL, - NULL, - NULL, - NULL -}; diff --git a/src/sis496.h b/src/sis496.h index 1ee67d59a..fbb73be49 100644 --- a/src/sis496.h +++ b/src/sis496.h @@ -1,4 +1,4 @@ -/* Copyright holders: Sarah Walker +/* Copyright holders: Kotori see COPYING for more details */ -extern device_t sis496_device; +void sis496_init(void); From 3eb09ff9fec8cff2dd3b1ca3da33414fda386e59 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 22 May 2017 00:21:22 -0400 Subject: [PATCH 244/392] Updates for dynamic loading of DLLs, some cleanups. --- src/86box.cfg | Bin 7452 -> 0 bytes src/86box.h | 2 + src/Makefile.mingw | 21 ++--- src/WIN/86Box.rc | 1 + src/WIN/plat_dynld.h | 30 +++++++ src/WIN/win.h | 93 +++++++++++-------- src/WIN/win_dynld.c | 64 +++++++++++++ src/WIN/win_language.c | 2 +- src/net_ne2000.c | 55 +++--------- src/net_pcap.c | 197 ++++++++++++++++++++--------------------- src/network.c | 34 +++++-- src/network.h | 5 +- 12 files changed, 296 insertions(+), 208 deletions(-) delete mode 100644 src/86box.cfg create mode 100644 src/WIN/plat_dynld.h create mode 100644 src/WIN/win_dynld.c diff --git a/src/86box.cfg b/src/86box.cfg deleted file mode 100644 index ad83f0d3556b0b9f3477aa51f21bf2a4a3740c75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7452 zcmb`M+iu%N6h-H`K>wj1P@tkLJ9dG-6e!w0v?6F2U=C}zSh;i zh2Q8JdqA_b|J?eRl`Y7P^4KZL2jzBf_od(8+_&zXd*gm^f9U(QuCLvd`(Al`)b-vo ze^=Um{6ya;jYrDPDnzum?iY1s&nfoLT6Q9NO zsUG;MV#XC;cphPH@%Y~Rt2|lHm}Y+}C-m8tdfiEbkBUOfnJZBBi!sz0$0I&L*tduZniiOl0o9FBy?JS<>4ReW&sb8CLj|X4P1; zKBnqxMZ8yBR!wR}bv~4Ls8Ur|RwDQ|`@5IAtk$eZ8+qO7mv#1}WSG14>{!~JR!3W> zOz+e9=t6Ga zm70}SbdIgAJoo58)^DCCRdx{aW5wKUr<*fYp;9svYAig}dUb4j9Yp z*7pIkmReW24)k1LHq>J+o>1`^_2Ajkk3C*;*n`hu55Ap!kz|i;6MI&O{_OFR!ybGN zd+_b-he`I>HnAURtUr6ay!ybG)`->!dY@66$YOFtdyyUP4pTiz}JNr?RJ+@8k zuQb-5JzjFygU?|PzMcJLl0CLf>|bfDKYP67um_*R9(+6dt0a4Do7i7#tUr6ay z!ybG)`&UW!*fz1h(O7@>c*$W8K8HQ{cJ|jv_SmM`7up;2XK!A*vp0Nq_J(g~f0JNu zwoU9m$6l}SJH{OLM9pCjzKuOR>w7)Rt%*H5p}w78=zS}v^9`TFzRO+@o+U`6Y5`kyyUP4 zpTiz}JNwjLuW;Blv1cdLpFLi3*n`hu55Ap!YOh!5?DIK$J6n09H*iibAM}Q6C%fr0 zvqgDwVy6M|Y0jl)8|n@{2EQ>nRy`hj)O$6jnse#TX-suSZExr&EbCVHsP$DY_S7{h z>qQ(jJli<=tgkEaSl4*W?k@4bHL1$j`FK;+39UJav3iE5kJN*c{p!Sode$x4W=p73 z-TGYD5B=Fp-KMSc2ho~ew_l2{o$T9OKmDzs&XE4e(*%o`Yl8JTP3+V==7deVCgGEy zZl9wGJ)Wlt7BANX>vNin5`BVAyC&iDA=boVcJCABTAn6Yyj&Bk&uMa*&;*-yO~R)} Ktck@ur^)}H>w5zL diff --git a/src/86box.h b/src/86box.h index ef0a45e15..d45b1bead 100644 --- a/src/86box.h +++ b/src/86box.h @@ -3,3 +3,5 @@ */ #define emulator_version "1.20" #define emulator_version_w L"1.20" + +#define CONFIG_FILE L"86box.cfg" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 39caf693b..49f095965 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.13 2017/05/17 +# Version: @(#)Makefile.mingw 1.0.14 2017/05/21 # # Authors: Kotori, # Fred N. van Kempen, @@ -29,13 +29,10 @@ STUFF = EXTRAS = # Do we want a debugging build? -DEBUG = y -OPTIM = n +DEBUG = n +OPTIM = y X64 = n -# Where is the WinPcap DLL ? -PCAPDLL = C:\\Windows\\System32\\wpcap.dll - ######################################################################### # Nothing should need changing from here on.. # @@ -46,7 +43,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) +OPTS = -DWIN32 -I$(PLAT) -I$(X64INC) $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) ifeq ($(VRAMDUMP), y) DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP @@ -179,7 +176,7 @@ VIDOBJ = video.o \ WINOBJ = win.o \ win_d3d.o win_d3d-fs.o \ win_ddraw.o win_ddraw-fs.o win_ddraw-screenshot.o \ - win_language.o win_status.o win_opendir.o \ + win_language.o win_status.o win_opendir.o win_dynld.o \ win_video.o win_serial.o win_mouse.o \ win_joystick.o win_midi.o \ win_settings.o win_deviceconfig.o win_joystickconfig.o \ @@ -200,7 +197,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ # Build rules. %.o: %.c @echo $< - $(CC) $(CFLAGS) -c $< + @$(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< @@ -217,7 +214,7 @@ $(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. @$(CC) -o $(PROG).exe \ $(OBJ) $(LZFOBJ) $(SLIRPOBJ) \ - $(LIBS) -static -Lpcap -lwpcapdelay + $(LIBS) #-static -Lpcap -lwpcapdelay ifneq ($(DEBUG), y) @strip $(PROG).exe endif @@ -241,10 +238,6 @@ clean: @echo Processing $< @$(WINDRES) $(RFLAGS) -i win/86Box.rc -o 86Box.res -libwpcapdelay.a: $(PCAPDLL) - @dlltool --export-all-symbols --output-def wpcap.def $(PCAPDLL) - @dlltool --def wpcap.def --output-delaylib libwpcapdelay.a - pcap_if.res: pcap_if.rc @echo Processing $< @$(WINDRES) $(RFLAGS) -i win/pcap_if.rc -o pcap_if.res diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index a593212e4..2da75e1ee 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -1004,6 +1004,7 @@ BEGIN 2199 "USB is not yet supported" 2200 "Invalid PCap device" 2201 "English (United States)" + 2202 "Pcap Library Not Available" END diff --git a/src/WIN/plat_dynld.h b/src/WIN/plat_dynld.h new file mode 100644 index 000000000..74af2e8f8 --- /dev/null +++ b/src/WIN/plat_dynld.h @@ -0,0 +1,30 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Define the Dynamic Module Loader interface. + * + * Version: @(#)plat_dynld.h 1.0.1 2017/05/21 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen + */ +#ifndef PLAT_DYNLD_H +# define PLAT_DYNLD_H + + +typedef struct { + const char *name; + void *func; +} dllimp_t; + + +extern void *dynld_module(const char *, dllimp_t *); +extern void dynld_close(void *); + + +#endif /*PLAT_DYNLD_H*/ diff --git a/src/WIN/win.h b/src/WIN/win.h index ffe8fea2f..255c15a6e 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -1,53 +1,72 @@ +/* + * This should be named 'plat.h' and then include any + * Windows-specific header files needed, to keep them + * out of the main code. + */ /* Copyright holders: Sarah Walker see COPYING for more details */ -extern HINSTANCE hinstance; -extern HWND ghwnd; -extern int mousecapture; +#ifndef BOX_WIN_H +# define BOX_WIN_H -#ifdef __cplusplus -extern "C" { +#if 0 +# define UNICODE +# define BITMAP WINDOWS_BITMAP +# include +# undef BITMAP #endif + #define szClassName L"86BoxMainWnd" #define szSubClassName L"86BoxSubWnd" #define szStatusBarClassName L"86BoxStatusBar" -void leave_fullscreen(); + +extern HINSTANCE hinstance; +extern HWND ghwnd; +extern HWND status_hwnd; +extern HWND hwndStatus; +extern int status_is_open; +extern int mousecapture; + +extern char openfilestring[260]; +extern WCHAR wopenfilestring[260]; + +extern int pause; + + +#ifdef __cplusplus +extern "C" { +#endif + +extern void leave_fullscreen(void); + +extern void status_open(HWND hwnd); + +extern void deviceconfig_open(HWND hwnd, struct device_t *device); +extern void joystickconfig_open(HWND hwnd, int joy_nr, int type); + +extern int getfile(HWND hwnd, char *f, char *fn); +extern int getsfile(HWND hwnd, char *f, char *fn); + +extern void get_executable_name(WCHAR *s, int size); +extern void set_window_title(WCHAR *s); + +extern void startblit(void); +extern void endblit(void); + +extern void win_settings_open(HWND hwnd); +extern void win_menu_update(); + +extern void update_status_bar_panes(HWND hwnds); + +extern int fdd_type_to_icon(int type); + +extern void hard_disk_add_open(HWND hwnd, int is_existing); #ifdef __cplusplus } #endif -void status_open(HWND hwnd); -extern HWND status_hwnd; -extern int status_is_open; - -void deviceconfig_open(HWND hwnd, struct device_t *device); -void joystickconfig_open(HWND hwnd, int joy_nr, int type); - -extern char openfilestring[260]; -extern WCHAR wopenfilestring[260]; - -int getfile(HWND hwnd, char *f, char *fn); -int getsfile(HWND hwnd, char *f, char *fn); - -void get_executable_name(WCHAR *s, int size); -void set_window_title(WCHAR *s); - -void startblit(); -void endblit(); - -extern int pause; - -void win_settings_open(HWND hwnd); -void win_menu_update(); - -void update_status_bar_panes(HWND hwnds); - -int fdd_type_to_icon(int type); - -extern HWND hwndStatus; - -void hard_disk_add_open(HWND hwnd, int is_existing); +#endif /*BOX_WIN_H*/ diff --git a/src/WIN/win_dynld.c b/src/WIN/win_dynld.c new file mode 100644 index 000000000..229febc3a --- /dev/null +++ b/src/WIN/win_dynld.c @@ -0,0 +1,64 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Try to load a support DLL. + * + * Version: @(#)win_dynld.c 1.0.1 2017/05/21 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen + */ +#include +#include +#include +#include +#include +#include +#include "plat_dynld.h" +#include "../ibm.h" + + +void * +dynld_module(const char *name, dllimp_t *table) +{ + HANDLE h; + dllimp_t *imp; + void *func; + char **foo; + + /* See if we can load the desired module. */ + if ((h = LoadLibrary(name)) == NULL) { + pclog("DynLd(\"%s\"): library not found!\n", name); + return(NULL); + } + + /* Now load the desired function pointers. */ + for (imp=table; imp->name!=NULL; imp++) { + func = GetProcAddress(h, imp->name); + if (func == NULL) { + pclog("DynLd(\"%s\"): function '%s' not found!\n", + name, imp->name); + CloseHandle(h); + return(NULL); + } + + /* To overcome typing issues.. */ + *(char **)imp->func = (char *)func; + } + + /* All good. */ + return((void *)h); +} + + +void +dynld_close(void *handle) +{ + if (handle != NULL) + CloseHandle((HANDLE *)handle); +} diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index e87964d37..00abb7faf 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -21,7 +21,7 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -#define STRINGS_NUM 154 +#define STRINGS_NUM 155 /* FIXME: should be in resource.h !! --FvK */ WCHAR lpResourceString[STRINGS_NUM][512]; diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 51fdd7b4e..81800086d 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.4 2017/05/17 + * Version: @(#)net_ne2000.c 1.0.5 2017/05/21 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -1842,10 +1842,21 @@ nic_init(int board) !dev->disable_netbios); if (network_attach(dev, dev->physaddr, nic_rx) < 0) { +#if 0 + msgbox_error_wstr(ghwnd, L"Unable to init platform network"); +#endif pclog(1, "%s: unable to init platform network type %d\n", dev->name, network_type); +#if 0 + /* + * To avoid crashes, we ignore the fact that even though + * there is no active platform support, we just continue + * initializing. If we return an error here, the device + * handling code will throw a fatal error... --FvK + */ free(dev); return(NULL); +#endif } if (dev->is_rtl8029as) @@ -1987,20 +1998,6 @@ static device_config_t ne1000_config[] = } }, }, - { - "net_type", "Network type", CONFIG_SELECTION, "", 0, - { - { - "PCap", 0 - }, - { - "SLiRP", 1 - }, - { - "" - } - }, - }, { "mac", "MAC Address", CONFIG_MAC, "", -1 }, @@ -2063,20 +2060,6 @@ static device_config_t ne2000_config[] = } }, }, - { - "net_type", "Network type", CONFIG_SELECTION, "", 0, - { - { - "PCap", 0 - }, - { - "SLiRP", 1 - }, - { - "" - } - }, - }, { "mac", "MAC Address", CONFIG_MAC, "", -1 }, @@ -2113,20 +2096,6 @@ static device_config_t rtl8029as_config[] = } }, }, - { - "net_type", "Network type", CONFIG_SELECTION, "", 0, - { - { - "PCap", 0 - }, - { - "SLiRP", 1 - }, - { - "" - } - }, - }, { "mac", "MAC Address", CONFIG_MAC, "", -1 }, diff --git a/src/net_pcap.c b/src/net_pcap.c index 3ca2e9089..448738715 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -1,6 +1,6 @@ /* * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM + * running old operating systems and software designed for IBM * PC systems and compatibles from 1981 through fairly recent * system designs based on the PCI bus. * @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.2 2017/05/17 + * Version: @(#)net_pcap.c 1.0.3 2017/05/21 * * Author: Fred N. van Kempen, */ @@ -22,59 +22,61 @@ #include "thread.h" #include "device.h" #include "network.h" +#include "plat_dynld.h" +static void *pcap_handle; /* handle to WinPcap DLL */ static pcap_t *pcap; /* handle to WinPcap library */ static thread_t *poll_tid; static NETRXCB poll_rx; /* network RX function to call */ static void *poll_arg; /* network RX function arg */ -#ifdef WALTJE -int pcap_do_log = 1; -# define ENABLE_PCAP_LOG -#else -int pcap_do_log = 0; -#endif +/* Pointers to the real functions. */ +static const char *(*f_pcap_lib_version)(void); +static int (*f_pcap_findalldevs)(pcap_if_t **,char *); +static void (*f_pcap_freealldevs)(pcap_if_t *); +static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); +static int (*f_pcap_compile)(pcap_t *,struct bpf_program *, + const char *,int,bpf_u_int32); +static int (*f_pcap_setfilter)(pcap_t *,struct bpf_program *); +static const u_char *(*f_pcap_next)(pcap_t *,struct pcap_pkthdr *); +static int (*f_pcap_sendpacket)(pcap_t *,const u_char *,int); +static void (*f_pcap_close)(pcap_t *); +static dllimp_t pcap_imports[] = { + { "pcap_lib_version", &f_pcap_lib_version }, + { "pcap_findalldevs", &f_pcap_findalldevs }, + { "pcap_freealldevs", &f_pcap_freealldevs }, + { "pcap_open_live", &f_pcap_open_live }, + { "pcap_compile", &f_pcap_compile }, + { "pcap_setfilter", &f_pcap_setfilter }, + { "pcap_next", &f_pcap_next }, + { "pcap_sendpacket", &f_pcap_sendpacket }, + { "pcap_close", &f_pcap_close }, + { NULL, NULL }, +}; -static void -pcap_log(const char *format, ...) -{ -#ifdef ENABLE_PCAP_LOG - va_list ap; - - if (pcap_do_log) { - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} -#define pclog pcap_log - - -/* Check if the interface has a packet for us. */ +/* Handle the receiving of frames from the channel. */ static void poll_thread(void *arg) { - const unsigned char *data; uint8_t *mac = (uint8_t *)arg; + const uint8_t *data = NULL; struct pcap_pkthdr h; - event_t *evt; uint32_t mac_cmp32[2]; uint16_t mac_cmp16[2]; + event_t *evt; pclog("PCAP: polling thread started, arg %08lx\n", arg); /* Create a waitable event. */ evt = thread_create_event(); - pclog("PCAP: poll event is %08lx\n", evt); + /* As long as the channel is open.. */ while (pcap != NULL) { /* Wait for the next packet to arrive. */ - data = pcap_next(pcap, &h); + data = f_pcap_next(pcap, &h); if (data != NULL) { /* Received MAC. */ mac_cmp32[0] = *(uint32_t *)(data+6); @@ -105,6 +107,43 @@ poll_thread(void *arg) } +/* Initialize the (Win)Pcap module for use. */ +int +network_pcap_init(netdev_t *list) +{ + char errbuf[PCAP_ERRBUF_SIZE]; + pcap_if_t *devlist, *dev; + int i = 0; + + /* Local variables. */ + pcap = NULL; + + /* Try loading the DLL. */ + pcap_handle = dynld_module("wpcap.dll", pcap_imports); + if (pcap_handle == NULL) return(-1); + + /* Retrieve the device list from the local machine */ + if (f_pcap_findalldevs(&devlist, errbuf) == -1) { + pclog("PCAP: error in pcap_findalldevs: %s\n", errbuf); + return(-1); + } + + for (dev=devlist; dev!=NULL; dev=dev->next) { + strcpy(list->device, dev->name); + if (dev->description) + strcpy(list->description, dev->description); + else + memset(list->description, '\0', sizeof(list->description)); + list++; i++; + } + + /* Release the memory. */ + f_pcap_freealldevs(devlist); + + return(i); +} + + /* Initialize WinPcap for us. */ int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) @@ -114,20 +153,13 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) struct bpf_program fp; char *dev; - /* Messy, but gets rid of a lot of useless info. */ - dev = (char *)pcap_lib_version(); - if (dev == NULL) { - /* Hmm, WinPcap doesn't seem to be alive.. */ - pclog("PCAP: WinPcap library not found, disabling network!\n"); - network_type = -1; - return(-1); - } + /* Did we already load the DLL? */ + if (pcap_handle == NULL) return(-1); - /* OK, good for now.. */ - strcpy(temp, dev); + strcpy(temp, f_pcap_lib_version()); dev = strchr(temp, '('); if (dev != NULL) *(dev-1) = '\0'; - pclog("Initializing WinPcap, version %s\n", temp); + pclog("PCAP: initializing, %s\n", temp); /* Get the value of our capture interface. */ dev = network_pcap; @@ -137,38 +169,35 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) } pclog(" Network interface: '%s'\n", dev); - pcap = pcap_open_live(dev, /* interface name */ - 1518, /* maximum packet size */ - 1, /* promiscuous mode? */ - 10, /* timeout in msec */ - temp); /* error buffer */ + pcap = f_pcap_open_live(dev, /* interface name */ + 1518, /* maximum packet size */ + 1, /* promiscuous mode? */ + 10, /* timeout in msec */ + temp); /* error buffer */ if (pcap == NULL) { - pclog("Unable to open WinPcap: %s!\n", temp); + pclog(" Unable to open device: %s!\n", temp); return(-1); } /* Create a MAC address based packet filter. */ - pclog("Building packet filter ..."); + pclog(" Installing packet filter for MAC=%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); sprintf(filter_exp, "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - if (pcap_compile(pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { - pclog("..."); - if (pcap_setfilter(pcap, &fp) == -1) { - pclog(" error installing filter!\n"); - } else { - pclog("!\nUsing filter\t[%s]\n", filter_exp); - } + if (f_pcap_compile(pcap, &fp, filter_exp, 0, 0xffffffff) != -1) { + if (f_pcap_setfilter(pcap, &fp) == -1) + pclog(" Error installing filter (%s) !\n", filter_exp); } else { - pclog(" could not compile filter!\n"); + pclog(" Could not compile filter (%s) !\n", filter_exp); } /* Save the callback info. */ poll_rx = func; poll_arg = arg; - pclog("PCAP: creating thread..\n"); + pclog(" Starting thread..\n"); poll_tid = thread_create(poll_thread, mac); return(0); @@ -199,7 +228,13 @@ network_pcap_close(void) #endif /* OK, now shut down WinPcap itself. */ - pcap_close(pc); + f_pcap_close(pc); + + /* Unload the DLL if possible. */ + if (pcap_handle != NULL) { + dynld_close(pcap_handle); + pcap_handle = NULL; + } } poll_rx = NULL; poll_arg = NULL; @@ -211,49 +246,5 @@ void network_pcap_in(uint8_t *bufp, int len) { if (pcap != NULL) - pcap_sendpacket(pcap, bufp, len); -} - - -/* Retrieve an easy-to-use list of devices. */ -int -network_devlist(netdev_t *list) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - char *temp_dev; - pcap_if_t *devlist, *dev; - int i = 0; - - /* Create a first entry that's always there - needed by UI. */ - strcpy(list->device, "none"); - strcpy(list->description, "None"); - list++; i++; - - /* See if WinPcap is even present, and get out of here if it's not. */ - temp_dev = (char *)pcap_lib_version(); - if (temp_dev == NULL) { - /* Hmm, WinPcap doesn't seem to be alive.. */ - pclog("PCAP: WinPcap library not found, not processing the networks list further!\n"); - return(i); - } - - /* Retrieve the device list from the local machine */ - if (pcap_findalldevs(&devlist, errbuf) == -1) { - pclog("NETWORK: error in pcap_findalldevs: %s\n", errbuf); - return(i); - } - - for (dev=devlist; dev!=NULL; dev=dev->next) { - strcpy(list->device, dev->name); - if (dev->description) - strcpy(list->description, dev->description); - else - memset(list->description, '\0', sizeof(list->description)); - list++; i++; - } - - /* Release the memory. */ - pcap_freealldevs(devlist); - - return(i); + f_pcap_sendpacket(pcap, bufp, len); } diff --git a/src/network.c b/src/network.c index 63a8c0f9d..90bd69aac 100644 --- a/src/network.c +++ b/src/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.4 2017/05/17 + * Version: @(#)network.c 1.0.5 2017/05/21 * * Authors: Kotori, * Fred N. van Kempen, @@ -25,6 +25,14 @@ #include "device.h" #include "network.h" #include "net_ne2000.h" +#ifndef unix +# define UNICODE +# define BITMAP WINDOWS_BITMAP +# include +# undef BITMAP +# include "win.h" +# include "win_language.h" +#endif static netcard_t net_cards[] = { @@ -59,11 +67,20 @@ char network_pcap[512]; void network_init(void) { + int i; + network_type = NET_TYPE_NONE; network_card = 0; - /* Initialize list of PCap devices. */ - network_ndev = network_devlist(network_devs); + /* Create a first device entry that's always there, as needed by UI. */ + strcpy(network_devs[0].device, "none"); + strcpy(network_devs[0].description, "None"); + network_ndev = 1; + + /* Initialize the Pcap system module, if present. */ + i = network_pcap_init(&network_devs[network_ndev]); + if (i > 0) + network_ndev += i; } @@ -79,7 +96,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) { int ret = -1; - if (! network_card) return(ret); + if (network_card == 0) return(ret); /* Save the card's callback info. */ net_cards[network_card].private = dev; @@ -89,6 +106,10 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) switch(network_type) { case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); + if (ret < 0) { + msgbox_error(ghwnd, 2202); + network_type = NET_TYPE_NONE; + } break; case NET_TYPE_SLIRP: @@ -128,7 +149,7 @@ network_close(void) void network_reset(void) { - pclog("NETWORK: reset (type=%d, card=%d\n", network_type, network_card); + pclog("NETWORK: reset (type=%d, card=%d)\n", network_type, network_card); /* Just in case.. */ network_close(); @@ -136,11 +157,10 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; - pclog("NETWORK: set up for %s, card=%s\n", + pclog("NETWORK: set up for %s, card='%s'\n", (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", net_cards[network_card].name); - pclog("NETWORK: reset (card=%d)\n", network_card); /* Add the (new?) card to the I/O system. */ if (net_cards[network_card].device) { pclog("NETWORK: adding device '%s'\n", diff --git a/src/network.h b/src/network.h index 30a8427b8..b8b98e2ae 100644 --- a/src/network.h +++ b/src/network.h @@ -8,7 +8,7 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.4 2017/05/17 + * Version: @(#)network.h 1.0.5 2017/05/21 * * Authors: Kotori, * Fred N. van Kempen, @@ -62,16 +62,15 @@ extern void network_close(void); extern void network_reset(void); extern void network_tx(uint8_t *, int); +extern int network_pcap_init(netdev_t *); extern int network_pcap_setup(uint8_t *, NETRXCB, void *); extern void network_pcap_close(void); extern void network_pcap_in(uint8_t *, int); -extern int network_devlist(netdev_t *); extern int network_slirp_setup(uint8_t *, NETRXCB, void *); extern void network_slirp_close(void); extern void network_slirp_in(uint8_t *, int); -extern int network_devlist(netdev_t *); extern int network_dev_to_id(char *); extern int network_card_available(int); extern char *network_card_getname(int); From a4cd4b2866201150e1bbc87a83302192f4d300bf Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 22 May 2017 13:52:45 +0200 Subject: [PATCH 245/392] Increased HD heads limit to 255, larger SCSI hdds now work. --- src/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index a335ab55a..04557b544 100644 --- a/src/config.c +++ b/src/config.c @@ -971,9 +971,9 @@ static void loadconfig_hard_disks(void) { hdc[c].spt = 99; } - if (hdc[c].hpc > 64) + if (hdc[c].hpc > 255) { - hdc[c].hpc = 64; + hdc[c].hpc = 255; } if (hdc[c].tracks > 266305) { From 77430348fca19fee4e927d1f0e8e6f68b3beb89b Mon Sep 17 00:00:00 2001 From: waltje Date: Wed, 24 May 2017 00:27:42 -0400 Subject: [PATCH 246/392] Another network cleaning (MAC address madness, BIOS stuff), WIN platform cleanup, Makefile[.local] cleanup. --- src/Makefile.local | 42 ++ src/Makefile.mingw | 134 ++--- src/WIN/win.c | 23 +- src/WIN/win.h | 11 +- src/WIN/win_crashdump.c | 344 +++++++------ src/WIN/win_d3d-fs.h | 13 - src/WIN/win_d3d.cc | 7 +- src/WIN/win_d3d.h | 27 +- src/WIN/{win_d3d-fs.cc => win_d3d_fs.cc} | 18 +- src/WIN/win_ddraw-fs.h | 11 - src/WIN/win_ddraw-screenshot.h | 4 - src/WIN/win_ddraw.cc | 5 - src/WIN/win_ddraw.h | 22 +- src/WIN/{win_ddraw-fs.cc => win_ddraw_fs.cc} | 32 +- ...-screenshot.cc => win_ddraw_screenshot.cc} | 18 +- src/WIN/win_deviceconfig.c | 9 +- src/config.c | 9 - src/net_ne2000.c | 457 +++++++++--------- src/net_pcap.c | 4 +- src/network.c | 12 +- src/pc.c | 12 +- 21 files changed, 653 insertions(+), 561 deletions(-) create mode 100644 src/Makefile.local delete mode 100644 src/WIN/win_d3d-fs.h rename src/WIN/{win_d3d-fs.cc => win_d3d_fs.cc} (99%) delete mode 100644 src/WIN/win_ddraw-fs.h delete mode 100644 src/WIN/win_ddraw-screenshot.h rename src/WIN/{win_ddraw-fs.cc => win_ddraw_fs.cc} (97%) rename src/WIN/{win_ddraw-screenshot.cc => win_ddraw_screenshot.cc} (94%) diff --git a/src/Makefile.local b/src/Makefile.local new file mode 100644 index 000000000..9b9988201 --- /dev/null +++ b/src/Makefile.local @@ -0,0 +1,42 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# Prefix for localizing the general Makefile.mingw for local +# settings, so we can avoid changing the main one for all of +# our local setups. +# +# Version: @(#)Makefile.local 1.0.2 2017/05/23 +# +# Author: Fred N. van Kempen, +# + +######################################################################### +# Anything here will override defaults in Makefile.MinGW. # +######################################################################### + + +DEBUG = y +OPTIM = n +COPTIM = -O1 + +# Name of the executable. +PROG = yourexe + +# Various compile-time options. +STUFF = #-DROM_TRACE=0xC800 -DIO_TRACE=0x70 +EXTRAS = #-DYOURNAME + + + +######################################################################### +# Include the master Makefile.MinGW for the rest. # +######################################################################### +include Makefile.mingw + + +# End of Makefile.local. diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 49f095965..4ba3565e2 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.14 2017/05/21 +# Version: @(#)Makefile.mingw 1.0.16 2017/05/22 # # Authors: Kotori, # Fred N. van Kempen, @@ -17,21 +17,33 @@ # # Name of the executable. +ifndef PROG PROG = 86Box +endif # Various compile-time options. # -DROM_TRACE=0xcd800 traces ROM access from segment C800 # -DIO_TACE=0x66 traces I/O on port 0x66 +ifndef STUFF STUFF = +endif # Add feature selections here. # -DBUGGER adds the ISA BusBugger emulation. -EXTRAS = +ifndef EXTRAS +EXTRAS = lala +endif # Do we want a debugging build? +ifndef DEBUG DEBUG = n +endif +ifndef OPTIM OPTIM = y +endif +ifndef X64 X64 = n +endif ######################################################################### @@ -43,27 +55,33 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe -OPTS = -DWIN32 -I$(PLAT) -I$(X64INC) $(EXTRAS) $(STUFF) +OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) ifeq ($(DEBUG), y) ifeq ($(VRAMDUMP), y) DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP else DFLAGS = -march=i686 -ggdb -DDEBUG endif +ifndef COPTIM COPTIM = -Og +endif else ifeq ($(OPTIM), y) DFLAGS = -march=native +ifndef COPTIM COPTIM = -O6 +endif else ifeq ($(X64), y) DFLAGS = else DFLAGS = -march=i686 endif +ifndef COPTIM COPTIM = -O3 endif endif +endif ifeq ($(OPTIM), y) AOPTIM = -mtune=native else @@ -102,17 +120,17 @@ CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ codegen_timing_winchip.o $(PLATCG) \ x86seg.o x87.o SYSOBJ = model.o \ - headland.o \ - i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ - neat.o \ - ali1429.o \ - opti495.o \ - scat.o \ - sis496.o \ - wd76c10.o \ - acer386sx.o acerm3a.o amstrad.o \ - compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ - tandy_eeprom.o tandy_rom.o + headland.o \ + i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ + neat.o \ + ali1429.o \ + opti495.o \ + scat.o \ + sis496.o \ + wd76c10.o \ + acer386sx.o acerm3a.o amstrad.o \ + compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ + tandy_eeprom.o tandy_rom.o DEVOBJ = bugger.o lpt.o serial.o \ um8669f.o pc87306.o sis85c471.o w83877f.o \ keyboard.o \ @@ -133,53 +151,53 @@ DEVOBJ = bugger.o lpt.o serial.o \ cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o USBOBJ = usb.o NETOBJ = network.o \ - net_pcap.o net_slirp.o \ - net_ne2000.o + net_pcap.o net_slirp.o \ + net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ - convolve.o convolve-sse.o envelope.o extfilt.o \ - filter.o pot.o sid.o voice.o wave6581__ST.o \ - wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ - wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ - wave8580_PST.o wave.o \ - dbopl.o nukedopl.o openal.o \ - snd_speaker.o snd_ps1.o snd_pssj.o \ - snd_adlib.o snd_adlibgold.o snd_ad1848.o \ - snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ - snd_emu8k.o snd_gus.o snd_opl.o \ - snd_mpu401.o snd_pas16.o snd_resid.o \ - snd_sn76489.o snd_ssi2001.o snd_wss.o \ - snd_ym7128.o + convolve.o convolve-sse.o envelope.o extfilt.o \ + filter.o pot.o sid.o voice.o wave6581__ST.o \ + wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ + wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o \ + dbopl.o nukedopl.o openal.o \ + snd_speaker.o snd_ps1.o snd_pssj.o \ + snd_adlib.o snd_adlibgold.o snd_ad1848.o \ + snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ + snd_emu8k.o snd_gus.o snd_opl.o \ + snd_mpu401.o snd_pas16.o snd_resid.o \ + snd_sn76489.o snd_ssi2001.o snd_wss.o \ + snd_ym7128.o VIDOBJ = video.o \ - vid_cga.o vid_cga_comp.o vid_mda.o vid_ega.o \ - vid_vga.o vid_svga.o vid_svga_render.o \ - vid_hercules.o vid_herculesplus.o vid_incolor.o \ - vid_colorplus.o \ - vid_genius.o \ - vid_s3.o vid_s3_virge.o \ - vid_et4000.o vid_et4000w32.o vid_icd2061.o \ - vid_oti067.o \ - vid_paradise.o \ - vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ - vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ - vid_ati68860_ramdac.o vid_ati_mach64.o \ - vid_ics2595.o \ - vid_sdac_ramdac.o \ - vid_stg_ramdac.o \ - vid_unk_ramdac.o \ - vid_wy700.o \ - vid_voodoo.o \ - vid_pcjr.o vid_ps1_svga.o \ - vid_olivetti_m24.o \ - vid_pc1512.o vid_pc1640.o vid_pc200.o \ - vid_tandy.o vid_tandysl.o + vid_cga.o vid_cga_comp.o vid_mda.o vid_ega.o \ + vid_vga.o vid_svga.o vid_svga_render.o \ + vid_hercules.o vid_herculesplus.o vid_incolor.o \ + vid_colorplus.o \ + vid_genius.o \ + vid_s3.o vid_s3_virge.o \ + vid_et4000.o vid_et4000w32.o vid_icd2061.o \ + vid_oti067.o \ + vid_paradise.o \ + vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ + vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ + vid_ati68860_ramdac.o vid_ati_mach64.o \ + vid_ics2595.o \ + vid_sdac_ramdac.o \ + vid_stg_ramdac.o \ + vid_unk_ramdac.o \ + vid_wy700.o \ + vid_voodoo.o \ + vid_pcjr.o vid_ps1_svga.o \ + vid_olivetti_m24.o \ + vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_tandy.o vid_tandysl.o WINOBJ = win.o \ - win_d3d.o win_d3d-fs.o \ - win_ddraw.o win_ddraw-fs.o win_ddraw-screenshot.o \ - win_language.o win_status.o win_opendir.o win_dynld.o \ - win_video.o win_serial.o win_mouse.o \ - win_joystick.o win_midi.o \ - win_settings.o win_deviceconfig.o win_joystickconfig.o \ + win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \ + win_d3d.o win_d3d_fs.o \ + win_language.o win_status.o win_opendir.o win_dynld.o \ + win_video.o win_serial.o win_mouse.o \ + win_joystick.o win_midi.o \ + win_settings.o win_deviceconfig.o win_joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) @@ -197,7 +215,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ # Build rules. %.o: %.c @echo $< - @$(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< diff --git a/src/WIN/win.c b/src/WIN/win.c index af72b0ef1..4b6c771d0 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1,21 +1,10 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ -#define UNICODE -#define _WIN32_WINNT 0x0501 -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include #include "../86box.h" #include "../device.h" #include "../disc.h" @@ -45,10 +34,12 @@ #include "win.h" #include "win_ddraw.h" -#include "win_ddraw-fs.h" #include "win_d3d.h" -#include "win_d3d-fs.h" #include "win_language.h" +#include +#include +#include +#include #include "resource.h" diff --git a/src/WIN/win.h b/src/WIN/win.h index 255c15a6e..1d4feec57 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -8,13 +8,16 @@ */ #ifndef BOX_WIN_H # define BOX_WIN_H - -#if 0 -# define UNICODE +# ifndef NO_UNICODE +# define UNICODE +# endif # define BITMAP WINDOWS_BITMAP +//# ifdef _WIN32_WINNT +//# undef _WIN32_WINNT +//# define _WIN32_WINNT 0x0501 +//# endif # include # undef BITMAP -#endif #define szClassName L"86BoxMainWnd" diff --git a/src/WIN/win_crashdump.c b/src/WIN/win_crashdump.c index 3fee061b3..957ce296e 100644 --- a/src/WIN/win_crashdump.c +++ b/src/WIN/win_crashdump.c @@ -12,174 +12,214 @@ #include "../86box.h" #include "win_crashdump.h" -PVOID hExceptionHandler; -char* ExceptionHandlerBuffer; + #define ExceptionHandlerBufferSize (10240) -LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { - // Win32-specific functions will be used wherever possible, just in case the C stdlib-equivalents try to allocate memory. - // (The Win32-specific functions are generally just wrappers over NT system calls anyway.) - - if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) { - // The exception code is not a fatal exception (highest 4 bits of ntstatus = 0xC) - // Not going to crash, let's not make a crash dump - return EXCEPTION_CONTINUE_SEARCH; - } - - // So, the program is about to crash. Oh no what do? - // Let's create a crash dump file as a debugging-aid. - - // First, get the path to 86Box.exe. - char* CurrentBufferPointer; - GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); - if (GetLastError() != ERROR_SUCCESS) { - // Could not get the full path of 86Box.exe. Just create the file in the current directory. - CurrentBufferPointer = ExceptionHandlerBuffer; - } else { - // Walk through the string backwards looking for the last backslash, so as to remove the "86Box.exe" filename from the string. - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - for (; CurrentBufferPointer > ExceptionHandlerBuffer; CurrentBufferPointer--) { - if (CurrentBufferPointer[0] == '\\') { - // Found the backslash, null terminate the string after it. - CurrentBufferPointer[1] = 0; - break; - } - } - - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - } - - // What would a good filename be? It should contain the current date and time so as to be (hopefully!) unique. - SYSTEMTIME SystemTime; - GetSystemTime(&SystemTime); - sprintf(CurrentBufferPointer, - "86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp", - SystemTime.wYear, - SystemTime.wMonth, - SystemTime.wDay, - SystemTime.wHour, - SystemTime.wMinute, - SystemTime.wSecond, - SystemTime.wMilliseconds); - - DWORD Error; - - // Now the filename is in the buffer, the file can be created. - HANDLE hDumpFile = CreateFile( - ExceptionHandlerBuffer, // The filename of the file to open. - GENERIC_WRITE, // The permissions to request. - 0, // Make sure other processes can't touch the crash dump at all while it's open. - NULL, // Leave the security descriptor undefined, it doesn't matter. - OPEN_ALWAYS, // Opens the file if it exists, creates a new file if it doesn't. - FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter. - NULL); // A template file is not being used. - - // Check to make sure the file was actually created. - if (hDumpFile == INVALID_HANDLE_VALUE) { - // CreateFile() failed, so just do nothing more. - return EXCEPTION_CONTINUE_SEARCH; - } - - // Now the file is open, let's write the data we were passed out in a human-readable format. - - // Let's get the name of the module where the exception occured. - HMODULE hMods[1024]; - MODULEINFO modInfo; - HMODULE ipModule = 0; - DWORD cbNeeded; - // Try to get a list of all loaded modules. - if (EnumProcessModules(GetCurrentProcess(), hMods, sizeof(hMods), &cbNeeded)) { - // The list was obtained, walk through each of the modules. - for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { - // For each module, get the module information (base address, size, entry point) - GetModuleInformation(GetCurrentProcess(), hMods[i], &modInfo, sizeof(MODULEINFO)); - // If the exception address is located in the range of where this module is loaded... - if ( - (ExceptionInfo->ExceptionRecord->ExceptionAddress >= modInfo.lpBaseOfDll) && - (ExceptionInfo->ExceptionRecord->ExceptionAddress < (modInfo.lpBaseOfDll + modInfo.SizeOfImage)) - ) { - // ...this is the module we're looking for! - ipModule = hMods[i]; - break; - } +static PVOID hExceptionHandler; +static char *ExceptionHandlerBuffer; + + +LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) +{ + SYSTEMTIME SystemTime; + HANDLE hDumpFile; + DWORD Error; + char *BufPtr; + + /* + * Win32-specific functions will be used wherever possible, + * just in case the C stdlib-equivalents try to allocate + * memory. + * (The Win32-specific functions are generally just wrappers + * over NT system calls anyway.) + */ + if ((ExceptionInfo->ExceptionRecord->ExceptionCode >> 28) != 0xC) { + /* + * ExceptionCode is not a fatal exception (high 4b of + * ntstatus = 0xC) Not going to crash, let's not make + * a crash dump. + */ + return(EXCEPTION_CONTINUE_SEARCH); + } + + /* + * So, the program is about to crash. Oh no what do? + * Let's create a crash dump file as a debugging-aid. + * + * First, get the path to the executable. + */ + GetModuleFileName(NULL,ExceptionHandlerBuffer,ExceptionHandlerBufferSize); + if (GetLastError() != ERROR_SUCCESS) { + /* Could not get full path, create in current directory. */ + BufPtr = ExceptionHandlerBuffer; + } else { + /* + * Walk through the string backwards looking for the + * last backslash, so as to remove the "86Box.exe" + * filename from the string. + */ + BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + for (; BufPtr > ExceptionHandlerBuffer; BufPtr--) { + if (BufPtr[0] == '\\') { + /* Found backslash, terminate the string after it. */ + BufPtr[1] = 0; + break; } } + + BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + } - // Start to put the crash-dump string into the buffer. + /* + * What would a good filename be? + * + * It should contain the current date and time so as + * to be (hopefully!) unique. + */ + GetSystemTime(&SystemTime); + sprintf(CurrentBufferPointer, + "86box-%d%02d%02d-%02d-%02d-%02d-%03d.dmp", + SystemTime.wYear, + SystemTime.wMonth, + SystemTime.wDay, + SystemTime.wHour, + SystemTime.wMinute, + SystemTime.wSecond, + SystemTime.wMilliseconds); + + /* Now the filename is in the buffer, the file can be created. */ + hDumpFile = CreateFile( + ExceptionHandlerBuffer, // The filename of the file to open. + GENERIC_WRITE, // The permissions to request. + 0, // Make sure other processes can't + // touch the crash dump at all + // while it's open. + NULL, // Leave the security descriptor + // undefined, it doesn't matter. + OPEN_ALWAYS, // Opens the file if it exists, + // creates a new file if it doesn't. + FILE_ATTRIBUTE_NORMAL, // File attributes / etc don't matter. + NULL); // A template file is not being used. - sprintf(ExceptionHandlerBuffer, - "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" - "" - "Exception details:\r\n" - "Exception NTSTATUS code: 0x%08x\r\n" - "Occured at address: 0x%p", - emulator_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, - - ExceptionInfo->ExceptionRecord->ExceptionCode, - ExceptionInfo->ExceptionRecord->ExceptionAddress); - + /* Check to make sure the file was actually created. */ + if (hDumpFile == INVALID_HANDLE_VALUE) { + /* CreateFile() failed, so just do nothing more. */ + return(EXCEPTION_CONTINUE_SEARCH); + } - // If we found the module that the exception occured in, get the full path to the module the exception occured at and include it. - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - if (ipModule != 0) { - sprintf(CurrentBufferPointer," ["); - GetModuleFileName(ipModule,&CurrentBufferPointer[2],ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); - if (GetLastError() == ERROR_SUCCESS) { - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - sprintf(CurrentBufferPointer,"]"); - CurrentBufferPointer += 1; + // Now the file is open, let's write the data we were passed out in a human-readable format. + + // Let's get the name of the module where the exception occured. + HMODULE hMods[1024]; + MODULEINFO modInfo; + HMODULE ipModule = 0; + DWORD cbNeeded; + + // Try to get a list of all loaded modules. + if (EnumProcessModules(GetCurrentProcess(), + hMods, sizeof(hMods), &cbNeeded)) { + // The list was obtained, walk through each of the modules. + for (DWORD i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) { + // For each module, get the module information + // (base address, size, entry point) + GetModuleInformation(GetCurrentProcess(), + hMods[i], &modInfo, sizeof(MODULEINFO)); + // If the exception address is located in the range of + // where this module is loaded... + if ( (ExceptionInfo->ExceptionRecord->ExceptionAddress >= modInfo.lpBaseOfDll) && + (ExceptionInfo->ExceptionRecord->ExceptionAddress < (modInfo.lpBaseOfDll + modInfo.SizeOfImage))) { + // ...this is the module we're looking for! + ipModule = hMods[i]; + break; } } + } - // Continue to create the crash-dump string. - sprintf(CurrentBufferPointer, - "\r\n" - "Number of parameters: %d\r\n" - "Exception parameters: ", - ExceptionInfo->ExceptionRecord->NumberParameters); - - // Add the exception parameters to the crash-dump string. - for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; - sprintf(CurrentBufferPointer,"0x%p ",ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); + // Start to put the crash-dump string into the buffer. + sprintf(ExceptionHandlerBuffer, + "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" + "" + "Exception details:\r\n" + "Exception NTSTATUS code: 0x%08x\r\n" + "Occured at address: 0x%p", + emulator_version, + SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, + SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, + SystemTime.wMilliseconds, + ExceptionInfo->ExceptionRecord->ExceptionCode, + ExceptionInfo->ExceptionRecord->ExceptionAddress); + + // If we found the module that the exception occured in, get the full path to the module the exception occured at and include it. + BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + if (ipModule != 0) { + sprintf(BufPtr," ["); + GetModuleFileName(ipModule, &BufPtr[2], + ExceptionHandlerBufferSize - strlen(ExceptionHandlerBuffer)); + if (GetLastError() == ERROR_SUCCESS) { + BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(BufPtr,"]"); + BufPtr += 1; } + } - CurrentBufferPointer = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1]; + // Continue to create the crash-dump string. + sprintf(BufPtr, + "\r\n" + "Number of parameters: %d\r\n" + "Exception parameters: ", + ExceptionInfo->ExceptionRecord->NumberParameters); - PCONTEXT Registers = ExceptionInfo->ContextRecord; + // Add the exception parameters to the crash-dump string. + for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { + BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; + sprintf(BufPtr,"0x%p ", + ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); + } + BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1]; + + PCONTEXT Registers = ExceptionInfo->ContextRecord; - #if defined(__i386__) && !defined(__x86_64) - // This binary is being compiled for x86, include a register dump. - sprintf(CurrentBufferPointer, - "\r\n" - "Register dump:\r\n" - "eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n" - "\r\n", - Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip); - #else - // Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition. - sprintf(CurrentBufferPointer,"\r\n"); - #endif +#if defined(__i386__) && !defined(__x86_64) + // This binary is being compiled for x86, include a register dump. + sprintf(BufPtr, + "\r\n" + "Register dump:\r\n" + "eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n" + "\r\n", + Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip); +#else + // Register dump is supported by no other architectures right now. MinGW headers seem to lack the x64 CONTEXT structure definition. + sprintf(BufPtr,"\r\n"); +#endif - // The crash-dump string has been created, write it to disk. - WriteFile(hDumpFile, - ExceptionHandlerBuffer, - strlen(ExceptionHandlerBuffer), - NULL, - NULL); - - // Finally, close the file. - CloseHandle(hDumpFile); - - // And return, therefore causing the crash, but only after the crash dump has been created. - - return EXCEPTION_CONTINUE_SEARCH; + // The crash-dump string has been created, write it to disk. + WriteFile(hDumpFile, ExceptionHandlerBuffer, + strlen(ExceptionHandlerBuffer), NULL, NULL); + + // Finally, close the file. + CloseHandle(hDumpFile); + + // And return, therefore causing the crash, + // but only after the crash dump has been created. + return(EXCEPTION_CONTINUE_SEARCH); } -void InitCrashDump() { - // An exception handler should not allocate memory, so allocate 10kb for it to use if it gets called, an amount which should be more than enough. - ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize); - // Register the exception handler. Zero first argument means this exception handler gets called last, therefore, crash dump is only made, when a crash is going to happen. - hExceptionHandler = AddVectoredExceptionHandler(0,MakeCrashDump); + +void InitCrashDump(void) +{ + /* + * An exception handler should not allocate memory, + * so allocate 10kb for it to use if it gets called, + * an amount which should be more than enough. + */ + ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize); + + /* + * Register the exception handler. + * Zero first argument means this exception handler gets + * called last, therefore, crash dump is only made, when + * a crash is going to happen. + */ + hExceptionHandler = AddVectoredExceptionHandler(0, MakeCrashDump); } diff --git a/src/WIN/win_d3d-fs.h b/src/WIN/win_d3d-fs.h deleted file mode 100644 index 41ca32e21..000000000 --- a/src/WIN/win_d3d-fs.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int d3d_fs_init(HWND h); - void d3d_fs_close(); - void d3d_fs_reset(); - void d3d_fs_resize(int x, int y); -#ifdef __cplusplus -} -#endif diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index 258bcd4f8..ce2d9a3b5 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -2,14 +2,9 @@ see COPYING for more details */ #include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include +#include "../video/video.h" #include "win.h" #include "win_d3d.h" -#include "../video/video.h" #include "win_cgapal.h" #include "resource.h" diff --git a/src/WIN/win_d3d.h b/src/WIN/win_d3d.h index 7210d454b..5994a87b1 100644 --- a/src/WIN/win_d3d.h +++ b/src/WIN/win_d3d.h @@ -1,13 +1,32 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +#ifndef WIN_D3D_H +# define WIN_D3D_H +# define UNICODE +# define BITMAP WINDOWS_BITMAP +# include +# include +# undef BITMAP + + #ifdef __cplusplus extern "C" { #endif - int d3d_init(HWND h); - void d3d_close(); - void d3d_reset(); - void d3d_resize(int x, int y); + +extern int d3d_init(HWND h); +extern void d3d_close(void); +extern void d3d_reset(void); +extern void d3d_resize(int x, int y); + +extern int d3d_fs_init(HWND h); +extern void d3d_fs_close(void); +extern void d3d_fs_reset(void); +extern void d3d_fs_resize(int x, int y); + #ifdef __cplusplus } #endif + + +#endif /*WIN_D3D_H*/ diff --git a/src/WIN/win_d3d-fs.cc b/src/WIN/win_d3d_fs.cc similarity index 99% rename from src/WIN/win_d3d-fs.cc rename to src/WIN/win_d3d_fs.cc index 4e6a367cb..9e410ec3b 100644 --- a/src/WIN/win_d3d-fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -3,15 +3,10 @@ */ #include #include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP -#include #include "../86box.h" #include "../video/video.h" #include "win.h" -#include "win_d3d-fs.h" +#include "win_d3d.h" #include "win_cgapal.h" #include "resource.h" @@ -110,6 +105,7 @@ static CUSTOMVERTEX d3d_verts[] = {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, }; + void cgapal_rebuild(void) { int c; @@ -133,6 +129,7 @@ void cgapal_rebuild(void) } } + int d3d_fs_init(HWND h) { HRESULT hr; @@ -197,6 +194,7 @@ int d3d_fs_init(HWND h) return 1; } + static void d3d_fs_close_objects(void) { if (d3dTexture) @@ -211,6 +209,7 @@ static void d3d_fs_close_objects(void) } } + static void d3d_fs_init_objects(void) { D3DLOCKED_RECT dr; @@ -248,6 +247,7 @@ static void d3d_fs_init_objects(void) d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } + /*void d3d_resize(int x, int y) { HRESULT hr; @@ -258,6 +258,7 @@ static void d3d_fs_init_objects(void) d3d_reset(); }*/ + void d3d_fs_reset(void) { HRESULT hr; @@ -293,6 +294,7 @@ void d3d_fs_reset(void) device_force_redraw(); } + void d3d_fs_close(void) { if (d3dTexture) @@ -318,6 +320,7 @@ void d3d_fs_close(void) DestroyWindow(d3d_device_window); } + static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h) { int ratio_w, ratio_h; @@ -368,6 +371,7 @@ static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, doubl } } + static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { HRESULT hr = D3D_OK; @@ -466,6 +470,7 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) PostMessage(ghwnd, WM_RESETD3D, 0, 0); } + static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) { HRESULT hr = D3D_OK; @@ -573,6 +578,7 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) PostMessage(ghwnd, WM_RESETD3D, 0, 0); } + void d3d_fs_take_screenshot(wchar_t *fn) { LPDIRECT3DSURFACE9 d3dSurface = NULL; diff --git a/src/WIN/win_ddraw-fs.h b/src/WIN/win_ddraw-fs.h deleted file mode 100644 index 048c9c160..000000000 --- a/src/WIN/win_ddraw-fs.h +++ /dev/null @@ -1,11 +0,0 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -#ifdef __cplusplus -extern "C" { -#endif - int ddraw_fs_init(HWND h); - void ddraw_fs_close(); -#ifdef __cplusplus -} -#endif diff --git a/src/WIN/win_ddraw-screenshot.h b/src/WIN/win_ddraw-screenshot.h deleted file mode 100644 index 4739174a1..000000000 --- a/src/WIN/win_ddraw-screenshot.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ -void ddraw_common_take_screenshot(wchar_t *fn, IDirectDrawSurface7 *pDDSurface); diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc index af329eb29..dd985baf8 100644 --- a/src/WIN/win_ddraw.cc +++ b/src/WIN/win_ddraw.cc @@ -3,13 +3,8 @@ */ #include #include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP #include "../video/video.h" #include "win_ddraw.h" -#include "win_ddraw-screenshot.h" #include "win_cgapal.h" diff --git a/src/WIN/win_ddraw.h b/src/WIN/win_ddraw.h index a4044899d..5090aa0cc 100644 --- a/src/WIN/win_ddraw.h +++ b/src/WIN/win_ddraw.h @@ -1,12 +1,30 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +#ifndef WIN_DDRAW_H +# define WIN_DDRAW_H +# define UNICODE +# define BITMAP WINDOWS_BITMAP +# include +# undef BITMAP + + #ifdef __cplusplus extern "C" { #endif - int ddraw_init(HWND h); - void ddraw_close(); + +extern int ddraw_init(HWND h); +extern void ddraw_close(void); + +extern int ddraw_fs_init(HWND h); +extern void ddraw_fs_close(void); + +extern void ddraw_common_take_screenshot(wchar_t *fn, + IDirectDrawSurface7 *pDDSurface); + #ifdef __cplusplus } #endif + +#endif /*WIN_DDRAW_H*/ diff --git a/src/WIN/win_ddraw-fs.cc b/src/WIN/win_ddraw_fs.cc similarity index 97% rename from src/WIN/win_ddraw-fs.cc rename to src/WIN/win_ddraw_fs.cc index 42fd984ed..88649f7e9 100644 --- a/src/WIN/win_ddraw-fs.cc +++ b/src/WIN/win_ddraw_fs.cc @@ -2,16 +2,22 @@ see COPYING for more details */ #include -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP #include "../video/video.h" -#include "win_ddraw-fs.h" -#include "win_ddraw-screenshot.h" +#include "win_ddraw.h" #include "win_cgapal.h" +static LPDIRECTDRAW lpdd = NULL; +static LPDIRECTDRAW7 lpdd7 = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; +static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; +static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; +static DDSURFACEDESC2 ddsd; +static HWND ddraw_hwnd; +static int ddraw_w, ddraw_h; + + extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); @@ -22,19 +28,9 @@ extern "C" void ddraw_fs_close(void); extern "C" void video_blit_complete(void); -static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); -static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h); +static void ddraw_fs_blit_memtoscreen(int, int, int, int, int, int); +static void ddraw_fs_blit_memtoscreen_8(int, int, int, int); -static LPDIRECTDRAW lpdd = NULL; -static LPDIRECTDRAW7 lpdd7 = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_pri = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_back = NULL; -static LPDIRECTDRAWSURFACE7 lpdds_back2 = NULL; -static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; -static DDSURFACEDESC2 ddsd; - -static HWND ddraw_hwnd; -static int ddraw_w, ddraw_h; int ddraw_fs_init(HWND h) { diff --git a/src/WIN/win_ddraw-screenshot.cc b/src/WIN/win_ddraw_screenshot.cc similarity index 94% rename from src/WIN/win_ddraw-screenshot.cc rename to src/WIN/win_ddraw_screenshot.cc index bb3cb6660..717b94348 100644 --- a/src/WIN/win_ddraw-screenshot.cc +++ b/src/WIN/win_ddraw_screenshot.cc @@ -5,25 +5,20 @@ #include #define UNICODE #define BITMAP WINDOWS_BITMAP -#include +#include #undef BITMAP #include "../video/video.h" #include "win.h" -#include "win_ddraw-screenshot.h" +#include "win_ddraw.h" #include "win_language.h" -extern "C" void fatal(const char *format, ...); +HBITMAP hbitmap; +int xs, ys, ys2; + + extern "C" void pclog(const char *format, ...); -extern "C" void device_force_redraw(void); - -extern "C" void ddraw_init(HWND h); -extern "C" void ddraw_close(void); - -HBITMAP hbitmap; - -int xs, ys, ys2; void CopySurface(IDirectDrawSurface7 *pDDSurface) { @@ -58,6 +53,7 @@ void CopySurface(IDirectDrawSurface7 *pDDSurface) return ; } + void DoubleLines(uint8_t *dst, uint8_t *src) { int i = 0; diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index 457a38f75..c64dd3af7 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -1,19 +1,18 @@ /* Copyright holders: Sarah Walker see COPYING for more details */ -#define BITMAP WINDOWS_BITMAP -#include -#include -#undef BITMAP - #include "../ibm.h" #include "../config.h" #include "../device.h" #include "resource.h" +#define NO_UNICODE /*FIXME: not Unicode? */ #include "win.h" +#include + static device_t *config_device; + static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; diff --git a/src/config.c b/src/config.c index 04557b544..26e65cfe6 100644 --- a/src/config.c +++ b/src/config.c @@ -6,8 +6,6 @@ #include #include #include -#include - #include "cdrom.h" #include "config.h" #include "device.h" @@ -30,15 +28,8 @@ #include "sound/snd_opl.h" #include "sound/sound.h" #include "video/video.h" - -#ifndef __unix -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP #include "win.h" #include "win_language.h" -#endif wchar_t config_file_default[256]; diff --git a/src/net_ne2000.c b/src/net_ne2000.c index e0435367c..88b97cf40 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.5 2017/05/21 + * Version: @(#)net_ne2000.c 1.0.6 2017/05/23 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -37,8 +37,9 @@ #include "network.h" #include "net_ne2000.h" #include "bswap.h" + #ifdef WALTJE -# define ENABLE_NE2000_LOG 1 +# define ENABLE_NE2000_LOG 2 #endif @@ -202,7 +203,7 @@ typedef struct { uint8_t mem[NE2K_MEMSIZ]; /* on-chip packet memory */ int board; - int is_rtl8029as; + int is_pci; char name[32]; uint32_t base_address; int base_irq; @@ -210,11 +211,10 @@ typedef struct { bios_size, bios_mask; bar_t pci_bar[2]; - int disable_netbios; + uint8_t pci_regs[256]; int tx_timer_index; int tx_timer_active; uint8_t maclocal[6]; /* configured MAC (local) address */ - uint8_t pci_regs[256]; uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; } nic_t; @@ -234,10 +234,10 @@ nelog(int lvl, const char *fmt, ...) va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); + fflush(stdout); } #endif } -#define pclog nelog /* reset - restore state to power-up, cancelling all i/o */ @@ -247,7 +247,7 @@ nic_reset(void *priv, int reset) nic_t *dev = (nic_t *)priv; int i; - pclog(1, "%s: reset\n", dev->name); + nelog(1, "%s: reset\n", dev->name); /* Initialize the MAC address area by doubling the physical address */ dev->macaddr[0] = dev->physaddr[0]; @@ -264,9 +264,8 @@ nic_reset(void *priv, int reset) dev->macaddr[11] = dev->physaddr[5]; /* ne2k signature */ - for (i = 12; i < 32; i++) { + for (i=12; i<32; i++) dev->macaddr[i] = 0x57; - } /* Zero out registers and memory */ memset(&dev->CR, 0x00, sizeof(dev->CR) ); @@ -324,7 +323,7 @@ chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) uint32_t retval = 0; if ((len == 2) && (addr & 0x1)) { - pclog(1, "%s: unaligned chipmem word read\n", dev->name); + nelog(3, "%s: unaligned chipmem word read\n", dev->name); } /* ROM'd MAC address */ @@ -352,9 +351,9 @@ chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) return(retval); } - pclog(1, "%s: out-of-bounds chipmem read, %04X\n", dev->name, addr); + nelog(3, "%s: out-of-bounds chipmem read, %04X\n", dev->name, addr); - if (dev->is_rtl8029as) { + if (dev->is_pci) { return(0xff); } else { switch(len) { @@ -373,7 +372,7 @@ static void chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) { if ((len == 2) && (addr & 0x1)) { - pclog(1, "%s: unaligned chipmem word write\n", dev->name); + nelog(3, "%s: unaligned chipmem word write\n", dev->name); } if ((addr >= NE2K_MEMSTART) && (addr < NE2K_MEMEND)) { @@ -386,7 +385,7 @@ chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) dev->mem[addr-NE2K_MEMSTART+3] = val >> 24; } } else { - pclog(1, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); + nelog(3, "%s: out-of-bounds chipmem write, %04X\n", dev->name, addr); } } @@ -411,11 +410,11 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) and the source-address and length registers must have been initialised. */ if (len > dev->remote_bytes) { - pclog(1, "%s: DMA read underrun iolen=%d remote_bytes=%d\n", + nelog(3, "%s: DMA read underrun iolen=%d remote_bytes=%d\n", dev->name, len, dev->remote_bytes); } - pclog(2, "%s: DMA read: addr=%4x remote_bytes=%d\n", + nelog(3, "%s: DMA read: addr=%4x remote_bytes=%d\n", dev->name, dev->remote_dma,dev->remote_bytes); retval = chipmem_read(dev, dev->remote_dma, len); @@ -457,7 +456,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) break; default: - pclog(1, "%s: ASIC read invalid address %04x\n", + nelog(3, "%s: ASIC read invalid address %04x\n", dev->name, (unsigned)off); break; } @@ -469,17 +468,17 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) static void asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - pclog(2, "%s: asic write addr=0x%02x, value=0x%04x\n", + nelog(3, "%s: asic write addr=0x%02x, value=0x%04x\n", dev->name, (unsigned)off, (unsigned) val); switch(off) { case 0x00: /* Data register - see asic_read for a description */ if ((len > 1) && (dev->DCR.wdsize == 0)) { - pclog(2, "%s: DMA write length %d on byte mode operation\n", + nelog(3, "%s: DMA write length %d on byte mode operation\n", dev->name, len); break; } if (dev->remote_bytes == 0) { - pclog(2, "%s: DMA write, byte count 0\n", dev->name); + nelog(3, "%s: DMA write, byte count 0\n", dev->name); } chipmem_write(dev, dev->remote_dma, val, len); @@ -517,7 +516,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) break; default: /* this is invalid, but happens under win95 device detection */ - pclog(1, "%s: ASIC write invalid address %04x, ignoring\n", + nelog(3, "%s: ASIC write invalid address %04x, ignoring\n", dev->name, (unsigned)off); break; } @@ -533,7 +532,7 @@ page0_read(nic_t *dev, uint32_t off, unsigned int len) if (len > 1) { /* encountered with win98 hardware probe */ - pclog(1, "%s: bad length! Page0 read from register 0x%02x, len=%u\n", + nelog(3, "%s: bad length! Page0 read from register 0x%02x, len=%u\n", dev->name, off, len); return(retval); } @@ -567,7 +566,7 @@ page0_read(nic_t *dev, uint32_t off, unsigned int len) case 0x06: /* FIFO */ /* reading FIFO is only valid in loopback mode */ - pclog(1, "%s: reading FIFO not supported yet\n", dev->name); + nelog(3, "%s: reading FIFO not supported yet\n", dev->name); retval = dev->fifo; break; @@ -591,19 +590,19 @@ page0_read(nic_t *dev, uint32_t off, unsigned int len) break; case 0x0a: /* reserved / RTL8029ID0 */ - if (dev->is_rtl8029as) { + if (dev->is_pci) { retval = 0x50; } else { - pclog(1, "%s: reserved Page0 read - 0x0a\n", dev->name); + nelog(3, "%s: reserved Page0 read - 0x0a\n", dev->name); retval = 0xff; } break; case 0x0b: /* reserved / RTL8029ID1 */ - if (dev->is_rtl8029as) { + if (dev->is_pci) { retval = 0x43; } else { - pclog(1, "%s: reserved Page0 read - 0x0b\n", dev->name); + nelog(3, "%s: reserved Page0 read - 0x0b\n", dev->name); retval = 0xff; } break; @@ -632,12 +631,12 @@ page0_read(nic_t *dev, uint32_t off, unsigned int len) break; default: - pclog(1, "%s: Page0 register 0x%02x out of range\n", + nelog(3, "%s: Page0 register 0x%02x out of range\n", dev->name, off); break; } - pclog(2, "%s: Page0 read from register 0x%02x, value=0x%02x\n", + nelog(3, "%s: Page0 read from register 0x%02x, value=0x%02x\n", dev->name, off, retval); return(retval); @@ -659,7 +658,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) return; } - pclog(2, "%s: Page0 write to register 0x%02x, value=0x%02x\n", + nelog(3, "%s: Page0 write to register 0x%02x, value=0x%02x\n", dev->name, off, val); switch(off) { @@ -749,7 +748,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0c: /* RCR */ /* Check if the reserved bits are set */ if (val & 0xc0) { - pclog(1, "%s: RCR write, reserved bits set\n", + nelog(3, "%s: RCR write, reserved bits set\n", dev->name); } @@ -762,30 +761,30 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) dev->RCR.monitor = ((val & 0x20) == 0x20); /* Monitor bit is a little suspicious... */ - if (val & 0x20) pclog(1, "%s: RCR write, monitor bit set!\n", + if (val & 0x20) nelog(3, "%s: RCR write, monitor bit set!\n", dev->name); break; case 0x0d: /* TCR */ /* Check reserved bits */ - if (val & 0xe0) pclog(1, "%s: TCR write, reserved bits set\n", + if (val & 0xe0) nelog(3, "%s: TCR write, reserved bits set\n", dev->name); /* Test loop mode (not supported) */ if (val & 0x06) { dev->TCR.loop_cntl = (val & 0x6) >> 1; - pclog(1, "%s: TCR write, loop mode %d not supported\n", + nelog(3, "%s: TCR write, loop mode %d not supported\n", dev->name, dev->TCR.loop_cntl); } else { dev->TCR.loop_cntl = 0; } /* Inhibit-CRC not supported. */ - if (val & 0x01) pclog(1, + if (val & 0x01) nelog(3, "%s: TCR write, inhibit-CRC not supported\n",dev->name); /* Auto-transmit disable very suspicious */ - if (val & 0x08) pclog(1, + if (val & 0x08) nelog(3, "%s: TCR write, auto transmit disable not supported\n", dev->name); @@ -795,16 +794,16 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0e: /* DCR */ /* the loopback mode is not suppported yet */ - if (! (val & 0x08)) pclog(1, + if (! (val & 0x08)) nelog(3, "%s: DCR write, loopback mode selected\n", dev->name); /* It is questionable to set longaddr and auto_rx, since * they are not supported on the NE2000. Print a warning * and continue. */ if (val & 0x04) - pclog(1, "%s: DCR write - LAS set ???\n", dev->name); + nelog(3, "%s: DCR write - LAS set ???\n", dev->name); if (val & 0x10) - pclog(1, "%s: DCR write - AR set ???\n", dev->name); + nelog(3, "%s: DCR write - AR set ???\n", dev->name); /* Set other values. */ dev->DCR.wdsize = ((val & 0x01) == 0x01); @@ -818,7 +817,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0f: /* IMR */ /* Check for reserved bit */ if (val & 0x80) - pclog(1, "%s: IMR write, reserved bit set\n",dev->name); + nelog(3, "%s: IMR write, reserved bit set\n",dev->name); /* Set other values */ dev->IMR.rx_inte = ((val & 0x01) == 0x01); @@ -843,7 +842,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) break; default: - pclog(1, "%s: Page0 write, bad register 0x%02x\n", + nelog(3, "%s: Page0 write, bad register 0x%02x\n", dev->name, off); break; } @@ -855,7 +854,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) static uint32_t page1_read(nic_t *dev, uint32_t off, unsigned int len) { - pclog(2, "%s: Page1 read from register 0x%02x, len=%u\n", + nelog(3, "%s: Page1 read from register 0x%02x, len=%u\n", dev->name, off, len); switch(off) { @@ -868,7 +867,7 @@ page1_read(nic_t *dev, uint32_t off, unsigned int len) return(dev->physaddr[off - 1]); case 0x07: /* CURR */ - pclog(2, "%s: returning current page: 0x%02x\n", + nelog(3, "%s: returning current page: 0x%02x\n", dev->name, (dev->curr_page)); return(dev->curr_page); @@ -883,7 +882,7 @@ page1_read(nic_t *dev, uint32_t off, unsigned int len) return(dev->mchash[off - 8]); default: - pclog(1, "%s: Page1 read register 0x%02x out of range\n", + nelog(3, "%s: Page1 read register 0x%02x out of range\n", dev->name, off); return(0); } @@ -893,7 +892,7 @@ page1_read(nic_t *dev, uint32_t off, unsigned int len) static void page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - pclog(2, "%s: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", + nelog(3, "%s: Page1 write to register 0x%02x, len=%u, value=0x%04x\n", dev->name, off, len, val); switch(off) { @@ -904,7 +903,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x05: case 0x06: dev->physaddr[off - 1] = val; - if (off == 6) pclog(1, + if (off == 6) nelog(3, "%s: physical address set to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->physaddr[0], dev->physaddr[1], @@ -928,7 +927,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) break; default: - pclog(1, "%s: Page1 write register 0x%02x out of range\n", + nelog(3, "%s: Page1 write register 0x%02x out of range\n", dev->name, off); break; } @@ -940,7 +939,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) static uint32_t page2_read(nic_t *dev, uint32_t off, unsigned int len) { - pclog(2, "%s: Page2 read from register 0x%02x, len=%u\n", + nelog(3, "%s: Page2 read from register 0x%02x, len=%u\n", dev->name, off, len); switch(off) { @@ -969,7 +968,7 @@ page2_read(nic_t *dev, uint32_t off, unsigned int len) case 0x09: case 0x0a: case 0x0b: - pclog(1, "%s: reserved Page2 read - register 0x%02x\n", + nelog(3, "%s: reserved Page2 read - register 0x%02x\n", dev->name, off); return(0xff); @@ -1005,7 +1004,7 @@ page2_read(nic_t *dev, uint32_t off, unsigned int len) (dev->IMR.rx_inte)); default: - pclog(1, "%s: Page2 register 0x%02x out of range\n", + nelog(3, "%s: Page2 register 0x%02x out of range\n", dev->name, off); break; } @@ -1020,7 +1019,7 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) /* Maybe all writes here should be BX_PANIC()'d, since they affect internal operation, but let them through for now and print a warning. */ - pclog(2, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", + nelog(3, "%s: Page2 write to register 0x%02x, len=%u, value=0x%04x\n", dev->name, off, len, val); switch(off) { case 0x01: /* CLDA0 */ @@ -1040,7 +1039,7 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) break; case 0x04: - pclog(1, "page 2 write to reserved register 0x04\n"); + nelog(3, "page 2 write to reserved register 0x04\n"); break; case 0x05: /* Local Next-packet pointer */ @@ -1067,12 +1066,12 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) case 0x0d: case 0x0e: case 0x0f: - pclog(1, "%s: Page2 write to reserved register 0x%02x\n", + nelog(3, "%s: Page2 write to reserved register 0x%02x\n", dev->name, off); break; default: - pclog(1, "%s: Page2 write, illegal register 0x%02x\n", + nelog(3, "%s: Page2 write, illegal register 0x%02x\n", dev->name, off); break; } @@ -1083,7 +1082,7 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) static uint32_t page3_read(nic_t *dev, uint32_t off, unsigned int len) { - if (dev->is_rtl8029as) switch(off) { + if (dev->is_pci) switch(off) { case 0x3: /* CONFIG0 */ return(0x00); @@ -1097,7 +1096,7 @@ page3_read(nic_t *dev, uint32_t off, unsigned int len) break; } - pclog(1, "%s: Page3 read register 0x%02x attempted\n", dev->name, off); + nelog(3, "%s: Page3 read register 0x%02x attempted\n", dev->name, off); return(0x00); } @@ -1105,7 +1104,7 @@ page3_read(nic_t *dev, uint32_t off, unsigned int len) static void page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - pclog(1, "%s: Page3 write register 0x%02x attempted\n", dev->name, off); + nelog(3, "%s: Page3 write register 0x%02x attempted\n", dev->name, off); } @@ -1121,7 +1120,7 @@ read_cr(nic_t *dev) (dev->CR.tx_packet << 2) | (dev->CR.start << 1) | (dev->CR.stop)); - pclog(2, "%s: read CR returns 0x%02x\n", dev->name, retval); + nelog(3, "%s: read CR returns 0x%02x\n", dev->name, retval); return(retval); } @@ -1130,11 +1129,11 @@ read_cr(nic_t *dev) static void write_cr(nic_t *dev, uint32_t val) { - pclog(2, "%s: wrote 0x%02x to CR\n", dev->name, val); + nelog(3, "%s: wrote 0x%02x to CR\n", dev->name, val); /* Validate remote-DMA */ if ((val & 0x38) == 0x00) { - pclog(2, "%s: CR write - invalid rDMA value 0\n", dev->name); + nelog(3, "%s: CR write - invalid rDMA value 0\n", dev->name); val |= 0x20; /* dma_cmd == 4 is a safe default */ } @@ -1150,9 +1149,8 @@ write_cr(nic_t *dev, uint32_t val) /* If start command issued, the RST bit in the ISR */ /* must be cleared */ - if ((val & 0x02) && !dev->CR.start) { + if ((val & 0x02) && !dev->CR.start) dev->ISR.reset = 0; - } dev->CR.start = ((val & 0x02) == 0x02); dev->CR.pgsel = (val & 0xc0) >> 6; @@ -1162,14 +1160,14 @@ write_cr(nic_t *dev, uint32_t val) /* Set up DMA read from receive ring */ dev->remote_start = dev->remote_dma = dev->bound_ptr * 256; dev->remote_bytes = (uint16_t) chipmem_read(dev, dev->bound_ptr * 256 + 2, 2); - pclog(2, "%s: sending buffer #x%x length %d\n", + nelog(3, "%s: sending buffer #x%x length %d\n", dev->name, dev->remote_start, dev->remote_bytes); } /* Check for start-tx */ if ((val & 0x04) && dev->TCR.loop_cntl) { if (dev->TCR.loop_cntl != 1) { - pclog(1, "%s: loop mode %d not supported\n", + nelog(3, "%s: loop mode %d not supported\n", dev->name, dev->TCR.loop_cntl); } else { nic_rx(dev, @@ -1177,15 +1175,15 @@ write_cr(nic_t *dev, uint32_t val) dev->tx_bytes); } } else if (val & 0x04) { - if (dev->CR.stop || (!dev->CR.start && !dev->is_rtl8029as)) { + if (dev->CR.stop || (!dev->CR.start && !dev->is_pci)) { if (dev->tx_bytes == 0) /* njh@bandsman.co.uk */ { return; /* Solaris9 probe */ } - pclog(1, "%s: CR write - tx start, dev in reset\n", dev->name); + nelog(3, "%s: CR write - tx start, dev in reset\n", dev->name); } if (dev->tx_bytes == 0) - pclog(1, "%s: CR write - tx start, tx bytes == 0\n", dev->name); + nelog(3, "%s: CR write - tx start, tx bytes == 0\n", dev->name); /* Send the packet to the system driver */ dev->CR.tx_packet = 1; @@ -1194,7 +1192,7 @@ write_cr(nic_t *dev, uint32_t val) /* some more debug */ if (dev->tx_timer_active) - pclog(1, "%s: CR write, tx timer still active\n", dev->name); + nelog(3, "%s: CR write, tx timer still active\n", dev->name); nic_tx(dev, val); } @@ -1206,9 +1204,8 @@ write_cr(nic_t *dev, uint32_t val) dev->ISR.rdma_done = 1; if (dev->IMR.rdma_inte) { picint(1 << dev->base_irq); - if (! dev->is_rtl8029as) { + if (! dev->is_pci) picintc(1 << dev->base_irq); - } } } } @@ -1220,7 +1217,7 @@ nic_read(nic_t *dev, uint32_t addr, unsigned len) uint32_t retval = 0; int off = addr - dev->base_address; - pclog(2, "%s: read addr %x, len %d\n", dev->name, addr, len); + nelog(3, "%s: read addr %x, len %d\n", dev->name, addr, len); if (off >= 0x10) { retval = asic_read(dev, off - 0x10, len); @@ -1244,7 +1241,7 @@ nic_read(nic_t *dev, uint32_t addr, unsigned len) break; default: - pclog(1, "%s: unknown value of pgsel in read - %d\n", + nelog(3, "%s: unknown value of pgsel in read - %d\n", dev->name, dev->CR.pgsel); break; } @@ -1284,7 +1281,7 @@ nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) { int off = addr - dev->base_address; - pclog(2, "%s: write addr %x, value %x len %d\n", dev->name, addr, val, len); + nelog(3, "%s: write addr %x, value %x len %d\n", dev->name, addr, val, len); /* The high 16 bytes of i/o space are for the ne2000 asic - the low 16 bytes are for the DS8390, with the current @@ -1312,7 +1309,7 @@ nic_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) break; default: - pclog(1, "%s: unknown value of pgsel in write - %d\n", + nelog(3, "%s: unknown value of pgsel in write - %d\n", dev->name, dev->CR.pgsel); break; } @@ -1348,7 +1345,7 @@ nic_writel(uint16_t addr, uint32_t val, void *priv) static void nic_ioset(nic_t *dev, uint16_t addr) { - if (dev->is_rtl8029as) { + if (dev->is_pci) { io_sethandler(addr, 16, nic_readb, nic_readw, nic_readl, nic_writeb, nic_writew, nic_writel, dev); @@ -1375,7 +1372,7 @@ nic_ioset(nic_t *dev, uint16_t addr) static void nic_ioremove(nic_t *dev, int16_t addr) { - if (dev->is_rtl8029as) { + if (dev->is_pci) { io_removehandler(addr, 16, nic_readb, nic_readw, nic_readl, nic_writeb, nic_writew, nic_writel, dev); @@ -1407,13 +1404,14 @@ nic_update_bios(nic_t *dev) reg_bios_enable = 1; /* PCI BIOS stuff, just enable_disable. */ - if (!dev->disable_netbios && reg_bios_enable) { + if ((dev->bios_addr > 0) && reg_bios_enable) { mem_mapping_enable(&dev->bios_rom.mapping); - mem_mapping_set_addr(&dev->bios_rom.mapping, dev->bios_addr, 0x10000); - pclog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); + mem_mapping_set_addr(&dev->bios_rom.mapping, + dev->bios_addr, dev->bios_size); + nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); } else { mem_mapping_disable(&dev->bios_rom.mapping); - if (dev->is_rtl8029as) + if (dev->is_pci) dev->pci_bar[1].addr = 0; } } @@ -1517,7 +1515,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) dev->base_address = dev->pci_bar[0].addr & 0xff00; /* Log the new base. */ - pclog(1, "%s: PCI: new I/O base is %04X\n", + nelog(1, "%s: PCI: new I/O base is %04X\n", dev->name, dev->base_address); /* We're done, so get out of the here. */ if (val & PCI_COMMAND_IO) @@ -1527,8 +1525,8 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) case 0x30: case 0x31: case 0x32: case 0x33: dev->pci_bar[1].addr_regs[addr & 3] = val; dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; - dev->bios_addr = dev->pci_bar[1].addr & 0xffffe000; dev->pci_bar[1].addr &= 0xffffe000; + dev->bios_addr = dev->pci_bar[1].addr; dev->pci_bar[1].addr |= 0x1801; nic_update_bios(dev); return; @@ -1540,7 +1538,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3C: dev->pci_regs[addr] = val; if (val != 0xFF) { - pclog(1, "%s: IRQ now: %i\n", dev->name, val); + nelog(1, "%s: IRQ now: %i\n", dev->name, val); dev->base_irq = irq; } return; @@ -1607,28 +1605,25 @@ nic_rx(void *priv, uint8_t *buf, int io_len) { static uint8_t bcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; nic_t *dev = (nic_t *)priv; - int pages; - int avail; - int idx; - int nextpage; uint8_t pkthdr[4]; - uint8_t *pktbuf = (uint8_t *) buf; uint8_t *startptr; - uint32_t mac_cmp32[2]; - uint16_t mac_cmp16[2]; + int pages, avail; + int idx, nextpage; + int endbytes; if (io_len != 60) - pclog(2, "%s: rx_frame with length %d\n", dev->name, io_len); + nelog(2, "%s: rx_frame with length %d\n", dev->name, io_len); - if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; + if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; /* Add the pkt header + CRC to the length, and work out how many 256-byte pages the frame would occupy */ - pages = (io_len + 4 + 4 + 255)/256; + pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256; if (dev->curr_page < dev->bound_ptr) { avail = dev->bound_ptr - dev->curr_page; } else { - avail = (dev->page_stop - dev->page_start) - (dev->curr_page - dev->bound_ptr); + avail = (dev->page_stop - dev->page_start) - + (dev->curr_page - dev->bound_ptr); } /* Avoid getting into a buffer overflow condition by not attempting @@ -1639,90 +1634,91 @@ nic_rx(void *priv, uint8_t *buf, int io_len) || (avail == pages) #endif ) { - pclog(1, "%s: no space\n", dev->name); + nelog(1, "%s: no space\n", dev->name); return; } if ((io_len < 40/*60*/) && !dev->RCR.runts_ok) { - pclog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); + nelog(1, "%s: rejected small packet, length %d\n", dev->name, io_len); return; } - /* some computers don't care... */ - if (io_len < 60) { - io_len=60; - } + /* Some computers don't care... */ + if (io_len < 60) + io_len = 60; - /* Do address filtering if not in promiscuous mode */ + nelog(2, "%s: rx_frame %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", + dev->name, + buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], + buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], + io_len); + + /* Do address filtering if not in promiscuous mode. */ if (! dev->RCR.promisc) { - /* Received. */ - mac_cmp32[0] = *(uint32_t *) (buf); - mac_cmp16[0] = *(uint16_t *) (((uint8_t *) buf) + 4); - - /* Local. */ - mac_cmp32[1] = *(uint32_t *) (bcast_addr); - mac_cmp16[1] = *(uint16_t *) (bcast_addr+4); - if ((mac_cmp32[0] == mac_cmp32[1]) && (mac_cmp16[0] == mac_cmp16[1])) { + /* If this is a broadcast frame.. */ + if (! memcmp(buf, bcast_addr, 6)) { + /* Broadcast not enabled, we're done. */ if (! dev->RCR.broadcast) { + nelog(2, "%s: rx_frame BC disabled\n", dev->name); return; } - } else if (pktbuf[0] & 0x01) { - if (! dev->RCR.multicast) { - return; - } - idx = mcast_index(buf); - if (!(dev->mchash[idx >> 3] & (1 << (idx & 0x7)))) { - return; - } - } else if (0 != memcmp(buf, dev->physaddr, 6)) { - return; } - } else { - pclog(2, "%s: rx_frame promiscuous receive\n", dev->name); - } - pclog(2, "%s: rx_frame %d to %x:%x:%x:%x:%x:%x from %x:%x:%x:%x:%x:%x\n", - dev->name, io_len, - pktbuf[0], pktbuf[1], pktbuf[2], pktbuf[3], pktbuf[4], pktbuf[5], - pktbuf[6], pktbuf[7], pktbuf[8], pktbuf[9], pktbuf[10], pktbuf[11]); + /* If this is a multicast frame.. */ + else if (buf[0] & 0x01) { + /* Multicast not enabled, we're done. */ + if (! dev->RCR.multicast) { +#if 1 + nelog(2, "%s: rx_frame MC disabled\n", dev->name); +#endif + return; + } + + /* Are we listening to this multicast address? */ + idx = mcast_index(buf); + if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) { + nelog(2, "%s: rx_frame MC not listed\n", dev->name); + return; + } + } + + /* Unicast, must be for us.. */ + else if (memcmp(buf, dev->physaddr, 6)) return; + } else { + nelog(2, "%s: rx_frame promiscuous receive\n", dev->name); + } nextpage = dev->curr_page + pages; - if (nextpage >= dev->page_stop) { - nextpage -= dev->page_stop - dev->page_start; - } + if (nextpage >= dev->page_stop) + nextpage -= (dev->page_stop - dev->page_start); - /* Setup packet header */ - pkthdr[0] = 0; /* rx status - old behavior - pkthdr[0] = 1; /* Probably better to set it all the time - rather than set it to 0, which is clearly wrong. */ - if (pktbuf[0] & 0x01) { - pkthdr[0] |= 0x20; /* rx status += multicast packet */ - } + /* Set up packet header. */ + pkthdr[0] = 0x01; /* RXOK - packet is OK */ + if (buf[0] & 0x01) + pkthdr[0] |= 0x20; /* MULTICAST packet */ pkthdr[1] = nextpage; /* ptr to next packet */ - pkthdr[2] = (io_len + 4) & 0xff; /* length-low */ - pkthdr[3] = (io_len + 4) >> 8; /* length-hi */ + pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */ + pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */ + nelog(2, "%s: rx_frame pkthdr [%02x %02x %02x %02x]\n", + dev->name, pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]); - /* copy into buffer, update curpage, and signal interrupt if config'd */ - startptr = & dev->mem[dev->curr_page * 256 - NE2K_MEMSTART]; + /* Copy into buffer, update curpage, and signal interrupt if config'd */ + startptr = &dev->mem[(dev->curr_page * 256) - NE2K_MEMSTART]; + memcpy(startptr, pkthdr, sizeof(pkthdr)); if ((nextpage > dev->curr_page) || ((dev->curr_page + pages) == dev->page_stop)) { - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, io_len); - dev->curr_page = nextpage; + memcpy(startptr+sizeof(pkthdr), buf, io_len); } else { - int endbytes = (dev->page_stop - dev->curr_page) * 256; - *(uint32_t *) startptr = *(uint32_t *) pkthdr; - memcpy(startptr + 4, buf, endbytes - 4); - startptr = & dev->mem[dev->page_start * 256 - NE2K_MEMSTART]; - memcpy(startptr, (void *)(pktbuf + endbytes - 4), io_len - endbytes + 8); - dev->curr_page = nextpage; + endbytes = (dev->page_stop - dev->curr_page) * 256; + memcpy(startptr+sizeof(pkthdr), buf, endbytes-sizeof(pkthdr)); + startptr = &dev->mem[(dev->page_start * 256) - NE2K_MEMSTART]; + memcpy(startptr, buf+endbytes-sizeof(pkthdr), io_len-endbytes+8); } + dev->curr_page = nextpage; dev->RSR.rx_ok = 1; - if (pktbuf[0] & 0x80) { + if (buf[0] & 0x80) dev->RSR.rx_mbit = 1; - } - dev->ISR.pkt_rx = 1; if (dev->IMR.rx_inte) @@ -1736,8 +1732,8 @@ nic_rom_init(nic_t *dev, wchar_t *s) FILE *f = romfopen(s, L"rb"); uint32_t temp; - if (f != NULL) { - dev->disable_netbios = 1; + if (f == NULL) { + dev->bios_addr = 0x00000; nic_update_bios(dev); return; } @@ -1754,14 +1750,11 @@ nic_rom_init(nic_t *dev, wchar_t *s) dev->bios_mask = (dev->bios_size >> 8) & 0xff; dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; -#if 1 - /* Shouldn't we use the configured address?? --FvK */ - rom_init(&dev->bios_rom, s, 0xd0000, - dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); -#else rom_init(&dev->bios_rom, s, dev->bios_addr, dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); -#endif + + nelog(1, "%s: BIOS enabled at %06lX (size %ld)\n", + dev->name, dev->bios_addr, dev->bios_size); } @@ -1788,37 +1781,41 @@ nic_init(int board) dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->board = board; - dev->is_rtl8029as = (PCI && (board == NE2K_RTL8029AS)) ? 1 : 0; - if (board == NE2K_RTL8029AS) { - strcpy(dev->name, "RTL8029AS"); - } else if (board == NE2K_NE1000) { - strcpy(dev->name, "NE1000"); - } else { - strcpy(dev->name, "NE2000"); + switch(dev->board) { + case NE2K_NE1000: + strcpy(dev->name, "NE1000"); + dev->maclocal[0] = 0x00; /* 00:00:D8 (NE1000 ISA OID) */ + dev->maclocal[1] = 0x00; + dev->maclocal[2] = 0xD8; + break; + + case NE2K_NE2000: + strcpy(dev->name, "NE2000"); + dev->maclocal[0] = 0x00; /* 00:A0:0C (NE2000 compatible OID) */ + dev->maclocal[1] = 0xA0; + dev->maclocal[2] = 0x0C; + break; + + case NE2K_RTL8029AS: + dev->is_pci = (PCI) ? 1 : 0; + strcpy(dev->name, "RTL8029AS"); + dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI OID) */ + dev->maclocal[1] = 0x20; + dev->maclocal[2] = 0x18; + break; } dev->base_irq = device_get_config_int("irq"); - dev->disable_netbios = device_get_config_int("disable_netbios"); - if (dev->is_rtl8029as) { + if (dev->is_pci) dev->base_address = 0x340; - } else { + else dev->base_address = device_get_config_int("addr"); - } + dev->bios_addr = device_get_config_int("bios_addr"); /* See if we have a local MAC address configured. */ mac = device_get_config_int_ex("mac", -1); - /* Set up our MAC address. */ -#if 1 - if (dev->is_rtl8029as) { - dev->maclocal[0] = 0xDE /* 0x00 */; /* 00:20:18 (RTL 8029AS PCI vendor prefix). */ - dev->maclocal[1] = 0x20; - dev->maclocal[2] = 0x18; - } else { - dev->maclocal[0] = 0xDE /* 0x00 */; /* 00:00:D8 (NE2000 ISA vendor prefix). */ - dev->maclocal[1] = 0x00; - dev->maclocal[2] = 0xD8; - } + /* Set up our BIA. */ if (mac & 0xff000000) { /* Generating new MAC. */ dev->maclocal[3] = disc_random_generate(); @@ -1828,33 +1825,20 @@ nic_init(int board) } else { dev->maclocal[3] = (mac>>16) & 0xff; dev->maclocal[4] = (mac>>8) & 0xff; -#if 1 dev->maclocal[5] = (mac & 0xfe); -#else - dev->maclocal[5] = (mac & 0xff) | 1; -#endif } -#else - dev->maclocal[0] = 0xac; - dev->maclocal[1] = 0xde; - dev->maclocal[2] = 0x48; - dev->maclocal[3] = 0x88; - dev->maclocal[4] = 0xbb; - dev->maclocal[5] = 0xaa; -#endif memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); - pclog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x BIOS=%d\n", + nelog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->base_address, dev->base_irq, dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], - dev->physaddr[3], dev->physaddr[4], dev->physaddr[5], - !dev->disable_netbios); + dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]); if (network_attach(dev, dev->physaddr, nic_rx) < 0) { #if 0 msgbox_error_wstr(ghwnd, L"Unable to init platform network"); #endif - pclog(1, "%s: unable to init platform network type %d\n", + nelog(1, "%s: unable to init platform network type %d\n", dev->name, network_type); #if 0 /* @@ -1868,18 +1852,18 @@ nic_init(int board) #endif } - if (dev->is_rtl8029as) + if (dev->is_pci) pci_add(nic_pci_read, nic_pci_write, dev); nic_ioset(dev, dev->base_address); - if (! dev->disable_netbios) { - nic_rom_init(dev, dev->is_rtl8029as ? L"roms/rtl8029as.rom" + if (dev->bios_addr > 0) { + nic_rom_init(dev, dev->is_pci ? L"roms/rtl8029as.rom" : L"roms/ne2000.rom"); - if (dev->is_rtl8029as) + if (dev->is_pci) mem_mapping_disable(&dev->bios_rom.mapping); } - if (dev->is_rtl8029as) { + if (dev->is_pci) { dev->pci_regs[0x04] = 1; dev->pci_regs[0x05] = 0; dev->pci_regs[0x07] = 2; @@ -1888,19 +1872,18 @@ nic_init(int board) dev->pci_regs[0x0B] = 2; dev->pci_bar[0].addr_regs[0] = 1; - - if (! dev->disable_netbios) { - dev->pci_bar[1].addr = 0; - dev->bios_addr = 0; - } else { + + if (dev->bios_addr > 0) { + /* What is it.. F800 or D000 (bios_addr) ? */ dev->pci_bar[1].addr = 0x000F8000; dev->pci_bar[1].addr_regs[1] = dev->bios_mask; dev->pci_bar[1].addr |= 0x1801; - dev->bios_addr = 0xD0000; + } else { + dev->pci_bar[1].addr = 0; } dev->pci_regs[0x3C] = dev->base_irq; - pclog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]); + nelog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]); dev->pci_regs[0x3D] = 1; memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); @@ -1918,8 +1901,8 @@ nic_init(int board) nic_reset(dev, 0); - pclog(1, "%s: %s init 0x%X %d\n", dev->name, - dev->is_rtl8029as?"PCI":"ISA", dev->base_address, dev->base_irq); + nelog(1, "%s: %s init 0x%X %d\n", dev->name, + dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); return(dev); } @@ -1937,7 +1920,7 @@ nic_close(void *priv) free(dev); - pclog(1, "%s: closed\n", dev->name); + nelog(1, "%s: closed\n", dev->name); } @@ -2011,7 +1994,21 @@ static device_config_t ne1000_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + { + { + "Disabled", 0x00000 + }, + { + "D000", 0xD0000 + }, + { + "C000", 0xC0000 + }, + { + "" + } + }, }, { "", "", -1 @@ -2073,7 +2070,21 @@ static device_config_t ne2000_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + { + { + "Disabled", 0x00000 + }, + { + "D000", 0xD0000 + }, + { + "C000", 0xC0000 + }, + { + "" + } + }, }, { "", "", -1 @@ -2109,7 +2120,21 @@ static device_config_t rtl8029as_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "disable_netbios", "Disable network BIOS", CONFIG_BINARY, "", 0 + "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + { + { + "Disabled", 0x00000 + }, + { + "D000", 0xD0000 + }, + { + "C000", 0xC0000 + }, + { + "" + } + }, }, { "", "", -1 diff --git a/src/net_pcap.c b/src/net_pcap.c index 448738715..a1b2292b0 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.3 2017/05/21 + * Version: @(#)net_pcap.c 1.0.4 2017/05/23 * * Author: Fred N. van Kempen, */ @@ -180,7 +180,7 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) } /* Create a MAC address based packet filter. */ - pclog(" Installing packet filter for MAC=%02x:%02x:%02x:%02x:%02x\n", + pclog(" Installing packet filter for MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); sprintf(filter_exp, "( ((ether dst ff:ff:ff:ff:ff:ff) or (ether dst %02x:%02x:%02x:%02x:%02x:%02x)) and not (ether src %02x:%02x:%02x:%02x:%02x:%02x) )", diff --git a/src/network.c b/src/network.c index 90bd69aac..c4cd9c547 100644 --- a/src/network.c +++ b/src/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.5 2017/05/21 + * Version: @(#)network.c 1.0.6 2017/05/22 * * Authors: Kotori, * Fred N. van Kempen, @@ -25,14 +25,8 @@ #include "device.h" #include "network.h" #include "net_ne2000.h" -#ifndef unix -# define UNICODE -# define BITMAP WINDOWS_BITMAP -# include -# undef BITMAP -# include "win.h" -# include "win_language.h" -#endif +#include "win.h" +#include "win_language.h" static netcard_t net_cards[] = { diff --git a/src/pc.c b/src/pc.c index 7e05e9260..66e0bb4ef 100644 --- a/src/pc.c +++ b/src/pc.c @@ -57,18 +57,10 @@ #include "video/video.h" #include "video/vid_voodoo.h" #include "amstrad.h" -#ifdef WALTJE -# define UNICODE -# include "plat_dir.h" -#endif - -#ifndef __unix -#define UNICODE -#define BITMAP WINDOWS_BITMAP -#include -#undef BITMAP #include "win.h" #include "win_language.h" +#ifdef WALTJE +# include "plat_dir.h" #endif From a6ae4da9ae8bed5d6744378f93847cae2cdd5708 Mon Sep 17 00:00:00 2001 From: waltje Date: Wed, 24 May 2017 00:35:51 -0400 Subject: [PATCH 247/392] Plus the updated Makefile.mingw... --- src/Makefile.mingw | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 4ba3565e2..ed0cb81f8 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.16 2017/05/22 +# Version: @(#)Makefile.mingw 1.0.16 2017/05/23 # # Authors: Kotori, # Fred N. van Kempen, @@ -31,7 +31,7 @@ endif # Add feature selections here. # -DBUGGER adds the ISA BusBugger emulation. ifndef EXTRAS -EXTRAS = lala +EXTRAS = endif # Do we want a debugging build? @@ -215,7 +215,7 @@ LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ # Build rules. %.o: %.c @echo $< - $(CC) $(CFLAGS) -c $< + @$(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< From 94680da416f1f76f3682d38da1f4fa3668bcd7fa Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 26 May 2017 13:12:31 -0400 Subject: [PATCH 248/392] Updated NE2000 driver (cleaned up, especially PCI), new location for ROM files! Cross-tested with SLiRP and PCap for NE2000 and RTL8029 on DOS, NT 3.51.5, W2K.4, Debian 3.1 and 7.6. NT and Deb 3.1 don't like the RTL, and never will. --- src/WIN/win_dynld.c | 6 +- src/net_ne2000.c | 575 ++++++++++++++++++++++++++------------------ 2 files changed, 349 insertions(+), 232 deletions(-) diff --git a/src/WIN/win_dynld.c b/src/WIN/win_dynld.c index 229febc3a..9f7d4d3c5 100644 --- a/src/WIN/win_dynld.c +++ b/src/WIN/win_dynld.c @@ -8,7 +8,7 @@ * * Try to load a support DLL. * - * Version: @(#)win_dynld.c 1.0.1 2017/05/21 + * Version: @(#)win_dynld.c 1.0.2 2017/05/24 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen @@ -26,7 +26,7 @@ void * dynld_module(const char *name, dllimp_t *table) { - HANDLE h; + HMODULE h; dllimp_t *imp; void *func; char **foo; @@ -60,5 +60,5 @@ void dynld_close(void *handle) { if (handle != NULL) - CloseHandle((HANDLE *)handle); + FreeLibrary((HMODULE)handle); } diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 88b97cf40..47b5d52db 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.6 2017/05/23 + * Version: @(#)net_ne2000.c 1.0.7 2017/05/25 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -38,11 +38,23 @@ #include "net_ne2000.h" #include "bswap.h" + #ifdef WALTJE # define ENABLE_NE2000_LOG 2 #endif +/* ROM BIOS file paths. */ +#define ROM_PATH_NE1000 L"roms/network/ne1000/ne1000.rom" +#define ROM_PATH_NE2000 L"roms/network/ne2000/ne2000.rom" +#define ROM_PATH_RTL8029 L"roms/network/rtl8029as/rtl8029as.rom" + +/* PCI info. */ +#define PCI_VENDID 0x10ec /* Realtek, Inc */ +#define PCI_DEVID 0x8029 /* RTL8029AS */ +#define PCI_REGSIZE 256 /* size of PCI space */ + + /* For PCI. */ typedef union { uint32_t addr; @@ -211,7 +223,7 @@ typedef struct { bios_size, bios_mask; bar_t pci_bar[2]; - uint8_t pci_regs[256]; + uint8_t pci_regs[PCI_REGSIZE]; int tx_timer_index; int tx_timer_active; uint8_t maclocal[6]; /* configured MAC (local) address */ @@ -242,7 +254,7 @@ nelog(int lvl, const char *fmt, ...) /* reset - restore state to power-up, cancelling all i/o */ static void -nic_reset(void *priv, int reset) +nic_reset(void *priv) { nic_t *dev = (nic_t *)priv; int i; @@ -310,13 +322,25 @@ nic_reset(void *priv, int reset) } -/* chipmem_read/chipmem_write - access the 64K private RAM. - The ne2000 memory is accessed through the data port of - the asic (offset 0) after setting up a remote-DMA transfer. - Both byte and word accesses are allowed. - The first 16 bytes contains the MAC address at even locations, - and there is 16K of buffer memory starting at 16K -*/ +static void +nic_soft_reset(void *priv) +{ + nic_t *dev = (nic_t *)priv; + + memset(&(dev->ISR), 0x00, sizeof(dev->ISR)); + dev->ISR.reset = 1; +} + + +/* + * Access the 32K private RAM. + * + * The NE2000 memory is accessed through the data port of the + * ASIC (offset 0) after setting up a remote-DMA transfer. + * Both byte and word accesses are allowed. + * The first 16 bytes contains the MAC address at even locations, + * and there is 16K of buffer memory starting at 16K. + */ static uint32_t chipmem_read(nic_t *dev, uint32_t addr, unsigned int len) { @@ -390,15 +414,19 @@ chipmem_write(nic_t *dev, uint32_t addr, uint32_t val, unsigned len) } -/* asic_read/asic_write - This is the high 16 bytes of i/o space - (the lower 16 bytes is for the DS8390). Only two locations - are used: offset 0, which is used for data transfer, and - offset 0xf, which is used to reset the device. - The data transfer port is used to as 'external' DMA to the - DS8390. The chip has to have the DMA registers set up, and - after that, insw/outsw instructions can be used to move - the appropriate number of bytes to/from the device. -*/ +/* + * Access the ASIC I/O space. + * + * This is the high 16 bytes of i/o space (the lower 16 bytes + * is for the DS8390). Only two locations are used: offset 0, + * which is used for data transfer, and offset 0x0f, which is + * used to reset the device. + * + * The data transfer port is used to as 'external' DMA to the + * DS8390. The chip has to have the DMA registers set up, and + * after that, insw/outsw instructions can be used to move + * the appropriate number of bytes to/from the device. + */ static uint32_t asic_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -452,7 +480,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) break; case 0x0f: /* Reset register */ - nic_reset(dev, 1); + nic_soft_reset(dev); break; default: @@ -468,7 +496,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) static void asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) { - nelog(3, "%s: asic write addr=0x%02x, value=0x%04x\n", + nelog(3, "%s: ASIC write addr=0x%02x, value=0x%04x\n", dev->name, (unsigned)off, (unsigned) val); switch(off) { case 0x00: /* Data register - see asic_read for a description */ @@ -523,8 +551,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page0_read/page0_write - These routines handle reads/writes to - the 'zeroth' page of the DS8390 register file */ +/* Handle reads/writes to the 'zeroth' page of the DS8390 register file. */ static uint32_t page0_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -849,8 +876,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page1_read/page1_write - These routines handle reads/writes to - the first page of the DS8390 register file */ +/* Handle reads/writes to the first page of the DS8390 register file. */ static uint32_t page1_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -934,8 +960,7 @@ page1_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page2_read/page2_write - These routines handle reads/writes to - the second page of the DS8390 register file */ +/* Handle reads/writes to the second page of the DS8390 register file. */ static uint32_t page2_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -1078,7 +1103,7 @@ page2_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* page3_read/page3_write - writes to this page are illegal */ +/* Writes to this page are illegal. */ static uint32_t page3_read(nic_t *dev, uint32_t off, unsigned int len) { @@ -1108,8 +1133,7 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) } -/* read_cr/write_cr - utility routines for handling reads/writes to - the Command Register */ +/* Routines for handling reads/writes to the Command Register. */ static uint32_t read_cr(nic_t *dev) { @@ -1410,7 +1434,9 @@ nic_update_bios(nic_t *dev) dev->bios_addr, dev->bios_size); nelog(1, "%s: BIOS now at: %06X\n", dev->name, dev->bios_addr); } else { + nelog(1, "%s: BIOS disabled\n", dev->name); mem_mapping_disable(&dev->bios_rom.mapping); + dev->bios_addr = 0; if (dev->is_pci) dev->pci_bar[1].addr = 0; } @@ -1421,68 +1447,105 @@ static uint8_t nic_pci_read(int func, int addr, void *priv) { nic_t *dev = (nic_t *)priv; + uint8_t ret = 0x00; switch(addr) { - case 0x00: - return 0xec; - case 0x01: - return 0x10; + case 0x00: /* PCI_VID_LO */ + case 0x01: /* PCI_VID_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x02: - return 0x29; - case 0x03: - return 0x80; + case 0x02: /* PCI_DID_LO */ + case 0x03: /* PCI_DID_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x2C: - return 0xF4; - case 0x2D: - return 0x1A; - case 0x2E: - return 0x00; - case 0x2F: - return 0x11; + case 0x04: /* PCI_COMMAND_LO */ + case 0x05: /* PCI_COMMAND_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x04: - return dev->pci_regs[0x04]; /*Respond to IO and memory accesses*/ - case 0x05: - return dev->pci_regs[0x05]; + case 0x06: /* PCI_STATUS_LO */ + case 0x07: /* PCI_STATUS_HI */ + ret = dev->pci_regs[addr]; + break; - case 0x07: - return 2; + case 0x08: /* PCI_REVID */ + ret = 0x00; /* Rev. 00 */ + break; + case 0x09: /* PCI_PIFR */ + ret = 0x00; /* Rev. 00 */ + break; - case 0x08: - return 0; /*Revision ID*/ - case 0x09: - return 0; /*Programming interface*/ + case 0x0A: /* PCI_SCR */ + ret = dev->pci_regs[addr]; + break; - case 0x0B: - return dev->pci_regs[0x0B]; + case 0x0B: /* PCI_BCR */ + ret = dev->pci_regs[addr]; + break; - case 0x10: - return 1; /*I/O space*/ - case 0x11: - return dev->pci_bar[0].addr_regs[1]; - case 0x12: - return dev->pci_bar[0].addr_regs[2]; - case 0x13: - return dev->pci_bar[0].addr_regs[3]; + case 0x0C: /* (reserved) */ + ret = dev->pci_regs[addr]; + break; - case 0x30: - return dev->pci_bar[1].addr_regs[0] & 0x01; /*BIOS ROM address*/ - case 0x31: - return (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; - case 0x32: - return dev->pci_bar[1].addr_regs[2]; - case 0x33: - return dev->pci_bar[1].addr_regs[3]; + case 0x0D: /* PCI_LTR */ + case 0x0E: /* PCI_HTR */ + ret = dev->pci_regs[addr]; + break; - case 0x3C: - return dev->pci_regs[0x3C]; - case 0x3D: - return dev->pci_regs[0x3D]; + case 0x0F: /* (reserved) */ + ret = dev->pci_regs[addr]; + break; + + case 0x10: /* PCI_BAR 7:5 */ + ret = (dev->pci_bar[0].addr_regs[1] & 0xe0) | 0x01; + break; + case 0x11: /* PCI_BAR 15:8 */ + ret = dev->pci_bar[0].addr_regs[1]; + break; + case 0x12: /* PCI_BAR 23:16 */ + ret = dev->pci_bar[0].addr_regs[2]; + break; + case 0x13: /* PCI_BAR 31:24 */ + ret = dev->pci_bar[0].addr_regs[3]; + break; + + case 0x2C: /* PCI_SVID_LO */ + case 0x2D: /* PCI_SVID_HI */ + ret = dev->pci_regs[addr]; + break; + + case 0x2E: /* PCI_SID_LO */ + case 0x2F: /* PCI_SID_HI */ + ret = dev->pci_regs[addr]; + break; + + case 0x30: /* PCI_ROMBAR */ + ret = dev->pci_bar[1].addr_regs[0] & 0x01; + break; + case 0x31: /* PCI_ROMBAR 15:11 */ + ret = (dev->pci_bar[1].addr_regs[1] & dev->bios_mask) | 0x18; + break; + case 0x32: /* PCI_ROMBAR 23:16 */ + ret = dev->pci_bar[1].addr_regs[2]; + break; + case 0x33: /* PCI_ROMBAR 31:24 */ + ret = dev->pci_bar[1].addr_regs[3]; + break; + + case 0x3C: /* PCI_ILR */ + ret = dev->pci_regs[addr]; + break; + + case 0x3D: /* PCI_IPR */ + ret = dev->pci_regs[addr]; + break; } - return 0; + nelog(2, "%s: PCI_Read(%d, %04x) = %02x\n", dev->name, func, addr, ret); + + return(ret); } @@ -1491,28 +1554,54 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) { nic_t *dev = (nic_t *)priv; + nelog(2, "%s: PCI_Write(%d, %04x, %02x)\n", dev->name, func, addr, val); + switch(addr) { - case 0x04: + case 0x04: /* PCI_COMMAND_LO */ + val &= 0x03; nic_ioremove(dev, dev->base_address); - if (val & PCI_COMMAND_IO) { + if (val & PCI_COMMAND_IO) nic_ioset(dev, dev->base_address); +#if 0 + if (val & PCI_COMMAND_MEMORY) { + ... } +#endif dev->pci_regs[addr] = val; break; - case 0x10: - val &= 0xfc; - val |= 1; - case 0x11: case 0x12: case 0x13: - /* I/O Base set. */ - /* First, remove the old I/O, if old base was >= 0x280. */ + case 0x0C: /* (reserved) */ + dev->pci_regs[addr] = val; + break; + + case 0x0D: /* PCI_LTR */ + dev->pci_regs[addr] = val; + break; + + case 0x0E: /* PCI_HTR */ + dev->pci_regs[addr] = val; + break; + + case 0x0F: /* (reserved) */ + dev->pci_regs[addr] = val; + break; + + case 0x10: /* PCI_BAR */ + val &= 0xfc; /* 0xe0 acc to RTL DS */ + val |= 0x01; /* re-enable IOIN bit */ + /*FALLTHROUGH*/ + + case 0x11: /* PCI_BAR + case 0x12: /* PCI_BAR + case 0x13: /* PCI_BAR */ + /* Remove old I/O. */ nic_ioremove(dev, dev->base_address); - /* Then let's set the PCI regs. */ + /* Set new I/O as per PCI request. */ dev->pci_bar[0].addr_regs[addr & 3] = val; /* Then let's calculate the new I/O base. */ - dev->base_address = dev->pci_bar[0].addr & 0xff00; + dev->base_address = dev->pci_bar[0].addr & 0xffe0; /* Log the new base. */ nelog(1, "%s: PCI: new I/O base is %04X\n", @@ -1520,9 +1609,12 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) /* We're done, so get out of the here. */ if (val & PCI_COMMAND_IO) nic_ioset(dev, dev->base_address); - return; + break; - case 0x30: case 0x31: case 0x32: case 0x33: + case 0x30: /* PCI_ROMBAR */ + case 0x31: /* PCI_ROMBAR */ + case 0x32: /* PCI_ROMBAR */ + case 0x33: /* PCI_ROMBAR */ dev->pci_bar[1].addr_regs[addr & 3] = val; dev->pci_bar[1].addr_regs[1] &= dev->bios_mask; dev->pci_bar[1].addr &= 0xffffe000; @@ -1531,38 +1623,29 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) nic_update_bios(dev); return; -#if 0 - /* Commented out until an APIC controller is emulated for - * the PIIX3, otherwise the RTL-8029/AS will not get an IRQ - * on boards using the PIIX3. */ - case 0x3C: - dev->pci_regs[addr] = val; + case 0x3C: /* PCI_ILR */ if (val != 0xFF) { +#if 1 + /* + * Commented out until an APIC controller is + * emulated for the PIIX3, otherwise the + * RTL-8029/AS will not get an IRQ on boards + * using the PIIX3. + */ + nelog(1, "%s: IRQ now: %i (IGNORED)\n", dev->name, val); +#else nelog(1, "%s: IRQ now: %i\n", dev->name, val); - dev->base_irq = irq; - } - return; + dev->base_irq = val; #endif - } -} - - -static void -nic_tx(nic_t *dev, uint32_t val) -{ - dev->CR.tx_packet = 0; - dev->TSR.tx_ok = 1; - dev->ISR.pkt_tx = 1; - - /* Generate an interrupt if not masked */ - if (dev->IMR.tx_inte) - picint(1 << dev->base_irq); - dev->tx_timer_active = 0; + } + dev->pci_regs[addr] = dev->base_irq; + return; + } } /* - * mcast_index() - return the 6-bit index into the multicast + * Return the 6-bit index into the multicast * table. Stolen unashamedly from FreeBSD's if_ed.c */ static int @@ -1593,12 +1676,25 @@ mcast_index(const void *dst) } +static void +nic_tx(nic_t *dev, uint32_t val) +{ + dev->CR.tx_packet = 0; + dev->TSR.tx_ok = 1; + dev->ISR.pkt_tx = 1; + + /* Generate an interrupt if not masked */ + if (dev->IMR.tx_inte) + picint(1 << dev->base_irq); + dev->tx_timer_active = 0; +} + + /* - * rx_frame() - called by the platform-specific code when an - * ethernet frame has been received. The destination address - * is tested to see if it should be accepted, and if the - * rx ring has enough room, it is copied into it and - * the receive process is updated + * Called by the platform-specific code when an Ethernet frame + * has been received. The destination address is tested to see + * if it should be accepted, and if the RX ring has enough room, + * it is copied into it and the receive process is updated. */ static void nic_rx(void *priv, uint8_t *buf, int io_len) @@ -1616,8 +1712,10 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if ((dev->CR.stop != 0) || (dev->page_start == 0)) return; - /* Add the pkt header + CRC to the length, and work - out how many 256-byte pages the frame would occupy */ + /* + * Add the pkt header + CRC to the length, and work + * out how many 256-byte pages the frame would occupy. + */ pages = (io_len + sizeof(pkthdr) + sizeof(uint32_t) + 255)/256; if (dev->curr_page < dev->bound_ptr) { avail = dev->bound_ptr - dev->curr_page; @@ -1626,9 +1724,11 @@ nic_rx(void *priv, uint8_t *buf, int io_len) (dev->curr_page - dev->bound_ptr); } - /* Avoid getting into a buffer overflow condition by not attempting - to do partial receives. The emulation to handle this condition - seems particularly painful. */ + /* + * Avoid getting into a buffer overflow condition by + * not attempting to do partial receives. The emulation + * to handle this condition seems particularly painful. + */ if ((avail < pages) #if NE2K_NEVER_FULL_RING || (avail == pages) @@ -1647,7 +1747,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (io_len < 60) io_len = 60; - nelog(2, "%s: rx_frame %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", + nelog(2, "%s: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name, buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], @@ -1659,7 +1759,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) if (! memcmp(buf, bcast_addr, 6)) { /* Broadcast not enabled, we're done. */ if (! dev->RCR.broadcast) { - nelog(2, "%s: rx_frame BC disabled\n", dev->name); + nelog(2, "%s: RX BC disabled\n", dev->name); return; } } @@ -1669,7 +1769,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Multicast not enabled, we're done. */ if (! dev->RCR.multicast) { #if 1 - nelog(2, "%s: rx_frame MC disabled\n", dev->name); + nelog(2, "%s: RX MC disabled\n", dev->name); #endif return; } @@ -1677,7 +1777,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Are we listening to this multicast address? */ idx = mcast_index(buf); if (! (dev->mchash[idx>>3] & (1<<(idx&0x7)))) { - nelog(2, "%s: rx_frame MC not listed\n", dev->name); + nelog(2, "%s: RX MC not listed\n", dev->name); return; } } @@ -1685,7 +1785,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) /* Unicast, must be for us.. */ else if (memcmp(buf, dev->physaddr, 6)) return; } else { - nelog(2, "%s: rx_frame promiscuous receive\n", dev->name); + nelog(2, "%s: RX promiscuous receive\n", dev->name); } nextpage = dev->curr_page + pages; @@ -1699,7 +1799,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) pkthdr[1] = nextpage; /* ptr to next packet */ pkthdr[2] = (io_len + sizeof(pkthdr))&0xff; /* length-low */ pkthdr[3] = (io_len + sizeof(pkthdr))>>8; /* length-hi */ - nelog(2, "%s: rx_frame pkthdr [%02x %02x %02x %02x]\n", + nelog(2, "%s: RX pkthdr [%02x %02x %02x %02x]\n", dev->name, pkthdr[0], pkthdr[1], pkthdr[2], pkthdr[3]); /* Copy into buffer, update curpage, and signal interrupt if config'd */ @@ -1717,8 +1817,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) dev->curr_page = nextpage; dev->RSR.rx_ok = 1; - if (buf[0] & 0x80) - dev->RSR.rx_mbit = 1; + dev->RSR.rx_mbit = (buf[0] & 0x01) ? 1 : 0; dev->ISR.pkt_rx = 1; if (dev->IMR.rx_inte) @@ -1729,54 +1828,50 @@ nic_rx(void *priv, uint8_t *buf, int io_len) static void nic_rom_init(nic_t *dev, wchar_t *s) { - FILE *f = romfopen(s, L"rb"); uint32_t temp; + FILE *f; - if (f == NULL) { - dev->bios_addr = 0x00000; - nic_update_bios(dev); - return; + if (dev->bios_addr > 0) { + if ((f = romfopen(s, L"rb")) != NULL) { + fseek(f, 0L, SEEK_END); + temp = ftell(f); + fclose(f); + dev->bios_size = 0x10000; + if (temp <= 0x8000) + dev->bios_size = 0x8000; + if (temp <= 0x4000) + dev->bios_size = 0x4000; + if (temp <= 0x2000) + dev->bios_size = 0x2000; + dev->bios_mask = (dev->bios_size >> 8) & 0xff; + dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; + } else { + dev->bios_addr = 0x00000; + dev->bios_size = 0; + return; + } + + /* Create a memory mapping for the space. */ + rom_init(&dev->bios_rom, s, dev->bios_addr, + dev->bios_size, dev->bios_size-1, 0, MEM_MAPPING_EXTERNAL); } - fseek(f, 0, SEEK_END); - temp = ftell(f); - fclose(f); - dev->bios_size = 0x10000; - if (temp <= 0x8000) - dev->bios_size = 0x8000; - if (temp <= 0x4000) - dev->bios_size = 0x4000; - if (temp <= 0x2000) - dev->bios_size = 0x2000; - dev->bios_mask = (dev->bios_size >> 8) & 0xff; - dev->bios_mask = (0x100 - dev->bios_mask) & 0xff; - rom_init(&dev->bios_rom, s, dev->bios_addr, - dev->bios_size, dev->bios_size - 1, 0, MEM_MAPPING_EXTERNAL); - - nelog(1, "%s: BIOS enabled at %06lX (size %ld)\n", + nelog(1, "%s: BIOS configured at %06lX (size %ld)\n", dev->name, dev->bios_addr, dev->bios_size); } -/* Return the 'local' part of our configured MAC address. */ -static uint32_t -nic_get_maclocal(nic_t *dev) -{ - uint32_t temp; - - temp = (((int) dev->maclocal[3]) << 16); - temp |= (((int) dev->maclocal[4]) << 8); - temp |= ((int) dev->maclocal[5]); - - return(temp); -} - - static void * nic_init(int board) { uint32_t mac; + wchar_t *rom; nic_t *dev; + int i; + + /* Get the desired debug level. */ + i = device_get_config_int("debug"); + if (i > 0) nic_do_log = i; dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); @@ -1787,6 +1882,7 @@ nic_init(int board) dev->maclocal[0] = 0x00; /* 00:00:D8 (NE1000 ISA OID) */ dev->maclocal[1] = 0x00; dev->maclocal[2] = 0xD8; + rom = ROM_PATH_NE1000; break; case NE2K_NE2000: @@ -1794,6 +1890,7 @@ nic_init(int board) dev->maclocal[0] = 0x00; /* 00:A0:0C (NE2000 compatible OID) */ dev->maclocal[1] = 0xA0; dev->maclocal[2] = 0x0C; + rom = ROM_PATH_NE2000; break; case NE2K_RTL8029AS: @@ -1802,43 +1899,112 @@ nic_init(int board) dev->maclocal[0] = 0x00; /* 00:20:18 (RTL 8029AS PCI OID) */ dev->maclocal[1] = 0x20; dev->maclocal[2] = 0x18; + rom = ROM_PATH_RTL8029; break; } - dev->base_irq = device_get_config_int("irq"); - if (dev->is_pci) + if (dev->is_pci) { dev->base_address = 0x340; - else + } else { dev->base_address = device_get_config_int("addr"); - dev->bios_addr = device_get_config_int("bios_addr"); + dev->bios_addr = device_get_config_int("bios_addr"); + } + dev->base_irq = device_get_config_int("irq"); /* See if we have a local MAC address configured. */ mac = device_get_config_int_ex("mac", -1); + /* Make this device known to the I/O system. */ + nic_ioset(dev, dev->base_address); + + /* Set up our BIOS ROM space, if any. */ + nic_rom_init(dev, rom); + + if (dev->is_pci) { + /* + * Configure the PCI space registers. + * + * We do this here, so the I/O routines are generic. + */ + dev->pci_regs[0x00] = (PCI_VENDID&0xff); + dev->pci_regs[0x01] = (PCI_VENDID>>8); + dev->pci_regs[0x02] = (PCI_DEVID&0xff); + dev->pci_regs[0x03] = (PCI_DEVID>>8); + + dev->pci_regs[0x04] = 0x01; /* IOEN */ + dev->pci_regs[0x05] = 0x00; + dev->pci_regs[0x07] = 0x02; /* DST0, medium devsel */ + + dev->pci_regs[0x0B] = 0x02; /* BCR: Network Controller */ + dev->pci_regs[0x0A] = 0x00; /* SCR: Ethernet */ + + dev->pci_regs[0x2C] = (PCI_VENDID&0xff); + dev->pci_regs[0x2D] = (PCI_VENDID>>8); + dev->pci_regs[0x2E] = (PCI_DEVID&0xff); + dev->pci_regs[0x2F] = (PCI_DEVID>>8); + + dev->pci_regs[0x3C] = dev->base_irq; /* PCI_ILR */ + dev->pci_regs[0x3D] = 0x01; /* PCI_IPR */ + + /* Enable our address space in PCI. */ + dev->pci_bar[0].addr_regs[0] = 0x01; + + /* Enable our BIOS space in PCI, if needed. */ + if (dev->bios_addr > 0) { + dev->pci_bar[1].addr = 0x000F8000; + dev->pci_bar[1].addr_regs[1] = dev->bios_mask; + dev->pci_bar[1].addr |= 0x1801; + } else { + dev->pci_bar[1].addr = 0; + } + + /* Initialize the RTL8029 EEPROM. */ + memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); + dev->eeprom[0x76] = + dev->eeprom[0x7A] = + dev->eeprom[0x7E] = (PCI_DEVID&0xff); + dev->eeprom[0x77] = + dev->eeprom[0x7B] = + dev->eeprom[0x7F] = (PCI_DEVID>>8); + dev->eeprom[0x78] = + dev->eeprom[0x7C] = (PCI_VENDID&0xff); + dev->eeprom[0x79] = + dev->eeprom[0x7D] = (PCI_VENDID>>8); + + /* Make this device known to the PCI bus. */ + pci_add(nic_pci_read, nic_pci_write, dev); + } + /* Set up our BIA. */ if (mac & 0xff000000) { - /* Generating new MAC. */ + /* Generate new local MAC. */ dev->maclocal[3] = disc_random_generate(); dev->maclocal[4] = disc_random_generate(); - dev->maclocal[5] = disc_random_generate() | 1; - device_set_config_int("mac", nic_get_maclocal(dev)); + dev->maclocal[5] = disc_random_generate(); + mac = (((int) dev->maclocal[3]) << 16); + mac |= (((int) dev->maclocal[4]) << 8); + mac |= ((int) dev->maclocal[5]); + device_set_config_int("mac", mac); } else { dev->maclocal[3] = (mac>>16) & 0xff; dev->maclocal[4] = (mac>>8) & 0xff; - dev->maclocal[5] = (mac & 0xfe); + dev->maclocal[5] = (mac & 0xff); } memcpy(dev->physaddr, dev->maclocal, sizeof(dev->maclocal)); - nelog(1,"%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", + nelog(0, "%s: I/O=%04x, IRQ=%d, MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, dev->base_address, dev->base_irq, dev->physaddr[0], dev->physaddr[1], dev->physaddr[2], dev->physaddr[3], dev->physaddr[4], dev->physaddr[5]); + /* Reset the board. */ + nic_reset(dev); + if (network_attach(dev, dev->physaddr, nic_rx) < 0) { #if 0 msgbox_error_wstr(ghwnd, L"Unable to init platform network"); #endif - nelog(1, "%s: unable to init platform network type %d\n", + nelog(0, "%s: unable to init platform network type %d\n", dev->name, network_type); #if 0 /* @@ -1852,56 +2018,7 @@ nic_init(int board) #endif } - if (dev->is_pci) - pci_add(nic_pci_read, nic_pci_write, dev); - nic_ioset(dev, dev->base_address); - - if (dev->bios_addr > 0) { - nic_rom_init(dev, dev->is_pci ? L"roms/rtl8029as.rom" - : L"roms/ne2000.rom"); - if (dev->is_pci) - mem_mapping_disable(&dev->bios_rom.mapping); - } - - if (dev->is_pci) { - dev->pci_regs[0x04] = 1; - dev->pci_regs[0x05] = 0; - dev->pci_regs[0x07] = 2; - - /* Network controller. */ - dev->pci_regs[0x0B] = 2; - - dev->pci_bar[0].addr_regs[0] = 1; - - if (dev->bios_addr > 0) { - /* What is it.. F800 or D000 (bios_addr) ? */ - dev->pci_bar[1].addr = 0x000F8000; - dev->pci_bar[1].addr_regs[1] = dev->bios_mask; - dev->pci_bar[1].addr |= 0x1801; - } else { - dev->pci_bar[1].addr = 0; - } - - dev->pci_regs[0x3C] = dev->base_irq; - nelog(1, "%s: IRQ=%i\n", dev->name, dev->pci_regs[0x3C]); - dev->pci_regs[0x3D] = 1; - - memset(dev->eeprom, 0x00, sizeof(dev->eeprom)); - dev->eeprom[0x76] = - dev->eeprom[0x7A] = - dev->eeprom[0x7E] = 0x29; - dev->eeprom[0x77] = - dev->eeprom[0x7B] = - dev->eeprom[0x7F] = 0x80; - dev->eeprom[0x78] = - dev->eeprom[0x7C] = 0x10; - dev->eeprom[0x79] = - dev->eeprom[0x7D] = 0xEC; - } - - nic_reset(dev, 0); - - nelog(1, "%s: %s init 0x%X %d\n", dev->name, + nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); return(dev); From a36720f174abfc57b18c75f253caf0b5c4c33eb4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 May 2017 03:53:32 +0200 Subject: [PATCH 249/392] Large changes to configuration files again (the old ones might break, be careful); Applied the mainline PCem slight CPU emulation speedup commit; Added emulation of removable SCSI hard disks; CD-ROM image handler now uses C FILE's (with the 64-bit size calls) instead of C++ iostreams, ISO images bigger than 2 GB should work properly again; Split RLL/ESDI and XT IDE disks to their own bus types; Turned status bar pane meaning and hard disks and CD-ROM BUS numbers to #define's; Other miscellaneous cleanups. --- src/86box.h | 4 +- src/CPU/386_dynarec.c | 6 +- src/CPU/808x.c | 2 + src/CPU/codegen.h | 22 +- src/CPU/codegen_ops_x86-64.h | 217 ++- src/CPU/codegen_ops_x86.h | 283 +++- src/CPU/codegen_x86-64.c | 4 +- src/CPU/codegen_x86.c | 3 +- src/CPU/x86_ops_misc.h | 29 + src/CPU/x86seg.c | 104 +- src/ICONS/hard_disk_rll.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_rll_active.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_xtide.ico | Bin 0 -> 1150 bytes src/ICONS/hard_disk_xtide_active.ico | Bin 0 -> 1150 bytes src/Makefile.mingw | 4 +- src/SOUND/snd_gus.c | 2 +- src/SOUND/snd_sb.c | 39 +- src/WIN/86Box.rc | 238 +-- src/WIN/plat_iodev.h | 5 + src/WIN/resource.h | 234 +-- src/WIN/win.c | 2332 +++++++++++++------------- src/WIN/win.h | 29 +- src/WIN/win_deviceconfig.c | 86 +- src/WIN/win_iodev.c | 171 ++ src/WIN/win_keyboard.c | 195 +++ src/WIN/win_language.c | 2 - src/WIN/win_mouse.cc | 1 + src/WIN/win_settings.c | 678 ++++++-- src/cdrom.c | 83 +- src/cdrom.h | 2 + src/cdrom_dosbox.cpp | 35 +- src/cdrom_dosbox.h | 8 +- src/cdrom_image.cc | 1 + src/config.c | 1254 ++++++++++++-- src/config.h | 6 + src/device.c | 93 + src/device.h | 10 +- src/disc.c | 2 +- src/fdc.c | 47 +- src/hdd.c | 2 + src/hdd_esdi.c | 12 +- src/ibm.h | 101 +- src/ide.c | 141 +- src/ide.h | 7 +- src/mfm_at.c | 16 +- src/mfm_xebec.c | 18 +- src/model.c | 5 +- src/net_ne2000.c | 33 +- src/network.c | 6 +- src/pc.c | 31 +- src/scsi.h | 12 +- src/scsi_aha154x.c | 84 +- src/scsi_buslogic.c | 44 +- src/scsi_disk.c | 612 +++++-- src/scsi_disk.h | 43 + src/xtide.c | 20 +- 56 files changed, 4736 insertions(+), 2682 deletions(-) create mode 100644 src/ICONS/hard_disk_rll.ico create mode 100644 src/ICONS/hard_disk_rll_active.ico create mode 100644 src/ICONS/hard_disk_xtide.ico create mode 100644 src/ICONS/hard_disk_xtide_active.ico create mode 100644 src/WIN/plat_iodev.h create mode 100644 src/WIN/win_iodev.c create mode 100644 src/WIN/win_keyboard.c create mode 100644 src/scsi_disk.h diff --git a/src/86box.h b/src/86box.h index d45b1bead..06975312f 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,7 +1,7 @@ /* Copyright holders: Tenshi see COPYING for more details */ -#define emulator_version "1.20" -#define emulator_version_w L"1.20" +#define emulator_version "2.00" +#define emulator_version_w L"2.00" #define CONFIG_FILE L"86box.cfg" diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 06066223f..328289d53 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -21,6 +21,8 @@ #define CPU_BLOCK_END() cpu_block_end = 1 +uint32_t cpu_cur_status = 0; + int cpu_reps, cpu_reps_latched; int cpu_notreps, cpu_notreps_latched; @@ -1372,7 +1374,7 @@ void exec386_dynarec(int cycs) and physical address. The physical address check will also catch any page faults at this stage*/ valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32); + (block->phys == phys_addr) && (block->status == cpu_cur_status); if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); @@ -1384,7 +1386,7 @@ void exec386_dynarec(int cycs) if (new_block) { valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32); + (new_block->phys == phys_addr) && (new_block->status == cpu_cur_status); if (valid_block) block = new_block; } diff --git a/src/CPU/808x.c b/src/CPU/808x.c index c102fa45f..80af2c9be 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -546,6 +546,7 @@ void resetx86() resets++; ins = 0; use32=0; + cpu_cur_status = 0; stack32=0; cpu_state.pc=0; msw=0; @@ -583,6 +584,7 @@ void softresetx86() { use32=0; stack32=0; + cpu_cur_status = 0; cpu_state.pc=0; msw=0; cr0=0; diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index ad0b3f63a..5a076db8f 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -35,6 +35,9 @@ typedef struct codeblock_t { + uint64_t page_mask, page_mask2; + uint64_t cmp; + /*Previous and next pointers, for the codeblock list associated with each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ @@ -45,22 +48,19 @@ typedef struct codeblock_t fails.*/ struct codeblock_t *parent, *left, *right; + int pnt; + int ins; + + int was_recompiled; + int TOP; + uint32_t pc; uint32_t _cs; uint32_t endpc; uint32_t phys, phys_2; - uint32_t use32; - int stack32; - int pnt; - int ins; - uint64_t page_mask, page_mask2; - - int was_recompiled; + uint32_t status; uint32_t flags; - int TOP; - - uint64_t cmp; - + uint8_t data[2048]; } codeblock_t; diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index 8573ab495..c27b0f37e 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -866,6 +866,10 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; if (IS_32_ADDR(&seg->base)) { @@ -900,6 +904,10 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; if (IS_32_ADDR(&seg->base)) { @@ -926,6 +934,11 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; + if (IS_32_ADDR(&seg->base)) { addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ @@ -962,7 +975,13 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1030,7 +1049,13 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1114,7 +1139,13 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1190,7 +1221,13 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1309,7 +1346,13 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1388,7 +1431,13 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1478,7 +1527,13 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1566,7 +1621,13 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5252,7 +5313,13 @@ static void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5299,12 +5366,16 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } if (IS_32_ADDR(writelookup2)) { addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ @@ -5328,7 +5399,9 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0); // addbyte(0xc3); /*RET*/ - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); @@ -5373,7 +5446,13 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5416,15 +5495,23 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } addbyte(0x8d); /*LEA ESI, 1[EDI]*/ addbyte(0x77); addbyte(0x01); - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5475,7 +5562,9 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5510,7 +5599,13 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5553,15 +5648,23 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } addbyte(0x8d); /*LEA ESI, 3[EDI]*/ addbyte(0x77); addbyte(0x03); - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5612,7 +5715,9 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && + !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5642,7 +5747,13 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5709,7 +5820,13 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5785,7 +5902,13 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5883,7 +6006,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -5955,7 +6084,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -6038,7 +6173,13 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h index c8c18a28c..229c066ca 100644 --- a/src/CPU/codegen_ops_x86.h +++ b/src/CPU/codegen_ops_x86.h @@ -616,6 +616,10 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -637,6 +641,10 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -650,6 +658,11 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) + return; + if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) + return; + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ addbyte(0x05); addlong((uint32_t)&seg->limit_low); @@ -675,9 +688,18 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -685,9 +707,18 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -697,9 +728,18 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -707,9 +747,18 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); @@ -720,9 +769,18 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -732,9 +790,18 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -743,9 +810,18 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -756,9 +832,18 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -786,9 +871,18 @@ static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -799,9 +893,18 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -812,9 +915,18 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -825,9 +937,18 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -838,9 +959,18 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -851,9 +981,18 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -874,9 +1013,18 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x89); /*MOV ECX, host_reg2*/ addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); } - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } @@ -3792,9 +3940,18 @@ static void LOAD_EA() static void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write*/ addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3802,9 +3959,18 @@ static void MEM_CHECK_WRITE(x86seg *seg) static void MEM_CHECK_WRITE_W(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write_w*/ addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3812,9 +3978,18 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) static void MEM_CHECK_WRITE_L(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write_l*/ addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index e591adc95..9f42b07dd 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -274,13 +274,13 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; - block->use32 = use32; - block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = 0; + block->status = cpu_cur_status; + block->was_recompiled = 0; recomp_page = block->phys & ~0xfff; diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index a42b32104..01015ce87 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1401,12 +1401,11 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; - block->use32 = use32; - block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; block->was_recompiled = 0; diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h index a2b4f6f31..c47517c37 100644 --- a/src/CPU/x86_ops_misc.h +++ b/src/CPU/x86_ops_misc.h @@ -755,9 +755,17 @@ static int opLOADALL(uint32_t fetchdat) ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); _ss.access = readmemb(0, 0x845); _ss.limit = readmemw(0, 0x846); + if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); _ds.access = readmemb(0, 0x84B); _ds.limit = readmemw(0, 0x84C); + if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); gdt.limit = readmemw(0, 0x852); ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); @@ -797,8 +805,29 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0; if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0; + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); + if (use32) + cpu_cur_status |= CPU_STATUS_USE32; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; set_segment_limit(s, segdat3); + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } static int opLOADALL386(uint32_t fetchdat) diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index cc0cc6dbc..10e79b7c9 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -159,6 +159,29 @@ void x86np(char *s, uint16_t error) } +static void set_stack32(int s) +{ + stack32 = s; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; + else + cpu_cur_status &= ~CPU_STATUS_STACK32; +} + +static void set_use32(int u) +{ + if (u) + { + use32 = 0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + } +} + void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); @@ -179,6 +202,21 @@ void do_seg_load(x86seg *s, uint16_t *segdat) s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; s->limit_low = s->limit + 1; } + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } static void do_seg_v86_init(x86seg *s) @@ -251,6 +289,8 @@ void loadseg(uint16_t seg, x86seg *s) s->seg=0; s->access = 0x80; s->base=-1; + if (s == &_ds) + cpu_cur_status &= ~CPU_STATUS_FLATDS; return; } addr=seg&~7; @@ -303,7 +343,7 @@ void loadseg(uint16_t seg, x86seg *s) x86ss(NULL,seg&~3); return; } - stack32 = (segdat[3] & 0x40) ? 1 : 0; + set_stack32((segdat[3] & 0x40) ? 1 : 0); } else if (s!=&_cs) { @@ -359,6 +399,22 @@ void loadseg(uint16_t seg, x86seg *s) stack32 = 0; s->checked = 1; } + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } #define DPL ((segdat[2]>>13)&3) @@ -426,8 +482,7 @@ void loadcs(uint16_t seg) x86np("Load CS not present", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3] & 0x40); CS=(seg&~3)|CPL; do_seg_load(&_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; @@ -530,8 +585,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) x86np("Load CS JMP not present\n", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -544,7 +598,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; cycles -= timing_jmp_pm; } else /*System segment*/ @@ -642,8 +695,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - cpu_state.pc=newpc; + set_use32(segdat[3]&0x40); + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -828,8 +881,7 @@ void loadcscall(uint16_t seg) x86np("Load CS call not present", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -848,7 +900,6 @@ void loadcscall(uint16_t seg) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; if (csout) pclog("Complete\n"); cycles -= timing_call_pm; } @@ -1005,7 +1056,7 @@ void loadcscall(uint16_t seg) } if (!stack32) oldsp &= 0xFFFF; SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; @@ -1022,7 +1073,7 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3]&0x40); cpu_state.pc=newpc; if (output) pclog("Set access 2\n"); @@ -1101,8 +1152,8 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - cpu_state.pc=newpc; + set_use32(segdat[3]&0x40); + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -1245,8 +1296,8 @@ void pmoderetf(int is32, uint16_t off) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - + set_use32(segdat[3] & 0x40); + cycles -= timing_retf_pm; } else @@ -1353,7 +1404,7 @@ void pmoderetf(int is32, uint16_t off) return; } SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -1375,7 +1426,7 @@ void pmoderetf(int is32, uint16_t off) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3] & 0x40); if (stack32) ESP+=off; else SP+=off; @@ -1570,7 +1621,7 @@ void pmodeint(int num, int soft) return; } SS=newss; - stack32 = (segdat3[3] & 0x40) ? 1 : 0; + set_stack32((segdat3[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat3); @@ -1655,7 +1706,7 @@ void pmodeint(int num, int soft) if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; - use32=(segdat2[3]&0x40)?0x300:0; + set_use32(segdat2[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -1809,6 +1860,7 @@ void pmodeiret(int is32) do_seg_v86_init(&_es); loadseg(segs[1],&_ds); do_seg_v86_init(&_ds); + cpu_cur_status &= ~CPU_STATUS_FLATDS; loadseg(segs[2],&_fs); do_seg_v86_init(&_fs); loadseg(segs[3],&_gs); @@ -1826,7 +1878,9 @@ void pmodeiret(int is32) ESP=newsp; loadseg(newss,&_ss); do_seg_v86_init(&_ss); + cpu_cur_status &= ~CPU_STATUS_FLATSS; use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; flags=(tempflags&0xFFD5)|2; cycles -= timing_iret_v86; return; @@ -1913,7 +1967,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -1996,7 +2050,7 @@ void pmodeiret(int is32) return; } SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -2018,7 +2072,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3] & 0x40); check_seg_valid(&_ds); check_seg_valid(&_es); @@ -2208,7 +2262,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat2[3]&0x40)?0x300:0; + set_use32(segdat2[3] & 0x40); EAX=new_eax; ECX=new_ecx; diff --git a/src/ICONS/hard_disk_rll.ico b/src/ICONS/hard_disk_rll.ico new file mode 100644 index 0000000000000000000000000000000000000000..6d329868b18a7ccceed6f1e18e91511e1d25e1cb GIT binary patch literal 1150 zcmd5)O-NK>6um?3BD78GmaSUkE?N}Uu0@FyL_(lw|0G(G6iMQgmYS7hky(zZXf`$G z=v3NdIOESmqGhSoWTQ^m&n8?v%ue@w@`bf&S?_V)_uhT?oOAE@T@jbwiHV}m6|!rw z$Z`=`snC!{=Ht4E=)Yx4=3&17gU1%PCz5^5?;N<=>g>DH;_SKX`@Xxd9@D=ciWi;M)nS)Hqn>XFn)w3C#|@pT^+$$KUX3@-xQb zUk!#QKH*t3j>wxS^u3<^1+DXkYKHia@uzR&7@hiJI4@$;7 z;n5g$zx&tiEyyIFU=DK$a;Zm83wkh4Zs$-GYcuk)R;OenR0bk5j9Wj}OHjwwZEL4L z`MO8nR&Cm`lq0C;>{-a+UXW`wY%TOBpU}Opvg4bSnw89+$YBq*536JQVGZ3QF?f4l zLOE+JUsqS*tzeXS7UWuA^5{t}q38E}0oS~4JajHw=U|SrKyV&8m*-o1P<}7Wb2js- eGc>n;zdQX;{=fPLM2Np#`7RNIMIu3k<^2S`sXfR5 literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_rll_active.ico b/src/ICONS/hard_disk_rll_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..5692d2452e953c5a0ed40159464c925462508f66 GIT binary patch literal 1150 zcmc(dK}-`-5Qbl)H)F($XOEsd=*@W07;n93NQ{XGw~K&U8$n4Uk=RIVG#Ukz2t+is zfQ{Hz3$&tA3XxJu4MqxTQ3{q)1@&S)G=k&&uRd+{pq|X;-`zL+zJF%kjt~aEii!l^ z*NgI%LaY-)Y+!MSBe^&~gy3&$SLGzv|8Ub?R*E?Lvm8~cp7%7=O(_`p|rfJc7td`_P>8uzWn4Do+<<})}8u*yT#qIh@| zpX+E<^S8OUYzKM*gC0~L%18BsI)+}R$UE|!nAxIuej3i)2_>;l39QNs4mrU>)|br;WpXGdBxHq)C{fJ%vmH%IB8W4hPf6i_*2qCpX Jh!Be?r*CIaPt5=T literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_xtide.ico b/src/ICONS/hard_disk_xtide.ico new file mode 100644 index 0000000000000000000000000000000000000000..3f64e288279a1aea2e062ee87d1a6f493bf72db8 GIT binary patch literal 1150 zcmd5)OGs5w6y1-SMP!r44uhbEfkhtzP0B$bWHqp#KL7Dh%CgKvdx>cj75FFZM`ZZv zqnY*c^PZSi%2O<|EX%ZVBn>X6tG$k#uqF-dUe-PL?z`7od!MsKTzZFuh(1FlVX?>x z5m~9wkVfX>x`^n%%waA;F7@bXK@Y~s^$#~8Dt)bcQ|#(x*Sm^;FmC-=FF_q!x2>K2 z?ZfKWepo~A2OpXT zZbCU>manVpVr%Am=2?(yeaWLIxrClya30sZ?(uH)=p4*&76{HG=d!B9i^`5OJZCeX eIzuzj+3OGf&0nZ*K!o_$mE#gISR~?8Sl%xcH7I%j literal 0 HcmV?d00001 diff --git a/src/ICONS/hard_disk_xtide_active.ico b/src/ICONS/hard_disk_xtide_active.ico new file mode 100644 index 0000000000000000000000000000000000000000..806329fead54095cdcee3cc79e2393d6e47c3b8c GIT binary patch literal 1150 zcmc(dOH30{6ozl3J7dI+YnLV_x->x(H7?YoBx*=}Ey#2buxY9Vv?!p}sFk1?jV?qB z0fG<}MAQNz%A*v5K!p^7M6fh-`s)R>#1Zn0}des_=IY89&|RP^`Utv&whuPCCet zr_Y)DE@anb!;H9LP98|`a8x@`)a*o6&smk1xi3A+SJHKqwC14jwjHYf@%=w}*?(r) z7F_K*@#X1E2xD&t5;XBXjL63^rDyMk(HOb`cay9^p1<4gM#EqY>-;M72S=v+F!Z_` z;ptvXei&8E_{%H|jycIv zC-3bI$Fb^lmv^m8&cPgKf#N)JF3SU6lm$-lKdbq?+~Ju^J+j99mH%IBbO-^@pR;=` NLMY7>qFoAz=^Hr#Kd=A* literal 0 HcmV?d00001 diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ed0cb81f8..8bc62edbc 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -195,8 +195,8 @@ WINOBJ = win.o \ win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \ win_d3d.o win_d3d_fs.o \ win_language.o win_status.o win_opendir.o win_dynld.o \ - win_video.o win_serial.o win_mouse.o \ - win_joystick.o win_midi.o \ + win_video.o win_serial.o win_keyboard.o win_mouse.o \ + win_iodev.o win_joystick.o win_midi.o \ win_settings.o win_deviceconfig.o win_joystickconfig.o \ 86Box.res OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ diff --git a/src/SOUND/snd_gus.c b/src/SOUND/snd_gus.c index 2735d77fd..bf625dfb2 100644 --- a/src/SOUND/snd_gus.c +++ b/src/SOUND/snd_gus.c @@ -547,7 +547,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); uint8_t readgus(uint16_t addr, void *p) { gus_t *gus = (gus_t *)p; - uint8_t val; + uint8_t val = 0xff; switch (addr) { case 0x340: /*MIDI status*/ diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 40bfd4213..e94646fd3 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -322,10 +322,10 @@ uint8_t sb_16_mixer_read(uint16_t addr, void *p) case 0x80: switch (sb->dsp.sb_irqnum) { - case 2: return 1; /*IRQ 7*/ - case 5: return 2; /*IRQ 7*/ + case 2: return 1; /*IRQ 2*/ + case 5: return 2; /*IRQ 5*/ case 7: return 4; /*IRQ 7*/ - case 10: return 8; /*IRQ 7*/ + case 10: return 8; /*IRQ 10*/ } break; case 0x81: @@ -465,7 +465,7 @@ void sb_pro_mcv_write(int port, uint8_t val, void *p) void *sb_1_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -482,7 +482,7 @@ void *sb_1_init() void *sb_15_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -517,7 +517,7 @@ void *sb_mcv_init() void *sb_2_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -535,7 +535,7 @@ void *sb_2_init() void *sb_pro_v1_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl2_init(&sb->opl); @@ -563,7 +563,7 @@ void *sb_pro_v1_init() void *sb_pro_v2_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl3_init(&sb->opl); @@ -594,9 +594,6 @@ void *sb_pro_mcv_init() opl3_init(&sb->opl); sb_dsp_init(&sb->dsp, SBPRO2); - /*sb_dsp_setaddr(&sb->dsp, addr); - sb_dsp_setirq(&sb->dsp, device_get_config_int("irq")); - sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));*/ sb_mixer_init(&sb->mixer); io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); sound_add_handler(sb_get_buffer_opl3, sb); @@ -616,7 +613,7 @@ void *sb_pro_mcv_init() void *sb_16_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); memset(sb, 0, sizeof(sb_t)); opl3_init(&sb->opl); @@ -631,7 +628,7 @@ void *sb_16_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_opl3, sb); - mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); + mpu401_init(&sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq401"), device_get_config_int("mode401")); sb->mixer.regs[0x30] = 31 << 3; sb->mixer.regs[0x31] = 31 << 3; @@ -661,7 +658,7 @@ int sb_awe32_available() void *sb_awe32_init() { sb_t *sb = malloc(sizeof(sb_t)); - uint16_t addr = device_get_config_int("addr"); + uint16_t addr = device_get_config_hex16("base"); int onboard_ram = device_get_config_int("onboard_ram"); memset(sb, 0, sizeof(sb_t)); @@ -677,7 +674,7 @@ void *sb_awe32_init() io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl); io_sethandler(addr + 4, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb); sound_add_handler(sb_get_buffer_emu8k, sb); - mpu401_init(&sb->mpu, device_get_config_int("addr401"), device_get_config_int("irq401"), device_get_config_int("mode401")); + mpu401_init(&sb->mpu, device_get_config_hex16("base401"), device_get_config_int("irq401"), device_get_config_int("mode401")); emu8k_init(&sb->emu8k, onboard_ram); sb->mixer.regs[0x30] = 31 << 3; @@ -733,7 +730,7 @@ void sb_add_status_info(char *s, int max_len, void *p) static device_config_t sb_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -826,7 +823,7 @@ static device_config_t sb_mcv_config[] = static device_config_t sb_pro_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -881,7 +878,7 @@ static device_config_t sb_pro_config[] = static device_config_t sb_16_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -901,7 +898,7 @@ static device_config_t sb_16_config[] = } }, { - "addr401", "MPU-401 Address", CONFIG_SELECTION, "", 0x330, + "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, { { "0x300", 0x300 @@ -1016,7 +1013,7 @@ static device_config_t sb_16_config[] = static device_config_t sb_awe32_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x220, + "base", "Address", CONFIG_HEX16, "", 0x220, { { "0x220", 0x220 @@ -1036,7 +1033,7 @@ static device_config_t sb_awe32_config[] = } }, { - "addr401", "MPU-401 Address", CONFIG_SELECTION, "", 0x330, + "base401", "MPU-401 Address", CONFIG_HEX16, "", 0x330, { { "0x300", 0x300 diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index e41ecbda8..b8761032d 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -32,194 +32,6 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US STATUSBARMENU MENU DISCARDABLE BEGIN - POPUP "FDD 1" - BEGIN - MENUITEM "&Change...", IDM_DISC_1 - MENUITEM "Change FDD 1 (&Write-protected)...", IDM_DISC_1_WP - MENUITEM "&Eject FDD 1", IDM_EJECT_1 - END - POPUP "FDD 2" - BEGIN - MENUITEM "&Change...", IDM_DISC_2 - MENUITEM "Change FDD 2 (&Write-protected)...", IDM_DISC_2_WP - MENUITEM "&Eject FDD 2", IDM_EJECT_2 - END - POPUP "FDD 3" - BEGIN - MENUITEM "&Change...", IDM_DISC_3 - MENUITEM "Change FDD 3 (&Write-protected)...", IDM_DISC_3_WP - MENUITEM "&Eject FDD 3", IDM_EJECT_3 - END - POPUP "FDD 4" - BEGIN - MENUITEM "&Change...", IDM_DISC_4 - MENUITEM "Change FDD 4 (&Write-protected)...", IDM_DISC_4_WP - MENUITEM "&Eject FDD 4", IDM_EJECT_4 - END - POPUP "CD-ROM 1" - BEGIN - MENUITEM "&Mute", IDM_CDROM_1_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_1_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_1_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_1_IMAGE - END - POPUP "CD-ROM 2" - BEGIN - MENUITEM "&Mute", IDM_CDROM_2_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_2_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_2_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_2_IMAGE - END - POPUP "CD-ROM 3" - BEGIN - MENUITEM "&Mute", IDM_CDROM_3_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_3_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_3_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_3_IMAGE - END - POPUP "CD-ROM 4" - BEGIN - MENUITEM "&Mute", IDM_CDROM_4_MUTE - MENUITEM SEPARATOR - MENUITEM "E&mpty", IDM_CDROM_4_EMPTY - MENUITEM "&Reload previous image", IDM_CDROM_4_RELOAD - MENUITEM SEPARATOR - MENUITEM "&Image...", IDM_CDROM_4_IMAGE - END - POPUP "Removable disk 01" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_01_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_01_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_01_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_01_EIMAGE - END - POPUP "Removable disk 02" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_02_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_02_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_02_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_02_EIMAGE - END - POPUP "Removable disk 03" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_03_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_03_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_03_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_03_EIMAGE - END - POPUP "Removable disk 04" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_04_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_04_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_04_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_04_EIMAGE - END - POPUP "Removable disk 05" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_05_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_05_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_05_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_05_EIMAGE - END - POPUP "Removable disk 06" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_06_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_06_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_06_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_06_EIMAGE - END - POPUP "Removable disk 07" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_07_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_07_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_07_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_07_EIMAGE - END - POPUP "Removable disk 08" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_08_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_08_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_08_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_08_EIMAGE - END - POPUP "Removable disk 09" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_09_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_09_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_09_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_09_EIMAGE - END - POPUP "Removable disk 10" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_10_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_10_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_10_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_10_EIMAGE - END - POPUP "Removable disk 11" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_11_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_11_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_11_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_11_EIMAGE - END - POPUP "Removable disk 12" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_12_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_12_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_12_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_12_EIMAGE - END - POPUP "Removable disk 13" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_13_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_13_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_13_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_13_EIMAGE - END - POPUP "Removable disk 14" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_14_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_14_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_14_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_14_EIMAGE - END - POPUP "Removable disk 15" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_15_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_15_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_15_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_15_EIMAGE - END - POPUP "Removable disk 16" - BEGIN - MENUITEM "E&mpty", IDM_RDISK_16_EMPTY - MENUITEM "&Reload previous image", IDM_RDISK_16_RELOAD - MENUITEM SEPARATOR - MENUITEM "&New image...", IDM_RDISK_16_IMAGE - MENUITEM "&Existing image...", IDM_RDISK_16_EIMAGE - END END MAINMENU MENU DISCARDABLE @@ -254,7 +66,7 @@ BEGIN MENUITEM "&2x", IDM_VID_SCALE_4X END MENUITEM SEPARATOR - MENUITEM "&Fullscreen", IDM_VID_FULLSCREEN + MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" BEGIN MENUITEM "&Full screen stretch", IDM_VID_FS_FULL @@ -346,6 +158,7 @@ BEGIN #ifdef ENABLE_LOG_BREAKPOINT VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY #endif + VK_PRIOR, IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL END @@ -668,12 +481,16 @@ END 177 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_active.ico" 192 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" 193 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" -194 ICON DISCARDABLE "ICONS/hard_disk.ico" -195 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -196 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -197 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -198 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -199 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" +194 ICON DISCARDABLE "ICONS/hard_disk_xtide.ico" +195 ICON DISCARDABLE "ICONS/hard_disk_xtide_active.ico" +196 ICON DISCARDABLE "ICONS/hard_disk_rll.ico" +197 ICON DISCARDABLE "ICONS/hard_disk_rll_active.ico" +198 ICON DISCARDABLE "ICONS/hard_disk.ico" +199 ICON DISCARDABLE "ICONS/hard_disk_active.ico" +200 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" +201 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" +202 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" +203 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" 256 ICON DISCARDABLE "ICONS/machine.ico" 257 ICON DISCARDABLE "ICONS/video.ico" 258 ICON DISCARDABLE "ICONS/input_devices.ico" @@ -972,9 +789,9 @@ BEGIN 2163 "Attempting to create a spuriously large hard disk image" 2164 "Invalid number of sectors (valid values are between 1 and 99)" 2165 "MFM" - 2166 "IDE (PIO-only)" - 2167 "IDE (PIO and DMA)" - 2168 "SCSI" + 2166 "XT IDE" + 2167 "RLL" + 2168 "IDE (PIO-only)" 2169 "%01i:%01i" 2170 "Custom..." 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" @@ -1004,13 +821,30 @@ BEGIN 2195 "IDE (PIO-only) (%01i:%01i)" 2196 "Add New Hard Disk" 2197 "Add Existing Hard Disk" - 2198 "Removable disk %i: %s" + 2198 "SCSI removable disk %i: %s" 2199 "USB is not yet supported" 2200 "Invalid PCap device" - 2201 "SCSI removable disk: %ws" - 2202 "" - 2203 "English (United States)" + 2201 "&Notify disk change" + 2202 "SCSI (removable)" + 2203 "SCSI (removable) (%02i:%02i)" 2204 "Pcap Library Not Available" + 2205 "RLL (%01i:%01i)" + 2206 "XT IDE (%01i:%01i)" + 2207 "RLL hard disk" + 2208 "XT IDE hard disk" + 2209 "IDE (PIO and DMA)" + 2210 "SCSI" + 2211 "&New image..." + 2212 "Existing image..." + 2213 "Existing image (&Write-protected)..." + 2214 "E&ject" + 2215 "&Mute" + 2216 "E&mpty" + 2217 "&Reload previous image" + 2218 "&Image..." + 2219 "PCap failed to set up because it may not be initialized" + 2220 "Image (&Write-protected)..." + 2221 "English (United States)" END diff --git a/src/WIN/plat_iodev.h b/src/WIN/plat_iodev.h new file mode 100644 index 000000000..650973483 --- /dev/null +++ b/src/WIN/plat_iodev.h @@ -0,0 +1,5 @@ +extern void cdrom_eject(uint8_t id); +extern void cdrom_reload(uint8_t id); +extern void removable_disk_unload(uint8_t id); +extern void removable_disk_eject(uint8_t id); +extern void removable_disk_reload(uint8_t id); diff --git a/src/WIN/resource.h b/src/WIN/resource.h index d70d84a2d..fdc53b649 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -117,19 +117,6 @@ #define IDM_ABOUT 40001 #define IDC_ABOUT_ICON 65535 -#define IDM_DISC_1 40000 -#define IDM_DISC_2 40001 -#define IDM_DISC_3 40002 -#define IDM_DISC_4 40003 -#define IDM_DISC_1_WP 40004 -#define IDM_DISC_2_WP 40005 -#define IDM_DISC_3_WP 40006 -#define IDM_DISC_4_WP 40007 -#define IDM_EJECT_1 40008 -#define IDM_EJECT_2 40009 -#define IDM_EJECT_3 40010 -#define IDM_EJECT_4 40011 - #define IDM_FILE_RESET 40015 #define IDM_FILE_HRESET 40016 #define IDM_FILE_EXIT 40017 @@ -159,92 +146,6 @@ #define IDM_VID_SCREENSHOT 40078 #define IDM_VID_INVERT 40079 -#define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_IMAGE 40144 -#define IDM_CDROM_1_RELOAD 40160 -#define IDM_CDROM_1_EMPTY 40176 -#define IDM_CDROM_1_REAL 40192 -#define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_IMAGE 40145 -#define IDM_CDROM_2_RELOAD 40161 -#define IDM_CDROM_2_EMPTY 40177 -#define IDM_CDROM_2_REAL 40193 -#define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_IMAGE 40146 -#define IDM_CDROM_3_RELOAD 40162 -#define IDM_CDROM_3_EMPTY 40178 -#define IDM_CDROM_3_REAL 40194 -#define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_IMAGE 40147 -#define IDM_CDROM_4_RELOAD 40163 -#define IDM_CDROM_4_EMPTY 40179 -#define IDM_CDROM_4_REAL 40195 - -#define IDM_RDISK_01_IMAGE 3200 -#define IDM_RDISK_01_EIMAGE 3216 -#define IDM_RDISK_01_RELOAD 3232 -#define IDM_RDISK_01_EMPTY 3248 -#define IDM_RDISK_02_IMAGE 3201 -#define IDM_RDISK_02_EIMAGE 3217 -#define IDM_RDISK_02_RELOAD 3233 -#define IDM_RDISK_02_EMPTY 3249 -#define IDM_RDISK_03_IMAGE 3202 -#define IDM_RDISK_03_EIMAGE 3218 -#define IDM_RDISK_03_RELOAD 3234 -#define IDM_RDISK_03_EMPTY 3250 -#define IDM_RDISK_04_IMAGE 3203 -#define IDM_RDISK_04_EIMAGE 3219 -#define IDM_RDISK_04_RELOAD 3235 -#define IDM_RDISK_04_EMPTY 3251 -#define IDM_RDISK_05_IMAGE 3204 -#define IDM_RDISK_05_EIMAGE 3220 -#define IDM_RDISK_05_RELOAD 3236 -#define IDM_RDISK_05_EMPTY 3252 -#define IDM_RDISK_06_IMAGE 3205 -#define IDM_RDISK_06_EIMAGE 3221 -#define IDM_RDISK_06_RELOAD 3237 -#define IDM_RDISK_06_EMPTY 3253 -#define IDM_RDISK_07_IMAGE 3206 -#define IDM_RDISK_07_EIMAGE 3222 -#define IDM_RDISK_07_RELOAD 3238 -#define IDM_RDISK_07_EMPTY 3254 -#define IDM_RDISK_08_IMAGE 3207 -#define IDM_RDISK_08_EIMAGE 3223 -#define IDM_RDISK_08_RELOAD 3239 -#define IDM_RDISK_08_EMPTY 3255 -#define IDM_RDISK_09_IMAGE 3208 -#define IDM_RDISK_09_EIMAGE 3224 -#define IDM_RDISK_09_RELOAD 3240 -#define IDM_RDISK_09_EMPTY 3256 -#define IDM_RDISK_10_IMAGE 3209 -#define IDM_RDISK_10_EIMAGE 3225 -#define IDM_RDISK_10_RELOAD 3241 -#define IDM_RDISK_10_EMPTY 3257 -#define IDM_RDISK_11_IMAGE 3210 -#define IDM_RDISK_11_EIMAGE 3226 -#define IDM_RDISK_11_RELOAD 3242 -#define IDM_RDISK_11_EMPTY 3258 -#define IDM_RDISK_12_IMAGE 3211 -#define IDM_RDISK_12_EIMAGE 3227 -#define IDM_RDISK_12_RELOAD 3243 -#define IDM_RDISK_12_EMPTY 3259 -#define IDM_RDISK_13_IMAGE 3212 -#define IDM_RDISK_13_EIMAGE 3228 -#define IDM_RDISK_13_RELOAD 3244 -#define IDM_RDISK_13_EMPTY 3260 -#define IDM_RDISK_14_IMAGE 3213 -#define IDM_RDISK_14_EIMAGE 3229 -#define IDM_RDISK_14_RELOAD 3245 -#define IDM_RDISK_14_EMPTY 3261 -#define IDM_RDISK_15_IMAGE 3214 -#define IDM_RDISK_15_EIMAGE 3230 -#define IDM_RDISK_15_RELOAD 3246 -#define IDM_RDISK_15_EMPTY 3262 -#define IDM_RDISK_16_IMAGE 3215 -#define IDM_RDISK_16_EIMAGE 3231 -#define IDM_RDISK_16_RELOAD 3247 -#define IDM_RDISK_16_EMPTY 3263 - #define IDM_IDE_TER_ENABLED 44000 #define IDM_IDE_TER_IRQ9 44009 #define IDM_IDE_TER_IRQ10 44010 @@ -326,85 +227,7 @@ #define IDC_EDIT6 1035 #define IDC_COMBOHDT 1036 -#define IDC_EJECTC 1040 -#define IDC_EDITC 1050 #define IDC_CFILE 1060 -#define IDC_CNEW 1070 -#define IDC_EDIT_C_SPT 1200 -#define IDC_EDIT_C_HPC 1210 -#define IDC_EDIT_C_CYL 1220 -#define IDC_EDIT_C_FN 1230 -#define IDC_TEXT_C_SIZE 1240 - -#define IDC_EJECTD 1041 -#define IDC_EDITD 1051 -#define IDC_DFILE 1061 -#define IDC_DNEW 1071 -#define IDC_EDIT_D_SPT 1201 -#define IDC_EDIT_D_HPC 1211 -#define IDC_EDIT_D_CYL 1221 -#define IDC_EDIT_D_FN 1231 -#define IDC_TEXT_D_SIZE 1241 - -#define IDC_EJECTE 1042 -#define IDC_EDITE 1052 -#define IDC_EFILE 1062 -#define IDC_ENEW 1072 -#define IDC_EDIT_E_SPT 1202 -#define IDC_EDIT_E_HPC 1212 -#define IDC_EDIT_E_CYL 1222 -#define IDC_EDIT_E_FN 1232 -#define IDC_TEXT_E_SIZE 1242 - -#define IDC_EJECTF 1043 -#define IDC_EDITF 1053 -#define IDC_FFILE 1063 -#define IDC_FNEW 1073 -#define IDC_EDIT_F_SPT 1203 -#define IDC_EDIT_F_HPC 1213 -#define IDC_EDIT_F_CYL 1223 -#define IDC_EDIT_F_FN 1233 -#define IDC_TEXT_F_SIZE 1243 - -#define IDC_EJECTG 1044 -#define IDC_EDITG 1054 -#define IDC_GFILE 1064 -#define IDC_GNEW 1074 -#define IDC_EDIT_G_SPT 1204 -#define IDC_EDIT_G_HPC 1214 -#define IDC_EDIT_G_CYL 1224 -#define IDC_EDIT_G_FN 1234 -#define IDC_TEXT_G_SIZE 1244 - -#define IDC_EJECTH 1045 -#define IDC_EDITH 1055 -#define IDC_HFILE 1065 -#define IDC_HNEW 1075 -#define IDC_EDIT_H_SPT 1205 -#define IDC_EDIT_H_HPC 1215 -#define IDC_EDIT_H_CYL 1225 -#define IDC_EDIT_H_FN 1235 -#define IDC_TEXT_H_SIZE 1245 - -#define IDC_EJECTI 1046 -#define IDC_EDITI 1056 -#define IDC_IFILE 1066 -#define IDC_INEW 1076 -#define IDC_EDIT_I_SPT 1206 -#define IDC_EDIT_I_HPC 1216 -#define IDC_EDIT_I_CYL 1226 -#define IDC_EDIT_I_FN 1236 -#define IDC_TEXT_I_SIZE 1246 - -#define IDC_EJECTJ 1047 -#define IDC_EDITJ 1057 -#define IDC_JFILE 1067 -#define IDC_JNEW 1077 -#define IDC_EDIT_J_SPT 1207 -#define IDC_EDIT_J_HPC 1217 -#define IDC_EDIT_J_CYL 1227 -#define IDC_EDIT_J_FN 1237 -#define IDC_TEXT_J_SIZE 1247 #define IDC_HDTYPE 1280 @@ -441,47 +264,26 @@ #define IDC_CONFIG_BASE 1200 -#define WM_RESETD3D WM_USER -#define WM_LEAVEFULLSCREEN WM_USER + 1 +/* The biggest amount of low bits needed for CD-ROMS (2 bits for ID and 5 bits for host drive, so 7 bits), + and removable disks (5 bits for ID), so we choose an 256-entry spacing for convenience. */ -#define C_BASE 6 -#define D_BASE 44 -#define E_BASE 82 -#define F_BASE 120 -#define G_BASE 158 -#define H_BASE 196 -#define I_BASE 234 -#define J_BASE 272 -#define CMD_BASE 314 -#define DLG_HEIGHT 346 +#define IDM_FLOPPY_IMAGE_NEW 0x1200 +#define IDM_FLOPPY_IMAGE_EXISTING 0x1300 +#define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400 +#define IDM_FLOPPY_DUMP_86F 0x1500 +#define IDM_FLOPPY_EJECT 0x1600 -#define IDC_CHECK_CDROM_1_ENABLED 1536 -#define IDC_COMBO_CDROM_1_BUS 1544 -#define IDC_COMBO_CDROM_1_CHANNEL 1552 -#define IDC_CHECK_CDROM_1_DMA_ENABLED 1560 -#define IDC_COMBO_CDROM_1_SCSI_ID 1568 -#define IDC_COMBO_CDROM_1_SCSI_LUN 1576 +#define IDM_CDROM_MUTE 0x2200 +#define IDM_CDROM_EMPTY 0x2300 +#define IDM_CDROM_RELOAD 0x2400 +#define IDM_CDROM_IMAGE 0x2500 +#define IDM_CDROM_HOST_DRIVE 0x2600 -#define IDC_CHECK_CDROM_2_ENABLED 1537 -#define IDC_COMBO_CDROM_2_BUS 1545 -#define IDC_COMBO_CDROM_2_CHANNEL 1553 -#define IDC_CHECK_CDROM_2_DMA_ENABLED 1561 -#define IDC_COMBO_CDROM_2_SCSI_ID 1569 -#define IDC_COMBO_CDROM_2_SCSI_LUN 1577 - -#define IDC_CHECK_CDROM_3_ENABLED 1538 -#define IDC_COMBO_CDROM_3_BUS 1546 -#define IDC_COMBO_CDROM_3_CHANNEL 1554 -#define IDC_CHECK_CDROM_3_DMA_ENABLED 1562 -#define IDC_COMBO_CDROM_3_SCSI_ID 1570 -#define IDC_COMBO_CDROM_3_SCSI_LUN 1578 - -#define IDC_CHECK_CDROM_4_ENABLED 1539 -#define IDC_COMBO_CDROM_4_BUS 1547 -#define IDC_COMBO_CDROM_4_CHANNEL 1555 -#define IDC_CHECK_CDROM_4_DMA_ENABLED 1563 -#define IDC_COMBO_CDROM_4_SCSI_ID 1571 -#define IDC_COMBO_CDROM_4_SCSI_LUN 1579 +#define IDM_RDISK_EJECT 0x3200 +#define IDM_RDISK_RELOAD 0x3300 +#define IDM_RDISK_SEND_CHANGE 0x3400 +#define IDM_RDISK_IMAGE 0x3500 +#define IDM_RDISK_IMAGE_WP 0x3600 #define IDC_STATIC 1792 @@ -495,3 +297,5 @@ # define _APS_NEXT_SYMED_VALUE 101 # endif #endif + +#define STRINGS_NUM 174 diff --git a/src/WIN/win.c b/src/WIN/win.c index 4b6c771d0..41e94fa54 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -23,12 +23,15 @@ #include "../cdrom_null.h" #include "../cdrom_ioctl.h" #include "../cdrom_image.h" +#include "../scsi.h" +#include "../scsi_disk.h" #include "../video/video.h" #include "../video/vid_ega.h" #include "../mouse.h" #include "../sound/sound.h" #include "../sound/snd_dbopl.h" #include "plat_keyboard.h" +#include "plat_iodev.h" #include "plat_mouse.h" #include "plat_midi.h" @@ -36,10 +39,12 @@ #include "win_ddraw.h" #include "win_d3d.h" #include "win_language.h" + #include #include #include #include + #include "resource.h" @@ -47,13 +52,45 @@ #define MAPVK_VK_TO_VSC 0 #endif -static int save_window_pos = 0; -uint64_t timer_freq; +/* Declare Windows procedure */ +LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -int rawinputkey[272]; +LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + +#define TIMER_1SEC 1 + +extern int updatestatus; + + +typedef struct win_event_t +{ + HANDLE handle; +} win_event_t; + +LONG_PTR OriginalStatusBarProcedure; +HWND ghwnd; +HINSTANCE hinstance; +HMENU menu; +int pause = 0; +int scale = 0; +HWND hwndRender, hwndStatus; +uint64_t timer_freq; +int winsizex=640, winsizey=480; +int efwinsizey=480; +int gfx_present[GFX_MAX]; +HANDLE ghMutex; +HANDLE mainthreadh; +int infocus=1; +int drawits=0; +int romspresent[ROM_MAX]; +int quited=0; +RECT oldclip; +int mousecapture=0; +int recv_key[272]; +HMENU *sb_menu_handles; +uint64_t main_time; -static RAWINPUTDEVICE device; -static uint16_t scancode_map[65536]; static struct { @@ -61,65 +98,47 @@ static struct void (*close)(); void (*resize)(int x, int y); } vid_apis[2][2] = -{ - { - ddraw_init, ddraw_close, NULL, - d3d_init, d3d_close, d3d_resize - }, - { - ddraw_fs_init, ddraw_fs_close, NULL, - d3d_fs_init, d3d_fs_close, NULL - }, -}; +{ { { ddraw_init, ddraw_close, NULL }, + { d3d_init, d3d_close, d3d_resize } }, + { { ddraw_fs_init, ddraw_fs_close, NULL }, + { d3d_fs_init, d3d_fs_close, NULL } } }; -#define TIMER_1SEC 1 +static int save_window_pos = 0; -int winsizex=640,winsizey=480; -int efwinsizey=480; -int gfx_present[GFX_MAX]; +static RAWINPUTDEVICE device; -HANDLE ghMutex; +static int win_doresize = 0; -HANDLE mainthreadh; +static int leave_fullscreen_flag = 0; -int infocus=1; +static int unscaled_size_x = 0; +static int unscaled_size_y = 0; -int drawits=0; +static uint64_t start_time; +static uint64_t end_time; -int romspresent[ROM_MAX]; -int quited=0; +HMENU smenu; -RECT oldclip; -int mousecapture=0; +static uint8_t host_cdrom_drive_available[26]; -/* Declare Windows procedure */ -LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); -LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +static uint8_t host_cdrom_drive_available_num = 0; -LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +static wchar_t **argv; +static int argc; +static wchar_t *argbuf; -LONG_PTR OriginalStatusBarProcedure; +static HANDLE hinstAcc; -HWND ghwnd; +static HICON hIcon[512]; -HINSTANCE hinstance; +static int *iStatusWidths; +static int *sb_icon_flags; +static int *sb_part_meanings; +static int *sb_part_icons; +static WCHAR **sbTips; -HMENU menu; +static int sb_parts = 0; -extern int updatestatus; - -int pause=0; - -static int win_doresize = 0; - -static int leave_fullscreen_flag = 0; - -static int unscaled_size_x = 0; -static int unscaled_size_y = 0; - -int scale = 0; - -HWND hwndRender, hwndStatus; void updatewindowsize(int x, int y) { @@ -236,11 +255,6 @@ void leave_fullscreen() leave_fullscreen_flag = 1; } -uint64_t main_time; - -uint64_t start_time; -uint64_t end_time; - void mainthread(LPVOID param) { int frames = 0; @@ -253,12 +267,14 @@ void mainthread(LPVOID param) old_time = GetTickCount(); while (!quited) { - if (updatestatus) - { - updatestatus = 0; - if (status_is_open) - SendMessage(status_hwnd, WM_USER, 0, 0); - } + if (updatestatus) + { + updatestatus = 0; + if (status_is_open) + { + SendMessage(status_hwnd, WM_USER, 0, 0); + } + } new_time = GetTickCount(); drawits += new_time - old_time; old_time = new_time; @@ -285,15 +301,9 @@ void mainthread(LPVOID param) video_wait_for_blit(); SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); GetWindowRect(ghwnd, &r); - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); GetWindowRect(hwndRender, &r); - MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), - winsizex, - 17, - TRUE); + MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), winsizex, 17, TRUE); GetWindowRect(ghwnd, &r); MoveWindow(ghwnd, r.left, r.top, @@ -331,11 +341,6 @@ void thread_sleep(int t) Sleep(t); } -typedef struct win_event_t -{ - HANDLE handle; -} win_event_t; - event_t *thread_create_event() { win_event_t *event = malloc(sizeof(win_event_t)); @@ -380,30 +385,123 @@ void thread_destroy_event(event_t *_event) free(event); } -HMENU smenu; - -static void initmenu(void) +static void init_cdrom_host_drives(void) { - int i, c; - HMENU m; + int i = 0; WCHAR s[64]; - for (i = 0; i < CDROM_NUM; i++) - { - m=GetSubMenu(smenu, i + 4); /*CD-ROM*/ + host_cdrom_drive_available_num = 0; - /* Loop through each Windows drive letter and test to see if - it's a CDROM */ - for (c='A';c<='Z';c++) - { - _swprintf(s,L"%c:\\",c); - if (GetDriveType(s)==DRIVE_CDROM) - { - _swprintf(s, win_language_get_string_from_id(2076), c); - AppendMenu(m,MF_STRING,IDM_CDROM_1_REAL+(c << 2)+i,s); - } - } + for (i='A'; i<='Z'; i++) + { + _swprintf(s, L"%c:\\", i + 0x41); + + if (GetDriveType(s)==DRIVE_CDROM) + { + host_cdrom_drive_available[i - 'A'] = 1; + + host_cdrom_drive_available_num++; + } + else + { + host_cdrom_drive_available[i - 'A'] = 0; + } + } +} + + +HMENU create_popup_menu(int part) +{ + HMENU newHandle; + newHandle = CreatePopupMenu(); + AppendMenu(smenu, MF_POPUP, (UINT_PTR) newHandle, 0); + return newHandle; +} + + +void create_floppy_submenu(HMENU m, int id) +{ + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_NEW | id, win_language_get_string_from_id(2211)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING | id, win_language_get_string_from_id(2212)); + AppendMenu(m, MF_STRING, IDM_FLOPPY_IMAGE_EXISTING_WP | id, win_language_get_string_from_id(2213)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_FLOPPY_EJECT | id, win_language_get_string_from_id(2214)); +} + +void create_cdrom_submenu(HMENU m, int id) +{ + int i = 0; + WCHAR s[64]; + + AppendMenu(m, MF_STRING, IDM_CDROM_MUTE | id, win_language_get_string_from_id(2215)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_CDROM_EMPTY | id, win_language_get_string_from_id(2216)); + AppendMenu(m, MF_STRING, IDM_CDROM_RELOAD | id, win_language_get_string_from_id(2217)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_CDROM_IMAGE | id, win_language_get_string_from_id(2218)); + + if (host_cdrom_drive_available_num == 0) + { + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + cdrom_drives[id].host_drive = 0; + } + + goto check_menu_items; } + else + { + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + if (!host_cdrom_drive_available[cdrom_drives[id].host_drive]) + { + cdrom_drives[id].host_drive = 0; + } + } + } + + AppendMenu(m, MF_SEPARATOR, 0, 0); + + for (i = 0; i < 26; i++) + { + _swprintf(s, L"%c:\\", i + 0x41); + if (host_cdrom_drive_available[i]) + { + AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i << 3) | id, s); + } + } + +check_menu_items: + if (!cdrom_drives[id].sound_on) + { + CheckMenuItem(smenu, IDM_CDROM_MUTE | id, MF_CHECKED); + } + + if (cdrom_drives[id].host_drive == 200) + { + CheckMenuItem(smenu, IDM_CDROM_IMAGE | id, MF_CHECKED); + } + else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(smenu, IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + } + else + { + cdrom_drives[id].host_drive = 0; + CheckMenuItem(smenu, IDM_CDROM_EMPTY | id, MF_CHECKED); + } +} + +void create_removable_disk_submenu(HMENU m, int id) +{ + AppendMenu(m, MF_STRING, IDM_RDISK_EJECT | id, win_language_get_string_from_id(2216)); + AppendMenu(m, MF_STRING, IDM_RDISK_RELOAD | id, win_language_get_string_from_id(2217)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_RDISK_SEND_CHANGE | id, win_language_get_string_from_id(2201)); + AppendMenu(m, MF_SEPARATOR, 0, 0); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE | id, win_language_get_string_from_id(2218)); + AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(2220)); } void get_executable_name(WCHAR *s, int size) @@ -425,96 +523,6 @@ uint64_t timer_read() return qpc_time.QuadPart; } -/* This is so we can disambiguate scan codes that would otherwise conflict and get - passed on incorrectly. */ -UINT16 convert_scan_code(UINT16 scan_code) -{ - switch (scan_code) - { - case 0xE001: - return 0xF001; - case 0xE002: - return 0xF002; - case 0xE0AA: - return 0xF003; - case 0xE005: - return 0xF005; - case 0xE006: - return 0xF006; - case 0xE007: - return 0xF007; - case 0xE071: - return 0xF008; - case 0xE072: - return 0xF009; - case 0xE07F: - return 0xF00A; - case 0xE0E1: - return 0xF00B; - case 0xE0EE: - return 0xF00C; - case 0xE0F1: - return 0xF00D; - case 0xE0FE: - return 0xF00E; - case 0xE0EF: - return 0xF00F; - - default: - return scan_code; - } -} - -void get_registry_key_map() -{ - WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; - WCHAR *valueName = L"Scancode Map"; - unsigned char buf[32768]; - DWORD bufSize; - HKEY hKey; - int j; - - /* First, prepare the default scan code map list which is 1:1. - Remappings will be inserted directly into it. - 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, - since each array element is a scan code and provides for E0, etc. ones too. */ - for (j = 0; j < 65536; j++) - scancode_map[j] = convert_scan_code(j); - - bufSize = 32768; - /* Get the scan code remappings from: - HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) - { - if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) - { - UINT32 *bufEx2 = (UINT32 *) buf; - int scMapCount = bufEx2[2]; - if ((bufSize != 0) && (scMapCount != 0)) - { - UINT16 *bufEx = (UINT16 *) (buf + 12); - for (j = 0; j < scMapCount*2; j += 2) - { - /* Each scan code is 32-bit: 16 bits of remapped scan code, - and 16 bits of original scan code. */ - int scancode_unmapped = bufEx[j + 1]; - int scancode_mapped = bufEx[j]; - - scancode_mapped = convert_scan_code(scancode_mapped); - - /* Fixes scan code map logging. */ - scancode_map[scancode_unmapped] = scancode_mapped; - } - } - } - RegCloseKey(hKey); - } -} - -static wchar_t **argv; -static int argc; -static wchar_t *argbuf; - static void process_command_line() { WCHAR *cmdline; @@ -581,14 +589,6 @@ static void process_command_line() argv[argc] = NULL; } -int valid_models[2] = { 0, 1 }; -int valid_bases[6] = { 0x130, 0x134, 0x230, 0x234, 0x330, 0x334 }; -int valid_irqs[6] = { 9, 10, 11, 12, 14, 15 }; -int valid_dma_channels[3] = { 5, 6, 7 }; -int valid_ide_channels[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; -int valid_scsi_ids[15] = { 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; -int valid_scsi_luns[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - int find_in_array(int *array, int val, int len, int menu_base) { int i = 0; @@ -604,8 +604,6 @@ int find_in_array(int *array, int val, int len, int menu_base) return temp; } -HANDLE hinstAcc; - HICON LoadIconEx(PCTSTR pszIconName) { return (HICON) LoadImage(hinstance, pszIconName, IMAGE_ICON, 16, 16, LR_SHARED); @@ -647,13 +645,6 @@ int fdd_type_to_icon(int type) } } -int sb_parts = 10; - -int sb_part_meanings[12]; -int sb_part_icons[12]; - -int sb_icon_width = 24; - int count_hard_disks(int bus) { int i = 0; @@ -671,29 +662,16 @@ int count_hard_disks(int bus) return c; } -HICON hIcon[512]; - -int iStatusWidths[] = { 18, 36, 54, 72, 90, 108, 126, 144, 168, 192, 210, -1 }; - -#define SBI_FLAG_ACTIVE 1 -#define SBI_FLAG_EMPTY 256 - -int sb_icon_flags[512]; - -/* This is for the disk activity indicator. */ -void update_status_bar_icon(int tag, int active) +int find_status_bar_part(int tag) { int i = 0; int found = -1; - int temp_flags = 0; - if ((tag & 0xf0) >= 0x40) + if (sb_part_meanings == NULL) { - return; + return -1; } - temp_flags |= active; - for (i = 0; i < 12; i++) { if (sb_part_meanings[i] == tag) @@ -703,6 +681,24 @@ void update_status_bar_icon(int tag, int active) } } + return found; +} + +/* This is for the disk activity indicator. */ +void update_status_bar_icon(int tag, int active) +{ + int found = -1; + int temp_flags = 0; + + if (((tag & 0xf0) >= SB_TEXT) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) + { + return; + } + + temp_flags |= active; + + found = find_status_bar_part(tag); + if (found != -1) { if (temp_flags != (sb_icon_flags[found] & 1)) @@ -721,22 +717,14 @@ void update_status_bar_icon(int tag, int active) /* This is for the drive state indicator. */ void update_status_bar_icon_state(int tag, int state) { - int i = 0; int found = -1; - if ((tag & 0xf0) >= 0x20) + if (((tag & 0xf0) >= SB_HDD) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { return; } - for (i = 0; i < 12; i++) - { - if (sb_part_meanings[i] == tag) - { - found = i; - break; - } - } + found = find_status_bar_part(tag); if (found != -1) { @@ -750,31 +738,35 @@ void update_status_bar_icon_state(int tag, int state) } } -WCHAR sbTips[24][512]; - void create_floppy_tip(int part) { - WCHAR *szText; WCHAR wtext[512]; + WCHAR tempTip[512]; int drive = sb_part_meanings[part] & 0xf; mbstowcs(wtext, fdd_getname(fdd_get_type(drive)), strlen(fdd_getname(fdd_get_type(drive))) + 1); if (wcslen(discfns[drive]) == 0) { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); + _swprintf(tempTip, win_language_get_string_from_id(2179), drive + 1, wtext, discfns[drive]); } + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void create_cdrom_tip(int part) { - WCHAR *szText; - char ansi_text[3][512]; WCHAR wtext[512]; + WCHAR tempTip[512]; int drive = sb_part_meanings[part] & 0xf; @@ -782,48 +774,91 @@ void create_cdrom_tip(int part) { if (wcslen(cdrom_image[drive].image_path) == 0) { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); } } else if (cdrom_drives[drive].host_drive < 0x41) { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { _swprintf(wtext, win_language_get_string_from_id(2186), cdrom_drives[drive].host_drive & ~0x20); - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, wtext); + _swprintf(tempTip, win_language_get_string_from_id(2180), drive + 1, wtext); } + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void create_removable_hd_tip(int part) { - WCHAR *szText; - WCHAR wtext[512]; + WCHAR tempTip[512]; - int drive = sb_part_meanings[part] & 0xf; + int drive = sb_part_meanings[part] & 0x1f; - if (wcslen(hdd_fn[drive]) == 0) + if (wcslen(hdc[drive].fn) == 0) { - _swprintf(sbTips[part], win_language_get_string_from_id(2201), win_language_get_string_from_id(2185)); + _swprintf(tempTip, win_language_get_string_from_id(2198), drive, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2179), hdd_fn[drive]); + _swprintf(tempTip, win_language_get_string_from_id(2198), drive, hdc[drive].fn); } + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(tempTip) << 1) + 2); + wcscpy(sbTips[part], tempTip); } void create_hd_tip(int part) { WCHAR *szText; + int id = 2181; int bus = sb_part_meanings[part] & 0xf; - szText = (WCHAR *) win_language_get_string_from_id(2181 + bus); - memcpy(sbTips[part], szText, (wcslen(szText) << 1) + 2); + + switch(bus) + { + case HDD_BUS_MFM: + id = 2181; + break; + case HDD_BUS_RLL: + id = 2207; + break; + case HDD_BUS_XTIDE: + id = 2208; + break; + case HDD_BUS_IDE_PIO_ONLY: + id = 2182; + break; + case HDD_BUS_IDE_PIO_AND_DMA: + id = 2183; + break; + case HDD_BUS_SCSI: + id = 2184; + break; + } + + szText = (WCHAR *) win_language_get_string_from_id(id); + + if (sbTips[part] != NULL) + { + free(sbTips[part]); + } + sbTips[part] = (WCHAR *) malloc((wcslen(szText) << 1) + 2); + wcscpy(sbTips[part], szText); } void update_tip(int meaning) @@ -843,16 +878,16 @@ void update_tip(int meaning) { switch(meaning & 0xf0) { - case 0x00: + case SB_FLOPPY: create_floppy_tip(part); break; - case 0x10: + case SB_CDROM: create_cdrom_tip(part); break; - case 0x20: + case SB_RDISK: create_removable_hd_tip(part); break; - case 0x30: + case SB_HDD: create_hd_tip(part); break; default: @@ -863,30 +898,6 @@ void update_tip(int meaning) } } -static int get_floppy_state(int id) -{ - return (wcslen(discfns[id]) == 0) ? 1 : 0; -} - -static int get_cd_state(int id) -{ - if (cdrom_drives[id].host_drive < 0x41) - { - return 1; - } - else - { - if (cdrom_drives[id].host_drive == 0x200) - { - return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; - } - else - { - return 0; - } - } -} - void status_settextw(wchar_t *wstr) { int i = 0; @@ -894,7 +905,7 @@ void status_settextw(wchar_t *wstr) for (i = 0; i < sb_parts; i++) { - if (sb_part_meanings[i] == 0x40) + if (sb_part_meanings[i] == SB_TEXT) { part = i; } @@ -915,95 +926,218 @@ void status_settext(char *str) status_settextw(cwstr); } +void destroy_menu_handles() +{ + int i = 0; + + if (sb_parts == 0) + { + return; + } + + for (i = 0; i < sb_parts; i++) + { + DestroyMenu(sb_menu_handles[i]); + } + + free(sb_menu_handles); +} + +void destroy_tips() +{ + int i = 0; + + if (sb_parts == 0) + { + return; + } + + for (i = 0; i < sb_parts; i++) + { + free(sbTips[i]); + } + + free(sbTips); +} + void update_status_bar_panes(HWND hwnds) { int i, j, id; int edge = 0; - int c_rll = 0; int c_mfm = 0; + int c_rll = 0; + int c_xtide = 0; int c_ide_pio = 0; int c_ide_dma = 0; int c_scsi = 0; - c_mfm = count_hard_disks(1); - c_ide_pio = count_hard_disks(2); - c_ide_dma = count_hard_disks(3); - c_scsi = count_hard_disks(4); + c_mfm = count_hard_disks(HDD_BUS_MFM); + c_rll = count_hard_disks(HDD_BUS_RLL); + c_xtide = count_hard_disks(HDD_BUS_XTIDE); + c_ide_pio = count_hard_disks(HDD_BUS_IDE_PIO_ONLY); + c_ide_dma = count_hard_disks(HDD_BUS_IDE_PIO_AND_DMA); + c_scsi = count_hard_disks(HDD_BUS_SCSI); - for (i = 0; i < sb_parts; i++) + if (sb_parts > 0) { - SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + for (i = 0; i < sb_parts; i++) + { + SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); + } + + sb_parts = 0; + + free(iStatusWidths); + free(sb_part_meanings); + free(sb_part_icons); + free(sb_icon_flags); + destroy_menu_handles(); + destroy_tips(); } - sb_parts = 0; - memset(iStatusWidths, 0, 48); - memset(sb_part_meanings, 0, 48); - for (i = 0; i < 4; i++) + for (i = 0; i < FDD_NUM; i++) { if (fdd_get_type(i) != 0) { /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x00 | i; sb_parts++; } } - for (i = 0; i < 4; i++) + for (i = 0; i < CDROM_NUM; i++) { if (cdrom_drives[i].bus_type != 0) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x10 | i; sb_parts++; } } for (i = 0; i < 16; i++) { - if (hdc[i].bus == 5) + if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x20 | i; sb_parts++; } } - if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5)) + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5) && !!memcmp(hdd_controller_name, "esdi", 4)) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x30; sb_parts++; } - if (c_ide_pio && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + if (c_rll && !memcmp(hdd_controller_name, "esdi", 4)) { - edge += sb_icon_width; - iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x31; sb_parts++; } - if (c_ide_dma && ((models[model].flags & MODEL_HAS_IDE) || !memcmp(hdd_controller_name, "xtide", 5))) + if (c_xtide && !memcmp(hdd_controller_name, "xtide", 5)) { - edge += sb_icon_width; + sb_parts++; + } + if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE)) + { + sb_parts++; + } + if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE)) + { + sb_parts++; + } + if (c_scsi && (scsi_card_current != 0)) + { + sb_parts++; + } + sb_parts++; + + iStatusWidths = (int *) malloc(sb_parts << 2); + sb_part_meanings = (int *) malloc(sb_parts << 2); + sb_part_icons = (int *) malloc(sb_parts << 2); + sb_icon_flags = (int *) malloc(sb_parts << 2); + sb_menu_handles = (HMENU *) malloc(sb_parts * sizeof(HMENU)); + sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); + + memset(iStatusWidths, 0, sb_parts << 2); + memset(sb_part_meanings, 0, sb_parts << 2); + memset(sb_part_icons, 0, sb_parts << 2); + memset(sb_icon_flags, 0, sb_parts << 2); + memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); + + sb_parts = 0; + + for (i = 0; i < FDD_NUM; i++) + { + if (fdd_get_type(i) != 0) + { + /* pclog("update_status_bar_panes(): Found floppy drive %c:, type %i\n", 65 + i, fdd_get_type(i)); */ + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_FLOPPY | i; + sb_parts++; + } + } + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type != 0) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_CDROM | i; + sb_parts++; + } + } + for (i = 0; i < HDC_NUM; i++) + { + if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_RDISK | i; + sb_parts++; + } + } + if (c_mfm && !(models[model].flags & MODEL_HAS_IDE) && !!memcmp(hdd_controller_name, "none", 4) && !!memcmp(hdd_controller_name, "xtide", 5) && !!memcmp(hdd_controller_name, "esdi", 4)) + { + edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x32; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_MFM; + sb_parts++; + } + if (c_rll && !memcmp(hdd_controller_name, "esdi", 4)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_RLL; + sb_parts++; + } + if (c_xtide && !memcmp(hdd_controller_name, "xtide", 5)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_XTIDE; + sb_parts++; + } + if (c_ide_pio && (models[model].flags & MODEL_HAS_IDE)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE_PIO_ONLY; + sb_parts++; + } + if (c_ide_dma && (models[model].flags & MODEL_HAS_IDE)) + { + edge += SB_ICON_WIDTH; + iStatusWidths[sb_parts] = edge; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_IDE_PIO_AND_DMA; sb_parts++; } if (c_scsi) { - edge += sb_icon_width; + edge += SB_ICON_WIDTH; iStatusWidths[sb_parts] = edge; - sb_part_meanings[sb_parts] = 0x33; + sb_part_meanings[sb_parts] = SB_HDD | HDD_BUS_SCSI; sb_parts++; } if (sb_parts) { - iStatusWidths[sb_parts - 1] += (24 - sb_icon_width); + iStatusWidths[sb_parts - 1] += (24 - SB_ICON_WIDTH); } iStatusWidths[sb_parts] = -1; - sb_part_meanings[sb_parts] = 0x40; + sb_part_meanings[sb_parts] = SB_TEXT; sb_parts++; SendMessage(hwnds, SB_SETPARTS, (WPARAM) sb_parts, (LPARAM) iStatusWidths); @@ -1012,13 +1146,16 @@ void update_status_bar_panes(HWND hwnds) { switch (sb_part_meanings[i] & 0xf0) { - case 0x00: + case SB_FLOPPY: /* Floppy */ sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; sb_part_icons[i] = fdd_type_to_icon(fdd_get_type(sb_part_meanings[i] & 0xf)) | sb_icon_flags[i]; + sb_menu_handles[i] = create_popup_menu(i); + create_floppy_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf); + EnableMenuItem(sb_menu_handles[i], IDM_FLOPPY_EJECT | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); create_floppy_tip(i); break; - case 0x10: + case SB_CDROM: /* CD-ROM */ id = sb_part_meanings[i] & 0xf; if (cdrom_drives[id].host_drive < 0x41) @@ -1036,11 +1173,11 @@ void update_status_bar_panes(HWND hwnds) sb_icon_flags[i] = 0; } } - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { j = 164; } - else if (cdrom_drives[id].bus_type == 3) + else if (cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { j = 162; } @@ -1049,20 +1186,28 @@ void update_status_bar_panes(HWND hwnds) j = 160; } sb_part_icons[i] = j | sb_icon_flags[i]; + sb_menu_handles[i] = create_popup_menu(i); + create_cdrom_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0xf); + EnableMenuItem(sb_menu_handles[i], IDM_CDROM_RELOAD | (sb_part_meanings[i] & 0xf), MF_BYCOMMAND | MF_GRAYED); create_cdrom_tip(i); break; - case 0x20: + case SB_RDISK: /* Removable hard disk */ - sb_icon_flags[i] = (wcslen(discfns[sb_part_meanings[i] & 0xf]) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(hdc[sb_part_meanings[i] & 0x1f].fn) == 0) ? 256 : 0; sb_part_icons[i] = 176 + sb_icon_flags[i]; + sb_menu_handles[i] = create_popup_menu(i); + create_removable_disk_submenu(sb_menu_handles[i], sb_part_meanings[i] & 0x1f); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_EJECT | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_RELOAD | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[i], IDM_RDISK_SEND_CHANGE | (sb_part_meanings[i] & 0x1f), MF_BYCOMMAND | ((sb_icon_flags[i] & 256) ? MF_GRAYED : MF_ENABLED)); create_removable_hd_tip(i); break; - case 0x30: + case SB_HDD: /* Hard disk */ - sb_part_icons[i] = 192 + ((sb_part_meanings[i] & 0xf) << 1); + sb_part_icons[i] = 192 + (((sb_part_meanings[i] & 0xf) - 1) << 1); create_hd_tip(i); break; - case 0x40: + case SB_TEXT: /* Status text */ SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); sb_part_icons[i] = -1; @@ -1114,7 +1259,7 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) hIcon[i] = LoadIconEx((PCTSTR) i); } - for (i = 192; i < 200; i++) + for (i = 192; i < 204; i++) { hIcon[i] = LoadIconEx((PCTSTR) i); } @@ -1150,30 +1295,17 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) InitCommonControls(); - hwndStatus = CreateWindowEx( - 0, - STATUSCLASSNAME, - (PCTSTR) NULL, - SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, - 0, dh - 17, dw, 17, - hwndParent, - (HMENU) idStatus, - hinst, - NULL); + hwndStatus = CreateWindowEx(0, STATUSCLASSNAME, (PCTSTR) NULL, SBARS_SIZEGRIP | WS_CHILD | WS_VISIBLE | SBT_TOOLTIPS, 0, dh - 17, dw, 17, hwndParent, + (HMENU) idStatus, hinst, NULL); GetWindowRect(hwndStatus, &rectDialog); - SetWindowPos( - hwndStatus, - HWND_TOPMOST, - rectDialog.left, - rectDialog.top, - rectDialog.right - rectDialog.left, - rectDialog.bottom - rectDialog.top, - SWP_SHOWWINDOW); + SetWindowPos(hwndStatus, HWND_TOPMOST, rectDialog.left, rectDialog.top, rectDialog.right - rectDialog.left, rectDialog.bottom - rectDialog.top, SWP_SHOWWINDOW); SendMessage(hwndStatus, SB_SETMINHEIGHT, (WPARAM) 17, (LPARAM) 0); + sb_parts = 0; + update_status_bar_panes(hwndStatus); return hwndStatus; @@ -1193,94 +1325,97 @@ void win_menu_update() #endif } -int recv_key[272]; - -int WINAPI WinMain (HINSTANCE hThisInstance, - HINSTANCE hPrevInstance, - LPSTR lpszArgument, - int nFunsterStil) - +int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { - HWND hwnd; /* This is the handle for our window */ - MSG messages; /* Here messages to the application are saved */ - WNDCLASSEX wincl; /* Data structure for the windowclass */ - int c, d, e, bRet; + HWND hwnd; /* This is the handle for our window */ + MSG messages; /* Here messages to the application are saved */ + WNDCLASSEX wincl; /* Data structure for the windowclass */ + int c, d, bRet; WCHAR emulator_title[200]; - LARGE_INTEGER qpc_freq; - HACCEL haccel; /* Handle to accelerator table */ + LARGE_INTEGER qpc_freq; + HACCEL haccel; /* Handle to accelerator table */ memset(recv_key, 0, sizeof(recv_key)); - process_command_line(); + process_command_line(); win_language_load_common_strings(); - - hinstance=hThisInstance; - /* The Window structure */ - wincl.hInstance = hThisInstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof (WNDCLASSEX); - /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); - wincl.hCursor = NULL; - wincl.lpszMenuName = NULL; /* No menu */ - wincl.cbClsExtra = 0; /* No extra bytes after the window class */ - wincl.cbWndExtra = 0; /* structure or the window instance */ - /* Use Windows's default color as the background of the window */ - wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; + hinstance=hThisInstance; + /* The Window structure */ + wincl.hInstance = hThisInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ + wincl.style = CS_DBLCLKS; /* Catch double-clicks */ + wincl.cbSize = sizeof (WNDCLASSEX); - /* Register the window class, and if it fails quit the program */ - if (!RegisterClassEx(&wincl)) - return 0; + /* Use default icon and mouse-pointer */ + wincl.hIcon = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hIconSm = LoadIcon(hinstance, (LPCTSTR) 100); + wincl.hCursor = NULL; + wincl.lpszMenuName = NULL; /* No menu */ + wincl.cbClsExtra = 0; /* No extra bytes after the window class */ + wincl.cbWndExtra = 0; /* structure or the window instance */ + /* Use Windows's default color as the background of the window */ + wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND; - wincl.lpszClassName = szSubClassName; - wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ + /* Register the window class, and if it fails quit the program */ + if (!RegisterClassEx(&wincl)) + { + return 0; + } - if (!RegisterClassEx(&wincl)) - return 0; + wincl.lpszClassName = szSubClassName; + wincl.lpfnWndProc = subWindowProcedure; /* This function is called by windows */ - menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + if (!RegisterClassEx(&wincl)) + { + return 0; + } - /* The class is registered, let's create the program*/ - hwnd = CreateWindowEx ( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - emulator_title, /* Title Text */ - (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ - CW_USEDEFAULT, /* Windows decides the position */ - CW_USEDEFAULT, /* where the window ends up on the screen */ - 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ - 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ - HWND_DESKTOP, /* The window is a child-window to desktop */ - menu, /* Menu */ - hThisInstance, /* Program Instance handler */ - NULL /* No Window Creation data */ + menu = LoadMenu(hThisInstance, TEXT("MainMenu")); + + _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + + /* The class is registered, let's create the program*/ + hwnd = CreateWindowEx ( + 0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + emulator_title, /* Title Text */ + (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX)/* | DS_3DLOOK*/, /* default window */ + CW_USEDEFAULT, /* Windows decides the position */ + CW_USEDEFAULT, /* where the window ends up on the screen */ + 640+(GetSystemMetrics(SM_CXFIXEDFRAME)*2), /* The programs width */ + 480+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1, /* and height in pixels */ + HWND_DESKTOP, /* The window is a child-window to desktop */ + menu, /* Menu */ + hThisInstance, /* Program Instance handler */ + NULL /* No Window Creation data */ ); - /* Make the window visible on the screen */ - ShowWindow (hwnd, nFunsterStil); + /* Make the window visible on the screen */ + ShowWindow (hwnd, nFunsterStil); - /* Load the accelerator table */ - haccel = LoadAccelerators(hinstAcc, L"MainAccel"); - if (haccel == NULL) - fatal("haccel is null\n"); + /* Load the accelerator table */ + haccel = LoadAccelerators(hinstAcc, L"MainAccel"); + if (haccel == NULL) + { + fatal("haccel is null\n"); + } - memset(rawinputkey, 0, sizeof(rawinputkey)); device.usUsagePage = 0x01; device.usUsage = 0x06; device.dwFlags = RIDEV_NOHOTKEYS; device.hwndTarget = hwnd; if (RegisterRawInputDevices(&device, 1, sizeof(device))) + { pclog("Raw input registered!\n"); + } else + { pclog("Raw input registration failed!\n"); + } get_registry_key_map(); @@ -1296,7 +1431,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - initmenu(); + init_cdrom_host_drives(); if (vid_apis[0][vid_api].init(hwndRender) == 0) { @@ -1313,28 +1448,6 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)|WS_VISIBLE); else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); - /* Note by Kiririn: I've redone this since the CD-ROM can be disabled but still have something inside it. */ - for (e = 0; e < CDROM_NUM; e++) - { - if (!cdrom_drives[e].sound_on) - { - CheckMenuItem(smenu, IDM_CDROM_1_MUTE + e, MF_CHECKED); - } - - if (cdrom_drives[e].host_drive == 200) - { - CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); - } - else if (cdrom_drives[e].host_drive >= 65) - { - CheckMenuItem(smenu, IDM_CDROM_1_REAL + e + (cdrom_drives[e].host_drive << 2), MF_CHECKED); - } - else - { - CheckMenuItem(smenu, IDM_CDROM_1_EMPTY + e, MF_CHECKED); - } - } - #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); @@ -1407,9 +1520,10 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } } - - for (c = 0; c < GFX_MAX; c++) - gfx_present[c] = video_card_available(video_old_to_new(c)); + for (c = 0; c < GFX_MAX; c++) + { + gfx_present[c] = video_card_available(video_old_to_new(c)); + } if (!video_card_available(video_old_to_new(gfxcard))) { @@ -1439,8 +1553,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, ghMutex = CreateMutex(NULL, FALSE, NULL); mainthreadh=(HANDLE)_beginthread(mainthread,0,NULL); SetThreadPriority(mainthreadh, THREAD_PRIORITY_HIGHEST); - - + updatewindowsize(640, 480); QueryPerformanceFrequency(&qpc_freq); @@ -1501,9 +1614,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, mousecapture=0; } - if ((recv_key[0x1D] || recv_key[0x9D]) && - (recv_key[0x38] || recv_key[0xB8]) && - (recv_key[0x51] || recv_key[0xD1]) && + if ((recv_key[0x1D] || recv_key[0x9D]) && (recv_key[0x38] || recv_key[0xB8]) && (recv_key[0x51] || recv_key[0xD1]) && video_fullscreen) { leave_fullscreen(); @@ -1538,13 +1649,15 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HHOOK hKeyboardHook; int hook_enabled = 0; -LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam ) +LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { BOOL bControlKeyDown; KBDLLHOOKSTRUCT* p; - if (nCode < 0 || nCode != HC_ACTION) - return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + if (nCode < 0 || nCode != HC_ACTION) + { + return CallNextHookEx( hKeyboardHook, nCode, wParam, lParam); + } p = (KBDLLHOOKSTRUCT*)lParam; @@ -1574,136 +1687,6 @@ void cdrom_close(uint8_t id) } } -int ide_ter_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[2] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[2] = irq; - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_TER_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -int ide_qua_set_irq(HMENU hmenu, int irq, int id) -{ - if (ide_irq[3] == irq) - { - return 0; - } - if (msgbox_reset_yn(ghwnd) != IDYES) - { - return 0; - } - pause = 1; - Sleep(100); - ide_irq[3] = irq; - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ9, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ10, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ11, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ12, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ14, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_IDE_QUA_IRQ15, MF_UNCHECKED); - CheckMenuItem(hmenu, id, MF_CHECKED); - saveconfig(); - resetpchard(); - pause = 0; - return 1; -} - -void video_toggle_option(HMENU hmenu, int *val, int id) -{ - *val ^= 1; - CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); - saveconfig(); -} - -void win_cdrom_eject(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - if (cdrom_drives[id].host_drive == 0) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - cdrom_drives[id].handler->exit(id); - cdrom_close(id); - cdrom_null_open(id, 0); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); - if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drive << 2), MF_UNCHECKED); - } - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - cdrom_drives[id].host_drive=0; - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_CHECKED); - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - -void win_cdrom_reload(uint8_t id) -{ - HMENU hmenu; - hmenu = GetSubMenu(smenu, id + 4); - int new_cdrom_drive; - if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) - { - /* Switch from empty to empty. Do nothing. */ - return; - } - cdrom_close(id); - if (cdrom_drives[id].prev_host_drive == 200) - { - image_open(id, cdrom_image[id].image_path); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); - } - else - { - new_cdrom_drive = cdrom_drives[id].prev_host_drive; - ioctl_open(id, new_cdrom_drive); - if (cdrom_drives[id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + id + (cdrom_drives[id].host_drive << 2), MF_CHECKED); - } - update_status_bar_icon_state(0x10 | id, get_cd_state(id)); - update_tip(0x10 | id); - saveconfig(); -} - static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; @@ -1734,520 +1717,464 @@ static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA void about_open(HWND hwnd) { - DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); + DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); +} + +static void win_pc_reset(int hard) +{ + pause=1; + Sleep(100); + savenvr(); + saveconfig(); + if (hard) + { + resetpchard(); + } + else + { + resetpc_cad(); + } + pause=0; +} + +void video_toggle_option(HMENU hmenu, int *val, int id) +{ + startblit(); + video_wait_for_blit(); + *val ^= 1; + CheckMenuItem(hmenu, id, *val ? MF_CHECKED : MF_UNCHECKED); + endblit(); + saveconfig(); + device_force_redraw(); } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - HMENU hmenu; - RECT rect; - uint32_t ri_size = 0; - int edgex, edgey; - int sb_borders[3]; + HMENU hmenu; + RECT rect; - switch (message) - { - case WM_CREATE: - SetTimer(hwnd, TIMER_1SEC, 1000, NULL); - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - break; - - case WM_COMMAND: - hmenu=GetMenu(hwnd); - switch (LOWORD(wParam)) - { - case IDM_FILE_HRESET: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpchard(); - pause=0; - break; - case IDM_FILE_RESET_CAD: - pause=1; - Sleep(100); - savenvr(); - saveconfig(); - resetpc_cad(); - pause=0; - break; - case IDM_FILE_EXIT: - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - case IDM_CONFIG: - win_settings_open(hwnd); - break; - case IDM_ABOUT: - about_open(hwnd); + switch (message) + { + case WM_CREATE: + SetTimer(hwnd, TIMER_1SEC, 1000, NULL); + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; break; - case IDM_STATUS: - status_open(hwnd); - break; - - case IDM_VID_RESIZE: - vid_resize=!vid_resize; - CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)?MF_CHECKED:MF_UNCHECKED); - if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_MINIMIZEBOX)|WS_VISIBLE); - else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); - GetWindowRect(hwnd,&rect); - SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - GetWindowRect(hwndStatus,&rect); - SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); - if (vid_resize) + + case WM_COMMAND: + hmenu=GetMenu(hwnd); + switch (LOWORD(wParam)) { - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); - scale = 1; - } - EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); - EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); - win_doresize = 1; - saveconfig(); - break; - case IDM_VID_REMEMBER: - window_remember = !window_remember; - CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); - GetWindowRect(hwnd, &rect); - if (window_remember) - { - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - } - saveconfig(); - break; + case IDM_FILE_HRESET: + win_pc_reset(1); + break; - case IDM_VID_DDRAW: case IDM_VID_D3D: - startblit(); - video_wait_for_blit(); - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); - vid_apis[0][vid_api].close(); - vid_api = LOWORD(wParam) - IDM_VID_DDRAW; - CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); - vid_apis[0][vid_api].init(hwndRender); - endblit(); - saveconfig(); - device_force_redraw(); - break; + case IDM_FILE_RESET_CAD: + win_pc_reset(0); + break; - case IDM_VID_FULLSCREEN: - - if(video_fullscreen!=1){ - - if (video_fullscreen_first) - { - video_fullscreen_first = 0; - msgbox_info(ghwnd, 2193); - } - startblit(); - video_wait_for_blit(); - mouse_close(); - vid_apis[0][vid_api].close(); - video_fullscreen = 1; - vid_apis[1][vid_api].init(ghwnd); - mouse_init(); - leave_fullscreen_flag = 0; - endblit(); - device_force_redraw(); - } - break; + case IDM_FILE_EXIT: + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; - case IDM_VID_FS_FULL: - case IDM_VID_FS_43: - case IDM_VID_FS_SQ: - case IDM_VID_FS_INT: - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); - video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; - CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); - saveconfig(); - break; + case IDM_CONFIG: + win_settings_open(hwnd); + break; - case IDM_VID_SCALE_1X: - case IDM_VID_SCALE_2X: - case IDM_VID_SCALE_3X: - case IDM_VID_SCALE_4X: - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); - scale = LOWORD(wParam) - IDM_VID_SCALE_1X; - CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); - saveconfig(); - break; + case IDM_ABOUT: + about_open(hwnd); + break; - case IDM_VID_FORCE43: - video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); - break; + case IDM_STATUS: + status_open(hwnd); + break; - case IDM_VID_INVERT: - video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); - break; + case IDM_VID_RESIZE: + vid_resize = !vid_resize; + CheckMenuItem(hmenu, IDM_VID_RESIZE, (vid_resize)? MF_CHECKED : MF_UNCHECKED); + if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_MINIMIZEBOX) | WS_VISIBLE); + else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX) | WS_VISIBLE); + GetWindowRect(hwnd, &rect); + SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + GetWindowRect(hwndStatus,&rect); + SetWindowPos(hwndStatus, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED); + if (vid_resize) + { + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_VID_SCALE_2X, MF_CHECKED); + scale = 1; + } + EnableMenuItem(hmenu, IDM_VID_SCALE_1X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); + EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + win_doresize = 1; + saveconfig(); + break; - case IDM_VID_OVERSCAN: - video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); - update_overscan = 1; - break; + case IDM_VID_REMEMBER: + window_remember = !window_remember; + CheckMenuItem(hmenu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); + GetWindowRect(hwnd, &rect); + if (window_remember) + { + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + } + saveconfig(); + break; - case IDM_VID_FLASH: - video_toggle_option(hmenu, &enable_flash, IDM_VID_FLASH); - break; + case IDM_VID_DDRAW: + case IDM_VID_D3D: + startblit(); + video_wait_for_blit(); + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); + vid_apis[0][vid_api].close(); + vid_api = LOWORD(wParam) - IDM_VID_DDRAW; + CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); + vid_apis[0][vid_api].init(hwndRender); + endblit(); + saveconfig(); + device_force_redraw(); + break; - case IDM_VID_SCREENSHOT: - take_screenshot(); - break; + case IDM_VID_FULLSCREEN: + if(video_fullscreen != 1) + { + if (video_fullscreen_first) + { + video_fullscreen_first = 0; + msgbox_info(ghwnd, 2193); + } + + startblit(); + video_wait_for_blit(); + mouse_close(); + vid_apis[0][vid_api].close(); + video_fullscreen = 1; + vid_apis[1][vid_api].init(ghwnd); + mouse_init(); + leave_fullscreen_flag = 0; + endblit(); + saveconfig(); + device_force_redraw(); + } + break; + + case IDM_VID_FS_FULL: + case IDM_VID_FS_43: + case IDM_VID_FS_SQ: + case IDM_VID_FS_INT: + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_UNCHECKED); + video_fullscreen_scale = LOWORD(wParam) - IDM_VID_FS_FULL; + CheckMenuItem(hmenu, IDM_VID_FS_FULL + video_fullscreen_scale, MF_CHECKED); + saveconfig(); + device_force_redraw(); + break; + + case IDM_VID_SCALE_1X: + case IDM_VID_SCALE_2X: + case IDM_VID_SCALE_3X: + case IDM_VID_SCALE_4X: + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_UNCHECKED); + scale = LOWORD(wParam) - IDM_VID_SCALE_1X; + CheckMenuItem(hmenu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + saveconfig(); + device_force_redraw(); + break; + + case IDM_VID_FORCE43: + video_toggle_option(hmenu, &force_43, IDM_VID_FORCE43); + break; + + case IDM_VID_INVERT: + video_toggle_option(hmenu, &invert_display, IDM_VID_INVERT); + break; + + case IDM_VID_OVERSCAN: + update_overscan = 1; + video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); + break; + + case IDM_VID_SCREENSHOT: + take_screenshot(); + break; #ifdef ENABLE_LOG_TOGGLES #ifdef ENABLE_BUSLOGIC_LOG - case IDM_LOG_BUSLOGIC: - buslogic_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_BUSLOGIC: + buslogic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_CDROM_LOG - case IDM_LOG_CDROM: - cdrom_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_CDROM: + cdrom_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_D86F_LOG - case IDM_LOG_D86F: - d86f_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_D86F: + d86f_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_FDC_LOG - case IDM_LOG_FDC: - fdc_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_FDC: + fdc_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_IDE_LOG - case IDM_LOG_IDE: - ide_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_IDE: + ide_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #ifdef ENABLE_NE2000_LOG - case IDM_LOG_NE2000: - ne2000_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); - break; + case IDM_LOG_NE2000: + ne2000_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); + break; #endif #endif #ifdef ENABLE_LOG_BREAKPOINT - case IDM_LOG_BREAKPOINT: - pclog("---- LOG BREAKPOINT ----\n"); - break; + case IDM_LOG_BREAKPOINT: + pclog("---- LOG BREAKPOINT ----\n"); + break; #endif #ifdef ENABLE_VRAM_DUMP - case IDM_DUMP_VRAM: - svga_dump_vram(); - break; + case IDM_DUMP_VRAM: + svga_dump_vram(); + break; #endif - case IDM_CONFIG_LOAD: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 0)) - { - if (msgbox_reset_yn(ghwnd) == IDYES) - { - config_save(config_file_default); - loadconfig(wopenfilestring); - pclog_w(L"NVR path: %s\n", nvr_path); - mem_resize(); - loadbios(); - resetpchard(); - } - } - pause = 0; - break; - - case IDM_CONFIG_SAVE: - pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 1)) - config_save(wopenfilestring); - pause = 0; - break; - } - return 0; - - case WM_INPUT: - { - UINT size; - RAWINPUT *raw; - - if (!infocus) - break; - - GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); - - raw = malloc(size); - - if (raw == NULL) - { - return 0; - } - - /* Here we read the raw input data for the keyboard */ - ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); - - if(ri_size != size) - { - return 0; - } - - /* If the input is keyboard, we process it */ - if (raw->header.dwType == RIM_TYPEKEYBOARD) - { - const RAWKEYBOARD rawKB = raw->data.keyboard; - USHORT scancode = rawKB.MakeCode; - - /* If it's not a scan code that starts with 0xE1 */ - if (!(rawKB.Flags & RI_KEY_E1)) - { - if (rawKB.Flags & RI_KEY_E0) - scancode |= (0xE0 << 8); - - /* Remap it according to the list from the Registry */ - scancode = scancode_map[scancode]; - - if ((scancode >> 8) == 0xF0) - scancode |= 0x100; /* Extended key code in disambiguated format */ - else if ((scancode >> 8) == 0xE0) - scancode |= 0x80; /* Normal extended key code */ - - /* If it's not 0 (therefore not 0xE1, 0xE2, etc), - then pass it on to the rawinputkey array */ - if (!(scancode & 0xf00)) + case IDM_CONFIG_LOAD: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 0)) { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + if (msgbox_reset_yn(ghwnd) == IDYES) + { + config_save(config_file_default); + loadconfig(wopenfilestring); + /* pclog_w(L"NVR path: %s\n", nvr_path); */ + mem_resize(); + loadbios(); + resetpchard(); + } } - } - else - { - if (rawKB.MakeCode == 0x1D) - scancode = 0xFF; - if (!(scancode & 0xf00)) + pause = 0; + break; + + case IDM_CONFIG_SAVE: + pause = 1; + if (!file_dlg_st(hwnd, 2174, "", 1)) { - rawinputkey[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); - recv_key[scancode & 0x1ff] = rawinputkey[scancode & 0x1ff]; + config_save(wopenfilestring); + } + pause = 0; + break; + } + return 0; + + case WM_INPUT: + process_raw_input(lParam, infocus); + break; + + case WM_SETFOCUS: + infocus=1; + if (!hook_enabled) + { + hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); + hook_enabled = 1; + } + break; + + case WM_KILLFOCUS: + infocus=0; + if (mousecapture) + { + ClipCursor(&oldclip); + ShowCursor(TRUE); + mousecapture=0; + } + memset(recv_key, 0, sizeof(recv_key)); + if (video_fullscreen) + { + leave_fullscreen_flag = 1; + } + if (hook_enabled) + { + UnhookWindowsHookEx(hKeyboardHook); + hook_enabled = 0; + } + break; + + case WM_LBUTTONUP: + if (!mousecapture && !video_fullscreen) + { + GetClipCursor(&oldclip); + GetWindowRect(hwnd, &rect); + rect.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.right = GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 20; + rect.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + ClipCursor(&rect); + mousecapture = 1; + while (1) + { + if (ShowCursor(FALSE) < 0) + { + break; } } - } - free(raw); + } + break; - } - break; + case WM_MBUTTONUP: + if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) + { + releasemouse(); + } + break; - case WM_SETFOCUS: - infocus=1; - if (!hook_enabled) - { - hKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0 ); - hook_enabled = 1; - } - break; + case WM_ENTERMENULOOP: + break; - case WM_KILLFOCUS: - infocus=0; - if (mousecapture) - { - ClipCursor(&oldclip); - ShowCursor(TRUE); - mousecapture=0; - } - memset(rawinputkey, 0, sizeof(rawinputkey)); - if (video_fullscreen) - leave_fullscreen_flag = 1; - if (hook_enabled) - { + case WM_SIZE: + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) + { + startblit(); + video_wait_for_blit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + endblit(); + } + + MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); + + if (mousecapture) + { + GetWindowRect(hwnd, &rect); + rect.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + rect.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 20; + rect.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + ClipCursor(&rect); + } + + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_MOVE: + if (window_remember) + { + GetWindowRect(hwnd, &rect); + window_x = rect.left; + window_y = rect.top; + window_w = rect.right - rect.left; + window_h = rect.bottom - rect.top; + save_window_pos = 1; + } + break; + + case WM_TIMER: + if (wParam == TIMER_1SEC) + { + onesec(); + } + break; + + case WM_RESETD3D: + startblit(); + if (video_fullscreen) + { + d3d_fs_reset(); + } + else + { + d3d_reset(); + } + endblit(); + break; + + case WM_LEAVEFULLSCREEN: + startblit(); + mouse_close(); + vid_apis[1][vid_api].close(); + video_fullscreen = 0; + vid_apis[0][vid_api].init(hwndRender); + mouse_init(); + endblit(); + device_force_redraw(); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + return 0; + + case WM_DESTROY: UnhookWindowsHookEx(hKeyboardHook); - hook_enabled = 0; - } - break; + KillTimer(hwnd, TIMER_1SEC); + PostQuitMessage (0); /* send a WM_QUIT to the message queue */ + break; - case WM_LBUTTONUP: - if (!mousecapture && !video_fullscreen) - { - RECT pcclip; + case WM_SYSCOMMAND: + /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ + if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) + { + return 0; /*disable ALT key for menu*/ + } - GetClipCursor(&oldclip); - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - mousecapture = 1; - while (1) - { - if (ShowCursor(FALSE) < 0) break; - } - } - break; - - case WM_MBUTTONUP: - if (!(mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON)) - releasemouse(); - break; - - case WM_ENTERMENULOOP: - break; - - case WM_SIZE: - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - - MoveWindow(hwndRender, 0, 0, - winsizex, - winsizey, - TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) - { - startblit(); - video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } - - MoveWindow(hwndStatus, 0, winsizey + 6, - winsizex, - 17, - TRUE); - - if (mousecapture) - { - RECT pcclip; - - GetWindowRect(hwnd, &pcclip); - pcclip.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - pcclip.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 10; - pcclip.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 10; - ClipCursor(&pcclip); - } - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_MOVE: - if (window_remember) - { - GetWindowRect(hwnd, &rect); - window_x = rect.left; - window_y = rect.top; - window_w = rect.right - rect.left; - window_h = rect.bottom - rect.top; - save_window_pos = 1; - } - break; - - case WM_TIMER: - if (wParam == TIMER_1SEC) - onesec(); - break; - - case WM_RESETD3D: - startblit(); - if (video_fullscreen) - d3d_fs_reset(); - else - d3d_reset(); - endblit(); - break; - - case WM_LEAVEFULLSCREEN: - startblit(); - mouse_close(); - vid_apis[1][vid_api].close(); - video_fullscreen = 0; - vid_apis[0][vid_api].init(ghwnd); - mouse_init(); - endblit(); - device_force_redraw(); - break; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - case WM_KEYUP: - case WM_SYSKEYUP: - return 0; - - case WM_DESTROY: - UnhookWindowsHookEx( hKeyboardHook ); - KillTimer(hwnd, TIMER_1SEC); - PostQuitMessage (0); /* send a WM_QUIT to the message queue */ - break; - - case WM_SYSCOMMAND: - /* Disable ALT key *ALWAYS*, I don't think there's any use for reaching the menu that way. */ - if (wParam == SC_KEYMENU && HIWORD(lParam) <= 0) - return 0; /*disable ALT key for menu*/ - - default: - return DefWindowProc (hwnd, message, wParam, lParam); - } - return 0; + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } + return 0; } LRESULT CALLBACK subWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch (message) - { - default: - return DefWindowProc(hwnd, message, wParam, lParam); - } - return 0; + switch (message) + { + default: + return DefWindowProc(hwnd, message, wParam, lParam); + } + return 0; } VOID APIENTRY HandlePopupMenu(HWND hwnd, POINT pt, int id) { - HMENU pmenu; - int menu_id = -1; if (id >= (sb_parts - 1)) { return; } - pt.x = id * sb_icon_width; /* Justify to the left. */ + pt.x = id * SB_ICON_WIDTH; /* Justify to the left. */ pt.y = 0; /* Justify to the top. */ ClientToScreen(hwnd, (LPPOINT) &pt); - if ((sb_part_meanings[id] & 0xf0) == 0x00) - { - menu_id = sb_part_meanings[id] & 0xf; - } - else if ((sb_part_meanings[id] & 0xf0) == 0x10) - { - menu_id = (sb_part_meanings[id] & 0xf) + 4; - } -#if 0 - else if ((sb_part_meanings[id] & 0xf0) == 0x20) - { - menu_id = (sb_part_meanings[id] & 0xf) + 8; - } -#endif - if (menu_id != -1) - { - pmenu = GetSubMenu(smenu, menu_id); - TrackPopupMenu(pmenu, TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); - } + TrackPopupMenu(sb_menu_handles[id], TPM_LEFTALIGN | TPM_BOTTOMALIGN | TPM_LEFTBUTTON, pt.x, pt.y, 0, hwndStatus, NULL); } LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -2257,211 +2184,212 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR WCHAR temp_image_path[1024]; int new_cdrom_drive; - int cdrom_id = 0; - int menu_sub_param = 0; - int menu_super_param = 0; int ret = 0; + int item_id = 0; + int item_params = 0; + int id = 0; + int part = 0; + int letter = 0; - HMENU hmenu; + HMENU hmenu; - switch (message) - { + switch (message) + { case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDM_DISC_1: - case IDM_DISC_1_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[0], 0); - if (!ret) - { - disc_close(0); - ui_writeprot[0] = (LOWORD(wParam) == IDM_DISC_1_WP) ? 1 : 0; - disc_load(0, wopenfilestring); - update_status_bar_icon_state(0x00, 0); - update_tip(0x00); - saveconfig(); - } - break; - case IDM_DISC_2: - case IDM_DISC_2_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[1], 0); - if (!ret) - { - disc_close(1); - ui_writeprot[1] = (LOWORD(wParam) == IDM_DISC_2_WP) ? 1 : 0; - disc_load(1, wopenfilestring); - update_status_bar_icon_state(0x01, 0); - update_tip(0x01); - saveconfig(); - } - break; - case IDM_DISC_3: - case IDM_DISC_3_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[2], 0); - if (!ret) - { - disc_close(2); - ui_writeprot[2] = (LOWORD(wParam) == IDM_DISC_3_WP) ? 1 : 0; - disc_load(2, wopenfilestring); - update_status_bar_icon_state(0x02, 0); - update_tip(0x02); - saveconfig(); - } - break; - case IDM_DISC_4: - case IDM_DISC_4_WP: - ret = file_dlg_w_st(hwnd, 2173, discfns[3], 0); - if (!ret) - { - disc_close(3); - ui_writeprot[3] = (LOWORD(wParam) == IDM_DISC_4_WP) ? 1 : 0; - disc_load(3, wopenfilestring); - update_status_bar_icon_state(0x03, 0); - update_tip(0x03); - saveconfig(); - } - break; - case IDM_EJECT_1: - disc_close(0); - update_status_bar_icon_state(0x00, 1); - update_tip(0x00); - saveconfig(); - break; - case IDM_EJECT_2: - disc_close(1); - update_status_bar_icon_state(0x01, 1); - update_tip(0x01); - saveconfig(); - break; - case IDM_EJECT_3: - disc_close(2); - update_status_bar_icon_state(0x02, 1); - update_tip(0x02); - saveconfig(); - break; - case IDM_EJECT_4: - disc_close(3); - update_status_bar_icon_state(0x03, 1); - update_tip(0x03); - saveconfig(); - break; + item_id = LOWORD(wParam) & 0xff00; /* Mask out the low 8 bits for item ID. */ + item_params = LOWORD(wParam) & 0x00ff; /* Mask out the high 8 bits for item parameter. */ - case IDM_CDROM_1_MUTE: - case IDM_CDROM_2_MUTE: - case IDM_CDROM_3_MUTE: - case IDM_CDROM_4_MUTE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - Sleep(100); - cdrom_drives[cdrom_id].sound_on ^= 1; - CheckMenuItem(hmenu, IDM_CDROM_1_MUTE + (cdrom_id * 1000), cdrom_drives[cdrom_id].sound_on ? MF_UNCHECKED : MF_CHECKED); - saveconfig(); - sound_cd_thread_reset(); - break; + switch (item_id) + { + case IDM_FLOPPY_IMAGE_EXISTING: + case IDM_FLOPPY_IMAGE_EXISTING_WP: + id = item_params & 0x0003; + part = find_status_bar_part(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } - case IDM_CDROM_1_EMPTY: - case IDM_CDROM_2_EMPTY: - case IDM_CDROM_3_EMPTY: - case IDM_CDROM_4_EMPTY: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_eject(cdrom_id); - break; - - case IDM_CDROM_1_RELOAD: - case IDM_CDROM_2_RELOAD: - case IDM_CDROM_3_RELOAD: - case IDM_CDROM_4_RELOAD: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - win_cdrom_reload(cdrom_id); - break; - - case IDM_CDROM_1_IMAGE: - case IDM_CDROM_2_IMAGE: - case IDM_CDROM_3_IMAGE: - case IDM_CDROM_4_IMAGE: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) - { - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - wcscpy(temp_image_path, wopenfilestring); - if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) - { - /* Switching from image to the same image. Do nothing. */ + ret = file_dlg_w_st(hwnd, 2173, discfns[id], id); + if (!ret) + { + disc_close(id); + ui_writeprot[id] = (item_id == IDM_FLOPPY_IMAGE_EXISTING_WP) ? 1 : 0; + disc_load(id, wopenfilestring); + update_status_bar_icon_state(SB_FLOPPY | id, wcslen(discfns[id]) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | (wcslen(discfns[id]) ? MF_ENABLED : MF_GRAYED)); + update_tip(SB_FLOPPY | id); + saveconfig(); + } break; - } - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - image_open(cdrom_id, temp_image_path); - if (cdrom_drives[cdrom_id].bus_type) - { - /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - default: - cdrom_id = LOWORD(wParam) & 3; - hmenu = GetSubMenu(smenu, cdrom_id + 4); - menu_sub_param = ((LOWORD(wParam) - IDM_CDROM_1_REAL) - cdrom_id) >> 2; - /* pclog("[%04X] Guest drive %c [%i]: -> Host drive %c [%i]:\n", LOWORD(wParam), 0x4b + cdrom_id, cdrom_id, menu_sub_param, menu_sub_param); */ - if (((LOWORD(wParam) & ~3) >= (IDM_CDROM_1_REAL + ('A' << 2))) && ((LOWORD(wParam) & ~3) <= (IDM_CDROM_1_REAL + ('Z' << 2)))) - { - new_cdrom_drive = menu_sub_param; - if (cdrom_drives[cdrom_id].host_drive == new_cdrom_drive) - { - /* Switching to the same drive. Do nothing. */ + case IDM_FLOPPY_EJECT: + id = item_params & 0x0003; + part = find_status_bar_part(SB_FLOPPY | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + disc_close(id); + update_status_bar_icon_state(SB_FLOPPY | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_FLOPPY_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_FLOPPY | id); + saveconfig(); break; - } - cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - cdrom_drives[cdrom_id].handler->exit(cdrom_id); - cdrom_close(cdrom_id); - ioctl_open(cdrom_id, new_cdrom_drive); - if (cdrom_drives[cdrom_id].bus_type) - { + + case IDM_CDROM_MUTE: + id = item_params & 0x0007; + hmenu = GetSubMenu(smenu, id + 4); + Sleep(100); + cdrom_drives[id].sound_on ^= 1; + CheckMenuItem(hmenu, IDM_CDROM_MUTE | id, cdrom_drives[id].sound_on ? MF_UNCHECKED : MF_CHECKED); + saveconfig(); + sound_cd_thread_reset(); + break; + + case IDM_CDROM_EMPTY: + id = item_params & 0x0007; + cdrom_eject(id); + break; + + case IDM_CDROM_RELOAD: + id = item_params & 0x0007; + cdrom_reload(id); + break; + + case IDM_CDROM_IMAGE: + id = item_params & 0x0007; + part = find_status_bar_part(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[id].image_path, 0)) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[id].image_path, temp_image_path) == 0) && (cdrom_drives[id].host_drive == 200)) + { + /* Switching from image to the same image. Do nothing. */ + break; + } + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + image_open(id, temp_image_path); + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_UNCHECKED); + } + cdrom_drives[id].host_drive = 200; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + update_tip(SB_CDROM | id); + saveconfig(); + } + break; + + case IDM_CDROM_HOST_DRIVE: + id = item_params & 0x0007; + letter = ((item_params >> 3) & 0x001f) + 'A'; + part = find_status_bar_part(SB_CDROM | id); + if ((part == -1) || (sb_menu_handles == NULL)) + { + break; + } + + new_cdrom_drive = letter; + if (cdrom_drives[id].host_drive == new_cdrom_drive) + { + /* Switching to the same drive. Do nothing. */ + break; + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + ioctl_open(id, new_cdrom_drive); /* Signal disc change to the emulated machine. */ - cdrom_insert(cdrom_id); - } - CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + cdrom_id, MF_UNCHECKED); - if ((cdrom_drives[cdrom_id].host_drive != 0) && (cdrom_drives[cdrom_id].host_drive != 200)) - { - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); - } - CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); - cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; - CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); - update_tip(0x10 | cdrom_id); - saveconfig(); - } - break; - } - return 0; + cdrom_insert(id); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_UNCHECKED); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_CDROM | id); + saveconfig(); + break; + + case IDM_RDISK_EJECT: + id = item_params & 0x001f; + removable_disk_eject(id); + break; + + case IDM_RDISK_RELOAD: + id = item_params & 0x001f; + removable_disk_reload(id); + break; + + case IDM_RDISK_SEND_CHANGE: + id = item_params & 0x001f; + scsi_disk_insert(id); + break; + + case IDM_RDISK_IMAGE: + case IDM_RDISK_IMAGE_WP: + id = item_params & 0x001f; + ret = file_dlg_w_st(hwnd, 2172, hdc[id].fn, id); + if (!ret) + { + removable_disk_unload(id); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + wcscpy(hdc[id].fn, wopenfilestring); + hdc[id].wp = (item_id == IDM_RDISK_IMAGE_WP) ? 1 : 0; + scsi_loadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id); + scsi_disk_insert(id); + if (wcslen(hdc[id].fn) > 0) + { + update_status_bar_icon_state(SB_RDISK | id, 0); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_ENABLED); + } + else + { + update_status_bar_icon_state(SB_RDISK | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); + } + update_tip(SB_RDISK | id); + saveconfig(); + } + break; + + default: + break; + } + return 0; case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: - GetClientRect(hwnd, (LPRECT)& rc); - pt.x = GET_X_LPARAM(lParam); - pt.y = GET_Y_LPARAM(lParam); - if (PtInRect((LPRECT) &rc, pt)) - { - HandlePopupMenu(hwnd, pt, (pt.x / sb_icon_width)); - } - break; + GetClientRect(hwnd, (LPRECT)& rc); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + if (PtInRect((LPRECT) &rc, pt)) + { + HandlePopupMenu(hwnd, pt, (pt.x / SB_ICON_WIDTH)); + } + break; default: - return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); - } - return 0; + return CallWindowProc((WNDPROC) OriginalStatusBarProcedure, hwnd, message, wParam, lParam); + } + return 0; } diff --git a/src/WIN/win.h b/src/WIN/win.h index 1d4feec57..f36b487e5 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -8,14 +8,15 @@ */ #ifndef BOX_WIN_H # define BOX_WIN_H + # ifndef NO_UNICODE # define UNICODE # endif # define BITMAP WINDOWS_BITMAP -//# ifdef _WIN32_WINNT -//# undef _WIN32_WINNT -//# define _WIN32_WINNT 0x0501 -//# endif +/* # ifdef _WIN32_WINNT + # undef _WIN32_WINNT + # define _WIN32_WINNT 0x0501 + # endif */ # include # undef BITMAP @@ -25,6 +26,14 @@ #define szStatusBarClassName L"86BoxStatusBar" +#define WM_RESETD3D WM_USER +#define WM_LEAVEFULLSCREEN WM_USER + 1 + +#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ + +#define SB_ICON_WIDTH 24 + + extern HINSTANCE hinstance; extern HWND ghwnd; extern HWND status_hwnd; @@ -37,6 +46,9 @@ extern WCHAR wopenfilestring[260]; extern int pause; +extern HMENU smenu; +extern HMENU *sb_menu_handles; + #ifdef __cplusplus extern "C" { @@ -66,6 +78,15 @@ extern void update_status_bar_panes(HWND hwnds); extern int fdd_type_to_icon(int type); extern void hard_disk_add_open(HWND hwnd, int is_existing); +extern int hard_disk_was_added(void); + +extern void get_registry_key_map(void); +extern void process_raw_input(LPARAM lParam, int infocus); + +extern int find_status_bar_part(int tag); + +extern void cdrom_close(uint8_t id); +extern void update_tip(int meaning); #ifdef __cplusplus } diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index c64dd3af7..1cfa026eb 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -42,7 +42,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id++; break; - + case CONFIG_SELECTION: val_int = config_get_int(config_device->name, config->name, config->default_int); @@ -58,6 +58,38 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + + case CONFIG_HEX16: + val_int = config_get_hex16(config_device->name, config->name, config->default_int); + + c = 0; + while (selection->description[0]) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); + if (val_int == selection->value) + SendMessage(h, CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; + + case CONFIG_HEX20: + val_int = config_get_hex20(config_device->name, config->name, config->default_int); + + c = 0; + while (selection->description[0]) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)selection->description); + if (val_int == selection->value) + SendMessage(h, CB_SETCURSEL, c, 0); + selection++; + c++; + } + + id += 2; + break; } config++; } @@ -89,7 +121,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id++; break; - + case CONFIG_SELECTION: val_int = config_get_int(config_device->name, config->name, config->default_int); @@ -103,6 +135,34 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + + case CONFIG_HEX16: + val_int = config_get_hex16(config_device->name, config->name, config->default_int); + + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; + + case CONFIG_HEX20: + val_int = config_get_hex20(config_device->name, config->name, config->default_int); + + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + for (; c > 0; c--) + selection++; + + if (val_int != selection->value) + changed = 1; + + id += 2; + break; } config++; } @@ -134,7 +194,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id++; break; - + case CONFIG_SELECTION: c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) @@ -143,6 +203,24 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + + case CONFIG_HEX16: + c = SendMessage(h, CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_hex16(config_device->name, config->name, selection->value); + + id += 2; + break; + + case CONFIG_HEX20: + c = SendMessage(h, CB_GETCURSEL, 0, 0); + for (; c > 0; c--) + selection++; + config_set_hex20(config_device->name, config->name, selection->value); + + id += 2; + break; } config++; } @@ -219,6 +297,8 @@ void deviceconfig_open(HWND hwnd, device_t *device) break; case CONFIG_SELECTION: + case CONFIG_HEX16: + case CONFIG_HEX20: /*Combo box*/ item = (DLGITEMTEMPLATE *)data; item->x = 70; diff --git a/src/WIN/win_iodev.c b/src/WIN/win_iodev.c new file mode 100644 index 000000000..a008aab8d --- /dev/null +++ b/src/WIN/win_iodev.c @@ -0,0 +1,171 @@ +#define UNICODE +#define _WIN32_WINNT 0x0501 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ibm.h" +#include "../device.h" +#include "../cdrom.h" +#include "../cdrom_image.h" +#include "../cdrom_ioctl.h" +#include "../cdrom_null.h" +#include "../scsi_disk.h" +#include "plat_iodev.h" +#include "resource.h" +#include "win.h" + +void cdrom_eject(uint8_t id) +{ + int part; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + if (cdrom_drives[id].host_drive == 0) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + cdrom_drives[id].handler->exit(id); + cdrom_close(id); + cdrom_null_open(id, 0); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drive << 3), MF_UNCHECKED); + } + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + cdrom_drives[id].host_drive=0; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED); + update_status_bar_icon_state(SB_CDROM | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); + update_tip(SB_CDROM | id); + saveconfig(); +} + +void cdrom_reload(uint8_t id) +{ + int part; + int new_cdrom_drive; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + if ((cdrom_drives[id].host_drive == cdrom_drives[id].prev_host_drive) || (cdrom_drives[id].prev_host_drive == 0) || (cdrom_drives[id].host_drive != 0)) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + cdrom_close(id); + if (cdrom_drives[id].prev_host_drive == 200) + { + image_open(id, cdrom_image[id].image_path); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + } + else + { + new_cdrom_drive = cdrom_drives[id].prev_host_drive; + ioctl_open(id, new_cdrom_drive); + if (cdrom_drives[id].bus_type) + { + /* Signal disc change to the emulated machine. */ + cdrom_insert(id); + } + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + } + update_status_bar_icon_state(SB_CDROM | id, 0); + EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_CDROM | id); + saveconfig(); +} + +void removable_disk_unload(uint8_t id) +{ + if (wcslen(hdc[id].fn) == 0) + { + /* Switch from empty to empty. Do nothing. */ + return; + } + scsi_unloadhd(hdc[id].scsi_id, hdc[id].scsi_lun, id); + scsi_disk_insert(id); +} + +void removable_disk_eject(uint8_t id) +{ + int part = 0; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + removable_disk_unload(id); + update_status_bar_icon_state(SB_RDISK | id, 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | MF_GRAYED); + update_tip(SB_RDISK | id); + saveconfig(); +} + +void removable_disk_reload(uint8_t id) +{ + int part = 0; + + part = find_status_bar_part(SB_CDROM | id); + + if ((part == -1) || (sb_menu_handles == NULL)) + { + return; + } + + if (wcslen(hdc[id].fn) != 0) + { + /* Attempting to reload while an image is already loaded. Do nothing. */ + return; + } + scsi_reloadhd(id); + /* scsi_disk_insert(id); */ + update_status_bar_icon_state(SB_RDISK | id, wcslen(hdc[id].fn) ? 0 : 1); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_EJECT | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED)); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(sb_menu_handles[part], IDM_RDISK_SEND_CHANGE | id, MF_BYCOMMAND | (wcslen(hdc[id].fn) ? MF_ENABLED : MF_GRAYED)); + update_tip(SB_RDISK | id); + saveconfig(); +} + diff --git a/src/WIN/win_keyboard.c b/src/WIN/win_keyboard.c new file mode 100644 index 000000000..89b4f6639 --- /dev/null +++ b/src/WIN/win_keyboard.c @@ -0,0 +1,195 @@ +#define UNICODE +#define _WIN32_WINNT 0x0501 +#define BITMAP WINDOWS_BITMAP +#include +#include +#undef BITMAP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../device.h" +#include "plat_keyboard.h" + +#include "win.h" + +#ifndef MAPVK_VK_TO_VSC +#define MAPVK_VK_TO_VSC 0 +#endif + +static uint16_t scancode_map[65536]; + +/* This is so we can disambiguate scan codes that would otherwise conflict and get + passed on incorrectly. */ +UINT16 convert_scan_code(UINT16 scan_code) +{ + switch (scan_code) + { + case 0xE001: + return 0xF001; + case 0xE002: + return 0xF002; + case 0xE0AA: + return 0xF003; + case 0xE005: + return 0xF005; + case 0xE006: + return 0xF006; + case 0xE007: + return 0xF007; + case 0xE071: + return 0xF008; + case 0xE072: + return 0xF009; + case 0xE07F: + return 0xF00A; + case 0xE0E1: + return 0xF00B; + case 0xE0EE: + return 0xF00C; + case 0xE0F1: + return 0xF00D; + case 0xE0FE: + return 0xF00E; + case 0xE0EF: + return 0xF00F; + + default: + return scan_code; + } +} + +void get_registry_key_map() +{ + WCHAR *keyName = L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layout"; + WCHAR *valueName = L"Scancode Map"; + unsigned char buf[32768]; + DWORD bufSize; + HKEY hKey; + int j; + UINT32 *bufEx2; + int scMapCount; + UINT16 *bufEx; + int scancode_unmapped; + int scancode_mapped; + + /* First, prepare the default scan code map list which is 1:1. + Remappings will be inserted directly into it. + 65536 bytes so scan codes fit in easily and it's easy to find what each maps too, + since each array element is a scan code and provides for E0, etc. ones too. */ + for (j = 0; j < 65536; j++) + scancode_map[j] = convert_scan_code(j); + + bufSize = 32768; + /* Get the scan code remappings from: + HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, 1, &hKey) == ERROR_SUCCESS) + { + if(RegQueryValueEx(hKey, valueName, NULL, NULL, buf, &bufSize) == ERROR_SUCCESS) + { + bufEx2 = (UINT32 *) buf; + scMapCount = bufEx2[2]; + if ((bufSize != 0) && (scMapCount != 0)) + { + bufEx = (UINT16 *) (buf + 12); + for (j = 0; j < scMapCount*2; j += 2) + { + /* Each scan code is 32-bit: 16 bits of remapped scan code, + and 16 bits of original scan code. */ + scancode_unmapped = bufEx[j + 1]; + scancode_mapped = bufEx[j]; + + scancode_mapped = convert_scan_code(scancode_mapped); + + /* Fixes scan code map logging. */ + scancode_map[scancode_unmapped] = scancode_mapped; + } + } + } + RegCloseKey(hKey); + } +} + +void process_raw_input(LPARAM lParam, int infocus) +{ + uint32_t ri_size = 0; + UINT size; + RAWINPUT *raw; + USHORT scancode; + + if (!infocus) + { + return; + } + + GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + + raw = malloc(size); + + if (raw == NULL) + { + return; + } + + /* Here we read the raw input data for the keyboard */ + ri_size = GetRawInputData((HRAWINPUT)(lParam), RID_INPUT, raw, &size, sizeof(RAWINPUTHEADER)); + + if(ri_size != size) + { + return; + } + + /* If the input is keyboard, we process it */ + if (raw->header.dwType == RIM_TYPEKEYBOARD) + { + RAWKEYBOARD rawKB = raw->data.keyboard; + scancode = rawKB.MakeCode; + + /* If it's not a scan code that starts with 0xE1 */ + if (!(rawKB.Flags & RI_KEY_E1)) + { + if (rawKB.Flags & RI_KEY_E0) + { + scancode |= (0xE0 << 8); + } + + /* Remap it according to the list from the Registry */ + scancode = scancode_map[scancode]; + + if ((scancode >> 8) == 0xF0) + { + scancode |= 0x100; /* Extended key code in disambiguated format */ + } + else if ((scancode >> 8) == 0xE0) + { + scancode |= 0x80; /* Normal extended key code */ + } + + /* If it's not 0 (therefore not 0xE1, 0xE2, etc), + then pass it on to the rawinputkey array */ + if (!(scancode & 0xf00)) + { + recv_key[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + } + } + else + { + if (rawKB.MakeCode == 0x1D) + { + scancode = 0xFF; + } + if (!(scancode & 0xf00)) + { + recv_key[scancode & 0x1ff] = !(rawKB.Flags & RI_KEY_BREAK); + } + } + } + + free(raw); +} \ No newline at end of file diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index 7159f46c4..d7e78ac14 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -21,8 +21,6 @@ LCID dwLanguage; uint32_t dwLangID, dwSubLangID; -#define STRINGS_NUM 157 /* FIXME: should be in resource.h !! --FvK */ - WCHAR lpResourceString[STRINGS_NUM][512]; char openfilestring[260]; diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc index f64b714a0..9a6f50e80 100644 --- a/src/WIN/win_mouse.cc +++ b/src/WIN/win_mouse.cc @@ -3,6 +3,7 @@ */ #define DIRECTINPUT_VERSION 0x0800 #include +#include #include "plat_mouse.h" #include "win.h" diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index db4f7da46..f586e6526 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -35,9 +35,6 @@ #include "resource.h" -#define WM_SAVESETTINGS 0x8888 /* 86Box-specific message, used to tell the child dialog to save the currently specified settings. */ - - /* Machine category */ static int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; @@ -62,7 +59,6 @@ static char temp_hdc_name[16]; /* Hard disks category */ static hard_disk_t temp_hdc[HDC_NUM]; -static wchar_t temp_hdd_fn[HDC_NUM][512]; /* Removable devices category */ static int temp_fdd_types[FDD_NUM]; @@ -134,10 +130,6 @@ static void win_settings_init(void) /* Hard disks category */ memcpy(temp_hdc, hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], hdd_fn[i], 1024); - } /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -199,10 +191,6 @@ static int win_settings_changed(void) /* Hard disks category */ i = i || memcmp(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (j = 0; j < HDC_NUM; j++) - { - i = i || memcmp(hdd_fn[j], temp_hdd_fn[j], 1024); - } /* Removable devices category */ for (j = 0; j < FDD_NUM; j++) @@ -298,10 +286,6 @@ static void win_settings_save(void) /* Hard disks category */ memcpy(hdc, temp_hdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(hdd_fn[i], temp_hdd_fn[i], 1024); - } /* Removable devices category */ for (i = 0; i < FDD_NUM; i++) @@ -687,11 +671,8 @@ static void recalc_vid_list(HWND hdlg) static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; - int c = 0; - int d = 0; LPTSTR lptsTemp; char *stransi; - char *s; int gfx = 0; switch (message) @@ -1499,7 +1480,6 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w int c = 0; int d = 0; LPTSTR lptsTemp; - device_t *scsi_dev; switch (message) { @@ -1652,13 +1632,17 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); - for (i = 0; i < 8; i += 2) + for (i = 0; i < 16; i += 2) { - hiconItem = LoadIcon(hinstance, (LPCWSTR) (176 + i)); + hiconItem = LoadIcon(hinstance, (LPCWSTR) (192 + i)); ImageList_AddIcon(hSmall, hiconItem); DestroyIcon(hiconItem); } + hiconItem = LoadIcon(hinstance, (LPCWSTR) 176); + ImageList_AddIcon(hSmall, hiconItem); + DestroyIcon(hiconItem); + ListView_SetImageList(hwndList, hSmall, LVSIL_SMALL); return TRUE; @@ -1666,8 +1650,6 @@ static BOOL win_settings_hard_disks_image_list_init(HWND hwndList) int next_free_id = 0; -wchar_t ifn[HDC_NUM][512]; - static void normalize_hd_list() { hard_disk_t ihdc[HDC_NUM]; @@ -1675,25 +1657,17 @@ static void normalize_hd_list() j = 0; memset(ihdc, 0, HDC_NUM * sizeof(hard_disk_t)); + for (i = 0; i < HDC_NUM; i++) { - memset(ifn[i], 0, 1024); - } - for (i = 0; i < HDC_NUM; i++) - { - if (temp_hdc[i].bus > 0) + if (temp_hdc[i].bus != HDD_BUS_DISABLED) { memcpy(&(ihdc[j]), &(temp_hdc[i]), sizeof(hard_disk_t)); - memcpy(ifn[j], temp_hdd_fn[i], 1024); j++; } } memcpy(temp_hdc, ihdc, HDC_NUM * sizeof(hard_disk_t)); - for (i = 0; i < HDC_NUM; i++) - { - memcpy(temp_hdd_fn[i], ifn[i], 1024); - } } int hdc_id_to_listview_index[HDC_NUM]; @@ -1734,6 +1708,11 @@ static void add_locations(HWND hdlg) { SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2165 + i)); } + for (i = 0; i < 2; i++) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2209 + i)); + } + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2202)); h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); for (i = 0; i < 8; i++) @@ -1800,10 +1779,11 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) { h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); bus = SendMessage(h, CB_GETCURSEL, 0, 0); + bus++; switch(bus) { - case 0: /* MFM/RLL */ + case HDD_BUS_MFM: /* MFM */ h = GetDlgItem(hdlg, 1799); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1813,8 +1793,28 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); break; - case 1: /* IDE (PIO-only) */ - case 2: /* IDE (PIO and DMA) */ + case HDD_BUS_RLL: /* RLL */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0); + break; + case HDD_BUS_XTIDE: /* XT IDE */ + h = GetDlgItem(hdlg, 1799); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + ShowWindow(h, SW_SHOW); + EnableWindow(h, TRUE); + SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.xtide_channel : temp_hdc[hdlv_current_sel].xtide_channel, 0); + break; + case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */ + case HDD_BUS_IDE_PIO_AND_DMA: /* IDE (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1824,7 +1824,8 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.ide_channel : temp_hdc[hdlv_current_sel].ide_channel, 0); break; - case 3: /* SCSI */ + case HDD_BUS_SCSI: /* SCSI */ + case HDD_BUS_SCSI_REMOVABLE: /* SCSI (removable) */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1872,6 +1873,8 @@ static void recalc_next_free_id(HWND hdlg) int i; int c_mfm = 0; + int c_rll = 0; + int c_xtide = 0; int c_ide_pio = 0; int c_ide_dma = 0; int c_scsi = 0; @@ -1881,19 +1884,31 @@ static void recalc_next_free_id(HWND hdlg) for (i = 0; i < HDC_NUM; i++) { - if (temp_hdc[i].bus == 1) + if (temp_hdc[i].bus == HDD_BUS_MFM) { c_mfm++; } - else if (temp_hdc[i].bus == 2) + else if (temp_hdc[i].bus == HDD_BUS_RLL) + { + c_rll++; + } + else if (temp_hdc[i].bus == HDD_BUS_XTIDE) + { + c_xtide++; + } + else if (temp_hdc[i].bus == HDD_BUS_IDE_PIO_ONLY) { c_ide_pio++; } - else if (temp_hdc[i].bus == 3) + else if (temp_hdc[i].bus == HDD_BUS_IDE_PIO_AND_DMA) { c_ide_dma++; } - else if (temp_hdc[i].bus == 4) + else if (temp_hdc[i].bus == HDD_BUS_SCSI) + { + c_scsi++; + } + else if (temp_hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) { c_scsi++; } @@ -1901,7 +1916,7 @@ static void recalc_next_free_id(HWND hdlg) for (i = 0; i < HDC_NUM; i++) { - if (temp_hdc[i].bus == 0) + if (temp_hdc[i].bus == HDD_BUS_DISABLED) { next_free_id = i; break; @@ -1912,7 +1927,7 @@ static void recalc_next_free_id(HWND hdlg) enable_add = enable_add || (next_free_id >= 0); /* pclog("Enable add: %i\n", enable_add); */ - enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); + enable_add = enable_add && ((c_mfm < MFM_NUM) || (c_rll < RLL_NUM) || (c_xtide < XTIDE_NUM) || (c_ide_pio < IDE_NUM) || (c_ide_dma < IDE_NUM) || (c_scsi < SCSI_NUM)); /* pclog("Enable add: %i\n", enable_add); */ h = GetDlgItem(hdlg, IDC_BUTTON_HDD_ADD_NEW); @@ -1964,25 +1979,34 @@ static void win_settings_hard_disks_update_item(HWND hwndList, int i, int column { switch(temp_hdc[i].bus) { - case 1: + case HDD_BUS_MFM: wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; - case 2: + case HDD_BUS_RLL: + wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); + break; + case HDD_BUS_XTIDE: + wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + break; + case HDD_BUS_IDE_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 3: + case HDD_BUS_IDE_PIO_AND_DMA: wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 4: + case HDD_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; + case HDD_BUS_SCSI_REMOVABLE: + wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; } lvI.pszText = szText; lvI.iImage = temp_hdc[i].bus - 1; } else if (column == 1) { - lvI.pszText = temp_hdd_fn[i]; + lvI.pszText = temp_hdc[i].fn; lvI.iImage = 0; } else if (column == 2) @@ -2039,18 +2063,27 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) lvI.iSubItem = 0; switch(temp_hdc[i].bus) { - case 1: + case HDD_BUS_MFM: wsprintf(szText, win_language_get_string_from_id(2156), temp_hdc[i].mfm_channel >> 1, temp_hdc[i].mfm_channel & 1); break; - case 2: + case HDD_BUS_RLL: + wsprintf(szText, win_language_get_string_from_id(2205), temp_hdc[i].rll_channel >> 1, temp_hdc[i].rll_channel & 1); + break; + case HDD_BUS_XTIDE: + wsprintf(szText, win_language_get_string_from_id(2206), temp_hdc[i].xtide_channel >> 1, temp_hdc[i].xtide_channel & 1); + break; + case HDD_BUS_IDE_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(2195), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 3: + case HDD_BUS_IDE_PIO_AND_DMA: wsprintf(szText, win_language_get_string_from_id(2157), temp_hdc[i].ide_channel >> 1, temp_hdc[i].ide_channel & 1); break; - case 4: + case HDD_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(2158), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); break; + case HDD_BUS_SCSI_REMOVABLE: + wsprintf(szText, win_language_get_string_from_id(2203), temp_hdc[i].scsi_id, temp_hdc[i].scsi_lun); + break; } lvI.pszText = szText; lvI.iItem = j; @@ -2062,7 +2095,7 @@ static BOOL win_settings_hard_disks_recalc_list(HWND hwndList) } lvI.iSubItem = 1; - lvI.pszText = temp_hdd_fn[i]; + lvI.pszText = temp_hdc[i].fn; lvI.iItem = j; lvI.iImage = 0; @@ -2210,6 +2243,8 @@ static void set_edit_box_contents(HWND hdlg, int id, uint64_t val) int hard_disk_added = 0; int max_spt = 63; +int max_hpc = 255; +int max_tracks = 266305; int no_update = 0; @@ -2270,13 +2305,13 @@ static void recalc_selection(HWND hdlg) SendMessage(h, CB_SETCURSEL, selection, 0); } +static int chs_enabled = 0; + static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; int64_t i = 0; - int bus; uint64_t temp; - WCHAR szText[256]; FILE *f; uint32_t sector_size = 512; uint32_t zero = 0; @@ -2287,13 +2322,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W switch (message) { case WM_INITDIALOG: - memset(hd_file_name, 0, 512); - - hdc_ptr = (existing & 2) ? hdc : temp_hdc; + memset(hd_file_name, 0, sizeof(hd_file_name)); if (existing & 2) { - next_free_id = (existing & 0xf0) >> 4; + next_free_id = (existing >> 3) & 0x1f; + hdc_ptr = &(hdc[next_free_id]); + } + else + { + hdc_ptr = &(temp_hdc[next_free_id]); } SetWindowText(hdlg, win_language_get_string_from_id((existing & 1) ? 2197 : 2196)); @@ -2320,19 +2358,64 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W EnableWindow(h, FALSE); h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); EnableWindow(h, FALSE); + chs_enabled = 0; + } + else + { + chs_enabled = 1; } add_locations(hdlg); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - SendMessage(h, CB_SETCURSEL, 1, 0); + if (existing & 2) + { + hdc_ptr->bus = HDD_BUS_SCSI_REMOVABLE; + max_spt = 99; + max_hpc = 255; + } + else + { + hdc_ptr->bus = HDD_BUS_IDE_PIO_ONLY; + max_spt = 63; + max_hpc = 16; + } + SendMessage(h, CB_SETCURSEL, hdc_ptr->bus, 0); + max_tracks = 266305; recalc_location_controls(hdlg, 1); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - SendMessage(h, CB_SETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - SendMessage(h, CB_SETCURSEL, 0, 0); + if (existing & 2) + { + /* We're functioning as a load image dialog for a removable SCSI hard disk, + called from win.c, so let's hide the bus selection as we should not + allow it at this point. */ + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, 1798); + ShowWindow(h, SW_HIDE); + + /* Disable and hide the SCSI ID and LUN combo boxes. */ + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + EnableWindow(h, FALSE); + ShowWindow(h, SW_HIDE); + + /* Set the file name edit box contents to our existing parameters. */ + h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) hdc[next_free_id].fn); + } + else + { + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + SendMessage(h, CB_SETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + SendMessage(h, CB_SETCURSEL, 0, 0); + } h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); EnableWindow(h, FALSE); no_update = 0; @@ -2342,47 +2425,77 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W switch (LOWORD(wParam)) { case IDOK: - if (wcslen(hd_file_name) == 0) + if (!(existing & 2)) { + h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); + hdc_ptr->bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + } + + /* Make sure no file name is allowed with removable SCSI hard disks. */ + if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE)) + { + hdc_ptr->bus = HDD_BUS_DISABLED; msgbox_error(hwndParentDialog, 2056); return TRUE; } + else if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE)) + { + /* Mark hard disk added but return empty - it will signify the disk was ejected. */ + hdc_ptr->spt = hdc_ptr->hpc = hdc_ptr->tracks = 0; + memset(hdc_ptr->fn, 0, sizeof(hdc_ptr->fn)); + + goto hd_add_ok_common; + } + + get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdc_ptr->spt)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdc_ptr->hpc)); + get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdc_ptr->tracks)); + spt = hdc_ptr->spt; + hpc = hdc_ptr->hpc; + tracks = hdc_ptr->tracks; - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &(hdc_ptr[next_free_id].spt)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, &(hdc_ptr[next_free_id].hpc)); - get_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, &(hdc_ptr[next_free_id].tracks)); - spt = hdc_ptr[next_free_id].spt; - hpc = hdc_ptr[next_free_id].hpc; - tracks = hdc_ptr[next_free_id].tracks; - h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdc_ptr[next_free_id].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - hdc_ptr[next_free_id].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); - hdc_ptr[next_free_id].scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); - hdc_ptr[next_free_id].scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); - hdc_ptr[next_free_id].ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); if (existing & 2) { -#if 0 - if (hdc[next_free_id].bus == 5) + if (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE) { - memset(prev_hdd_fn[next_free_id], 0, 1024); - memcpy(prev_hdd_fn[next_free_id], hdd_fn[next_free_id], (wcslen(hdd_fn[next_free_id]) << 1) + 2); + memset(hdc_ptr->prev_fn, 0, sizeof(hdc_ptr->prev_fn)); + wcscpy(hdc_ptr->prev_fn, hdc_ptr->fn); } -#endif - - memset(hdd_fn[next_free_id], 0, 1024); - memcpy(hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); } else { - memset(temp_hdd_fn[next_free_id], 0, 1024); - memcpy(temp_hdd_fn[next_free_id], hd_file_name, (wcslen(hd_file_name) << 1) + 2); + switch(hdc_ptr->bus) + { + case HDD_BUS_MFM: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdc_ptr->mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_RLL: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdc_ptr->rll_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_XTIDE: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); + hdc_ptr->xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL_IDE); + hdc_ptr->ide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + case HDD_BUS_SCSI: + case HDD_BUS_SCSI_REMOVABLE: + h = GetDlgItem(hdlg, IDC_COMBO_HD_ID); + hdc_ptr->scsi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_COMBO_HD_LUN); + hdc_ptr->scsi_lun = SendMessage(h, CB_GETCURSEL, 0, 0); + break; + } } + memset(hdc_ptr->fn, 0, sizeof(hdc_ptr->fn)); + wcscpy(hdc_ptr->fn, hd_file_name); + sector_size = 512; if (!(existing & 1) && (wcslen(hd_file_name) > 0)) @@ -2442,27 +2555,24 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W msgbox_info(hwndParentDialog, 2059); } -#if 0 - if ((existing & 2) && (hdc[next_free_id].bus == 5)) - { - scsi_hd_insert(id); - update_status_bar_icon_state(0x20 | next_free_id, 0); - } -#endif - +hd_add_ok_common: hard_disk_added = 1; EndDialog(hdlg, 0); return TRUE; case IDCANCEL: hard_disk_added = 0; + if (!(existing & 2)) + { + hdc_ptr->bus = HDD_BUS_DISABLED; + } EndDialog(hdlg, 0); return TRUE; case IDC_CFILE: if (!file_dlg_w(hdlg, win_language_get_string_from_id(2172), L"", !(existing & 1))) { - if (!existing) + if (!(existing & 1)) { f = _wfopen(wopenfilestring, L"rb"); if (f != NULL) @@ -2478,6 +2588,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W f = _wfopen(wopenfilestring, (existing & 1) ? L"rb" : L"wb"); if (f == NULL) { +hdd_add_file_open_error: msgbox_error(hwndParentDialog, (existing & 1) ? 2060 : 2057); return TRUE; } @@ -2532,6 +2643,10 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W tracks = ((size >> 9) / hpc) / spt; } + if ((spt > max_spt) || (hpc > max_hpc) || (tracks > max_tracks)) + { + goto hdd_add_file_open_error; + } no_update = 1; set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); @@ -2551,6 +2666,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); EnableWindow(h, TRUE); + chs_enabled = 1; + no_update = 0; } else @@ -2561,7 +2678,8 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W h = GetDlgItem(hdlg, IDC_EDIT_HD_FILE_NAME); SendMessage(h, WM_SETTEXT, 0, (LPARAM) wopenfilestring); - memcpy(hd_file_name, wopenfilestring, (wcslen(wopenfilestring) << 1) + 2); + memset(hd_file_name, 0, sizeof(hd_file_name)); + wcscpy(hd_file_name, wopenfilestring); return TRUE; @@ -2580,6 +2698,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2598,6 +2726,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); } + + if (hpc > max_hpc) + { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2616,6 +2754,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); recalc_selection(hdlg); } + + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2634,6 +2782,16 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); recalc_selection(hdlg); } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2671,6 +2829,34 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, size >> 20); } + + if (spt > max_spt) + { + spt = max_spt; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + + if (hpc > max_hpc) + { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; @@ -2683,17 +2869,114 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W no_update = 1; recalc_location_controls(hdlg, 1); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - bus = SendMessage(h, CB_GETCURSEL, 0, 0); - get_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, &spt); - max_spt = (bus == 2) ? 99 : 63; + hdc_ptr->bus = SendMessage(h,CB_GETCURSEL,0,0) + 1; + + switch(hdc_ptr->bus) + { + case HDD_BUS_DISABLED: + default: + max_spt = max_hpc = max_tracks = 0; + break; + case HDD_BUS_MFM: + max_spt = 17; + max_hpc = 15; + max_tracks = 1023; + break; + case HDD_BUS_RLL: + case HDD_BUS_XTIDE: + max_spt = 63; + max_hpc = 16; + max_tracks = 1023; + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + max_spt = 63; + max_hpc = 16; + max_tracks = 266305; + break; + case HDD_BUS_SCSI_REMOVABLE: + if (spt == 0) + { + spt = 63; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + } + if (hpc == 0) + { + hpc = 16; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + } + if (tracks == 0) + { + tracks = 1023; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + } + case HDD_BUS_SCSI: + max_spt = 99; + max_hpc = 255; + max_tracks = 266305; + break; + } + + if ((hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, TRUE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, TRUE); + } + else if ((hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE) && !chs_enabled) + { + h = GetDlgItem(hdlg, IDC_EDIT_HD_SPT); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_HPC); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_CYL); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_EDIT_HD_SIZE); + EnableWindow(h, FALSE); + h = GetDlgItem(hdlg, IDC_COMBO_HD_TYPE); + EnableWindow(h, FALSE); + } + if (spt > max_spt) { spt = max_spt; size = (tracks * hpc * spt) << 9; - set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, 17); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SPT, spt); set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); recalc_selection(hdlg); } + + if (hpc > max_hpc) + { + hpc = max_hpc; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_HPC, hpc); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + + if (tracks > max_tracks) + { + tracks = max_tracks; + size = (tracks * hpc * spt) << 9; + set_edit_box_contents(hdlg, IDC_EDIT_HD_CYL, tracks); + set_edit_box_contents(hdlg, IDC_EDIT_HD_SIZE, (size >> 20)); + recalc_selection(hdlg); + } + no_update = 0; break; } @@ -2704,6 +2987,11 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W return FALSE; } +int hard_disk_was_added(void) +{ + return hard_disk_added; +} + void hard_disk_add_open(HWND hwnd, int is_existing) { BOOL ret; @@ -2806,7 +3094,18 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_HD_CHANNEL); - temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_MFM) + { + temp_hdc[hdlv_current_sel].mfm_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + } + else if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_RLL) + { + temp_hdc[hdlv_current_sel].rll_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + } + else if (temp_hdc[hdlv_current_sel].bus == HDD_BUS_XTIDE) + { + temp_hdc[hdlv_current_sel].xtide_channel = SendMessage(h, CB_GETCURSEL, 0, 0); + } h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); ignore_change = 0; @@ -2879,8 +3178,8 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA return FALSE; case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd_fn[hdlv_current_sel], L"", 4); - temp_hdc[hdlv_current_sel].bus = 0; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ + memcpy(temp_hdc[hdlv_current_sel].fn, L"", 4); + temp_hdc[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ normalize_hd_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ ignore_change = 1; h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); @@ -2916,17 +3215,17 @@ static int combo_id_to_string_id(int combo_id) { switch (combo_id) { - case 0: /* Disabled */ + case CDROM_BUS_DISABLED: /* Disabled */ default: return 2151; break; - case 2: /* Atapi (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */ return 2189; break; - case 3: /* Atapi (PIA and DMA) */ + case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */ return 2190; break; - case 4: /* SCSI */ + case CDROM_BUS_SCSI: /* SCSI */ return 2168; break; } @@ -2936,17 +3235,17 @@ static int combo_id_to_format_string_id(int combo_id) { switch (combo_id) { - case 0: /* Disabled */ + case CDROM_BUS_DISABLED: /* Disabled */ default: return 2151; break; - case 2: /* Atapi (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* Atapi (PIO-only) */ return 2191; break; - case 3: /* Atapi (PIA and DMA) */ + case CDROM_BUS_ATAPI_PIO_AND_DMA: /* Atapi (PIA and DMA) */ return 2192; break; - case 4: /* SCSI */ + case CDROM_BUS_SCSI: /* SCSI */ return 2158; break; } @@ -2980,9 +3279,6 @@ static BOOL win_settings_cdrom_drives_image_list_init(HWND hwndList) HICON hiconItem; HIMAGELIST hSmall; - int i = 0; - int j = 0; - hSmall = ImageList_Create(GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), ILC_MASK | ILC_COLOR32, 1, 1); @@ -3044,9 +3340,7 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) { LVITEM lvI; int i = 0; - char s[256]; WCHAR szText[256]; - int bid = 0; int fsid = 0; lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; @@ -3058,32 +3352,30 @@ static BOOL win_settings_cdrom_drives_recalc_list(HWND hwndList) switch (temp_cdrom_drives[i].bus_type) { - case 0: + case CDROM_BUS_DISABLED: default: lvI.pszText = win_language_get_string_from_id(fsid); + lvI.iImage = 0; break; - case 2: - case 3: + case CDROM_BUS_ATAPI_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); lvI.pszText = szText; + lvI.iImage = 1; break; - case 4: + case CDROM_BUS_ATAPI_PIO_AND_DMA: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + lvI.iImage = 2; + break; + case CDROM_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); lvI.pszText = szText; + lvI.iImage = 3; break; } lvI.iItem = i; - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; } @@ -3202,9 +3494,7 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) { LVITEM lvI; - char s[256]; WCHAR szText[256]; - int bid; int fsid; lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; @@ -3217,30 +3507,28 @@ static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) switch (temp_cdrom_drives[i].bus_type) { - case 0: + case CDROM_BUS_DISABLED: default: lvI.pszText = win_language_get_string_from_id(fsid); + lvI.iImage = 0; break; - case 2: - case 3: + case CDROM_BUS_ATAPI_PIO_ONLY: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); lvI.pszText = szText; + lvI.iImage = 1; break; - case 4: + case CDROM_BUS_ATAPI_PIO_AND_DMA: + wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].ide_channel >> 1, temp_cdrom_drives[i].ide_channel & 1); + lvI.pszText = szText; + lvI.iImage = 2; + break; + case CDROM_BUS_SCSI: wsprintf(szText, win_language_get_string_from_id(fsid), temp_cdrom_drives[i].scsi_device_id, temp_cdrom_drives[i].scsi_device_lun); lvI.pszText = szText; + lvI.iImage = 3; break; } - if (temp_cdrom_drives[i].bus_type) - { - lvI.iImage = temp_cdrom_drives[i].bus_type - 1; - } - else - { - lvI.iImage = 0; - } - if (ListView_SetItem(hwndList, &lvI) == -1) { return; @@ -3256,9 +3544,12 @@ static void cdrom_add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = 1; i < 5; i++) + for (i = CDROM_BUS_DISABLED; i < CDROM_BUS_SCSI; i++) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI_PIO_ONLY)) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(combo_id_to_string_id(i))); + } } h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); @@ -3312,8 +3603,8 @@ static void cdrom_recalc_location_controls(HWND hdlg) switch(bus) { - case 2: /* ATAPI (PIO-only) */ - case 3: /* ATAPI (PIO and DMA) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* ATAPI (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_AND_DMA: /* ATAPI (PIO and DMA) */ h = GetDlgItem(hdlg, 1802); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3323,7 +3614,7 @@ static void cdrom_recalc_location_controls(HWND hdlg) EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); break; - case 4: /* SCSI */ + case CDROM_BUS_SCSI: /* SCSI */ h = GetDlgItem(hdlg, 1800); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3352,7 +3643,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message HWND h; int i = 0; int old_sel = 0; - int cid = 0; + int b = 0; WCHAR szText[256]; switch (message) @@ -3388,15 +3679,28 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message win_settings_cdrom_drives_recalc_list(h); ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); cdrom_add_locations(hdlg); + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + + switch (temp_cdrom_drives[cdlv_current_sel].bus_type) { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type - 1, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); + case CDROM_BUS_DISABLED: + default: + b = 0; + break; + case CDROM_BUS_ATAPI_PIO_ONLY: + b = 1; + break; + case CDROM_BUS_ATAPI_PIO_AND_DMA: + b = 2; + break; + case CDROM_BUS_SCSI: + b = 3; + break; } + + SendMessage(h, CB_SETCURSEL, b, 0); + cdrom_recalc_location_controls(hdlg); rd_ignore_change = 0; @@ -3446,15 +3750,28 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message return FALSE; } rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - if (temp_cdrom_drives[cdlv_current_sel].bus_type > 1) + + switch (temp_cdrom_drives[cdlv_current_sel].bus_type) { - SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].bus_type - 1, 0); - } - else - { - SendMessage(h, CB_SETCURSEL, 0, 0); + case CDROM_BUS_DISABLED: + default: + b = 0; + break; + case CDROM_BUS_ATAPI_PIO_ONLY: + b = 1; + break; + case CDROM_BUS_ATAPI_PIO_AND_DMA: + b = 2; + break; + case CDROM_BUS_SCSI: + b = 3; + break; } + + SendMessage(h, CB_SETCURSEL, b, 0); + cdrom_recalc_location_controls(hdlg); rd_ignore_change = 0; } @@ -3485,10 +3802,21 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - temp_cdrom_drives[cdlv_current_sel].bus_type = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; - if (temp_cdrom_drives[cdlv_current_sel].bus_type == 1) + b = SendMessage(h, CB_GETCURSEL, 0, 0); + switch (b) { - temp_cdrom_drives[cdlv_current_sel].bus_type = 0; + case 0: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_DISABLED; + break; + case 1: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_ATAPI_PIO_ONLY; + break; + case 2: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_ATAPI_PIO_AND_DMA; + break; + case 3: + temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_SCSI; + break; } cdrom_recalc_location_controls(hdlg); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); diff --git a/src/cdrom.c b/src/cdrom.c index 6540846ba..10c811f7d 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -13,6 +13,7 @@ #include "piix.h" #include "scsi.h" #include "timer.h" +#include "WIN/plat_iodev.h" /* Bits of 'status' */ #define ERR_STAT 0x01 @@ -732,7 +733,7 @@ int find_cdrom_for_channel(uint8_t channel) for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type < 4) && (cdrom_drives[i].ide_channel == channel)) + if (((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) && (cdrom_drives[i].ide_channel == channel)) { return i; } @@ -764,7 +765,7 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun) for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].bus_type == 4) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) + if ((cdrom_drives[i].bus_type == CDROM_BUS_SCSI) && (cdrom_drives[i].scsi_device_id == scsi_id) && (cdrom_drives[i].scsi_device_lun == scsi_lun)) { return i; } @@ -833,16 +834,16 @@ void cdrom_init(int id, int cdb_len_setting) cdrom[id].sense[0] = 0xf0; cdrom[id].sense[7] = 10; cdrom_drives[id].bus_mode = 0; - if (cdrom_drives[id].bus_type > 2) + if (cdrom_drives[id].bus_type > CDROM_BUS_ATAPI_PIO_AND_DMA) { cdrom_drives[id].bus_mode |= 2; } - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { cdrom_drives[id].bus_mode |= 1; } cdrom_log("CD-ROM %i: Bus type %i, bus mode %i\n", id, cdrom_drives[id].bus_type, cdrom_drives[id].bus_mode); - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { cdrom_set_signature(id); cdrom_drives[id].max_blocks_at_once = 1; @@ -1076,7 +1077,7 @@ int cdrom_mode_select_header(uint8_t id, uint8_t val) } else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 2)) { - if ((cdrom_drives[id].bus_type == 4) && (cdrom[id].current_page_len == 8)) + if ((cdrom_drives[id].bus_type == CDROM_BUS_SCSI) && (cdrom[id].current_page_len == 8)) { cdrom[id].block_descriptor_len |= ((uint16_t) val) << 8; cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); @@ -1084,7 +1085,7 @@ int cdrom_mode_select_header(uint8_t id, uint8_t val) } else if (cdrom[id].current_page_pos == (cdrom[id].current_page_len - 1)) { - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { cdrom[id].block_descriptor_len |= (uint16_t) val; cdrom_log("CD-ROM %i: Position: %02X, value: %02X, block descriptor length: %02X\n", id, cdrom[id].current_page_pos, val, cdrom[id].block_descriptor_len); @@ -1470,7 +1471,7 @@ static void cdrom_command_write_dma(uint8_t id) static int cdrom_request_length_is_zero(uint8_t id) { - if ((cdrom[id].request_length == 0) && (cdrom_drives[id].bus_type < 4)) + if ((cdrom[id].request_length == 0) && (cdrom_drives[id].bus_type < CDROM_BUS_SCSI)) { return 1; } @@ -1490,7 +1491,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al } if (cdrom_request_length_is_zero(id) || (len == 0) || (cdrom_current_mode(id) == 0)) { - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = 0; } @@ -1506,7 +1507,7 @@ static void cdrom_data_command_finish(uint8_t id, int len, int block_len, int al { if (direction == 0) { - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength = alloc_len; } @@ -2063,7 +2064,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) { int ready = 0; - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { if (((cdrom[id].request_length >> 5) & 7) != cdrom_drives[id].scsi_device_lun) { @@ -2075,20 +2076,20 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) if (!(cdrom_command_flags[cdb[0]] & IMPLEMENTED)) { - cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], (cdrom_drives[id].bus_type == 4) ? "SCSI" : ((cdrom_drives[id].bus_type == 3) ? "ATAPI PIO/DMA" : "ATAPI PIO")); + cdrom_log("CD-ROM %i: Attempting to execute unknown command %02X over %s\n", id, cdb[0], (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? "SCSI" : ((cdrom_drives[id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) ? "ATAPI PIO/DMA" : "ATAPI PIO")); cdrom_illegal_opcode(id); return 0; } - if ((cdrom_drives[id].bus_type < 4) && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) + if ((cdrom_drives[id].bus_type < CDROM_BUS_SCSI) && (cdrom_command_flags[cdb[0]] & SCSI_ONLY)) { cdrom_log("CD-ROM %i: Attempting to execute SCSI-only command %02X over ATAPI\n", id, cdb[0]); cdrom_illegal_opcode(id); return 0; } - if ((cdrom_drives[id].bus_type == 4) && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) + if ((cdrom_drives[id].bus_type == CDROM_BUS_SCSI) && (cdrom_command_flags[cdb[0]] & ATAPI_ONLY)) { cdrom_log("CD-ROM %i: Attempting to execute ATAPI-only command %02X over SCSI\n", id, cdb[0]); cdrom_illegal_opcode(id); @@ -2297,13 +2298,13 @@ void cdrom_command(uint8_t id, uint8_t *cdb) int ret; int real_pos; int track = 0; - char device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; - char device_identify_ex[14] = { '8', '6', 'B', '_', 'C', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; #if 0 int CdbLength; #endif - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { cdrom[id].status &= ~ERR_STAT; } @@ -2315,12 +2316,12 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].packet_len = 0; cdrom[id].request_pos = 0; - device_identify[6] = id + 0x30; + device_identify[7] = id + 0x30; - device_identify_ex[6] = id + 0x30; - device_identify_ex[9] = emulator_version[0]; - device_identify_ex[11] = emulator_version[2]; - device_identify_ex[12] = emulator_version[3]; + device_identify_ex[7] = id + 0x30; + device_identify_ex[10] = emulator_version[0]; + device_identify_ex[12] = emulator_version[2]; + device_identify_ex[13] = emulator_version[3]; cdrom[id].data_pos = 0; @@ -2501,7 +2502,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } max_len = cdrom[id].sector_len; - /* if (cdrom_drives[id].bus_type == 4) */ + /* if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) */ if (cdrom_current_mode(id) == 2) { cdrom[id].requested_blocks = max_len; @@ -2529,11 +2530,11 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdrom[id].all_blocks_total = cdrom[id].block_total; if (cdrom[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon(0x10 | id, 1); + update_status_bar_icon(SB_CDROM | id, 1); } else { - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); } return; @@ -2573,7 +2574,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) case GPCMD_MODE_SENSE_6: case GPCMD_MODE_SENSE_10: - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { block_desc = ((cdb[1] >> 3) & 1) ? 0 : 1; } @@ -3116,16 +3117,10 @@ void cdrom_command(uint8_t id, uint8_t *cdb) { cdrom_drives[id].handler->stop(id); } -#ifndef __unix - win_cdrom_eject(id); -#endif + cdrom_eject(id); break; case 3: /* Load the disc (close tray). */ -#ifndef __unix - win_cdrom_reload(id); -#else - cdrom_drives[id].handler->load(id); -#endif + cdrom_reload(id); break; } @@ -3197,8 +3192,8 @@ void cdrom_command(uint8_t id, uint8_t *cdb) memset(cdbufferb, 0, 8); cdbufferb[0] = 5; /*CD-ROM*/ cdbufferb[1] = 0x80; /*Removable*/ - cdbufferb[2] = (cdrom_drives[id].bus_type == 4) ? 0x02 : 0x00; /*SCSI-2 compliant*/ - cdbufferb[3] = (cdrom_drives[id].bus_type == 4) ? 0x02 : 0x21; + cdbufferb[2] = (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? 0x02 : 0x00; /*SCSI-2 compliant*/ + cdbufferb[3] = (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? 0x02 : 0x21; cdbufferb[4] = 31; ide_padstr8(cdbufferb + 8, 8, "86Box"); /* Vendor */ @@ -3352,7 +3347,7 @@ void cdrom_callback(uint8_t id) /* Callback for non-Read CD commands */ { int old_pos = 0; - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { cdrom_log("CD-ROM %i: Lowering IDE IRQ\n", id); ide_irq_lower(&(ide_drives[cdrom_drives[id].ide_channel])); @@ -3478,7 +3473,7 @@ int cdrom_read_from_dma(uint8_t id) int in_data_length = 0; - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { ret = cdrom_read_from_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } @@ -3492,7 +3487,7 @@ int cdrom_read_from_dma(uint8_t id) return 0; } - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { in_data_length = SCSIDevices[cdrom_drives[id].scsi_device_id][cdrom_drives[id].scsi_device_lun].InitLength; cdrom_log("CD-ROM %i: SCSI Input data length: %i\n", id, in_data_length); @@ -3598,7 +3593,7 @@ int cdrom_write_to_dma(uint8_t id) { int ret = 0; - if (cdrom_drives[id].bus_type == 4) + if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { ret = cdrom_write_to_scsi_dma(cdrom_drives[id].scsi_device_id, cdrom_drives[id].scsi_device_lun); } @@ -3617,7 +3612,7 @@ int cdrom_write_to_dma(uint8_t id) void cdrom_irq_raise(uint8_t id) { - if (cdrom_drives[id].bus_type < 4) + if (cdrom_drives[id].bus_type < CDROM_BUS_SCSI) { ide_irq_raise(&(ide_drives[cdrom_drives[id].ide_channel])); } @@ -3645,7 +3640,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].status = READY_STAT; cdrom[id].phase = 3; cdrom[id].packet_status = 0xFF; - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_OUT: @@ -3660,7 +3655,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_DATA_IN: @@ -3675,7 +3670,7 @@ void cdrom_phase_callback(uint8_t id) cdrom[id].packet_status = CDROM_PHASE_COMPLETE; cdrom[id].status = READY_STAT; cdrom[id].phase = 3; - update_status_bar_icon(0x10 | id, 0); + update_status_bar_icon(SB_CDROM | id, 0); cdrom_irq_raise(id); return; case CDROM_PHASE_ERROR: diff --git a/src/cdrom.h b/src/cdrom.h index 63470c36f..5e167fe35 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -237,6 +237,8 @@ void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_len void cdrom_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks); void cdrom_insert(uint8_t id); +int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); + #define cdrom_sense_error cdrom[id].sense[0] #define cdrom_sense_key cdrom[id].sense[2] #define cdrom_asc cdrom[id].sense[12] diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index 53223a775..eadd5541b 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -18,6 +18,11 @@ /* Modified for use with PCem by bit */ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include + #include #include #include @@ -46,8 +51,8 @@ using namespace std; CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { - file = new ifstream(filename, ios::in | ios::binary); - error = (file == NULL) || (file->fail()); + file = fopen64(filename, "rb"); + error = (file == NULL); } CDROM_Interface_Image::BinaryFile::~BinaryFile() @@ -57,17 +62,17 @@ CDROM_Interface_Image::BinaryFile::~BinaryFile() bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) { - file->seekg(seek, ios::beg); - file->read((char*)buffer, count); - return !(file->fail()); + uint64_t offs = 0; + offs = ftello64(file); + fseeko64(file, offs, SEEK_SET); + offs = fread(buffer, 1, count, file); + return (offs == count); } -int CDROM_Interface_Image::BinaryFile::getLength() +uint64_t CDROM_Interface_Image::BinaryFile::getLength() { - file->seekg(0, ios::end); - int length = (int)file->tellg(); - if (file->fail()) return -1; - return length; + fseeko64(file, 0, SEEK_END); + return ftello64(file); } CDROM_Interface_Image::CDROM_Interface_Image() @@ -286,7 +291,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) { Track track = {0, 0, 0, 0, 0, 0, false, NULL}; tracks.clear(); - int shift = 0; + uint64_t shift = 0; int currPregap = 0; int totalPregap = 0; int prestart = 0; @@ -405,7 +410,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) return true; } -bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap) { // frames between index 0(prestart) and 1(curr.start) must be skipped int skip; @@ -429,14 +434,14 @@ bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int // current track consumes data from the same file as the previous if (prev.file == curr.file) { curr.start += shift; - prev.length = curr.start + totalPregap - prev.start - skip; + prev.length = curr.start + ((uint64_t) totalPregap) - prev.start - ((uint64_t) skip); curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; totalPregap += currPregap; curr.start += totalPregap; // current track uses a different file as the previous track } else { - int tmp = prev.file->getLength() - prev.skip; - prev.length = tmp / prev.sectorSize; + uint64_t tmp = prev.file->getLength() - ((uint64_t) prev.skip); + prev.length = tmp / ((uint64_t) prev.sectorSize); if (tmp % prev.sectorSize != 0) prev.length++; // padding curr.start += prev.start + prev.length + currPregap; diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index 39ed79bed..b545269f5 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -104,7 +104,7 @@ private: class TrackFile { public: virtual bool read(Bit8u *buffer, int seek, int count) = 0; - virtual int getLength() = 0; + virtual uint64_t getLength() = 0; virtual ~TrackFile() { }; }; @@ -113,10 +113,10 @@ private: BinaryFile(const char *filename, bool &error); ~BinaryFile(); bool read(Bit8u *buffer, int seek, int count); - int getLength(); + uint64_t getLength(); private: BinaryFile(); - std::ifstream *file; + FILE *file; }; struct Track { @@ -163,7 +163,7 @@ static void CDAudioCallBack(Bitu len); bool GetCueKeyword(std::string &keyword, std::istream &in); bool GetCueFrame(int &frames, std::istream &in); bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + bool AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap); std::vector tracks; typedef std::vector::iterator track_it; diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 6c14bf2c2..c941315cd 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -935,6 +935,7 @@ static int image_status(uint8_t id) void image_reset(uint8_t id) { + return; } void image_close(uint8_t id) diff --git a/src/config.c b/src/config.c index 26e65cfe6..4ac4837f1 100644 --- a/src/config.c +++ b/src/config.c @@ -6,6 +6,7 @@ #include #include #include + #include "cdrom.h" #include "config.h" #include "device.h" @@ -22,14 +23,15 @@ #include "network.h" #include "nvr.h" #include "scsi.h" -#include "plat_joystick.h" -#include "plat_midi.h" +#include "win/plat_joystick.h" +#include "win/plat_midi.h" #include "sound/snd_dbopl.h" #include "sound/snd_opl.h" #include "sound/sound.h" #include "video/video.h" -#include "win.h" -#include "win_language.h" + +#include "win/win.h" +#include "win/win_language.h" wchar_t config_file_default[256]; @@ -269,6 +271,26 @@ static entry_t *find_entry(section_t *section, char *name) } +static int entries_num(section_t *section) +{ + entry_t *current_entry; + int i = 0; + + current_entry = (entry_t *)section->entry_head.next; + + while (current_entry) + { + if (strlen(current_entry->name) > 0) + { + i++; + } + + current_entry = (entry_t *)current_entry->list.next; + } + return i; +} + + static section_t *create_section(char *name) { section_t *new_section = malloc(sizeof(section_t)); @@ -336,6 +358,50 @@ int config_get_hex16(char *head, char *name, int def) } +int config_get_hex20(char *head, char *name, int def) +{ + section_t *section; + entry_t *entry; + int value; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + sscanf(entry->data, "%05X", &value); + + return value; +} + + +int config_get_mac(char *head, char *name, int def) +{ + section_t *section; + entry_t *entry; + int val0 = 0, val1 = 0, val2 = 0; + + section = find_section(head); + + if (!section) + return def; + + entry = find_entry(section, name); + + if (!entry) + return def; + + sscanf(entry->data, "%02x:%02x:%02x", &val0, &val1, &val2); + + return (val0 << 16) + (val1 << 8) + val2; +} + + char *config_get_string(char *head, char *name, char *def) { section_t *section; @@ -374,6 +440,46 @@ wchar_t *config_get_wstring(char *head, char *name, wchar_t *def) } +void config_delete_var(char *head, char *name) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + return; + + entry = find_entry(section, name); + + if (!entry) + return; + + memset(entry->name, 0, strlen(entry->name)); + + return; +} + + +void config_delete_section_if_empty(char *head) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + return; + + if (entries_num(section) == 0) + { + memset(section->name, 0, strlen(section->name)); + } + + return; +} + + void config_set_int(char *head, char *name, int val) { section_t *section; @@ -414,6 +520,46 @@ void config_set_hex16(char *head, char *name, int val) } +void config_set_hex20(char *head, char *name, int val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + sprintf(entry->data, "%05X", val); + mbstowcs(entry->wdata, entry->data, 512); +} + + +void config_set_mac(char *head, char *name, int val) +{ + section_t *section; + entry_t *entry; + + section = find_section(head); + + if (!section) + section = create_section(head); + + entry = find_entry(section, name); + + if (!entry) + entry = create_entry(section, name); + + sprintf(entry->data, "%02x:%02x:%02x", (val >> 16) & 0xff, (val >> 8) & 0xff, val & 0xff); + mbstowcs(entry->wdata, entry->data, 512); +} + + void config_set_string(char *head, char *name, char *val) { section_t *section; @@ -575,16 +721,20 @@ void config_save(wchar_t *fn) while (current_entry) { - mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); - if (current_entry->wdata[0] == L'\0') + if(strlen(current_entry->name) > 0) { - fwprintf(f, L"%ws = \n", wname); + mbstowcs(wname, current_entry->name, strlen(current_entry->name) + 1); + if (current_entry->wdata[0] == L'\0') + { + fwprintf(f, L"%ws = \n", wname); + } + else + { + fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); + } + + fl++; } - else - { - fwprintf(f, L"%ws = %ws\n", wname, current_entry->wdata); - } - fl++; current_entry = (entry_t *)current_entry->list.next; } @@ -597,6 +747,8 @@ void config_save(wchar_t *fn) +static wchar_t *read_nvr_path; + /* General */ static void loadconfig_general(void) { @@ -622,35 +774,62 @@ static void loadconfig_general(void) vid_api = 1; } + config_delete_var(cat, "vid_api"); + video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); force_43 = !!config_get_int(cat, "force_43", 0); - scale = !!config_get_int(cat, "scale", 1); + scale = config_get_int(cat, "scale", 1); + if (scale > 3) + { + scale = 3; + } enable_overscan = !!config_get_int(cat, "enable_overscan", 0); - p = config_get_string(cat, "window_coordinates", NULL); - if (p == NULL) - p = "0, 0, 0, 0"; - sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); window_remember = config_get_int(cat, "window_remember", 0); + if (window_remember) + { + p = config_get_string(cat, "window_coordinates", NULL); + if (p == NULL) + p = "0, 0, 0, 0"; + sscanf(p, "%i, %i, %i, %i", &window_w, &window_h, &window_x, &window_y); + } + else + { + config_delete_var(cat, "window_remember"); + config_delete_var(cat, "window_coordinates"); + window_w = window_h = window_x = window_y = 0; + } + + if (read_nvr_path != NULL) + { + free(read_nvr_path); + read_nvr_path = NULL; + } + memset(nvr_path, 0x00, sizeof(nvr_path)); wp = config_get_wstring(cat, "nvr_path", L""); if (wp != NULL) { - if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); + if (wcslen(wp) && (wcslen(wp) <= 992)) + { + read_nvr_path = (wchar_t *) malloc((wcslen(wp) << 1) + 2); + wcscpy(read_nvr_path, wp); + wcscpy(nvr_path, wp); + } else { - append_filename_w(nvr_path, pcempath, L"nvr", 511); + append_filename_w(nvr_path, pcempath, L"nvr\\", 511); } } - else append_filename_w(nvr_path, pcempath, L"nvr", 511); + else append_filename_w(nvr_path, pcempath, L"nvr\\", 511); if (nvr_path[wcslen(nvr_path) - 1] != L'/') { if (nvr_path[wcslen(nvr_path) - 1] != L'\\') { - nvr_path[wcslen(nvr_path)] = L'/'; + nvr_path[wcslen(nvr_path)] = L'\\'; nvr_path[wcslen(nvr_path) + 1] = L'\0'; } } @@ -732,7 +911,7 @@ static void loadconfig_input_devices(void) else mouse_type = 0; - joystick_type = config_get_int(cat, "joystick_type", 0); + joystick_type = config_get_int(cat, "joystick_type", 7); for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) { @@ -767,6 +946,7 @@ static void loadconfig_input_devices(void) static void loadconfig_sound(void) { char *cat = "Sound"; + char temps[512]; char *p; p = config_get_string(cat, "sndcard", NULL); @@ -780,7 +960,21 @@ static void loadconfig_sound(void) SSI2001 = !!config_get_int(cat, "ssi2001", 0); GAMEBLASTER = !!config_get_int(cat, "gameblaster", 0); GUS = !!config_get_int(cat, "gus", 0); - opl3_type = !!config_get_int(cat, "opl3_type", 1); + + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "opl3_type", "dbopl"); + if (p != NULL) + { + strcpy(temps, p); + } + if (!strcmp(temps, "nukedopl")) + { + opl3_type = 1; + } + else + { + opl3_type = 0; + } } @@ -788,9 +982,28 @@ static void loadconfig_sound(void) static void loadconfig_network(void) { char *cat = "Network"; + char temps[512]; char *p; - network_type = config_get_int(cat, "net_type", NET_TYPE_NONE); + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "net_type", "none"); + if (p != NULL) + { + strcpy(temps, p); + } + if (!strcmp(temps, "slirp")) + { + network_type = NET_TYPE_SLIRP; + } + else if (!strcmp(temps, "pcap")) + { + network_type = NET_TYPE_PCAP; + } + else + { + network_type = NET_TYPE_NONE; + } + memset(network_pcap, '\0', sizeof(network_pcap)); p = config_get_string(cat, "net_pcap_device", "none"); if (p != NULL) @@ -863,63 +1076,99 @@ static int config_string_to_bus(char *str, int cdrom) { if (!strcmp(str, "none")) { - return 0; + return HDD_BUS_DISABLED; } if (!strcmp(str, "mfm")) { if (cdrom) goto no_mfm_cdrom; - return 1; + return HDD_BUS_MFM; } if (!strcmp(str, "rll")) { if (cdrom) goto no_mfm_cdrom; - return 1; + return HDD_BUS_RLL; } if (!strcmp(str, "esdi")) { if (cdrom) goto no_mfm_cdrom; - return 1; + return HDD_BUS_RLL; } if (!strcmp(str, "ide_pio_only")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "ide")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; + } + + if (!strcmp(str, "atapi_pio_only")) + { + return HDD_BUS_IDE_PIO_ONLY; + } + + if (!strcmp(str, "atapi")) + { + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "eide")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "xtide")) { - return 2; + return HDD_BUS_XTIDE; } if (!strcmp(str, "atide")) { - return 2; + return HDD_BUS_IDE_PIO_ONLY; } if (!strcmp(str, "ide_pio_and_dma")) { - return 3; + return HDD_BUS_IDE_PIO_AND_DMA; + } + + if (!strcmp(str, "atapi_pio_and_dma")) + { + return HDD_BUS_IDE_PIO_AND_DMA; } if (!strcmp(str, "scsi")) { - return 4; + return HDD_BUS_SCSI; + } + + if (!strcmp(str, "removable")) + { + if (cdrom) goto no_mfm_cdrom; + + return HDD_BUS_SCSI_REMOVABLE; + } + + if (!strcmp(str, "scsi_removable")) + { + if (cdrom) goto no_mfm_cdrom; + + return HDD_BUS_SCSI_REMOVABLE; + } + + if (!strcmp(str, "removable_scsi")) + { + if (cdrom) goto no_mfm_cdrom; + + return HDD_BUS_SCSI_REMOVABLE; } if (!strcmp(str, "usb")) @@ -936,6 +1185,27 @@ no_mfm_cdrom: } +static int hard_disk_is_valid(int c) +{ + if (hdc[c].bus == HDD_BUS_DISABLED) + { + return 0; + } + + if ((wcslen(hdc[c].fn) == 0) && (hdc[c].bus != HDD_BUS_SCSI_REMOVABLE)) + { + return 0; + } + + if ((hdc[c].tracks == 0) || (hdc[c].hpc == 0) || (hdc[c].spt == 0)) + { + return 0; + } + + return 1; +} + + /* Hard disks */ static void loadconfig_hard_disks(void) { @@ -946,6 +1216,8 @@ static void loadconfig_hard_disks(void) int c; char *p; wchar_t *wp; + int max_spt, max_hpc, max_tracks; + int board = 0, dev = 0; memset(temps, '\0', sizeof(temps)); for (c = 0; c < HDC_NUM; c++) @@ -953,56 +1225,162 @@ static void loadconfig_hard_disks(void) sprintf(temps, "hdd_%02i_parameters", c + 1); p = config_get_string(cat, temps, NULL); if (p == NULL) - p = "0, 0, 0, none"; - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); + p = "0, 0, 0, 0, none"; + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, &hdc[c].wp, s); hdc[c].bus = config_string_to_bus(s, 0); - if (hdc[c].spt > 99) + switch(hdc[c].bus) { - hdc[c].spt = 99; + case HDD_BUS_DISABLED: + default: + max_spt = max_hpc = max_tracks = 0; + break; + case HDD_BUS_MFM: + max_spt = 17; + max_hpc = 15; + max_tracks = 1023; + break; + case HDD_BUS_RLL: + case HDD_BUS_XTIDE: + max_spt = 63; + max_hpc = 16; + max_tracks = 1023; + break; + case HDD_BUS_IDE_PIO_ONLY: + case HDD_BUS_IDE_PIO_AND_DMA: + max_spt = 63; + max_hpc = 16; + max_tracks = 266305; + break; + case HDD_BUS_SCSI: + case HDD_BUS_SCSI_REMOVABLE: + max_spt = 99; + max_hpc = 255; + max_tracks = 266305; + break; } - if (hdc[c].hpc > 255) + + if (hdc[c].spt > max_spt) { - hdc[c].hpc = 255; + hdc[c].spt = max_spt; } - if (hdc[c].tracks > 266305) + if (hdc[c].hpc > max_hpc) { - hdc[c].tracks = 266305; + hdc[c].hpc = max_hpc; + } + if (hdc[c].tracks > max_tracks) + { + hdc[c].tracks = max_tracks; + } + + /* MFM */ + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + if (hdc[c].bus == HDD_BUS_MFM) + { + hdc[c].mfm_channel = !!config_get_int(cat, temps, c & 1); + } + else + { + config_delete_var(cat, temps); + } + + /* XT IDE */ + sprintf(temps, "hdd_%02i_xtide_channel", c + 1); + if (hdc[c].bus == HDD_BUS_XTIDE) + { + hdc[c].xtide_channel = !!config_get_int(cat, temps, c & 1); + } + else + { + config_delete_var(cat, temps); + } + + /* RLL (ESDI) */ + sprintf(temps, "hdd_%02i_rll_channel", c + 1); + if (hdc[c].bus == HDD_BUS_RLL) + { + hdc[c].rll_channel = !!config_get_int(cat, temps, c & 1); + } + else + { + config_delete_var(cat, temps); + } + + /* IDE */ + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + if ((hdc[c].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[c].bus == HDD_BUS_IDE_PIO_AND_DMA)) + { + sprintf(temps2, "%01u:%01u", c >> 1, c & 1); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%01u:%01u", &board, &dev); + + board &= 3; + dev %= 1; + hdc[c].ide_channel = (board << 1) + dev; + + if (hdc[c].ide_channel > 7) + { + hdc[c].ide_channel = 7; + } + } + else + { + config_delete_var(cat, temps); + } + + /* SCSI */ + sprintf(temps, "hdd_%02i_scsi_location", c + 1); + if ((hdc[c].bus == HDD_BUS_SCSI) || (hdc[c].bus == HDD_BUS_SCSI_REMOVABLE)) + { + sprintf(temps2, "%02u:%02u", c, 0); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); + + if (hdc[c].scsi_id > 15) + { + hdc[c].scsi_id = 15; + } + if (hdc[c].scsi_lun > 7) + { + hdc[c].scsi_lun = 7; + } + } + else + { + config_delete_var(cat, temps); + } + + memset(hdc[c].fn, 0, sizeof(hdc[c].fn)); + memset(hdc[c].prev_fn, 0, sizeof(hdc[c].prev_fn)); + sprintf(temps, "hdd_%02i_fn", c + 1); + wp = config_get_wstring(cat, temps, L""); + memcpy(hdc[c].fn, wp, (wcslen(wp) << 1) + 2); + + /* If the hard disk is in any way empty or invalid, mark the relevant variables for deletion. */ + if (!hard_disk_is_valid(c)) + { + sprintf(temps, "hdd_%02i_parameters", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_preide_channels", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_ide_channels", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_scsi_location", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "hdd_%02i_fn", c + 1); + config_delete_var(cat, temps); } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int(cat, temps, 0); - if (hdc[c].mfm_channel > 1) - { - hdc[c].mfm_channel = 1; - } + config_delete_var(cat, temps); sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int(cat, temps, 0); - if (hdc[c].ide_channel > 7) - { - hdc[c].ide_channel = 7; - } - - sprintf(temps, "hdd_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", c, 0); - p = config_get_string(cat, temps, temps2); - sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); - - if (hdc[c].scsi_id > 15) - { - hdc[c].scsi_id = 15; - } - if (hdc[c].scsi_lun > 7) - { - hdc[c].scsi_lun = 7; - } - - memset(hdd_fn[c], 0, 1024); - sprintf(temps, "hdd_%02i_fn", c + 1); - wp = config_get_wstring(cat, temps, L""); - memcpy(hdd_fn[c], wp, (wcslen(wp) << 1) + 2); + config_delete_var(cat, temps); } } @@ -1017,6 +1395,7 @@ static void loadconfig_removable_devices(void) int c; char *p; wchar_t *wp; + unsigned int board = 0, dev = 0; for (c = 0; c < FDD_NUM; c++) { @@ -1034,6 +1413,25 @@ static void loadconfig_removable_devices(void) printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); ui_writeprot[c] = !!config_get_int(cat, temps, 0); + + /* Check, whether each value is default, if yes, delete it so that only non-default values will later be saved. */ + if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_delete_var(cat, temps); + } + + if (wcslen(discfns[c]) == 0) + { + sprintf(temps, "fdd_%02i_fn", c + 1); + config_delete_var(cat, temps); + } + + if (ui_writeprot[c] == 0) + { + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_delete_var(cat, temps); + } } memset(temps, 0, 512); @@ -1057,29 +1455,77 @@ static void loadconfig_removable_devices(void) cdrom_drives[c].bus_type = config_string_to_bus(s, 1); sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int(cat, temps, c + 2); - if (cdrom_drives[c].ide_channel > 7) + if ((cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[c].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { - cdrom_drives[c].ide_channel = 7; + sprintf(temps2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &board, &dev); + + board &= 3; + dev %= 1; + cdrom_drives[c].ide_channel = (board << 1) + dev; + + if (cdrom_drives[c].ide_channel > 7) + { + cdrom_drives[c].ide_channel = 7; + } + } + else + { + config_delete_var(cat, temps); } sprintf(temps, "cdrom_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", c + 2, 0); - p = config_get_string(cat, temps, temps2); - sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); + if (cdrom_drives[c].bus_type == CDROM_BUS_SCSI) + { + sprintf(temps2, "%02u:%02u", c + 2, 0); + p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &cdrom_drives[c].scsi_device_id, &cdrom_drives[c].scsi_device_lun); - if (cdrom_drives[c].scsi_device_id > 15) - { - cdrom_drives[c].scsi_device_id = 15; + if (cdrom_drives[c].scsi_device_id > 15) + { + cdrom_drives[c].scsi_device_id = 15; + } + if (cdrom_drives[c].scsi_device_lun > 7) + { + cdrom_drives[c].scsi_device_lun = 7; + } } - if (cdrom_drives[c].scsi_device_lun > 7) + else { - cdrom_drives[c].scsi_device_lun = 7; + config_delete_var(cat, temps); } sprintf(temps, "cdrom_%02i_image_path", c + 1); wp = config_get_wstring(cat, temps, L""); memcpy(cdrom_image[c].image_path, wp, (wcslen(wp) << 1) + 2); + + if ((cdrom_drives[c].host_drive < 0x41) || ((cdrom_drives[c].host_drive == 0x200) && (wcslen(cdrom_image[c].image_path) == 0))) + { + cdrom_drives[c].host_drive = 0; + } + + /* If the CD-ROM is disabled, delete all its variables. */ + if (cdrom_drives[c].bus_type == CDROM_BUS_DISABLED) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_parameters", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_scsi_location", c + 1); + config_delete_var(cat, temps); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + config_delete_var(cat, temps); + } + + sprintf(temps, "cdrom_%02i_iso_path", c + 1); + config_delete_var(cat, temps); } } @@ -1144,32 +1590,107 @@ static void saveconfig_general(void) char temps[512]; config_set_int(cat, "vid_resize", vid_resize); - switch(vid_api) + if (vid_resize == 0) { - case 0: - config_set_string(cat, "vid_renderer", "ddraw"); - break; - case 1: - default: - config_set_string(cat, "vid_renderer", "d3d9"); - break; + config_delete_var(cat, "vid_resize"); } - config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); - config_set_int(cat, "force_43", force_43); - config_set_int(cat, "scale", scale); - config_set_int(cat, "enable_overscan", enable_overscan); + if (vid_api == 1) + { + config_delete_var(cat, "vid_renderer"); + } + else + { + switch(vid_api) + { + case 0: + config_set_string(cat, "vid_renderer", "ddraw"); + break; + case 1: + default: + config_set_string(cat, "vid_renderer", "d3d9"); + break; + } + } + + if (video_fullscreen_scale == 0) + { + config_delete_var(cat, "video_fullscreen_scale"); + } + else + { + config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); + } + + if (video_fullscreen_first == 1) + { + config_delete_var(cat, "video_fullscreen_first"); + } + else + { + config_set_int(cat, "video_fullscreen_first", video_fullscreen_first); + } + + if (force_43 == 0) + { + config_delete_var(cat, "force_43"); + } + else + { + config_set_int(cat, "force_43", force_43); + } + + if (scale == 1) + { + config_delete_var(cat, "scale"); + } + else + { + config_set_int(cat, "scale", scale); + } + + if (enable_overscan == 0) + { + config_delete_var(cat, "enable_overscan"); + } + else + { + config_set_int(cat, "enable_overscan", enable_overscan); + } - sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); - config_set_string(cat, "window_coordinates", temps); config_set_int(cat, "window_remember", window_remember); + if (window_remember) + { + sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); + config_set_string(cat, "window_coordinates", temps); + } + else + { + config_delete_var(cat, "window_remember"); + config_delete_var(cat, "window_coordinates"); + } - config_set_wstring(cat, "nvr_path", nvr_path); + if (read_nvr_path == NULL) + { + config_delete_var(cat, "nvr_path"); + } + else + { + config_set_wstring(cat, "nvr_path", nvr_path); + } #ifndef __unix - config_set_hex16(cat, "language", dwLanguage); + if (dwLanguage == 0x0409) + { + config_delete_var(cat, "language"); + } + else + { + config_set_hex16(cat, "language", dwLanguage); + } #endif + + config_delete_section_if_empty(cat); } @@ -1179,14 +1700,64 @@ static void saveconfig_machine(void) char *cat = "Machine"; config_set_string(cat, "model", model_get_internal_name()); - config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); - config_set_int(cat, "cpu", cpu); - config_set_int(cat, "cpu_waitstates", cpu_waitstates); - config_set_int(cat, "mem_size", mem_size); + if (cpu_manufacturer == 0) + { + config_delete_var(cat, "cpu_manufacturer"); + } + else + { + config_set_int(cat, "cpu_manufacturer", cpu_manufacturer); + } + + if (cpu == 0) + { + config_delete_var(cat, "cpu"); + } + else + { + config_set_int(cat, "cpu", cpu); + } + + if (cpu_waitstates == 0) + { + config_delete_var(cat, "cpu_waitstates"); + } + else + { + config_set_int(cat, "cpu_waitstates", cpu_waitstates); + } + + if (mem_size == 4096) + { + config_delete_var(cat, "mem_size"); + } + else + { + config_set_int(cat, "mem_size", mem_size); + } + config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); - config_set_int(cat, "enable_sync", enable_sync); + + if (enable_external_fpu == 0) + { + config_delete_var(cat, "cpu_enable_fpu"); + } + else + { + config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); + } + + if (enable_sync == 0) + { + config_delete_var(cat, "enable_sync"); + } + else + { + config_set_int(cat, "enable_sync", enable_sync); + } + + config_delete_section_if_empty(cat); } @@ -1196,8 +1767,26 @@ static void saveconfig_video(void) char *cat = "Video"; config_set_string(cat, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(cat, "video_speed", video_speed); - config_set_int(cat, "voodoo", voodoo_enabled); + + if (video_speed == 3) + { + config_delete_var(cat, "video_speed"); + } + else + { + config_set_int(cat, "video_speed", video_speed); + } + + if (voodoo_enabled == 0) + { + config_delete_var(cat, "voodoo"); + } + else + { + config_set_int(cat, "voodoo", voodoo_enabled); + } + + config_delete_section_if_empty(cat); } @@ -1211,33 +1800,71 @@ static void saveconfig_input_devices(void) config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type)); - config_set_int(cat, "joystick_type", joystick_type); + if ((joystick_type == 0) || (joystick_type == 7)) + { + if (joystick_type == 7) + { + config_delete_var(cat, "joystick_type"); + } + else + { + config_set_int(cat, "joystick_type", joystick_type); + } - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - sprintf(s, "joystick_%i_nr", c); - config_set_int(cat, s, joystick_state[c].plat_joystick_nr); + for (c = 0; c < 16; c++) + { + sprintf(s, "joystick_%i_nr", c); + config_delete_var(cat, s); - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int(cat, s, joystick_state[c].axis_mapping[d]); + for (d = 0; d < 16; d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_delete_var(cat, s); } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int(cat, s, joystick_state[c].button_mapping[d]); + for (d = 0; d < 16; d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_delete_var(cat, s); } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i", c, d); - sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); - config_set_string(cat, s, temps); - } - } - } + for (d = 0; d < 16; d++) + { + sprintf(s, "joystick_%i_pov_%i", c, d); + config_delete_var(cat, s); + } + } + } + else + { + config_set_int(cat, "joystick_type", joystick_type); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + config_set_int(cat, s, joystick_state[c].plat_joystick_nr); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int(cat, s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int(cat, s, joystick_state[c].button_mapping[d]); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i", c, d); + sprintf(temps, "%i, %i", joystick_state[c].pov_mapping[d][0], joystick_state[c].pov_mapping[d][1]); + config_set_string(cat, s, temps); + } + } + } + } + + config_delete_section_if_empty(cat); } @@ -1246,14 +1873,61 @@ static void saveconfig_sound(void) { char *cat = "Sound"; - config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); + if (sound_card_current == 0) + { + config_delete_var(cat, "sndcard"); + } + else + { + config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); + } - config_set_int(cat, "midi_host_device", midi_id); + if (midi_id == 0) + { + config_delete_var(cat, "midi_host_device"); + } + else + { + config_set_int(cat, "midi_host_device", midi_id); + } - config_set_int(cat, "gameblaster", GAMEBLASTER); - config_set_int(cat, "gus", GUS); - config_set_int(cat, "ssi2001", SSI2001); - config_set_int(cat, "opl3_type", opl3_type); + if (SSI2001 == 0) + { + config_delete_var(cat, "ssi2001"); + } + else + { + config_set_int(cat, "ssi2001", SSI2001); + } + + if (GAMEBLASTER == 0) + { + config_delete_var(cat, "gameblaster"); + } + else + { + config_set_int(cat, "gameblaster", GAMEBLASTER); + } + + if (GUS == 0) + { + config_delete_var(cat, "gus"); + } + else + { + config_set_int(cat, "gus", GUS); + } + + if (opl3_type == 0) + { + config_delete_var(cat, "opl3_type"); + } + else + { + config_set_string(cat, "opl3_type", (opl3_type == 1) ? "nukedopl" : "dbopl"); + } + + config_delete_section_if_empty(cat); } @@ -1262,16 +1936,42 @@ static void saveconfig_network(void) { char *cat = "Network"; - if (network_pcap[0] != '\0') + if (network_type == NET_TYPE_NONE) { - config_set_string(cat, "net_pcap_device", network_pcap); + config_delete_var(cat, "net_type"); } else { - config_set_string(cat, "net_pcap_device", "none"); + config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "pcap" : "slirp"); } - config_set_int(cat, "net_type", network_type); - config_set_string(cat, "net_card", network_card_get_internal_name(network_card)); + + if (network_pcap[0] != '\0') + { + if (!strcmp(network_pcap, "none")) + { + config_delete_var(cat, "net_pcap_device"); + } + else + { + config_set_string(cat, "net_pcap_device", network_pcap); + } + } + else + { + /* config_set_string(cat, "net_pcap_device", "none"); */ + config_delete_var(cat, "net_pcap_device"); + } + + if (network_card == 0) + { + config_delete_var(cat, "net_card"); + } + else + { + config_set_string(cat, "net_card", network_card_get_internal_name(network_card)); + } + + config_delete_section_if_empty(cat); } @@ -1281,47 +1981,111 @@ static void saveconfig_other_peripherals(void) char *cat = "Other peripherals"; char temps[512]; char temps2[512]; - int c, d; + int c; - config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + if (scsi_card_current == 0) + { + config_delete_var(cat, "scsicard"); + } + else + { + config_set_string(cat, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + } - config_set_string(cat, "hdd_controller", hdd_controller_name); + if (!strcmp(hdd_controller_name, "none")) + { + config_delete_var(cat, "hdd_controller"); + } + else + { + config_set_string(cat, "hdd_controller", hdd_controller_name); + } memset(temps, '\0', sizeof(temps)); for (c = 2; c < 4; c++) { sprintf(temps, "ide_%02i", c + 1); sprintf(temps2, "%i, %02i", !!ide_enable[c], ide_irq[c]); - config_set_string(cat, temps, temps2); + + if (ide_enable[c] == 0) + { + config_delete_var(cat, temps); + } + else + { + config_set_string(cat, temps, temps2); + } } - config_set_int(cat, "serial1_enabled", serial_enabled[0]); - config_set_int(cat, "serial2_enabled", serial_enabled[1]); - config_set_int(cat, "lpt_enabled", lpt_enabled); - config_set_int(cat, "bugger_enabled", bugger_enabled); + if (serial_enabled[0]) + { + config_delete_var(cat, "serial1_enabled"); + } + else + { + config_set_int(cat, "serial1_enabled", serial_enabled[0]); + } + + if (serial_enabled[1]) + { + config_delete_var(cat, "serial2_enabled"); + } + else + { + config_set_int(cat, "serial2_enabled", serial_enabled[1]); + } + + if (lpt_enabled) + { + config_delete_var(cat, "lpt_enabled"); + } + else + { + config_set_int(cat, "lpt_enabled", lpt_enabled); + } + + if (bugger_enabled == 0) + { + config_delete_var(cat, "bugger_enabled"); + } + else + { + config_set_int(cat, "bugger_enabled", bugger_enabled); + } + + config_delete_section_if_empty(cat); } -static char *config_bus_to_string(int bus) +static char *config_bus_to_string(int bus, int cdrom) { switch (bus) { - case 0: + case HDD_BUS_DISABLED: default: return "none"; break; - case 1: + case HDD_BUS_MFM: return "mfm"; break; - case 2: - return "ide_pio_only"; + case HDD_BUS_XTIDE: + return "xtide"; break; - case 3: - return "ide_pio_and_dma"; + case HDD_BUS_RLL: + return "rll"; break; - case 4: + case HDD_BUS_IDE_PIO_ONLY: + return cdrom ? "atapi_pio_only" : "ide_pio_only"; + break; + case HDD_BUS_IDE_PIO_AND_DMA: + return cdrom ? "atapi_pio_and_dma" : "ide_pio_and_dma"; + break; + case HDD_BUS_SCSI: return "scsi"; break; + case HDD_BUS_SCSI_REMOVABLE: + return "scsi_removable"; + break; } } @@ -1330,34 +2094,92 @@ static char *config_bus_to_string(int bus) static void saveconfig_hard_disks(void) { char *cat = "Hard disks"; - char temps[512]; - char temps2[512]; + char temps[24]; + char temps2[64]; char s[512]; - int c, d; + int c; char *p; - memset(temps, '\0', sizeof(temps)); + memset(temps, 0, sizeof(temps)); for (c = 0; c < HDC_NUM; c++) { sprintf(temps, "hdd_%02i_parameters", c + 1); - memset(s, '\0', sizeof(s)); - p = config_bus_to_string(hdc[c].bus); - sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, p); - config_set_string(cat, temps, temps2); + memset(s, 0, sizeof(s)); + if (!hard_disk_is_valid(c)) + { + config_delete_var(cat, temps); + } + else + { + p = config_bus_to_string(hdc[c].bus, 0); + sprintf(temps2, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", hdc[c].spt, hdc[c].hpc, hdc[c].tracks, hdc[c].wp, p); + config_set_string(cat, temps, temps2); + } sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int(cat, temps, hdc[c].mfm_channel); + if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_MFM)) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, hdc[c].mfm_channel); + } + + sprintf(temps, "hdd_%02i_xtide_channel", c + 1); + if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_XTIDE)) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, hdc[c].xtide_channel); + } + + sprintf(temps, "hdd_%02i_rll_channel", c + 1); + if (!hard_disk_is_valid(c) || (hdc[c].bus != HDD_BUS_RLL)) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, hdc[c].rll_channel); + } sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int(cat, temps, hdc[c].ide_channel); + if (!hard_disk_is_valid(c) || ((hdc[c].bus != HDD_BUS_IDE_PIO_ONLY) && (hdc[c].bus != HDD_BUS_IDE_PIO_AND_DMA))) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%01u:%01u", hdc[c].ide_channel >> 1, hdc[c].ide_channel & 1); + config_set_string(cat, temps, temps2); + } sprintf(temps, "hdd_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); - config_set_string(cat, temps, temps2); + if (!hard_disk_is_valid(c) || ((hdc[c].bus != HDD_BUS_SCSI) && (hdc[c].bus != HDD_BUS_SCSI_REMOVABLE))) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%02u:%02u", hdc[c].scsi_id, hdc[c].scsi_lun); + config_set_string(cat, temps, temps2); + } sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring(cat, temps, hdd_fn[c]); + if (!hard_disk_is_valid(c) || (wcslen(hdc[c].fn) == 0)) + { + config_delete_var(cat, temps); + } + else + { + config_set_wstring(cat, temps, hdc[c].fn); + } } + + config_delete_section_if_empty(cat); } @@ -1367,46 +2189,110 @@ static void saveconfig_removable_devices(void) char *cat = "Removable devices"; char temps[512]; char temps2[512]; - int c, d; + int c; memset(temps, '\0', sizeof(temps)); for (c = 0; c < FDD_NUM; c++) { sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string(cat, temps, fdd_get_internal_name(fdd_get_type(c))); + if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) + { + config_delete_var(cat, temps); + } + else + { + config_set_string(cat, temps, fdd_get_internal_name(fdd_get_type(c))); + } + sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring(cat, temps, discfns[c]); + if (wcslen(discfns[c]) == 0) + { + config_delete_var(cat, temps); + + ui_writeprot[c] = 0; + + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_delete_var(cat, temps); + } + else + { + config_set_wstring(cat, temps, discfns[c]); + } + sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int(cat, temps, ui_writeprot[c]); + if (ui_writeprot[c] == 0) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, ui_writeprot[c]); + } } memset(temps, '\0', sizeof(temps)); for (c = 0; c < CDROM_NUM; c++) { sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int(cat, temps, cdrom_drives[c].host_drive); + if ((cdrom_drives[c].bus_type == 0) || (cdrom_drives[c].host_drive < 'A') || ((cdrom_drives[c].host_drive > 'Z') && (cdrom_drives[c].host_drive != 200))) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, cdrom_drives[c].host_drive); + } sprintf(temps, "cdrom_%02i_parameters", c + 1); - sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type)); - config_set_string(cat, temps, temps2); + if (cdrom_drives[c].bus_type == 0) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%u, %s", cdrom_drives[c].sound_on, config_bus_to_string(cdrom_drives[c].bus_type, 1)); + config_set_string(cat, temps, temps2); + } sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int(cat, temps, cdrom_drives[c].ide_channel); + if ((cdrom_drives[c].bus_type != CDROM_BUS_ATAPI_PIO_ONLY) && (cdrom_drives[c].bus_type != CDROM_BUS_ATAPI_PIO_AND_DMA)) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%01u:%01u", cdrom_drives[c].ide_channel >> 1, cdrom_drives[c].ide_channel & 1); + config_set_string(cat, temps, temps2); + } sprintf(temps, "cdrom_%02i_scsi_location", c + 1); - sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); - config_set_string(cat, temps, temps2); + if (cdrom_drives[c].bus_type != CDROM_BUS_SCSI) + { + config_delete_var(cat, temps); + } + else + { + sprintf(temps2, "%02u:%02u", cdrom_drives[c].scsi_device_id, cdrom_drives[c].scsi_device_lun); + config_set_string(cat, temps, temps2); + } sprintf(temps, "cdrom_%02i_image_path", c + 1); - config_set_wstring(cat, temps, cdrom_image[c].image_path); + if ((cdrom_drives[c].bus_type == 0) || (wcslen(cdrom_image[c].image_path) == 0)) + { + config_delete_var(cat, temps); + } + else + { + config_set_wstring(cat, temps, cdrom_image[c].image_path); + } } + + config_delete_section_if_empty(cat); } void saveconfig(void) { - int c, d; - /* General */ saveconfig_general(); diff --git a/src/config.h b/src/config.h index fb33cd98d..c2b08da0b 100644 --- a/src/config.h +++ b/src/config.h @@ -11,9 +11,15 @@ extern "C" { #endif extern int config_get_int(char *head, char *name, int def); +extern int config_get_hex16(char *head, char *name, int def); +extern int config_get_hex20(char *head, char *name, int def); +extern int config_get_mac(char *head, char *name, int def); extern char *config_get_string(char *head, char *name, char *def); extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); extern void config_set_int(char *head, char *name, int val); +extern void config_set_hex16(char *head, char *name, int val); +extern void config_set_hex20(char *head, char *name, int val); +extern void config_set_mac(char *head, char *name, int val); extern void config_set_string(char *head, char *name, char *val); extern void config_set_wstring(char *head, char *name, wchar_t *val); diff --git a/src/device.c b/src/device.c index 5d92699c5..b706f99b9 100644 --- a/src/device.c +++ b/src/device.c @@ -145,6 +145,48 @@ int device_get_config_int_ex(char *s, int default_int) return default_int; } +int device_get_config_hex16(char *s) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_hex16(current_device->name, s, config->default_int); + + config++; + } + return 0; +} + +int device_get_config_hex20(char *s) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_hex20(current_device->name, s, config->default_int); + + config++; + } + return 0; +} + +int device_get_config_mac(char *s, int default_int) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + return config_get_mac(current_device->name, s, default_int); + + config++; + } + return default_int; +} + void device_set_config_int(char *s, int val) { device_config_t *config = current_device->config; @@ -162,6 +204,57 @@ void device_set_config_int(char *s, int val) return; } +void device_set_config_hex16(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_hex16(current_device->name, s, val); + return; + } + + config++; + } + return; +} + +void device_set_config_hex20(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_hex20(current_device->name, s, val); + return; + } + + config++; + } + return; +} + +void device_set_config_mac(char *s, int val) +{ + device_config_t *config = current_device->config; + + while (config->type != -1) + { + if (!strcmp(s, config->name)) + { + config_set_mac(current_device->name, s, val); + return; + } + + config++; + } + return; +} + char *device_get_config_string(char *s) { device_config_t *config = current_device->config; diff --git a/src/device.h b/src/device.h index 172c5c69b..7ad34630e 100644 --- a/src/device.h +++ b/src/device.h @@ -2,7 +2,9 @@ #define CONFIG_INT 1 #define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 -#define CONFIG_MAC 4 +#define CONFIG_HEX16 4 +#define CONFIG_HEX20 5 +#define CONFIG_MAC 6 typedef struct device_config_selection_t { @@ -43,7 +45,13 @@ char *device_add_status_info(char *s, int max_len); int device_get_config_int(char *name); int device_get_config_int_ex(char *s, int default_int); +int device_get_config_hex16(char *name); +int device_get_config_hex20(char *name); +int device_get_config_mac(char *name, int default_int); void device_set_config_int(char *s, int val); +void device_set_config_hex16(char *s, int val); +void device_set_config_hex20(char *s, int val); +void device_set_config_mac(char *s, int val); char *device_get_config_string(char *name); enum diff --git a/src/disc.c b/src/disc.c index ad7459fe2..74c779296 100644 --- a/src/disc.c +++ b/src/disc.c @@ -130,7 +130,7 @@ void disc_load(int drive, wchar_t *fn) pclog_w(L"Couldn't load %s %s\n",fn,p); drive_empty[drive] = 1; fdd_set_head(real_drive(drive), 0); - discfns[drive][0] = L'\0'; + memset(discfns[drive], 0, sizeof(discfns[drive])); update_status_bar_icon_state(drive, 1); } diff --git a/src/fdc.c b/src/fdc.c index 7a640096b..6392d41ac 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -957,7 +957,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); readflash = 1; fdc.inread = 1; break; @@ -1003,7 +1003,7 @@ bad_command: disc_writesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.pos = 0; if (fdc.pcjr) fdc.stat = 0xb0; @@ -1036,7 +1036,7 @@ bad_command: disc_comparesector(fdc.drive, fdc.sector, fdc.params[1], fdc.head, fdc.rate, fdc.params[4]); disctime = 0; fdc.written = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.pos = 0; if (fdc.pcjr || !fdc.dma) { @@ -1080,7 +1080,7 @@ bad_command: fdc.stat = 0x50; } disctime = 0; - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.inread = 1; break; @@ -1437,7 +1437,7 @@ void fdc_poll_common_finish(int compare, int st5) fdc.res[9]=fdc.sector; fdc.res[10]=fdc.params[4]; fdc_log("Read/write finish (%02X %02X %02X %02X %02X %02X %02X)\n" , fdc.res[4], fdc.res[5], fdc.res[6], fdc.res[7], fdc.res[8], fdc.res[9], fdc.res[10]); - update_status_bar_icon(fdc.drive, 0); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 0); paramstogo=7; } @@ -1483,7 +1483,7 @@ void fdc_callback() return; case 2: /*Read track*/ - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); fdc.eot[fdc.drive]--; fdc.read_track_sector.id.r++; if (!fdc.eot[fdc.drive] || fdc.tc) @@ -1643,7 +1643,7 @@ void fdc_callback() { fdc.sector++; } - update_status_bar_icon(fdc.drive, 1); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); switch (discint) { case 5: @@ -1882,7 +1882,7 @@ void fdc_error(int st5, int st6) fdc.res[10]=0; break; } - update_status_bar_icon(fdc.drive, 0); + update_status_bar_icon(SB_FLOPPY | fdc.drive, 0); paramstogo=7; } @@ -1940,36 +1940,6 @@ int fdc_data(uint8_t data) } else { - if (fdc.tc) - { - fdc_log("FDC read: TC\n"); - return 0; - } - - if (dma_channel_write(2, data) & DMA_OVER) - { - fdc_log("FDC read: DMA over\n"); - fdc.tc = 1; - } - - if (!fdc.fifo) - { - fdc.data_ready = 1; - fdc.stat = 0xd0; - } - else - { - fdc_fifo_buf_advance(); - if (fdc.fifobufpos == 0) - { - /* We have wrapped around, means FIFO is over */ - fifo_count++; - fdc_log("%04X: FIFO wrap around (threshold == %02X), DRQ sent\n", fifo_count, fdc.tfifo); - fdc.data_ready = 1; - fdc.stat = 0xd0; - } - } -#if 0 result = dma_channel_write(2, data); if (fdc.tc) @@ -1998,7 +1968,6 @@ int fdc_data(uint8_t data) fdc.stat = 0xd0; } } -#endif } return 0; diff --git a/src/hdd.c b/src/hdd.c index f9491ec7a..694a42788 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -13,6 +13,8 @@ static device_t null_hdd_device; static int hdd_controller_current; +hard_disk_t hdc[HDC_NUM]; + static struct { char name[50]; diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index a6f5ce466..4772b2c48 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -433,7 +433,7 @@ static void esdi_callback(void *p) fatal("Read past end of drive\n"); fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); fread(esdi->data, 512, 1, drive->hdfile); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1); } while (esdi->data_pos < 256) { @@ -522,11 +522,11 @@ static void esdi_callback(void *p) fwrite(esdi->data, 512, 1, drive->hdfile); esdi->rba++; esdi->sector_pos++; - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1); esdi->data_pos = 0; } - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 0); esdi->status = STATUS_CMD_IN_PROGRESS; esdi->cmd_state = 2; @@ -848,11 +848,11 @@ static void *esdi_init() for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + if ((hdc[i].bus == HDD_BUS_RLL) && (hdc[i].rll_channel < RLL_NUM)) { - loadhd(esdi, i, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(esdi, i, hdc[i].rll_channel, hdc[i].fn); c++; - if (c >= MFM_NUM) break; + if (c >= RLL_NUM) break; } } diff --git a/src/ibm.h b/src/ibm.h index 8b4680fc0..4b01f1584 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -161,6 +161,15 @@ struct } cpu_state; #define cycles cpu_state._cycles + +uint32_t cpu_cur_status; + +#define CPU_STATUS_USE32 (1 << 0) +#define CPU_STATUS_STACK32 (1 << 1) +#define CPU_STATUS_FLATDS (1 << 2) +#define CPU_STATUS_FLATSS (1 << 3) + + #define cpu_rm cpu_state.rm_data.rm_mod_reg.rm #define cpu_mod cpu_state.rm_data.rm_mod_reg.mod #define cpu_reg cpu_state.rm_data.rm_mod_reg.reg @@ -550,7 +559,27 @@ int gated,speakval,speakon; wchar_t pcempath[512]; -/*Hard disc*/ +/*Hard disk*/ +enum +{ + HDD_BUS_DISABLED = 0, + HDD_BUS_MFM, + HDD_BUS_XTIDE, + HDD_BUS_RLL, + HDD_BUS_IDE_PIO_ONLY, + HDD_BUS_IDE_PIO_AND_DMA, + HDD_BUS_SCSI, + HDD_BUS_SCSI_REMOVABLE, + HDD_BUS_USB +}; + +#define HDC_NUM 30 +#define MFM_NUM 2 +#define RLL_NUM 2 +#define XTIDE_NUM 2 +#define IDE_NUM 8 +#define SCSI_NUM 16 /* Theoretically the controller can have at least 64 devices, or even 128 in case of a wide bus, but + let's not exaggerate with them - 16 ought to be enough for everyone. */ #pragma pack(push,1) typedef struct { @@ -558,69 +587,28 @@ typedef struct { uint64_t spt,hpc; /*Sectors per track, heads per cylinder*/ uint64_t tracks; int is_hdi; + int wp; uint32_t base; uint64_t at_spt,at_hpc; /*[Translation] Sectors per track, heads per cylinder*/ unsigned int bus; /* 0 = none, 1 = MFM/RLL, 2 = IDE, 3 = SCSI */ unsigned int mfm_channel; + unsigned int rll_channel; + unsigned int xtide_channel; unsigned int ide_channel; unsigned int scsi_id; unsigned int scsi_lun; + wchar_t fn[260]; + wchar_t prev_fn[260]; } hard_disk_t; #pragma pack(pop) -#pragma pack(push,1) -typedef struct { - /* Stuff for SCSI hard disks. */ - uint8_t cdb[16]; - uint8_t current_cdb[16]; - uint8_t max_cdb_len; - int requested_blocks; - int max_blocks_at_once; - uint16_t request_length; - int block_total; - int all_blocks_total; - uint32_t packet_len; - int packet_status; - uint8_t status; - uint8_t phase; - uint32_t pos; - int callback; - int total_read; - int unit_attention; - uint8_t sense[256]; - uint8_t previous_command; - uint8_t error; - uint16_t buffer[390144]; - uint32_t sector_pos; - uint32_t sector_len; - uint32_t last_sector; - uint32_t seek_pos; - int data_pos; - int old_len; - int cdb_len_setting; - int cdb_len; - int request_pos; - uint64_t base; - uint8_t hd_cdb[16]; -} scsi_hard_disk_t; -#pragma pack(pop) - -#define HDC_NUM 16 -#define IDE_NUM 8 -#define MFM_NUM 2 -#define SCSI_NUM 16 /* Theoretically the controller can have at least 64 devices, or even 128 in case of a wide bus, but - let's not exaggerate with them - 16 ought to be enough for everyone. */ - -hard_disk_t hdc[HDC_NUM]; -scsi_hard_disk_t shdc[HDC_NUM]; +extern hard_disk_t hdc[HDC_NUM]; FILE *shdf[HDC_NUM]; uint64_t hdt[128][3]; uint64_t hdt_mfm[128][3]; -extern wchar_t hdd_fn[HDC_NUM][512]; - int image_is_hdi(const wchar_t *s); int image_is_hdx(const wchar_t *s, int check_signature); @@ -629,7 +617,16 @@ int keybsenddelay; /*CD-ROM*/ -extern int idecallback[4]; +enum +{ + CDROM_BUS_DISABLED = 0, + CDROM_BUS_ATAPI_PIO_ONLY = 4, + CDROM_BUS_ATAPI_PIO_AND_DMA, + CDROM_BUS_SCSI, + CDROM_BUS_USB = 8 +}; + +extern int idecallback[5]; #define CD_STATUS_EMPTY 0 #define CD_STATUS_DATA_ONLY 1 @@ -776,3 +773,9 @@ extern void update_status_bar_icon(int tag, int active); extern void update_status_bar_icon_state(int tag, int state); extern void status_settextw(wchar_t *wstr); extern void status_settext(char *str); + +#define SB_FLOPPY 0x00 +#define SB_CDROM 0x10 +#define SB_RDISK 0x20 +#define SB_HDD 0x40 +#define SB_TEXT 0x50 diff --git a/src/ide.c b/src/ide.c index 1308fcf89..7f1000264 100644 --- a/src/ide.c +++ b/src/ide.c @@ -92,19 +92,17 @@ uint64_t hdt[128][3] = { { 306, 4, 17 }, { 615, 2, 17 }, { 306, 4, 26 }, { { 1930, 4, 62 }, { 967, 16, 31 }, { 1013, 10, 63 }, { 1218, 15, 36 }, { 654, 16, 63 }, { 659, 16, 63 }, { 702, 16, 63 }, { 1002, 13, 63 }, /* 112-119 */ { 854, 16, 63 }, { 987, 16, 63 }, { 995, 16, 63 }, { 1024, 16, 63 }, { 1036, 16, 63 }, { 1120, 16, 59 }, { 1054, 16, 63 }, { 0, 0, 0 } }; /* 119-127 */ -IDE ide_drives[IDE_NUM]; +IDE ide_drives[IDE_NUM + XTIDE_NUM]; IDE *ext_ide; -wchar_t hdd_fn[HDC_NUM][512]; - int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); void (*ide_bus_master_set_irq)(int channel); -int idecallback[4] = {0, 0, 0, 0}; +int idecallback[5] = {0, 0, 0, 0, 0}; -int cur_ide[4]; +int cur_ide[5]; int ide_do_log = 0; @@ -132,7 +130,7 @@ int ide_drive_is_cdrom(IDE *ide) } else { - if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type > 1) && (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type < 4)) + if ((cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[atapi_cdrom_drives[ide->channel]].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { return 1; } @@ -143,24 +141,18 @@ int ide_drive_is_cdrom(IDE *ide) } } -static char as[512]; - int image_is_hdi(const wchar_t *s) { - int i, len; - char ext[5] = { 0, 0, 0, 0, 0 }; - wcstombs(as, s, (wcslen(s) << 1) + 2); - len = strlen(as); - if ((len < 4) || (as[0] == '.')) + int len; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + char *ws = (char *) s; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) { return 0; } - memcpy(ext, as + len - 4, 4); - for (i = 0; i < 4; i++) - { - ext[i] = toupper(ext[i]); - } - if (strcmp(ext, ".HDI") == 0) + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcsicmp(ext, L".HDI") == 0) { return 1; } @@ -172,23 +164,19 @@ int image_is_hdi(const wchar_t *s) int image_is_hdx(const wchar_t *s, int check_signature) { - int i, len; + int len; FILE *f; uint64_t filelen; uint64_t signature; - char ext[5] = { 0, 0, 0, 0, 0 }; - wcstombs(as, s, (wcslen(s) << 1) + 2); - len = strlen(as); - if ((len < 4) || (as[0] == '.')) + char *ws = (char *) s; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) { return 0; } - memcpy(ext, as + len - 4, 4); - for (i = 0; i < 4; i++) - { - ext[i] = toupper(ext[i]); - } - if (strcmp(ext, ".HDX") == 0) + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcsicmp(ext, L".HDX") == 0) { if (check_signature) { @@ -226,7 +214,7 @@ int image_is_hdx(const wchar_t *s, int check_signature) } } -int ide_enable[4] = { 1, 1, 0, 0 }; +int ide_enable[5] = { 1, 1, 0, 0, 1 }; int ide_irq[4] = { 14, 15, 10, 11 }; void ide_irq_raise(IDE *ide) @@ -353,10 +341,13 @@ void ide_padstr8(uint8_t *buf, int buf_size, const char *src) static void ide_identify(IDE *ide) { uint32_t c, h, s; - char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; +#if 0 uint64_t full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); +#endif - device_identify[6] = ide->channel + 0x30; + device_identify[6] = (ide->hdc_num / 10) + 0x30; + device_identify[7] = (ide->hdc_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); memset(ide->buffer, 0, 512); @@ -382,7 +373,7 @@ static void ide_identify(IDE *ide) ide->buffer[21] = 512; /*Buffer size*/ ide->buffer[47] = 16; /*Max sectors on multiple transfer command*/ ide->buffer[48] = 1; /*Dword transfers supported*/ - if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) { ide->buffer[49] = (1 << 8); /* LBA and DMA supported */ } @@ -418,7 +409,7 @@ static void ide_identify(IDE *ide) ide->buffer[60] = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) & 0xFFFF; /* Total addressable sectors (LBA) */ ide->buffer[61] = ((hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt) >> 16) & 0x0FFF; } - if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == 3)) + if (PCI && (ide->board < 2) && (hdc[ide->hdc_num].bus == HDD_BUS_IDE_PIO_AND_DMA)) { ide->buffer[52] = 2 << 8; /*DMA timing mode*/ @@ -436,13 +427,13 @@ static void ide_identify(IDE *ide) */ static void ide_atapi_identify(IDE *ide) { - char device_identify[8] = { '8', '6', 'B', '_', 'C', 'D', '0', 0 }; + char device_identify[9] = { '8', '6', 'B', '_', 'C', 'D', '0', '0', 0 }; uint8_t cdrom_id; memset(ide->buffer, 0, 512); cdrom_id = atapi_cdrom_drives[ide->channel]; - device_identify[6] = cdrom_id + 0x30; + device_identify[7] = cdrom_id + 0x30; ide_log("ATAPI Identify: %s\n", device_identify); ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ @@ -451,7 +442,7 @@ static void ide_atapi_identify(IDE *ide) ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[49] = 0x200; /* LBA supported */ - if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_mode & 2)) + if (PCI && (ide->board < 2) && (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA)) { ide->buffer[48] = 1; /*Dword transfers supported*/ ide->buffer[49] |= 0x100; /* DMA supported */ @@ -518,7 +509,7 @@ static void loadhd(IDE *ide, int d, const wchar_t *fn) if (ide->hdfile == NULL) { /* Try to open existing hard disk image */ - if (fn[0] == '.') + if (fn[0] == L'.') { ide->type = IDE_NONE; return; @@ -659,7 +650,7 @@ int ide_cdrom_is_pio_only(IDE *ide) { return 0; } - if (cdrom_drives[cdrom_id].bus_mode & 2) + if (cdrom_drives[cdrom_id].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA) { return 0; } @@ -703,7 +694,7 @@ static int ide_set_features(IDE *ide) break; case 0x04: /* Multiword DMA mode */ - if (!PCI || (hdc[ide->hdc_num].bus != 3) || (ide->board >= 2) || (submode > 2)) + if (!PCI || (hdc[ide->hdc_num].bus != HDD_BUS_IDE_PIO_AND_DMA) || (ide->board >= 2) || (submode > 2)) { return 0; } @@ -750,7 +741,7 @@ void resetide(void) build_atapi_cdrom_map(); /* Close hard disk image files (if previously open) */ - for (d = 0; d < IDE_NUM; d++) + for (d = 0; d < (IDE_NUM + XTIDE_NUM); d++) { ide_drives[d].channel = d; ide_drives[d].type = IDE_NONE; @@ -774,12 +765,19 @@ void resetide(void) c = 0; for (d = 0; d < HDC_NUM; d++) { - if (((hdc[d].bus == 2) || (hdc[d].bus == 3)) && (hdc[d].ide_channel < IDE_NUM)) + if (((hdc[d].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[d].bus == HDD_BUS_IDE_PIO_AND_DMA)) && (hdc[d].ide_channel < IDE_NUM)) { pclog("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); - loadhd(&ide_drives[hdc[d].ide_channel], d, hdd_fn[d]); + loadhd(&ide_drives[hdc[d].ide_channel], d, hdc[d].fn); c++; - if (c >= IDE_NUM) break; + if (c >= (IDE_NUM + XTIDE_NUM)) break; + } + if ((hdc[d].bus == HDD_BUS_XTIDE) && (hdc[d].xtide_channel < XTIDE_NUM)) + { + pclog("Found XTIDE hard disk on channel %i\n", hdc[d].xtide_channel); + loadhd(&ide_drives[hdc[d].xtide_channel | 8], d, hdc[d].fn); + c++; + if (c >= (IDE_NUM + XTIDE_NUM)) break; } } @@ -800,7 +798,19 @@ void resetide(void) ide_drives[d].error = 1; } - for (d = 0; d < 4; d++) + for (d = 0; d < XTIDE_NUM; d++) + { + ide_set_signature(&ide_drives[d | 8]); + + if (ide_drives[d].type == IDE_HDD) + { + ide_drives[d].mdma_mode = 0; + } + + ide_drives[d].error = 1; + } + + for (d = 0; d < 5; d++) { cur_ide[d] = d << 1; } @@ -1399,7 +1409,7 @@ uint32_t ide_read_data(int ide_board, int length) } else { - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } } } @@ -1722,7 +1732,7 @@ void callbackide(int ide_board) ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); return; case WIN_READ_DMA: @@ -1756,12 +1766,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } } } @@ -1799,7 +1809,7 @@ void callbackide(int ide_board) ide->blockcount = 0; } - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); return; case WIN_WRITE: @@ -1822,12 +1832,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } return; @@ -1863,12 +1873,12 @@ void callbackide(int ide_board) ide_next_sector(ide); ide->atastat = BUSY_STAT; idecallback[ide_board]=6*IDE_TIME; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } } } @@ -1899,12 +1909,12 @@ void callbackide(int ide_board) ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->pos=0; ide_next_sector(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); } else { ide->atastat = READY_STAT | DSC_STAT; - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 0); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 0); } return; @@ -1921,7 +1931,7 @@ void callbackide(int ide_board) ide->pos=0; ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); + update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); return; case WIN_FORMAT: @@ -1943,7 +1953,7 @@ void callbackide(int ide_board) ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); - /* update_status_bar_icon((hdc[ide->hdc_num].bus == 3) ? 0x32 : 0x31, 1); */ + /* update_status_bar_icon(SB_HDD | hdc[ide->hdc_num].bus, 1); */ return; case WIN_DRIVE_DIAGNOSTICS: @@ -2124,6 +2134,12 @@ void ide_callback_qua() callbackide(3); } +void ide_callback_xtide() +{ + idecallback[4] = 0; + callbackide(4); +} + void ide_write_pri(uint16_t addr, uint8_t val, void *priv) { writeide(0, addr, val); @@ -2355,6 +2371,13 @@ void ide_init() timer_add(ide_callback_sec, &idecallback[1], &idecallback[1], NULL); } +void ide_xtide_init() +{ + ide_bus_master_read = ide_bus_master_write = NULL; + + timer_add(ide_callback_xtide, &idecallback[4], &idecallback[4], NULL); +} + void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)) { ide_bus_master_read = read; diff --git a/src/ide.h b/src/ide.h index db8d52330..de63c9372 100644 --- a/src/ide.h +++ b/src/ide.h @@ -51,6 +51,7 @@ extern uint16_t readidew(int ide_board); extern void callbackide(int ide_board); extern void resetide(void); extern void ide_init(); +extern void ide_xtide_init(); extern void ide_ter_init(); extern void ide_qua_init(); extern void ide_pri_enable(); @@ -65,15 +66,15 @@ extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int trans extern int ideboard; -extern int ide_enable[4]; +extern int ide_enable[5]; extern int ide_irq[4]; -extern int idecallback[4]; +extern int idecallback[5]; void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); -IDE ide_drives[IDE_NUM]; +IDE ide_drives[IDE_NUM + XTIDE_NUM]; void ide_padstr8(uint8_t *buf, int buf_size, const char *src); diff --git a/src/mfm_at.c b/src/mfm_at.c index f0dd98ed1..b62fbbef0 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -439,7 +439,7 @@ uint16_t mfm_readw(uint16_t port, void *p) } else { - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); } } } @@ -505,7 +505,7 @@ void mfm_callback(void *p) mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; case CMD_WRITE: @@ -526,12 +526,12 @@ void mfm_callback(void *p) mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm->pos = 0; mfm_next_sector(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); } else { mfm->status = STAT_READY | STAT_DSC; - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); } break; @@ -540,7 +540,7 @@ void mfm_callback(void *p) mfm->pos = 0; mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; case CMD_FORMAT: @@ -560,7 +560,7 @@ void mfm_callback(void *p) } mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; case CMD_DIAGNOSE: @@ -596,9 +596,9 @@ void *mfm_init() c = 0; for (d = 0; d < HDC_NUM; d++) { - if ((hdc[d].bus == 1) && (hdc[d].mfm_channel < MFM_NUM)) + if ((hdc[d].bus == HDD_BUS_MFM) && (hdc[d].mfm_channel < MFM_NUM)) { - loadhd(mfm, hdc[d].mfm_channel, d, hdd_fn[d]); + loadhd(mfm, hdc[d].mfm_channel, d, hdc[d].fn); c++; if (c >= MFM_NUM) break; } diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index d7b80d831..b318c4de3 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -374,7 +374,7 @@ static void xebec_callback(void *p) xebec_complete(xebec); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); break; default: @@ -431,7 +431,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); } if (xebec->irq_dma_mask & DMA_ENA) xebec->callback = XEBEC_TIME; @@ -485,7 +485,7 @@ static void xebec_callback(void *p) fseeko64(drive->hdfile, addr * 512, SEEK_SET); fread(xebec->sector_buf, 512, 1, drive->hdfile); - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); xebec->state = STATE_SEND_DATA; @@ -500,7 +500,7 @@ static void xebec_callback(void *p) else { xebec_complete(xebec); - update_status_bar_icon(0x30, 0); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 0); } break; @@ -572,7 +572,7 @@ static void xebec_callback(void *p) fwrite(xebec->sector_buf, 512, 1, drive->hdfile); } - update_status_bar_icon(0x30, 1); + update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); xebec_next_sector(xebec); xebec->data_pos = 0; @@ -851,9 +851,9 @@ static void *xebec_init() for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + if ((hdc[i].bus == HDD_BUS_MFM) && (hdc[i].mfm_channel < MFM_NUM)) { - loadhd(xebec, i, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(xebec, i, hdc[i].mfm_channel, hdc[i].fn); c++; if (c > MFM_NUM) break; } @@ -914,9 +914,9 @@ static void *dtc_5150x_init() for (i = 0; i < HDC_NUM; i++) { - if ((hdc[i].bus == 1) && (hdc[i].mfm_channel < MFM_NUM)) + if ((hdc[i].bus == HDD_BUS_MFM) && (hdc[i].mfm_channel < MFM_NUM)) { - loadhd(xebec, i, hdc[i].mfm_channel, hdd_fn[i]); + loadhd(xebec, i, hdc[i].mfm_channel, hdc[i].fn); c++; if (c > MFM_NUM) break; } diff --git a/src/model.c b/src/model.c index 8b36ce114..b428c3628 100644 --- a/src/model.c +++ b/src/model.c @@ -544,16 +544,17 @@ void secondary_ide_check() for (i = 0; i < CDROM_NUM; i++) { - if ((cdrom_drives[i].ide_channel >= 2) && (cdrom_drives[i].ide_channel <= 3) && !cdrom_drives[i].bus_type) + if ((cdrom_drives[i].ide_channel >= 2) && (cdrom_drives[i].ide_channel <= 3) && ((cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_ONLY) || (cdrom_drives[i].bus_type == CDROM_BUS_ATAPI_PIO_AND_DMA))) { secondary_cdroms++; } - if (!secondary_cdroms) ide_sec_disable(); } + if (!secondary_cdroms) ide_sec_disable(); } void at_ali1429_init() { + ali1429_reset(); at_ide_init(); ali1429_init(); diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 47b5d52db..fee972934 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1906,13 +1906,13 @@ nic_init(int board) if (dev->is_pci) { dev->base_address = 0x340; } else { - dev->base_address = device_get_config_int("addr"); - dev->bios_addr = device_get_config_int("bios_addr"); + dev->base_address = device_get_config_hex16("base"); + dev->bios_addr = device_get_config_hex20("bios_addr"); } dev->base_irq = device_get_config_int("irq"); /* See if we have a local MAC address configured. */ - mac = device_get_config_int_ex("mac", -1); + mac = device_get_config_mac("mac", -1); /* Make this device known to the I/O system. */ nic_ioset(dev, dev->base_address); @@ -1984,7 +1984,7 @@ nic_init(int board) mac = (((int) dev->maclocal[3]) << 16); mac |= (((int) dev->maclocal[4]) << 8); mac |= ((int) dev->maclocal[5]); - device_set_config_int("mac", mac); + device_set_config_mac("mac", mac); } else { dev->maclocal[3] = (mac>>16) & 0xff; dev->maclocal[4] = (mac>>8) & 0xff; @@ -2065,7 +2065,7 @@ rtl8029as_init(void) static device_config_t ne1000_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x300, + "base", "Address", CONFIG_HEX16, "", 0x300, { { "0x280", 0x280 @@ -2111,7 +2111,7 @@ static device_config_t ne1000_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, { { "Disabled", 0x00000 @@ -2135,7 +2135,7 @@ static device_config_t ne1000_config[] = static device_config_t ne2000_config[] = { { - "addr", "Address", CONFIG_SELECTION, "", 0x300, + "base", "Address", CONFIG_HEX16, "", 0x300, { { "0x280", 0x280 @@ -2187,7 +2187,7 @@ static device_config_t ne2000_config[] = "mac", "MAC Address", CONFIG_MAC, "", -1 }, { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, { { "Disabled", 0x00000 @@ -2236,23 +2236,6 @@ static device_config_t rtl8029as_config[] = { "mac", "MAC Address", CONFIG_MAC, "", -1 }, - { - "bios_addr", "BIOS address", CONFIG_SELECTION, "", 0, - { - { - "Disabled", 0x00000 - }, - { - "D000", 0xD0000 - }, - { - "C000", 0xC0000 - }, - { - "" - } - }, - }, { "", "", -1 } diff --git a/src/network.c b/src/network.c index c4cd9c547..14c62fb95 100644 --- a/src/network.c +++ b/src/network.c @@ -101,7 +101,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); if (ret < 0) { - msgbox_error(ghwnd, 2202); + msgbox_error(ghwnd, 2219); network_type = NET_TYPE_NONE; } break; @@ -143,6 +143,8 @@ network_close(void) void network_reset(void) { + int i = 0; + pclog("NETWORK: reset (type=%d, card=%d)\n", network_type, network_card); /* Just in case.. */ @@ -151,6 +153,8 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; + i = network_pcap_init(&network_devs[network_ndev]); + pclog("NETWORK: set up for %s, card='%s'\n", (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", net_cards[network_card].name); diff --git a/src/pc.c b/src/pc.c index 66e0bb4ef..5d6dc4244 100644 --- a/src/pc.c +++ b/src/pc.c @@ -374,20 +374,17 @@ void initpc(int argc, wchar_t *argv[]) SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); } - if (cdrom_drives[i].host_drive == 0) + if (cdrom_drives[i].host_drive == 200) { - cdrom_null_open(i, cdrom_drives[i].host_drive); + image_open(i, cdrom_image[i].image_path); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_open(i, cdrom_drives[i].host_drive); } else { - if (cdrom_drives[i].host_drive == 200) - { - image_open(i, cdrom_image[i].image_path); - } - else - { - ioctl_open(i, cdrom_drives[i].host_drive); - } + cdrom_null_open(i, cdrom_drives[i].host_drive); } } @@ -412,7 +409,6 @@ void initpc(int argc, wchar_t *argv[]) scsi_card_init(); fullspeed(); - ali1429_reset(); shadowbios=0; for (i = 0; i < CDROM_NUM; i++) @@ -423,7 +419,7 @@ void initpc(int argc, wchar_t *argv[]) { image_reset(i); } - else + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) { ioctl_reset(i); } @@ -528,7 +524,6 @@ void resetpchard(void) loadnvr(); shadowbios = 0; - ali1429_reset(); keyboard_at_reset(); @@ -542,7 +537,7 @@ void resetpchard(void) { image_reset(i); } - else + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) { ioctl_reset(i); } @@ -689,10 +684,10 @@ void closepc(void) cdrom_drives[i].handler->exit(i); } dumppic(); - disc_close(0); - disc_close(1); - disc_close(2); - disc_close(3); + for (i = 0; i < FDD_NUM; i++) + { + disc_close(i); + } dumpregs(0); closevideo(); device_close_all(); diff --git a/src/scsi.h b/src/scsi.h index 2c9280c29..e07317a77 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -78,20 +78,26 @@ /* SCSI Additional Sense Codes */ #define ASC_AUDIO_PLAY_OPERATION 0x00 +#define ASC_NOT_READY 0x04 #define ASC_ILLEGAL_OPCODE 0x20 #define ASC_LBA_OUT_OF_RANGE 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 #define ASC_INV_LUN 0x25 #define ASC_INV_FIELD_IN_PARAMETER_LIST 0x26 +#define ASC_WRITE_PROTECTED 0x27 #define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 -#define ASC_INCOMPATIBLE_FORMAT 0x30 +#define ASC_CAPACITY_DATA_CHANGED 0x2A +#define ASC_INCOMPATIBLE_FORMAT 0x30 #define ASC_MEDIUM_NOT_PRESENT 0x3a #define ASC_DATA_PHASE_ERROR 0x4b #define ASC_ILLEGAL_MODE_FOR_THIS_TRACK 0x64 +#define ASCQ_UNIT_IN_PROCESS_OF_BECOMING_READY 0x01 +#define ASCQ_INITIALIZING_COMMAND_REQUIRED 0x02 +#define ASCQ_CAPACITY_DATA_CHANGED 0x09 #define ASCQ_AUDIO_PLAY_OPERATION_IN_PROGRESS 0x11 -#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 -#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 +#define ASCQ_AUDIO_PLAY_OPERATION_PAUSED 0x12 +#define ASCQ_AUDIO_PLAY_OPERATION_COMPLETED 0x13 /* Tell RISC OS that we have a 4x CD-ROM drive (600kb/sec data, 706kb/sec raw). Not that it means anything */ diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 7babc817a..f3c9bbbe2 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -35,6 +35,7 @@ #include "device.h" #include "cdrom.h" #include "scsi.h" +#include "scsi_disk.h" #include "scsi_aha154x.h" @@ -457,8 +458,6 @@ aha154x_eeprom(uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8_t *bufp) static uint8_t aha154x_memory(uint8_t cmd) { - uint8_t r = 0xff; - pclog("AHA154x: MEMORY cmd=%02x\n", cmd); if (cmd == 0x27) { @@ -599,29 +598,6 @@ typedef struct { } ReplyInquireSetupInformation; #pragma pack(pop) -/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */ -#pragma pack(push,1) -typedef struct { - uint8_t uBusType; - uint8_t uBiosAddress; - uint16_t u16ScatterGatherLimit; - uint8_t cMailbox; - uint32_t uMailboxAddressBase; - uint8_t uReserved1 :2, - fFastEISA :1, - uReserved2 :3, - fLevelSensitiveInterrupt:1, - uReserved3 :1; - uint8_t aFirmwareRevision[3]; - uint8_t fHostWideSCSI :1, - fHostDifferentialSCSI :1, - fHostSupportsSCAM :1, - fHostUltraSCSI :1, - fHostSmartTermination :1, - uReserved4 :3; -} ReplyInquireExtendedSetupInformation; -#pragma pack(pop) - #pragma pack(push,1) typedef struct { @@ -863,7 +839,7 @@ enum { }; -#ifdef xWALTJE +#ifdef WALTJE int aha_do_log = 1; # define ENABLE_AHA154X_LOG #else @@ -1355,39 +1331,15 @@ aha_readw(uint16_t port, void *priv) } -static uint32_t -aha_readl(uint16_t port, void *priv) -{ - return aha_read(port, priv); -} - - -/* This is BS - we just need a 'dev_present' indication.. --FvK */ -static int -aha_dev_present(uint8_t id, uint8_t lun) -{ - if (lun > 7) return(0); - - if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); - - if ((cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type == 4)) return(1); - - return(0); -} - - static void aha_write(uint16_t port, uint8_t val, void *priv) { int i = 0; uint8_t j = 0; aha_t *dev = (aha_t *)priv; - uint8_t max_id = 8; uint8_t Offset; MailboxInit_t *MailboxInit; ReplyInquireSetupInformation *ReplyISI; - ReplyInquireExtendedSetupInformation *ReplyIESI; - int cCharsToTransfer; pclog("AHA154X: Write Port 0x%02X, Value %02X\n", port, val); @@ -1745,13 +1697,6 @@ aha_writew(uint16_t Port, uint16_t Val, void *p) } -static void -aha_writeL(uint16_t Port, uint32_t Val, void *p) -{ - aha_write(Port, Val & 0xFF, p); -} - - static uint8_t ConvertSenseLength(uint8_t RequestSenseLength) { @@ -1824,6 +1769,8 @@ aha_disk_cmd(aha_t *dev) Lun = req->LUN; hdc_id = scsi_hard_disks[Id][Lun]; + if (hdc_id == 0xff) fatal("SCSI hard disk on %02i:%02i has disappeared\n", Id, Lun); + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", Id, Lun, hdc_id); @@ -1908,6 +1855,8 @@ aha_cdrom_cmd(aha_t *dev) Lun = req->LUN; cdrom_id = scsi_cdrom_drives[Id][Lun]; + if (cdrom_id == 0xff) fatal("SCSI CD-ROM on %02i:%02i has disappeared\n", Id, Lun); + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); @@ -2220,11 +2169,11 @@ aha_init(int chip, int has_bios) ResetDev = dev; dev->chip = chip; - dev->Base = device_get_config_int("addr"); + dev->Base = device_get_config_hex16("base"); dev->Irq = device_get_config_int("irq"); dev->DmaChannel = device_get_config_int("dma"); bios = device_get_config_int("bios"); - bios_addr = device_get_config_int("bios_addr"); + bios_addr = device_get_config_hex20("bios_addr"); if (dev->Base != 0) { io_sethandler(dev->Base, 4, @@ -2245,10 +2194,11 @@ aha_init(int chip, int has_bios) } } - for (i=0; i 7) return(0); - - if (scsi_cdrom_drives[id][lun] >= CDROM_NUM) return(0); - - if ((cdrom_drives[scsi_cdrom_drives[id][lun]].bus_type == 4)) return(1); - - return(0); -} - - static void BuslogicWriteW(uint16_t Port, uint16_t Val, void *p); static void BuslogicWriteL(uint16_t Port, uint32_t Val, void *p); static void @@ -1020,7 +1004,6 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) int i = 0; uint8_t j = 0; Buslogic_t *bl = (Buslogic_t *)p; - uint8_t max_id = (bl->chip >= CHIP_BUSLOGIC_ISA) ? 16 : 8; uint8_t Offset; MailboxInit_t *MailboxInit; ReplyInquireSetupInformation *ReplyISI; @@ -1130,8 +1113,6 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) break; case 0x01: -aha_0x01: - { bl->Mbx24bit = 1; MailboxInit = (MailboxInit_t *)bl->CmdBuf; @@ -1147,8 +1128,7 @@ aha_0x01: bl->Status &= ~STAT_INIT; bl->DataReplyLeft = 0; - } - break; + break; case 0x03: bl->DataBuf[0] = 0x00; @@ -1633,6 +1613,8 @@ BuslogicHDCommand(Buslogic_t *bl) Lun = req->LUN; hdc_id = scsi_hard_disks[Id][Lun]; + if (hdc_id == 0xff) fatal("SCSI hard disk on %02i:%02i has disappeared\n", Id, Lun); + pclog("SCSI HD command being executed on: SCSI ID %i, SCSI LUN %i, HD %i\n", Id, Lun, hdc_id); @@ -1717,6 +1699,8 @@ BuslogicCDROMCommand(Buslogic_t *bl) Lun = req->LUN; cdrom_id = scsi_cdrom_drives[Id][Lun]; + if (cdrom_id == 0xff) fatal("SCSI CD-ROM on %02i:%02i has disappeared\n", Id, Lun); + pclog("CD-ROM command being executed on: SCSI ID %i, SCSI LUN %i, CD-ROM %i\n", Id, Lun, cdrom_id); @@ -1913,7 +1897,7 @@ BuslogicProcessMailbox(Buslogic_t *bl) if (mb32.u.out.ActionCode != MBO_FREE) { /* We got the mailbox, mark it as free in the guest. */ - pclog("BuslogicStartMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); + pclog("BuslogicProcessMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); } @@ -2203,7 +2187,7 @@ BuslogicInit(int chip) chip = CHIP_BUSLOGIC_ISA; } bl->chip = chip; - bl->Base = device_get_config_int("addr"); + bl->Base = device_get_config_hex16("addr"); bl->PCIBase = 0; bl->MMIOBase = 0; bl->Irq = device_get_config_int("irq"); @@ -2233,14 +2217,16 @@ BuslogicInit(int chip) if (scsi_hard_disks[i][j] != 0xff) { SCSIDevices[i][j].LunType = SCSI_DISK; + pclog("Found SCSI disk: %02i:%02i\n", i, j); } } } - for (i=0; i> 9) - 1; + shdc[id].last_sector = 0; shdc[id].cdb_len = 12; } + + scsi_disk_insert(id); + + s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + + goto prepare_new_hard_disk; } else { /* Failed for another reason */ - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + scsi_hd_log("Failed for another reason\n"); + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + } return; } } @@ -272,41 +336,334 @@ static void scsi_loadhd(int scsi_id, int scsi_lun, int id) { fseeko64(shdf[id], 0x8, SEEK_SET); fread(&(shdc[id].base), 1, 4, shdf[id]); + fseeko64(shdf[id], 0xC, SEEK_SET); + full_size = 0; + fread(&full_size, 1, 4, shdf[id]); fseeko64(shdf[id], 0x10, SEEK_SET); fread(§or_size, 1, 4, shdf[id]); if (sector_size != 512) { /* Sector size is not 512 */ + scsi_hd_log("HDI: Sector size is not 512\n"); fclose(shdf[id]); - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + } return; } - fread(&(hdc[id].spt), 1, 4, shdf[id]); - fread(&(hdc[id].hpc), 1, 4, shdf[id]); - fread(&(hdc[id].tracks), 1, 4, shdf[id]); + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_load_error; + } + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; } else if (image_is_hdx(fn, 1)) { shdc[id].base = 0x28; + fseeko64(shdf[id], 8, SEEK_SET); + fread(&full_size, 1, 8, shdf[id]); fseeko64(shdf[id], 0x10, SEEK_SET); fread(§or_size, 1, 4, shdf[id]); if (sector_size != 512) { /* Sector size is not 512 */ + scsi_hd_log("HDX: Sector size is not 512\n"); fclose(shdf[id]); - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) + { + scsi_hard_disks[scsi_id][scsi_lun] = 0xff; + } + else + { + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + } return; } - fread(&(hdc[id].spt), 1, 4, shdf[id]); - fread(&(hdc[id].hpc), 1, 4, shdf[id]); - fread(&(hdc[id].tracks), 1, 4, shdf[id]); + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_load_error; + } + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; fread(&(hdc[id].at_spt), 1, 4, shdf[id]); fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); } - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + else + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + } shdc[id].cdb_len = 12; + scsi_disk_insert(id); } + + fseeko64(shdf[id], 0, SEEK_END); + if (ftello64(shdf[id]) != (full_size + shdc[id].base)) + { + s = (full_size + shdc[id].base) - ftello64(shdf[id]); +prepare_new_hard_disk: + s >>= 9; + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } + } + + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + + fclose(shdf[id]); +} + +void scsi_reloadhd(int id) +{ + uint32_t sector_size = 512; + uint32_t zero = 0; + uint64_t signature = 0xD778A82044445459ll; + uint64_t full_size = 0; + uint64_t spt = 0, hpc = 0, tracks = 0; + int c; + uint64_t i = 0, s = 0;; + wchar_t *fn = hdc[id].fn; + + memset(empty_sector, 0, sizeof(empty_sector)); + + if(hdc[id].prev_fn == NULL) + { + return; + } + else + { + wcscpy(hdc[id].fn, hdc[id].prev_fn); + memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + } + + shdc[id].base = 0; + + if (shdf[id] != NULL) + { + fclose(shdf[id]); + shdf[id] = NULL; + } + + /* Try to open existing hard disk image */ + if (fn[0] == '.') + { + scsi_hd_log("File name starts with .\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + shdf[id] = _wfopen(fn, L"rb+"); + if (shdf[id] == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + if (hdc[id].wp) + { + scsi_hd_log("A write-protected image must exist\n"); + goto scsi_hd_reload_error; + } + + shdf[id] = _wfopen(fn, L"wb+"); + if (shdf[id] == NULL) + { +scsi_hd_reload_error: + scsi_hd_log("Unable to open image\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + else + { + memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); + if (image_is_hdi(fn)) + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + shdc[id].base = 0x1000; + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&(shdc[id].base), 1, 4, shdf[id]); + fwrite(&full_size, 1, 4, shdf[id]); + fwrite(§or_size, 1, 4, shdf[id]); + fwrite(&(hdc[id].spt), 1, 4, shdf[id]); + fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); + fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); + for (c = 0; c < 0x3f8; c++) + { + fwrite(&zero, 1, 4, shdf[id]); + } + } + else if (image_is_hdx(fn, 0)) + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + shdc[id].base = 0x28; + fwrite(&signature, 1, 8, shdf[id]); + fwrite(&full_size, 1, 8, shdf[id]); + fwrite(§or_size, 1, 4, shdf[id]); + fwrite(&(hdc[id].spt), 1, 4, shdf[id]); + fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); + fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + fwrite(&zero, 1, 4, shdf[id]); + } + shdc[id].last_sector = 0; + shdc[id].cdb_len = 12; + } + + scsi_disk_insert(id); + + s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + + goto reload_prepare_new_hard_disk; + } + else + { + /* Failed for another reason */ + scsi_hd_log("Failed for another reason\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + } + else + { + memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); + if (image_is_hdi(fn)) + { + fseeko64(shdf[id], 0x8, SEEK_SET); + fread(&(shdc[id].base), 1, 4, shdf[id]); + fseeko64(shdf[id], 0xC, SEEK_SET); + full_size = 0; + fread(&full_size, 1, 4, shdf[id]); + fseeko64(shdf[id], 0x10, SEEK_SET); + fread(§or_size, 1, 4, shdf[id]); + if (sector_size != 512) + { + /* Sector size is not 512 */ + scsi_hd_log("HDI: Sector size is not 512\n"); + fclose(shdf[id]); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_reload_error; + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; + } + else if (image_is_hdx(fn, 1)) + { + shdc[id].base = 0x28; + fseeko64(shdf[id], 8, SEEK_SET); + fread(&full_size, 1, 8, shdf[id]); + fseeko64(shdf[id], 0x10, SEEK_SET); + fread(§or_size, 1, 4, shdf[id]); + if (sector_size != 512) + { + /* Sector size is not 512 */ + scsi_hd_log("HDX: Sector size is not 512\n"); + fclose(shdf[id]); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + shdc[id].cdb_len = 12; + return; + } + fread(&spt, 1, 4, shdf[id]); + fread(&hpc, 1, 4, shdf[id]); + fread(&tracks, 1, 4, shdf[id]); + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + fclose(shdf[id]); + shdf[id] = NULL; + goto scsi_hd_reload_error; + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; + fread(&(hdc[id].at_spt), 1, 4, shdf[id]); + fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); + } + else + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + } + shdc[id].cdb_len = 12; + scsi_disk_insert(id); + } + + fseeko64(shdf[id], 0, SEEK_END); + if (ftello64(shdf[id]) != (full_size + shdc[id].base)) + { + s = (full_size + shdc[id].base) - ftello64(shdf[id]); +reload_prepare_new_hard_disk: + s >>= 9; + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } + } + + shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; +} + +void scsi_unloadhd(int scsi_id, int scsi_lun, int id) +{ + if (wcslen(hdc[id].fn) == 0) + { + return; + } + + if (shdf[id] != NULL) + { + fclose(shdf[id]); + shdf[id] = NULL; + } + + shdc[id].last_sector = -1; + + memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + wcscpy(hdc[id].prev_fn, hdc[id].fn); + + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + + shdc[id].cdb_len = 12; + + fclose(shdf[id]); } void build_scsi_hd_map() @@ -326,7 +683,15 @@ void build_scsi_hd_map() scsi_hard_disks[i][j] = find_hdc_for_scsi_id(i, j); if (scsi_hard_disks[i][j] != 0xff) { - scsi_loadhd(i, j, scsi_hard_disks[i][j]); + memset(&(shdc[scsi_hard_disks[i][j]]), 0, sizeof(shdc[scsi_hard_disks[i][j]])); + if (wcslen(hdc[scsi_hard_disks[i][j]].fn) > 0) + { + scsi_loadhd(i, j, scsi_hard_disks[i][j]); + } + else + { + shdc[scsi_hard_disks[i][j]].cdb_len = 12; + } } } } @@ -334,7 +699,6 @@ void build_scsi_hd_map() int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *len) { - int ret = 0; int size = 0; size = shdc[id].last_sector; @@ -477,7 +841,7 @@ static void scsi_hd_sense_clear(int id, int command) static void scsi_hd_cmd_error(uint8_t id) { shdc[id].error = ((scsi_hd_sense_key & 0xf) << 4) | ABRT_ERR; - if (shdc[id].unit_attention) + if (shdc[id].unit_attention & 3) { shdc[id].error |= MCR_ERR; } @@ -490,8 +854,8 @@ static void scsi_hd_cmd_error(uint8_t id) static void scsi_hd_unit_attention(uint8_t id) { - shdc[id].error = (SENSE_UNIT_ATTENTION << 4) | ABRT_ERR; - if (cdrom[id].unit_attention) + shdc[id].error = (SENSE_NOT_READY << 4) | ABRT_ERR; + if (shdc[id].unit_attention & 3) { shdc[id].error |= MCR_ERR; } @@ -510,6 +874,32 @@ static void scsi_hd_not_ready(uint8_t id) scsi_hd_cmd_error(id); } +#if 0 +static void scsi_hd_icmd_required(uint8_t id) +{ + scsi_hd_sense_key = SENSE_NOT_READY; + scsi_hd_asc = ASC_NOT_READY; + scsi_hd_ascq = ASCQ_INITIALIZING_COMMAND_REQUIRED; + scsi_hd_cmd_error(id); +} + +static void scsi_hd_capacity_data_changed(uint8_t id) +{ + scsi_hd_sense_key = SENSE_UNIT_ATTENTION; + scsi_hd_asc = ASC_CAPACITY_DATA_CHANGED; + scsi_hd_ascq = ASCQ_CAPACITY_DATA_CHANGED; + scsi_hd_cmd_error(id); +} +#endif + +static void scsi_hd_write_protected(uint8_t id) +{ + scsi_hd_sense_key = SENSE_UNIT_ATTENTION; + scsi_hd_asc = ASC_WRITE_PROTECTED; + scsi_hd_ascq = 0; + scsi_hd_cmd_error(id); +} + static void scsi_hd_invalid_lun(uint8_t id) { scsi_hd_sense_key = SENSE_ILLEGAL_REQUEST; @@ -586,78 +976,6 @@ void scsi_hd_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) } } -int scsi_hd_read_data(uint8_t id, uint32_t *len) -{ - uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; - - int temp_len = 0; - - int last_valid_data_pos = 0; - - uint64_t pos64 = (uint64_t) shdc[id].sector_pos; - - if (shdc[id].sector_pos > shdc[id].last_sector) - { - /* scsi_hd_log("SCSI HD %i: Trying to read beyond the end of disk\n", id); */ - scsi_hd_lba_out_of_range(id); - return 0; - } - - shdc[id].old_len = 0; - *len = 0; - - fseeko64(shdf[id], pos64 << 9, SEEK_SET); - fread(hdbufferb + shdc[id].data_pos, (shdc[id].sector_len << 9), 1, shdf[id]); - temp_len = (shdc[id].sector_len << 9); - - last_valid_data_pos = shdc[id].data_pos; - - shdc[id].data_pos += temp_len; - shdc[id].old_len += temp_len; - - *len += temp_len; - - scsi_hd_log("SCSI HD %i: Data from raw sector read: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, hdbufferb[last_valid_data_pos + 0], hdbufferb[last_valid_data_pos + 1], hdbufferb[last_valid_data_pos + 2], hdbufferb[last_valid_data_pos + 3], hdbufferb[last_valid_data_pos + 4], hdbufferb[last_valid_data_pos + 5], hdbufferb[last_valid_data_pos + 6], hdbufferb[last_valid_data_pos + 7]); - - return 1; -} - -int scsi_hd_read_blocks(uint8_t id, uint32_t *len, int first_batch) -{ - int ret = 0; - - shdc[id].data_pos = 0; - - if (!shdc[id].sector_len) - { - scsi_hd_command_complete(id); - return -1; - } - - scsi_hd_log("Reading %i blocks starting from %i...\n", shdc[id].requested_blocks, shdc[id].sector_pos); - - scsi_hd_update_cdb(shdc[id].current_cdb, shdc[id].sector_pos, shdc[id].requested_blocks); - - ret = scsi_hd_read_data(id, len); - - scsi_hd_log("Read %i bytes of blocks...\n", *len); - - if (!ret) - { - return 0; - } - - shdc[id].sector_pos += shdc[id].requested_blocks; - shdc[id].sector_len -= shdc[id].requested_blocks; - - return 1; -} - -void scsi_disk_insert(uint8_t id) -{ - shdc[id].unit_attention = (hdc[id].bus == 5) ? 1 : 0; -} - /*SCSI Sense Initialization*/ void scsi_hd_sense_code_ok(uint8_t id) { @@ -680,14 +998,15 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) if (!(scsi_hd_command_flags[cdb[0]] & IMPLEMENTED)) { scsi_hd_log("SCSI HD %i: Attempting to execute unknown command %02X\n", id, cdb[0]); + /* pclog("SCSI HD %i: Attempting to execute unknown command %02X (%02X %02X)\n", id, cdb[0], ((cdb[1] >> 3) & 1) ? 0 : 1, cdb[2] & 0x3F); */ scsi_hd_illegal_opcode(id); return 0; } - if (hdc[id].bus == 5) + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { /* Removable disk, set ready state. */ - if (wcslen(hdd_fn[id]) > 0) + if (wcslen(hdc[id].fn) > 0) { ready = 1; } @@ -761,6 +1080,11 @@ static void scsi_hd_seek(uint8_t id, uint32_t pos) static void scsi_hd_rezero(uint8_t id) { + if (id == 255) + { + return; + } + shdc[id].sector_pos = shdc[id].sector_len = 0; scsi_hd_seek(id, 0); } @@ -775,6 +1099,8 @@ void scsi_hd_reset(uint8_t id) void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { + int is_ua = 0; + /*Will return 18 bytes of 0*/ if (alloc_length != 0) { @@ -788,7 +1114,8 @@ void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; - buffer[13]=0; + buffer[13]=0x00; + is_ua = 1; } /* scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, hdbufferb[2], hdbufferb[12], hdbufferb[13]); */ @@ -808,10 +1135,10 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l { int ready = 1; - if (hdc[id].bus == 5) + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { /* Removable disk, set ready state. */ - if (wcslen(hdd_fn[id]) > 0) + if (wcslen(hdc[id].fn) > 0) { ready = 1; } @@ -851,10 +1178,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) unsigned size_idx; unsigned preamble_len; uint32_t alloc_length; - int ret; uint64_t pos64; - char device_identify[8] = { '8', '6', 'B', '_', 'H', 'D', '0', 0 }; - char device_identify_ex[14] = { '8', '6', 'B', '_', 'H', 'D', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + uint64_t full_size = 0; + char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; + char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; #if 0 int CdbLength; @@ -864,13 +1191,22 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].packet_len = 0; shdc[id].request_pos = 0; - device_identify[6] = id + 0x30; + device_identify[6] = (id / 10) + 0x30; + device_identify[7] = (id % 10) + 0x30; + + device_identify_ex[6] = (id / 10) + 0x30; + device_identify_ex[7] = (id % 10) + 0x30; + device_identify_ex[10] = emulator_version[0]; + device_identify_ex[12] = emulator_version[2]; + device_identify_ex[13] = emulator_version[3]; + + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + device_identify[4] = 'R'; + + device_identify_ex[4] = 'R'; + } - device_identify_ex[6] = id + 0x30; - device_identify_ex[9] = emulator_version[0]; - device_identify_ex[11] = emulator_version[2]; - device_identify_ex[12] = emulator_version[3]; - shdc[id].data_pos = 0; memcpy(shdc[id].current_cdb, cdb, shdc[id].cdb_len); @@ -958,20 +1294,15 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len = shdc[id].sector_len; shdc[id].requested_blocks = max_len; -#if 0 - ret = scsi_hd_read_blocks(id, &alloc_length, 1); - if (ret <= 0) - { - return; - } -#endif - pos64 = (uint64_t) shdc[id].sector_pos; if (shdc[id].requested_blocks > 0) { - fseeko64(shdf[id], pos64 << 9, SEEK_SET); - fread(hdbufferb, (shdc[id].sector_len << 9), 1, shdf[id]); + shdf[id] = _wfopen(hdc[id].fn, L"rb+"); + fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); + memset(hdbufferb, 0, shdc[id].sector_len << 9); + fread(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + fclose(shdf[id]); } alloc_length = shdc[id].packet_len = max_len << 9; @@ -986,17 +1317,23 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 1); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); } else { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } return; case GPCMD_WRITE_6: case GPCMD_WRITE_10: case GPCMD_WRITE_12: + if ((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) && hdc[id].wp) + { + scsi_hd_write_protected(id); + return; + } + switch(cdb[0]) { case GPCMD_WRITE_6: @@ -1031,8 +1368,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if (shdc[id].requested_blocks > 0) { - fseeko64(shdf[id], pos64 << 9, SEEK_SET); + shdf[id] = _wfopen(hdc[id].fn, L"rb+"); + fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); fwrite(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + fclose(shdf[id]); } alloc_length = shdc[id].packet_len = max_len << 9; @@ -1047,16 +1386,16 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].all_blocks_total = shdc[id].block_total; if (shdc[id].packet_status != CDROM_PHASE_COMPLETE) { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 1); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 1); } else { - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); } return; case GPCMD_START_STOP_UNIT: - if (hdc[id].bus != 5) + if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) { scsi_hd_illegal_opcode(id); break; @@ -1068,18 +1407,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) case 1: /* Start the disc and read the TOC. */ break; case 2: /* Eject the disc if possible. */ -#ifndef __unix -#if 0 - win_removable_disk_eject(id); -#endif -#endif + removable_disk_eject(id); break; case 3: /* Load the disc (close tray). */ -#ifndef __unix -#if 0 - win_removable_disk_reload(id); -#endif -#endif + removable_disk_reload(id); break; } @@ -1150,7 +1481,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) memset(hdbufferb, 0, 8); hdbufferb[0] = 0; /*SCSI HD*/ - if (hdc[id].bus == 5) + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { hdbufferb[1] = 0x80; /*Removable*/ } @@ -1204,6 +1535,7 @@ atapi_out: break; default: + /* pclog("SCSI HD %i: Attempting to execute pseudo-implemented command %02X\n", id, cdb[0]); */ scsi_hd_illegal_opcode(id); break; } @@ -1301,7 +1633,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].status = READY_STAT; shdc[id].phase = 3; shdc[id].packet_status = 0xFF; - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_DATA_OUT: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT\n", id); @@ -1314,7 +1646,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_DATA_IN: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN\n", id); @@ -1327,7 +1659,7 @@ void scsi_hd_callback(uint8_t id) shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; - update_status_bar_icon((hdc[id].bus == 5) ? (0x20 | id) : 0x23, 0); + update_status_bar_icon((hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? (SB_RDISK | id) : (SB_HDD | HDD_BUS_SCSI), 0); return; case CDROM_PHASE_ERROR: scsi_hd_log("SCSI HD %i: PHASE_ERROR\n", id); diff --git a/src/scsi_disk.h b/src/scsi_disk.h new file mode 100644 index 000000000..59d210e69 --- /dev/null +++ b/src/scsi_disk.h @@ -0,0 +1,43 @@ +#pragma pack(push,1) +typedef struct { + /* Stuff for SCSI hard disks. */ + uint8_t cdb[16]; + uint8_t current_cdb[16]; + uint8_t max_cdb_len; + int requested_blocks; + int max_blocks_at_once; + uint16_t request_length; + int block_total; + int all_blocks_total; + uint32_t packet_len; + int packet_status; + uint8_t status; + uint8_t phase; + uint32_t pos; + int callback; + int total_read; + int unit_attention; + uint8_t sense[256]; + uint8_t previous_command; + uint8_t error; + uint16_t buffer[390144]; + uint32_t sector_pos; + uint32_t sector_len; + uint32_t last_sector; + uint32_t seek_pos; + int data_pos; + int old_len; + int cdb_len_setting; + int cdb_len; + int request_pos; + uint64_t base; + uint8_t hd_cdb[16]; +} scsi_hard_disk_t; +#pragma pack(pop) + +extern scsi_hard_disk_t shdc[HDC_NUM]; + +extern void scsi_disk_insert(uint8_t id); +extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); +extern void scsi_reloadhd(int id); +extern void scsi_unloadhd(int scsi_id, int scsi_lun, int id); diff --git a/src/xtide.c b/src/xtide.c index ce827151b..78ca248fa 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -22,12 +22,12 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) switch (port & 0xf) { case 0x0: - writeidew(0, val | (xtide->data_high << 8)); + writeidew(8, val | (xtide->data_high << 8)); return; case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - writeide(0, (port & 0xf) | 0x1f0, val); + writeide(8, (port & 0xf) | 0x1f0, val); return; case 0x8: @@ -35,7 +35,7 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) return; case 0xe: - writeide(0, 0x3f6, val); + writeide(8, 0x3f6, val); return; } } @@ -49,19 +49,19 @@ static uint8_t xtide_read(uint16_t port, void *p) switch (port & 0xf) { case 0x0: - tempw = readidew(0); + tempw = readidew(8); xtide->data_high = tempw >> 8; return tempw & 0xff; case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - return readide(0, (port & 0xf) | 0x1f0); + return readide(8, (port & 0xf) | 0x1f0); case 0x8: return xtide->data_high; case 0xe: - return readide(0, 0x3f6); + return readide(8, 0x3f6); default: return 0xff; @@ -75,9 +75,7 @@ static void *xtide_init(void) memset(xtide, 0, sizeof(xtide_t)); rom_init(&xtide->bios_rom, L"roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); - ide_pri_disable(); - ide_sec_disable(); + ide_xtide_init(); io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); return xtide; @@ -102,9 +100,7 @@ static void *xtide_ps2_init(void) memset(xtide, 0, sizeof(xtide_t)); rom_init(&xtide->bios_rom, L"roms/SIDE1V12.BIN", 0xc8000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - ide_init(); - ide_pri_disable(); - ide_sec_disable(); + ide_xtide_init(); io_sethandler(0x0360, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); return xtide; From 2fcbb4a5c923ecdc95c84844185152df2945f6ec Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 27 May 2017 03:58:29 +0200 Subject: [PATCH 250/392] Removed broken 0x3DA leftovers from long ago. --- src/VIDEO/vid_et4000w32.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/VIDEO/vid_et4000w32.c b/src/VIDEO/vid_et4000w32.c index 69b21af50..7a4d84659 100644 --- a/src/VIDEO/vid_et4000w32.c +++ b/src/VIDEO/vid_et4000w32.c @@ -235,14 +235,6 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) return svga->crtcreg; case 0x3D5: return svga->crtc[svga->crtcreg]; - - case 0x3DA: - svga->attrff = 0; - svga->cgastat ^= 0x30; - temp = svga->cgastat & 0x39; - if (svga->hdisp_on) temp |= 2; - if (!(svga->cgastat & 8)) temp |= 0x80; - return temp; case 0x210A: case 0x211A: case 0x212A: case 0x213A: case 0x214A: case 0x215A: case 0x216A: case 0x217A: From c836bfdaf8210b9f1cd685d8ef9a0c2972c69eb1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 May 2017 04:17:18 +0200 Subject: [PATCH 251/392] SCSI now again appears in the CD-ROM bus combo box. --- src/WIN/win_settings.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index f586e6526..95f2e81f8 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -2318,6 +2318,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W uint32_t base = 0x1000; uint64_t signature = 0xD778A82044445459ll; char buf[512]; + int b = 0; switch (message) { @@ -2869,7 +2870,13 @@ hdd_add_file_open_error: no_update = 1; recalc_location_controls(hdlg, 1); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - hdc_ptr->bus = SendMessage(h,CB_GETCURSEL,0,0) + 1; + b = SendMessage(h,CB_GETCURSEL,0,0) + 1; + if (b == hdc_ptr->bus) + { + goto hd_add_bus_skip; + } + + hdc_ptr->bus = b; switch(hdc_ptr->bus) { @@ -2977,6 +2984,7 @@ hdd_add_file_open_error: recalc_selection(hdlg); } +hd_add_bus_skip: no_update = 0; break; } @@ -3007,6 +3015,7 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA { HWND h; int old_sel = 0; + int b = 0; switch (message) { @@ -3078,11 +3087,17 @@ static BOOL CALLBACK win_settings_hard_disks_proc(HWND hdlg, UINT message, WPARA } ignore_change = 1; - recalc_location_controls(hdlg, 0); h = GetDlgItem(hdlg, IDC_COMBO_HD_BUS); - temp_hdc[hdlv_current_sel].bus = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + b = SendMessage(h, CB_GETCURSEL, 0, 0) + 1; + if (b == temp_hdc[hdlv_current_sel].bus) + { + goto hd_bus_skip; + } + temp_hdc[hdlv_current_sel].bus = b; + recalc_location_controls(hdlg, 0); h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); win_settings_hard_disks_update_item(h, hdlv_current_sel, 0); +hd_bus_skip: ignore_change = 0; return FALSE; @@ -3226,7 +3241,7 @@ static int combo_id_to_string_id(int combo_id) return 2190; break; case CDROM_BUS_SCSI: /* SCSI */ - return 2168; + return 2210; break; } } @@ -3544,7 +3559,7 @@ static void cdrom_add_locations(HWND hdlg) lptsTemp = (LPTSTR) malloc(512); h = GetDlgItem(hdlg, IDC_COMBO_CD_BUS); - for (i = CDROM_BUS_DISABLED; i < CDROM_BUS_SCSI; i++) + for (i = CDROM_BUS_DISABLED; i <= CDROM_BUS_SCSI; i++) { if ((i == CDROM_BUS_DISABLED) || (i >= CDROM_BUS_ATAPI_PIO_ONLY)) { @@ -3644,6 +3659,7 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message int i = 0; int old_sel = 0; int b = 0; + int b2 = 0; WCHAR szText[256]; switch (message) @@ -3806,21 +3822,27 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message switch (b) { case 0: - temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_DISABLED; + b2 = CDROM_BUS_DISABLED; break; case 1: - temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_ATAPI_PIO_ONLY; + b2 = CDROM_BUS_ATAPI_PIO_ONLY; break; case 2: - temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_ATAPI_PIO_AND_DMA; + b2 = CDROM_BUS_ATAPI_PIO_AND_DMA; break; case 3: - temp_cdrom_drives[cdlv_current_sel].bus_type = CDROM_BUS_SCSI; + b2 = CDROM_BUS_SCSI; break; } + if (b2 == temp_cdrom_drives[cdlv_current_sel].bus_type) + { + goto cdrom_bus_skip; + } + temp_cdrom_drives[cdlv_current_sel].bus_type = b2; cdrom_recalc_location_controls(hdlg); h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_update_item(h, cdlv_current_sel); +cdrom_bus_skip: rd_ignore_change = 0; return FALSE; From 5ca57c5b638c9d58e9fa85d18b3c97b2f122f7e3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 May 2017 04:33:29 +0200 Subject: [PATCH 252/392] Fixed loading of slave IDE channels for hard disks and CD-ROM's to the configuration files. --- src/config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config.c b/src/config.c index 4ac4837f1..6bb2f46e2 100644 --- a/src/config.c +++ b/src/config.c @@ -1316,7 +1316,7 @@ static void loadconfig_hard_disks(void) sscanf(p, "%01u:%01u", &board, &dev); board &= 3; - dev %= 1; + dev &= 1; hdc[c].ide_channel = (board << 1) + dev; if (hdc[c].ide_channel > 7) @@ -1462,7 +1462,7 @@ static void loadconfig_removable_devices(void) sscanf(p, "%02u:%02u", &board, &dev); board &= 3; - dev %= 1; + dev &= 1; cdrom_drives[c].ide_channel = (board << 1) + dev; if (cdrom_drives[c].ide_channel > 7) From 84480b73476c76bee88b1c216cffb1a00629e60e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 27 May 2017 04:47:18 +0200 Subject: [PATCH 253/392] Changed gray monochrome monitor palettes per patch from Basic2004. --- src/WIN/win_d3d_fs.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 9e410ec3b..93b23da0b 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -83,13 +83,13 @@ PALETTE cgapal_mono[6] = {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, }, { // 4 - grey, 4-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x12,0x14,0x10},{0x15,0x17,0x13},{0x21,0x24,0x1e},{0x23,0x26,0x21},{0x30,0x31,0x2e},{0x34,0x35,0x33}, - {0x07,0x08,0x07},{0x0e,0x0f,0x0d},{0x19,0x1b,0x16},{0x1c,0x1f,0x1a},{0x28,0x2b,0x26},{0x2b,0x2d,0x2a},{0x37,0x38,0x37},{0x3d,0x3d,0x3c}, + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},{0x33,0x34,0x32},{0x37,0x38,0x35}, + {0x09,0x0a,0x0b},{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, }, { // 5 - grey, 16-color-optimized contrast - {0x00,0x00,0x00},{0x0b,0x0c,0x0a},{0x0f,0x11,0x0e},{0x12,0x14,0x10},{0x1b,0x1d,0x18},{0x1c,0x1f,0x1a},{0x25,0x28,0x23},{0x28,0x2b,0x26}, - {0x1c,0x1e,0x19},{0x20,0x23,0x1d},{0x27,0x2a,0x25},{0x29,0x2c,0x27},{0x31,0x32,0x30},{0x33,0x34,0x32},{0x3a,0x3b,0x3a},{0x3d,0x3d,0x3c}, - }, + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c}, + {0x1f,0x21,0x21},{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, + } }; uint32_t pal_lookup[256]; From 2c468f551a0e30555fa41cd3a574beea8329d0ec Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 26 May 2017 22:57:38 -0400 Subject: [PATCH 254/392] Changed rm to del. --- src/Makefile.mingw | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index ed0cb81f8..27207fc66 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.16 2017/05/23 +# Version: @(#)Makefile.mingw 1.0.17 2017/05/26 # # Authors: Kotori, # Fred N. van Kempen, @@ -248,9 +248,9 @@ endif clean: - rm *.o - rm *.exe - rm *.res + -del *.o >NUL: + -del *.exe >NUL: + -del *.res >NUL: 86Box.res: 86Box.rc @echo Processing $< From fc2a293536919b6cd35e849f92b619749d4165f7 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 May 2017 01:18:32 +0200 Subject: [PATCH 255/392] CD-ROM images are now working correctly again; Fixed all the reported bugs regarding the Settings dialog; MIDI out device is now no longer reset to 0 after hard reset; Removed all vestiges of the old disk activity flash; The configuration file is no longer saved when it shouldn't be; Redone the status bar icon updating so it is only done in win.c; Made sure all variables in ibm.h are extern; A lot of other bugfixes; Added Mouse Systems Mouse emulation (patch from TheCollector1995); Added IBM PS/1 Model 2133 (486) emulation (patch from TheCollector1995); Tweaked the CPU dynamic recompiler cycle periods - 486SX 33 and 486DX 33 now work; Increased compatibility with configuration files from before the previous commit. --- src/CPU/386.c | 9 ++ src/CPU/386_dynarec.c | 71 +++++++++++++++- src/CPU/cpu.c | 10 +-- src/CPU/cpu.h | 1 + src/SOUND/snd_speaker.c | 3 + src/VIDEO/vid_ega.c | 1 - src/VIDEO/vid_svga.c | 2 - src/VIDEO/vid_svga_render.c | 73 +++++++++++++++- src/VIDEO/video.c | 2 +- src/VIDEO/video.h | 3 +- src/WIN/win.c | 107 ++++++++++++++++-------- src/WIN/win_ddraw.cc | 46 ----------- src/WIN/win_ddraw_fs.cc | 22 ----- src/WIN/win_iodev.c | 25 ++++-- src/WIN/win_midi.c | 6 +- src/WIN/win_settings.c | 50 +++++++++-- src/cdrom_dosbox.cpp | 10 +-- src/cdrom_dosbox.h | 4 +- src/cdrom_image.cc | 1 - src/cdrom_ioctl.c | 1 - src/cdrom_null.c | 2 +- src/config.c | 86 +++++++++++++++---- src/disc.c | 3 + src/disc_86f.c | 24 +++--- src/disc_fdi.c | 2 +- src/disc_imd.c | 10 +-- src/disc_img.c | 8 +- src/disc_td0.c | 6 +- src/dma.c | 9 ++ src/fdc.c | 3 +- src/ibm.h | 75 +++++++++-------- src/ide.c | 9 +- src/keyboard.c | 1 + src/mem.c | 23 ++++++ src/model.c | 31 ++++--- src/mouse.c | 2 +- src/mouse_serial.c | 68 ++++++++++++++- src/mouse_serial.h | 1 + src/net_pcap.c | 26 ++++++ src/network.c | 6 +- src/network.h | 1 + src/nvr.c | 2 + src/pc.c | 31 ++++--- src/pic.c | 2 + src/pit.c | 5 ++ src/ppi.c | 3 + src/ps1.c | 20 +++++ src/ps1.h | 1 + src/scsi.c | 6 ++ src/scsi.h | 2 +- src/scsi_aha154x.c | 17 +++- src/scsi_buslogic.c | 17 +++- src/scsi_disk.c | 160 ++++++++++++------------------------ src/scsi_disk.h | 3 +- 54 files changed, 740 insertions(+), 372 deletions(-) diff --git a/src/CPU/386.c b/src/CPU/386.c index 6bd69af85..074fa9696 100644 --- a/src/CPU/386.c +++ b/src/CPU/386.c @@ -28,6 +28,13 @@ uint32_t oldpc2; int trap; +uint16_t flags,eflags; +uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; + +x86seg gdt,ldt,idt,tr; +x86seg _cs,_ds,_es,_ss,_fs,_gs; +x86seg _oldds; + extern int cpl_override; @@ -40,6 +47,8 @@ uint16_t ea_rseg; int is486; int cgate32; +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; uint8_t romext[32768]; diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 328289d53..61db68737 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -1280,6 +1280,39 @@ int dontprint=0; #define CACHE_ON() (!(cr0 & (1 << 30)) /*&& (cr0 & 1)*/ && !(flags & T_FLAG)) +static int cpu_cycle_period(void) +{ + switch(cpu_pci_speed) + { + case 16000000: + return 800; + break; + case 20000000: + case 40000000: + return 1000; + break; + case 25000000: + default: + return 1000; + break; + case 27500000: + return 1100; + break; + case 30000000: + return 1200; + break; + case 333333333: + return 1333; + break; + case 37500000: + return 1500; + break; + case 41666667: + return 1041; + break; + } +} + static int cycles_main = 0; void exec386_dynarec(int cycs) { @@ -1294,8 +1327,42 @@ void exec386_dynarec(int cycs) while (cycles_main > 0) { int cycles_start; - - cycles += 1000; + +#if 0 + switch(cpu_pci_speed) + { + case 16000000: + cycles += 640; + break; + case 20000000: + cycles += 800; + break; + case 25000000: + default: + cycles += 1000; + break; + case 27500000: + cycles += 1100; + break; + case 30000000: + cycles += 1200; + break; + case 333333333: + cycles += 1333; + break; + case 37500000: + cycles += 1500; + break; + case 40000000: + cycles += 1600; + break; + case 41666667: + cycles += 1666; + break; + } +#endif + cycles += cpu_cycle_period(); + cycles_start = cycles; timer_start_period(cycles << TIMER_SHIFT); diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index 453e8626a..f6e8bb816 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -75,12 +75,15 @@ int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; +int hasfpu; + uint64_t cpu_CR4_mask; int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; int cpu_prefetch_cycles, cpu_prefetch_width; int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; +int cpu_pci_speed; int is286, is386; int israpidcad, is_pentium; @@ -405,7 +408,7 @@ CPU cpus_Cx486[] = {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7}, {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9}, {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, + {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, {"", -1, 0, 0, 0} }; @@ -617,11 +620,6 @@ void cpu_set() if (enable_external_fpu) { hasfpu = 1; - if (cpu_s->cpu_type == CPU_i486SX) - { - /* The 487SX is a full implementation of the 486DX and takes over the entire CPU's operation. */ - cpu_s->cpu_type = CPU_i486DX; - } } } diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index cbf7b7516..dd7fbff31 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -138,6 +138,7 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ extern int cpu_prefetch_cycles, cpu_prefetch_width; extern int cpu_waitstates; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; +extern int cpu_pci_speed; extern uint64_t tsc; diff --git a/src/SOUND/snd_speaker.c b/src/SOUND/snd_speaker.c index 25344d922..3ac8298a9 100644 --- a/src/SOUND/snd_speaker.c +++ b/src/SOUND/snd_speaker.c @@ -8,6 +8,9 @@ int speaker_gated = 0; int speaker_enable = 0, was_speaker_enable = 0; +int gated,speakval,speakon; + + static int16_t speaker_buffer[SOUNDBUFLEN]; static int speaker_pos = 0; diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index b64f30324..7fe76ddaa 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -686,7 +686,6 @@ void ega_poll(void *p) ega->video_bpp = (ega->gdcreg[5] & 0x20) ? 2 : 4; } - readflash=0; ega->firstline = 2000; ega->lastline = 0; diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 39a72ae15..c2af8a822 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -870,8 +870,6 @@ void svga_poll(void *p) if (!svga->override) svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); - readflash = 0; - svga->firstline = 2000; svga->lastline = 0; diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index d51d6d249..eba7e0b43 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -43,10 +43,75 @@ int svga_display_line(svga_t *svga) void svga_render_blank(svga_t *svga) { +#if 0 int x, xx; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; int dl = svga_display_line(svga); + uint32_t *p; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + if (dl >= 2046) + { + return; + } + + for (x = 0; x < svga->hdisp; x++) + { + switch (svga->seqregs[1] & 9) + { + case 0: + for (xx = 0; xx < 9; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 9) + xx + 32 + x_add]) != NULL) + { + p[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + + case 1: + for (xx = 0; xx < 8; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 8) + xx + 32 + x_add]) != NULL) + { + p[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + + case 8: + for (xx = 0; xx < 18; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 18) + xx + 32 + x_add]) != NULL) + { + p[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + + case 9: + for (xx = 0; xx < 16; xx++) + { + p = ((uint32_t *)buffer32->line[dl]); + if (&(p[(x * 16) + xx + 32 + x_add]) != NULL) + { + p[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); + } + } + break; + } + } +#endif + int x, xx; + int y_add = (enable_overscan) ? 16 : 0; + int x_add = y_add >> 1; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -57,16 +122,16 @@ void svga_render_blank(svga_t *svga) switch (svga->seqregs[1] & 9) { case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 9) + xx + 32 + x_add] = svga_color_transform(0); break; case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 8) + xx + 32 + x_add] = svga_color_transform(0); break; case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 18) + xx + 32 + x_add] = svga_color_transform(0); break; case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[svga->displine + y_add])[(x * 16) + xx + 32 + x_add] = svga_color_transform(0); break; } } diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index f3deed5bc..b195cdb5c 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -199,8 +199,8 @@ uint8_t edatlookup[4][4]; int enable_overscan; int overscan_x, overscan_y; + int force_43; -int enable_flash; /*Video timing settings - diff --git a/src/VIDEO/video.h b/src/VIDEO/video.h index 7054c33b3..b1bff117c 100644 --- a/src/VIDEO/video.h +++ b/src/VIDEO/video.h @@ -81,10 +81,9 @@ extern void (*video_blit_memtoscreen_8_func)(int x, int y, int w, int h); /* Enable EGA/(S)VGA overscan border. */ extern int enable_overscan; extern int overscan_x, overscan_y; + /* Forcibly stretch emulated video output to 4:3 or not. */ extern int force_43; -/* Enable disk activity flash. */ -extern int enable_flash; extern int video_timing_b, video_timing_w, video_timing_l; extern int video_speed; diff --git a/src/WIN/win.c b/src/WIN/win.c index 41e94fa54..0f1d77e99 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -138,6 +138,7 @@ static int *sb_part_icons; static WCHAR **sbTips; static int sb_parts = 0; +static int sb_ready = 0; void updatewindowsize(int x, int y) @@ -311,6 +312,12 @@ void mainthread(LPVOID param) winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, TRUE); + if (mousecapture) + { + GetWindowRect(ghwnd, &r); + ClipCursor(&r); + } + win_doresize = 0; } @@ -394,7 +401,7 @@ static void init_cdrom_host_drives(void) for (i='A'; i<='Z'; i++) { - _swprintf(s, L"%c:\\", i + 0x41); + _swprintf(s, L"%c:\\", i); if (GetDriveType(s)==DRIVE_CDROM) { @@ -465,7 +472,7 @@ void create_cdrom_submenu(HMENU m, int id) for (i = 0; i < 26; i++) { - _swprintf(s, L"%c:\\", i + 0x41); + wsprintf(s, L"Host CD/DVD Drive (%c:)", i + 0x41); if (host_cdrom_drive_available[i]) { AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i << 3) | id, s); @@ -475,21 +482,21 @@ void create_cdrom_submenu(HMENU m, int id) check_menu_items: if (!cdrom_drives[id].sound_on) { - CheckMenuItem(smenu, IDM_CDROM_MUTE | id, MF_CHECKED); + CheckMenuItem(m, IDM_CDROM_MUTE | id, MF_CHECKED); } if (cdrom_drives[id].host_drive == 200) { - CheckMenuItem(smenu, IDM_CDROM_IMAGE | id, MF_CHECKED); + CheckMenuItem(m, IDM_CDROM_IMAGE | id, MF_CHECKED); } else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - CheckMenuItem(smenu, IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + CheckMenuItem(m, IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); } else { cdrom_drives[id].host_drive = 0; - CheckMenuItem(smenu, IDM_CDROM_EMPTY | id, MF_CHECKED); + CheckMenuItem(m, IDM_CDROM_EMPTY | id, MF_CHECKED); } } @@ -667,7 +674,7 @@ int find_status_bar_part(int tag) int i = 0; int found = -1; - if (sb_part_meanings == NULL) + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) { return -1; } @@ -690,7 +697,7 @@ void update_status_bar_icon(int tag, int active) int found = -1; int temp_flags = 0; - if (((tag & 0xf0) >= SB_TEXT) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) + if (((tag & 0xf0) >= SB_TEXT) || !sb_ready || (sb_parts == 0) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { return; } @@ -719,7 +726,7 @@ void update_status_bar_icon_state(int tag, int state) { int found = -1; - if (((tag & 0xf0) >= SB_HDD) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) + if (((tag & 0xf0) >= SB_HDD) || !sb_ready || (sb_parts == 0) || (sb_icon_flags == NULL) || (sb_part_icons == NULL)) { return; } @@ -866,6 +873,11 @@ void update_tip(int meaning) int i = 0; int part = -1; + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) + { + return; + } + for (i = 0; i < sb_parts; i++) { if (sb_part_meanings[i] == meaning) @@ -903,6 +915,11 @@ void status_settextw(wchar_t *wstr) int i = 0; int part = -1; + if (!sb_ready || (sb_parts == 0) || (sb_part_meanings == NULL)) + { + return; + } + for (i = 0; i < sb_parts; i++) { if (sb_part_meanings[i] == SB_TEXT) @@ -972,6 +989,8 @@ void update_status_bar_panes(HWND hwnds) int c_ide_dma = 0; int c_scsi = 0; + sb_ready = 0; + c_mfm = count_hard_disks(HDD_BUS_MFM); c_rll = count_hard_disks(HDD_BUS_RLL); c_xtide = count_hard_disks(HDD_BUS_XTIDE); @@ -1011,7 +1030,7 @@ void update_status_bar_panes(HWND hwnds) sb_parts++; } } - for (i = 0; i < 16; i++) + for (i = 0; i < HDC_NUM; i++) { if (hdc[i].bus == HDD_BUS_SCSI_REMOVABLE) { @@ -1044,17 +1063,17 @@ void update_status_bar_panes(HWND hwnds) } sb_parts++; - iStatusWidths = (int *) malloc(sb_parts << 2); - sb_part_meanings = (int *) malloc(sb_parts << 2); - sb_part_icons = (int *) malloc(sb_parts << 2); - sb_icon_flags = (int *) malloc(sb_parts << 2); + iStatusWidths = (int *) malloc(sb_parts * sizeof(int)); + sb_part_meanings = (int *) malloc(sb_parts * sizeof(int)); + sb_part_icons = (int *) malloc(sb_parts * sizeof(int)); + sb_icon_flags = (int *) malloc(sb_parts * sizeof(int)); sb_menu_handles = (HMENU *) malloc(sb_parts * sizeof(HMENU)); sbTips = (WCHAR **) malloc(sb_parts * sizeof(WCHAR *)); - memset(iStatusWidths, 0, sb_parts << 2); - memset(sb_part_meanings, 0, sb_parts << 2); - memset(sb_part_icons, 0, sb_parts << 2); - memset(sb_icon_flags, 0, sb_parts << 2); + memset(iStatusWidths, 0, sb_parts * sizeof(int)); + memset(sb_part_meanings, 0, sb_parts * sizeof(int)); + memset(sb_part_icons, 0, sb_parts * sizeof(int)); + memset(sb_icon_flags, 0, sb_parts * sizeof(int)); memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); sb_parts = 0; @@ -1225,6 +1244,8 @@ void update_status_bar_panes(HWND hwnds) SendMessage(hwnds, SB_SETICON, i, (LPARAM) NULL); } } + + sb_ready = 1; } HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) @@ -1421,17 +1442,27 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz ghwnd=hwnd; - initpc(argc, argv); - +printf("hwndRender;\n"); hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); +printf("initpc();\n"); + initpc(argc, argv); + +printf("init_cdrom_host_drives();\n"); + init_cdrom_host_drives(); + +printf("EmulatorStatusBar();\n"); hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); +printf("OriginalStatusBarProcedure;\n"); OriginalStatusBarProcedure = GetWindowLongPtr(hwndStatus, GWLP_WNDPROC); +printf("SetWindowLongPtr;\n"); SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); - init_cdrom_host_drives(); + +printf("initmodules();\n"); + initmodules(); if (vid_apis[0][vid_api].init(hwndRender) == 0) { @@ -2024,10 +2055,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { GetClipCursor(&oldclip); GetWindowRect(hwnd, &rect); - rect.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 20; - rect.right = GetSystemMetrics(SM_CXFIXEDFRAME) + 20; - rect.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 20; - rect.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + ClipCursor(&rect); mousecapture = 1; while (1) @@ -2069,10 +2097,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (mousecapture) { GetWindowRect(hwnd, &rect); - rect.left += GetSystemMetrics(SM_CXFIXEDFRAME) + 20; - rect.right -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; - rect.top += GetSystemMetrics(SM_CXFIXEDFRAME) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 20; - rect.bottom -= GetSystemMetrics(SM_CXFIXEDFRAME) + 20; + ClipCursor(&rect); } @@ -2085,6 +2110,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM window_h = rect.bottom - rect.top; save_window_pos = 1; } + + saveconfig(); break; case WM_MOVE: @@ -2124,6 +2151,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM mouse_close(); vid_apis[1][vid_api].close(); video_fullscreen = 0; + saveconfig(); vid_apis[0][vid_api].init(hwndRender); mouse_init(); endblit(); @@ -2283,10 +2311,20 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_UNCHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); + } + cdrom_drives[id].host_drive = (wcslen(cdrom_image[id].image_path) == 0) ? 0 : 200; + if (cdrom_drives[id].host_drive == 200) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + update_status_bar_icon_state(SB_CDROM | id, 0); + } + else + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + update_status_bar_icon_state(SB_CDROM | id, 1); } - cdrom_drives[id].host_drive = 200; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); update_tip(SB_CDROM | id); saveconfig(); } @@ -2316,12 +2354,13 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_UNCHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); } CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); cdrom_drives[id].host_drive = new_cdrom_drive; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); + update_status_bar_icon_state(SB_CDROM | id, 0); update_tip(SB_CDROM | id); saveconfig(); break; diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc index dd985baf8..c5c111734 100644 --- a/src/WIN/win_ddraw.cc +++ b/src/WIN/win_ddraw.cc @@ -178,29 +178,6 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash) - { - readflash = 0; -#ifdef LEGACY_READ_FLASH - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = &(((uint32_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - } -#endif - } lpdds_back2->Unlock(NULL); // pclog("Blit from %i,%i %i,%i to %i,%i %i,%i\n", r_src.left, r_src.top, r_src.right, r_src.bottom, r_dest.left, r_dest.top, r_dest.right, r_dest.bottom); @@ -276,29 +253,6 @@ static void ddraw_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash) - { - readflash = 0; - if (enable_flash) - { - hr = lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) - { - lpdds_back2->Restore(); - lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (!ddsd.lpSurface) return; - for (yy = 8; yy < 14; yy++) - { - p = (uint32_t *) &(((uint8_t *) ddsd.lpSurface)[yy * ddsd.lPitch]); - for (xx = (w - 40); xx < (w - 8); xx++) - p[xx] = 0xffffffff; - } - lpdds_back2->Unlock(NULL); - } - } - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); if (hr == DDERR_SURFACELOST) { diff --git a/src/WIN/win_ddraw_fs.cc b/src/WIN/win_ddraw_fs.cc index 88649f7e9..f29524d64 100644 --- a/src/WIN/win_ddraw_fs.cc +++ b/src/WIN/win_ddraw_fs.cc @@ -227,17 +227,6 @@ static void ddraw_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); if (hr == DDERR_SURFACELOST) { @@ -314,17 +303,6 @@ static void ddraw_fs_blit_memtoscreen_8(int x, int y, int w, int h) lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); } - if (readflash && enable_flash) - { - RECT r; - r.left = window_rect.right - 40; - r.right = window_rect.right - 8; - r.top = 8; - r.bottom = 14; - ddbltfx.dwFillColor = 0xffffff; - lpdds_back2->Blt(&r, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - } - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); } diff --git a/src/WIN/win_iodev.c b/src/WIN/win_iodev.c index a008aab8d..465302c68 100644 --- a/src/WIN/win_iodev.c +++ b/src/WIN/win_iodev.c @@ -52,7 +52,7 @@ void cdrom_eject(uint8_t id) CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); if ((cdrom_drives[id].host_drive >= 65) && (cdrom_drives[id].host_drive <= 90)) { - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drive << 3), MF_UNCHECKED); + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_UNCHECKED); } cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; cdrom_drives[id].host_drive=0; @@ -89,9 +89,20 @@ void cdrom_reload(uint8_t id) /* Signal disc change to the emulated machine. */ cdrom_insert(id); } - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - cdrom_drives[id].host_drive = 200; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + if (wcslen(cdrom_image[id].image_path) == 0) + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_CHECKED); + cdrom_drives[id].host_drive = 0; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_UNCHECKED); + update_status_bar_icon_state(SB_CDROM | id, 1); + } + else + { + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); + cdrom_drives[id].host_drive = 200; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_IMAGE | id, MF_CHECKED); + update_status_bar_icon_state(SB_CDROM | id, 0); + } } else { @@ -103,10 +114,10 @@ void cdrom_reload(uint8_t id) cdrom_insert(id); } CheckMenuItem(sb_menu_handles[part], IDM_CDROM_EMPTY | id, MF_UNCHECKED); - cdrom_drive = new_cdrom_drive; - CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | (cdrom_drives[id].host_drive << 3), MF_CHECKED); + cdrom_drives[id].host_drive = new_cdrom_drive; + CheckMenuItem(sb_menu_handles[part], IDM_CDROM_HOST_DRIVE | id | ((cdrom_drives[id].host_drive - 'A') << 3), MF_CHECKED); + update_status_bar_icon_state(SB_CDROM | id, 0); } - update_status_bar_icon_state(SB_CDROM | id, 0); EnableMenuItem(sb_menu_handles[part], IDM_CDROM_RELOAD | id, MF_BYCOMMAND | MF_GRAYED); update_tip(SB_CDROM | id); saveconfig(); diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c index 5ce523a0a..66f354857 100644 --- a/src/WIN/win_midi.c +++ b/src/WIN/win_midi.c @@ -49,8 +49,8 @@ void midi_init() { MMRESULT hr = MMSYSERR_NOERROR; - memset(midi_rt_buf, 0, 1024); - memset(midi_cmd_buf, 0, 1024); + memset(midi_rt_buf, 0, sizeof(midi_rt_buf)); + memset(midi_cmd_buf, 0, sizeof(midi_cmd_buf)); midi_cmd_pos = midi_cmd_len = 0; midi_status = 0; @@ -81,7 +81,7 @@ void midi_close() { midiOutReset(midi_out_device); midiOutClose(midi_out_device); - midi_out_device = NULL; + /* midi_out_device = NULL; */ CloseHandle(m_event); } } diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 95f2e81f8..84a6a0645 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -87,6 +87,7 @@ static void win_settings_init(void) /* Machine category */ temp_model = model; temp_cpu_m = cpu_manufacturer; + temp_wait_states = cpu_waitstates; temp_cpu = cpu; temp_mem_size = mem_size; temp_dynarec = cpu_use_dynarec; @@ -149,6 +150,7 @@ static int win_settings_changed(void) /* Machine category */ i = i || (model != temp_model); i = i || (cpu_manufacturer != temp_cpu_m); + i = i || (cpu_waitstates != temp_wait_states); i = i || (cpu != temp_cpu); i = i || (mem_size != temp_mem_size); i = i || (temp_dynarec != cpu_use_dynarec); @@ -243,6 +245,7 @@ static void win_settings_save(void) model = temp_model; romset = model_getromset(); cpu_manufacturer = temp_cpu_m; + cpu_waitstates = temp_wait_states; cpu = temp_cpu; mem_size = temp_mem_size; cpu_use_dynarec = temp_dynarec; @@ -297,6 +300,8 @@ static void win_settings_save(void) mem_resize(); loadbios(); + update_status_bar_panes(hwndStatus); + resetpchard(); cpu_set(); @@ -308,8 +313,6 @@ static void win_settings_save(void) speedchanged(); if (joystick_type != 7) gameport_update_joystick_type(); - - update_status_bar_panes(hwndStatus); } @@ -399,6 +402,10 @@ static void win_settings_machine_recalc_cpu_m(HWND hdlg) c++; } EnableWindow(h, TRUE); + if (temp_cpu > c) + { + temp_cpu = c; + } SendMessage(h, CB_SETCURSEL, temp_cpu, 0); win_settings_machine_recalc_cpu(hdlg); @@ -440,6 +447,10 @@ static void win_settings_machine_recalc_model(HWND hdlg) c++; } EnableWindow(h, TRUE); + if (temp_cpu_m > c) + { + temp_cpu_m = c; + } SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); if (c == 1) { @@ -519,7 +530,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } - SendMessage(h, CB_SETCURSEL, cpu_waitstates, 0); + SendMessage(h, CB_SETCURSEL, temp_wait_states, 0); h=GetDlgItem(hdlg, IDC_CHECK_DYNAREC); SendMessage(h, BM_SETCHECK, temp_dynarec, 0); @@ -644,7 +655,7 @@ static void recalc_vid_list(HWND hdlg) { mbstowcs(szText, s, strlen(s) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) szText); - if (video_new_to_old(c) == gfxcard) + if (video_new_to_old(c) == temp_gfxcard) { SendMessage(h, CB_SETCURSEL, d, 0); @@ -1682,7 +1693,12 @@ static int get_selected_hard_disk(HWND hdlg) int i, j = 0; HWND h; - for (i = 0; i < 6; i++) + if (hd_listview_items == 0) + { + return 0; + } + + for (i = 0; i < hd_listview_items; i++) { h = GetDlgItem(hdlg, IDC_LIST_HARD_DISKS); j = ListView_GetItemState(h, i, LVIS_SELECTED); @@ -2318,7 +2334,9 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W uint32_t base = 0x1000; uint64_t signature = 0xD778A82044445459ll; char buf[512]; + char *big_buf; int b = 0; + uint64_t r = 0; switch (message) { @@ -2547,9 +2565,27 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W memset(buf, 0, 512); size >>= 9; - for (i = 0; i < size; i++) + r = (size >> 11) << 11; + size -= r; + r >>= 11; + + if (size) { - fwrite(buf, 512, 1, f); + for (i = 0; i < size; i++) + { + fwrite(buf, 1, 512, f); + } + } + + if (r) + { + big_buf = (char *) malloc(1048576); + memset(big_buf, 0, 1048576); + for (i = 0; i < r; i++) + { + fwrite(big_buf, 1, 1048576, f); + } + free(big_buf); } fclose(f); diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index eadd5541b..906f7b0c8 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -60,11 +60,10 @@ CDROM_Interface_Image::BinaryFile::~BinaryFile() delete file; } -bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) { uint64_t offs = 0; - offs = ftello64(file); - fseeko64(file, offs, SEEK_SET); + fseeko64(file, seek, SEEK_SET); offs = fread(buffer, 1, count, file); return (offs == count); } @@ -186,8 +185,9 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se int track = GetTrack(sector) - 1; if (track < 0) return false; - int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; - int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + uint64_t seek = tracks[track].skip + (sector - tracks[track].start); + seek *= (uint64_t) tracks[track].sectorSize; + uint64_t length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; if (tracks[track].mode2 && !raw) seek += 24; diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index b545269f5..f8fd704a7 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -103,7 +103,7 @@ class CDROM_Interface_Image : public CDROM_Interface private: class TrackFile { public: - virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual bool read(Bit8u *buffer, uint64_t seek, uint64_t count) = 0; virtual uint64_t getLength() = 0; virtual ~TrackFile() { }; }; @@ -112,7 +112,7 @@ private: public: BinaryFile(const char *filename, bool &error); ~BinaryFile(); - bool read(Bit8u *buffer, int seek, int count); + bool read(Bit8u *buffer, uint64_t seek, uint64_t count); uint64_t getLength(); private: BinaryFile(); diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index c941315cd..07566b7ef 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -995,7 +995,6 @@ int image_open(uint8_t id, wchar_t *fn) cdrom_image[id].image_inited = 1; } - update_status_bar_icon_state(0x10 | id, 0); return 0; } diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index 5da98bda6..b0d416521 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -1056,7 +1056,6 @@ int ioctl_open(uint8_t id, char d) ioctl_read_capacity(id, NULL); CloseHandle(cdrom_ioctl_windows[id].hIOCTL); cdrom_ioctl_windows[id].hIOCTL = NULL; - update_status_bar_icon_state(0x10 | id, 0); } return 0; } diff --git a/src/cdrom_null.c b/src/cdrom_null.c index 5d86b7992..2a0ce9da5 100644 --- a/src/cdrom_null.c +++ b/src/cdrom_null.c @@ -101,7 +101,7 @@ void cdrom_set_null_handler(uint8_t id) { cdrom_drives[id].handler = &null_cdrom; cdrom_drives[id].host_drive = 0; - update_status_bar_icon_state(0x10 | id, 1); + memset(cdrom_image[id].image_path, 0, sizeof(cdrom_image[id].image_path)); } static CDROM null_cdrom = diff --git a/src/config.c b/src/config.c index 6bb2f46e2..550f442fe 100644 --- a/src/config.c +++ b/src/config.c @@ -866,9 +866,9 @@ static void loadconfig_machine(void) mem_size = config_get_int(cat, "mem_size", 4096); if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - if (mem_size > 1048576) + if (mem_size > 262144) { - mem_size = 1048576; + mem_size = 262144; } cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); @@ -967,7 +967,7 @@ static void loadconfig_sound(void) { strcpy(temps, p); } - if (!strcmp(temps, "nukedopl")) + if (!strcmp(temps, "nukedopl") || !strcmp(temps, "1")) { opl3_type = 1; } @@ -991,11 +991,11 @@ static void loadconfig_network(void) { strcpy(temps, p); } - if (!strcmp(temps, "slirp")) + if (!strcmp(temps, "slirp") || !strcmp(temps, "2")) { network_type = NET_TYPE_SLIRP; } - else if (!strcmp(temps, "pcap")) + else if (!strcmp(temps, "pcap") || !strcmp(temps, "1")) { network_type = NET_TYPE_PCAP; } @@ -1206,6 +1206,33 @@ static int hard_disk_is_valid(int c) } +static int tally_char(char *string, char c) +{ + int i = 0; + int tally = 0; + + if (string == NULL) + { + return 0; + } + + if (strlen(string) == 0) + { + return 0; + } + + for (i = 0; i < strlen(string); i++) + { + if (string[i] == c) + { + tally++; + } + } + + return tally; +} + + /* Hard disks */ static void loadconfig_hard_disks(void) { @@ -1226,7 +1253,15 @@ static void loadconfig_hard_disks(void) p = config_get_string(cat, temps, NULL); if (p == NULL) p = "0, 0, 0, 0, none"; - sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, &hdc[c].wp, s); + if (tally_char(p, ',') == 3) + { + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, s); + hdc[c].wp = 0; + } + else + { + sscanf(p, "%" PRIu64 ", %" PRIu64", %" PRIu64 ", %i, %s", &hdc[c].spt, &hdc[c].hpc, &hdc[c].tracks, &hdc[c].wp, s); + } hdc[c].bus = config_string_to_bus(s, 0); @@ -1313,11 +1348,20 @@ static void loadconfig_hard_disks(void) { sprintf(temps2, "%01u:%01u", c >> 1, c & 1); p = config_get_string(cat, temps, temps2); - sscanf(p, "%01u:%01u", &board, &dev); - board &= 3; - dev &= 1; - hdc[c].ide_channel = (board << 1) + dev; + if (strstr(p, ":") == NULL) + { + sscanf(p, "%i", &hdc[c].ide_channel); + hdc[c].ide_channel &= 7; + } + else + { + sscanf(p, "%01u:%01u", &board, &dev); + + board &= 3; + dev &= 1; + hdc[c].ide_channel = (board << 1) + dev; + } if (hdc[c].ide_channel > 7) { @@ -1335,6 +1379,7 @@ static void loadconfig_hard_disks(void) { sprintf(temps2, "%02u:%02u", c, 0); p = config_get_string(cat, temps, temps2); + sscanf(p, "%02u:%02u", &hdc[c].scsi_id, &hdc[c].scsi_lun); if (hdc[c].scsi_id > 15) @@ -1459,11 +1504,20 @@ static void loadconfig_removable_devices(void) { sprintf(temps2, "%01u:%01u", (c + 2) >> 1, (c + 2) & 1); p = config_get_string(cat, temps, temps2); - sscanf(p, "%02u:%02u", &board, &dev); - board &= 3; - dev &= 1; - cdrom_drives[c].ide_channel = (board << 1) + dev; + if (strstr(p, ":") == NULL) + { + sscanf(p, "%i", &hdc[c].ide_channel); + cdrom_drives[c].ide_channel &= 7; + } + else + { + sscanf(p, "%02u:%02u", &board, &dev); + + board &= 3; + dev &= 1; + cdrom_drives[c].ide_channel = (board << 1) + dev; + } if (cdrom_drives[c].ide_channel > 7) { @@ -1748,7 +1802,7 @@ static void saveconfig_machine(void) config_set_int(cat, "cpu_enable_fpu", enable_external_fpu); } - if (enable_sync == 0) + if (enable_sync == 1) { config_delete_var(cat, "enable_sync"); } @@ -1942,7 +1996,7 @@ static void saveconfig_network(void) } else { - config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "pcap" : "slirp"); + config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "slirp" : "pcap"); } if (network_pcap[0] != '\0') diff --git a/src/disc.c b/src/disc.c index 74c779296..6bd93cb59 100644 --- a/src/disc.c +++ b/src/disc.c @@ -17,6 +17,9 @@ #include "fdd.h" #include "timer.h" +wchar_t discfns[4][256]; +extern int driveempty[4]; + int disc_poll_time[FDD_NUM] = { 16, 16, 16, 16 }; int disc_track[FDD_NUM]; diff --git a/src/disc_86f.c b/src/disc_86f.c index bfb8f6f50..bca91ca74 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -3041,7 +3041,7 @@ void d86f_load(int drive, wchar_t *fn) d86f[drive].f = _wfopen(fn, L"rb"); if (!d86f[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } writeprot[drive] = 1; @@ -3062,7 +3062,7 @@ void d86f_load(int drive, wchar_t *fn) { /* File is WAY too small, abort. */ fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3071,7 +3071,7 @@ void d86f_load(int drive, wchar_t *fn) /* File is not of the valid format, abort. */ d86f_log("86F: Unrecognized magic bytes: %08X\n", magic); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3109,7 +3109,7 @@ void d86f_load(int drive, wchar_t *fn) { /* File too small, abort. */ fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3131,7 +3131,7 @@ void d86f_load(int drive, wchar_t *fn) { d86f_log("86F: CRC64 error\n"); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } #endif @@ -3147,7 +3147,7 @@ void d86f_load(int drive, wchar_t *fn) if (!d86f[drive].f) { d86f_log("86F: Unable to create temporary decompressed file\n"); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3177,7 +3177,7 @@ void d86f_load(int drive, wchar_t *fn) { d86f_log("86F: Error decompressing file\n"); _wremove(temp_file_name); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3193,7 +3193,7 @@ void d86f_load(int drive, wchar_t *fn) { _wremove(temp_file_name); } - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3206,7 +3206,7 @@ void d86f_load(int drive, wchar_t *fn) { _wremove(temp_file_name); } - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -3239,16 +3239,16 @@ void d86f_load(int drive, wchar_t *fn) /* File has no track 0 side 0, abort. */ d86f_log("86F: No Track 0 side 0\n"); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } if ((d86f_get_sides(drive) == 2) && !(d86f[drive].track_offset[1])) { /* File is 2-sided but has no track 0 side 1, abort. */ - d86f_log("86F: No Track 0 side 0\n"); + d86f_log("86F: No Track 0 side 1\n"); fclose(d86f[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } diff --git a/src/disc_fdi.c b/src/disc_fdi.c index bf8410e91..62875d8e4 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -248,7 +248,7 @@ void fdi_load(int drive, wchar_t *fn) fdi[drive].f = _wfopen(fn, L"rb"); if (!fdi[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } diff --git a/src/disc_imd.c b/src/disc_imd.c index fcbed568d..f932f4fd4 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -80,7 +80,7 @@ void imd_load(int drive, wchar_t *fn) imd[drive].f = _wfopen(fn, L"rb"); if (!imd[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } writeprot[drive] = 1; @@ -97,7 +97,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: Not a valid ImageDisk image\n"); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -118,7 +118,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: No ASCII EOF character\n"); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -131,7 +131,7 @@ void imd_load(int drive, wchar_t *fn) { pclog("IMD: File ends after ASCII EOF character\n"); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -250,7 +250,7 @@ void imd_load(int drive, wchar_t *fn) /* If we can't fit the sectors with a reasonable minimum gap even at 2% slower RPM, abort. */ pclog("IMD: Unable to fit the %i sectors in a track\n", track_spt); fclose(imd[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } } diff --git a/src/disc_img.c b/src/disc_img.c index 0391820d0..d529db045 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -337,7 +337,7 @@ void img_load(int drive, wchar_t *fn) img[drive].f = _wfopen(fn, L"rb"); if (!img[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } writeprot[drive] = 1; @@ -736,7 +736,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } } @@ -798,7 +798,7 @@ jump_if_fdf: { pclog("Image is bigger than can fit on an ED floppy, ejecting...\n"); fclose(img[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } @@ -815,7 +815,7 @@ jump_if_fdf: { pclog("ERROR: Floppy image of unknown format was inserted into drive %c:!\n", drive + 0x41); fclose(img[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } diff --git a/src/disc_td0.c b/src/disc_td0.c index c63a62dc5..e20020fcc 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -511,7 +511,7 @@ void td0_load(int drive, wchar_t *fn) td0[drive].f = _wfopen(fn, L"rb"); if (!td0[drive].f) { - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } fwriteprot[drive] = writeprot[drive]; @@ -521,7 +521,7 @@ void td0_load(int drive, wchar_t *fn) { pclog("TD0: Not a valid Teledisk image\n"); fclose(td0[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else @@ -536,7 +536,7 @@ void td0_load(int drive, wchar_t *fn) { pclog("TD0: Failed to initialize\n"); fclose(td0[drive].f); - update_status_bar_icon_state(drive, 1); + memset(discfns[drive], 0, sizeof(discfns[drive])); return; } else diff --git a/src/dma.c b/src/dma.c index 259401dee..29804cd82 100644 --- a/src/dma.c +++ b/src/dma.c @@ -12,9 +12,12 @@ static uint8_t dmaregs[16]; static uint8_t dma16regs[16]; static uint8_t dmapages[16]; +DMA dma, dma16; + void dma_reset(void) { +#if 0 int c; dma.wp = 0; for (c = 0; c < 16; c++) @@ -41,6 +44,12 @@ void dma_reset(void) dma16.cb[c] = 0; } dma16.m = 0; +#endif + memset(dmaregs, 0, 16); + memset(dma16regs, 0, 16); + memset(dmapages, 0, 16); + memset(&dma, 0, sizeof(DMA)); + memset(&dma16, 0, sizeof(DMA)); } uint8_t dma_read(uint16_t addr, void *priv) diff --git a/src/fdc.c b/src/fdc.c index 6392d41ac..60c2b44d3 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -130,6 +130,8 @@ typedef struct FDC uint16_t base_address; } FDC; +int disctime; + static FDC fdc; void fdc_callback(); @@ -958,7 +960,6 @@ bad_command: } disctime = 0; update_status_bar_icon(SB_FLOPPY | fdc.drive, 1); - readflash = 1; fdc.inread = 1; break; diff --git a/src/ibm.h b/src/ibm.h index 4b01f1584..e9c00c15c 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -9,15 +9,15 @@ /*Memory*/ -uint8_t *ram; -uint32_t rammask; +extern uint8_t *ram; +extern uint32_t rammask; -int readlookup[256],readlookupp[256]; -uintptr_t *readlookup2; -int readlnext; -int writelookup[256],writelookupp[256]; -uintptr_t *writelookup2; -int writelnext; +extern int readlookup[256],readlookupp[256]; +extern uintptr_t *readlookup2; +extern int readlnext; +extern int writelookup[256],writelookupp[256]; +extern uintptr_t *writelookup2; +extern int writelnext; extern int mmu_perm; @@ -162,7 +162,7 @@ struct #define cycles cpu_state._cycles -uint32_t cpu_cur_status; +extern uint32_t cpu_cur_status; #define CPU_STATUS_USE32 (1 << 0) #define CPU_STATUS_STACK32 (1 << 1) @@ -186,18 +186,18 @@ COMPILE_TIME_ASSERT(sizeof(cpu_state) <= 128) /*x86reg regs[8];*/ -uint16_t flags,eflags; -uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; +extern uint16_t flags,eflags; +extern uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; extern int ins,output; extern int cycdiff; -x86seg gdt,ldt,idt,tr; -x86seg _cs,_ds,_es,_ss,_fs,_gs; -x86seg _oldds; +extern x86seg gdt,ldt,idt,tr; +extern x86seg _cs,_ds,_es,_ss,_fs,_gs; +extern x86seg _oldds; -uint32_t pccache; -uint8_t *pccache2; +extern uint32_t pccache; +extern uint8_t *pccache2; /*Segments - _cs,_ds,_es,_ss are the segment structures CS,DS,ES,SS is the 16-bit data @@ -229,8 +229,8 @@ union #define cr0 CR0.l #define msw CR0.w -uint32_t cr2, cr3, cr4; -uint32_t dr[8]; +extern uint32_t cr2, cr3, cr4; +extern uint32_t dr[8]; #define C_FLAG 0x0001 #define P_FLAG 0x0004 @@ -328,7 +328,7 @@ typedef struct DMA uint8_t ps2_mode[4]; } DMA; -DMA dma,dma16; +extern DMA dma, dma16; /*PPI*/ @@ -338,7 +338,7 @@ typedef struct PPI uint8_t pa,pb; } PPI; -PPI ppi; +extern PPI ppi; /*PIC*/ @@ -350,13 +350,13 @@ typedef struct PIC int read; } PIC; -PIC pic,pic2; +extern PIC pic, pic2; extern int pic_intpending; -int disctime; -wchar_t discfns[4][256]; -int driveempty[4]; +extern int disctime; +extern wchar_t discfns[4][256]; +extern int driveempty[4]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_HERCULESPLUS || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset=ROM_IBMAT)) #define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && gfxcard!=GFX_COMPAQ_EGA && gfxcard!=GFX_SUPER_EGA && gfxcard!=GFX_HERCULESPLUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200) @@ -456,14 +456,15 @@ enum ROM_CMDPC60, ROM_S1668, /*Tyan Titan-Pro ATX / 440FX / AMI BIOS / SMC FDC37C669*/ + ROM_IBMPS1_2133, ROM_MAX }; extern int romspresent[ROM_MAX]; -int hasfpu; -int romset; +extern int hasfpu; +extern int romset; enum { @@ -525,7 +526,6 @@ int cpuspeed; /*Video*/ -int readflash; extern int egareads,egawrites; extern int vid_resize; extern int vid_api; @@ -534,12 +534,12 @@ extern int changeframecount; /*Sound*/ -int ppispeakon; -float CGACONST; -float MDACONST; -float VGACONST1,VGACONST2; -float RTCCONST; -int gated,speakval,speakon; +extern int ppispeakon; +extern float CGACONST; +extern float MDACONST; +extern float VGACONST1,VGACONST2; +extern float RTCCONST; +extern int gated,speakval,speakon; #define SOUNDBUFLEN (48000/20) @@ -556,7 +556,7 @@ int gated,speakval,speakon; #define SND_WSS 9 /*Windows Sound System*/ #define SND_PAS16 10 /*Pro Audio Spectrum 16*/ -wchar_t pcempath[512]; +extern wchar_t pcempath[512]; /*Hard disk*/ @@ -604,8 +604,6 @@ typedef struct { extern hard_disk_t hdc[HDC_NUM]; -FILE *shdf[HDC_NUM]; - uint64_t hdt[128][3]; uint64_t hdt_mfm[128][3]; @@ -613,7 +611,7 @@ int image_is_hdi(const wchar_t *s); int image_is_hdx(const wchar_t *s, int check_signature); /*Keyboard*/ -int keybsenddelay; +extern int keybsenddelay; /*CD-ROM*/ @@ -681,7 +679,7 @@ extern int path_len; wchar_t *nvr_concat(wchar_t *to_concat); -int mem_a20_state; +extern int mem_a20_state; #ifdef ENABLE_LOG_TOGGLES @@ -735,6 +733,7 @@ extern void execx86(int cycs); extern void flushmmucache(void); extern void flushmmucache_cr3(void); extern int idivl(int32_t val); +extern void initmodules(void); extern void initpc(int argc, wchar_t *argv[]); extern void loadcscall(uint16_t seg); extern void loadcsjmp(uint16_t seg, uint32_t oxpc); diff --git a/src/ide.c b/src/ide.c index 7f1000264..dbea750bd 100644 --- a/src/ide.c +++ b/src/ide.c @@ -761,6 +761,7 @@ void resetide(void) idecallback[0]=idecallback[1]=0; idecallback[2]=idecallback[3]=0; + idecallback[4]=0; c = 0; for (d = 0; d < HDC_NUM; d++) @@ -774,7 +775,7 @@ void resetide(void) } if ((hdc[d].bus == HDD_BUS_XTIDE) && (hdc[d].xtide_channel < XTIDE_NUM)) { - pclog("Found XTIDE hard disk on channel %i\n", hdc[d].xtide_channel); + pclog("Found XT IDE hard disk on channel %i\n", hdc[d].xtide_channel); loadhd(&ide_drives[hdc[d].xtide_channel | 8], d, hdc[d].fn); c++; if (c >= (IDE_NUM + XTIDE_NUM)) break; @@ -802,12 +803,12 @@ void resetide(void) { ide_set_signature(&ide_drives[d | 8]); - if (ide_drives[d].type == IDE_HDD) + if (ide_drives[d | 8].type == IDE_HDD) { - ide_drives[d].mdma_mode = 0; + ide_drives[d | 8].mdma_mode = 0; } - ide_drives[d].error = 1; + ide_drives[d | 8].error = 1; } for (d = 0; d < 5; d++) diff --git a/src/keyboard.c b/src/keyboard.c index 75ec25887..0ea442618 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -6,6 +6,7 @@ #include "keyboard.h" int keybsendcallback = 0; +int keybsenddelay; typedef struct { diff --git a/src/mem.c b/src/mem.c index b6651ad20..5da6f0866 100644 --- a/src/mem.c +++ b/src/mem.c @@ -46,8 +46,23 @@ mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; static mem_mapping_t romext_mapping; +uint8_t *ram; +uint32_t rammask; + +uint32_t pccache; +uint8_t *pccache2; + +int readlookup[256],readlookupp[256]; +uintptr_t *readlookup2; +int readlnext; +int writelookup[256],writelookupp[256]; +uintptr_t *writelookup2; +int writelnext; + int shadowbios,shadowbios_write; +int mem_a20_state; + static unsigned char isram[0x10000]; static uint8_t ff_array[0x1000]; @@ -467,6 +482,14 @@ int loadbios() biosmask = 0x1ffff; return 1; + case ROM_IBMPS1_2133: + f = romfopen(L"roms/ibmps1_2133/PS1_2133_52G2974_ROM.bin", L"rb"); + if (!f) break; + fread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_DESKPRO_386: f=romfopen(L"roms/deskpro386/109592-005.U11.bin",L"rb"); ff=romfopen(L"roms/deskpro386/109591-005.U13.bin",L"rb"); diff --git a/src/model.c b/src/model.c index b428c3628..2f62d6374 100644 --- a/src/model.c +++ b/src/model.c @@ -89,6 +89,7 @@ void at_ide_init(); void deskpro386_init(); void ps1_m2011_init(); void ps1_m2121_init(); +void ps1_m2133_init(); void ps2_m30_286_init(); void ps2_model_50_init(); void ps2_model_55sx_init(); @@ -129,6 +130,8 @@ PCI_RESET pci_reset_handler; int serial_enabled[2] = { 0, 0 }; int lpt_enabled = 0, bugger_enabled = 0; +int romset; + MODEL models[] = { {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, @@ -176,6 +179,7 @@ MODEL models[] = {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, + {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, ps1_m2133_init, NULL}, {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_dtk486_init, NULL}, @@ -187,19 +191,19 @@ MODEL models[] = {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_mb500n_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p54tp4xe_init, NULL}, - {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_ap53_init, NULL}, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p55t2s_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_acerm3a_init, NULL}, - {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 512, 1, at_p55t2p4_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p54tp4xe_init, NULL}, + {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_ap53_init, NULL}, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2s_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerm3a_init, NULL}, + {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerv35n_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2p4_init, NULL}, {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL}, {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL}, {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55tvp4_init, NULL}, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 1024, 1, at_i440fx_init, NULL}, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 1024, 1, at_s1668_init, NULL}, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i440fx_init, NULL}, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_s1668_init, NULL}, {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; @@ -445,6 +449,13 @@ void ps1_m2121_init() fdc_set_ps1(); } +void ps1_m2133_init() +{ + ps1_common_init(); + ps1mb_m2133_init(); + fdc_set_ps1(); +} + void ps2_m30_286_init() { AT = 1; diff --git a/src/mouse.c b/src/mouse.c index 3e11903dc..08850d4d7 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -14,8 +14,8 @@ static mouse_t *mouse_list[] = { &mouse_bus, /* 3 Logitech Bus Mouse 2-button */ &mouse_amstrad, /* 4 Amstrad PC System Mouse */ &mouse_olim24, /* 5 Olivetti M24 System Mouse */ -#if 0 &mouse_msystems, /* 6 Mouse Systems */ +#if 0 &mouse_genius, /* 7 Genius Bus Mouse */ #endif NULL diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 8afe9b3b3..6a2c9ef34 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -28,6 +28,7 @@ typedef struct mouse_serial_t { delay; int oldb; SERIAL *serial; + int is_ms_format; } mouse_serial_t; @@ -50,11 +51,12 @@ sermouse_timer(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; ms->delay = 0; - if (ms->pos == -1) { - ms->pos = 0; + if (ms->pos == -1) + { + ms->pos = 0; - /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M'); + /* This identifies a two-button Microsoft Serial mouse. */ + serial_write_fifo(ms->serial, 'M'); } } @@ -130,3 +132,61 @@ mouse_t mouse_serial_microsoft = { sermouse_close, sermouse_poll }; + +static uint8_t +mssystems_mouse_poll(int x, int y, int z, int b, void *priv) +{ + mouse_serial_t *ms = (mouse_serial_t *)priv; + uint8_t data[5]; + + if (!x && !y && b == ms->oldb) return(1); + + ms->oldb = b; + + y=-y; + + if (x>127) x = 127; + if (y>127) y = 127; + if (x<-128) x = -128; + if (y<-128) y = -128; + + data[0] = 0x80 | ((((b & 0x04) >> 1) + ((b & 0x02) << 1) + (b & 0x01)) ^ 0x07); + data[1] = x; + data[2] = y; + data[3] = 0; + data[4] = 0; + + pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); + + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); + serial_write_fifo(ms->serial, data[3]); + serial_write_fifo(ms->serial, data[4]); + + return(0); +} + +static void * +mssystems_mouse_init(void) +{ + mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(ms, 0x00, sizeof(mouse_serial_t)); + ms->port = SERMOUSE_PORT; + + /* Attach a serial port to the mouse. */ + ms->serial = serial_attach(ms->port, sermouse_callback, ms); + + timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); + + return(ms); +} + +mouse_t mouse_msystems = { + "Mouse Systems Mouse (serial)", + "mssystems", + MOUSE_TYPE_MSYSTEMS, + mssystems_mouse_init, + sermouse_close, + mssystems_mouse_poll +}; \ No newline at end of file diff --git a/src/mouse_serial.h b/src/mouse_serial.h index f37b32da2..c76dce483 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -22,6 +22,7 @@ extern mouse_t mouse_serial_microsoft; +extern mouse_t mouse_msystems; #endif /*MOUSE_SERIAL_H*/ diff --git a/src/net_pcap.c b/src/net_pcap.c index a1b2292b0..1d137450a 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -144,6 +144,16 @@ network_pcap_init(netdev_t *list) } +/* Initialize the (Win)Pcap module for use. */ +void +network_pcap_reset(void) +{ + /* Try loading the DLL. */ + pcap_handle = dynld_module("wpcap.dll", pcap_imports); + return; +} + + /* Initialize WinPcap for us. */ int network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) @@ -156,11 +166,26 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) /* Did we already load the DLL? */ if (pcap_handle == NULL) return(-1); +#if 1 + /* Get the value of our capture interface. */ + dev = network_pcap; + if (dev == NULL) { + pclog(" PCap device is a null pointer!\n"); + return(-1); + } + if ((dev[0] == '\0') || !strcmp(dev, "none")) { + pclog(" No network device configured!\n"); + return(-1); + } + pclog(" Network interface: '%s'\n", dev); +#endif + strcpy(temp, f_pcap_lib_version()); dev = strchr(temp, '('); if (dev != NULL) *(dev-1) = '\0'; pclog("PCAP: initializing, %s\n", temp); +#if 0 /* Get the value of our capture interface. */ dev = network_pcap; if ((dev[0] == '\0') || !strcmp(dev, "none")) { @@ -168,6 +193,7 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) return(-1); } pclog(" Network interface: '%s'\n", dev); +#endif pcap = f_pcap_open_live(dev, /* interface name */ 1518, /* maximum packet size */ diff --git a/src/network.c b/src/network.c index 14c62fb95..a707be3b0 100644 --- a/src/network.c +++ b/src/network.c @@ -63,8 +63,10 @@ network_init(void) { int i; +#if 0 network_type = NET_TYPE_NONE; network_card = 0; +#endif /* Create a first device entry that's always there, as needed by UI. */ strcpy(network_devs[0].device, "none"); @@ -75,6 +77,8 @@ network_init(void) i = network_pcap_init(&network_devs[network_ndev]); if (i > 0) network_ndev += i; + + if (network_type != NET_TYPE_PCAP) network_pcap_close(); } @@ -153,7 +157,7 @@ network_reset(void) /* If no active card, we're done. */ if ((network_type==NET_TYPE_NONE) || (network_card==0)) return; - i = network_pcap_init(&network_devs[network_ndev]); + if (network_type==NET_TYPE_PCAP) network_pcap_reset(); pclog("NETWORK: set up for %s, card='%s'\n", (network_type==NET_TYPE_SLIRP)?"SLiRP":"WinPcap", diff --git a/src/network.h b/src/network.h index b8b98e2ae..f36c87a5e 100644 --- a/src/network.h +++ b/src/network.h @@ -63,6 +63,7 @@ extern void network_reset(void); extern void network_tx(uint8_t *, int); extern int network_pcap_init(netdev_t *); +extern void network_pcap_reset(void); extern int network_pcap_setup(uint8_t *, NETRXCB, void *); extern void network_pcap_close(void); extern void network_pcap_in(uint8_t *, int); diff --git a/src/nvr.c b/src/nvr.c index f3490260a..56a1d7e20 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -245,6 +245,7 @@ void loadnvr() case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"rb"); nvrmask = 127; break; case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"rb"); nvrmask = 127; break; case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"rb"); nvrmask = 127; break; + case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"rb"); nvrmask = 127; break; default: return; } if (!f) @@ -329,6 +330,7 @@ void savenvr() case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"wb"); break; case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"wb"); break; case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"wb"); break; + case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"wb"); break; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/pc.c b/src/pc.c index 5d6dc4244..2588eda45 100644 --- a/src/pc.c +++ b/src/pc.c @@ -64,6 +64,8 @@ #endif +wchar_t pcempath[512]; + wchar_t nvr_path[1024]; int path_len; @@ -261,8 +263,6 @@ void pc_reset(void) setpitclock(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed); else setpitclock(14318184.0); - - ali1429_reset(); } @@ -271,7 +271,7 @@ void initpc(int argc, wchar_t *argv[]) { wchar_t *p; wchar_t *config_file = NULL; - int c, i; + int c; FILE *ff; get_executable_name(pcempath, 511); pclog("executable_name = %ws\n", pcempath); @@ -330,13 +330,6 @@ void initpc(int argc, wchar_t *argv[]) } } - /* Initialize modules. */ - network_init(); - mouse_init(); - midi_init(); - serial_init(); - disc_random_init(); - if (config_file == NULL) { append_filename_w(config_file_default, pcempath, L"86box.cfg", 511); @@ -348,8 +341,22 @@ void initpc(int argc, wchar_t *argv[]) loadconfig(config_file); pclog("Config loaded\n"); +#if 0 if (config_file) saveconfig(); +#endif +} + +void initmodules(void) +{ + int i; + + /* Initialize modules. */ + network_init(); + mouse_init(); + midi_init(); + serial_init(); + disc_random_init(); joystick_init(); @@ -464,7 +471,9 @@ void resetpchard(void) suppress_overscan = 0; savenvr(); +#if 0 saveconfig(); +#endif device_close_all(); mouse_emu_close(); @@ -499,7 +508,7 @@ void resetpchard(void) for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type) + if (cdrom_drives[i].bus_type == CDROM_BUS_SCSI) { SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); } diff --git a/src/pic.c b/src/pic.c index 128089924..7c20125e9 100644 --- a/src/pic.c +++ b/src/pic.c @@ -8,6 +8,8 @@ int intclear; int keywaiting=0; int pic_intpending; +PIC pic, pic2; + void pic_updatepending() { uint16_t temp_pending = 0; diff --git a/src/pit.c b/src/pit.c index b735656a5..53169d27f 100644 --- a/src/pit.c +++ b/src/pit.c @@ -25,6 +25,11 @@ double PITCONST; float cpuclock; float isa_timing, bus_timing; +float CGACONST; +float MDACONST; +float VGACONST1,VGACONST2; +float RTCCONST; + int firsttime=1; void setpitclock(float clock) { diff --git a/src/ppi.c b/src/ppi.c index e5d5a27ec..dfb315e2c 100644 --- a/src/ppi.c +++ b/src/ppi.c @@ -13,6 +13,9 @@ #include "plat_keyboard.h" #include "plat_mouse.h" +PPI ppi; +int ppispeakon; + void ppi_reset() { ppi.pa=0x0; diff --git a/src/ps1.c b/src/ps1.c index d54df75af..97b319e75 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -304,3 +304,23 @@ void ps1mb_m2121_init() mem_remap_top_384k(); } + +void ps1mb_m2133_init() +{ + io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0094, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0102, 0x0004, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + io_sethandler(0x0190, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); + + ps1_190 = 0; + + lpt1_remove(); + lpt2_remove(); + lpt1_init(0x3bc); + + serial_remove(1); + serial_remove(2); + + mem_remap_top_384k(); +} diff --git a/src/ps1.h b/src/ps1.h index d58466d69..506983665 100644 --- a/src/ps1.h +++ b/src/ps1.h @@ -3,3 +3,4 @@ */ void ps1mb_init(); void ps1mb_m2121_init(); +void ps1mb_m2133_init(); diff --git a/src/scsi.c b/src/scsi.c index c01458d44..4a2ce29fb 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -120,4 +120,10 @@ void SCSIReset(uint8_t id, uint8_t lun) SCSIDevices[id][lun].LunType = SCSI_NONE; } } + + if(SCSIDevices[id][lun].CmdBuffer != NULL) + { + free(SCSIDevices[id][lun].CmdBuffer); + SCSIDevices[id][lun].CmdBuffer = NULL; + } } diff --git a/src/scsi.h b/src/scsi.h index e07317a77..8c3efc3b5 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -230,7 +230,7 @@ extern int prev_status; struct { - uint8_t CmdBuffer[390144]; + uint8_t *CmdBuffer; uint32_t CmdBufferLength; int LunType; uint32_t InitLength; diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index f3c9bbbe2..10e03cca6 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -1101,6 +1101,14 @@ aha_buf_alloc(Req_t *req, int Is24bit) pclog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { @@ -1280,6 +1288,12 @@ aha_buf_free(Req_t *req) req->CmdBlock.new.DataLength); } } + + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } } @@ -1955,9 +1969,6 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) SCSIStatus = SCSI_STATUS_OK; SCSIDevices[Id][Lun].InitLength = 0; - /* Do this here, so MODE SELECT data does not get lost in transit. */ - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - aha_buf_alloc(req, req->Is24bit); if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 88c660eb5..5de27579b 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -757,6 +757,14 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) pclog("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); + if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND_RES) { @@ -936,6 +944,12 @@ BuslogicDataBufferFree(Req_t *req) req->CmdBlock.new.DataLength); } } + + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) + { + free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; + } } @@ -1799,9 +1813,6 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb SCSIStatus = SCSI_STATUS_OK; SCSIDevices[Id][Lun].InitLength = 0; - /* Do this here, so MODE SELECT data does not get lost in transit. */ - memset(SCSIDevices[Id][Lun].CmdBuffer, 0, 390144); - BuslogicDataBufferAllocate(req, req->Is24bit); if (SCSIDevices[Id][Lun].LunType == SCSI_NONE) { diff --git a/src/scsi_disk.c b/src/scsi_disk.c index f6c76eb95..268fba97f 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -45,6 +45,8 @@ scsi_hard_disk_t shdc[HDC_NUM]; +FILE *shdf[HDC_NUM]; + uint8_t scsi_hard_disks[16][8] = { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }, @@ -202,7 +204,8 @@ void scsi_disk_insert(uint8_t id) shdc[id].unit_attention = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; } -char empty_sector[512]; +static char empty_sector[512]; +static char *empty_sector_1mb; void scsi_loadhd(int scsi_id, int scsi_lun, int id) { @@ -212,7 +215,7 @@ void scsi_loadhd(int scsi_id, int scsi_lun, int id) uint64_t full_size = 0; uint64_t spt = 0, hpc = 0, tracks = 0; int c; - uint64_t i = 0, s = 0;; + uint64_t i = 0, s = 0, t = 0; wchar_t *fn = hdc[id].fn; memset(empty_sector, 0, sizeof(empty_sector)); @@ -423,15 +426,35 @@ scsi_hd_load_error: } fseeko64(shdf[id], 0, SEEK_END); - if (ftello64(shdf[id]) != (full_size + shdc[id].base)) + if (ftello64(shdf[id]) < (full_size + shdc[id].base)) { s = (full_size + shdc[id].base) - ftello64(shdf[id]); prepare_new_hard_disk: s >>= 9; - for (i = 0; i < s; i++) + t = (s >> 11) << 11; + s -= t; + t >>= 11; + + empty_sector_1mb = (char *) malloc(1048576); + memset(empty_sector_1mb, 0, 1048576); + + if (s > 0) { - fwrite(empty_sector, 1, 512, shdf[id]); + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } } + + if (t > 0) + { + for (i = 0; i < t; i++) + { + fwrite(empty_sector_1mb, 1, 1045876, shdf[id]); + } + } + + free(empty_sector_1mb); } shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; @@ -447,7 +470,7 @@ void scsi_reloadhd(int id) uint64_t full_size = 0; uint64_t spt = 0, hpc = 0, tracks = 0; int c; - uint64_t i = 0, s = 0;; + uint64_t i = 0, s = 0, t = 0; wchar_t *fn = hdc[id].fn; memset(empty_sector, 0, sizeof(empty_sector)); @@ -627,15 +650,35 @@ scsi_hd_reload_error: } fseeko64(shdf[id], 0, SEEK_END); - if (ftello64(shdf[id]) != (full_size + shdc[id].base)) + if (ftello64(shdf[id]) < (full_size + shdc[id].base)) { s = (full_size + shdc[id].base) - ftello64(shdf[id]); reload_prepare_new_hard_disk: s >>= 9; - for (i = 0; i < s; i++) + t = (s >> 11) << 11; + s -= t; + t >>= 11; + + empty_sector_1mb = (char *) malloc(1048576); + memset(empty_sector_1mb, 0, 1048576); + + if (s > 0) { - fwrite(empty_sector, 1, 512, shdf[id]); + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, shdf[id]); + } } + + if (t > 0) + { + for (i = 0; i < t; i++) + { + fwrite(empty_sector_1mb, 1, 1045876, shdf[id]); + } + } + + free(empty_sector_1mb); } shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; @@ -874,24 +917,6 @@ static void scsi_hd_not_ready(uint8_t id) scsi_hd_cmd_error(id); } -#if 0 -static void scsi_hd_icmd_required(uint8_t id) -{ - scsi_hd_sense_key = SENSE_NOT_READY; - scsi_hd_asc = ASC_NOT_READY; - scsi_hd_ascq = ASCQ_INITIALIZING_COMMAND_REQUIRED; - scsi_hd_cmd_error(id); -} - -static void scsi_hd_capacity_data_changed(uint8_t id) -{ - scsi_hd_sense_key = SENSE_UNIT_ATTENTION; - scsi_hd_asc = ASC_CAPACITY_DATA_CHANGED; - scsi_hd_ascq = ASCQ_CAPACITY_DATA_CHANGED; - scsi_hd_cmd_error(id); -} -#endif - static void scsi_hd_write_protected(uint8_t id) { scsi_hd_sense_key = SENSE_UNIT_ATTENTION; @@ -1166,11 +1191,10 @@ void scsi_hd_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_l scsi_hd_request_sense(id, buffer, alloc_length); } -int scsi_hd_read_from_dma(uint8_t id); - void scsi_hd_command(uint8_t id, uint8_t *cdb) { - uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; + /* uint8_t *hdbufferb = (uint8_t *) shdc[id].buffer; */ + uint8_t *hdbufferb = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].CmdBuffer; uint32_t len; int pos=0; int max_len; @@ -1362,8 +1386,6 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len = shdc[id].sector_len; shdc[id].requested_blocks = max_len; - scsi_hd_read_from_dma(id); - pos64 = (uint64_t) shdc[id].sector_pos; if (shdc[id].requested_blocks > 0) @@ -1545,72 +1567,6 @@ atapi_out: void scsi_hd_callback(uint8_t id); -int scsi_hd_read_from_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t *hdbufferb; - - uint8_t id = scsi_hard_disks[scsi_id][scsi_lun]; - - hdbufferb = (uint8_t *) shdc[id].buffer; - - if (id > HDC_NUM) - { - return 0; - } - - scsi_hd_log("Reading from SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); - memcpy(hdbufferb, SCSIDevices[scsi_id][scsi_lun].CmdBuffer, SCSIDevices[scsi_id][scsi_lun].InitLength); - return 1; -} - -int scsi_hd_read_from_dma(uint8_t id) -{ - int ret = 0; - - ret = scsi_hd_read_from_scsi_dma(hdc[id].scsi_id, hdc[id].scsi_lun); - - if (!ret) - { - return 0; - } - - return 0; -} - -int scsi_hd_write_to_scsi_dma(uint8_t scsi_id, uint8_t scsi_lun) -{ - uint8_t *hdbufferb; - - uint8_t id = scsi_hard_disks[scsi_id][scsi_lun]; - - if (id > HDC_NUM) - { - return 0; - } - - hdbufferb = (uint8_t *) shdc[id].buffer; - - scsi_hd_log("Writing to SCSI DMA: SCSI ID %02X, init length %i\n", scsi_id, SCSIDevices[scsi_id][scsi_lun].InitLength); - memcpy(SCSIDevices[scsi_id][scsi_lun].CmdBuffer, hdbufferb, SCSIDevices[scsi_id][scsi_lun].InitLength); - scsi_hd_log("SCSI HD %i: Data from HD buffer: %02X %02X %02X %02X %02X %02X %02X %02X\n", id, hdbufferb[0], hdbufferb[1], hdbufferb[2], hdbufferb[3], hdbufferb[4], hdbufferb[5], hdbufferb[6], hdbufferb[7]); - scsi_hd_log("SCSI HD %i: Data from SCSI DMA : %02X %02X %02X %02X %02X %02X %02X %02X\n", id, SCSIDevices[scsi_id][scsi_lun].CmdBuffer[0], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[1], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[2], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[3], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[4], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[5], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[6], SCSIDevices[scsi_id][scsi_lun].CmdBuffer[7]); - return 1; -} - -int scsi_hd_write_to_dma(uint8_t id) -{ - int ret = 0; - - ret = scsi_hd_write_to_scsi_dma(hdc[id].scsi_id, hdc[id].scsi_lun); - - if (!ret) - { - return 0; - } - - return 1; -} - /* If the result is 1, issue an IRQ, otherwise not. */ void scsi_hd_callback(uint8_t id) { @@ -1622,12 +1578,6 @@ void scsi_hd_callback(uint8_t id) shdc[id].phase = 1; shdc[id].status = READY_STAT | DRQ_STAT | (shdc[id].status & ERR_STAT); return; - case CDROM_PHASE_COMMAND: - scsi_hd_log("SCSI HD %i: PHASE_COMMAND\n", id); - shdc[id].status = BUSY_STAT | (shdc[id].status &ERR_STAT); - memcpy(shdc[id].hd_cdb, (uint8_t *) shdc[id].buffer, shdc[id].cdb_len); - scsi_hd_command(id, shdc[id].hd_cdb); - return; case CDROM_PHASE_COMPLETE: scsi_hd_log("SCSI HD %i: PHASE_COMPLETE\n", id); shdc[id].status = READY_STAT; @@ -1642,7 +1592,6 @@ void scsi_hd_callback(uint8_t id) return; case CDROM_PHASE_DATA_OUT_DMA: scsi_hd_log("SCSI HD %i: PHASE_DATA_OUT_DMA\n", id); - scsi_hd_read_from_dma(id); shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; @@ -1655,7 +1604,6 @@ void scsi_hd_callback(uint8_t id) return; case CDROM_PHASE_DATA_IN_DMA: scsi_hd_log("SCSI HD %i: PHASE_DATA_IN_DMA\n", id); - scsi_hd_write_to_dma(id); shdc[id].packet_status = CDROM_PHASE_COMPLETE; shdc[id].status = READY_STAT; shdc[id].phase = 3; diff --git a/src/scsi_disk.h b/src/scsi_disk.h index 59d210e69..233c04fd1 100644 --- a/src/scsi_disk.h +++ b/src/scsi_disk.h @@ -20,7 +20,6 @@ typedef struct { uint8_t sense[256]; uint8_t previous_command; uint8_t error; - uint16_t buffer[390144]; uint32_t sector_pos; uint32_t sector_len; uint32_t last_sector; @@ -41,3 +40,5 @@ extern void scsi_disk_insert(uint8_t id); extern void scsi_loadhd(int scsi_id, int scsi_lun, int id); extern void scsi_reloadhd(int id); extern void scsi_unloadhd(int scsi_id, int scsi_lun, int id); + +extern FILE *shdf[HDC_NUM]; From f416613cfa54a1e50e3a541c09ecc58f6edcc9e2 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 29 May 2017 01:29:45 +0200 Subject: [PATCH 256/392] Fixed floppy handling in the IBM PS/1 2133, now floppies work again. --- src/model.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/model.c b/src/model.c index 2f62d6374..7408a0670 100644 --- a/src/model.c +++ b/src/model.c @@ -430,7 +430,10 @@ void ps1_common_init() keyboard_at_init(); nvr_init(); pic2_init(); - fdc_set_dskchg_activelow(); + if (romset != ROM_IBMPS1_2133) + { + fdc_set_dskchg_activelow(); + } device_add(&ps1_audio_device); /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ if (joystick_type != 7) device_add(&gameport_201_device); @@ -453,7 +456,6 @@ void ps1_m2133_init() { ps1_common_init(); ps1mb_m2133_init(); - fdc_set_ps1(); } void ps2_m30_286_init() From 40f7c88982e296545415d1478db8229020a99ce3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 May 2017 01:59:12 +0200 Subject: [PATCH 257/392] Timers, whose enable and/or count pointers are NULL, are now ignored by timer_process(), should fix the random crashes on hard reset. --- src/timer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/timer.c b/src/timer.c index 07cc7c336..d3fd618a7 100644 --- a/src/timer.c +++ b/src/timer.c @@ -39,6 +39,11 @@ void timer_process() for (c = 0; c < timers_present; c++) { + /* This is needed to avoid timer crashes on hard reset. */ + if ((timers[c].enable == NULL) || (timers[c].count == NULL)) + { + continue; + } enable[c] = *timers[c].enable; if (*timers[c].enable) { From 3b0b27f5b636e3326bb817dee44fd7ccfd87280d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 May 2017 02:41:07 +0200 Subject: [PATCH 258/392] The PCap setup routine now again correctly sets dev to network_pcap before attempting to initialize PCap. --- src/net_pcap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/net_pcap.c b/src/net_pcap.c index 1d137450a..3e6affcd9 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -193,6 +193,8 @@ network_pcap_setup(uint8_t *mac, NETRXCB func, void *arg) return(-1); } pclog(" Network interface: '%s'\n", dev); +#else + dev = network_pcap; #endif pcap = f_pcap_open_live(dev, /* interface name */ From 974d517cb392b69b2969922205e387a2753b7246 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 29 May 2017 02:47:27 +0200 Subject: [PATCH 259/392] PS/1 audio device removed from the 2133 since it doesn't support it. --- src/model.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/model.c b/src/model.c index 7408a0670..2c88624f2 100644 --- a/src/model.c +++ b/src/model.c @@ -433,8 +433,8 @@ void ps1_common_init() if (romset != ROM_IBMPS1_2133) { fdc_set_dskchg_activelow(); + device_add(&ps1_audio_device); } - device_add(&ps1_audio_device); /*PS/1 audio uses ports 200h and 202-207h, so only initialise gameport on 201h*/ if (joystick_type != 7) device_add(&gameport_201_device); } From b32ac5f096e129eb33f211237942eb499c3b32ec Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 28 May 2017 23:49:06 -0400 Subject: [PATCH 260/392] Fix --- src/Makefile.mingw | 8 ++++---- src/config.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d6cef3cfe..6264531cf 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.17 2017/05/26 +# Version: @(#)Makefile.mingw 1.0.18 2017/05/28 # # Authors: Kotori, # Fred N. van Kempen, @@ -207,9 +207,9 @@ SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ ip_input.o queue.o tcp_input.o debug.o ip_output.o \ sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o -LIBS = -mwindows -lcomctl32 -lwinmm -lopenal.dll -lopenal -lddraw \ - -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lwsock32 -liphlpapi \ - -lstdc++ -lpsapi -static-libstdc++ -static-libgcc +LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ + -mwindows -lcomctl32 -lwinmm -lwsock32 -liphlpapi -lpsapi \ + -static-libstdc++ -static -lstdc++ -static-libgcc -static -lgcc # Build rules. diff --git a/src/config.c b/src/config.c index 6bb2f46e2..1a9941217 100644 --- a/src/config.c +++ b/src/config.c @@ -1942,7 +1942,7 @@ static void saveconfig_network(void) } else { - config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "pcap" : "slirp"); + config_set_string(cat, "net_type", (network_type == NET_TYPE_SLIRP) ? "slirp" : "pcap"); } if (network_pcap[0] != '\0') From 761292e9f159f6e83d2f05f722a8fde7a32997c5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 May 2017 06:17:13 +0200 Subject: [PATCH 261/392] Added sanity checks to SCSI hard disk emulation and made changes to the dynamic SCSI data buffer allocation, fixes problems when less data is requested for the INQUIRY command than it would actually need. --- src/WIN/win.c | 7 -- src/pc.c | 8 --- src/scsi_aha154x.c | 32 ++++----- src/scsi_buslogic.c | 28 ++++---- src/scsi_disk.c | 163 ++++++++++++++++++++++++-------------------- 5 files changed, 118 insertions(+), 120 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 0f1d77e99..3abbcf894 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1442,26 +1442,19 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz ghwnd=hwnd; -printf("hwndRender;\n"); hwndRender = CreateWindow(L"STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_BITMAP, 0, 0, 1, 1, ghwnd, NULL, hinstance, NULL); -printf("initpc();\n"); initpc(argc, argv); -printf("init_cdrom_host_drives();\n"); init_cdrom_host_drives(); -printf("EmulatorStatusBar();\n"); hwndStatus = EmulatorStatusBar(hwnd, IDC_STATUS, hThisInstance); -printf("OriginalStatusBarProcedure;\n"); OriginalStatusBarProcedure = GetWindowLongPtr(hwndStatus, GWLP_WNDPROC); -printf("SetWindowLongPtr;\n"); SetWindowLongPtr(hwndStatus, GWL_WNDPROC, (LONG_PTR) &StatusBarProcedure); smenu = LoadMenu(hThisInstance, TEXT("StatusBarMenu")); -printf("initmodules();\n"); initmodules(); if (vid_apis[0][vid_api].init(hwndRender) == 0) diff --git a/src/pc.c b/src/pc.c index 2588eda45..6537c8733 100644 --- a/src/pc.c +++ b/src/pc.c @@ -506,14 +506,6 @@ void resetpchard(void) ide_qua_init(); } - for (i = 0; i < CDROM_NUM; i++) - { - if (cdrom_drives[i].bus_type == CDROM_BUS_SCSI) - { - SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); - } - } - resetide(); scsi_card_init(); diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 10e03cca6..2a80b626a 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -1090,6 +1090,7 @@ aha_buf_alloc(Req_t *req, int Is24bit) uint32_t sg_buffer_pos = 0; uint32_t DataPointer, DataLength; uint32_t SGEntryLength = (Is24bit ? sizeof(SGE) : sizeof(SGE32)); + uint32_t Address; if (Is24bit) { DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); @@ -1106,8 +1107,6 @@ aha_buf_alloc(Req_t *req, int Is24bit) free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; } - SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); - memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || @@ -1126,8 +1125,6 @@ aha_buf_alloc(Req_t *req, int Is24bit) aha_rd_sge(Is24bit, SGAddrCurrent, SGRead, SGBuffer); for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - uint32_t Address; - pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); Address = SGBuffer[ScatterEntry].SegmentPointer; @@ -1143,6 +1140,10 @@ aha_buf_alloc(Req_t *req, int Is24bit) SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + pclog("Allocating buffer for Scatter/Gather (%i bytes)\n", DataToTransfer); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer); + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without checking its length, so do this procedure for both no read/write commands. */ if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || @@ -1158,8 +1159,6 @@ aha_buf_alloc(Req_t *req, int Is24bit) SGRead, SGBuffer); for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - uint32_t Address; - pclog("BusLogic S/G Write: ScatterEntry=%u\n", ScatterEntry); Address = SGBuffer[ScatterEntry].SegmentPointer; @@ -1176,9 +1175,14 @@ aha_buf_alloc(Req_t *req, int Is24bit) } } else if (req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND || req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { - uint32_t Address = DataPointer; + Address = DataPointer; SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + + pclog("Allocating buffer for direct transfer (%i bytes)\n", DataLength); + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); + if (DataLength > 0) { DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, @@ -1203,6 +1207,7 @@ aha_buf_free(Req_t *req) uint32_t SGAddrCurrent; uint32_t Address; uint32_t Residual; + uint32_t DataToTransfer; if (req->Is24bit) { DataPointer = ADDR_TO_U32(req->CmdBlock.old.DataPointer); @@ -1243,9 +1248,6 @@ aha_buf_free(Req_t *req) SGRead, SGBuffer); for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - uint32_t Address; - uint32_t DataToTransfer; - pclog("BusLogic S/G: ScatterEntry=%u\n", ScatterEntry); Address = SGBuffer[ScatterEntry].SegmentPointer; @@ -2202,14 +2204,12 @@ aha_init(int chip, int has_bios) if (scsi_hard_disks[i][j] != 0xff) { SCSIDevices[i][j].LunType = SCSI_DISK; } - } - } - - for (i=0; i<16; i++) { - for (j=0; j<8; j++) { - if (find_cdrom_for_scsi_id(i, j) != 0xff) { + else if (find_cdrom_for_scsi_id(i, j) != 0xff) { SCSIDevices[i][j].LunType = SCSI_CDROM; } + else { + SCSIDevices[i][j].LunType = SCSI_NONE; + } } } diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 5de27579b..a691fa699 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -762,8 +762,6 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; } - SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); - memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); if ((req->CmdBlock.common.ControlByte != 0x03) && DataLength) { if (req->CmdBlock.common.Opcode == SCATTER_GATHER_COMMAND || @@ -799,6 +797,9 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer); + /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without checking its length, so do this procedure for both no read/write commands. */ if ((req->CmdBlock.common.ControlByte == CCB_DATA_XFER_OUT) || @@ -835,6 +836,10 @@ BuslogicDataBufferAllocate(Req_t *req, int Is24bit) uint32_t Address = DataPointer; SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; + + SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); + memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); + if (DataLength > 0) { DMAPageRead(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, @@ -2222,22 +2227,17 @@ BuslogicInit(int chip) pclog("Building SCSI CD-ROM map...\n"); build_scsi_cdrom_map(); - for (i=0; i<16; i++) { - for (j=0; j<8; j++) - { - if (scsi_hard_disks[i][j] != 0xff) - { - SCSIDevices[i][j].LunType = SCSI_DISK; - pclog("Found SCSI disk: %02i:%02i\n", i, j); - } - } - } - for (i=0; i<16; i++) { for (j=0; j<8; j++) { - if (find_cdrom_for_scsi_id(i, j) != 0xff) { + if (scsi_hard_disks[i][j] != 0xff) { + SCSIDevices[i][j].LunType = SCSI_DISK; + } + else if (find_cdrom_for_scsi_id(i, j) != 0xff) { SCSIDevices[i][j].LunType = SCSI_CDROM; } + else { + SCSIDevices[i][j].LunType = SCSI_NONE; + } } } diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 268fba97f..369225f00 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -966,41 +966,6 @@ static void scsi_hd_data_phase_error(uint8_t id) scsi_hd_cmd_error(id); } -void scsi_hd_update_cdb(uint8_t *cdb, int lba_pos, int number_of_blocks) -{ - switch(cdb[0]) - { - case GPCMD_READ_6: - case GPCMD_WRITE_6: - cdb[1] = (lba_pos >> 16) & 0xff; - cdb[2] = (lba_pos >> 8) & 0xff; - cdb[3] = lba_pos & 0xff; - break; - - case GPCMD_READ_10: - case GPCMD_WRITE_10: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[7] = (number_of_blocks >> 8) & 0xff; - cdb[8] = number_of_blocks & 0xff; - break; - - case GPCMD_READ_12: - case GPCMD_WRITE_12: - cdb[2] = (lba_pos >> 24) & 0xff; - cdb[3] = (lba_pos >> 16) & 0xff; - cdb[4] = (lba_pos >> 8) & 0xff; - cdb[5] = lba_pos & 0xff; - cdb[6] = (number_of_blocks >> 24) & 0xff; - cdb[7] = (number_of_blocks >> 16) & 0xff; - cdb[8] = (number_of_blocks >> 8) & 0xff; - cdb[9] = number_of_blocks & 0xff; - break; - } -} - /*SCSI Sense Initialization*/ void scsi_hd_sense_code_ok(uint8_t id) { @@ -1124,8 +1089,6 @@ void scsi_hd_reset(uint8_t id) void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) { - int is_ua = 0; - /*Will return 18 bytes of 0*/ if (alloc_length != 0) { @@ -1140,7 +1103,6 @@ void scsi_hd_request_sense(uint8_t id, uint8_t *buffer, uint8_t alloc_length) buffer[2]=SENSE_UNIT_ATTENTION; buffer[12]=ASC_MEDIUM_MAY_HAVE_CHANGED; buffer[13]=0x00; - is_ua = 1; } /* scsi_hd_log("SCSI HD %i: Reporting sense: %02X %02X %02X\n", id, hdbufferb[2], hdbufferb[12], hdbufferb[13]); */ @@ -1203,9 +1165,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) unsigned preamble_len; uint32_t alloc_length; uint64_t pos64; - uint64_t full_size = 0; char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; + char *tempbuffer; #if 0 int CdbLength; @@ -1307,7 +1269,13 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - if (!shdc[id].sector_len) + if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector)) + { + scsi_hd_lba_out_of_range(id); + return; + } + + if ((!shdc[id].sector_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1320,16 +1288,23 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) pos64 = (uint64_t) shdc[id].sector_pos; - if (shdc[id].requested_blocks > 0) + alloc_length = shdc[id].packet_len = max_len << 9; + + if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { shdf[id] = _wfopen(hdc[id].fn, L"rb+"); fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); - memset(hdbufferb, 0, shdc[id].sector_len << 9); - fread(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + { + fread(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]); + } + else + { + fread(hdbufferb, 1, alloc_length, shdf[id]); + } fclose(shdf[id]); } - alloc_length = shdc[id].packet_len = max_len << 9; if (shdc[id].requested_blocks > 1) { scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 0); @@ -1375,7 +1350,13 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - if (!shdc[id].sector_len) + if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector)) + { + scsi_hd_lba_out_of_range(id); + return; + } + + if ((!shdc[id].sector_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) { /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ shdc[id].packet_status = CDROM_PHASE_COMPLETE; @@ -1388,15 +1369,23 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) pos64 = (uint64_t) shdc[id].sector_pos; - if (shdc[id].requested_blocks > 0) + alloc_length = shdc[id].packet_len = max_len << 9; + + if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { shdf[id] = _wfopen(hdc[id].fn, L"rb+"); fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); - fwrite(hdbufferb, 1, (shdc[id].sector_len << 9), shdf[id]); + if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + { + fwrite(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]); + } + else + { + fwrite(hdbufferb, 1, alloc_length, shdf[id]); + } fclose(shdf[id]); } - alloc_length = shdc[id].packet_len = max_len << 9; if (shdc[id].requested_blocks > 1) { scsi_hd_data_command_finish(id, alloc_length, alloc_length / shdc[id].requested_blocks, alloc_length, 1); @@ -1444,22 +1433,32 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len <<= 8; max_len |= cdb[4]; + if ((!max_len) || (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength == 0)) + { + /* scsi_hd_log("SCSI HD %i: All done - callback set\n", id); */ + shdc[id].packet_status = CDROM_PHASE_COMPLETE; + shdc[id].callback = 20 * SCSI_TIME; + break; + } + + tempbuffer = malloc(1024); + if (cdb[1] & 1) { preamble_len = 4; size_idx = 3; - hdbufferb[idx++] = 05; - hdbufferb[idx++] = cdb[2]; - hdbufferb[idx++] = 0; + tempbuffer[idx++] = 05; + tempbuffer[idx++] = cdb[2]; + tempbuffer[idx++] = 0; idx++; switch (cdb[2]) { case 0x00: - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 0x83; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 0x83; break; case 0x83: if (idx + 24 > max_len) @@ -1468,10 +1467,10 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) return; } - hdbufferb[idx++] = 0x02; - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 20; + tempbuffer[idx++] = 0x02; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 20; ide_padstr8(hdbufferb + idx, 20, "53R141"); /* Serial */ idx += 20; @@ -1479,15 +1478,15 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) { goto atapi_out; } - hdbufferb[idx++] = 0x02; - hdbufferb[idx++] = 0x01; - hdbufferb[idx++] = 0x00; - hdbufferb[idx++] = 68; - ide_padstr8(hdbufferb + idx, 8, "86Box"); /* Vendor */ + tempbuffer[idx++] = 0x02; + tempbuffer[idx++] = 0x01; + tempbuffer[idx++] = 0x00; + tempbuffer[idx++] = 68; + ide_padstr8(tempbuffer + idx, 8, "86Box"); /* Vendor */ idx += 8; - ide_padstr8(hdbufferb + idx, 40, device_identify_ex); /* Product */ + ide_padstr8(tempbuffer + idx, 40, device_identify_ex); /* Product */ idx += 40; - ide_padstr8(hdbufferb + idx, 20, "53R141"); /* Product */ + ide_padstr8(tempbuffer + idx, 20, "53R141"); /* Product */ idx += 20; break; default: @@ -1501,30 +1500,44 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) preamble_len = 5; size_idx = 4; - memset(hdbufferb, 0, 8); - hdbufferb[0] = 0; /*SCSI HD*/ + memset(tempbuffer, 0, 8); + tempbuffer[0] = 0; /*SCSI HD*/ if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { - hdbufferb[1] = 0x80; /*Removable*/ + tempbuffer[1] = 0x80; /*Removable*/ } else { - hdbufferb[1] = 0; /*Fixed*/ + tempbuffer[1] = 0; /*Fixed*/ } - hdbufferb[2] = 0x02; /*SCSI-2 compliant*/ - hdbufferb[3] = 0x02; - hdbufferb[4] = 31; + tempbuffer[2] = 0x02; /*SCSI-2 compliant*/ + tempbuffer[3] = 0x02; + tempbuffer[4] = 31; - ide_padstr8(hdbufferb + 8, 8, "86Box"); /* Vendor */ - ide_padstr8(hdbufferb + 16, 16, device_identify); /* Product */ - ide_padstr8(hdbufferb + 32, 4, emulator_version); /* Revision */ + ide_padstr8(tempbuffer + 8, 8, "86Box"); /* Vendor */ + ide_padstr8(tempbuffer + 16, 16, device_identify); /* Product */ + ide_padstr8(tempbuffer + 32, 4, emulator_version); /* Revision */ idx = 36; } atapi_out: - hdbufferb[size_idx] = idx - preamble_len; + tempbuffer[size_idx] = idx - preamble_len; len=idx; + if (len > max_len) + { + len = max_len; + } + + if (len > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) + { + len = SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength; + } + + memcpy(hdbufferb, tempbuffer, len); + + free(tempbuffer); + scsi_hd_data_command_finish(id, len, len, max_len, 0); break; From 7d53b48f79063de29c73f6025971acfb6b04390e Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 29 May 2017 19:48:50 +0200 Subject: [PATCH 262/392] Reverted SCSI hard disk operation back to open-once, should remove the slow downs when the hard disk image is on an USB drive. --- src/scsi_disk.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 369225f00..67975d6fa 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -459,7 +459,9 @@ prepare_new_hard_disk: shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; +#if 0 fclose(shdf[id]); +#endif } void scsi_reloadhd(int id) @@ -682,6 +684,10 @@ reload_prepare_new_hard_disk: } shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; + +#if 0 + fclose(shdf[id]); +#endif } void scsi_unloadhd(int scsi_id, int scsi_lun, int id) @@ -1292,7 +1298,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { +#if 0 shdf[id] = _wfopen(hdc[id].fn, L"rb+"); +#endif fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) { @@ -1302,7 +1310,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) { fread(hdbufferb, 1, alloc_length, shdf[id]); } +#if 0 fclose(shdf[id]); +#endif } if (shdc[id].requested_blocks > 1) @@ -1373,7 +1383,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { +#if 0 shdf[id] = _wfopen(hdc[id].fn, L"rb+"); +#endif fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) { @@ -1383,7 +1395,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) { fwrite(hdbufferb, 1, alloc_length, shdf[id]); } +#if 0 fclose(shdf[id]); +#endif } if (shdc[id].requested_blocks > 1) From 84595f1c78eaca6ed4f0e873d32dbe71c2fa518d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 30 May 2017 03:38:38 +0200 Subject: [PATCH 263/392] Added my name to all the emulator's files that I touched; Unfinished JEGA emulation based on akm's DOSVAX (AX-emulating fork of DOSBox), not yet hooked into the reset of the emulator. --- src/86box.h | 19 +- src/CPU/386_common.h | 21 +- src/CPU/386_ops.h | 23 +- src/CPU/808x.c | 21 +- src/CPU/cpu.c | 23 +- src/CPU/cpu.h | 23 +- src/CPU/x86_ops_i686.h | 19 +- src/CPU/x86_ops_misc.h | 18 ++ src/CPU/x86seg.c | 21 +- src/CPU/x86seg.h | 19 +- src/CPU/x87_ops.h | 20 ++ src/CPU/x87_ops_loadstore.h | 18 ++ src/SOUND/snd_mpu401.c | 22 ++ src/SOUND/snd_mpu401.h | 22 ++ src/SOUND/snd_sb.c | 20 ++ src/SOUND/snd_sb.h | 20 ++ src/SOUND/sound.c | 18 ++ src/SOUND/sound.h | 18 ++ src/VIDEO/vid_ati_mach64.c | 19 +- src/VIDEO/vid_ati_mach64.h | 18 ++ src/VIDEO/vid_cga.c | 21 +- src/VIDEO/vid_cga.h | 21 +- src/VIDEO/vid_cga_comp.c | 20 +- src/VIDEO/vid_cga_comp.h | 19 ++ src/VIDEO/vid_ega.c | 373 ++++++++++++++++++++++++++++++-- src/VIDEO/vid_ega.h | 32 ++- src/VIDEO/vid_s3.c | 20 +- src/VIDEO/vid_s3.h | 22 +- src/VIDEO/vid_svga.c | 22 +- src/VIDEO/vid_svga.h | 21 +- src/VIDEO/vid_svga_render.c | 21 +- src/VIDEO/vid_svga_render.h | 21 +- src/WIN/86Box.rc | 18 +- src/WIN/resource.h | 21 +- src/WIN/win.c | 21 +- src/WIN/win.h | 18 ++ src/WIN/win_cgapal.h | 16 ++ src/WIN/win_d3d.cc | 21 +- src/WIN/win_d3d.h | 21 +- src/WIN/win_d3d_fs.cc | 21 +- src/WIN/win_ddraw_screenshot.cc | 19 +- src/WIN/win_deviceconfig.c | 21 +- src/WIN/win_iodev.c | 16 ++ src/WIN/win_joystick.cc | 21 +- src/WIN/win_keyboard.c | 16 ++ src/WIN/win_language.c | 21 +- src/WIN/win_language.h | 18 ++ src/WIN/win_midi.c | 21 +- src/WIN/win_mouse.cc | 21 +- src/WIN/win_settings.c | 19 +- src/cdrom.c | 17 +- src/cdrom.h | 17 ++ src/cdrom_ioctl.c | 22 +- src/cdrom_ioctl.h | 22 +- src/cdrom_null.c | 22 +- src/cdrom_null.h | 22 +- src/device.c | 19 ++ src/device.h | 19 ++ src/disc.c | 22 +- src/disc.h | 22 +- src/disc_86f.c | 18 ++ src/disc_86f.h | 21 +- src/disc_fdi.c | 22 +- src/disc_fdi.h | 22 +- src/disc_imd.c | 19 +- src/disc_imd.h | 19 +- src/disc_img.c | 22 +- src/disc_img.h | 22 +- src/disc_random.c | 17 +- src/disc_random.h | 17 ++ src/disc_td0.c | 26 ++- src/disc_td0.h | 27 ++- src/dma.c | 21 +- src/dma.h | 21 +- src/fdc.c | 22 +- src/fdc.h | 22 +- src/fdc37c665.c | 21 +- src/fdc37c665.h | 21 +- src/fdc37c669.c | 17 +- src/fdc37c669.h | 16 ++ src/fdc37c932fr.c | 20 +- src/fdc37c932fr.h | 19 +- src/fdd.c | 21 +- src/fdd.h | 21 +- src/i430fx.c | 21 +- src/i430fx.h | 21 +- src/i430hx.c | 21 +- src/i430hx.h | 21 +- src/i430lx.c | 21 +- src/i430lx.h | 21 +- src/i430nx.c | 21 +- src/i430nx.h | 21 +- src/i430vx.c | 21 +- src/i430vx.h | 21 +- src/i440fx.c | 21 +- src/i440fx.h | 21 +- src/ibm.h | 21 +- src/ide.c | 24 +- src/ide.h | 24 +- src/intel_flash.c | 18 ++ src/intel_flash.h | 18 ++ src/keyboard.c | 21 +- src/keyboard.h | 21 +- src/keyboard_at.c | 21 +- src/keyboard_at.h | 21 +- src/memregs.c | 21 +- src/memregs.h | 20 +- src/model.c | 21 +- src/model.h | 21 +- src/nvr.c | 20 ++ src/nvr.h | 23 +- src/pc.c | 21 +- src/pc87306.c | 21 +- src/pc87306.h | 20 +- src/piix.c | 21 +- src/piix.h | 21 +- src/scsi_aha154x.c | 2 +- src/scsi_buslogic.c | 22 +- src/scsi_buslogic.h | 19 ++ src/scsi_disk.c | 14 +- src/scsi_disk.h | 14 ++ src/sio.c | 17 +- src/sio.h | 17 +- src/sis50x.c | 17 +- src/sis50x.h | 17 +- src/sis85c471.c | 17 +- src/sis85c471.h | 14 ++ src/um8669f.c | 21 +- src/um8669f.h | 21 +- src/w83877f.c | 19 +- src/w83877f.h | 19 +- src/xtide.c | 18 ++ src/xtide.h | 18 ++ 133 files changed, 2706 insertions(+), 314 deletions(-) diff --git a/src/86box.h b/src/86box.h index 06975312f..b14a9477a 100644 --- a/src/86box.h +++ b/src/86box.h @@ -1,6 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Main emulator include file. + * + * Version: @(#)86box.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #define emulator_version "2.00" #define emulator_version_w L"2.00" diff --git a/src/CPU/386_common.h b/src/CPU/386_common.h index a091a817d..6042cc151 100644 --- a/src/CPU/386_common.h +++ b/src/CPU/386_common.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Common 386 CPU code. + * + * Version: @(#)386_common.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern uint16_t ea_rseg; #undef readmemb diff --git a/src/CPU/386_ops.h b/src/CPU/386_ops.h index 4e5d78125..0217c384d 100644 --- a/src/CPU/386_ops.h +++ b/src/CPU/386_ops.h @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 286/386+ instruction handlers list. + * + * Version: @(#)386_ops.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include "x86_ops.h" diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 80af2c9be..c0e6dfa15 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x CPU emulation. + * + * Version: @(#)808x.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*SHR AX,1 4 clocks - fetch opcode diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index f6e8bb816..cbb7161fb 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * Version: @(#)cpu.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include "../ibm.h" #include "cpu.h" #include "../model.h" diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index dd7fbff31..ce0955b7f 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * Version: @(#)cpu.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef _CPU_H_ #define _CPU_H_ diff --git a/src/CPU/x86_ops_i686.h b/src/CPU/x86_ops_i686.h index b684e1195..84a10c28b 100644 --- a/src/CPU/x86_ops_i686.h +++ b/src/CPU/x86_ops_i686.h @@ -1,6 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 i686 (Pentium Pro/Pentium II) CPU Instructions. + * + * Version: @(#)x86_ops_i686.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + static int internal_illegal(char *s) { cpu_state.pc = cpu_state.oldpc; diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h index c47517c37..7734217eb 100644 --- a/src/CPU/x86_ops_misc.h +++ b/src/CPU/x86_ops_misc.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Miscellaneous x86 CPU Instructions. + * + * Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + static int opCBW(uint32_t fetchdat) { AH = (AL & 0x80) ? 0xff : 0; diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index 10e79b7c9..4f43d8dc8 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 CPU segment emulation. + * + * Version: @(#)x86seg.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/CPU/x86seg.h b/src/CPU/x86seg.h index 4a36f360b..f4badadf4 100644 --- a/src/CPU/x86seg.h +++ b/src/CPU/x86seg.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 CPU segment emulation. + * + * Version: @(#)x86seg.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void do_seg_load(x86seg *s, uint16_t *segdat); diff --git a/src/CPU/x87_ops.h b/src/CPU/x87_ops.h index e212c6ccb..b9320081f 100644 --- a/src/CPU/x87_ops.h +++ b/src/CPU/x87_ops.h @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include #include diff --git a/src/CPU/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h index ed083b921..39a14c4fb 100644 --- a/src/CPU/x87_ops_loadstore.h +++ b/src/CPU/x87_ops_loadstore.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + static int opFILDiw_a16(uint32_t fetchdat) { int16_t temp; diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 474d717b9..c5c67611b 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -1,3 +1,25 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Roland MPU-401 emulation. + * + * Version: @(#)sound_mpu401.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * DOSBox Team, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2008-2017 DOSBox Team. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #include "../ibm.h" #include "../io.h" #include "../pic.h" diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h index 8cb721883..264f2ed97 100644 --- a/src/SOUND/snd_mpu401.h +++ b/src/SOUND/snd_mpu401.h @@ -1,3 +1,25 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Roland MPU-401 emulation. + * + * Version: @(#)sound_mpu401.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * DOSBox Team, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2008-2017 DOSBox Team. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #define MPU401_VERSION 0x15 #define MPU401_REVISION 0x01 #define MPU401_QUEUE 32 diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index e94646fd3..d428c1a7d 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound Blaster emulation. + * + * Version: @(#)sound_sb.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #include #include "../ibm.h" #include "../io.h" diff --git a/src/SOUND/snd_sb.h b/src/SOUND/snd_sb.h index 4a0b974b8..de5b5af93 100644 --- a/src/SOUND/snd_sb.h +++ b/src/SOUND/snd_sb.h @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound Blaster emulation. + * + * Version: @(#)sound_sb.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + extern device_t sb_1_device; extern device_t sb_15_device; extern device_t sb_mcv_device; diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 24cf2c1c1..6a6deafc7 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound emulation core. + * + * Version: @(#)sound.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/SOUND/sound.h b/src/SOUND/sound.h index ffa9d87af..22d2d2afa 100644 --- a/src/SOUND/sound.h +++ b/src/SOUND/sound.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Sound emulation core. + * + * Version: @(#)sound.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p); extern int sound_card_current; diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index 12bbf2383..261d6681f 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -1,4 +1,21 @@ -/*ATI Mach64 emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * ATi Mach64 graphics card emulation. + * + * Version: @(#)vid_ati_mach64.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "../ibm.h" #include "../io.h" diff --git a/src/VIDEO/vid_ati_mach64.h b/src/VIDEO/vid_ati_mach64.h index 2db76fa79..c159a6b57 100644 --- a/src/VIDEO/vid_ati_mach64.h +++ b/src/VIDEO/vid_ati_mach64.h @@ -1,2 +1,20 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * ATi Mach64 graphics card emulation. + * + * Version: @(#)vid_ati_mach64.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern device_t mach64gx_device; extern device_t mach64vt2_device; diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index afae65439..7b3332f3f 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the old and new IBM CGA graphics cards. + * + * Version: @(#)vid_cga.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*CGA emulation*/ #include #include diff --git a/src/VIDEO/vid_cga.h b/src/VIDEO/vid_cga.h index ca513785d..bd8d5dbc5 100644 --- a/src/VIDEO/vid_cga.h +++ b/src/VIDEO/vid_cga.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the old and new IBM CGA graphics cards. + * + * Version: @(#)vid_cga.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + typedef struct cga_t { mem_mapping_t mapping; diff --git a/src/VIDEO/vid_cga_comp.c b/src/VIDEO/vid_cga_comp.c index a63d69f2e..513788bec 100644 --- a/src/VIDEO/vid_cga_comp.c +++ b/src/VIDEO/vid_cga_comp.c @@ -1,5 +1,21 @@ -/* Code borrowed from DOSBox and adapted by OBattler. - Original author: reenigne. */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * IBM CGA composite filter, borrowed from reenigne's DOSBox + * patch and ported to C. + * + * Version: @(#)vid_cga.c 1.0.0 2017/05/30 + * + * Author: reenigne, + * Miran Grca, + * Copyright 2015-2017 reenigne. + * Copyright 2015-2017 Miran Grca. + */ #include #include diff --git a/src/VIDEO/vid_cga_comp.h b/src/VIDEO/vid_cga_comp.h index 4640efd8f..fbea172e7 100644 --- a/src/VIDEO/vid_cga_comp.h +++ b/src/VIDEO/vid_cga_comp.h @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * IBM CGA composite filter, borrowed from reenigne's DOSBox + * patch and ported to C. + * + * Version: @(#)vid_cga.h 1.0.0 2017/05/30 + * + * Author: reenigne, + * Miran Grca, + * Copyright 2015-2017 reenigne. + * Copyright 2015-2017 Miran Grca. + */ + #define Bit8u uint8_t #define Bit32u uint32_t #define Bitu unsigned int diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index 7fe76ddaa..f0db448b6 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -1,4 +1,25 @@ -/*EGA emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the EGA, Chips & Technologies SuperEGA, and + * AX JEGA graphics cards. + * + * Version: @(#)vid_ega.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * akm, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 akm. + */ + +#include #include #include "../ibm.h" #include "../io.h" @@ -23,11 +44,111 @@ static int old_overscan_color = 0; int update_overscan = 0; +#define SBCS 0 +#define DBCS 1 +#define ID_LEN 6 +#define NAME_LEN 8 +#define SBCS19_LEN 256 * 19 +#define DBCS16_LEN 65536 * 32 + +uint8_t jfont_sbcs_19[SBCS19_LEN];//256 * 19( * 8) +uint8_t jfont_dbcs_16[DBCS16_LEN];//65536 * 16 * 2 (* 8) + +typedef struct { + char id[ID_LEN]; + char name[NAME_LEN]; + unsigned char width; + unsigned char height; + unsigned char type; +} fontx_h; + +typedef struct { + uint16_t start; + uint16_t end; +} fontxTbl; + +void ega_jega_write_font(ega_t *ega) +{ + unsigned int chr = ega->RDFFB; + unsigned int chr_2 = ega->RDFSB; + + ega->RSTAT &= ~0x02; + + /* Check if the character code is in the Wide character set of Shift-JIS */ + if (((chr >= 0x40) && (chr <= 0x7e)) || ((chr >= 0x80) && (chr <= 0xfc))) + { + if (ega->font_index >= 32) + { + ega->font_index = 0; + } + chr <<= 8; + /* Fix vertical character position */ + chr |= chr_2; + if (ega->font_index < 16) + { + jfont_dbcs_16[(chr * 32) + (ega->font_index * 2)] = ega->RDFAP; /* 16x16 font */ + } + else + { + jfont_dbcs_16[(chr * 32) + ((ega->font_index - 16) * 2) + 1] = ega->RDFAP; /* 16x16 font */ + } + } + else + { + if (ega->font_index >= 19) + { + ega->font_index = 0; + } + jfont_sbcs_19[(chr * 19) + ega->font_index] = ega->RDFAP; /* 8x19 font */ + } + ega->font_index++; + ega->RSTAT |= 0x02; +} + +void ega_jega_read_font(ega_t *ega) +{ + unsigned int chr = ega->RDFFB; + unsigned int chr_2 = ega->RDFSB; + + ega->RSTAT &= ~0x02; + + /* Check if the character code is in the Wide character set of Shift-JIS */ + if (((chr >= 0x40) && (chr <= 0x7e)) || ((chr >= 0x80) && (chr <= 0xfc))) + { + if (ega->font_index >= 32) + { + ega->font_index = 0; + } + chr <<= 8; + /* Fix vertical character position */ + chr |= chr_2; + if (ega->font_index < 16) + { + ega->RDFAP = jfont_dbcs_16[(chr * 32) + (ega->font_index * 2)]; /* 16x16 font */ + } + else + { + ega->RDFAP = jfont_dbcs_16[(chr * 32) + ((ega->font_index - 16) * 2) + 1]; /* 16x16 font */ + } + } + else + { + if (ega->font_index >= 19) + { + ega->font_index = 0; + } + ega->RDFAP = jfont_sbcs_19[(chr * 19) + ega->font_index]; /* 8x19 font */ + } + ega->font_index++; + ega->RSTAT |= 0x02; +} + void ega_out(uint16_t addr, uint8_t val, void *p) { ega_t *ega = (ega_t *)p; int c; uint8_t o, old; + uint8_t crtcreg; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -130,21 +251,82 @@ void ega_out(uint16_t addr, uint8_t val, void *p) break; case 0x3d0: case 0x3d4: - ega->crtcreg = val & 31; + ega->crtcreg = val; return; case 0x3d1: case 0x3d5: - if (ega->crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; - old = ega->crtc[ega->crtcreg]; - ega->crtc[ega->crtcreg] = val; - if (old != val) - { - if (ega->crtcreg < 0xe || ega->crtcreg > 0x10) - { - fullchange = changeframecount; - ega_recalctimings(ega); - } - } + if ((ega->crtcreg < 0xb9) || !ega->is_jega) + { + crtcreg = ega->crtcreg & 0x1f; + if (crtcreg <= 7 && ega->crtc[0x11] & 0x80) return; + old = ega->crtc[crtcreg]; + ega->crtc[crtcreg] = val; + if (old != val) + { + if (crtcreg < 0xe || crtcreg > 0x10) + { + fullchange = changeframecount; + ega_recalctimings(ega); + } + } + } + else + { + switch(ega->crtcreg) + { + case 0xb9: /* Mode register 1 */ + ega->RMOD1 = val; + break; + case 0xba: /* Mode register 2 */ + ega->RMOD2 = val; + break; + case 0xbb: /* ANK Group sel */ + ega->RDAGS = val; + break; + case 0xbc: /* Font access first byte */ + if (ega->RDFFB != val) + { + ega->RDFFB = val; + ega->font_index = 0; + } + break; + case 0xbd: /* Font access Second Byte */ + if (ega->RDFSB != val) + { + ega->RDFSB = val; + ega->font_index = 0; + } + break; + case 0xbe: /* Font Access Pattern */ + ega->RDFAP = val; + ega_jega_write_font(ega); + break; + case 0xdb: + ega->RPSSC = val; + break; + case 0xd9: + ega->RPSSU = val; + break; + case 0xda: + ega->RPSSL = val; + break; + case 0xdc: /* Superimposed mode (only AX-2 system, not implemented) */ + ega->RPPAJ = val; + break; + case 0xdd: + ega->RCMOD = val; + break; + case 0xde: /* Cursor Skew control */ + ega->RCSKW = val; + break; + case 0xdf: /* Font R/W register */ + ega->RSTAT = val; + break; + default: + pclog("JEGA: Write to illegal index %02X\n", ega->crtcreg); + break; + } + } break; } } @@ -174,6 +356,7 @@ static uint8_t ega_get_input_status_0(ega_t *ega) uint8_t ega_in(uint16_t addr, void *p) { ega_t *ega = (ega_t *)p; + int crtcreg; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(ega->miscout & 1)) addr ^= 0x60; @@ -204,7 +387,49 @@ uint8_t ega_in(uint16_t addr, void *p) return ega->crtcreg; case 0x3d1: case 0x3d5: - return ega->crtc[ega->crtcreg]; + if ((ega->crtcreg < 0xb9) || !ega->is_jega) + { + crtcreg = ega->crtcreg & 0x1f; + return ega->crtc[crtcreg]; + } + else + { + switch(ega->crtcreg) + { + case 0xb9: + return ega->RMOD1; + case 0xba: + return ega->RMOD2; + case 0xbb: + return ega->RDAGS; + case 0xbc: /* BCh RDFFB Font access First Byte */ + return ega->RDFFB; + case 0xbd: /* BDh RDFFB Font access Second Byte */ + return ega->RDFSB; + case 0xbe: /* BEh RDFAP Font Access Pattern */ + ega_jega_read_font(ega); + return ega->RDFAP; + case 0xdb: + return ega->RPSSC; + case 0xd9: + return ega->RPSSU; + case 0xda: + return ega->RPSSL; + case 0xdc: + return ega->RPPAJ; + case 0xdd: + return ega->RCMOD; + case 0xde: + return ega->RCSKW; + case 0xdf: + return ega->ROMSL; + case 0xbf: + return 0x03; /* The font is always readable and writable */ + default: + pclog("JEGA: Read from illegal index %02X\n", ega->crtcreg); + return 0x00; + } + } case 0x3da: ega->attrff = 0; ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/ @@ -936,6 +1161,8 @@ void ega_common_defaults(ega_t *ega) ega->extvram = 1; update_overscan = 0; + + ega->is_jega = 0; } void *ega_standalone_init() @@ -1048,6 +1275,112 @@ void *sega_standalone_init() return ega; } +uint16_t chrtosht(FILE *fp) +{ + uint16_t i, j; + i = (uint8_t) getc(fp); + j = (uint8_t) getc(fp) << 8; + return (i | j); +} + +unsigned int getfontx2header(FILE *fp, fontx_h *header) +{ + fread(header->id, ID_LEN, 1, fp); + if (strncmp(header->id, "FONTX2", ID_LEN) != 0) + { + return 1; + } + fread(header->name, NAME_LEN, 1, fp); + header->width = (uint8_t)getc(fp); + header->height = (uint8_t)getc(fp); + header->type = (uint8_t)getc(fp); + return 0; +} + +void readfontxtbl(fontxTbl *table, unsigned int size, FILE *fp) +{ + while (size > 0) + { + table->start = chrtosht(fp); + table->end = chrtosht(fp); + ++table; + --size; + } +} + +static void LoadFontxFile(wchar_t *fname) +{ + fontx_h head; + fontxTbl *table; + unsigned int code; + uint8_t size; + unsigned int i; + + if (!fname) return; + if(*fname=='\0') return; + FILE * mfile=romfopen(fname,L"rb"); + if (!mfile) + { + pclog("MSG: Can't open FONTX2 file: %s\n",fname); + return; + } + if (getfontx2header(mfile, &head) != 0) + { + fclose(mfile); + pclog("MSG: FONTX2 header is incorrect\n"); + return; + } + /* switch whether the font is DBCS or not */ + if (head.type == DBCS) + { + if (head.width == 16 && head.height == 16) + { + size = getc(mfile); + table = (fontxTbl *)calloc(size, sizeof(fontxTbl)); + readfontxtbl(table, size, mfile); + for (i = 0; i < size; i++) + { + for (code = table[i].start; code <= table[i].end; code++) + { + fread(&jfont_dbcs_16[(code * 32)], sizeof(uint8_t), 32, mfile); + } + } + } + else + { + fclose(mfile); + pclog("MSG: FONTX2 DBCS font size is not correct\n"); + return; + } + } + else + { + if (head.width == 8 && head.height == 19) + { + fread(jfont_sbcs_19, sizeof(uint8_t), SBCS19_LEN, mfile); + } + else + { + fclose(mfile); + pclog("MSG: FONTX2 SBCS font size is not correct\n"); + return; + } + } + fclose(mfile); +} + +void *jega_standalone_init() +{ + ega_t *ega = (ega_t *) sega_standalone_init(); + + LoadFontxFile(L"roms/JPNHN19X.FNT"); + LoadFontxFile(L"roms/JPNZN16X.FNT"); + + ega->is_jega = 1; + + return ega; +} + static int ega_standalone_available() { return rom_present(L"roms/ibm_6277356_ega_card_u44_27128.bin"); @@ -1113,3 +1446,15 @@ device_t sega_device = NULL, NULL }; + +device_t jega_device = +{ + "AX JEGA", + 0, + jega_standalone_init, + ega_close, + sega_standalone_available, + ega_speed_changed, + NULL, + NULL +}; diff --git a/src/VIDEO/vid_ega.h b/src/VIDEO/vid_ega.h index 9b0e215d8..2fef2c0ca 100644 --- a/src/VIDEO/vid_ega.h +++ b/src/VIDEO/vid_ega.h @@ -1,6 +1,26 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the EGA, Chips & Technologies SuperEGA, and + * AX JEGA graphics cards. + * + * Version: @(#)vid_ega.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * akm, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 akm. + */ + +#include + typedef struct ega_t { mem_mapping_t mapping; @@ -68,6 +88,12 @@ typedef struct ega_t int vrammask; int video_res_x, video_res_y, video_bpp; + + uint8_t RMOD1, RMOD2, RDAGS, RDFFB, RDFSB, RDFAP, RPESL, RPULP, RPSSC, RPSSU, RPSSL; + uint8_t RPPAJ; + uint8_t RCMOD, RCCLH, RCCLL, RCCSL, RCCEL, RCSKW, ROMSL, RSTAT; + int is_jega, font_index; + int chr_left, chr_wide; } ega_t; extern int update_overscan; diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index de67496d7..9f141668d 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1,4 +1,22 @@ -/*S3 emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 + * graphics cards. + * + * Version: @(#)vid_s3.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "../ibm.h" #include "../io.h" diff --git a/src/VIDEO/vid_s3.h b/src/VIDEO/vid_s3.h index 396e6523b..8ace7397d 100644 --- a/src/VIDEO/vid_s3.h +++ b/src/VIDEO/vid_s3.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 + * graphics cards. + * + * Version: @(#)vid_s3.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + device_t s3_bahamas64_device; device_t s3_9fx_device; device_t s3_phoenix_trio32_device; diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index c2af8a822..8684de91f 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -1,7 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Generic SVGA handling*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic SVGA handling. + * + * Version: @(#)vid_svga.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*This is intended to be used by another SVGA driver, and not as a card in it's own right*/ #include #include diff --git a/src/VIDEO/vid_svga.h b/src/VIDEO/vid_svga.h index 54270a0cb..d4307dfde 100644 --- a/src/VIDEO/vid_svga.h +++ b/src/VIDEO/vid_svga.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic SVGA handling. + * + * Version: @(#)vid_svga.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + typedef struct svga_t { mem_mapping_t mapping; diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index eba7e0b43..0d09326e7 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * SVGA renderers. + * + * Version: @(#)vid_svga_render.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "../ibm.h" #include "../mem.h" diff --git a/src/VIDEO/vid_svga_render.h b/src/VIDEO/vid_svga_render.h index f6611db57..eb3715fdd 100644 --- a/src/VIDEO/vid_svga_render.h +++ b/src/VIDEO/vid_svga_render.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * SVGA renderers. + * + * Version: @(#)vid_svga_render.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern int firstline_draw, lastline_draw; extern int displine; extern int sc; diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index b8761032d..a3eaae8eb 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -1,3 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows resource script. + * + * Version: @(#)86Box.rc 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include //Microsoft Developer Studio generated resource script. @@ -238,7 +254,7 @@ FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,129,94,71,12 ICON 100,IDC_ABOUT_ICON,7,7,20,20 - LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Tohka, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", IDC_ABOUT_ICON,54,7,146,73 CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, 86,208,1 diff --git a/src/WIN/resource.h b/src/WIN/resource.h index fdc53b649..567fc7889 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -1,6 +1,21 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows resource defines. + * + * Version: @(#)resource.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /* {{NO_DEPENDENCIES}} Microsoft Developer Studio generated include file. Used by 86Box.rc diff --git a/src/WIN/win.c b/src/WIN/win.c index 3abbcf894..3561d3b14 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * The Emulator's Windows core. + * + * Version: @(#)win.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/WIN/win.h b/src/WIN/win.h index f36b487e5..ee6d2535b 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * The Emulator's Windows core. + * + * Version: @(#)win.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /* * This should be named 'plat.h' and then include any * Windows-specific header files needed, to keep them diff --git a/src/WIN/win_cgapal.h b/src/WIN/win_cgapal.h index d6ac7ffd8..0388cde27 100644 --- a/src/WIN/win_cgapal.h +++ b/src/WIN/win_cgapal.h @@ -1,3 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * The Windows CGA palette handler header. + * + * Version: @(#)win_cgapal.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern PALETTE cgapal; extern PALETTE cgapal_mono[6]; diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index ce2d9a3b5..04720448a 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Direct3D 9 rendererer and screenshots taking. + * + * Version: @(#)win_d3d.cc 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "../video/video.h" #include "win.h" diff --git a/src/WIN/win_d3d.h b/src/WIN/win_d3d.h index 5994a87b1..11128d486 100644 --- a/src/WIN/win_d3d.h +++ b/src/WIN/win_d3d.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Direct3D 9 rendererer and screenshots taking. + * + * Version: @(#)win_d3d.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef WIN_D3D_H # define WIN_D3D_H # define UNICODE diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 93b23da0b..91c420132 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Direct3D 9 full screen rendererer and screenshots taking. + * + * Version: @(#)win_d3d_fs.cc 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include "../86box.h" diff --git a/src/WIN/win_ddraw_screenshot.cc b/src/WIN/win_ddraw_screenshot.cc index 717b94348..b98a207d1 100644 --- a/src/WIN/win_ddraw_screenshot.cc +++ b/src/WIN/win_ddraw_screenshot.cc @@ -1,6 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * DirectDraw screenshot taking code. + * + * Version: @(#)win_ddraw_screenshot.cc 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include #include #define UNICODE diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index 1cfa026eb..1dc548278 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows device configuration dialog implementation. + * + * Version: @(#)win_deviceconfig.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "../ibm.h" #include "../config.h" #include "../device.h" diff --git a/src/WIN/win_iodev.c b/src/WIN/win_iodev.c index 465302c68..56d5d5df8 100644 --- a/src/WIN/win_iodev.c +++ b/src/WIN/win_iodev.c @@ -1,3 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows IO device menu handler. + * + * Version: @(#)win_iodev.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #define UNICODE #define _WIN32_WINNT 0x0501 #define BITMAP WINDOWS_BITMAP diff --git a/src/WIN/win_joystick.cc b/src/WIN/win_joystick.cc index 63d970eaa..91c2138b0 100644 --- a/src/WIN/win_joystick.cc +++ b/src/WIN/win_joystick.cc @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Joystick interface to host device. + * + * Version: @(#)win_joystick.cc 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define DIRECTINPUT_VERSION 0x0800 #include #include diff --git a/src/WIN/win_keyboard.c b/src/WIN/win_keyboard.c index 89b4f6639..e7b847f7d 100644 --- a/src/WIN/win_keyboard.c +++ b/src/WIN/win_keyboard.c @@ -1,3 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows raw keyboard input handler. + * + * Version: @(#)win_d3d.cc 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #define UNICODE #define _WIN32_WINNT 0x0501 #define BITMAP WINDOWS_BITMAP diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index d7e78ac14..00cb70482 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows localization core. + * + * Version: @(#)win_language.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #define UNICODE #define BITMAP WINDOWS_BITMAP diff --git a/src/WIN/win_language.h b/src/WIN/win_language.h index 5c4237249..bb7af81b7 100644 --- a/src/WIN/win_language.h +++ b/src/WIN/win_language.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows localization core. + * + * Version: @(#)win_language.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #ifdef __cplusplus extern "C" { #endif diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c index 66f354857..3850201bf 100644 --- a/src/WIN/win_midi.c +++ b/src/WIN/win_midi.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * MIDI interface to host device. + * + * Version: @(#)win_midi.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include "../ibm.h" diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc index 9a6f50e80..105575557 100644 --- a/src/WIN/win_mouse.cc +++ b/src/WIN/win_mouse.cc @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Mouse interface to host device. + * + * Version: @(#)win_mouse.cc 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define DIRECTINPUT_VERSION 0x0800 #include #include diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 84a6a0645..5ff60adcf 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1,6 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Windows 86Box Settings dialog handler. + * + * Version: @(#)win_midi.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #define UNICODE #define BITMAP WINDOWS_BITMAP #include diff --git a/src/cdrom.c b/src/cdrom.c index 10c811f7d..2bac1e2e3 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1,4 +1,19 @@ -/* CD-ROM emulation, used by both ATAPI and SCSI */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. + * + * Version: @(#)cdrom.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include #include diff --git a/src/cdrom.h b/src/cdrom.h index 5e167fe35..6f10756c0 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -1,3 +1,20 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM drive with SCSI(-like) + * commands, for both ATAPI and SCSI usage. + * + * Version: @(#)cdrom.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #ifndef __CDROM_H__ #define __CDROM_H__ diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index b0d416521..b5f827fa7 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -1,7 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ -/*Win32 CD-ROM support via IOCTL*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM host drive IOCTL interface for + * Windows using SCSI Passthrough Direct. + * + * Version: @(#)cdrom_ioctl.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #define WINVER 0x0600 #include diff --git a/src/cdrom_ioctl.h b/src/cdrom_ioctl.h index e39f12ddf..a5c710230 100644 --- a/src/cdrom_ioctl.h +++ b/src/cdrom_ioctl.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM host drive IOCTL interface for + * Windows using SCSI Passthrough Direct. + * + * Version: @(#)cdrom_ioctl.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef CDROM_IOCTL_H #define CDROM_IOCTL_H diff --git a/src/cdrom_null.c b/src/cdrom_null.c index 2a0ce9da5..a2383b626 100644 --- a/src/cdrom_null.c +++ b/src/cdrom_null.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM null interface for unmounted + * guest CD-ROM drives. + * + * Version: @(#)cdrom_null.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "cdrom.h" #include "cdrom_ioctl.h" diff --git a/src/cdrom_null.h b/src/cdrom_null.h index 7217760ca..69117d43f 100644 --- a/src/cdrom_null.h +++ b/src/cdrom_null.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the CD-ROM null interface for unmounted + * guest CD-ROM drives. + * + * Version: @(#)cdrom_null.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef CDROM_NULL_H #define CDROM_NULL_H diff --git a/src/device.c b/src/device.c index b706f99b9..1f7e5b577 100644 --- a/src/device.c +++ b/src/device.c @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the generic device interface to handle + * all devices attached to the emulator. + * + * Version: @(#)device.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "cpu/cpu.h" #include "config.h" diff --git a/src/device.h b/src/device.h index 7ad34630e..acb875dcc 100644 --- a/src/device.h +++ b/src/device.h @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the generic device interface to handle + * all devices attached to the emulator. + * + * Version: @(#)device.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2016 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define CONFIG_STRING 0 #define CONFIG_INT 1 #define CONFIG_BINARY 2 diff --git a/src/disc.c b/src/disc.c index 6bd93cb59..e7af927bd 100644 --- a/src/disc.c +++ b/src/disc.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic floppy disk interface that communicates with the + * other handlers. + * + * Version: @(#)disc.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define UNICODE #include diff --git a/src/disc.h b/src/disc.h index 4bf7a96cb..62ba83d83 100644 --- a/src/disc.h +++ b/src/disc.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Generic floppy disk interface that communicates with the + * other handlers. + * + * Version: @(#)disc.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define FDD_NUM 4 typedef struct diff --git a/src/disc_86f.c b/src/disc_86f.c index bca91ca74..9eb713365 100644 --- a/src/disc_86f.c +++ b/src/disc_86f.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the 86F floppy image format (stores the + * data in the form of FM/MFM-encoded transitions) which also + * forms the core of the emulator's floppy disk emulation. + * + * Version: @(#)disc_86f.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/disc_86f.h b/src/disc_86f.h index 7efc9b3f5..ec7e83c1e 100644 --- a/src/disc_86f.h +++ b/src/disc_86f.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the 86F floppy image format (stores the + * data in the form of FM/MFM-encoded transitions) which also + * forms the core of the emulator's floppy disk emulation. + * + * Version: @(#)disc_86f.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void d86f_init(); void d86f_load(int drive, wchar_t *fn); void d86f_close(int drive); diff --git a/src/disc_fdi.c b/src/disc_fdi.c index 62875d8e4..af192b76f 100644 --- a/src/disc_fdi.c +++ b/src/disc_fdi.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the FDI floppy stream image format + * interface to the FDI2RAW module. + * + * Version: @(#)disc_fdi.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/disc_fdi.h b/src/disc_fdi.h index 781efac23..ae77e0279 100644 --- a/src/disc_fdi.h +++ b/src/disc_fdi.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the FDI floppy stream image format + * interface to the FDI2RAW module. + * + * Version: @(#)disc_fdi.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void fdi_init(); void fdi_load(int drive, wchar_t *fn); void fdi_close(int drive); diff --git a/src/disc_imd.c b/src/disc_imd.c index f932f4fd4..b0a8b0016 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -1,6 +1,19 @@ -/* Copyright holders: Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IMD floppy image format. + * + * Version: @(#)disc_imd.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "disc.h" #include "disc_imd.h" diff --git a/src/disc_imd.h b/src/disc_imd.h index a132605d9..f017cebf0 100644 --- a/src/disc_imd.h +++ b/src/disc_imd.h @@ -1,6 +1,19 @@ -/* Copyright holders: Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IMD floppy image format. + * + * Version: @(#)disc_imd.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void imd_init(); void imd_load(int drive, wchar_t *fn); void imd_close(int drive); diff --git a/src/disc_img.c b/src/disc_img.c index d529db045..f9016be4b 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the raw sector-based floppy image format, + * as well as the Japanese FDI, CopyQM, and FDF formats. + * + * Version: @(#)disc_img.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include diff --git a/src/disc_img.h b/src/disc_img.h index 4cb82ea1f..94c4780cf 100644 --- a/src/disc_img.h +++ b/src/disc_img.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the raw sector-based floppy image format, + * as well as the Japanese FDI, CopyQM, and FDF formats. + * + * Version: @(#)disc_img.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void img_init(); void img_load(int drive, wchar_t *fn); void img_close(int drive); diff --git a/src/disc_random.c b/src/disc_random.c index 1712193e4..17b28c2e5 100644 --- a/src/disc_random.c +++ b/src/disc_random.c @@ -1,4 +1,19 @@ -/* Better random number generator by Battler. */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * A better random number generation, used for floppy weak bits + * and network MAC address generation. + * + * Version: @(#)disc_random.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include #include diff --git a/src/disc_random.h b/src/disc_random.h index 25dc87326..601e9d84f 100644 --- a/src/disc_random.h +++ b/src/disc_random.h @@ -1,2 +1,19 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * A better random number generation, used for floppy weak bits + * and network MAC address generation. + * + * Version: @(#)disc_random.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + uint8_t disc_random_generate(); void disc_random_init(); diff --git a/src/disc_td0.c b/src/disc_td0.c index e20020fcc..ac2cd9a6b 100644 --- a/src/disc_td0.c +++ b/src/disc_td0.c @@ -1,5 +1,29 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * +* Implementation of the Teledisk floppy image format. + * + * Version: @(#)disc_td0.c 1.0.0 2017/05/30 + * + * Author: Milodrag Milanovic, + * Haruhiko OKUMURA, + * Haruyasu YOSHIZAKI, + * Kenji RIKITAKE, + * Miran Grca, + * Copyright 1988-2017 Haruhiko OKUMURA. + * Copyright 1988-2017 Haruyasu YOSHIZAKI. + * Copyright 1988-2017 Kenji RIKITAKE. + * Copyright 2013-2017 Milodrag Milanovic. + * Copyright 2016-2017 Miran Grca. + */ + /* license:BSD-3-Clause - copyright-holders:Miodrag Milanovic,Kiririn (translation to C and port to 86Box) */ + copyright-holders:Miodrag Milanovic, Miran Grca (translation to C and port to 86Box) */ /********************************************************************* formats/td0_dsk.c diff --git a/src/disc_td0.h b/src/disc_td0.h index 306c7be20..e28f2dc7d 100644 --- a/src/disc_td0.h +++ b/src/disc_td0.h @@ -1,6 +1,27 @@ -/* Copyright holders: Kiririn - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Teledisk floppy image format. + * + * Version: @(#)disc_td0.h 1.0.0 2017/05/30 + * + * Author: Milodrag Milanovic, + * Haruhiko OKUMURA, + * Haruyasu YOSHIZAKI, + * Kenji RIKITAKE, + * Miran Grca, + * Copyright 1988-2017 Haruhiko OKUMURA. + * Copyright 1988-2017 Haruyasu YOSHIZAKI. + * Copyright 1988-2017 Kenji RIKITAKE. + * Copyright 2013-2017 Milodrag Milanovic. + * Copyright 2016-2017 Miran Grca. + */ + void td0_init(); void td0_load(int drive, wchar_t *fn); void td0_close(int drive); diff --git a/src/dma.c b/src/dma.c index 29804cd82..a90156a6d 100644 --- a/src/dma.c +++ b/src/dma.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel DMA controllers. + * + * Version: @(#)dma.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "cpu/x86.h" #include "mem.h" diff --git a/src/dma.h b/src/dma.h index 515f02f87..947d80425 100644 --- a/src/dma.h +++ b/src/dma.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel DMA controllers. + * + * Version: @(#)dma.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void dma_init(void); void dma16_init(void); void ps2_dma_init(void); diff --git a/src/fdc.c b/src/fdc.c index 60c2b44d3..eed50ca13 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NEC uPD-765 and compatible floppy disk + * controller. + * + * Version: @(#)fdc.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/fdc.h b/src/fdc.h index 5bdb7d00e..0e8c42654 100644 --- a/src/fdc.h +++ b/src/fdc.h @@ -1,6 +1,22 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the NEC uPD-765 and compatible floppy disk + * controller. + * + * Version: @(#)fdc.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void fdc_init(); void fdc_add(); void fdc_add_for_superio(); diff --git a/src/fdc37c665.c b/src/fdc37c665.c index bbcf157b5..7cc5889ce 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C665 Super I/O Chip. + * + * Version: @(#)fdc37c665.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "disc.h" diff --git a/src/fdc37c665.h b/src/fdc37c665.h index 8f906807d..cbe28216f 100644 --- a/src/fdc37c665.h +++ b/src/fdc37c665.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C665 Super I/O Chip. + * + * Version: @(#)fdc37c665.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern void fdc37c665_init(); diff --git a/src/fdc37c669.c b/src/fdc37c669.c index 605b79e17..33d19b8ba 100644 --- a/src/fdc37c669.c +++ b/src/fdc37c669.c @@ -1,7 +1,18 @@ /* - SMSC SMC FDC37C669 Super I/O Chip - Used by the 430TX -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C669 Super I/O Chip. + * + * Version: @(#)fdc37c669.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/fdc37c669.h b/src/fdc37c669.h index f3fa420d7..31189524a 100644 --- a/src/fdc37c669.h +++ b/src/fdc37c669.h @@ -1 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C669 Super I/O Chip. + * + * Version: @(#)fdc37c669.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void fdc37c669_init(); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 5b4057d1e..d5faf988e 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -1,10 +1,18 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ /* - SMSC SMC fdc37c932fr Super I/O Chip - Used by all some Acer boards, and by the Epox P55-VA -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C932FR Super I/O Chip. + * + * Version: @(#)fdc37c932fr.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/fdc37c932fr.h b/src/fdc37c932fr.h index ef83f5d01..1e48bb0e9 100644 --- a/src/fdc37c932fr.h +++ b/src/fdc37c932fr.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the SMC FDC37C932FR Super I/O Chip. + * + * Version: @(#)fdc37c932fr.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void fdc37c932fr_init(); diff --git a/src/fdd.c b/src/fdd.c index 35a2b6865..449bf02bd 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the floppy drive emulation. + * + * Version: @(#)fdd.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "disc.h" #include "fdc.h" diff --git a/src/fdd.h b/src/fdd.h index c4a18afbe..7b34c4a1a 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the floppy drive emulation. + * + * Version: @(#)fdd.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define SEEK_RECALIBRATE -999 void fdd_forced_seek(int drive, int track_diff); void fdd_seek(int drive, int track_diff); diff --git a/src/i430fx.c b/src/i430fx.c index a0324c3ce..bfc635fed 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430FX PCISet chip. + * + * Version: @(#)i430fx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" diff --git a/src/i430fx.h b/src/i430fx.h index 9ed0f355e..1904ea0f5 100644 --- a/src/i430fx.h +++ b/src/i430fx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430FX PCISet chip. + * + * Version: @(#)i430fx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430fx_init(); diff --git a/src/i430hx.c b/src/i430hx.c index 80c52c02f..dc2b75b02 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430HX PCISet chip. + * + * Version: @(#)i430hx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" diff --git a/src/i430hx.h b/src/i430hx.h index a6899ca24..4ef96e6ae 100644 --- a/src/i430hx.h +++ b/src/i430hx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430HX PCISet chip. + * + * Version: @(#)i430hx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430hx_init(); diff --git a/src/i430lx.c b/src/i430lx.c index 7494b6c76..ccb44ebff 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430LX PCISet chip. + * + * Version: @(#)i430lx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" diff --git a/src/i430lx.h b/src/i430lx.h index 60c061df4..23153f7f4 100644 --- a/src/i430lx.h +++ b/src/i430lx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430LX PCISet chip. + * + * Version: @(#)i430lx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430lx_init(); diff --git a/src/i430nx.c b/src/i430nx.c index da7b1a5fe..487aa48bd 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430NX PCISet chip. + * + * Version: @(#)i430nx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" diff --git a/src/i430nx.h b/src/i430nx.h index 3c759a205..93d1466bb 100644 --- a/src/i430nx.h +++ b/src/i430nx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430NX PCISet chip. + * + * Version: @(#)i430nx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430nx_init(); diff --git a/src/i430vx.c b/src/i430vx.c index 2eef17d33..e9ff1f42b 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430VX PCISet chip. + * + * Version: @(#)i430vx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" diff --git a/src/i430vx.h b/src/i430vx.h index af7e5337e..8ed77f3fe 100644 --- a/src/i430vx.h +++ b/src/i430vx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 430VX PCISet chip. + * + * Version: @(#)i430vx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i430vx_init(); diff --git a/src/i440fx.c b/src/i440fx.c index 9074e2e7a..a315801c9 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 440FX PCISet chip. + * + * Version: @(#)i440fx.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" diff --git a/src/i440fx.h b/src/i440fx.h index 72cf59458..3ce8b744f 100644 --- a/src/i440fx.h +++ b/src/i440fx.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 440FX PCISet chip. + * + * Version: @(#)i440fx.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void i440fx_init(); diff --git a/src/ibm.h b/src/ibm.h index e9c00c15c..b210b07a0 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * General include file. + * + * Version: @(#)ibm.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/ide.c b/src/ide.c index dbea750bd..f9c28ffdc 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1,6 +1,24 @@ -/* Copyright holders: Sarah Walker, Tenshi, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. + * + * Version: @(#)ide.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _GNU_SOURCE diff --git a/src/ide.h b/src/ide.h index de63c9372..85462b67e 100644 --- a/src/ide.h +++ b/src/ide.h @@ -1,6 +1,24 @@ -/* Copyright holders: Sarah Walker, Tenshi, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the IDE emulation for hard disks and ATAPI + * CD-ROM devices. + * + * Version: @(#)ide.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * TheCollector1995, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 TheCollector1995. + */ + #ifndef __IDE__ #define __IDE__ diff --git a/src/intel_flash.c b/src/intel_flash.c index 1ccb225a9..6ded787ef 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 2 Mbit 8-bit flash devices. + * + * Version: @(#)intel_flash.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" #include "device.h" diff --git a/src/intel_flash.h b/src/intel_flash.h index 242480961..d63b48c18 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of the Intel 2 Mbit 8-bit flash devices. + * + * Version: @(#)intel_flash.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern device_t intel_flash_bxt_ami_device; extern device_t intel_flash_bxb_ami_device; extern device_t intel_flash_bxt_device; diff --git a/src/keyboard.c b/src/keyboard.c index 0ea442618..7a60c5a62 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Host to guest keyboard interface and keyboard scan code sets. + * + * Version: @(#)keyboard.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include "ibm.h" #include "plat_keyboard.h" #include "keyboard.h" diff --git a/src/keyboard.h b/src/keyboard.h index b53b3a8d5..217f1cee1 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Host to guest keyboard interface and keyboard scan code sets. + * + * Version: @(#)keyboard.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern void (*keyboard_send)(uint8_t val); extern void (*keyboard_poll)(); extern int keyboard_scan; diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 4e6c7f7e9..06fba2399 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Intel 8042 (AT keyboard controller) emulation. + * + * Version: @(#)keyboard_at.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" #include "io.h" diff --git a/src/keyboard_at.h b/src/keyboard_at.h index 2fdfb5ee8..d92101543 100644 --- a/src/keyboard_at.h +++ b/src/keyboard_at.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Intel 8042 (AT keyboard controller) emulation. + * + * Version: @(#)keyboard_at.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void keyboard_at_init(); void keyboard_at_init_ps2(); void keyboard_at_reset(); diff --git a/src/memregs.c b/src/memregs.c index ec832225a..6d002f512 100644 --- a/src/memregs.c +++ b/src/memregs.c @@ -1,10 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ /* - 0xE1 and 0xE2 Memory Registers - Used by just about any emulated machine -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the memory I/O scratch registers on ports 0xE1 + * and 0xE2, used by just about any emulated machine. + * + * Version: @(#)memregs.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/memregs.h b/src/memregs.h index 590aa2af2..cb8d626b7 100644 --- a/src/memregs.h +++ b/src/memregs.h @@ -1,5 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the memory I/O scratch registers on ports 0xE1 + * and 0xE2, used by just about any emulated machine. + * + * Version: @(#)memregs.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void memregs_init(); void powermate_memregs_init(); diff --git a/src/model.c b/src/model.c index 2c88624f2..7eb73479f 100644 --- a/src/model.c +++ b/src/model.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the emulated machines. + * + * Version: @(#)model.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include "ibm.h" diff --git a/src/model.h b/src/model.h index bfdc19077..a337b122b 100644 --- a/src/model.h +++ b/src/model.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tohka - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the emulated machines. + * + * Version: @(#)model.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #define MODEL_AT 1 #define MODEL_PS2 2 #define MODEL_AMSTRAD 4 diff --git a/src/nvr.c b/src/nvr.c index 56a1d7e20..5888c1005 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CMOS NVRAM emulation. + * + * Version: @(#)nvr.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Mahod, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 Mahod. + */ + #include #include "ibm.h" #include "io.h" diff --git a/src/nvr.h b/src/nvr.h index 069a476a7..46eaa07ec 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -1,6 +1,23 @@ -/* Copyright holders: Mahod, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CMOS NVRAM emulation. + * + * Version: @(#)nvr.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Mahod, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2016-2017 Mahod. + */ + void nvr_init(); extern int enable_sync; diff --git a/src/pc.c b/src/pc.c index 6537c8733..dc7b3a5de 100644 --- a/src/pc.c +++ b/src/pc.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation core dispatcher. + * + * Version: @(#)pc.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include diff --git a/src/pc87306.c b/src/pc87306.c index c0a6bb7d1..c0887451b 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -1,10 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ /* - National Semiconductors PC87306 Super I/O Chip - Used by Intel Advanced/EV -*/ + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the National Semiconductors PC87306 Super I/O + * chip. + * + * Version: @(#)pc87306.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" diff --git a/src/pc87306.h b/src/pc87306.h index 0f48f3d97..d1891fdd8 100644 --- a/src/pc87306.h +++ b/src/pc87306.h @@ -1,4 +1,18 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the National Semiconductors PC87306 Super I/O + * chip. + * + * Version: @(#)pc87306.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void pc87306_init(); diff --git a/src/piix.c b/src/piix.c index 04cf62418..8e7378dbd 100644 --- a/src/piix.c +++ b/src/piix.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the Intel PIIX and PIIX3 Xcelerators. + * + * Emulation core dispatcher. + * + * Version: @(#)piix.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*PRD format : word 0 - base address diff --git a/src/piix.h b/src/piix.h index c86a680ce..00000138c 100644 --- a/src/piix.h +++ b/src/piix.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the Intel PIIX and PIIX3 Xcelerators. + * + * Emulation core dispatcher. + * + * Version: @(#)piix.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + void piix_init(int card); void piix3_init(int card); diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 2a80b626a..72f615843 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -15,7 +15,7 @@ * Version: @(#)scsi_aha154x.c 1.0.6 2017/05/06 * * Authors: Fred N. van Kempen, - * Original Buslogic version by SA1988. + * Original Buslogic version by SA1988 and Miran Grca. * Copyright 2017 Fred N. van Kempen. */ #include diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index a691fa699..e9d2ca48a 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -1,6 +1,22 @@ -/* Copyright holders: SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI + * controllers. + * + * Version: @(#)scsi_buslogic.c 1.0.0 2017/05/30 + * + * Author: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + */ + /*Buslogic SCSI emulation*/ /* Emulated SCSI controllers: diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h index c2d5dccc5..c952e06d1 100644 --- a/src/scsi_buslogic.h +++ b/src/scsi_buslogic.h @@ -1,3 +1,22 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI + * controllers. + * + * Version: @(#)scsi_buslogic.h 1.0.0 2017/05/30 + * + * Author: TheCollector1995, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + * Copyright 2017-2017 Fred N. van Kempen. + */ + #ifndef SCSI_BUSLOGIC_H # define SCSI_BUSLOGIC_H diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 67975d6fa..33b88a4bb 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -1,4 +1,16 @@ -/* SCSI hard disk emulation */ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of SCSI fixed and removable disks. + * + * Version: @(#)scsi_disk.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE diff --git a/src/scsi_disk.h b/src/scsi_disk.h index 233c04fd1..95fdd9316 100644 --- a/src/scsi_disk.h +++ b/src/scsi_disk.h @@ -1,3 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of SCSI fixed and removable disks. + * + * Version: @(#)scsi_disk.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + #pragma pack(push,1) typedef struct { /* Stuff for SCSI hard disks. */ diff --git a/src/sio.c b/src/sio.c index 9ad476e38..3250ba2f0 100644 --- a/src/sio.c +++ b/src/sio.c @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of Intel System I/O PCI chip. + * + * Version: @(#)sio.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + /*PRD format : word 0 - base address diff --git a/src/sio.h b/src/sio.h index 38b0ff468..9aacd3e6b 100644 --- a/src/sio.h +++ b/src/sio.h @@ -1,5 +1,16 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of Intel System I/O PCI chip. + * + * Version: @(#)sio.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + void trc_init(void); void sio_init(int card); diff --git a/src/sis50x.c b/src/sis50x.c index ad4be95c6..59e887d78 100644 --- a/src/sis50x.c +++ b/src/sis50x.c @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 50x PCI chips. + * + * Version: @(#)sis50x.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + #include #include "ibm.h" #include "device.h" diff --git a/src/sis50x.h b/src/sis50x.h index d2028dc2b..df5565043 100644 --- a/src/sis50x.h +++ b/src/sis50x.h @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 50x PCI chips. + * + * Version: @(#)sis50x.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + extern device_t sis501_device; extern device_t sis503_device; extern device_t sis50x_device; diff --git a/src/sis85c471.c b/src/sis85c471.c index e7d5af86c..f56716f43 100644 --- a/src/sis85c471.c +++ b/src/sis85c471.c @@ -1,6 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 85c471 chip. + * + * Version: @(#)sis85c471.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + /* SiS sis85c471 Super I/O Chip Used by Batman's Revenge diff --git a/src/sis85c471.h b/src/sis85c471.h index 5ccd63ab5..5a69fdf65 100644 --- a/src/sis85c471.h +++ b/src/sis85c471.h @@ -1,3 +1,17 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * Emulation of the SiS 85c471 chip. + * + * Version: @(#)sis85c471.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2017-2017 Miran Grca. + */ + /* Copyright holders: Tenshi see COPYING for more details */ diff --git a/src/um8669f.c b/src/um8669f.c index 00433f24c..964f2613a 100644 --- a/src/um8669f.c +++ b/src/um8669f.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the UMC UM8669F Super I/O Chip. + * + * Version: @(#)um8669f.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*um8669f : aa to 108 unlocks diff --git a/src/um8669f.h b/src/um8669f.h index 19a56ba02..92052a151 100644 --- a/src/um8669f.h +++ b/src/um8669f.h @@ -1,4 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the UMC UM8669F Super I/O Chip. + * + * Version: @(#)um8669f.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern void um8669f_init(); diff --git a/src/w83877f.c b/src/w83877f.c index cb980df09..6a6dd0552 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -1,6 +1,19 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83877F Super I/O Chip. + * + * Version: @(#)w83877f.c 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + /* Winbond W83877F Super I/O Chip Used by the Award 430HX diff --git a/src/w83877f.h b/src/w83877f.h index 33120fbde..f4a103c94 100644 --- a/src/w83877f.h +++ b/src/w83877f.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the Winbond W83877F Super I/O Chip. + * + * Version: @(#)w83877f.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + extern void w83877f_init(); diff --git a/src/xtide.c b/src/xtide.c index 78ca248fa..aaa1b8294 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * XT IDE controller emulation. + * + * Version: @(#)xtide.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include "ibm.h" #include "io.h" diff --git a/src/xtide.h b/src/xtide.h index 666783629..925d96568 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * XT IDE controller emulation. + * + * Version: @(#)xtide.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern device_t xtide_device; extern device_t xtide_at_device; extern device_t xtide_ps2_device; From 7ac99180e4d1b57b9fef46c68e9674eea6bcd906 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 29 May 2017 21:57:31 -0400 Subject: [PATCH 264/392] Moved ICONS/ to WIN/ICONS/, updated RC files. Renamed IDS_STRINGnnn to IDS_nnnn, renamed unnamed string IDs to IDS_nnnn, updated resource.h file. Win_settings.c used an unused 2047 string ID, now set to IDS_LANG_ENUS. --- src/WIN/86Box.rc | 511 +++++++++--------- src/{ => WIN}/ICONS/86Box-RB.ico | Bin src/{ => WIN}/ICONS/86Box.ico | Bin src/{ => WIN}/ICONS/cdrom_atapi.ico | Bin src/{ => WIN}/ICONS/cdrom_atapi_active.ico | Bin src/{ => WIN}/ICONS/cdrom_atapi_dma.ico | Bin .../ICONS/cdrom_atapi_dma_active.ico | Bin src/{ => WIN}/ICONS/cdrom_atapi_dma_empty.ico | Bin .../ICONS/cdrom_atapi_dma_empty_active.ico | Bin src/{ => WIN}/ICONS/cdrom_atapi_empty.ico | Bin .../ICONS/cdrom_atapi_empty_active.ico | Bin src/{ => WIN}/ICONS/cdrom_disabled.ico | Bin src/{ => WIN}/ICONS/cdrom_scsi.ico | Bin src/{ => WIN}/ICONS/cdrom_scsi_active.ico | Bin src/{ => WIN}/ICONS/cdrom_scsi_empty.ico | Bin .../ICONS/cdrom_scsi_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_1dd.ico | Bin src/{ => WIN}/ICONS/floppy_35_1dd_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_1dd_empty.ico | Bin .../ICONS/floppy_35_1dd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_2dd.ico | Bin src/{ => WIN}/ICONS/floppy_35_2dd_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_2dd_empty.ico | Bin .../ICONS/floppy_35_2dd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_2ed.ico | Bin src/{ => WIN}/ICONS/floppy_35_2ed_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_2ed_empty.ico | Bin .../ICONS/floppy_35_2ed_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_2hd.ico | Bin src/{ => WIN}/ICONS/floppy_35_2hd_active.ico | Bin src/{ => WIN}/ICONS/floppy_35_2hd_empty.ico | Bin .../ICONS/floppy_35_2hd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_1dd.ico | Bin src/{ => WIN}/ICONS/floppy_525_1dd_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_1dd_empty.ico | Bin .../ICONS/floppy_525_1dd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_2dd.ico | Bin src/{ => WIN}/ICONS/floppy_525_2dd_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_2dd_empty.ico | Bin .../ICONS/floppy_525_2dd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_2hd.ico | Bin src/{ => WIN}/ICONS/floppy_525_2hd_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_2hd_empty.ico | Bin .../ICONS/floppy_525_2hd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_2qd.ico | Bin src/{ => WIN}/ICONS/floppy_525_2qd_active.ico | Bin src/{ => WIN}/ICONS/floppy_525_2qd_empty.ico | Bin .../ICONS/floppy_525_2qd_empty_active.ico | Bin src/{ => WIN}/ICONS/floppy_disabled.ico | Bin src/{ => WIN}/ICONS/hard_disk.ico | Bin src/{ => WIN}/ICONS/hard_disk_active.ico | Bin src/{ => WIN}/ICONS/hard_disk_ide.ico | Bin src/{ => WIN}/ICONS/hard_disk_ide_active.ico | Bin src/{ => WIN}/ICONS/hard_disk_mfm.ico | Bin src/{ => WIN}/ICONS/hard_disk_mfm_active.ico | Bin .../ICONS/hard_disk_removable_scsi.ico | Bin .../ICONS/hard_disk_removable_scsi_active.ico | Bin .../ICONS/hard_disk_removable_scsi_empty.ico | Bin .../hard_disk_removable_scsi_empty_active.ico | Bin src/{ => WIN}/ICONS/hard_disk_rll.ico | Bin src/{ => WIN}/ICONS/hard_disk_rll_active.ico | Bin src/{ => WIN}/ICONS/hard_disk_scsi.ico | Bin src/{ => WIN}/ICONS/hard_disk_scsi_active.ico | Bin src/{ => WIN}/ICONS/hard_disk_xtide.ico | Bin .../ICONS/hard_disk_xtide_active.ico | Bin src/{ => WIN}/ICONS/input_devices.ico | Bin src/{ => WIN}/ICONS/machine.ico | Bin src/{ => WIN}/ICONS/network.ico | Bin src/{ => WIN}/ICONS/other_peripherals.ico | Bin src/{ => WIN}/ICONS/removable_devices.ico | Bin src/{ => WIN}/ICONS/sound.ico | Bin src/{ => WIN}/ICONS/video.ico | Bin src/WIN/pcap_if.rc | 10 +- src/WIN/resource.h | 223 ++++++-- src/WIN/win.c | 18 +- src/WIN/win.h | 1 + src/WIN/win_settings.c | 14 +- src/config.c | 8 +- src/network.c | 7 +- 79 files changed, 478 insertions(+), 314 deletions(-) rename src/{ => WIN}/ICONS/86Box-RB.ico (100%) rename src/{ => WIN}/ICONS/86Box.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_active.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_dma.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_dma_active.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_dma_empty.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_dma_empty_active.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_empty.ico (100%) rename src/{ => WIN}/ICONS/cdrom_atapi_empty_active.ico (100%) rename src/{ => WIN}/ICONS/cdrom_disabled.ico (100%) rename src/{ => WIN}/ICONS/cdrom_scsi.ico (100%) rename src/{ => WIN}/ICONS/cdrom_scsi_active.ico (100%) rename src/{ => WIN}/ICONS/cdrom_scsi_empty.ico (100%) rename src/{ => WIN}/ICONS/cdrom_scsi_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_1dd.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_1dd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_1dd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_1dd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2dd.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2dd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2dd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2dd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2ed.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2ed_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2ed_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2ed_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2hd.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2hd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2hd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_35_2hd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_1dd.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_1dd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_1dd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_1dd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2dd.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2dd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2dd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2dd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2hd.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2hd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2hd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2hd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2qd.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2qd_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2qd_empty.ico (100%) rename src/{ => WIN}/ICONS/floppy_525_2qd_empty_active.ico (100%) rename src/{ => WIN}/ICONS/floppy_disabled.ico (100%) rename src/{ => WIN}/ICONS/hard_disk.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_ide.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_ide_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_mfm.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_mfm_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_removable_scsi.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_removable_scsi_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_removable_scsi_empty.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_removable_scsi_empty_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_rll.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_rll_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_scsi.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_scsi_active.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_xtide.ico (100%) rename src/{ => WIN}/ICONS/hard_disk_xtide_active.ico (100%) rename src/{ => WIN}/ICONS/input_devices.ico (100%) rename src/{ => WIN}/ICONS/machine.ico (100%) rename src/{ => WIN}/ICONS/network.ico (100%) rename src/{ => WIN}/ICONS/other_peripherals.ico (100%) rename src/{ => WIN}/ICONS/removable_devices.ico (100%) rename src/{ => WIN}/ICONS/sound.ico (100%) rename src/{ => WIN}/ICONS/video.ico (100%) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index b8761032d..37c1a69e8 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -66,7 +66,7 @@ BEGIN MENUITEM "&2x", IDM_VID_SCALE_4X END MENUITEM SEPARATOR - MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN + MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN POPUP "Fullscreen &stretch mode" BEGIN MENUITEM "&Full screen stretch", IDM_VID_FS_FULL @@ -83,9 +83,11 @@ BEGIN END MENUITEM "S&tatus", IDM_STATUS #ifdef ENABLE_LOG_TOGGLES -#if defined ENABLE_BUSLOGIC_LOG || defined ENABLE_CDROM_LOG || defined ENABLE_D86F_LOG || defined ENABLE_FDC_LOG || defined ENABLE_IDE_LOG || defined ENABLE_NE2000_LOG +# if defined(ENABLE_BUSLOGIC_LOG) || defined(ENABLE_CDROM_LOG) || \ + defined(ENABLE_D86F_LOG) || defined(ENABLE_FDC_LOG) || \ + defined(ENABLE_IDE_LOG) || defined(ENABLE_NE2000_LOG) MENUITEM SEPARATOR -#endif +# endif #ifdef ENABLE_BUSLOGIC_LOG MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC #endif @@ -450,81 +452,81 @@ END // remains consistent on all systems. #ifdef RELEASE_BUILD /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box-RB.ico" #else /* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box.ico" #endif -128 ICON DISCARDABLE "ICONS/floppy_525_1dd.ico" -129 ICON DISCARDABLE "ICONS/floppy_525_1dd_active.ico" -130 ICON DISCARDABLE "ICONS/floppy_525_2dd.ico" -131 ICON DISCARDABLE "ICONS/floppy_525_2dd_active.ico" -132 ICON DISCARDABLE "ICONS/floppy_525_2qd.ico" -133 ICON DISCARDABLE "ICONS/floppy_525_2qd_active.ico" -134 ICON DISCARDABLE "ICONS/floppy_525_2hd.ico" -135 ICON DISCARDABLE "ICONS/floppy_525_2hd_active.ico" -144 ICON DISCARDABLE "ICONS/floppy_35_1dd.ico" -145 ICON DISCARDABLE "ICONS/floppy_35_1dd_active.ico" -146 ICON DISCARDABLE "ICONS/floppy_35_2dd.ico" -147 ICON DISCARDABLE "ICONS/floppy_35_2dd_active.ico" -150 ICON DISCARDABLE "ICONS/floppy_35_2hd.ico" -151 ICON DISCARDABLE "ICONS/floppy_35_2hd_active.ico" -152 ICON DISCARDABLE "ICONS/floppy_35_2ed.ico" -153 ICON DISCARDABLE "ICONS/floppy_35_2ed_active.ico" -160 ICON DISCARDABLE "ICONS/cdrom_atapi.ico" -161 ICON DISCARDABLE "ICONS/cdrom_atapi_active.ico" -162 ICON DISCARDABLE "ICONS/cdrom_atapi_dma.ico" -163 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_active.ico" -164 ICON DISCARDABLE "ICONS/cdrom_scsi.ico" -165 ICON DISCARDABLE "ICONS/cdrom_scsi_active.ico" -176 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi.ico" -177 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_active.ico" -192 ICON DISCARDABLE "ICONS/hard_disk_mfm.ico" -193 ICON DISCARDABLE "ICONS/hard_disk_mfm_active.ico" -194 ICON DISCARDABLE "ICONS/hard_disk_xtide.ico" -195 ICON DISCARDABLE "ICONS/hard_disk_xtide_active.ico" -196 ICON DISCARDABLE "ICONS/hard_disk_rll.ico" -197 ICON DISCARDABLE "ICONS/hard_disk_rll_active.ico" -198 ICON DISCARDABLE "ICONS/hard_disk.ico" -199 ICON DISCARDABLE "ICONS/hard_disk_active.ico" -200 ICON DISCARDABLE "ICONS/hard_disk_ide.ico" -201 ICON DISCARDABLE "ICONS/hard_disk_ide_active.ico" -202 ICON DISCARDABLE "ICONS/hard_disk_scsi.ico" -203 ICON DISCARDABLE "ICONS/hard_disk_scsi_active.ico" -256 ICON DISCARDABLE "ICONS/machine.ico" -257 ICON DISCARDABLE "ICONS/video.ico" -258 ICON DISCARDABLE "ICONS/input_devices.ico" -259 ICON DISCARDABLE "ICONS/sound.ico" -260 ICON DISCARDABLE "ICONS/network.ico" -261 ICON DISCARDABLE "ICONS/other_peripherals.ico" -262 ICON DISCARDABLE "ICONS/hard_disk.ico" -263 ICON DISCARDABLE "ICONS/removable_devices.ico" -384 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty.ico" -385 ICON DISCARDABLE "ICONS/floppy_525_1dd_empty_active.ico" -386 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty.ico" -387 ICON DISCARDABLE "ICONS/floppy_525_2dd_empty_active.ico" -388 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty.ico" -389 ICON DISCARDABLE "ICONS/floppy_525_2qd_empty_active.ico" -390 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty.ico" -391 ICON DISCARDABLE "ICONS/floppy_525_2hd_empty_active.ico" -400 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty.ico" -401 ICON DISCARDABLE "ICONS/floppy_35_1dd_empty_active.ico" -402 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty.ico" -403 ICON DISCARDABLE "ICONS/floppy_35_2dd_empty_active.ico" -406 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty.ico" -407 ICON DISCARDABLE "ICONS/floppy_35_2hd_empty_active.ico" -408 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty.ico" -409 ICON DISCARDABLE "ICONS/floppy_35_2ed_empty_active.ico" -416 ICON DISCARDABLE "ICONS/cdrom_atapi_empty.ico" -417 ICON DISCARDABLE "ICONS/cdrom_atapi_empty_active.ico" -418 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty.ico" -419 ICON DISCARDABLE "ICONS/cdrom_atapi_dma_empty_active.ico" -420 ICON DISCARDABLE "ICONS/cdrom_scsi_empty.ico" -421 ICON DISCARDABLE "ICONS/cdrom_scsi_empty_active.ico" -432 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_empty.ico" -433 ICON DISCARDABLE "ICONS/hard_disk_removable_scsi_empty_active.ico" -512 ICON DISCARDABLE "ICONS/floppy_disabled.ico" -514 ICON DISCARDABLE "ICONS/cdrom_disabled.ico" +128 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd.ico" +129 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd_active.ico" +130 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd.ico" +131 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd_active.ico" +132 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd.ico" +133 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd_active.ico" +134 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd.ico" +135 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd_active.ico" +144 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd.ico" +145 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd_active.ico" +146 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd.ico" +147 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd_active.ico" +150 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd.ico" +151 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd_active.ico" +152 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed.ico" +153 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed_active.ico" +160 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi.ico" +161 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_active.ico" +162 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma.ico" +163 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma_active.ico" +164 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi.ico" +165 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi_active.ico" +176 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi.ico" +177 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi_active.ico" +192 ICON DISCARDABLE "WIN/ICONS/hard_disk_mfm.ico" +193 ICON DISCARDABLE "WIN/ICONS/hard_disk_mfm_active.ico" +194 ICON DISCARDABLE "WIN/ICONS/hard_disk_xtide.ico" +195 ICON DISCARDABLE "WIN/ICONS/hard_disk_xtide_active.ico" +196 ICON DISCARDABLE "WIN/ICONS/hard_disk_rll.ico" +197 ICON DISCARDABLE "WIN/ICONS/hard_disk_rll_active.ico" +198 ICON DISCARDABLE "WIN/ICONS/hard_disk.ico" +199 ICON DISCARDABLE "WIN/ICONS/hard_disk_active.ico" +200 ICON DISCARDABLE "WIN/ICONS/hard_disk_ide.ico" +201 ICON DISCARDABLE "WIN/ICONS/hard_disk_ide_active.ico" +202 ICON DISCARDABLE "WIN/ICONS/hard_disk_scsi.ico" +203 ICON DISCARDABLE "WIN/ICONS/hard_disk_scsi_active.ico" +256 ICON DISCARDABLE "WIN/ICONS/machine.ico" +257 ICON DISCARDABLE "WIN/ICONS/video.ico" +258 ICON DISCARDABLE "WIN/ICONS/input_devices.ico" +259 ICON DISCARDABLE "WIN/ICONS/sound.ico" +260 ICON DISCARDABLE "WIN/ICONS/network.ico" +261 ICON DISCARDABLE "WIN/ICONS/other_peripherals.ico" +262 ICON DISCARDABLE "WIN/ICONS/hard_disk.ico" +263 ICON DISCARDABLE "WIN/ICONS/removable_devices.ico" +384 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd_empty.ico" +385 ICON DISCARDABLE "WIN/ICONS/floppy_525_1dd_empty_active.ico" +386 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd_empty.ico" +387 ICON DISCARDABLE "WIN/ICONS/floppy_525_2dd_empty_active.ico" +388 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd_empty.ico" +389 ICON DISCARDABLE "WIN/ICONS/floppy_525_2qd_empty_active.ico" +390 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd_empty.ico" +391 ICON DISCARDABLE "WIN/ICONS/floppy_525_2hd_empty_active.ico" +400 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd_empty.ico" +401 ICON DISCARDABLE "WIN/ICONS/floppy_35_1dd_empty_active.ico" +402 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd_empty.ico" +403 ICON DISCARDABLE "WIN/ICONS/floppy_35_2dd_empty_active.ico" +406 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd_empty.ico" +407 ICON DISCARDABLE "WIN/ICONS/floppy_35_2hd_empty_active.ico" +408 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed_empty.ico" +409 ICON DISCARDABLE "WIN/ICONS/floppy_35_2ed_empty_active.ico" +416 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_empty.ico" +417 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_empty_active.ico" +418 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma_empty.ico" +419 ICON DISCARDABLE "WIN/ICONS/cdrom_atapi_dma_empty_active.ico" +420 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi_empty.ico" +421 ICON DISCARDABLE "WIN/ICONS/cdrom_scsi_empty_active.ico" +432 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi_empty.ico" +433 ICON DISCARDABLE "WIN/ICONS/hard_disk_removable_scsi_empty_active.ico" +512 ICON DISCARDABLE "WIN/ICONS/floppy_disabled.ico" +514 ICON DISCARDABLE "WIN/ICONS/cdrom_disabled.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -647,205 +649,206 @@ END STRINGTABLE DISCARDABLE BEGIN - 2048 "86Box" - IDS_STRING2049 "86Box Error" - IDS_STRING2050 "86Box Fatal Error" - IDS_STRING2051 "This will reset 86Box.\nAre you sure you want to save the settings?" - IDS_STRING2052 "DirectDraw Screenshot Error" - IDS_STRING2053 "Invalid number of sectors (valid values are between 1 and 63)" - IDS_STRING2054 "Invalid number of heads (valid values are between 1 and 16)" - IDS_STRING2055 "Invalid number of cylinders (valid values are between 1 and 266305)" - IDS_STRING2056 "Please enter a valid file name" - IDS_STRING2057 "Unable to open the file for write" - IDS_STRING2058 "Attempting to create a HDI image larger than 4 GB" - IDS_STRING2059 "Remember to partition and format the new drive" - IDS_STRING2060 "Unable to open the file for read" - IDS_STRING2061 "HDI or HDX image with a sector size that is not 512 are not supported" - IDS_STRING2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." - IDS_STRING2063 "Configured ROM set not available.\nDefaulting to an available ROM set." + 2048 "86Box" + IDS_2049 "86Box Error" + IDS_2050 "86Box Fatal Error" + IDS_2051 "This will reset 86Box.\nAre you sure you want to save the settings?" + IDS_2052 "DirectDraw Screenshot Error" + IDS_2053 "Invalid number of sectors (valid values are between 1 and 63)" + IDS_2054 "Invalid number of heads (valid values are between 1 and 16)" + IDS_2055 "Invalid number of cylinders (valid values are between 1 and 266305)" + IDS_2056 "Please enter a valid file name" + IDS_2057 "Unable to open the file for write" + IDS_2058 "Attempting to create a HDI image larger than 4 GB" + IDS_2059 "Remember to partition and format the new drive" + IDS_2060 "Unable to open the file for read" + IDS_2061 "HDI or HDX image with a sector size that is not 512 are not supported" + IDS_2062 "86Box was unable to find any ROMs.\nAt least one ROM set is required to use 86Box." + IDS_2063 "Configured ROM set not available.\nDefaulting to an available ROM set." END STRINGTABLE DISCARDABLE BEGIN - IDS_STRING2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." - IDS_STRING2065 "Machine" - IDS_STRING2066 "Video" - IDS_STRING2067 "Input devices" - IDS_STRING2068 "Sound" - IDS_STRING2069 "Network" - IDS_STRING2070 "Other peripherals" - IDS_STRING2071 "Hard disks" - IDS_STRING2072 "Removable devices" - IDS_STRING2073 "%i"" floppy drive: %s" - IDS_STRING2074 "Disabled CD-ROM drive" - IDS_STRING2075 "%s CD-ROM drive: %s" - IDS_STRING2076 "Host CD/DVD Drive (%c:)" - IDS_STRING2077 "Click to capture mouse" - IDS_STRING2078 "Press F12-F8 to release mouse" - IDS_STRING2079 "Press F12-F8 or middle button to release mouse" + IDS_2064 "Configured video BIOS not available.\nDefaulting to an available video BIOS." + IDS_2065 "Machine" + IDS_2066 "Video" + IDS_2067 "Input devices" + IDS_2068 "Sound" + IDS_2069 "Network" + IDS_2070 "Other peripherals" + IDS_2071 "Hard disks" + IDS_2072 "Removable devices" + IDS_2073 "%i"" floppy drive: %s" + IDS_2074 "Disabled CD-ROM drive" + IDS_2075 "%s CD-ROM drive: %s" + IDS_2076 "Host CD/DVD Drive (%c:)" + IDS_2077 "Click to capture mouse" + IDS_2078 "Press F12-F8 to release mouse" + IDS_2079 "Press F12-F8 or middle button to release mouse" END STRINGTABLE DISCARDABLE BEGIN - 2080 "Drive" - 2081 "Location" - 2082 "Bus" - 2083 "File" - 2084 "C" - 2085 "H" - 2086 "S" - 2087 "MB" - 2088 "%i" - 2089 "Enabled" - 2090 "Mute" - 2091 "Type" - 2092 "Bus" - 2093 "DMA" - 2094 "KB" - 2095 "MFM, RLL, or ESDI CD-ROM drives never existed" + IDS_2080 "Drive" + IDS_2081 "Location" + IDS_2082 "Bus" + IDS_2083 "File" + IDS_2084 "C" + IDS_2085 "H" + IDS_2086 "S" + IDS_2087 "MB" + IDS_2088 "%i" + IDS_2089 "Enabled" + IDS_2090 "Mute" + IDS_2091 "Type" + IDS_2092 "Bus" + IDS_2093 "DMA" + IDS_2094 "KB" + IDS_2095 "MFM, RLL, or ESDI CD-ROM drives never existed" END STRINGTABLE DISCARDABLE BEGIN - 2096 "Slave" - 2097 "SCSI (ID %s, LUN %s)" - 2098 "Adapter Type" - 2099 "Base Address" - 2100 "IRQ" - 2101 "8-bit DMA" - 2102 "16-bit DMA" - 2103 "BIOS" - 2104 "Network Type" - 2105 "Surround Module" - 2106 "MPU-401 Base Address" - 2107 "No PCap devices found" - 2108 "On-board RAM" - 2109 "Memory Size" - 2110 "Display Type" - 2111 "RGB" + IDS_2096 "Slave" + IDS_2097 "SCSI (ID %s, LUN %s)" + IDS_2098 "Adapter Type" + IDS_2099 "Base Address" + IDS_2100 "IRQ" + IDS_2101 "8-bit DMA" + IDS_2102 "16-bit DMA" + IDS_2103 "BIOS" + IDS_2104 "Network Type" + IDS_2105 "Surround Module" + IDS_2106 "MPU-401 Base Address" + IDS_2107 "No PCap devices found" + IDS_2108 "On-board RAM" + IDS_2109 "Memory Size" + IDS_2110 "Display Type" + IDS_2111 "RGB" END STRINGTABLE DISCARDABLE BEGIN - 2112 "Composite" - 2113 "Composite Type" - 2114 "Old" - 2115 "New" - 2116 "RGB Type" - 2117 "Color" - 2118 "Monochrome (Green)" - 2119 "Monochrome (Amber)" - 2120 "Monochrome (Gray)" - 2121 "Color (no brown)" - 2122 "Monochrome (Default)" - 2123 "Snow Emulation" - 2124 "Bilinear Filtering" - 2125 "Dithering" - 2126 "Framebuffer Memory Size" - 2127 "Texture Memory Size" + IDS_2112 "Composite" + IDS_2113 "Composite Type" + IDS_2114 "Old" + IDS_2115 "New" + IDS_2116 "RGB Type" + IDS_2117 "Color" + IDS_2118 "Monochrome (Green)" + IDS_2119 "Monochrome (Amber)" + IDS_2120 "Monochrome (Gray)" + IDS_2121 "Color (no brown)" + IDS_2122 "Monochrome (Default)" + IDS_2123 "Snow Emulation" + IDS_2124 "Bilinear Filtering" + IDS_2125 "Dithering" + IDS_2126 "Framebuffer Memory Size" + IDS_2127 "Texture Memory Size" END STRINGTABLE DISCARDABLE BEGIN - 2128 "Screen Filter" - 2129 "Render Threads" - 2130 "Recompiler" - 2131 "System Default" - 2132 "%i Wait state(s)" - 2133 "8-bit" - 2134 "Slow 16-bit" - 2135 "Fast 16-bit" - 2136 "Slow VLB/PCI" - 2137 "Mid VLB/PCI" - 2138 "Fast VLB/PCI" - 2139 "Microsoft 2-button mouse (serial)" - 2140 "Mouse Systems mouse (serial)" - 2141 "2-button mouse (PS/2)" - 2142 "Microsoft Intellimouse (PS/2)" - 2143 "Bus mouse" + IDS_2128 "Screen Filter" + IDS_2129 "Render Threads" + IDS_2130 "Recompiler" + IDS_2131 "System Default" + IDS_2132 "%i Wait state(s)" + IDS_2133 "8-bit" + IDS_2134 "Slow 16-bit" + IDS_2135 "Fast 16-bit" + IDS_2136 "Slow VLB/PCI" + IDS_2137 "Mid VLB/PCI" + IDS_2138 "Fast VLB/PCI" + IDS_2139 "Microsoft 2-button mouse (serial)" + IDS_2140 "Mouse Systems mouse (serial)" + IDS_2141 "2-button mouse (PS/2)" + IDS_2142 "Microsoft Intellimouse (PS/2)" + IDS_2143 "Bus mouse" END STRINGTABLE DISCARDABLE BEGIN - 2144 "Standard 2-button joystick(s)" - 2145 "Standard 4-button joystick" - 2146 "Standard 6-button joystick" - 2147 "Standard 8-button joystick" - 2148 "CH Flightstick Pro" - 2149 "Microsoft SideWinder Pad" - 2150 "Thrustmaster Flight Control System" - 2151 "Disabled" - 2152 "None" - 2153 "AT Fixed Disk Adapter" - 2154 "Internal IDE" - 2155 "IRQ %i" - 2156 "MFM (%01i:%01i)" - 2157 "IDE (PIO+DMA) (%01i:%01i)" - 2158 "SCSI (%02i:%02i)" - 2159 "Invalid number of cylinders (valid values are between 1 and 1023)" - 2160 "%" PRIu64 - 2161 "Genius Bus mouse" - 2162 "Amstrad mouse" - 2163 "Attempting to create a spuriously large hard disk image" - 2164 "Invalid number of sectors (valid values are between 1 and 99)" - 2165 "MFM" - 2166 "XT IDE" - 2167 "RLL" - 2168 "IDE (PIO-only)" - 2169 "%01i:%01i" - 2170 "Custom..." - 2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" - 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" - 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" - 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2177 "Olivetti M24 mouse" - 2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" - 2179 "Floppy %i (%s): %ws" - 2180 "CD-ROM %i: %ws" - 2181 "MFM hard disk" - 2182 "IDE hard disk (PIO-only)" - 2183 "IDE hard disk (PIO and DMA)" - 2184 "SCSI hard disk" - 2185 "(empty)" - 2186 "(host drive %c:)" - 2187 "Custom (large)..." - 2188 "Type" - 2189 "ATAPI (PIO-only)" - 2190 "ATAPI (PIO and DMA)" - 2191 "ATAPI (PIO-only) (%01i:%01i)" - 2192 "ATAPI (PIO and DMA) (%01i:%01i)" - 2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" - 2194 "Unable to create bitmap file: %s" - 2195 "IDE (PIO-only) (%01i:%01i)" - 2196 "Add New Hard Disk" - 2197 "Add Existing Hard Disk" - 2198 "SCSI removable disk %i: %s" - 2199 "USB is not yet supported" - 2200 "Invalid PCap device" - 2201 "&Notify disk change" - 2202 "SCSI (removable)" - 2203 "SCSI (removable) (%02i:%02i)" - 2204 "Pcap Library Not Available" - 2205 "RLL (%01i:%01i)" - 2206 "XT IDE (%01i:%01i)" - 2207 "RLL hard disk" - 2208 "XT IDE hard disk" - 2209 "IDE (PIO and DMA)" - 2210 "SCSI" - 2211 "&New image..." - 2212 "Existing image..." - 2213 "Existing image (&Write-protected)..." - 2214 "E&ject" - 2215 "&Mute" - 2216 "E&mpty" - 2217 "&Reload previous image" - 2218 "&Image..." - 2219 "PCap failed to set up because it may not be initialized" - 2220 "Image (&Write-protected)..." - 2221 "English (United States)" + IDS_2144 "Standard 2-button joystick(s)" + IDS_2145 "Standard 4-button joystick" + IDS_2146 "Standard 6-button joystick" + IDS_2147 "Standard 8-button joystick" + IDS_2148 "CH Flightstick Pro" + IDS_2149 "Microsoft SideWinder Pad" + IDS_2150 "Thrustmaster Flight Control System" + IDS_2151 "Disabled" + IDS_2152 "None" + IDS_2153 "AT Fixed Disk Adapter" + IDS_2154 "Internal IDE" + IDS_2155 "IRQ %i" + IDS_2156 "MFM (%01i:%01i)" + IDS_2157 "IDE (PIO+DMA) (%01i:%01i)" + IDS_2158 "SCSI (%02i:%02i)" + IDS_2159 "Invalid number of cylinders (valid values are between 1 and 1023)" + IDS_2160 "%" PRIu64 + IDS_2161 "Genius Bus mouse" + IDS_2162 "Amstrad mouse" + IDS_2163 "Attempting to create a spuriously large hard disk image" + IDS_2164 "Invalid number of sectors (valid values are between 1 and 99)" + IDS_2165 "MFM" + IDS_2166 "XT IDE" + IDS_2167 "RLL" + IDS_2168 "IDE (PIO-only)" + IDS_2169 "%01i:%01i" + IDS_2170 "Custom..." + IDS_2171 "%" PRIu64 " MB (CHS: %" PRIu64 ", %" PRIu64 ", %" PRIu64 ")" + IDS_2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" + IDS_2173"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" + IDS_2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" + IDS_2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" + IDS_2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + IDS_2177 "Olivetti M24 mouse" + IDS_2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" + IDS_2179 "Floppy %i (%s): %ws" + IDS_2180 "CD-ROM %i: %ws" + IDS_2181 "MFM hard disk" + IDS_2182 "IDE hard disk (PIO-only)" + IDS_2183 "IDE hard disk (PIO and DMA)" + IDS_2184 "SCSI hard disk" + IDS_2185 "(empty)" + IDS_2186 "(host drive %c:)" + IDS_2187 "Custom (large)..." + IDS_2188 "Type" + IDS_2189 "ATAPI (PIO-only)" + IDS_2190 "ATAPI (PIO and DMA)" + IDS_2191 "ATAPI (PIO-only) (%01i:%01i)" + IDS_2192 "ATAPI (PIO and DMA) (%01i:%01i)" + IDS_2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + IDS_2194 "Unable to create bitmap file: %s" + IDS_2195 "IDE (PIO-only) (%01i:%01i)" + IDS_2196 "Add New Hard Disk" + IDS_2197 "Add Existing Hard Disk" + IDS_2198 "SCSI removable disk %i: %s" + IDS_2199 "USB is not yet supported" + IDS_2200 "Invalid PCap device" + IDS_2201 "&Notify disk change" + IDS_2202 "SCSI (removable)" + IDS_2203 "SCSI (removable) (%02i:%02i)" + IDS_2204 "Pcap Library Not Available" + IDS_2205 "RLL (%01i:%01i)" + IDS_2206 "XT IDE (%01i:%01i)" + IDS_2207 "RLL hard disk" + IDS_2208 "XT IDE hard disk" + IDS_2209 "IDE (PIO and DMA)" + IDS_2210 "SCSI" + IDS_2211 "&New image..." + IDS_2212 "Existing image..." + IDS_2213 "Existing image (&Write-protected)..." + IDS_2214 "E&ject" + IDS_2215 "&Mute" + IDS_2216 "E&mpty" + IDS_2217 "&Reload previous image" + IDS_2218 "&Image..." + IDS_2219 "PCap failed to set up because it may not be initialized" + IDS_2220 "Image (&Write-protected)..." + IDS_2221 "English (United States)" END +#define IDS_LANG_ENUS IDS_2221 #ifndef _MAC @@ -855,8 +858,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,20,0,0 - PRODUCTVERSION 1,20,0,0 + FILEVERSION 2,0,0,0 + PRODUCTVERSION 2,0,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -874,14 +877,14 @@ BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "IRC #SoftHistory\0" VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" - VALUE "FileVersion", "1.20\0" - VALUE "InternalName", "pc_new\0" + VALUE "FileVersion", "2.00\0" + VALUE "InternalName", "86Box\0" VALUE "LegalCopyright", "Copyright © SoftHistory, Sarah Walker, 2007-2017, Released under the GNU GPL v2\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "86Box.exe\0" VALUE "PrivateBuild", "\0" VALUE "ProductName", "86Box Emulator\0" - VALUE "ProductVersion", "1.20\0" + VALUE "ProductVersion", "2.00\0" VALUE "SpecialBuild", "\0" END END diff --git a/src/ICONS/86Box-RB.ico b/src/WIN/ICONS/86Box-RB.ico similarity index 100% rename from src/ICONS/86Box-RB.ico rename to src/WIN/ICONS/86Box-RB.ico diff --git a/src/ICONS/86Box.ico b/src/WIN/ICONS/86Box.ico similarity index 100% rename from src/ICONS/86Box.ico rename to src/WIN/ICONS/86Box.ico diff --git a/src/ICONS/cdrom_atapi.ico b/src/WIN/ICONS/cdrom_atapi.ico similarity index 100% rename from src/ICONS/cdrom_atapi.ico rename to src/WIN/ICONS/cdrom_atapi.ico diff --git a/src/ICONS/cdrom_atapi_active.ico b/src/WIN/ICONS/cdrom_atapi_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_active.ico rename to src/WIN/ICONS/cdrom_atapi_active.ico diff --git a/src/ICONS/cdrom_atapi_dma.ico b/src/WIN/ICONS/cdrom_atapi_dma.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma.ico rename to src/WIN/ICONS/cdrom_atapi_dma.ico diff --git a/src/ICONS/cdrom_atapi_dma_active.ico b/src/WIN/ICONS/cdrom_atapi_dma_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma_active.ico rename to src/WIN/ICONS/cdrom_atapi_dma_active.ico diff --git a/src/ICONS/cdrom_atapi_dma_empty.ico b/src/WIN/ICONS/cdrom_atapi_dma_empty.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma_empty.ico rename to src/WIN/ICONS/cdrom_atapi_dma_empty.ico diff --git a/src/ICONS/cdrom_atapi_dma_empty_active.ico b/src/WIN/ICONS/cdrom_atapi_dma_empty_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_dma_empty_active.ico rename to src/WIN/ICONS/cdrom_atapi_dma_empty_active.ico diff --git a/src/ICONS/cdrom_atapi_empty.ico b/src/WIN/ICONS/cdrom_atapi_empty.ico similarity index 100% rename from src/ICONS/cdrom_atapi_empty.ico rename to src/WIN/ICONS/cdrom_atapi_empty.ico diff --git a/src/ICONS/cdrom_atapi_empty_active.ico b/src/WIN/ICONS/cdrom_atapi_empty_active.ico similarity index 100% rename from src/ICONS/cdrom_atapi_empty_active.ico rename to src/WIN/ICONS/cdrom_atapi_empty_active.ico diff --git a/src/ICONS/cdrom_disabled.ico b/src/WIN/ICONS/cdrom_disabled.ico similarity index 100% rename from src/ICONS/cdrom_disabled.ico rename to src/WIN/ICONS/cdrom_disabled.ico diff --git a/src/ICONS/cdrom_scsi.ico b/src/WIN/ICONS/cdrom_scsi.ico similarity index 100% rename from src/ICONS/cdrom_scsi.ico rename to src/WIN/ICONS/cdrom_scsi.ico diff --git a/src/ICONS/cdrom_scsi_active.ico b/src/WIN/ICONS/cdrom_scsi_active.ico similarity index 100% rename from src/ICONS/cdrom_scsi_active.ico rename to src/WIN/ICONS/cdrom_scsi_active.ico diff --git a/src/ICONS/cdrom_scsi_empty.ico b/src/WIN/ICONS/cdrom_scsi_empty.ico similarity index 100% rename from src/ICONS/cdrom_scsi_empty.ico rename to src/WIN/ICONS/cdrom_scsi_empty.ico diff --git a/src/ICONS/cdrom_scsi_empty_active.ico b/src/WIN/ICONS/cdrom_scsi_empty_active.ico similarity index 100% rename from src/ICONS/cdrom_scsi_empty_active.ico rename to src/WIN/ICONS/cdrom_scsi_empty_active.ico diff --git a/src/ICONS/floppy_35_1dd.ico b/src/WIN/ICONS/floppy_35_1dd.ico similarity index 100% rename from src/ICONS/floppy_35_1dd.ico rename to src/WIN/ICONS/floppy_35_1dd.ico diff --git a/src/ICONS/floppy_35_1dd_active.ico b/src/WIN/ICONS/floppy_35_1dd_active.ico similarity index 100% rename from src/ICONS/floppy_35_1dd_active.ico rename to src/WIN/ICONS/floppy_35_1dd_active.ico diff --git a/src/ICONS/floppy_35_1dd_empty.ico b/src/WIN/ICONS/floppy_35_1dd_empty.ico similarity index 100% rename from src/ICONS/floppy_35_1dd_empty.ico rename to src/WIN/ICONS/floppy_35_1dd_empty.ico diff --git a/src/ICONS/floppy_35_1dd_empty_active.ico b/src/WIN/ICONS/floppy_35_1dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_1dd_empty_active.ico rename to src/WIN/ICONS/floppy_35_1dd_empty_active.ico diff --git a/src/ICONS/floppy_35_2dd.ico b/src/WIN/ICONS/floppy_35_2dd.ico similarity index 100% rename from src/ICONS/floppy_35_2dd.ico rename to src/WIN/ICONS/floppy_35_2dd.ico diff --git a/src/ICONS/floppy_35_2dd_active.ico b/src/WIN/ICONS/floppy_35_2dd_active.ico similarity index 100% rename from src/ICONS/floppy_35_2dd_active.ico rename to src/WIN/ICONS/floppy_35_2dd_active.ico diff --git a/src/ICONS/floppy_35_2dd_empty.ico b/src/WIN/ICONS/floppy_35_2dd_empty.ico similarity index 100% rename from src/ICONS/floppy_35_2dd_empty.ico rename to src/WIN/ICONS/floppy_35_2dd_empty.ico diff --git a/src/ICONS/floppy_35_2dd_empty_active.ico b/src/WIN/ICONS/floppy_35_2dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_2dd_empty_active.ico rename to src/WIN/ICONS/floppy_35_2dd_empty_active.ico diff --git a/src/ICONS/floppy_35_2ed.ico b/src/WIN/ICONS/floppy_35_2ed.ico similarity index 100% rename from src/ICONS/floppy_35_2ed.ico rename to src/WIN/ICONS/floppy_35_2ed.ico diff --git a/src/ICONS/floppy_35_2ed_active.ico b/src/WIN/ICONS/floppy_35_2ed_active.ico similarity index 100% rename from src/ICONS/floppy_35_2ed_active.ico rename to src/WIN/ICONS/floppy_35_2ed_active.ico diff --git a/src/ICONS/floppy_35_2ed_empty.ico b/src/WIN/ICONS/floppy_35_2ed_empty.ico similarity index 100% rename from src/ICONS/floppy_35_2ed_empty.ico rename to src/WIN/ICONS/floppy_35_2ed_empty.ico diff --git a/src/ICONS/floppy_35_2ed_empty_active.ico b/src/WIN/ICONS/floppy_35_2ed_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_2ed_empty_active.ico rename to src/WIN/ICONS/floppy_35_2ed_empty_active.ico diff --git a/src/ICONS/floppy_35_2hd.ico b/src/WIN/ICONS/floppy_35_2hd.ico similarity index 100% rename from src/ICONS/floppy_35_2hd.ico rename to src/WIN/ICONS/floppy_35_2hd.ico diff --git a/src/ICONS/floppy_35_2hd_active.ico b/src/WIN/ICONS/floppy_35_2hd_active.ico similarity index 100% rename from src/ICONS/floppy_35_2hd_active.ico rename to src/WIN/ICONS/floppy_35_2hd_active.ico diff --git a/src/ICONS/floppy_35_2hd_empty.ico b/src/WIN/ICONS/floppy_35_2hd_empty.ico similarity index 100% rename from src/ICONS/floppy_35_2hd_empty.ico rename to src/WIN/ICONS/floppy_35_2hd_empty.ico diff --git a/src/ICONS/floppy_35_2hd_empty_active.ico b/src/WIN/ICONS/floppy_35_2hd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_35_2hd_empty_active.ico rename to src/WIN/ICONS/floppy_35_2hd_empty_active.ico diff --git a/src/ICONS/floppy_525_1dd.ico b/src/WIN/ICONS/floppy_525_1dd.ico similarity index 100% rename from src/ICONS/floppy_525_1dd.ico rename to src/WIN/ICONS/floppy_525_1dd.ico diff --git a/src/ICONS/floppy_525_1dd_active.ico b/src/WIN/ICONS/floppy_525_1dd_active.ico similarity index 100% rename from src/ICONS/floppy_525_1dd_active.ico rename to src/WIN/ICONS/floppy_525_1dd_active.ico diff --git a/src/ICONS/floppy_525_1dd_empty.ico b/src/WIN/ICONS/floppy_525_1dd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_1dd_empty.ico rename to src/WIN/ICONS/floppy_525_1dd_empty.ico diff --git a/src/ICONS/floppy_525_1dd_empty_active.ico b/src/WIN/ICONS/floppy_525_1dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_1dd_empty_active.ico rename to src/WIN/ICONS/floppy_525_1dd_empty_active.ico diff --git a/src/ICONS/floppy_525_2dd.ico b/src/WIN/ICONS/floppy_525_2dd.ico similarity index 100% rename from src/ICONS/floppy_525_2dd.ico rename to src/WIN/ICONS/floppy_525_2dd.ico diff --git a/src/ICONS/floppy_525_2dd_active.ico b/src/WIN/ICONS/floppy_525_2dd_active.ico similarity index 100% rename from src/ICONS/floppy_525_2dd_active.ico rename to src/WIN/ICONS/floppy_525_2dd_active.ico diff --git a/src/ICONS/floppy_525_2dd_empty.ico b/src/WIN/ICONS/floppy_525_2dd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_2dd_empty.ico rename to src/WIN/ICONS/floppy_525_2dd_empty.ico diff --git a/src/ICONS/floppy_525_2dd_empty_active.ico b/src/WIN/ICONS/floppy_525_2dd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_2dd_empty_active.ico rename to src/WIN/ICONS/floppy_525_2dd_empty_active.ico diff --git a/src/ICONS/floppy_525_2hd.ico b/src/WIN/ICONS/floppy_525_2hd.ico similarity index 100% rename from src/ICONS/floppy_525_2hd.ico rename to src/WIN/ICONS/floppy_525_2hd.ico diff --git a/src/ICONS/floppy_525_2hd_active.ico b/src/WIN/ICONS/floppy_525_2hd_active.ico similarity index 100% rename from src/ICONS/floppy_525_2hd_active.ico rename to src/WIN/ICONS/floppy_525_2hd_active.ico diff --git a/src/ICONS/floppy_525_2hd_empty.ico b/src/WIN/ICONS/floppy_525_2hd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_2hd_empty.ico rename to src/WIN/ICONS/floppy_525_2hd_empty.ico diff --git a/src/ICONS/floppy_525_2hd_empty_active.ico b/src/WIN/ICONS/floppy_525_2hd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_2hd_empty_active.ico rename to src/WIN/ICONS/floppy_525_2hd_empty_active.ico diff --git a/src/ICONS/floppy_525_2qd.ico b/src/WIN/ICONS/floppy_525_2qd.ico similarity index 100% rename from src/ICONS/floppy_525_2qd.ico rename to src/WIN/ICONS/floppy_525_2qd.ico diff --git a/src/ICONS/floppy_525_2qd_active.ico b/src/WIN/ICONS/floppy_525_2qd_active.ico similarity index 100% rename from src/ICONS/floppy_525_2qd_active.ico rename to src/WIN/ICONS/floppy_525_2qd_active.ico diff --git a/src/ICONS/floppy_525_2qd_empty.ico b/src/WIN/ICONS/floppy_525_2qd_empty.ico similarity index 100% rename from src/ICONS/floppy_525_2qd_empty.ico rename to src/WIN/ICONS/floppy_525_2qd_empty.ico diff --git a/src/ICONS/floppy_525_2qd_empty_active.ico b/src/WIN/ICONS/floppy_525_2qd_empty_active.ico similarity index 100% rename from src/ICONS/floppy_525_2qd_empty_active.ico rename to src/WIN/ICONS/floppy_525_2qd_empty_active.ico diff --git a/src/ICONS/floppy_disabled.ico b/src/WIN/ICONS/floppy_disabled.ico similarity index 100% rename from src/ICONS/floppy_disabled.ico rename to src/WIN/ICONS/floppy_disabled.ico diff --git a/src/ICONS/hard_disk.ico b/src/WIN/ICONS/hard_disk.ico similarity index 100% rename from src/ICONS/hard_disk.ico rename to src/WIN/ICONS/hard_disk.ico diff --git a/src/ICONS/hard_disk_active.ico b/src/WIN/ICONS/hard_disk_active.ico similarity index 100% rename from src/ICONS/hard_disk_active.ico rename to src/WIN/ICONS/hard_disk_active.ico diff --git a/src/ICONS/hard_disk_ide.ico b/src/WIN/ICONS/hard_disk_ide.ico similarity index 100% rename from src/ICONS/hard_disk_ide.ico rename to src/WIN/ICONS/hard_disk_ide.ico diff --git a/src/ICONS/hard_disk_ide_active.ico b/src/WIN/ICONS/hard_disk_ide_active.ico similarity index 100% rename from src/ICONS/hard_disk_ide_active.ico rename to src/WIN/ICONS/hard_disk_ide_active.ico diff --git a/src/ICONS/hard_disk_mfm.ico b/src/WIN/ICONS/hard_disk_mfm.ico similarity index 100% rename from src/ICONS/hard_disk_mfm.ico rename to src/WIN/ICONS/hard_disk_mfm.ico diff --git a/src/ICONS/hard_disk_mfm_active.ico b/src/WIN/ICONS/hard_disk_mfm_active.ico similarity index 100% rename from src/ICONS/hard_disk_mfm_active.ico rename to src/WIN/ICONS/hard_disk_mfm_active.ico diff --git a/src/ICONS/hard_disk_removable_scsi.ico b/src/WIN/ICONS/hard_disk_removable_scsi.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi.ico rename to src/WIN/ICONS/hard_disk_removable_scsi.ico diff --git a/src/ICONS/hard_disk_removable_scsi_active.ico b/src/WIN/ICONS/hard_disk_removable_scsi_active.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi_active.ico rename to src/WIN/ICONS/hard_disk_removable_scsi_active.ico diff --git a/src/ICONS/hard_disk_removable_scsi_empty.ico b/src/WIN/ICONS/hard_disk_removable_scsi_empty.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi_empty.ico rename to src/WIN/ICONS/hard_disk_removable_scsi_empty.ico diff --git a/src/ICONS/hard_disk_removable_scsi_empty_active.ico b/src/WIN/ICONS/hard_disk_removable_scsi_empty_active.ico similarity index 100% rename from src/ICONS/hard_disk_removable_scsi_empty_active.ico rename to src/WIN/ICONS/hard_disk_removable_scsi_empty_active.ico diff --git a/src/ICONS/hard_disk_rll.ico b/src/WIN/ICONS/hard_disk_rll.ico similarity index 100% rename from src/ICONS/hard_disk_rll.ico rename to src/WIN/ICONS/hard_disk_rll.ico diff --git a/src/ICONS/hard_disk_rll_active.ico b/src/WIN/ICONS/hard_disk_rll_active.ico similarity index 100% rename from src/ICONS/hard_disk_rll_active.ico rename to src/WIN/ICONS/hard_disk_rll_active.ico diff --git a/src/ICONS/hard_disk_scsi.ico b/src/WIN/ICONS/hard_disk_scsi.ico similarity index 100% rename from src/ICONS/hard_disk_scsi.ico rename to src/WIN/ICONS/hard_disk_scsi.ico diff --git a/src/ICONS/hard_disk_scsi_active.ico b/src/WIN/ICONS/hard_disk_scsi_active.ico similarity index 100% rename from src/ICONS/hard_disk_scsi_active.ico rename to src/WIN/ICONS/hard_disk_scsi_active.ico diff --git a/src/ICONS/hard_disk_xtide.ico b/src/WIN/ICONS/hard_disk_xtide.ico similarity index 100% rename from src/ICONS/hard_disk_xtide.ico rename to src/WIN/ICONS/hard_disk_xtide.ico diff --git a/src/ICONS/hard_disk_xtide_active.ico b/src/WIN/ICONS/hard_disk_xtide_active.ico similarity index 100% rename from src/ICONS/hard_disk_xtide_active.ico rename to src/WIN/ICONS/hard_disk_xtide_active.ico diff --git a/src/ICONS/input_devices.ico b/src/WIN/ICONS/input_devices.ico similarity index 100% rename from src/ICONS/input_devices.ico rename to src/WIN/ICONS/input_devices.ico diff --git a/src/ICONS/machine.ico b/src/WIN/ICONS/machine.ico similarity index 100% rename from src/ICONS/machine.ico rename to src/WIN/ICONS/machine.ico diff --git a/src/ICONS/network.ico b/src/WIN/ICONS/network.ico similarity index 100% rename from src/ICONS/network.ico rename to src/WIN/ICONS/network.ico diff --git a/src/ICONS/other_peripherals.ico b/src/WIN/ICONS/other_peripherals.ico similarity index 100% rename from src/ICONS/other_peripherals.ico rename to src/WIN/ICONS/other_peripherals.ico diff --git a/src/ICONS/removable_devices.ico b/src/WIN/ICONS/removable_devices.ico similarity index 100% rename from src/ICONS/removable_devices.ico rename to src/WIN/ICONS/removable_devices.ico diff --git a/src/ICONS/sound.ico b/src/WIN/ICONS/sound.ico similarity index 100% rename from src/ICONS/sound.ico rename to src/WIN/ICONS/sound.ico diff --git a/src/ICONS/video.ico b/src/WIN/ICONS/video.ico similarity index 100% rename from src/ICONS/video.ico rename to src/WIN/ICONS/video.ico diff --git a/src/WIN/pcap_if.rc b/src/WIN/pcap_if.rc index 57d78e657..dd4a8f120 100644 --- a/src/WIN/pcap_if.rc +++ b/src/WIN/pcap_if.rc @@ -5,12 +5,14 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #endif //_WIN32 +/* + * Icons by Devcore + * - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png + */ #ifdef RELEASE_BUILD -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box-RB.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box-RB.ico" #else -/* Icon by Devcore - https://commons.wikimedia.org/wiki/File:Icon_PC2_256x256.png */ -100 ICON DISCARDABLE "ICONS/86Box.ico" +100 ICON DISCARDABLE "WIN/ICONS/86Box.ico" #endif diff --git a/src/WIN/resource.h b/src/WIN/resource.h index fdc53b649..a9d14e0b4 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -83,40 +83,197 @@ #define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 #define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 #define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 -#define IDS_STRING2049 2049 -#define IDS_STRING2050 2050 -#define IDS_STRING2051 2051 -#define IDS_STRING2052 2052 -#define IDS_STRING2053 2053 -#define IDS_STRING2054 2054 -#define IDS_STRING2055 2055 -#define IDS_STRING2056 2056 -#define IDS_STRING2057 2057 -#define IDS_STRING2058 2058 -#define IDS_STRING2059 2059 -#define IDS_STRING2060 2060 -#define IDS_STRING2061 2061 -#define IDS_STRING2062 2062 -#define IDS_STRING2063 2063 -#define IDS_STRING2064 2064 -#define IDS_STRING2065 2065 -#define IDS_STRING2066 2066 -#define IDS_STRING2067 2067 -#define IDS_STRING2068 2068 -#define IDS_STRING2069 2069 -#define IDS_STRING2070 2070 -#define IDS_STRING2071 2071 -#define IDS_STRING2072 2072 -#define IDS_STRING2073 2073 -#define IDS_STRING2074 2074 -#define IDS_STRING2075 2075 -#define IDS_STRING2076 2076 -#define IDS_STRING2077 2077 -#define IDS_STRING2078 2078 -#define IDS_STRING2079 2079 -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 +#define IDS_STRINGS 2048 +#define IDS_2049 2049 +#define IDS_2050 2050 +#define IDS_2051 2051 +#define IDS_2052 2052 +#define IDS_2053 2053 +#define IDS_2054 2054 +#define IDS_2055 2055 +#define IDS_2056 2056 +#define IDS_2057 2057 +#define IDS_2058 2058 +#define IDS_2059 2059 +#define IDS_2060 2060 +#define IDS_2061 2061 +#define IDS_2062 2062 +#define IDS_2063 2063 +#define IDS_2064 2064 +#define IDS_2065 2065 +#define IDS_2066 2066 +#define IDS_2067 2067 +#define IDS_2068 2068 +#define IDS_2069 2069 +#define IDS_2070 2070 +#define IDS_2071 2071 +#define IDS_2072 2072 +#define IDS_2073 2073 +#define IDS_2074 2074 +#define IDS_2075 2075 +#define IDS_2076 2076 +#define IDS_2077 2077 +#define IDS_2078 2078 +#define IDS_2079 2079 +#define IDS_2080 2080 +#define IDS_2081 2081 +#define IDS_2082 2082 +#define IDS_2083 2083 +#define IDS_2084 2084 +#define IDS_2085 2085 +#define IDS_2086 2086 +#define IDS_2087 2087 +#define IDS_2088 2088 +#define IDS_2089 2089 +#define IDS_2090 2090 +#define IDS_2091 2091 +#define IDS_2092 2092 +#define IDS_2093 2093 +#define IDS_2094 2094 +#define IDS_2095 2095 +#define IDS_2096 2096 +#define IDS_2097 2097 +#define IDS_2098 2098 +#define IDS_2099 2099 +#define IDS_2100 2100 +#define IDS_2101 2101 +#define IDS_2102 2102 +#define IDS_2103 2103 +#define IDS_2104 2104 +#define IDS_2105 2105 +#define IDS_2106 2106 +#define IDS_2107 2107 +#define IDS_2108 2108 +#define IDS_2109 2109 +#define IDS_2110 2110 +#define IDS_2111 2111 +#define IDS_2112 2112 +#define IDS_2113 2113 +#define IDS_2114 2114 +#define IDS_2115 2115 +#define IDS_2116 2116 +#define IDS_2117 2117 +#define IDS_2118 2118 +#define IDS_2119 2119 +#define IDS_2120 2120 +#define IDS_2121 2121 +#define IDS_2122 2122 +#define IDS_2123 2123 +#define IDS_2124 2124 +#define IDS_2125 2125 +#define IDS_2126 2126 +#define IDS_2127 2127 +#define IDS_2128 2128 +#define IDS_2129 2129 +#define IDS_2130 2130 +#define IDS_2131 2131 +#define IDS_2132 2132 +#define IDS_2133 2133 +#define IDS_2134 2134 +#define IDS_2135 2135 +#define IDS_2136 2136 +#define IDS_2137 2137 +#define IDS_2138 2138 +#define IDS_2139 2139 +#define IDS_2140 2140 +#define IDS_2141 2141 +#define IDS_2142 2142 +#define IDS_2143 2143 +#define IDS_2144 2144 +#define IDS_2145 2145 +#define IDS_2146 2146 +#define IDS_2147 2147 +#define IDS_2148 2148 +#define IDS_2149 2149 +#define IDS_2150 2150 +#define IDS_2151 2151 +#define IDS_2152 2152 +#define IDS_2153 2153 +#define IDS_2154 2154 +#define IDS_2155 2155 +#define IDS_2156 2156 +#define IDS_2157 2157 +#define IDS_2158 2158 +#define IDS_2159 2159 +#define IDS_2160 2160 +#define IDS_2161 2161 +#define IDS_2162 2162 +#define IDS_2163 2163 +#define IDS_2164 2164 +#define IDS_2165 2165 +#define IDS_2166 2166 +#define IDS_2167 2167 +#define IDS_2168 2168 +#define IDS_2169 2169 +#define IDS_2170 2170 +#define IDS_2171 2171 +#define IDS_2172 2172 +#define IDS_2173 2173 +#define IDS_2174 2174 +#define IDS_2175 2175 +#define IDS_2176 2176 +#define IDS_2177 2177 +#define IDS_2178 2178 +#define IDS_2179 2179 +#define IDS_2180 2180 +#define IDS_2181 2181 +#define IDS_2182 2182 +#define IDS_2183 2183 +#define IDS_2184 2184 +#define IDS_2185 2185 +#define IDS_2186 2186 +#define IDS_2187 2187 +#define IDS_2188 2188 +#define IDS_2189 2189 +#define IDS_2190 2190 +#define IDS_2191 2191 +#define IDS_2192 2192 +#define IDS_2193 2193 +#define IDS_2194 2194 +#define IDS_2195 2195 +#define IDS_2196 2196 +#define IDS_2197 2197 +#define IDS_2198 2198 +#define IDS_2199 2199 +#define IDS_2200 2200 +#define IDS_2201 2201 +#define IDS_2202 2202 +#define IDS_2203 2203 +#define IDS_2204 2204 +#define IDS_2205 2205 +#define IDS_2206 2206 +#define IDS_2207 2207 +#define IDS_2208 2208 +#define IDS_2209 2209 +#define IDS_2200 2200 +#define IDS_2201 2201 +#define IDS_2202 2202 +#define IDS_2203 2203 +#define IDS_2204 2204 +#define IDS_2205 2205 +#define IDS_2206 2206 +#define IDS_2207 2207 +#define IDS_2208 2208 +#define IDS_2209 2209 +#define IDS_2210 2210 +#define IDS_2211 2211 +#define IDS_2212 2212 +#define IDS_2213 2213 +#define IDS_2214 2214 +#define IDS_2215 2215 +#define IDS_2216 2216 +#define IDS_2217 2217 +#define IDS_2218 2218 +#define IDS_2219 2219 +#define IDS_2220 2220 +#define IDS_2221 2221 + +#define IDS_LANG_ENUS IDS_2221 + + +#define IDM_ABOUT 40001 +#define IDC_ABOUT_ICON 65535 #define IDM_FILE_RESET 40015 #define IDM_FILE_HRESET 40016 #define IDM_FILE_EXIT 40017 diff --git a/src/WIN/win.c b/src/WIN/win.c index 3abbcf894..6c25ddfa3 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1518,7 +1518,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz } if (c == ROM_MAX) { - msgbox_critical(ghwnd, 2062); + msgbox_critical(ghwnd, IDS_2062); return 0; } @@ -1529,7 +1529,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz { if (romset!=-1) { - msgbox_info(ghwnd, 2063); + msgbox_info(ghwnd, IDS_2063); } for (c=0;c= 0; c--) { @@ -1870,7 +1870,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (video_fullscreen_first) { video_fullscreen_first = 0; - msgbox_info(ghwnd, 2193); + msgbox_info(ghwnd, IDS_2193); } startblit(); @@ -1984,7 +1984,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_LOAD: pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 0)) + if (!file_dlg_st(hwnd, IDS_2174, "", 0)) { if (msgbox_reset_yn(ghwnd) == IDYES) { @@ -2001,7 +2001,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_CONFIG_SAVE: pause = 1; - if (!file_dlg_st(hwnd, 2174, "", 1)) + if (!file_dlg_st(hwnd, IDS_2174, "", 1)) { config_save(wopenfilestring); } @@ -2231,7 +2231,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; } - ret = file_dlg_w_st(hwnd, 2173, discfns[id], id); + ret = file_dlg_w_st(hwnd, IDS_2173, discfns[id], id); if (!ret) { disc_close(id); @@ -2287,7 +2287,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; } - if (!file_dlg_w_st(hwnd, 2175, cdrom_image[id].image_path, 0)) + if (!file_dlg_w_st(hwnd, IDS_2175, cdrom_image[id].image_path, 0)) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; wcscpy(temp_image_path, wopenfilestring); @@ -2376,7 +2376,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR case IDM_RDISK_IMAGE: case IDM_RDISK_IMAGE_WP: id = item_params & 0x001f; - ret = file_dlg_w_st(hwnd, 2172, hdc[id].fn, id); + ret = file_dlg_w_st(hwnd, IDS_2172, hdc[id].fn, id); if (!ret) { removable_disk_unload(id); diff --git a/src/WIN/win.h b/src/WIN/win.h index f36b487e5..a5a8b9918 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -18,6 +18,7 @@ # define _WIN32_WINNT 0x0501 # endif */ # include +# include "resource.h" # undef BITMAP diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 84a6a0645..76a4ebfb5 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -2454,7 +2454,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus != HDD_BUS_SCSI_REMOVABLE)) { hdc_ptr->bus = HDD_BUS_DISABLED; - msgbox_error(hwndParentDialog, 2056); + msgbox_error(hwndParentDialog, IDS_2056); return TRUE; } else if ((wcslen(hd_file_name) == 0) && (hdc_ptr->bus == HDD_BUS_SCSI_REMOVABLE)) @@ -2526,7 +2526,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (size >= 0x100000000ll) { fclose(f); - msgbox_error(hwndParentDialog, 2058); + msgbox_error(hwndParentDialog, IDS_2058); return TRUE; } @@ -2549,7 +2549,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W if (size > 0xffffffffffffffffll) { fclose(f); - msgbox_error(hwndParentDialog, 2163); + msgbox_error(hwndParentDialog, IDS_2163); return TRUE; } @@ -2589,7 +2589,7 @@ static BOOL CALLBACK win_settings_hard_disks_add_proc(HWND hdlg, UINT message, W } fclose(f); - msgbox_info(hwndParentDialog, 2059); + msgbox_info(hwndParentDialog, IDS_2059); } hd_add_ok_common: @@ -2615,7 +2615,7 @@ hd_add_ok_common: if (f != NULL) { fclose(f); - if (msgbox_question(ghwnd, 2178) != IDYES) + if (msgbox_question(ghwnd, IDS_2178) != IDYES) { return FALSE; } @@ -2637,7 +2637,7 @@ hdd_add_file_open_error: fread(§or_size, 1, 4, f); if (sector_size != 512) { - msgbox_error(hwndParentDialog, 2061); + msgbox_error(hwndParentDialog, IDS_2061); fclose(f); return TRUE; } @@ -4047,7 +4047,7 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); - h = GetDlgItem(hdlg, 2047); + h = GetDlgItem(hdlg, IDS_LANG_ENUS); /*was:2047 !*/ EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); return TRUE; diff --git a/src/config.c b/src/config.c index 550f442fe..26edf34ee 100644 --- a/src/config.c +++ b/src/config.c @@ -1011,11 +1011,11 @@ static void loadconfig_network(void) { if ((network_ndev == 1) && strcmp(network_pcap, "none")) { - msgbox_error(ghwnd, 2107); + msgbox_error(ghwnd, IDS_2107); } else if (network_dev_to_id(p) == -1) { - msgbox_error(ghwnd, 2200); + msgbox_error(ghwnd, IDS_2200); } strcpy(network_pcap, "none"); @@ -1173,14 +1173,14 @@ static int config_string_to_bus(char *str, int cdrom) if (!strcmp(str, "usb")) { - msgbox_error(ghwnd, 2199); + msgbox_error(ghwnd, IDS_2199); return 0; } return 0; no_mfm_cdrom: - msgbox_error(ghwnd, 2095); + msgbox_error(ghwnd, IDS_2095); return 0; } diff --git a/src/network.c b/src/network.c index a707be3b0..be58eaac2 100644 --- a/src/network.c +++ b/src/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.6 2017/05/22 + * Version: @(#)network.c 1.0.7 2017/05/29 * * Authors: Kotori, * Fred N. van Kempen, @@ -78,7 +78,8 @@ network_init(void) if (i > 0) network_ndev += i; - if (network_type != NET_TYPE_PCAP) network_pcap_close(); + if (network_type != NET_TYPE_PCAP) + network_pcap_close(); } @@ -105,7 +106,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); if (ret < 0) { - msgbox_error(ghwnd, 2219); + msgbox_error(ghwnd, IDS_2219); network_type = NET_TYPE_NONE; } break; From 044e3ba8ea6b319e591d5c8871327ea523aef93e Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 29 May 2017 22:21:55 -0400 Subject: [PATCH 265/392] Removed resource.h from source files, its included through win.h now. --- src/WIN/win.c | 5 +---- src/WIN/win_d3d.cc | 4 +--- src/WIN/win_d3d_fs.cc | 4 +--- src/WIN/win_deviceconfig.c | 4 +--- src/WIN/win_iodev.c | 3 +-- src/WIN/win_joystickconfig.c | 3 ++- src/WIN/win_language.c | 5 ++--- src/WIN/win_settings.c | 2 -- src/WIN/win_status.c | 1 - 9 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 292c446df..09d271da5 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -10,12 +10,11 @@ * * Version: @(#)win.c 1.0.0 2017/05/30 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include #include @@ -60,8 +59,6 @@ #include #include -#include "resource.h" - #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index 04720448a..f090465b3 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -10,18 +10,16 @@ * * Version: @(#)win_d3d.cc 1.0.0 2017/05/30 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include "../video/video.h" #include "win.h" #include "win_d3d.h" #include "win_cgapal.h" -#include "resource.h" extern "C" void fatal(const char *format, ...); diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 91c420132..fb58c8c3a 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -10,12 +10,11 @@ * * Version: @(#)win_d3d_fs.cc 1.0.0 2017/05/30 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include #include "../86box.h" @@ -23,7 +22,6 @@ #include "win.h" #include "win_d3d.h" #include "win_cgapal.h" -#include "resource.h" extern "C" void fatal(const char *format, ...); diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index 1dc548278..1b1f994ce 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -10,16 +10,14 @@ * * Version: @(#)win_deviceconfig.c 1.0.0 2017/05/30 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include "../ibm.h" #include "../config.h" #include "../device.h" -#include "resource.h" #define NO_UNICODE /*FIXME: not Unicode? */ #include "win.h" #include diff --git a/src/WIN/win_iodev.c b/src/WIN/win_iodev.c index 56d5d5df8..c2c2de9db 100644 --- a/src/WIN/win_iodev.c +++ b/src/WIN/win_iodev.c @@ -13,7 +13,6 @@ * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. */ - #define UNICODE #define _WIN32_WINNT 0x0501 #define BITMAP WINDOWS_BITMAP @@ -38,9 +37,9 @@ #include "../cdrom_null.h" #include "../scsi_disk.h" #include "plat_iodev.h" -#include "resource.h" #include "win.h" + void cdrom_eject(uint8_t id) { int part; diff --git a/src/WIN/win_joystickconfig.c b/src/WIN/win_joystickconfig.c index 8962366d6..3cd5a0c68 100644 --- a/src/WIN/win_joystickconfig.c +++ b/src/WIN/win_joystickconfig.c @@ -11,14 +11,15 @@ #include "../device.h" #include "../gameport.h" #include "plat_joystick.h" -#include "resource.h" #include "win.h" + static int joystick_nr; static int joystick_config_type; #define AXIS_STRINGS_MAX 3 static char *axis_strings[AXIS_STRINGS_MAX] = {"X Axis", "Y Axis", "Z Axis"}; + static void rebuild_axis_button_selections(HWND hdlg) { int id = IDC_CONFIG_BASE + 2; diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index 00cb70482..6279e2da6 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -10,12 +10,11 @@ * * Version: @(#)win_language.c 1.0.0 2017/05/30 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #define UNICODE #define BITMAP WINDOWS_BITMAP @@ -28,10 +27,10 @@ #include "../ibm.h" #include "../device.h" #include "../ide.h" -#include "resource.h" #include "win.h" #include "win_language.h" + LCID dwLanguage; uint32_t dwLangID, dwSubLangID; diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 1d6c475d9..73fc90ed1 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -13,7 +13,6 @@ * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. */ - #define UNICODE #define BITMAP WINDOWS_BITMAP #include @@ -45,7 +44,6 @@ #include "plat_midi.h" #include "win.h" #include "win_language.h" -#include "resource.h" /* Machine category */ diff --git a/src/WIN/win_status.c b/src/WIN/win_status.c index 59a7a5947..32012cb75 100644 --- a/src/WIN/win_status.c +++ b/src/WIN/win_status.c @@ -11,7 +11,6 @@ #include "../cpu/x86_ops.h" #include "../cpu/codegen.h" #include "../device.h" -#include "resource.h" #include "win.h" From 287323aa3a03906eb4cf4a448d6f4f299065ab7a Mon Sep 17 00:00:00 2001 From: waltje Date: Wed, 31 May 2017 01:22:52 -0400 Subject: [PATCH 266/392] Changes to allow XP to work again. See comment in Makefile.MinGW regarding -DANSI_CFG. --- src/Makefile.mingw | 3 ++- src/config.c | 52 ++++++++++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 6264531cf..21b5bc92c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.18 2017/05/28 +# Version: @(#)Makefile.mingw 1.0.19 2017/05/30 # # Authors: Kotori, # Fred N. van Kempen, @@ -30,6 +30,7 @@ endif # Add feature selections here. # -DBUGGER adds the ISA BusBugger emulation. +# -DANSI_CFG forces the config file to ANSI encoding. ifndef EXTRAS EXTRAS = endif diff --git a/src/config.c b/src/config.c index 26edf34ee..a524e27be 100644 --- a/src/config.c +++ b/src/config.c @@ -1,6 +1,10 @@ /* Copyright holders: Sarah Walker - see COPYING for more details -*/ + * see COPYING for more details + * + * NOTE: Forcing config files to be in Unicode encoding breaks it on + * Windows XP, and possibly also Vista. Use -DANSI_CFG for use + * on these systems. + */ #include #include #include @@ -136,23 +140,25 @@ static char ename[256]; void config_load(wchar_t *fn) { - int c; - + section_t *current_section; section_t *new_section; entry_t *new_entry; + FILE *f; + int c; int sd = 0, ed = 0, data_pos; - FILE *f = _wfopen(fn, L"rt, ccs=UNICODE"); - section_t *current_section; - - memset(&config_head, 0, sizeof(list_t)); - - current_section = malloc(sizeof(section_t)); - memset(current_section, 0, sizeof(section_t)); - list_add(¤t_section->list, &config_head); - +#ifdef ANSI_CFG + f = _wfopen(fn, L"rt"); +#else + f = _wfopen(fn, L"rt, ccs=UNICODE"); +#endif if (!f) return; + + current_section = malloc(sizeof(section_t)); + memset(current_section, 0x00, sizeof(section_t)); + memset(&config_head, 0x00, sizeof(list_t)); + list_add(¤t_section->list, &config_head); while (1) { @@ -229,7 +235,11 @@ void config_load(wchar_t *fn) void config_new(void) { +#ifdef ANSI_CFG + FILE *f = _wfopen(config_file, L"wt"); +#else FILE *f = _wfopen(config_file, L"wt, ccs=UNICODE"); +#endif fclose(f); } @@ -692,13 +702,19 @@ static wchar_t wname[512]; void config_save(wchar_t *fn) { - FILE *f = _wfopen(fn, L"wt, ccs=UNICODE"); section_t *current_section; - + FILE *f; int fl = 0; - + +#ifdef ANSI_CFG + f = _wfopen(fn, L"wt"); +#else + f = _wfopen(fn, L"wt, ccs=UNICODE"); +#endif + if (f == NULL) + return; + current_section = (section_t *)config_head.next; - while (current_section) { entry_t *current_entry; @@ -746,9 +762,9 @@ void config_save(wchar_t *fn) } - static wchar_t *read_nvr_path; + /* General */ static void loadconfig_general(void) { From d90abaa4a9c0f2c7c869776745b30a5f03f464e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 31 May 2017 09:05:53 +0200 Subject: [PATCH 267/392] Fix mouse cursor leaving the rendering area when captured --- src/WIN/win.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 09d271da5..0be43d165 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -326,7 +326,7 @@ void mainthread(LPVOID param) if (mousecapture) { - GetWindowRect(ghwnd, &r); + GetWindowRect(hwndRender, &r); ClipCursor(&r); } @@ -2059,7 +2059,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (!mousecapture && !video_fullscreen) { GetClipCursor(&oldclip); - GetWindowRect(hwnd, &rect); + GetWindowRect(hwndRender, &rect); ClipCursor(&rect); mousecapture = 1; @@ -2101,7 +2101,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (mousecapture) { - GetWindowRect(hwnd, &rect); + GetWindowRect(hwndRender, &rect); ClipCursor(&rect); } From 872f06657aa0dcabd008414795db682b0e4df6c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Wed, 31 May 2017 12:00:37 +0200 Subject: [PATCH 268/392] Disabled multiselect in Settings --- src/WIN/86Box.rc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index cbbea2b67..dd7c91c85 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -195,7 +195,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,246,220,50,14 PUSHBUTTON "Cancel",IDCANCEL,307,220,50,14 CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,7,90,197 + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,197 CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 LTEXT "Language:",2047,7,222,41,10 COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | @@ -401,7 +401,8 @@ STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,18,253,92 + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,18,253,92 LTEXT "Hard disks:",-1,7,7,34,8 PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 @@ -428,11 +429,12 @@ STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32", - LVS_REPORT | LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP, - 7,18,253,60 + LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,18,253,60 LTEXT "Floppy drives:",-1,7,7,43,8 CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,7,116,253,60 + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,116,253,60 LTEXT "CD-ROM drives:",-1,7,106,50,8 COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP From e6adf90e297e3d055bb78d25ccde9334d432a1de Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 01:47:54 +0200 Subject: [PATCH 269/392] Fixed several CD-ROM-related status bar icon bugs; CD-ROM set to host drive no longer gets reset to empty; The CD audio thread initializer now ignores the mute status of the drives; CD-ROM IOCTL audio handler is now more thread-safe; Fixed CD-ROM image audio; Added more sanity checks to memory read/write code in 808x.c; Initial settings are now sane again. --- src/CPU/808x.c | 6 +++ src/Makefile.mingw | 2 +- src/SOUND/sound.c | 4 +- src/WIN/win.c | 19 +++---- src/cdrom.c | 7 +++ src/cdrom_dosbox.cpp | 51 +++++++++++-------- src/cdrom_dosbox.h | 15 +++--- src/cdrom_image.cc | 15 ------ src/cdrom_ioctl.c | 117 ++++++++++++++++++++++++++++++------------- src/config.c | 42 +++++++++++++--- src/config.h | 2 +- src/pc.c | 30 +++++------ 12 files changed, 193 insertions(+), 117 deletions(-) diff --git a/src/CPU/808x.c b/src/CPU/808x.c index c0e6dfa15..32a52e955 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -61,12 +61,14 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val); uint8_t readmemb(uint32_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=4; + if (readlookup2 == NULL) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } uint8_t readmembf(uint32_t a) { + if (readlookup2 == NULL) return readmembl(a); if (readlookup2[(a)>>12]==-1) return readmembl(a); else return *(uint8_t *)(readlookup2[(a) >> 12] + (a)); } @@ -74,6 +76,7 @@ uint8_t readmembf(uint32_t a) uint16_t readmemw(uint32_t s, uint16_t a) { if (a!=(cs+cpu_state.pc)) memcycs+=(8>>is8086); + if (readlookup2 == NULL) return readmemwl(s,a); if ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)) return readmemwl(s,a); else return *(uint16_t *)(readlookup2[(s + a) >> 12] + s + a); } @@ -91,6 +94,7 @@ void writemembl(uint32_t addr, uint8_t val); void writememb(uint32_t a, uint8_t v) { memcycs+=4; + if (writelookup2 == NULL) writemembl(a,v); if (writelookup2[(a)>>12]==-1) writemembl(a,v); else *(uint8_t *)(writelookup2[a >> 12] + a) = v; } @@ -98,12 +102,14 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val); void writememw(uint32_t s, uint32_t a, uint16_t v) { memcycs+=(8>>is8086); + if (writelookup2 == NULL) writememwl(s,a,v); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } void writememll(uint32_t seg, uint32_t addr, uint32_t val); void writememl(uint32_t s, uint32_t a, uint32_t v) { + if (writelookup2 == NULL) writememll(s,a,v); if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememll(s,a,v); else *(uint32_t *)(writelookup2[(s + a) >> 12] + s + a) = v; } diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 21b5bc92c..d443739c1 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -40,7 +40,7 @@ ifndef DEBUG DEBUG = n endif ifndef OPTIM -OPTIM = y +OPTIM = n endif ifndef X64 X64 = n diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 6a6deafc7..fb0237ac9 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -246,7 +246,7 @@ void sound_init() for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) { available_cdrom_drives++; } @@ -335,7 +335,7 @@ void sound_cd_thread_reset() for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].bus_type && cdrom_drives[i].sound_on) + if (cdrom_drives[i].bus_type != CDROM_BUS_DISABLED) { available_cdrom_drives++; } diff --git a/src/WIN/win.c b/src/WIN/win.c index 0be43d165..7d742beb3 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -473,7 +473,7 @@ void create_cdrom_submenu(HMENU m, int id) { if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) { - if (!host_cdrom_drive_available[cdrom_drives[id].host_drive]) + if (!host_cdrom_drive_available[cdrom_drives[id].host_drive - 'A']) { cdrom_drives[id].host_drive = 0; } @@ -1189,20 +1189,17 @@ void update_status_bar_panes(HWND hwnds) case SB_CDROM: /* CD-ROM */ id = sb_part_meanings[i] & 0xf; - if (cdrom_drives[id].host_drive < 0x41) + if (cdrom_drives[id].host_drive == 200) { - sb_icon_flags[i] = 256; + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; + } + else if ((cdrom_drives[id].host_drive >= 'A') && (cdrom_drives[id].host_drive <= 'Z')) + { + sb_icon_flags[i] = 0; } else { - if (cdrom_drives[id].host_drive == 0x200) - { - sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; - } - else - { - sb_icon_flags[i] = 0; - } + sb_icon_flags[i] = 256; } if (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) { diff --git a/src/cdrom.c b/src/cdrom.c index 2bac1e2e3..21eba3ae0 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2111,6 +2111,12 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) return 0; } + if ((cdrom_drives[id].handler->status(id) == CD_STATUS_PLAYING) || (cdrom_drives[id].handler->status(id) == CD_STATUS_PAUSED)) + { + ready = 1; + goto skip_ready_check; + } + if (cdrom_drives[id].handler->medium_changed(id)) { /* cdrom_log("CD-ROM %i: Medium has changed...\n", id); */ @@ -2119,6 +2125,7 @@ int cdrom_pre_execution_check(uint8_t id, uint8_t *cdb) ready = cdrom_drives[id].handler->ready(id); +skip_ready_check: if (!ready && cdrom[id].unit_attention) { /* If the drive is not ready, there is no reason to keep the diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index 906f7b0c8..be632fd38 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -51,27 +51,38 @@ using namespace std; CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { - file = fopen64(filename, "rb"); - error = (file == NULL); + // file = fopen64(filename, "rb"); + // error = (file == NULL); + memset(fn, 0, sizeof(fn)); + strcpy(fn, filename); + error = false; } CDROM_Interface_Image::BinaryFile::~BinaryFile() { - delete file; + // delete file; + memset(fn, 0, sizeof(fn)); } bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) { uint64_t offs = 0; + file = fopen64(fn, "rb"); fseeko64(file, seek, SEEK_SET); offs = fread(buffer, 1, count, file); - return (offs == count); + fclose(file); + // return (offs == count); + return 1; } uint64_t CDROM_Interface_Image::BinaryFile::getLength() { + uint64_t ret = 0; + file = fopen64(fn, "rb"); fseeko64(file, 0, SEEK_END); - return ftello64(file); + ret = ftello64(file); + fclose(file); + return ret; } CDROM_Interface_Image::CDROM_Interface_Image() @@ -184,9 +195,9 @@ bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long se { int track = GetTrack(sector) - 1; if (track < 0) return false; - - uint64_t seek = tracks[track].skip + (sector - tracks[track].start); - seek *= (uint64_t) tracks[track].sectorSize; + + uint64_t s = (uint64_t) sector; + uint64_t seek = tracks[track].skip + ((s - tracks[track].start) * tracks[track].sectorSize); uint64_t length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; @@ -259,10 +270,10 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) return true; } -bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2) { Bit8u pvd[COOKED_SECTOR_SIZE]; - int seek = 16 * sectorSize; // first vd is located at sector 16 + uint64_t seek = 16 * sectorSize; // first vd is located at sector 16 if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; if (mode2) seek += 24; file->read(pvd, seek, COOKED_SECTOR_SIZE); @@ -292,9 +303,9 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) Track track = {0, 0, 0, 0, 0, 0, false, NULL}; tracks.clear(); uint64_t shift = 0; - int currPregap = 0; - int totalPregap = 0; - int prestart = 0; + uint64_t currPregap = 0; + uint64_t totalPregap = 0; + uint64_t prestart = 0; bool success; bool canAddTrack = false; char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument @@ -353,9 +364,9 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) canAddTrack = true; } else if (command == "INDEX") { - int index; + uint64_t index; line >> index; - int frame; + uint64_t frame; success = GetCueFrame(frame, line); if (index == 1) track.start = frame; @@ -410,10 +421,10 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) return true; } -bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap) +bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap) { // frames between index 0(prestart) and 1(curr.start) must be skipped - int skip; + uint64_t skip; if (prestart > 0) { if (prestart > curr.start) return false; skip = curr.start - prestart; @@ -434,8 +445,8 @@ bool CDROM_Interface_Image::AddTrack(Track &curr, uint64_t &shift, int prestart, // current track consumes data from the same file as the previous if (prev.file == curr.file) { curr.start += shift; - prev.length = curr.start + ((uint64_t) totalPregap) - prev.start - ((uint64_t) skip); - curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + (prev.length * prev.sectorSize) + (skip * curr.sectorSize); totalPregap += currPregap; curr.start += totalPregap; // current track uses a different file as the previous track @@ -525,7 +536,7 @@ bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) return true; } -bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +bool CDROM_Interface_Image::GetCueFrame(uint64_t &frames, istream &in) { string msf; in >> msf; diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index f8fd704a7..243723fe4 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -116,6 +116,7 @@ private: uint64_t getLength(); private: BinaryFile(); + char fn[260]; FILE *file; }; @@ -123,10 +124,10 @@ private: int number; int track_number; int attr; - int start; - int length; - int skip; - int sectorSize; + uint64_t start; + uint64_t length; + uint64_t skip; + uint64_t sectorSize; bool mode2; TrackFile *file; }; @@ -156,14 +157,14 @@ static void CDAudioCallBack(Bitu len); void ClearTracks(); bool LoadIsoFile(char *filename); - bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + bool CanReadPVD(TrackFile *file, uint64_t sectorSize, bool mode2); // cue sheet processing bool LoadCueSheet(char *cuefile); bool GetRealFileName(std::string& filename, std::string& pathname); bool GetCueKeyword(std::string &keyword, std::istream &in); - bool GetCueFrame(int &frames, std::istream &in); + bool GetCueFrame(uint64_t &frames, std::istream &in); bool GetCueString(std::string &str, std::istream &in); - bool AddTrack(Track &curr, uint64_t &shift, int prestart, int &totalPregap, int currPregap); + bool AddTrack(Track &curr, uint64_t &shift, uint64_t prestart, uint64_t &totalPregap, uint64_t currPregap); std::vector tracks; typedef std::vector::iterator track_it; diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 07566b7ef..ae4ef727c 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -779,7 +779,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, break; cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); -// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); b[len++] = 0; /* reserved */ b[len++] = attr; b[len++] = number; /* track number */ @@ -805,20 +804,6 @@ static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, } b[0] = (uint8_t)(((len-2) >> 8) & 0xff); b[1] = (uint8_t)((len-2) & 0xff); - /* - pclog("Table of Contents:\n"); - pclog("First track - %02X\n", first_track); - pclog("Last track - %02X\n", last_track); - for (c = 0; c <= last_track; c++) - { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); - } - for (c = 0;c <= last_track; c++) { - cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); - pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); - } - */ return len; } diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index b5f827fa7..5422c25b5 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)cdrom_ioctl.c 1.0.0 2017/05/30 + * Version: @(#)cdrom_ioctl.c 1.0.1 2017/05/31 * * Author: Sarah Walker, * Miran Grca, @@ -35,6 +35,7 @@ typedef struct { HANDLE hIOCTL; CDROM_TOC toc; + int is_playing; } cdrom_ioctl_windows_t; cdrom_ioctl_windows_t cdrom_ioctl_windows[CDROM_NUM]; @@ -62,6 +63,8 @@ void cdrom_ioctl_log(const char *format, ...) #endif } +static int ioctl_hopen(uint8_t id); + void ioctl_audio_callback(uint8_t id, int16_t *output, int len) { RAW_READ_INFO in; @@ -84,10 +87,11 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) in.DiskOffset.HighPart = 0; in.SectorCount = 1; in.TrackMode = CDDA; - ioctl_open(id, 0); if (!DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_RAW_READ, &in, sizeof(in), &(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 2352, &count, NULL)) { memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_buflen = len; } @@ -96,11 +100,12 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) cdrom[id].seek_pos++; cdrom_ioctl[id].cd_buflen += (2352 / 2); } - ioctl_close(id); } else { memset(&(cdrom_ioctl[id].cd_buffer[cdrom_ioctl[id].cd_buflen]), 0, (BUF_SIZE - cdrom_ioctl[id].cd_buflen) * 2); + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl[id].cd_buflen = len; } @@ -112,6 +117,8 @@ void ioctl_audio_callback(uint8_t id, int16_t *output, int len) void ioctl_audio_stop(uint8_t id) { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); cdrom_ioctl[id].cd_state = CD_STOPPED; } @@ -232,6 +239,11 @@ static void ioctl_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) /* Adjust because the host expects a minimum adjusted LBA of 0 which is equivalent to an absolute LBA of 150. */ cdrom[id].seek_pos = 150; } + if (!cdrom_ioctl_windows[id].is_playing) + { + ioctl_hopen(id); + cdrom_ioctl_windows[id].is_playing = 1; + } cdrom_ioctl[id].cd_state = CD_PLAYING; } @@ -265,6 +277,11 @@ static void ioctl_stop(uint8_t id) { return; } + if (cdrom_ioctl_windows[id].is_playing) + { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_close(id); + } cdrom_ioctl[id].cd_state = CD_STOPPED; } @@ -277,9 +294,16 @@ static int ioctl_ready(uint8_t id) { return 0; } - ioctl_open(id, 0); - temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); - ioctl_close(id); + if (cdrom_ioctl_windows[id].hIOCTL == NULL) + { + ioctl_hopen(id); + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + ioctl_close(id); + } + else + { + temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); + } if (!temp) { return 0; @@ -310,7 +334,7 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i return 0; } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, &lbtoc, sizeof(lbtoc), &size, NULL); ioctl_close(id); cdrom_ioctl[id].tocvalid=1; @@ -326,6 +350,8 @@ static int ioctl_get_last_block(uint8_t id, unsigned char starttrack, int msf, i return lb; } +static void ioctl_read_capacity(uint8_t id, uint8_t *b); + static int ioctl_medium_changed(uint8_t id) { unsigned long size; @@ -335,7 +361,7 @@ static int ioctl_medium_changed(uint8_t id) { return 0; /* This will be handled by the not ready handler instead. */ } - ioctl_open(id, 0); + ioctl_hopen(id); temp = DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc,sizeof(ltoc), &size, NULL); ioctl_close(id); if (!temp) @@ -351,6 +377,10 @@ static int ioctl_medium_changed(uint8_t id) { cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; } + ioctl_hopen(id); + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + ioctl_close(id); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; } @@ -363,6 +393,10 @@ static int ioctl_medium_changed(uint8_t id) cdrom_ioctl[id].cd_state = CD_STOPPED; cdrom_ioctl_log("Setting TOC...\n"); cdrom_ioctl_windows[id].toc = ltoc; + ioctl_hopen(id); + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + ioctl_close(id); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); return 1; /* TOC mismatches. */ } @@ -390,7 +424,7 @@ static uint8_t ioctl_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) else { insub.Format = IOCTL_CDROM_CURRENT_POSITION; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); ioctl_close(id); memset(cdrom_ioctl[id].sub_q_data_format, 0, 16); @@ -485,8 +519,13 @@ static void ioctl_eject(uint8_t id) { return; } + if (cdrom_ioctl_windows[id].is_playing) + { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_stop(id); + } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_EJECT_MEDIA,NULL,0,NULL,0,&size,NULL); ioctl_close(id); } @@ -498,9 +537,16 @@ static void ioctl_load(uint8_t id) { return; } + if (cdrom_ioctl_windows[id].is_playing) + { + cdrom_ioctl_windows[id].is_playing = 0; + ioctl_stop(id); + } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_STORAGE_LOAD_MEDIA,NULL,0,NULL,0,&size,NULL); + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); ioctl_close(id); cdrom_ioctl[id].cdrom_capacity = ioctl_get_last_block(id, 0, 0, 4096, 0); } @@ -597,10 +643,10 @@ struct sptd_with_sense static int ioctl_get_block_length(uint8_t id, const UCHAR *cdb, int number_of_blocks, int no_length_check) { - int sector_type = 0; - int temp_len = 0; + int sector_type = 0; + int temp_len = 0; - if (no_length_check) + if (no_length_check) { switch (cdb[0]) { @@ -753,8 +799,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) if (!cdrom_ioctl[id].capacity_read) { - ioctl_open(id, 0); - SCSICommand(id, cdb, buf, &len, 1); memcpy(cdrom_ioctl[id].rcbuf, buf, len); @@ -764,8 +808,6 @@ static void ioctl_read_capacity(uint8_t id, uint8_t *b) { memcpy(b, cdrom_ioctl[id].rcbuf, 16); } - - ioctl_close(id); } static int ioctl_media_type_id(uint8_t id) @@ -782,7 +824,7 @@ static int ioctl_media_type_id(uint8_t id) old_sense[1] = cdrom_asc; old_sense[2] = cdrom_asc; - ioctl_open(id, 0); + ioctl_hopen(id); SCSICommand(id, cdb, msbuf, &len, 1); @@ -846,7 +888,7 @@ static int ioctl_sector_data_type(uint8_t id, int sector, int ismsf) cdb_msf[4] = cdb_msf[7] = ((sector >> 8) & 0xff); cdb_msf[5] = cdb_msf[8] = (sector & 0xff); - ioctl_open(id, 0); + ioctl_hopen(id); if (ioctl_is_track_audio(id, sector, ismsf)) { @@ -901,7 +943,7 @@ static void ioctl_validate_toc(uint8_t id) return; } cdrom_ioctl[id].cd_state = CD_STOPPED; - ioctl_open(id, 0); + ioctl_hopen(id); cdrom_ioctl_log("Validating TOC...\n"); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); ioctl_close(id); @@ -935,7 +977,7 @@ static int ioctl_pass_through(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t ioctl_validate_toc(id); } - ioctl_open(id, 0); + ioctl_hopen(id); memcpy((void *) cdb, in_cdb, 12); @@ -1046,7 +1088,7 @@ void ioctl_reset(uint8_t id) return; } - ioctl_open(id, 0); + ioctl_hopen(id); DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL, IOCTL_CDROM_READ_TOC, NULL, 0, <oc, sizeof(ltoc), &size, NULL); ioctl_close(id); @@ -1054,28 +1096,30 @@ void ioctl_reset(uint8_t id) cdrom_ioctl[id].tocvalid = 1; } +int ioctl_hopen(uint8_t id) +{ + if (cdrom_ioctl_windows[id].is_playing) return 0; + cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + return 0; +} + int ioctl_open(uint8_t id, char d) { - if (!cdrom_ioctl[id].ioctl_inited) - { - sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); - cdrom_ioctl[id].tocvalid=0; - } + sprintf(cdrom_ioctl[id].ioctl_path,"\\\\.\\%c:",d); + cdrom_ioctl[id].tocvalid=0; cdrom_ioctl_windows[id].hIOCTL = CreateFile(cdrom_ioctl[id].ioctl_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); cdrom_drives[id].handler = &ioctl_cdrom; - if (!cdrom_ioctl[id].ioctl_inited) - { - cdrom_ioctl[id].ioctl_inited=1; - cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ - ioctl_read_capacity(id, NULL); - CloseHandle(cdrom_ioctl_windows[id].hIOCTL); - cdrom_ioctl_windows[id].hIOCTL = NULL; - } + cdrom_ioctl[id].ioctl_inited=1; + cdrom_ioctl[id].capacity_read=0; /* With this two lines, we read the READ CAPACITY command output from the host drive into our cache buffer. */ + ioctl_read_capacity(id, NULL); + CloseHandle(cdrom_ioctl_windows[id].hIOCTL); + cdrom_ioctl_windows[id].hIOCTL = NULL; return 0; } void ioctl_close(uint8_t id) { + if (cdrom_ioctl_windows[id].is_playing) return; if (cdrom_ioctl_windows[id].hIOCTL) { CloseHandle(cdrom_ioctl_windows[id].hIOCTL); @@ -1085,6 +1129,7 @@ void ioctl_close(uint8_t id) static void ioctl_exit(uint8_t id) { + cdrom_ioctl_windows[id].is_playing = 0; ioctl_stop(id); cdrom_ioctl[id].ioctl_inited=0; cdrom_ioctl[id].tocvalid=0; diff --git a/src/config.c b/src/config.c index a524e27be..4ba9517d8 100644 --- a/src/config.c +++ b/src/config.c @@ -138,7 +138,7 @@ static wchar_t cfgbuffer[1024]; static char sname[256]; static char ename[256]; -void config_load(wchar_t *fn) +int config_load(wchar_t *fn) { section_t *current_section; section_t *new_section; @@ -153,7 +153,7 @@ void config_load(wchar_t *fn) f = _wfopen(fn, L"rt, ccs=UNICODE"); #endif if (!f) - return; + return 0; current_section = malloc(sizeof(section_t)); memset(current_section, 0x00, sizeof(section_t)); @@ -230,6 +230,8 @@ void config_load(wchar_t *fn) fclose(f); config_dump(); + + return 1; } @@ -793,7 +795,7 @@ static void loadconfig_general(void) config_delete_var(cat, "vid_api"); video_fullscreen_scale = config_get_int(cat, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 1); + video_fullscreen_first = config_get_int(cat, "video_fullscreen_first", 0); force_43 = !!config_get_int(cat, "force_43", 0); scale = config_get_int(cat, "scale", 1); @@ -1570,7 +1572,12 @@ static void loadconfig_removable_devices(void) wp = config_get_wstring(cat, temps, L""); memcpy(cdrom_image[c].image_path, wp, (wcslen(wp) << 1) + 2); - if ((cdrom_drives[c].host_drive < 0x41) || ((cdrom_drives[c].host_drive == 0x200) && (wcslen(cdrom_image[c].image_path) == 0))) + if (cdrom_drives[c].host_drive < 'A') + { + cdrom_drives[c].host_drive = 0; + } + + if ((cdrom_drives[c].host_drive == 0x200) && (wcslen(cdrom_image[c].image_path) == 0)) { cdrom_drives[c].host_drive = 0; } @@ -1602,9 +1609,32 @@ static void loadconfig_removable_devices(void) void loadconfig(wchar_t *fn) { + int i = 0; + if (fn == NULL) fn = config_file_default; - config_load(fn); + i = config_load(fn); + + if (i == 0) + { + cpu = 0; +#ifndef __unix + dwLanguage = 0x0409; +#endif + scale = 1; + vid_api = 1; + enable_sync = 1; + joystick_type = 7; + strcpy(hdd_controller_name, "none"); + serial_enabled[0] = 1; + serial_enabled[1] = 1; + lpt_enabled = 1; + fdd_set_type(0, 2); + fdd_set_type(1, 2); + mem_size = 640; + + return; + } /* General */ loadconfig_general(); @@ -1692,7 +1722,7 @@ static void saveconfig_general(void) config_set_int(cat, "video_fullscreen_scale", video_fullscreen_scale); } - if (video_fullscreen_first == 1) + if (video_fullscreen_first == 0) { config_delete_var(cat, "video_fullscreen_first"); } diff --git a/src/config.h b/src/config.h index c2b08da0b..9efe0edd4 100644 --- a/src/config.h +++ b/src/config.h @@ -33,7 +33,7 @@ extern char *get_extension(char *s); extern wchar_t *get_extension_w(wchar_t *s); -extern void config_load(wchar_t *fn); +extern int config_load(wchar_t *fn); extern void config_save(wchar_t *fn); extern void config_dump(void); diff --git a/src/pc.c b/src/pc.c index dc7b3a5de..b85f401a1 100644 --- a/src/pc.c +++ b/src/pc.c @@ -435,16 +435,13 @@ void initmodules(void) for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].host_drive != 0) + if (cdrom_drives[i].host_drive == 200) { - if (cdrom_drives[i].host_drive == 200) - { - image_reset(i); - } - else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - { - ioctl_reset(i); - } + image_reset(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_reset(i); } } } @@ -547,16 +544,13 @@ void resetpchard(void) for (i = 0; i < CDROM_NUM; i++) { - if (cdrom_drives[i].host_drive != 0) + if (cdrom_drives[i].host_drive == 200) { - if (cdrom_drives[i].host_drive == 200) - { - image_reset(i); - } - else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) - { - ioctl_reset(i); - } + image_reset(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_reset(i); } } From 02a832915606ac68a5f667a02b949e666560c163 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 02:33:02 +0200 Subject: [PATCH 270/392] READ TOC command now falls back to legacy IOCTL handling when pass through reports error. --- src/cdrom.c | 7 +- src/cdrom.h | 2 +- src/cdrom_image.cc | 2 +- src/cdrom_ioctl.c | 162 +++++++++++++++++++++++++++++++++++++++++++-- src/cdrom_null.c | 2 +- 5 files changed, 166 insertions(+), 9 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index 21eba3ae0..2f02f42cd 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2421,7 +2421,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) ret = cdrom_pass_through(id, &len, cdrom[id].current_cdb, cdbufferb); if (!ret) { - return; + /* return; */ + cdrom_sense_key = cdrom_asc = cdrom_ascq = 0; + goto cdrom_readtoc_fallback; } alloc_length = cdbufferb[0]; alloc_length <<= 8; @@ -2434,6 +2436,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) } else { +cdrom_readtoc_fallback: toc_format = cdb[2] & 0xf; if (toc_format == 0) @@ -2451,7 +2454,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) cdbufferb[0] = 0; cdbufferb[1] = 0xA; break; case 2: /*Raw*/ - len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, msf, max_len); + len = cdrom_drives[id].handler->readtoc_raw(id, cdbufferb, max_len); break; default: cdrom_invalid_field(id); diff --git a/src/cdrom.h b/src/cdrom.h index 6f10756c0..871dc1f02 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -46,7 +46,7 @@ typedef struct CDROM void (*audio_stop)(uint8_t id); int (*readtoc)(uint8_t id, uint8_t *b, uint8_t starttrack, int msf, int maxlen, int single); int (*readtoc_session)(uint8_t id, uint8_t *b, int msf, int maxlen); - int (*readtoc_raw)(uint8_t id, uint8_t *b, int msf, int maxlen); + int (*readtoc_raw)(uint8_t id, uint8_t *b, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len); int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index ae4ef727c..07380e79a 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -854,7 +854,7 @@ static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxl return len; } -static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) { int track; int len = 4; diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index 5422c25b5..408f691b7 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -1036,7 +1036,7 @@ split_block_read_iterate: cdrom_ioctl_log("CD-ROM %i: ioctl_pass_through(): Expected transfer length %i is -1, this indicates an illegal mode\n", id, temp_block_length); } - cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + cdrom_ioctl_log("IOCTL DATA: %02X %02X %02X %02X %02X %02X %02X %02X\n", b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); ioctl_close(id); @@ -1045,6 +1045,160 @@ split_block_read_iterate: return ret; } +static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + int len=4; + long size; + int c,d; + uint32_t temp; + uint32_t last_block; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + ioctl_hopen(id); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC, NULL,0,&cdrom_ioctl_windows[id].toc,sizeof(cdrom_ioctl_windows[id].toc),&size,NULL); + ioctl_close(id); + cdrom_ioctl[id].tocvalid = 1; + b[2]=cdrom_ioctl_windows[id].toc.FirstTrack; + b[3]=cdrom_ioctl_windows[id].toc.LastTrack; + d=0; + for (c=0;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++) + { + if (cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber>=starttrack) + { + d=c; + break; + } + } + b[2]=cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber; + last_block = 0; + for (c=d;c<=cdrom_ioctl_windows[id].toc.LastTrack;c++) + { + uint32_t address; + if ((len+8)>maxlen) break; + b[len++]=0; /*Reserved*/ + b[len++]=(cdrom_ioctl_windows[id].toc.TrackData[c].Adr<<4)|cdrom_ioctl_windows[id].toc.TrackData[c].Control; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].TrackNumber; + b[len++]=0; /*Reserved*/ + address = MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]); + if (address > last_block) + last_block = address; + + if (msf) + { + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[0]; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[1]; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[2]; + b[len++]=cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]; + } + else + { + temp=MSFtoLBA(cdrom_ioctl_windows[id].toc.TrackData[c].Address[1],cdrom_ioctl_windows[id].toc.TrackData[c].Address[2],cdrom_ioctl_windows[id].toc.TrackData[c].Address[3]) - 150; + b[len++]=temp>>24; + b[len++]=temp>>16; + b[len++]=temp>>8; + b[len++]=temp; + } + if (single) break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + return len; +} + +static int ioctl_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + int len=4; + int size; + uint32_t temp; + CDROM_READ_TOC_EX toc_ex; + CDROM_TOC_SESSION_DATA toc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + memset(&toc_ex,0,sizeof(toc_ex)); + memset(&toc,0,sizeof(toc)); + toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_SESSION; + toc_ex.Msf=msf; + toc_ex.SessionTrack=0; + ioctl_hopen(id); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); + ioctl_close(id); + b[2]=toc.FirstCompleteSession; + b[3]=toc.LastCompleteSession; + b[len++]=0; /*Reserved*/ + b[len++]=(toc.TrackData[0].Adr<<4)|toc.TrackData[0].Control; + b[len++]=toc.TrackData[0].TrackNumber; + b[len++]=0; /*Reserved*/ + if (msf) + { + b[len++]=toc.TrackData[0].Address[0]; + b[len++]=toc.TrackData[0].Address[1]; + b[len++]=toc.TrackData[0].Address[2]; + b[len++]=toc.TrackData[0].Address[3]; + } + else + { + temp=MSFtoLBA(toc.TrackData[0].Address[1],toc.TrackData[0].Address[2],toc.TrackData[0].Address[3]) - 150; + b[len++]=temp>>24; + b[len++]=temp>>16; + b[len++]=temp>>8; + b[len++]=temp; + } + + return len; +} + +static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) +{ + int len=4; + int size; + uint32_t temp; + int i; + int BytesRead = 0; + CDROM_READ_TOC_EX toc_ex; + CDROM_TOC_FULL_TOC_DATA toc; + if (!cdrom_drives[id].host_drive) + { + return 0; + } + cdrom_ioctl[id].cd_state = CD_STOPPED; + memset(&toc_ex,0,sizeof(toc_ex)); + memset(&toc,0,sizeof(toc)); + toc_ex.Format=CDROM_READ_TOC_EX_FORMAT_FULL_TOC; + toc_ex.Msf=1; + toc_ex.SessionTrack=0; + ioctl_hopen(id); + DeviceIoControl(cdrom_ioctl_windows[id].hIOCTL,IOCTL_CDROM_READ_TOC_EX, &toc_ex,sizeof(toc_ex),&toc,sizeof(toc),(PDWORD)&size,NULL); + ioctl_close(id); + b[2]=toc.FirstCompleteSession; + b[3]=toc.LastCompleteSession; + + size -= sizeof(CDROM_TOC_FULL_TOC_DATA); + size /= sizeof(toc.Descriptors[0]); + + for (i = 0; i <= size; i++) + { + b[len++]=toc.Descriptors[i].SessionNumber; + b[len++]=(toc.Descriptors[i].Adr<<4)|toc.Descriptors[i].Control; + b[len++]=0; + b[len++]=toc.Descriptors[i].Reserved1; /*Reserved*/ + b[len++]=toc.Descriptors[i].MsfExtra[0]; + b[len++]=toc.Descriptors[i].MsfExtra[1]; + b[len++]=toc.Descriptors[i].MsfExtra[2]; + b[len++]=toc.Descriptors[i].Zero; + b[len++]=toc.Descriptors[i].Msf[0]; + b[len++]=toc.Descriptors[i].Msf[1]; + b[len++]=toc.Descriptors[i].Msf[2]; + } + + return len; +} + static uint32_t ioctl_size(uint8_t id) { uint8_t capacity_buffer[8]; @@ -1142,9 +1296,9 @@ static CDROM ioctl_cdrom= ioctl_media_type_id, ioctl_audio_callback, ioctl_audio_stop, - NULL, - NULL, - NULL, + ioctl_readtoc, + ioctl_readtoc_session, + ioctl_readtoc_raw, ioctl_getcurrentsubchannel, ioctl_pass_through, NULL, diff --git a/src/cdrom_null.c b/src/cdrom_null.c index a2383b626..c9d759bba 100644 --- a/src/cdrom_null.c +++ b/src/cdrom_null.c @@ -63,7 +63,7 @@ static int null_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxle return 0; } -static int null_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +static int null_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) { return 0; } From 84f53bc3d0a2c28ccb1207f6a3fb5dfb7440957f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 17:52:39 +0200 Subject: [PATCH 271/392] Added the monochrome monitor constrast change option, patch from basic2004. --- src/VIDEO/vid_cga.c | 4 - src/VIDEO/vid_ega.c | 235 +++++------------------------------------- src/VIDEO/video.c | 1 + src/VIDEO/video.h | 1 + src/WIN/86Box.rc | 4 +- src/WIN/resource.h | 1 + src/WIN/win.c | 10 ++ src/WIN/win_d3d_fs.cc | 29 ++++-- src/config.c | 15 ++- 9 files changed, 76 insertions(+), 224 deletions(-) diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index 7b3332f3f..2bb16be22 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -77,10 +77,6 @@ void cga_out(uint16_t addr, uint8_t val, void *p) if ((cga->cgamode ^ val) & 1) { cga_palette = (cga->rgb_type << 1); - if (!(val & 1) && (cga_palette > 0) && (cga_palette < 8)) - { - cga_palette--; - } cgapal_rebuild(); } #endif diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index f0db448b6..55f46f17e 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA, Chips & Technologies SuperEGA, and * AX JEGA graphics cards. * - * Version: @(#)vid_ega.c 1.0.0 2017/05/30 + * Version: @(#)vid_ega.c 1.0.1 2017/06/01 * * Author: Sarah Walker, * Miran Grca, @@ -29,6 +29,7 @@ #include "../device.h" #include "video.h" #include "vid_ega.h" +#include "vid_ega_render.h" extern uint8_t edatlookup[4][4]; @@ -495,28 +496,10 @@ void ega_recalctimings(ega_t *ega) ega->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT)); } -int ega_display_line(ega_t *ega) -{ - int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; - unsigned int dl = ega->displine; - if (ega->crtc[9] & 0x1f) - { - dl -= (ega->crtc[8] & 0x1f); - } - dl += y_add; - dl &= 0x7ff; - return dl; -} - void ega_poll(void *p) { ega_t *ega = (ega_t *)p; - uint8_t chr, dat, attr; - uint32_t charaddr; - int x, xx; - uint32_t fg, bg; - int offset; - uint8_t edat[4]; + int x; int drawcursor = 0; int y_add = enable_overscan ? (overscan_y >> 1) : 0; int x_add = enable_overscan ? 8 : 0; @@ -524,7 +507,6 @@ void ega_poll(void *p) int x_add_ex = enable_overscan ? 16 : 0; uint32_t *q, i, j; int wx = 640, wy = 350; - int dl = ega_display_line(ega); if (!ega->linepos) { @@ -543,204 +525,36 @@ void ega_poll(void *p) if (ega->scrblank) { - for (x = 0; x < ega->hdisp; x++) - { - switch (ega->seqregs[1] & 9) - { - case 0: - for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = 0; - break; - case 1: - for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = 0; - break; - case 8: - for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = 0; - break; - case 9: - for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = 0; - break; - } - } + ega_render_blank(ega); } else if (!(ega->gdcreg[6] & 1)) { - if (fullchange) - { - for (x = 0; x < ega->hdisp; x++) - { - drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); - chr = ega->vram[(ega->ma << 1) & ega->vrammask]; - attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - - if (attr & 8) charaddr = ega->charsetb + (chr * 128); - else charaddr = ega->charseta + (chr * 128); - - if (drawcursor) - { - bg = ega->pallook[ega->egapal[attr & 15]]; - fg = ega->pallook[ega->egapal[attr >> 4]]; - } - else - { - fg = ega->pallook[ega->egapal[attr & 15]]; - bg = ega->pallook[ega->egapal[attr >> 4]]; - if (attr & 0x80 && ega->attrregs[0x10] & 8) - { - bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; - if (ega->blink & 16) - fg = bg; - } - } - - dat = ega->vram[charaddr + (ega->sc << 2)]; - if (ega->seqregs[1] & 8) - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = - ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - else - { - if (ega->seqregs[1] & 1) - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - } - else - { - for (xx = 0; xx < 8; xx++) - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; - if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; - else - ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; - } - } - ega->ma += 4; - ega->ma &= ega->vrammask; - } - } + ega_render_text_standard(ega, drawcursor); } else { switch (ega->gdcreg[5] & 0x20) { case 0x00: - if (ega->seqregs[1] & 8) - { - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; - - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } - else - { - offset = (8 - ega->scrollcache) + 24; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[ega->ma | 0x8000]; - edat[1] = ega->vram[ega->ma | 0x8001]; - edat[2] = ega->vram[ega->ma | 0x8002]; - edat[3] = ega->vram[ega->ma | 0x8003]; - } - else - { - edat[0] = ega->vram[ega->ma]; - edat[1] = ega->vram[ega->ma | 0x1]; - edat[2] = ega->vram[ega->ma | 0x2]; - edat[3] = ega->vram[ega->ma | 0x3]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; - - dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); - ((uint32_t *)buffer32->line[dl])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; - ((uint32_t *)buffer32->line[dl])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; - } - } - break; + if (ega->seqregs[1] & 8) + { + ega_render_4bpp_lowres(ega); + } + else + { + ega_render_4bpp_highres(ega); + } + break; case 0x20: - offset = ((8 - ega->scrollcache) << 1) + 16; - for (x = 0; x <= ega->hdisp; x++) - { - if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) - { - edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; - edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; - } - else - { - edat[0] = ega->vram[(ega->ma << 1)]; - edat[1] = ega->vram[(ega->ma << 1) + 1]; - } - ega->ma += 4; - ega->ma &= ega->vrammask; - - ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; - ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; - } - break; + if (ega->seqregs[1] & 8) + { + ega_render_2bpp_lowres(ega); + } + else + { + ega_render_2bpp_highres(ega); + } + break; } } if (ega->lastline < ega->displine) @@ -903,7 +717,8 @@ void ega_poll(void *p) else { if (ega->crtc[9] & 0x80) - ega->video_res_y /= 2; if (!(ega->crtc[0x17] & 1)) + ega->video_res_y /= 2; + if (!(ega->crtc[0x17] & 1)) ega->video_res_y *= 2; ega->video_res_y /= (ega->crtc[9] & 31) + 1; if (ega->seqregs[1] & 8) diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index b195cdb5c..ae9e56048 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -59,6 +59,7 @@ #include "vid_wy700.h" +int vid_cga_contrast = 0; int cga_palette = 0; typedef struct diff --git a/src/VIDEO/video.h b/src/VIDEO/video.h index b1bff117c..f9b7fef85 100644 --- a/src/VIDEO/video.h +++ b/src/VIDEO/video.h @@ -111,6 +111,7 @@ void ddraw_fs_take_screenshot(wchar_t *fn); #endif extern int cga_palette; +extern int vid_cga_contrast; void loadfont(wchar_t *s, int format); void initvideo(); diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index dd7c91c85..380d8a423 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -90,10 +90,12 @@ BEGIN MENUITEM "&Square pixels", IDM_VID_FS_SQ MENUITEM "&Integer scale", IDM_VID_FS_INT END - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT MENUITEM SEPARATOR + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON + MENUITEM SEPARATOR MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 17792a1e1..8541c17e1 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -317,6 +317,7 @@ #define IDM_VID_FLASH 40077 #define IDM_VID_SCREENSHOT 40078 #define IDM_VID_INVERT 40079 +#define IDM_VID_CGACON 40080 #define IDM_IDE_TER_ENABLED 44000 #define IDM_IDE_TER_IRQ9 44009 diff --git a/src/WIN/win.c b/src/WIN/win.c index 7d742beb3..fe7e8fcd9 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -50,6 +50,7 @@ #include "plat_midi.h" #include "win.h" +#include "win_cgapal.h" #include "win_ddraw.h" #include "win_d3d.h" #include "win_language.h" @@ -1512,6 +1513,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz CheckMenuItem(menu, IDM_VID_REMEMBER, window_remember ? MF_CHECKED : MF_UNCHECKED); CheckMenuItem(menu, IDM_VID_SCALE_1X + scale, MF_CHECKED); + CheckMenuItem(menu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); + d=romset; for (c=0;c 1) && (cga_palette < 8)) { - for (c = 0; c < 16; c++) + if (vid_cga_contrast != 0) { - pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); - } - } + for (c = 0; c < 16; c++) + { + pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 2][c].r], video_6to8[cgapal_mono[cga_palette - 2][c].g], video_6to8[cgapal_mono[cga_palette - 2][c].b]); + } + } + else + { + for (c = 0; c < 16; c++) + { + pal_lookup[c] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 16] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 32] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + pal_lookup[c + 48] = makecol(video_6to8[cgapal_mono[cga_palette - 1][c].r], video_6to8[cgapal_mono[cga_palette - 1][c].g], video_6to8[cgapal_mono[cga_palette - 1][c].b]); + } + } + } + if (cga_palette == 8) { pal_lookup[0x16] = makecol(video_6to8[42], video_6to8[42], video_6to8[0]); } } - int d3d_fs_init(HWND h) { diff --git a/src/config.c b/src/config.c index 4ba9517d8..c325c3a5d 100644 --- a/src/config.c +++ b/src/config.c @@ -804,6 +804,8 @@ static void loadconfig_general(void) scale = 3; } enable_overscan = !!config_get_int(cat, "enable_overscan", 0); + vid_cga_contrast = !!config_get_int(cat, "vid_cga_contrast", 0); + window_remember = config_get_int(cat, "window_remember", 0); @@ -1758,9 +1760,20 @@ static void saveconfig_general(void) config_set_int(cat, "enable_overscan", enable_overscan); } - config_set_int(cat, "window_remember", window_remember); + if (vid_cga_contrast == 0) + { + config_delete_var(cat, "vid_cga_contrast"); + } + else + { + config_set_int(cat, "vid_cga_contrast", vid_cga_contrast); + } + + if (window_remember) { + config_set_int(cat, "window_remember", window_remember); + sprintf(temps, "%i, %i, %i, %i", window_w, window_h, window_x, window_y); config_set_string(cat, "window_coordinates", temps); } From 7d79ee6349647ed16f7371435bb3713acb9a83df Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 17:55:38 +0200 Subject: [PATCH 272/392] Committed the missing files and updated the makefile. --- src/Makefile.mingw | 3 +- src/VIDEO/vid_ega_render.c | 308 +++++++++++++++++++++++++++++++++++++ src/VIDEO/vid_ega_render.h | 37 +++++ 3 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 src/VIDEO/vid_ega_render.c create mode 100644 src/VIDEO/vid_ega_render.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d443739c1..e77c1af04 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -170,7 +170,8 @@ SNDOBJ = sound.o \ snd_sn76489.o snd_ssi2001.o snd_wss.o \ snd_ym7128.o VIDOBJ = video.o \ - vid_cga.o vid_cga_comp.o vid_mda.o vid_ega.o \ + vid_cga.o vid_cga_comp.o vid_mda.o \ + vid_ega.o vid_ega_render.o \ vid_vga.o vid_svga.o vid_svga_render.o \ vid_hercules.o vid_herculesplus.o vid_incolor.o \ vid_colorplus.o \ diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c new file mode 100644 index 000000000..de8aa85ab --- /dev/null +++ b/src/VIDEO/vid_ega_render.c @@ -0,0 +1,308 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * EGA renderers. + * + * Version: @(#)vid_ega_render.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + +#include +#include "../ibm.h" +#include "../device.h" +#include "../mem.h" +#include "../rom.h" +#include "video.h" +#include "vid_ega.h" +#include "vid_ega_render.h" + + +int invert_display = 0; + + +int ega_display_line(ega_t *ega) +{ + int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; + unsigned int dl = ega->displine; + if (ega->crtc[9] & 0x1f) + { + dl -= (ega->crtc[8] & 0x1f); + } + dl += y_add; + dl &= 0x7ff; + return dl; +} + +void ega_render_blank(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + int x, xx; + + for (x = 0; x < ega->hdisp; x++) + { + switch (ega->seqregs[1] & 9) + { + case 0: + for (xx = 0; xx < 9; xx++) ((uint32_t *)buffer32->line[dl])[(x * 9) + xx + 32 + x_add] = 0; + break; + case 1: + for (xx = 0; xx < 8; xx++) ((uint32_t *)buffer32->line[dl])[(x * 8) + xx + 32 + x_add] = 0; + break; + case 8: + for (xx = 0; xx < 18; xx++) ((uint32_t *)buffer32->line[dl])[(x * 18) + xx + 32 + x_add] = 0; + break; + case 9: + for (xx = 0; xx < 16; xx++) ((uint32_t *)buffer32->line[dl])[(x * 16) + xx + 32 + x_add] = 0; + break; + } + } +} + +void ega_render_text_standard(ega_t *ega, int drawcursor) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t chr, dat, attr; + uint32_t charaddr; + int x, xx; + uint32_t fg, bg; + + if (fullchange) + { + for (x = 0; x < ega->hdisp; x++) + { + drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + + if (attr & 8) charaddr = ega->charsetb + (chr * 128); + else charaddr = ega->charseta + (chr * 128); + + if (drawcursor) + { + bg = ega->pallook[ega->egapal[attr & 15]]; + fg = ega->pallook[ega->egapal[attr >> 4]]; + } + else + { + fg = ega->pallook[ega->egapal[attr & 15]]; + bg = ega->pallook[ega->egapal[attr >> 4]]; + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + bg = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + if (ega->blink & 16) + fg = bg; + } + } + + dat = ega->vram[charaddr + (ega->sc << 2)]; + if (ega->seqregs[1] & 8) + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x << 4) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x << 4) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + (xx << 1)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 33 + (xx << 1)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = bg; + else + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 16) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * 18) + 32 + 17) & 2047) + x_add] = (dat & 1) ? fg : bg; + } + } + else + { + if (ega->seqregs[1] & 1) + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x << 3) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = 0; xx < 8; xx++) + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + xx) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4)) + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = bg; + else + ((uint32_t *)buffer32->line[dl])[(((x * 9) + 32 + 8) & 2047) + x_add] = (dat & 1) ? fg : bg; + } + } + ega->ma += 4; + ega->ma &= ega->vrammask; + } + } +} + +void ega_render_2bpp_lowres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + int x; + int offset; + uint8_t edat[4]; + + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; + edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; + } + else + { + edat[0] = ega->vram[(ega->ma << 1)]; + edat[1] = ega->vram[(ega->ma << 1) + 1]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + + ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add]= ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } +} + +void ega_render_2bpp_highres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + int x; + int offset; + uint8_t edat[4]; + + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[(ega->ma << 1) + 0x8000]; + edat[1] = ega->vram[(ega->ma << 1) + 0x8001]; + } + else + { + edat[0] = ega->vram[(ega->ma << 1)]; + edat[1] = ega->vram[(ega->ma << 1) + 1]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + + ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[edat[1] & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ega->pallook[ega->egapal[(edat[1] >> 6) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 0) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 2) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 4) & 3]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ega->pallook[ega->egapal[(edat[0] >> 6) & 3]]; + } +} + +void ega_render_4bpp_lowres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t dat; + int x; + int offset; + uint8_t edat[4]; + + offset = ((8 - ega->scrollcache) << 1) + 16; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; + } + else + { + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 14 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 15 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 12 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 13 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 10 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 11 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 8 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 9 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 6 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + 4 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 4) + 2 + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 4) + offset + x_add] = ((uint32_t *)buffer32->line[dl])[(x << 4) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } +} + +void ega_render_4bpp_highres(ega_t *ega) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t dat; + int x; + int offset; + uint8_t edat[4]; + + offset = (8 - ega->scrollcache) + 24; + for (x = 0; x <= ega->hdisp; x++) + { + if (ega->sc & 1 && !(ega->crtc[0x17] & 1)) + { + edat[0] = ega->vram[ega->ma | 0x8000]; + edat[1] = ega->vram[ega->ma | 0x8001]; + edat[2] = ega->vram[ega->ma | 0x8002]; + edat[3] = ega->vram[ega->ma | 0x8003]; + } + else + { + edat[0] = ega->vram[ega->ma]; + edat[1] = ega->vram[ega->ma | 0x1]; + edat[2] = ega->vram[ega->ma | 0x2]; + edat[3] = ega->vram[ega->ma | 0x3]; + } + ega->ma += 4; + ega->ma &= ega->vrammask; + + dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 7 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 6 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 5 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 4 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 3 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + 2 + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2); + ((uint32_t *)buffer32->line[dl])[(x << 3) + 1 + offset + x_add] = ega->pallook[ega->egapal[(dat & 0xf) & ega->attrregs[0x12]]]; + ((uint32_t *)buffer32->line[dl])[(x << 3) + offset + x_add] = ega->pallook[ega->egapal[(dat >> 4) & ega->attrregs[0x12]]]; + } +} diff --git a/src/VIDEO/vid_ega_render.h b/src/VIDEO/vid_ega_render.h new file mode 100644 index 000000000..0f7805751 --- /dev/null +++ b/src/VIDEO/vid_ega_render.h @@ -0,0 +1,37 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * EGA renderers. + * + * Version: @(#)vid_ega_render.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + +extern int firstline_draw, lastline_draw; +extern int displine; +extern int sc; + +extern uint32_t ma, ca; +extern int con, cursoron, cgablink; + +extern int scrollcache; + +extern uint8_t edatlookup[4][4]; + +void ega_render_blank(ega_t *ega); +void ega_render_text_standard(ega_t *ega, int drawcursor); +void ega_render_text_jega(ega_t *ega); + +void ega_render_2bpp_lowres(ega_t *ega); +void ega_render_2bpp_highres(ega_t *ega); +void ega_render_4bpp_lowres(ega_t *ega); +void ega_render_4bpp_highres(ega_t *ega); From d8e66ad82979c9441c8933b3e0a66bcf3147012b Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 18:45:47 +0200 Subject: [PATCH 273/392] Reverted the mainline PCEM CPU flat segment speedup commit - it's still buggy (Duke Nukem 3D and Little Big Adventure 2 like crashing), I'll recommit it when Sarah Walker fixes the bugs. --- src/CPU/386.c | 9 -- src/CPU/386_common.h | 21 +-- src/CPU/386_dynarec.c | 44 +----- src/CPU/386_ops.h | 23 +-- src/CPU/808x.c | 23 +-- src/CPU/codegen.h | 22 +-- src/CPU/codegen_ops_x86-64.h | 217 +++++---------------------- src/CPU/codegen_ops_x86.h | 283 +++++++---------------------------- src/CPU/codegen_x86-64.c | 4 +- src/CPU/codegen_x86.c | 3 +- src/CPU/cpu.c | 33 ++-- src/CPU/cpu.h | 24 +-- src/CPU/x86_ops_misc.h | 47 ------ src/CPU/x86seg.c | 125 ++++------------ src/CPU/x86seg.h | 19 +-- src/CPU/x87_ops.h | 20 --- src/CPU/x87_ops_loadstore.h | 18 --- src/ibm.h | 8 - 18 files changed, 163 insertions(+), 780 deletions(-) diff --git a/src/CPU/386.c b/src/CPU/386.c index 074fa9696..6bd69af85 100644 --- a/src/CPU/386.c +++ b/src/CPU/386.c @@ -28,13 +28,6 @@ uint32_t oldpc2; int trap; -uint16_t flags,eflags; -uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; - -x86seg gdt,ldt,idt,tr; -x86seg _cs,_ds,_es,_ss,_fs,_gs; -x86seg _oldds; - extern int cpl_override; @@ -47,8 +40,6 @@ uint16_t ea_rseg; int is486; int cgate32; -uint32_t cr2, cr3, cr4; -uint32_t dr[8]; uint8_t romext[32768]; diff --git a/src/CPU/386_common.h b/src/CPU/386_common.h index 6042cc151..a091a817d 100644 --- a/src/CPU/386_common.h +++ b/src/CPU/386_common.h @@ -1,21 +1,6 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Common 386 CPU code. - * - * Version: @(#)386_common.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ extern uint16_t ea_rseg; #undef readmemb diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 61db68737..1463f844e 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -21,8 +21,6 @@ #define CPU_BLOCK_END() cpu_block_end = 1 -uint32_t cpu_cur_status = 0; - int cpu_reps, cpu_reps_latched; int cpu_notreps, cpu_notreps_latched; @@ -1327,42 +1325,8 @@ void exec386_dynarec(int cycs) while (cycles_main > 0) { int cycles_start; - -#if 0 - switch(cpu_pci_speed) - { - case 16000000: - cycles += 640; - break; - case 20000000: - cycles += 800; - break; - case 25000000: - default: - cycles += 1000; - break; - case 27500000: - cycles += 1100; - break; - case 30000000: - cycles += 1200; - break; - case 333333333: - cycles += 1333; - break; - case 37500000: - cycles += 1500; - break; - case 40000000: - cycles += 1600; - break; - case 41666667: - cycles += 1666; - break; - } -#endif - cycles += cpu_cycle_period(); - + + cycles += cpu_cycle_period(); cycles_start = cycles; timer_start_period(cycles << TIMER_SHIFT); @@ -1441,7 +1405,7 @@ void exec386_dynarec(int cycs) and physical address. The physical address check will also catch any page faults at this stage*/ valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->phys == phys_addr) && (block->status == cpu_cur_status); + (block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32); if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); @@ -1453,7 +1417,7 @@ void exec386_dynarec(int cycs) if (new_block) { valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->phys == phys_addr) && (new_block->status == cpu_cur_status); + (new_block->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32); if (valid_block) block = new_block; } diff --git a/src/CPU/386_ops.h b/src/CPU/386_ops.h index 0217c384d..4e5d78125 100644 --- a/src/CPU/386_ops.h +++ b/src/CPU/386_ops.h @@ -1,23 +1,6 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * 286/386+ instruction handlers list. - * - * Version: @(#)386_ops.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * leilei, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 leilei. - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Sarah Walker, Tenshi, leilei + see COPYING for more details +*/ #include "x86_ops.h" diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 32a52e955..5c48a4bb0 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -1,21 +1,6 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * 808x CPU emulation. - * - * Version: @(#)808x.c 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Sarah Walker, Tenshi + see COPYING for more details +*/ /*SHR AX,1 4 clocks - fetch opcode @@ -567,7 +552,6 @@ void resetx86() resets++; ins = 0; use32=0; - cpu_cur_status = 0; stack32=0; cpu_state.pc=0; msw=0; @@ -605,7 +589,6 @@ void softresetx86() { use32=0; stack32=0; - cpu_cur_status = 0; cpu_state.pc=0; msw=0; cr0=0; diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index 5a076db8f..ad0b3f63a 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -35,9 +35,6 @@ typedef struct codeblock_t { - uint64_t page_mask, page_mask2; - uint64_t cmp; - /*Previous and next pointers, for the codeblock list associated with each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ @@ -48,19 +45,22 @@ typedef struct codeblock_t fails.*/ struct codeblock_t *parent, *left, *right; - int pnt; - int ins; - - int was_recompiled; - int TOP; - uint32_t pc; uint32_t _cs; uint32_t endpc; uint32_t phys, phys_2; - uint32_t status; + uint32_t use32; + int stack32; + int pnt; + int ins; + uint64_t page_mask, page_mask2; + + int was_recompiled; uint32_t flags; - + int TOP; + + uint64_t cmp; + uint8_t data[2048]; } codeblock_t; diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index c27b0f37e..8573ab495 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -866,10 +866,6 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) - return; - if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) - return; if (IS_32_ADDR(&seg->base)) { @@ -904,10 +900,6 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) - return; - if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) - return; if (IS_32_ADDR(&seg->base)) { @@ -934,11 +926,6 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) - return; - if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) - return; - if (IS_32_ADDR(&seg->base)) { addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ @@ -975,13 +962,7 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1049,13 +1030,7 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1139,13 +1114,7 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1221,13 +1190,7 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1346,13 +1309,7 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1431,13 +1388,7 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1527,13 +1478,7 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1621,13 +1566,7 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5313,13 +5252,7 @@ static void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5366,16 +5299,12 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); if (IS_32_ADDR(writelookup2)) { addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ @@ -5399,9 +5328,7 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0); // addbyte(0xc3); /*RET*/ - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; + *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); @@ -5446,13 +5373,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5495,23 +5416,15 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); addbyte(0x8d); /*LEA ESI, 1[EDI]*/ addbyte(0x77); addbyte(0x01); - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5562,9 +5475,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5599,13 +5510,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5648,23 +5553,15 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - } + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); addbyte(0x8d); /*LEA ESI, 3[EDI]*/ addbyte(0x77); addbyte(0x03); - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); - } + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5715,9 +5612,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - if (!((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) && - !((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5747,13 +5642,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5820,13 +5709,7 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5902,13 +5785,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ECX, ECX*/ - addbyte(0xc9); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -6006,13 +5883,7 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -6084,13 +5955,7 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -6173,13 +6038,7 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EBX, EBX*/ - addbyte(0xdb); - } - else if (IS_32_ADDR(&seg->base)) + if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h index 229c066ca..c8c18a28c 100644 --- a/src/CPU/codegen_ops_x86.h +++ b/src/CPU/codegen_ops_x86.h @@ -616,10 +616,6 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) - return; - if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) - return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -641,10 +637,6 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; - if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) - return; - if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) - return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -658,11 +650,6 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { - if ((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) - return; - if ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS)) - return; - addbyte(0x3b); /*CMP EAX, seg->limit_low*/ addbyte(0x05); addlong((uint32_t)&seg->limit_low); @@ -688,18 +675,9 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -707,18 +685,9 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -728,18 +697,9 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -747,18 +707,9 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); @@ -769,18 +720,9 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -790,18 +732,9 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -810,18 +743,9 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -832,18 +756,9 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR EDX, EDX*/ - addbyte(0xd2); - } - else - { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -871,18 +786,9 @@ static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -893,18 +799,9 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -915,18 +812,9 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -937,18 +825,9 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -959,18 +838,9 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -981,18 +851,9 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -1013,18 +874,9 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x89); /*MOV ECX, host_reg2*/ addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); } - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } @@ -3940,18 +3792,9 @@ static void LOAD_EA() static void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_check_write*/ addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3959,18 +3802,9 @@ static void MEM_CHECK_WRITE(x86seg *seg) static void MEM_CHECK_WRITE_W(x86seg *seg) { CHECK_SEG_WRITE(seg); - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_check_write_w*/ addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3978,18 +3812,9 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) static void MEM_CHECK_WRITE_L(x86seg *seg) { CHECK_SEG_WRITE(seg); - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) - { - addbyte(0x31); /*XOR ESI, ESI*/ - addbyte(0xf6); - } - else - { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); - } + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); addbyte(0xe8); /*CALL mem_check_write_l*/ addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index 9f42b07dd..e591adc95 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -274,13 +274,13 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; + block->use32 = use32; + block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = 0; - block->status = cpu_cur_status; - block->was_recompiled = 0; recomp_page = block->phys & ~0xfff; diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index 01015ce87..a42b32104 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1401,11 +1401,12 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; + block->use32 = use32; + block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; block->was_recompiled = 0; diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index cbb7161fb..453e8626a 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -1,23 +1,6 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * CPU type handler. - * - * Version: @(#)cpu.c 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * leilei, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 leilei. - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Sarah Walker, Tenshi, leilei + see COPYING for more details +*/ #include "../ibm.h" #include "cpu.h" #include "../model.h" @@ -92,15 +75,12 @@ int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; -int hasfpu; - uint64_t cpu_CR4_mask; int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; int cpu_prefetch_cycles, cpu_prefetch_width; int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; -int cpu_pci_speed; int is286, is386; int israpidcad, is_pentium; @@ -425,7 +405,7 @@ CPU cpus_Cx486[] = {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7}, {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9}, {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, + {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, {"", -1, 0, 0, 0} }; @@ -637,6 +617,11 @@ void cpu_set() if (enable_external_fpu) { hasfpu = 1; + if (cpu_s->cpu_type == CPU_i486SX) + { + /* The 487SX is a full implementation of the 486DX and takes over the entire CPU's operation. */ + cpu_s->cpu_type = CPU_i486DX; + } } } diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index ce0955b7f..cbf7b7516 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -1,23 +1,6 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * CPU type handler. - * - * Version: @(#)cpu.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * leilei, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 leilei. - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Sarah Walker, Tenshi, leilei + see COPYING for more details +*/ #ifndef _CPU_H_ #define _CPU_H_ @@ -155,7 +138,6 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ extern int cpu_prefetch_cycles, cpu_prefetch_width; extern int cpu_waitstates; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; -extern int cpu_pci_speed; extern uint64_t tsc; diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h index 7734217eb..a2b4f6f31 100644 --- a/src/CPU/x86_ops_misc.h +++ b/src/CPU/x86_ops_misc.h @@ -1,21 +1,3 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Miscellaneous x86 CPU Instructions. - * - * Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - static int opCBW(uint32_t fetchdat) { AH = (AL & 0x80) ? 0xff : 0; @@ -773,17 +755,9 @@ static int opLOADALL(uint32_t fetchdat) ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); _ss.access = readmemb(0, 0x845); _ss.limit = readmemw(0, 0x846); - if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; - else - cpu_cur_status &= ~CPU_STATUS_FLATSS; ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); _ds.access = readmemb(0, 0x84B); _ds.limit = readmemw(0, 0x84C); - if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; - else - cpu_cur_status &= ~CPU_STATUS_FLATDS; gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); gdt.limit = readmemw(0, 0x852); ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); @@ -823,29 +797,8 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0; if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0; - cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); - if (use32) - cpu_cur_status |= CPU_STATUS_USE32; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; set_segment_limit(s, segdat3); - - if (s == &_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - - cpu_cur_status |= CPU_STATUS_FLATDS; - else - cpu_cur_status &= ~CPU_STATUS_FLATDS; - } - if (s == &_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; - else - cpu_cur_status &= ~CPU_STATUS_FLATSS; - } } static int opLOADALL386(uint32_t fetchdat) diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index 4f43d8dc8..cc0cc6dbc 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -1,21 +1,6 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x86 CPU segment emulation. - * - * Version: @(#)x86seg.c 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Sarah Walker, SA1988 + see COPYING for more details +*/ #include #include #include @@ -174,29 +159,6 @@ void x86np(char *s, uint16_t error) } -static void set_stack32(int s) -{ - stack32 = s; - if (stack32) - cpu_cur_status |= CPU_STATUS_STACK32; - else - cpu_cur_status &= ~CPU_STATUS_STACK32; -} - -static void set_use32(int u) -{ - if (u) - { - use32 = 0x300; - cpu_cur_status |= CPU_STATUS_USE32; - } - else - { - use32 = 0; - cpu_cur_status &= ~CPU_STATUS_USE32; - } -} - void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); @@ -217,21 +179,6 @@ void do_seg_load(x86seg *s, uint16_t *segdat) s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; s->limit_low = s->limit + 1; } - - if (s == &_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; - else - cpu_cur_status &= ~CPU_STATUS_FLATDS; - } - if (s == &_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; - else - cpu_cur_status &= ~CPU_STATUS_FLATSS; - } } static void do_seg_v86_init(x86seg *s) @@ -304,8 +251,6 @@ void loadseg(uint16_t seg, x86seg *s) s->seg=0; s->access = 0x80; s->base=-1; - if (s == &_ds) - cpu_cur_status &= ~CPU_STATUS_FLATDS; return; } addr=seg&~7; @@ -358,7 +303,7 @@ void loadseg(uint16_t seg, x86seg *s) x86ss(NULL,seg&~3); return; } - set_stack32((segdat[3] & 0x40) ? 1 : 0); + stack32 = (segdat[3] & 0x40) ? 1 : 0; } else if (s!=&_cs) { @@ -414,22 +359,6 @@ void loadseg(uint16_t seg, x86seg *s) stack32 = 0; s->checked = 1; } - - if (s == &_ds) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATDS; - else - - cpu_cur_status &= ~CPU_STATUS_FLATDS; - } - if (s == &_ss) - { - if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) - cpu_cur_status |= CPU_STATUS_FLATSS; - else - cpu_cur_status &= ~CPU_STATUS_FLATSS; - } } #define DPL ((segdat[2]>>13)&3) @@ -497,7 +426,8 @@ void loadcs(uint16_t seg) x86np("Load CS not present", seg & 0xfffc); return; } - set_use32(segdat[3] & 0x40); + if (segdat[3]&0x40) use32=0x300; + else use32=0; CS=(seg&~3)|CPL; do_seg_load(&_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; @@ -600,7 +530,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) x86np("Load CS JMP not present\n", seg & 0xfffc); return; } - set_use32(segdat[3]&0x40); + if (segdat[3]&0x40) use32=0x300; + else use32=0; #ifdef CS_ACCESSED cpl_override = 1; @@ -613,6 +544,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + use32=(segdat[3]&0x40)?0x300:0; cycles -= timing_jmp_pm; } else /*System segment*/ @@ -710,8 +642,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; + use32=(segdat[3]&0x40)?0x300:0; + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -896,7 +828,8 @@ void loadcscall(uint16_t seg) x86np("Load CS call not present", seg & 0xfffc); return; } - set_use32(segdat[3]&0x40); + if (segdat[3]&0x40) use32=0x300; + else use32=0; #ifdef CS_ACCESSED cpl_override = 1; @@ -915,6 +848,7 @@ void loadcscall(uint16_t seg) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + use32=(segdat[3]&0x40)?0x300:0; if (csout) pclog("Complete\n"); cycles -= timing_call_pm; } @@ -1071,7 +1005,7 @@ void loadcscall(uint16_t seg) } if (!stack32) oldsp &= 0xFFFF; SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); + stack32 = (segdat2[3] & 0x40) ? 1 : 0; if (stack32) ESP=newsp; else SP=newsp; @@ -1088,7 +1022,7 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); + use32=(segdat[3]&0x40)?0x300:0; cpu_state.pc=newpc; if (output) pclog("Set access 2\n"); @@ -1167,8 +1101,8 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); - cpu_state.pc=newpc; + use32=(segdat[3]&0x40)?0x300:0; + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -1311,8 +1245,8 @@ void pmoderetf(int is32, uint16_t off) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3] & 0x40); - + use32=(segdat[3]&0x40)?0x300:0; + cycles -= timing_retf_pm; } else @@ -1419,7 +1353,7 @@ void pmoderetf(int is32, uint16_t off) return; } SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); + stack32 = (segdat2[3] & 0x40) ? 1 : 0; if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -1441,7 +1375,7 @@ void pmoderetf(int is32, uint16_t off) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3] & 0x40); + use32=(segdat[3]&0x40)?0x300:0; if (stack32) ESP+=off; else SP+=off; @@ -1636,7 +1570,7 @@ void pmodeint(int num, int soft) return; } SS=newss; - set_stack32((segdat3[3] & 0x40) ? 1 : 0); + stack32 = (segdat3[3] & 0x40) ? 1 : 0; if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat3); @@ -1721,7 +1655,7 @@ void pmodeint(int num, int soft) if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; - set_use32(segdat2[3]&0x40); + use32=(segdat2[3]&0x40)?0x300:0; #ifdef CS_ACCESSED cpl_override = 1; @@ -1875,7 +1809,6 @@ void pmodeiret(int is32) do_seg_v86_init(&_es); loadseg(segs[1],&_ds); do_seg_v86_init(&_ds); - cpu_cur_status &= ~CPU_STATUS_FLATDS; loadseg(segs[2],&_fs); do_seg_v86_init(&_fs); loadseg(segs[3],&_gs); @@ -1893,9 +1826,7 @@ void pmodeiret(int is32) ESP=newsp; loadseg(newss,&_ss); do_seg_v86_init(&_ss); - cpu_cur_status &= ~CPU_STATUS_FLATSS; use32=0; - cpu_cur_status &= ~CPU_STATUS_USE32; flags=(tempflags&0xFFD5)|2; cycles -= timing_iret_v86; return; @@ -1982,7 +1913,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3]&0x40); + use32=(segdat[3]&0x40)?0x300:0; #ifdef CS_ACCESSED cpl_override = 1; @@ -2065,7 +1996,7 @@ void pmodeiret(int is32) return; } SS=newss; - set_stack32((segdat2[3] & 0x40) ? 1 : 0); + stack32 = (segdat2[3] & 0x40) ? 1 : 0; if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -2087,7 +2018,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat[3] & 0x40); + use32=(segdat[3]&0x40)?0x300:0; check_seg_valid(&_ds); check_seg_valid(&_es); @@ -2277,7 +2208,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - set_use32(segdat2[3] & 0x40); + use32=(segdat2[3]&0x40)?0x300:0; EAX=new_eax; ECX=new_ecx; diff --git a/src/CPU/x86seg.h b/src/CPU/x86seg.h index f4badadf4..4a36f360b 100644 --- a/src/CPU/x86seg.h +++ b/src/CPU/x86seg.h @@ -1,17 +1,4 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x86 CPU segment emulation. - * - * Version: @(#)x86seg.h 1.0.0 2017/05/30 - * - * Author: Miran Grca, - * Copyright 2016-2017 Miran Grca. - */ - +/* Copyright holders: Tenshi + see COPYING for more details +*/ void do_seg_load(x86seg *s, uint16_t *segdat); diff --git a/src/CPU/x87_ops.h b/src/CPU/x87_ops.h index b9320081f..e212c6ccb 100644 --- a/src/CPU/x87_ops.h +++ b/src/CPU/x87_ops.h @@ -1,23 +1,3 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x87 FPU instructions core. - * - * Version: @(#)x87_ops.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * leilei, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 leilei. - * Copyright 2016-2017 Miran Grca. - */ - #include #include diff --git a/src/CPU/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h index 39a14c4fb..ed083b921 100644 --- a/src/CPU/x87_ops_loadstore.h +++ b/src/CPU/x87_ops_loadstore.h @@ -1,21 +1,3 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * x87 FPU instructions core. - * - * Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - static int opFILDiw_a16(uint32_t fetchdat) { int16_t temp; diff --git a/src/ibm.h b/src/ibm.h index b210b07a0..04acfd78a 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -177,14 +177,6 @@ struct #define cycles cpu_state._cycles -extern uint32_t cpu_cur_status; - -#define CPU_STATUS_USE32 (1 << 0) -#define CPU_STATUS_STACK32 (1 << 1) -#define CPU_STATUS_FLATDS (1 << 2) -#define CPU_STATUS_FLATSS (1 << 3) - - #define cpu_rm cpu_state.rm_data.rm_mod_reg.rm #define cpu_mod cpu_state.rm_data.rm_mod_reg.mod #define cpu_reg cpu_state.rm_data.rm_mod_reg.reg From 6491036670afa4f60bf8f1eda90f9f8c04e3d737 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 18:55:01 +0200 Subject: [PATCH 274/392] Fixed compile-breaking bugs. --- src/CPU/386.c | 10 ++++++++++ src/CPU/cpu.c | 2 ++ src/CPU/cpu.h | 1 + 3 files changed, 13 insertions(+) diff --git a/src/CPU/386.c b/src/CPU/386.c index 6bd69af85..0422036b4 100644 --- a/src/CPU/386.c +++ b/src/CPU/386.c @@ -28,6 +28,13 @@ uint32_t oldpc2; int trap; +uint16_t flags,eflags; +uint32_t oldds,oldss,olddslimit,oldsslimit,olddslimitw,oldsslimitw; + +x86seg gdt,ldt,idt,tr; +x86seg _cs,_ds,_es,_ss,_fs,_gs; +x86seg _oldds; + extern int cpl_override; @@ -40,6 +47,9 @@ uint16_t ea_rseg; int is486; int cgate32; +uint32_t cr2, cr3, cr4; +uint32_t dr[8]; + uint8_t romext[32768]; diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index 453e8626a..e4cc64ac8 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -74,6 +74,7 @@ int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; +int cpu_pci_speed; uint64_t cpu_CR4_mask; @@ -606,6 +607,7 @@ void cpu_set() if (cpu_s->multi) cpu_busspeed = cpu_s->rspeed / cpu_s->multi; cpu_multi = cpu_s->multi; + cpu_pci_speed = cpu_s->pci_speed; cpu_hasrdtsc = 0; cpu_hasMMX = 0; cpu_hasMSR = 0; diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index cbf7b7516..d8d24b27a 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -117,6 +117,7 @@ extern int cpu_iscyrix; extern int cpu_16bitbus; extern int cpu_busspeed; extern int cpu_multi; +extern int cpu_pci_speed; extern int cpu_hasrdtsc; extern int cpu_hasMSR; From 29dae741221dec755dd97d464ca2115e6f60710a Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 18:58:22 +0200 Subject: [PATCH 275/392] Fixed more compile-breaking bugs. --- src/CPU/cpu.c | 2 ++ src/VIDEO/vid_ega_render.c | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index e4cc64ac8..a55e7e86e 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -76,6 +76,8 @@ int cpu_hasCR4; int cpu_use_dynarec; int cpu_pci_speed; +int hasfpu; + uint64_t cpu_CR4_mask; int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c index de8aa85ab..f100b3c64 100644 --- a/src/VIDEO/vid_ega_render.c +++ b/src/VIDEO/vid_ega_render.c @@ -26,9 +26,6 @@ #include "vid_ega_render.h" -int invert_display = 0; - - int ega_display_line(ega_t *ega) { int y_add = (enable_overscan) ? (overscan_y >> 1) : 0; From 3fb0368cdeefe59309848d770cd46fbe64b873c6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 19:58:04 +0200 Subject: [PATCH 276/392] Reduced sound buffer size; Fixed XTIDE (hopefully). --- src/ibm.h | 2 +- src/xtide.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 04acfd78a..99e02db34 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -548,7 +548,7 @@ extern float VGACONST1,VGACONST2; extern float RTCCONST; extern int gated,speakval,speakon; -#define SOUNDBUFLEN (48000/20) +#define SOUNDBUFLEN (48000/50) /*Sound Blaster*/ diff --git a/src/xtide.c b/src/xtide.c index aaa1b8294..b6deef1a5 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -40,12 +40,12 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) switch (port & 0xf) { case 0x0: - writeidew(8, val | (xtide->data_high << 8)); + writeidew(4, val | (xtide->data_high << 8)); return; case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - writeide(8, (port & 0xf) | 0x1f0, val); + writeide(4, (port & 0xf) | 0x1f0, val); return; case 0x8: @@ -53,7 +53,7 @@ static void xtide_write(uint16_t port, uint8_t val, void *p) return; case 0xe: - writeide(8, 0x3f6, val); + writeide(4, 0x3f6, val); return; } } @@ -67,19 +67,19 @@ static uint8_t xtide_read(uint16_t port, void *p) switch (port & 0xf) { case 0x0: - tempw = readidew(8); + tempw = readidew(4); xtide->data_high = tempw >> 8; return tempw & 0xff; case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7: - return readide(8, (port & 0xf) | 0x1f0); + return readide(4, (port & 0xf) | 0x1f0); case 0x8: return xtide->data_high; case 0xe: - return readide(8, 0x3f6); + return readide(4, 0x3f6); default: return 0xff; From fde78d13f815f4784a56440b23bb62bd75216714 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 1 Jun 2017 22:26:56 +0200 Subject: [PATCH 277/392] The IDE CD-ROM check now reports 0 for IDE devices 8 and 9 (corresponding to XT IDE channels 0 and 1), XTIDE now sees the hard disks. --- src/ide.c | 30 +++++++++++++++++++++--------- src/ide.h | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/ide.c b/src/ide.c index f9c28ffdc..b83a84fd6 100644 --- a/src/ide.c +++ b/src/ide.c @@ -142,6 +142,11 @@ uint8_t getstat(IDE *ide) { return ide->atastat; } int ide_drive_is_cdrom(IDE *ide) { + if (ide->channel >= 8) + { + return 0; + } + if (atapi_cdrom_drives[ide->channel] >= CDROM_NUM) { return 0; @@ -233,12 +238,15 @@ int image_is_hdx(const wchar_t *s, int check_signature) } int ide_enable[5] = { 1, 1, 0, 0, 1 }; -int ide_irq[4] = { 14, 15, 10, 11 }; +int ide_irq[5] = { 14, 15, 10, 11, 0 }; void ide_irq_raise(IDE *ide) { if ((ide->board > 3) || ide->irqstat) { + ide->irqstat=1; + ide->service=1; + return; } @@ -265,6 +273,7 @@ void ide_irq_lower(IDE *ide) { if ((ide->board > 3) || !(ide->irqstat)) { + ide->irqstat=0; return; } @@ -683,12 +692,12 @@ static int ide_set_features(IDE *ide) features = ide->cylprecomp; features_data = ide->secount; - pclog("Features code %02X\n", features); + ide_log("Features code %02X\n", features); switch(features) { case 0x03: /* Set transfer mode. */ - pclog("Transfer mode %02X\n", features_data >> 3); + ide_log("Transfer mode %02X\n", features_data >> 3); mode = (features_data >> 3); submode = features_data & 7; @@ -786,14 +795,14 @@ void resetide(void) { if (((hdc[d].bus == HDD_BUS_IDE_PIO_ONLY) || (hdc[d].bus == HDD_BUS_IDE_PIO_AND_DMA)) && (hdc[d].ide_channel < IDE_NUM)) { - pclog("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); + ide_log("Found IDE hard disk on channel %i\n", hdc[d].ide_channel); loadhd(&ide_drives[hdc[d].ide_channel], d, hdc[d].fn); c++; if (c >= (IDE_NUM + XTIDE_NUM)) break; } if ((hdc[d].bus == HDD_BUS_XTIDE) && (hdc[d].xtide_channel < XTIDE_NUM)) { - pclog("Found XT IDE hard disk on channel %i\n", hdc[d].xtide_channel); + ide_log("Found XT IDE hard disk on channel %i\n", hdc[d].xtide_channel); loadhd(&ide_drives[hdc[d].xtide_channel | 8], d, hdc[d].fn); c++; if (c >= (IDE_NUM + XTIDE_NUM)) break; @@ -1610,11 +1619,14 @@ void callbackide(int ide_board) int c; int64_t snum; int cdrom_id; - uint64_t full_size; + uint64_t full_size = 0; ide = &ide_drives[cur_ide[ide_board]]; ide_other = &ide_drives[cur_ide[ide_board] ^ 1]; - full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + if (ide->type == IDE_HDD) + { + full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); + } ext_ide = ide; if (ide_drive_is_cdrom(ide)) @@ -2274,12 +2286,12 @@ void ide_pri_enable_ex() { if (ide_base_main[0] & 0x300) { - pclog("Enabling primary base (%04X)...\n", ide_base_main[0]); + ide_log("Enabling primary base (%04X)...\n", ide_base_main[0]); io_sethandler(ide_base_main[0], 0x0008, ide_read_pri, ide_read_pri_w, ide_read_pri_l, ide_write_pri, ide_write_pri_w, ide_write_pri_l, NULL); } if (ide_side_main[0] & 0x300) { - pclog("Enabling primary side (%04X)...\n", ide_side_main[0]); + ide_log("Enabling primary side (%04X)...\n", ide_side_main[0]); io_sethandler(ide_side_main[0], 0x0001, ide_read_pri, NULL, NULL, ide_write_pri, NULL, NULL , NULL); } } diff --git a/src/ide.h b/src/ide.h index 85462b67e..be7fe0c50 100644 --- a/src/ide.h +++ b/src/ide.h @@ -85,7 +85,7 @@ extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int trans extern int ideboard; extern int ide_enable[5]; -extern int ide_irq[4]; +extern int ide_irq[5]; extern int idecallback[5]; From ab847fdecdd9fb2f0885f785a86b7eca672de555 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Jun 2017 01:38:25 +0200 Subject: [PATCH 278/392] Applied all the mainline PCem PCI commits; Applied patch from James-F that makes the Sound Blaster filters more accurate. --- src/SOUND/filters.h | 11 ++- src/SOUND/snd_opl.c | 8 +- src/SOUND/snd_sb.c | 8 +- src/VIDEO/vid_ati_mach64.c | 65 ++++++++++--- src/VIDEO/vid_s3.c | 60 ++++++++++-- src/VIDEO/vid_s3_virge.c | 44 ++++++++- src/i430fx.c | 22 ++++- src/i430hx.c | 21 +++- src/i430lx.c | 20 +++- src/i430nx.c | 20 +++- src/i430vx.c | 21 +++- src/i440fx.c | 24 ++++- src/model.c | 139 ++++++++++++++++++--------- src/pci.c | 88 ++++++++++++----- src/pci.h | 19 +++- src/piix.c | 46 ++++++++- src/piix.h | 4 +- src/sio.c | 192 ++++++++++++++++++++++--------------- src/sio.h | 10 +- src/sis496.c | 31 +++++- 20 files changed, 649 insertions(+), 204 deletions(-) diff --git a/src/SOUND/filters.h b/src/SOUND/filters.h index 6269b55e3..528bf0b05 100644 --- a/src/SOUND/filters.h +++ b/src/SOUND/filters.h @@ -131,10 +131,10 @@ static __inline float high_cut_iir(int i, float NewSample) { #undef NCoef -#define NCoef 1 +#define NCoef 2 static __inline float sb_iir(int i, float NewSample) { -/* float ACoef[NCoef+1] = { + float ACoef[NCoef+1] = { 0.03356837051492005100, 0.06713674102984010200, 0.03356837051492005100 @@ -144,9 +144,9 @@ static __inline float sb_iir(int i, float NewSample) { 1.00000000000000000000, -1.41898265221812010000, 0.55326988968868285000 - };*/ + }; - float ACoef[NCoef+1] = { +/* float ACoef[NCoef+1] = { 0.17529642630084405000, 0.17529642630084405000 }; @@ -154,7 +154,8 @@ static __inline float sb_iir(int i, float NewSample) { float BCoef[NCoef+1] = { 1.00000000000000000000, -0.64940759319751051000 - }; + };*/ + static float y[2][NCoef+1]; /* output samples */ static float x[2][NCoef+1]; /* input samples */ int n; diff --git a/src/SOUND/snd_opl.c b/src/SOUND/snd_opl.c index d04b7be9a..c5ccc6070 100644 --- a/src/SOUND/snd_opl.c +++ b/src/SOUND/snd_opl.c @@ -88,8 +88,8 @@ void opl2_update2(opl_t *opl) opl2_update(1, &opl->buffer[opl->pos*2 + 1], sound_pos_global - opl->pos); for (; opl->pos < sound_pos_global; opl->pos++) { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 4) + ((opl->filtbuf[0] * 11) / 16); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 4) + ((opl->filtbuf[1] * 11) / 16); + opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); + opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); } } } @@ -101,8 +101,8 @@ void opl3_update2(opl_t *opl) opl3_update(0, &opl->buffer[opl->pos*2], sound_pos_global - opl->pos); for (; opl->pos < sound_pos_global; opl->pos++) { - opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 4) + ((opl->filtbuf[0] * 11) / 16); - opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 4) + ((opl->filtbuf[1] * 11) / 16); + opl->filtbuf[0] = opl->buffer[opl->pos*2] = (opl->buffer[opl->pos*2] / 2); + opl->filtbuf[1] = opl->buffer[opl->pos*2+1] = (opl->buffer[opl->pos*2+1] / 2); } } } diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index d428c1a7d..688cb4cee 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -81,8 +81,8 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 47000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 47000) >> 16); if (sb->mixer.filter) { @@ -132,8 +132,8 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((sb->opl.buffer[c] * mixer->fm_l) >> 16); - out_r = ((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 47000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 47000) >> 16); if (sb->mixer.filter) { diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index 261d6681f..aabb9271b 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -83,6 +83,8 @@ typedef struct mach64_t int type; uint8_t pci_regs[256]; + uint8_t int_line; + int card; int bank_r[2]; int bank_w[2]; @@ -209,7 +211,8 @@ typedef struct mach64_t uint16_t pci_id; uint32_t config_chip_id; uint32_t block_decoded_io; - + int use_block_decoded_io; + int pll_addr; uint8_t pll_regs[16]; double pll_freq[4]; @@ -557,6 +560,19 @@ void mach64_updatemapping(mach64_t *mach64) } } +static void mach64_update_irqs(mach64_t *mach64) +{ + if (!PCI) + { + return; + } + + if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) + pci_set_irq(mach64->card, PCI_INTA); + else + pci_clear_irq(mach64->card, PCI_INTA); +} + static __inline void wake_fifo_thread(mach64_t *mach64) { thread_set_event(mach64->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ @@ -1652,6 +1668,7 @@ static void mach64_vblank_start(svga_t *svga) int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; mach64->crtc_int_cntl |= 4; + mach64_update_irqs(mach64); svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; @@ -2203,6 +2220,7 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); if (val & 4) mach64->crtc_int_cntl &= ~4; + mach64_update_irqs(mach64); break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -3113,18 +3131,21 @@ static void mach64_io_set(mach64_t *mach64) mach64_io_remove(mach64); io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - for (c = 0; c < 8; c++) - { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } + + if (!mach64->use_block_decoded_io) + { + for (c = 0; c < 8; c++) + { + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } + } io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - if (mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) + if (mach64->use_block_decoded_io && mach64->block_decoded_io && mach64->block_decoded_io < 0x10000) io_sethandler(mach64->block_decoded_io, 0x0400, mach64_block_inb, mach64_block_inw, mach64_block_inl, mach64_block_outb, mach64_block_outw, mach64_block_outl, mach64); } @@ -3169,6 +3190,11 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return mach64->pci_regs[0x32]; case 0x33: return mach64->pci_regs[0x33]; + + case 0x3c: return mach64->int_line; + case 0x3d: return PCI_INTA; + + case 0x40: return mach64->use_block_decoded_io; } return 0; } @@ -3251,6 +3277,21 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&mach64->bios_rom.mapping); } return; + + case 0x3c: + mach64->int_line = val; + break; + + case 0x40: + if (mach64->type == MACH64_VT2) + { + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_remove(mach64); + mach64->use_block_decoded_io = val & 0x04; + if (mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) + mach64_io_set(mach64); + } + break; } } @@ -3279,7 +3320,7 @@ static void *mach64_common_init() mach64_io_set(mach64); - pci_add(mach64_pci_read, mach64_pci_write, mach64); + mach64->card = pci_add(mach64_pci_read, mach64_pci_write, mach64); mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; @@ -3311,6 +3352,8 @@ static void *mach64gx_init() else mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ + mach64->use_block_decoded_io = PCI ? 4 : 0; + ati_eeprom_load(&mach64->eeprom, L"mach64.nvr", 1); rom_init(&mach64->bios_rom, L"roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 9f141668d..5c1ea29cc 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -94,12 +94,15 @@ typedef struct s3_t int chip; uint8_t id, id_ext, id_ext_pci; + + uint8_t int_line; int packed_mmio; uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; uint32_t vram_mask; @@ -150,8 +153,16 @@ typedef struct s3_t int blitter_busy; uint64_t blitter_time; uint64_t status_time; + + uint8_t subsys_cntl, subsys_stat; } s3_t; +#define INT_VSY (1 << 0) +#define INT_GE_BSY (1 << 1) +#define INT_FIFO_OVR (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_MASK 0xf + void s3_updatemapping(); void s3_accel_write(uint32_t addr, uint8_t val, void *p); @@ -173,6 +184,19 @@ static void s3_wait_fifo_idle(s3_t *s3) } } +static void s3_update_irqs(s3_t *s3) +{ + if (!PCI) + { + return; + } + + if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) + pci_set_irq(s3->card, PCI_INTA); + else + pci_clear_irq(s3->card, PCI_INTA); +} + void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3); #define WRITE8(addr, var, val) switch ((addr) & 3) \ @@ -725,9 +749,19 @@ static void fifo_thread(void *param) s3->blitter_time += end_time - start_time; } s3->blitter_busy = 0; + s3->subsys_stat |= INT_FIFO_EMP; + s3_update_irqs(s3); } } +static void s3_vblank_start(svga_t *svga) +{ + s3_t *s3 = (s3_t *)svga->p; + + s3->subsys_stat |= INT_VSY; + s3_update_irqs(s3); +} + static void s3_queue(s3_t *s3, uint32_t addr, uint32_t val, uint32_t type) { fifo_entry_t *fifo = &s3->fifo[s3->fifo_write_idx & FIFO_MASK]; @@ -1129,9 +1163,12 @@ void s3_accel_out(uint16_t port, uint8_t val, void *p) else switch (port) { case 0x42e8: + s3->subsys_stat &= ~val; + s3_update_irqs(s3); break; case 0x42e9: - s3->accel.subsys_cntl = val; + s3->subsys_cntl = val; + s3_update_irqs(s3); break; case 0x46e8: s3->accel.setup_md = val; @@ -1161,9 +1198,9 @@ uint8_t s3_accel_in(uint16_t port, void *p) switch (port) { case 0x42e8: - return 0; + return s3->subsys_stat; case 0x42e9: - return 0; + return s3->subsys_cntl; case 0x82e8: s3_wait_fifo_idle(s3); @@ -2060,6 +2097,9 @@ uint8_t s3_pci_read(int func, int addr, void *p) case 0x31: return 0x00; case 0x32: return s3->pci_regs[0x32]; case 0x33: return s3->pci_regs[0x33]; + + case 0x3c: return s3->int_line; + case 0x3d: return PCI_INTA; } return 0; } @@ -2072,7 +2112,7 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) switch (addr) { case PCI_REG_COMMAND: - s3->pci_regs[PCI_REG_COMMAND] = val & 0x27; + s3->pci_regs[PCI_REG_COMMAND] = val & 0x23; if (val & PCI_COMMAND_IO) s3_io_set(s3); else @@ -2101,6 +2141,10 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&s3->bios_rom.mapping); } return; + + case 0x3c: + s3->int_line = val; + return; } } @@ -2153,6 +2197,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); svga->crtc[0x37] = 1 | (7 << 5); + svga->vblank_start = s3_vblank_start; + svga->crtc[0x53] = 1 << 3; svga->crtc[0x59] = 0x70; @@ -2160,9 +2206,9 @@ static void *s3_init(wchar_t *bios_fn, int chip) if (PCI) { - pci_add(s3_pci_read, s3_pci_write, s3); + s3->card = pci_add(s3_pci_read, s3_pci_write, s3); } - + s3->pci_regs[0x04] = 3; s3->pci_regs[0x30] = 0x00; @@ -2174,6 +2220,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); s3->fifo_thread = thread_create(fifo_thread, s3); + + s3->int_line = 0; return s3; } diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 21723de42..49630de9c 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -121,6 +121,7 @@ typedef struct virge_t uint32_t linear_base, linear_size; uint8_t pci_regs[256]; + int card; int is_375; @@ -228,6 +229,8 @@ typedef struct virge_t event_t *fifo_not_full_event; int virge_busy; + + uint8_t subsys_stat, subsys_cntl; } virge_t; static __inline void wake_fifo_thread(virge_t *virge) @@ -292,6 +295,26 @@ enum CMD_SET_COMMAND_NOP = (15 << 27) }; +#define INT_VSY (1 << 0) +#define INT_S3D_DONE (1 << 1) +#define INT_FIFO_OVF (1 << 2) +#define INT_FIFO_EMP (1 << 3) +#define INT_3DF_EMP (1 << 6) +#define INT_MASK 0xff + +static void s3_virge_update_irqs(virge_t *virge) +{ + if (!PCI) + { + return; + } + + if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK)) + pci_set_irq(virge->card, PCI_INTA); + else + pci_clear_irq(virge->card, PCI_INTA); +} + static void s3_virge_out(uint16_t addr, uint8_t val, void *p) { virge_t *virge = (virge_t *)p; @@ -339,6 +362,7 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) case 0x32: if ((svga->crtc[0x67] & 0xc) != 0xc) svga->vrammask = (val & 0x40) ? 0x3ffff : ((virge->memory_size << 20) - 1); + s3_virge_update_irqs(virge); break; case 0x50: @@ -691,6 +715,14 @@ static void s3_virge_updatemapping(virge_t *virge) } +static void s3_virge_vblank_start(svga_t *svga) +{ + virge_t *virge = (virge_t *)svga->p; + + virge->subsys_stat |= INT_VSY; + s3_virge_update_irqs(virge); +} + static void s3_virge_wait_fifo_idle(virge_t *virge) { while (!FIFO_EMPTY) @@ -822,6 +854,7 @@ static uint32_t s3_virge_mmio_read_l(uint32_t addr, void *p) ret = (0x10 << 8); else ret = (0x10 << 8) | (1 << 13); + ret |= virge->subsys_stat; if (!virge->virge_busy) wake_fifo_thread(virge); break; @@ -1441,6 +1474,12 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) svga_recalctimings(svga); svga->fullchange = changeframecount; break; + + case 0x8504: + virge->subsys_stat &= ~(val & 0xff); + virge->subsys_cntl = (val >> 8); + s3_virge_update_irqs(virge); + break; case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: @@ -3248,6 +3287,8 @@ static void render_thread(void *param) thread_set_event(virge->not_full_event); } virge->s3d_busy = 0; + virge->subsys_stat |= INT_S3D_DONE; + s3_virge_update_irqs(virge); } } @@ -3707,6 +3748,7 @@ static void *s3_virge_init() s3_virge_in, s3_virge_out, s3_virge_hwcursor_draw, s3_virge_overlay_draw); + virge->svga.vblank_start = s3_virge_vblank_start; rom_init(&virge->bios_rom, L"roms/s3virge.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) @@ -3774,7 +3816,7 @@ static void *s3_virge_init() virge->is_375 = 0; - pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); + virge->card = pci_add(s3_virge_pci_read, s3_virge_pci_write, virge); virge->wake_render_thread = thread_create_event(); virge->wake_main_thread = thread_create_event(); diff --git a/src/i430fx.c b/src/i430fx.c index bfc635fed..a5100d789 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -49,15 +49,33 @@ static void i430fx_map(uint32_t addr, uint32_t size, int state) void i430fx_write(int func, int addr, uint8_t val, void *priv) { if (func) - return; + return; + + if (addr >= 0x10 && addr < 0x4f) + return; switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430fx[0x59] ^ val) & 0xf0) { diff --git a/src/i430hx.c b/src/i430hx.c index dc2b75b02..1e83fa513 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -52,13 +52,32 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430hx[0x59] ^ val) & 0xf0) { diff --git a/src/i430lx.c b/src/i430lx.c index ccb44ebff..ff22680bf 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -51,13 +51,31 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x42; + val |= 0x04; + break; + case 0x05: + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430lx[0x59] ^ val) & 0xf0) { diff --git a/src/i430nx.c b/src/i430nx.c index 487aa48bd..2827b293b 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -51,13 +51,31 @@ void i430nx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x42; + val |= 0x04; + break; + case 0x05: + val &= 0x01; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430nx[0x59] ^ val) & 0xf0) { diff --git a/src/i430vx.c b/src/i430vx.c index e9ff1f42b..bbe88865c 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -52,13 +52,32 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i430vx[0x59] ^ val) & 0xf0) { diff --git a/src/i440fx.c b/src/i440fx.c index a315801c9..1a19b10bc 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -52,20 +52,38 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) if (func) return; + if ((addr >= 0x10) && (addr < 0x4f)) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + case 0x0c: case 0x0e: return; + case 0x04: /*Command register*/ + val &= 0x02; + val |= 0x04; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val &= 0x80; + val |= 0x02; + break; + case 0x59: /*PAM0*/ if ((card_i440fx[0x59] ^ val) & 0xf0) { i440fx_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } - // pclog("i440fx_write : PAM0 write %02X\n", val); break; case 0x5a: /*PAM1*/ if ((card_i440fx[0x5a] ^ val) & 0x0f) @@ -96,14 +114,12 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) i440fx_map(0xe0000, 0x04000, val & 0xf); if ((card_i440fx[0x5e] ^ val) & 0xf0) i440fx_map(0xe4000, 0x04000, val >> 4); - // pclog("i440fx_write : PAM5 write %02X\n", val); break; case 0x5f: /*PAM6*/ if ((card_i440fx[0x5f] ^ val) & 0x0f) i440fx_map(0xe8000, 0x04000, val & 0xf); if ((card_i440fx[0x5f] ^ val) & 0xf0) i440fx_map(0xec000, 0x04000, val >> 4); - // pclog("i440fx_write : PAM6 write %02X\n", val); break; } diff --git a/src/model.c b/src/model.c index 7eb73479f..675e4d18a 100644 --- a/src/model.c +++ b/src/model.c @@ -609,7 +609,10 @@ void at_sis496_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xd); + pci_slot(0xf); sis496_init(); trc_init(); } @@ -624,8 +627,11 @@ void at_premiere_common_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); - sio_init(1); + pci_init(PCI_CONFIG_TYPE_2); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + sio_init(2, 0xc, 0xe, 0x6, 0); fdc37c665_init(); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); @@ -641,9 +647,12 @@ void at_586mc1_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_2, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_2); i430lx_init(); - sio_init(1); + pci_slot(0xc); + pci_slot(0xe); + pci_slot(0x6); + sio_init(2, 0xc, 0xe, 0x6, 0); device_add(&intel_flash_bxt_device); secondary_ide_check(); } @@ -658,9 +667,13 @@ void at_advanced_common_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); pc87306_init(); } @@ -673,34 +686,28 @@ void at_endeavor_init() void at_mb500n_init() { at_ide_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c665_init(); device_add(&intel_flash_bxt_device); } -#if 0 -void at_powermate_v_init() -{ - at_ide_init(); - powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - i430fx_init(); - piix_init(7); - fdc37c665_init(); - acerm3a_io_init(); - device_add(&intel_flash_bxt_device); -} -#endif - void at_p54tp4xe_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430fx_init(); - piix_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -710,9 +717,13 @@ void at_ap53_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c669_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -723,9 +734,13 @@ void at_p55t2s_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); pc87306_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -736,9 +751,13 @@ void at_acerm3a_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); @@ -749,9 +768,13 @@ void at_acerv35n_init() at_ide_init(); memregs_init(); powermate_memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i430hx_init(); - piix3_init(7); + piix_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); @@ -761,9 +784,13 @@ void at_p55t2p4_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -772,9 +799,13 @@ void at_i430vx_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); um8669f_init(); device_add(&intel_flash_bxt_device); } @@ -783,9 +814,13 @@ void at_p55tvp4_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -794,9 +829,13 @@ void at_p55va_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430vx_init(); - piix3_init(7); + piix3_init(7, 18, 17, 20, 19); fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } @@ -805,9 +844,13 @@ void at_i440fx_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0, 31); - i440fx_init(); - piix3_init(7); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); + i430vx_init(); + piix3_init(7, 18, 17, 20, 19); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -816,9 +859,13 @@ void at_s1668_init() { at_ide_init(); memregs_init(); - pci_init(PCI_CONFIG_TYPE_1, 0xd, 0x10); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xd); + pci_slot(0xe); + pci_slot(0xf); + pci_slot(0x10); i440fx_init(); - piix3_init(7); + piix3_init(7, 0xd, 0xe, 0xf, 0x10); fdc37c665_init(); device_add(&intel_flash_bxt_device); } diff --git a/src/pci.c b/src/pci.c index 73b056118..022286669 100644 --- a/src/pci.c +++ b/src/pci.c @@ -1,19 +1,19 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include - #include "ibm.h" #include "io.h" #include "mem.h" +#include "pic.h" #include "pci.h" void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv); uint8_t (*pci_card_read[32])(int func, int addr, void *priv); void *pci_priv[32]; -static uint8_t pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; -static int pci_min_card, pci_max_card; +static int pci_irq_routing[32]; +static int pci_irq_active[32]; +static int pci_irqs[4]; +static int pci_card_valid[32]; + +static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; int pci_burst_time, pci_nonburst_time; void pci_cf8_write(uint16_t port, uint32_t val, void *p) @@ -37,7 +37,7 @@ void pci_write(uint16_t port, uint8_t val, void *priv) case 0xcfc: case 0xcfd: case 0xcfe: case 0xcff: if (!pci_enable) return; - + if (!pci_bus && pci_card_write[pci_card]) pci_card_write[pci_card](pci_func, pci_index | (port & 3), val, pci_priv[pci_card]); @@ -57,10 +57,8 @@ uint8_t pci_read(uint16_t port, void *priv) return pci_card_read[pci_card](pci_func, pci_index | (port & 3), pci_priv[pci_card]); return 0xff; - - default: - return 0xff; } + return 0xff; } void pci_type2_write(uint16_t port, uint8_t val, void *priv); @@ -111,8 +109,40 @@ uint8_t pci_type2_read(uint16_t port, void *priv) } return 0xff; } - -void pci_init(int type, int min_card, int max_card) + +void pci_set_irq_routing(int pci_int, int irq) +{ + pci_irqs[pci_int - 1] = irq; +} + +void pci_set_card_routing(int card, int pci_int) +{ + pci_irq_routing[card] = pci_int; +} + +void pci_set_irq(int card, int pci_int) +{ + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) + picint(1 << pci_irqs[irq]); + pci_irq_active[card] = 1; + } +} + +void pci_clear_irq(int card, int pci_int) +{ + if (pci_irq_routing[card]) + { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) + picintc(1 << pci_irqs[irq]); + pci_irq_active[card] = 0; + } +} + +void pci_init(int type) { int c; @@ -130,14 +160,22 @@ void pci_init(int type, int min_card, int max_card) } for (c = 0; c < 32; c++) - { - pci_card_read[c] = NULL; - pci_card_write[c] = NULL; - pci_priv[c] = NULL; - } + { + pci_card_read[c] = NULL; + pci_card_write[c] = NULL; + pci_priv[c] = NULL; + pci_irq_routing[c] = 0; + pci_irq_active[c] = 0; + pci_card_valid[c] = 0; + } - pci_min_card = min_card; - pci_max_card = max_card; + for (c = 0; c < 4; c++) + pci_irqs[c] = PCI_IRQ_DISABLED; +} + +void pci_slot(int card) +{ + pci_card_valid[card] = 1; } void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) @@ -147,18 +185,20 @@ void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), pci_priv[card] = priv; } -void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv) { int c; - for (c = pci_min_card; c <= pci_max_card; c++) + for (c = 0; c < 32; c++) { - if (!pci_card_read[c] && !pci_card_write[c]) + if (pci_card_valid[c] && !pci_card_read[c] && !pci_card_write[c]) { pci_card_read[c] = read; pci_card_write[c] = write; pci_priv[c] = priv; - return; + return c; } } + + return -1; } diff --git a/src/pci.h b/src/pci.h index 6c6782e23..6a8778e0f 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,9 +1,11 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void pci_init(int type, int min_card, int max_card); +void pci_init(int type); +void pci_slot(int card); void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); -void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +int pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); +void pci_set_irq_routing(int card, int irq); +void pci_set_card_routing(int card, int pci_int); +void pci_set_irq(int card, int pci_int); +void pci_clear_irq(int card, int pci_int); #define PCI_REG_COMMAND 0x04 @@ -13,4 +15,11 @@ void pci_add(uint8_t (*read)(int func, int addr, void *priv), void (*write)(int #define PCI_CONFIG_TYPE_1 1 #define PCI_CONFIG_TYPE_2 2 +#define PCI_INTA 1 +#define PCI_INTB 2 +#define PCI_INTC 3 +#define PCI_INTD 4 + +#define PCI_IRQ_DISABLED -1 + extern int pci_burst_time, pci_nonburst_time; diff --git a/src/piix.c b/src/piix.c index 8e7378dbd..f2a38bf46 100644 --- a/src/piix.c +++ b/src/piix.c @@ -107,12 +107,40 @@ void piix_write(int func, int addr, uint8_t val, void *priv) } else { + if (addr >= 0x0f && addr < 0x4c) + return; + switch (addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0e: return; + + case 0x60: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x62: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x63: + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } if (addr == 0x4C) { @@ -576,7 +604,7 @@ void piix_reset(void) card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ card_piix[0x02] = 0x2e; card_piix[0x03] = 0x12; /*82371FB (PIIX)*/ card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; - card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; + card_piix[0x06] = 0x80; card_piix[0x07] = 0x02; card_piix[0x08] = 0x00; /*A0 stepping*/ card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; card_piix[0x0e] = 0x80; /*Multi-function device*/ @@ -615,7 +643,7 @@ void piix3_reset(void) card_piix[0x00] = 0x86; card_piix[0x01] = 0x80; /*Intel*/ card_piix[0x02] = 0x00; card_piix[0x03] = 0x70; /*82371SB (PIIX3)*/ card_piix[0x04] = 0x07; card_piix[0x05] = 0x00; - card_piix[0x06] = 0x00; card_piix[0x07] = 0x02; + card_piix[0x06] = 0x80; card_piix[0x07] = 0x02; card_piix[0x08] = 0x00; /*A0 stepping*/ card_piix[0x09] = 0x00; card_piix[0x0a] = 0x01; card_piix[0x0b] = 0x06; card_piix[0x0e] = 0x80; /*Multi-function device*/ @@ -650,7 +678,7 @@ void piix3_reset(void) card_piix_ide[0x44] = 0x00; } -void piix_init(int card) +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -669,9 +697,14 @@ void piix_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = piix_reset; + + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); } -void piix3_init(int card) +void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, piix_read, piix_write, NULL); @@ -690,4 +723,9 @@ void piix3_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = piix3_reset; + + pci_set_card_routing(pci_a, PCI_INTA); + pci_set_card_routing(pci_b, PCI_INTB); + pci_set_card_routing(pci_c, PCI_INTC); + pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/piix.h b/src/piix.h index 00000138c..a922ff41e 100644 --- a/src/piix.h +++ b/src/piix.h @@ -16,8 +16,8 @@ * Copyright 2016-2017 Miran Grca. */ -void piix_init(int card); -void piix3_init(int card); +void piix_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); +void piix3_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); uint8_t piix_bus_master_read(uint16_t port, void *priv); void piix_bus_master_write(uint16_t port, uint8_t val, void *priv); diff --git a/src/sio.c b/src/sio.c index 3250ba2f0..96d2ef375 100644 --- a/src/sio.c +++ b/src/sio.c @@ -6,27 +6,24 @@ * * Emulation of Intel System I/O PCI chip. * - * Version: @(#)sio.c 1.0.0 2017/05/30 + * Version: @(#)sio.c 1.0.1 2017/06/02 * - * Author: Miran Grca, - * Copyright 2017-2017 Miran Grca. + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. */ -/*PRD format : - - word 0 - base address - word 1 - bits 1 - 15 = byte count, bit 31 = end of transfer -*/ #include + #include "ibm.h" -#include "cpu/cpu.h" #include "cdrom.h" #include "disc.h" #include "dma.h" #include "fdc.h" +#include "keyboard_at.h" #include "ide.h" #include "io.h" -#include "keyboard_at.h" #include "mem.h" #include "pci.h" @@ -36,66 +33,99 @@ static uint8_t card_sio[256]; void sio_write(int func, int addr, uint8_t val, void *priv) { -// pclog("sio_write: func=%d addr=%02x val=%02x %04x:%08x\n", func, addr, val, CS, pc); - - if ((addr & 0xff) < 4) return; - if (func > 0) - return; + return; - if (func == 0) - { - switch (addr) - { - case 0x00: case 0x01: case 0x02: case 0x03: - case 0x08: case 0x09: case 0x0a: case 0x0b: - case 0x0e: + if (addr >= 0x0f && addr < 0x4c) return; - } - card_sio[addr] = val; - if (addr == 0x40) - { - if (!((val ^ card_sio[addr]) & 0x40)) - { - return; - } - if (val & 0x40) - { - dma_alias_remove(); - } - else - { - dma_alias_set(); - } - } - else if (addr == 0x4f) - { - if (!((val ^ card_sio[addr]) & 0x40)) - { - return; - } + switch (addr) + { + case 0x00: case 0x01: case 0x02: case 0x03: + case 0x08: case 0x09: case 0x0a: case 0x0b: + case 0x0e: + return; + + case 0x04: /*Command register*/ + val &= 0x08; + val |= 0x07; + break; + case 0x05: + val = 0; + break; + + case 0x06: /*Status*/ + val = 0; + break; + case 0x07: + val = 0x02; + break; - if (val & 0x40) - { - port_92_add(); - } - else - { - port_92_remove(); - } + case 0x40: + if (!((val ^ card_sio[addr]) & 0x40)) + { + return; } + + if (val & 0x40) + { + dma_alias_remove(); + } + else + { + dma_alias_set(); + } + break; + + case 0x4f: + if (!((val ^ card_sio[addr]) & 0x40)) + { + return; + } + + if (val & 0x40) + { + port_92_add(); + } + else + { + port_92_remove(); + } + + case 0x60: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTA, val & 0xf); + break; + case 0x61: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTC, val & 0xf); + break; + case 0x62: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTB, val & 0xf); + break; + case 0x63: + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + else + pci_set_irq_routing(PCI_INTD, val & 0xf); + break; } + card_sio[addr] = val; } uint8_t sio_read(int func, int addr, void *priv) { -// pclog("sio_read: func=%d addr=%02x %04x:%08x\n", func, addr, CS, pc); - if (func > 0) - return 0xff; + return 0xff; - return card_sio[addr]; + return card_sio[addr]; } static int trc_reg = 0; @@ -164,31 +194,30 @@ void sio_reset(void) { memset(card_sio, 0, 256); card_sio[0x00] = 0x86; card_sio[0x01] = 0x80; /*Intel*/ - card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378ZB (SIO)*/ + card_sio[0x02] = 0x84; card_sio[0x03] = 0x04; /*82378IB (SIO)*/ card_sio[0x04] = 0x07; card_sio[0x05] = 0x00; - card_sio[0x06] = 0x00; card_sio[0x07] = 0x02; - card_sio[0x08] = 0x00; /*A0 stepping*/ - card_sio[0x40] = 0x20; - card_sio[0x42] = 0x24; - card_sio[0x45] = 0x10; - card_sio[0x46] = 0x0F; - card_sio[0x48] = 0x01; - card_sio[0x4A] = 0x10; - card_sio[0x4B] = 0x0F; - card_sio[0x4C] = 0x56; - card_sio[0x4D] = 0x40; - card_sio[0x4E] = 0x07; - card_sio[0x4F] = 0x4F; - card_sio[0x60] = card_sio[0x61] = card_sio[0x62] = card_sio[0x63] = 0x80; - card_sio[0x80] = 0x78; - card_sio[0xA0] = 0x08; - card_sio[0xA8] = 0x0F; + card_sio[0x06] = 0x00; card_sio[0x07] = 0x02; + card_sio[0x08] = 0x03; /*A0 stepping*/ + + card_sio[0x40] = 0x20; card_sio[0x41] = 0x00; + card_sio[0x42] = 0x04; card_sio[0x43] = 0x00; + card_sio[0x44] = 0x20; card_sio[0x45] = 0x10; + card_sio[0x46] = 0x0f; card_sio[0x47] = 0x00; + card_sio[0x48] = 0x01; card_sio[0x49] = 0x10; + card_sio[0x4a] = 0x10; card_sio[0x4b] = 0x0f; + card_sio[0x4c] = 0x56; card_sio[0x4d] = 0x40; + card_sio[0x4e] = 0x07; card_sio[0x4f] = 0x4f; + card_sio[0x54] = 0x00; card_sio[0x55] = 0x00; card_sio[0x56] = 0x00; + card_sio[0x60] = 0x80; card_sio[0x61] = 0x80; card_sio[0x62] = 0x80; card_sio[0x63] = 0x80; + card_sio[0x80] = 0x78; card_sio[0x81] = 0x00; + card_sio[0xa0] = 0x08; + card_sio[0xa8] = 0x0f; } -void sio_init(int card) +void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d) { pci_add_specific(card, sio_read, sio_write, NULL); - + sio_reset(); trc_init(); @@ -200,4 +229,13 @@ void sio_init(int card) dma_alias_set(); pci_reset_handler.pci_set_reset = sio_reset; + + if (pci_a) + pci_set_card_routing(pci_a, PCI_INTA); + if (pci_b) + pci_set_card_routing(pci_b, PCI_INTB); + if (pci_c) + pci_set_card_routing(pci_c, PCI_INTC); + if (pci_d) + pci_set_card_routing(pci_d, PCI_INTD); } diff --git a/src/sio.h b/src/sio.h index 9aacd3e6b..0e3ea651f 100644 --- a/src/sio.h +++ b/src/sio.h @@ -6,11 +6,13 @@ * * Emulation of Intel System I/O PCI chip. * - * Version: @(#)sio.h 1.0.0 2017/05/30 + * Version: @(#)sio.h 1.0.1 2017/06/02 * - * Author: Miran Grca, - * Copyright 2017-2017 Miran Grca. + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. */ void trc_init(void); -void sio_init(int card); +void sio_init(int card, int pci_a, int pci_b, int pci_c, int pci_d); diff --git a/src/sis496.c b/src/sis496.c index a858102a3..cb4d9303d 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -68,8 +68,33 @@ void sis496_write(int func, int addr, uint8_t val, void *p) sis496_recalcmapping(); } break; - } + case 0xc0: + if (val & 0x80) + pci_set_irq_routing(PCI_INTA, val & 0xf); + else + pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); + break; + case 0xc1: + if (val & 0x80) + pci_set_irq_routing(PCI_INTB, val & 0xf); + else + pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); + break; + case 0xc2: + if (val & 0x80) + pci_set_irq_routing(PCI_INTC, val & 0xf); + else + pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); + break; + case 0xc3:// pclog("IRQ routing %02x %02x\n", addr, val); + if (val & 0x80) + pci_set_irq_routing(PCI_INTD, val & 0xf); + else + pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); + break; + } + if ((addr >= 4 && addr < 8) || addr >= 0x40) sis496.pci_conf[addr] = val; } @@ -118,6 +143,10 @@ void sis496_init(void) sis496_reset(); pci_reset_handler.pci_master_reset = sis496_pci_reset; + + pci_set_card_routing(15, PCI_INTA); + pci_set_card_routing(13, PCI_INTD); + pci_set_card_routing(11, PCI_INTC); } void sis496_close(void *p) From b805a994b98c1bd8889d47f8c4c98083fbdc9e0a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Jun 2017 02:22:38 +0200 Subject: [PATCH 279/392] Fixed the ATi Mach64 and S3 Virge graphics cards; HDD controller initializer now ignores non-IDE controllers if the specified model has IDE; The RTL8029AS NIC and BusLogic BT-958D SCSI controller are now APIC-aware. --- src/VIDEO/vid_ati_mach64.c | 4 +-- src/VIDEO/vid_s3_virge.c | 4 +-- src/WIN/win_settings.c | 2 +- src/hdd.c | 9 +++++- src/net_ne2000.c | 65 +++++++++++++++++++++++++------------- src/scsi_buslogic.c | 46 ++++++++++++++++++++------- 6 files changed, 91 insertions(+), 39 deletions(-) diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index aabb9271b..6ac27c4d4 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -3352,8 +3352,6 @@ static void *mach64gx_init() else mach64->config_stat0 |= 1; /*VLB, 256Kx16 DRAM*/ - mach64->use_block_decoded_io = PCI ? 4 : 0; - ati_eeprom_load(&mach64->eeprom, L"mach64.nvr", 1); rom_init(&mach64->bios_rom, L"roms/mach64gx/bios.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -3371,6 +3369,8 @@ static void *mach64vt2_init() mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ mach64->config_stat0 = 4; + mach64->use_block_decoded_io = PCI ? 4 : 0; + ati_eeprom_load(&mach64->eeprom, L"mach64vt.nvr", 1); rom_init(&mach64->bios_rom, L"roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 49630de9c..d742051ae 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -3728,9 +3728,9 @@ static void s3_virge_pci_write(int func, int addr, uint8_t val, void *p) mem_mapping_disable(&virge->bios_rom.mapping); } return; - /* case 0x3c: + case 0x3c: virge->pci_regs[0x3c] = val; - return; */ + return; } } diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 73fc90ed1..31d1ff303 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -988,7 +988,7 @@ static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) h = GetDlgItem(hdlg, IDC_COMBO_HDC); - if (models[model].flags & MODEL_HAS_IDE) + if (models[temp_model].flags & MODEL_HAS_IDE) { hdc_ignore = 1; diff --git a/src/hdd.c b/src/hdd.c index 694a42788..7fdb21d95 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -1,6 +1,8 @@ #include "ibm.h" +#include "CPU/cpu.h" #include "device.h" #include "hdd.h" +#include "model.h" #include "hdd_esdi.h" #include "mfm_at.h" @@ -63,7 +65,12 @@ int hdd_controller_current_is_mfm() void hdd_controller_init(char *internal_name) { int c = 0; - + + if (models[model].flags & MODEL_HAS_IDE) + { + return; + } + while (hdd_controllers[c].device) { if (!strcmp(internal_name, hdd_controllers[c].internal_name)) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index fee972934..c6b22db54 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -229,6 +229,8 @@ typedef struct { uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; + + int card; } nic_t; @@ -252,6 +254,36 @@ nelog(int lvl, const char *fmt, ...) } +static void +nic_interrupt(void *priv, int set) +{ + nic_t *dev = (nic_t *) priv; + + if (!PCI || strcmp(dev->name, "RTL8029AS")) + { + if (set) + { + picint(1 << dev->base_irq); + } + else + { + picintc(1 << dev->base_irq); + } + } + else + { + if (set) + { + pci_set_irq(dev->card, PCI_INTA); + } + else + { + pci_clear_irq(dev->card, PCI_INTA); + } + } +} + + /* reset - restore state to power-up, cancelling all i/o */ static void nic_reset(void *priv) @@ -317,8 +349,7 @@ nic_reset(void *priv) dev->ISR.reset = 1; dev->DCR.longaddr = 1; - picint(1<base_irq); - picintc(1<base_irq); + nic_interrupt(dev, 0); } @@ -474,7 +505,7 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) if (dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; if (dev->IMR.rdma_inte) { - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); } } break; @@ -534,7 +565,7 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) if (dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; if (dev->IMR.rdma_inte) { - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); } } break; @@ -742,7 +773,7 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) (dev->IMR.tx_inte << 1) | (dev->IMR.rx_inte)); if (val == 0x00) { - picintc(1 << dev->base_irq); + nic_interrupt(dev, 0); } break; @@ -862,9 +893,9 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) (dev->ISR.pkt_tx << 1) | (dev->ISR.pkt_rx)); if (((val & val2) & 0x7f) == 0) { - picintc(1 << dev->base_irq); + nic_interrupt(dev, 0); } else { - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); } break; @@ -1227,9 +1258,9 @@ write_cr(nic_t *dev, uint32_t val) if (dev->CR.rdma_cmd == 0x01 && dev->CR.start && dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; if (dev->IMR.rdma_inte) { - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); if (! dev->is_pci) - picintc(1 << dev->base_irq); + nic_interrupt(dev, 0); } } } @@ -1625,18 +1656,8 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) case 0x3C: /* PCI_ILR */ if (val != 0xFF) { -#if 1 - /* - * Commented out until an APIC controller is - * emulated for the PIIX3, otherwise the - * RTL-8029/AS will not get an IRQ on boards - * using the PIIX3. - */ - nelog(1, "%s: IRQ now: %i (IGNORED)\n", dev->name, val); -#else nelog(1, "%s: IRQ now: %i\n", dev->name, val); dev->base_irq = val; -#endif } dev->pci_regs[addr] = dev->base_irq; return; @@ -1685,7 +1706,7 @@ nic_tx(nic_t *dev, uint32_t val) /* Generate an interrupt if not masked */ if (dev->IMR.tx_inte) - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); dev->tx_timer_active = 0; } @@ -1821,7 +1842,7 @@ nic_rx(void *priv, uint8_t *buf, int io_len) dev->ISR.pkt_rx = 1; if (dev->IMR.rx_inte) - picint(1 << dev->base_irq); + nic_interrupt(dev, 1); } @@ -1972,7 +1993,7 @@ nic_init(int board) dev->eeprom[0x7D] = (PCI_VENDID>>8); /* Make this device known to the PCI bus. */ - pci_add(nic_pci_read, nic_pci_write, dev); + dev->card = pci_add(nic_pci_read, nic_pci_write, dev); } /* Set up our BIA. */ diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index e9d2ca48a..a95a9a569 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -493,6 +493,7 @@ typedef struct { int Lock; mem_mapping_t mmio_mapping; int chip; + int Card; } Buslogic_t; #pragma pack(pop) @@ -534,18 +535,46 @@ BuslogicLog(const char *format, ...) #define pclog BuslogicLog +static void +BuslogicInterrupt(Buslogic_t *bl, int set) +{ + if (bl->chip != CHIP_BUSLOGIC_PCI) + { + if (set) + { + picint(1 << bl->Irq); + } + else + { + picintc(1 << bl->Irq); + } + } + else + { + if (set) + { + pci_set_irq(bl->Card, PCI_INTA); + } + else + { + pci_clear_irq(bl->Card, PCI_INTA); + } + } +} + + static void BuslogicClearInterrupt(Buslogic_t *bl) { pclog("Buslogic: Lowering Interrupt 0x%02X\n", bl->Interrupt); bl->Interrupt = 0; pclog("Lowering IRQ %i\n", bl->Irq); - picintc(1 << bl->Irq); + BuslogicInterrupt(bl, 0); if (bl->PendingInterrupt) { bl->Interrupt = bl->PendingInterrupt; pclog("Buslogic: Raising Interrupt 0x%02X (Pending)\n", bl->Interrupt); if (bl->MailboxOutInterrupts || !(bl->Interrupt & INTR_MBOA)) { - if (bl->IrqEnabled) picint(1 << bl->Irq); + if (bl->IrqEnabled) BuslogicInterrupt(bl, 1); } bl->PendingInterrupt = 0; } @@ -635,7 +664,7 @@ BuslogicCommandComplete(Buslogic_t *bl) bl->Interrupt = (INTR_ANY | INTR_HACC); pclog("Raising IRQ %i\n", bl->Irq); if (bl->IrqEnabled) - picint(1 << bl->Irq); + BuslogicInterrupt(bl, 1); } bl->Command = 0xFF; @@ -653,7 +682,7 @@ BuslogicRaiseInterrupt(Buslogic_t *bl, uint8_t Interrupt) bl->Interrupt = Interrupt; pclog("Raising IRQ %i\n", bl->Irq); if (bl->IrqEnabled) - picint(1 << bl->Irq); + BuslogicInterrupt(bl, 1); } } @@ -1339,7 +1368,7 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) else bl->IrqEnabled = 1; pclog("Lowering IRQ %i\n", bl->Irq); - picintc(1 << bl->Irq); + BuslogicInterrupt(bl, 0); break; case 0x81: @@ -2186,18 +2215,13 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } return; -#if 0 - /* Commented out until an APIC controller is emulated for the PIIX3, - * otherwise the BT-958 will not get an IRQ on boards using the PIIX3. - */ case 0x3C: buslogic_pci_regs[addr] = val; if (val != 0xFF) { - buslogic_log("BusLogic IRQ now: %i\n", val); + BuslogicLog("BusLogic IRQ now: %i\n", val); bl->Irq = val; } return; -#endif } } From 3b2cfb487806fc0df8fa15b9b873c889cfebc004 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 1 Jun 2017 20:26:05 -0400 Subject: [PATCH 280/392] Oops --- src/Makefile.mingw | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e77c1af04..e716ff206 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.19 2017/05/30 +# Version: @(#)Makefile.mingw 1.0.21 2017/06/01 # # Authors: Kotori, # Fred N. van Kempen, @@ -250,9 +250,9 @@ endif clean: - -del *.o >NUL: - -del *.exe >NUL: - -del *.res >NUL: + -rm *.o + -rm *.exe + -rm *.res 86Box.res: 86Box.rc @echo Processing $< From bb89799ed25c27c0fafbb21a8419765cc6afb276 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 1 Jun 2017 21:49:57 -0400 Subject: [PATCH 281/392] See comment in net_ne2000.c. Dump IO and IRQ selection, keep BIOS selection for PCI. --- src/net_ne2000.c | 96 ++++++++++++++++++++++++++++-------------------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index c6b22db54..f08c3353b 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -11,7 +11,7 @@ * NOTE: Its still a mess, but we're getting there. The file will * also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.7 2017/05/25 + * Version: @(#)net_ne2000.c 1.0.8 2017/06/01 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -229,8 +229,7 @@ typedef struct { uint8_t maclocal[6]; /* configured MAC (local) address */ uint8_t eeprom[128]; /* for RTL8029AS */ rom_t bios_rom; - - int card; + int card; /* PCI card slot */ } nic_t; @@ -255,31 +254,18 @@ nelog(int lvl, const char *fmt, ...) static void -nic_interrupt(void *priv, int set) +nic_interrupt(nic_t *dev, int set) { - nic_t *dev = (nic_t *) priv; - - if (!PCI || strcmp(dev->name, "RTL8029AS")) - { - if (set) - { - picint(1 << dev->base_irq); - } - else - { - picintc(1 << dev->base_irq); - } - } - else - { - if (set) - { - pci_set_irq(dev->card, PCI_INTA); - } - else - { - pci_clear_irq(dev->card, PCI_INTA); - } + if (PCI && dev->is_pci) { + if (set) + pci_set_irq(dev->card, PCI_INTA); + else + pci_clear_irq(dev->card, PCI_INTA); + } else { + if (set) + picint(1<base_irq); + else + picintc(1<base_irq); } } @@ -504,9 +490,8 @@ asic_read(nic_t *dev, uint32_t off, unsigned int len) /* If all bytes have been written, signal remote-DMA complete */ if (dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) { + if (dev->IMR.rdma_inte) nic_interrupt(dev, 1); - } } break; @@ -564,9 +549,8 @@ asic_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) /* If all bytes have been written, signal remote-DMA complete */ if (dev->remote_bytes == 0) { dev->ISR.rdma_done = 1; - if (dev->IMR.rdma_inte) { + if (dev->IMR.rdma_inte) nic_interrupt(dev, 1); - } } break; @@ -772,9 +756,8 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) (dev->IMR.rxerr_inte << 2) | (dev->IMR.tx_inte << 1) | (dev->IMR.rx_inte)); - if (val == 0x00) { + if (val == 0x00) nic_interrupt(dev, 0); - } break; case 0x08: /* RSAR0 */ @@ -892,11 +875,10 @@ page0_write(nic_t *dev, uint32_t off, uint32_t val, unsigned len) (dev->ISR.rx_err << 2) | (dev->ISR.pkt_tx << 1) | (dev->ISR.pkt_rx)); - if (((val & val2) & 0x7f) == 0) { + if (((val & val2) & 0x7f) == 0) nic_interrupt(dev, 0); - } else { + else nic_interrupt(dev, 1); - } break; default: @@ -1992,7 +1974,7 @@ nic_init(int board) dev->eeprom[0x79] = dev->eeprom[0x7D] = (PCI_VENDID>>8); - /* Make this device known to the PCI bus. */ + /* Insert this device onto the PCI bus, keep its slot number. */ dev->card = pci_add(nic_pci_read, nic_pci_write, dev); } @@ -2141,7 +2123,10 @@ static device_config_t ne1000_config[] = "D000", 0xD0000 }, { - "C000", 0xC0000 + "D800", 0xD8000 + }, + { + "C800", 0xC8000 }, { "" @@ -2217,7 +2202,10 @@ static device_config_t ne2000_config[] = "D000", 0xD0000 }, { - "C000", 0xC0000 + "D800", 0xD8000 + }, + { + "C800", 0xC8000 }, { "" @@ -2231,6 +2219,7 @@ static device_config_t ne2000_config[] = static device_config_t rtl8029as_config[] = { +#if 0 { "irq", "IRQ", CONFIG_SELECTION, "", 10, { @@ -2254,6 +2243,35 @@ static device_config_t rtl8029as_config[] = } }, }, +#endif +#if 1 + /* + * WTF. + * Even though it is PCI, the user should still have control + * over whether or not it's Option ROM BIOS will be enabled + * or not. + */ + { + "bios_addr", "BIOS address", CONFIG_HEX20, "", 0, + { + { + "Disabled", 0x00000 + }, + { + "D000", 0xD0000 + }, + { + "D800", 0xD8000 + }, + { + "C800", 0xC8000 + }, + { + "" + } + }, + }, +#endif { "mac", "MAC Address", CONFIG_MAC, "", -1 }, From 6a4f8eacb7b72e41f666bce71f28c74037d86e50 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Jun 2017 17:56:14 +0200 Subject: [PATCH 282/392] Commented out APIC support for network and SCSI - tested with Windows 98, Epox P55-VA, and SCSI, and ended with Windows reporting a Fatal exception 0E. Will be restored when Sarah fixes the APIC emulation. --- src/VIDEO/vid_s3.c | 150 ++++++++++++++++++++++++++------------------ src/net_ne2000.c | 4 +- src/scsi_buslogic.c | 43 +++++++++---- 3 files changed, 121 insertions(+), 76 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 5c1ea29cc..c44021f04 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -155,6 +155,7 @@ typedef struct s3_t uint64_t status_time; uint8_t subsys_cntl, subsys_stat; + uint8_t status_9ae9; } s3_t; #define INT_VSY (1 << 0) @@ -444,70 +445,88 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } + if (port & 0x8000) + { + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } + else + { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + } } static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x400) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } - else - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } - else - { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } + if (port & 0x8000) + { + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + s3_accel_out_fifo(s3, port + 2, val >> 16); + s3_accel_out_fifo(s3, port + 3, val >> 24); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x400) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } + else if ((s3->accel.cmd & 0x600) == 0x200) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } + else + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } + else + { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) + { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + else + { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } + } } static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) @@ -1257,7 +1276,7 @@ uint8_t s3_accel_in(uint16_t port, void *p) if (!FIFO_EMPTY) temp |= 0x02; /*Hardware busy*/ else - temp |= 0x04; /*FIFO empty*/ + temp |= s3->status_9ae9; /*FIFO empty*/ if (FIFO_FULL) temp |= 0xf8; /*FIFO full*/ return temp; @@ -1642,6 +1661,15 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dest = s3->accel.cy * s3->width; } + + s3->status_9ae9 = 4; /*To avoid the spam from OS/2's drivers*/ + + if ((s3->accel.cmd & 0x100) && !cpu_input) + { + s3->status_9ae9 = 2; /*To avoid the spam from OS/2's drivers*/ + return; /*Wait for data from CPU*/ + } + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; diff --git a/src/net_ne2000.c b/src/net_ne2000.c index f08c3353b..9df7ac7ff 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -1636,6 +1636,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) nic_update_bios(dev); return; +#if 0 case 0x3C: /* PCI_ILR */ if (val != 0xFF) { nelog(1, "%s: IRQ now: %i\n", dev->name, val); @@ -1643,6 +1644,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) } dev->pci_regs[addr] = dev->base_irq; return; +#endif } } @@ -2219,7 +2221,6 @@ static device_config_t ne2000_config[] = static device_config_t rtl8029as_config[] = { -#if 0 { "irq", "IRQ", CONFIG_SELECTION, "", 10, { @@ -2243,7 +2244,6 @@ static device_config_t rtl8029as_config[] = } }, }, -#endif #if 1 /* * WTF. diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index a95a9a569..eaf475044 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -532,14 +532,16 @@ BuslogicLog(const char *format, ...) } #endif } -#define pclog BuslogicLog +/* #define pclog BuslogicLog */ static void BuslogicInterrupt(Buslogic_t *bl, int set) { +#if 0 if (bl->chip != CHIP_BUSLOGIC_PCI) { +#endif if (set) { picint(1 << bl->Irq); @@ -548,18 +550,20 @@ BuslogicInterrupt(Buslogic_t *bl, int set) { picintc(1 << bl->Irq); } +#if 0 } else { if (set) { - pci_set_irq(bl->Card, PCI_INTA); + pci_set_irq(bl->Card, PCI_INTD); } else { - pci_clear_irq(bl->Card, PCI_INTA); + pci_clear_irq(bl->Card, PCI_INTD); } } +#endif } @@ -1254,7 +1258,14 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) case 0x0B: bl->DataBuf[0] = (1 << bl->DmaChannel); - bl->DataBuf[1] = (1<<(bl->Irq-9)); + if ((bl->Irq >= 9) && (bl->Irq <= 15)) + { + bl->DataBuf[1] = (1<<(bl->Irq-9)); + } + else + bl->DataBuf[1] = 0; + { + } bl->DataBuf[2] = 7; /* HOST ID */ bl->DataReplyLeft = 3; break; @@ -2127,7 +2138,7 @@ BuslogicPCIRead(int func, int addr, void *p) case 0x3C: return bl->Irq; case 0x3D: - return 1; + return 4; } return(0); @@ -2138,16 +2149,17 @@ static void BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) { Buslogic_t *bl = (Buslogic_t *)p; + uint8_t valxor; switch (addr) { case 0x04: - io_removehandler(bl->PCIBase, 4, + valxor = (val & 0x27) ^ buslogic_pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) { + io_removehandler(bl->PCIBase, 4, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, BuslogicWriteW, BuslogicWriteL, bl); - mem_mapping_disable(&bl->mmio_mapping); - if (val & PCI_COMMAND_IO) { - if (bl->PCIBase != 0) { + if ((bl->PCIBase != 0) && (val & PCI_COMMAND_IO)) { io_sethandler(bl->PCIBase, 0x0020, BuslogicRead, BuslogicReadW, BuslogicReadL, BuslogicWrite, @@ -2155,13 +2167,14 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) bl); } } - if (val & PCI_COMMAND_MEM) { - if (bl->PCIBase != 0) { + if (valxor & PCI_COMMAND_MEM) { + mem_mapping_disable(&bl->mmio_mapping); + if ((bl->MMIOBase != 0) & (val & PCI_COMMAND_MEM)) { mem_mapping_set_addr(&bl->mmio_mapping, bl->MMIOBase, 0x20); } } - buslogic_pci_regs[addr] = val; + buslogic_pci_regs[addr] = val & 0x27; break; case 0x10: @@ -2215,6 +2228,7 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } return; +#if 0 case 0x3C: buslogic_pci_regs[addr] = val; if (val != 0xFF) { @@ -2222,6 +2236,7 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) bl->Irq = val; } return; +#endif } } @@ -2291,9 +2306,11 @@ BuslogicInit(int chip) buslogic_pci_bar[0].addr_regs[0] = 1; buslogic_pci_bar[1].addr_regs[0] = 0; - buslogic_pci_regs[0x04] = 1; + buslogic_pci_regs[0x04] = 3; +#if 0 buslogic_pci_regs[0x05] = 0; buslogic_pci_regs[0x07] = 2; +#endif buslogic_pci_bar[2].addr = 0; mem_mapping_add(&bl->mmio_mapping, 0xfffd0000, 0x20, From 383ec2c845920c1e56f30952890b4ed88f4a3908 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Jun 2017 18:03:47 +0200 Subject: [PATCH 283/392] Applied Sound Blaster mixer steps patch from James-F. --- src/SOUND/snd_sb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 688cb4cee..eebffbd8a 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -63,9 +63,9 @@ typedef struct sb_t static int sb_att[]= { - 310,368,437,520,618,735,873,1038,1234,1467,1743,2072,2463,2927,3479, - 4134,4914,5840,6941,8250,9805,11653,13850,16461,19564,23252,27635,32845, - 39036,46395,55140,65535 + 65,82,103,130,164,207,260,328,413,520,655,825,2463,1038,1307, + 1645,2072,2608,3283,4134,5205,6553,8250,10385,13075,16461,20724,26089, + 32845,41349,52055,65535 }; static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) From 142eac1368ee56fa1b82cdf838c090ff2d7f8900 Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 2 Jun 2017 14:11:53 -0400 Subject: [PATCH 284/392] Textual changes. --- src/net_ne2000.c | 5 ++--- src/scsi_buslogic.c | 16 ++++++---------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 9df7ac7ff..5c8f2c829 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -8,10 +8,9 @@ * * Implementation of an NE2000/RTL8029AS network controller. * - * NOTE: Its still a mess, but we're getting there. The file will - * also implement an NE1000 for 8-bit ISA systems. + * NOTE: The file will also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.8 2017/06/01 + * Version: @(#)net_ne2000.c 1.0.9 2017/06/02 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index eaf475044..207e8ea79 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -4,10 +4,13 @@ * PC systems and compatibles from 1981 through fairly recent * system designs based on the PCI bus. * - * Emulation of BusLogic BT-542B ISA and BT-958D PCI SCSI - * controllers. + * Emulation of BusLogic ISA and PCI SCSI controllers. Boards + * supported: * - * Version: @(#)scsi_buslogic.c 1.0.0 2017/05/30 + * 0 - BT-542B ISA; + * 1 - BT-958 PCI (but BT-542B ISA on non-PCI machines) + * + * Version: @(#)scsi_buslogic.c 1.0.2 2017/06/02 * * Author: TheCollector1995, * Miran Grca, @@ -16,13 +19,6 @@ * Copyright 2016-2017 Miran Grca. * Copyright 2017-2017 Fred N. van Kempen. */ - -/*Buslogic SCSI emulation*/ - -/* Emulated SCSI controllers: - 0 - BusLogic BT-542B ISA; - 1 - BusLogic BT-958 PCI (but BT-542B ISA on non-PCI machines). */ - #include #include #include From d4cadcdbdb982524bed24ab90833434709570507 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 2 Jun 2017 20:57:26 +0200 Subject: [PATCH 285/392] Fixed the Sound Blaster mixer scale, per new patch from James-F. --- src/SOUND/snd_sb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index eebffbd8a..25963e1a1 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -63,7 +63,7 @@ typedef struct sb_t static int sb_att[]= { - 65,82,103,130,164,207,260,328,413,520,655,825,2463,1038,1307, + 50,65,82,103,130,164,207,260,328,413,520,655,825,1038,1307, 1645,2072,2608,3283,4134,5205,6553,8250,10385,13075,16461,20724,26089, 32845,41349,52055,65535 }; From ec732312c3e5261bef339ea5116d0aa19bfb183b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 00:45:12 +0200 Subject: [PATCH 286/392] Implemented PCI interrupt controller ports 4D0 and 4D1; Applied more mainline PCem commits; Repplied the CPU optimization commit alongside the fix commit. --- src/CPU/386.c | 1 - src/CPU/386_common.h | 21 ++- src/CPU/386_dynarec.c | 44 +++++- src/CPU/386_ops.h | 23 +++- src/CPU/808x.c | 23 +++- src/CPU/codegen.h | 22 +-- src/CPU/codegen_ops_x86-64.h | 189 ++++++++++++++++++++----- src/CPU/codegen_ops_x86.h | 260 +++++++++++++++++++++++++++-------- src/CPU/codegen_x86-64.c | 8 +- src/CPU/codegen_x86.c | 7 +- src/CPU/cpu.c | 33 +++-- src/CPU/cpu.h | 25 +++- src/CPU/x86.h | 3 + src/CPU/x86_ops_misc.h | 47 +++++++ src/CPU/x86seg.c | 133 ++++++++++++++---- src/CPU/x86seg.h | 19 ++- src/CPU/x87_ops.h | 20 +++ src/CPU/x87_ops_loadstore.h | 18 +++ src/SOUND/snd_sb.c | 9 +- src/SOUND/snd_sb_dsp.c | 4 + src/WIN/win_ddraw.cc | 6 + src/i430vx.c | 8 +- src/ibm.h | 7 + src/pci.c | 43 +++++- src/piix.c | 9 +- src/scsi_buslogic.c | 2 +- 26 files changed, 807 insertions(+), 177 deletions(-) diff --git a/src/CPU/386.c b/src/CPU/386.c index 0422036b4..074fa9696 100644 --- a/src/CPU/386.c +++ b/src/CPU/386.c @@ -51,7 +51,6 @@ uint32_t cr2, cr3, cr4; uint32_t dr[8]; - uint8_t romext[32768]; uint8_t *ram,*rom; diff --git a/src/CPU/386_common.h b/src/CPU/386_common.h index a091a817d..6042cc151 100644 --- a/src/CPU/386_common.h +++ b/src/CPU/386_common.h @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Common 386 CPU code. + * + * Version: @(#)386_common.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + extern uint16_t ea_rseg; #undef readmemb diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 1463f844e..61db68737 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -21,6 +21,8 @@ #define CPU_BLOCK_END() cpu_block_end = 1 +uint32_t cpu_cur_status = 0; + int cpu_reps, cpu_reps_latched; int cpu_notreps, cpu_notreps_latched; @@ -1325,8 +1327,42 @@ void exec386_dynarec(int cycs) while (cycles_main > 0) { int cycles_start; - - cycles += cpu_cycle_period(); + +#if 0 + switch(cpu_pci_speed) + { + case 16000000: + cycles += 640; + break; + case 20000000: + cycles += 800; + break; + case 25000000: + default: + cycles += 1000; + break; + case 27500000: + cycles += 1100; + break; + case 30000000: + cycles += 1200; + break; + case 333333333: + cycles += 1333; + break; + case 37500000: + cycles += 1500; + break; + case 40000000: + cycles += 1600; + break; + case 41666667: + cycles += 1666; + break; + } +#endif + cycles += cpu_cycle_period(); + cycles_start = cycles; timer_start_period(cycles << TIMER_SHIFT); @@ -1405,7 +1441,7 @@ void exec386_dynarec(int cycs) and physical address. The physical address check will also catch any page faults at this stage*/ valid_block = (block->pc == cs + cpu_state.pc) && (block->_cs == cs) && - (block->use32 == use32) && (block->phys == phys_addr) && (block->stack32 == stack32); + (block->phys == phys_addr) && (block->status == cpu_cur_status); if (!valid_block) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); @@ -1417,7 +1453,7 @@ void exec386_dynarec(int cycs) if (new_block) { valid_block = (new_block->pc == cs + cpu_state.pc) && (new_block->_cs == cs) && - (new_block->use32 == use32) && (new_block->phys == phys_addr) && (new_block->stack32 == stack32); + (new_block->phys == phys_addr) && (new_block->status == cpu_cur_status); if (valid_block) block = new_block; } diff --git a/src/CPU/386_ops.h b/src/CPU/386_ops.h index 4e5d78125..0217c384d 100644 --- a/src/CPU/386_ops.h +++ b/src/CPU/386_ops.h @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 286/386+ instruction handlers list. + * + * Version: @(#)386_ops.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include "x86_ops.h" diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 5c48a4bb0..32a52e955 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x CPU emulation. + * + * Version: @(#)808x.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + /*SHR AX,1 4 clocks - fetch opcode @@ -552,6 +567,7 @@ void resetx86() resets++; ins = 0; use32=0; + cpu_cur_status = 0; stack32=0; cpu_state.pc=0; msw=0; @@ -589,6 +605,7 @@ void softresetx86() { use32=0; stack32=0; + cpu_cur_status = 0; cpu_state.pc=0; msw=0; cr0=0; diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index ad0b3f63a..5a076db8f 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -35,6 +35,9 @@ typedef struct codeblock_t { + uint64_t page_mask, page_mask2; + uint64_t cmp; + /*Previous and next pointers, for the codeblock list associated with each physical page. Two sets of pointers, as a codeblock can be present in two pages.*/ @@ -45,22 +48,19 @@ typedef struct codeblock_t fails.*/ struct codeblock_t *parent, *left, *right; + int pnt; + int ins; + + int was_recompiled; + int TOP; + uint32_t pc; uint32_t _cs; uint32_t endpc; uint32_t phys, phys_2; - uint32_t use32; - int stack32; - int pnt; - int ins; - uint64_t page_mask, page_mask2; - - int was_recompiled; + uint32_t status; uint32_t flags; - int TOP; - - uint64_t cmp; - + uint8_t data[2048]; } codeblock_t; diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index 8573ab495..f08db0b31 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -866,6 +866,8 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && codegen_flat_ds) + return; if (IS_32_ADDR(&seg->base)) { @@ -900,6 +902,8 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if ((seg == &_ds) && codegen_flat_ds) + return; if (IS_32_ADDR(&seg->base)) { @@ -926,6 +930,9 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + return; + if (IS_32_ADDR(&seg->base)) { addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ @@ -962,7 +969,12 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1030,7 +1042,12 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1114,7 +1131,12 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1190,7 +1212,12 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1309,7 +1336,12 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1388,7 +1420,12 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1478,7 +1515,12 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -1566,7 +1608,12 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5252,7 +5299,12 @@ static void MEM_CHECK_WRITE(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5299,12 +5351,15 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); - addbyte(0x74); /*JE slowpath*/ - jump3 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + jump3 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } if (IS_32_ADDR(writelookup2)) { addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ @@ -5328,7 +5383,8 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0); // addbyte(0xc3); /*RET*/ - *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; /*slowpath:*/ addbyte(0x67); /*LEA EDI, [EAX+ESI]*/ addbyte(0x8d); @@ -5373,7 +5429,12 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5416,15 +5477,21 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } addbyte(0x8d); /*LEA ESI, 1[EDI]*/ addbyte(0x77); addbyte(0x01); - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5475,7 +5542,8 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5510,7 +5578,12 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) CHECK_SEG_WRITE(seg); - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); @@ -5553,15 +5626,21 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - addbyte(0x83); /*CMP ESI, -1*/ - addbyte(0xfe); - addbyte(-1); + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xfe); + addbyte(-1); + } addbyte(0x8d); /*LEA ESI, 3[EDI]*/ addbyte(0x77); addbyte(0x03); - addbyte(0x74); /*JE slowpath*/ - jump4 = &codeblock[block_current].data[block_pos]; - addbyte(0); + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + { + addbyte(0x74); /*JE slowpath*/ + jump4 = &codeblock[block_current].data[block_pos]; + addbyte(0); + } addbyte(0x89); /*MOV EBX, EDI*/ addbyte(0xfb); addbyte(0xc1); /*SHR EDI, 12*/ @@ -5612,7 +5691,8 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) /*slowpath:*/ *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; + if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) + *jump4 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump4 - 1; jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); @@ -5642,7 +5722,12 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5709,7 +5794,12 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5785,7 +5875,12 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - if (IS_32_ADDR(&seg->base)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ECX, ECX*/ + addbyte(0xc9); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); @@ -5883,7 +5978,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -5955,7 +6056,13 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); @@ -6038,7 +6145,13 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if (IS_32_ADDR(&seg->base)) + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EBX, EBX*/ + addbyte(0xdb); + } + else if (IS_32_ADDR(&seg->base)) { addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h index c8c18a28c..5251884b7 100644 --- a/src/CPU/codegen_ops_x86.h +++ b/src/CPU/codegen_ops_x86.h @@ -616,6 +616,8 @@ static void CHECK_SEG_READ(x86seg *seg) return; if (seg->checked) return; + if (seg == &_ds && codegen_flat_ds) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -637,6 +639,8 @@ static void CHECK_SEG_WRITE(x86seg *seg) return; if (seg->checked) return; + if (seg == &_ds && codegen_flat_ds) + return; addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x05|0x38); @@ -650,6 +654,9 @@ static void CHECK_SEG_WRITE(x86seg *seg) } static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + return; + addbyte(0x3b); /*CMP EAX, seg->limit_low*/ addbyte(0x05); addlong((uint32_t)&seg->limit_low); @@ -675,9 +682,18 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) static void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || + ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_b*/ addlong(mem_load_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -685,9 +701,17 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) } static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_b_no_abrt*/ addlong(mem_load_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -697,9 +721,17 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w*/ addlong(mem_load_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -707,9 +739,17 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) } static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); @@ -720,9 +760,17 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) } static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_w_no_abrt*/ addlong(mem_load_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -732,9 +780,17 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) } static void MEM_LOAD_ADDR_EA_L(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_l*/ addlong(mem_load_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -743,9 +799,17 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) } static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_l_no_abrt*/ addlong(mem_load_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -756,9 +820,17 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { - addbyte(0x8b); /*MOVL EDX, seg->base*/ - addbyte(0x05 | (REG_EDX << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR EDX, EDX*/ + addbyte(0xd2); + } + else + { + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_load_addr_ea_q*/ addlong(mem_load_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); @@ -786,9 +858,17 @@ static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -799,9 +879,17 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -812,9 +900,17 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -825,9 +921,17 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -838,9 +942,17 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -851,9 +963,17 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) } static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } if (host_reg != REG_ECX) { addbyte(0x89); /*MOV ECX, host_reg*/ @@ -874,9 +994,17 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x89); /*MOV ECX, host_reg2*/ addbyte(0xc0 | REG_ECX | (host_reg2 << 3)); } - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_store_addr_ea_q*/ addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } @@ -3792,9 +3920,17 @@ static void LOAD_EA() static void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write*/ addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3802,9 +3938,17 @@ static void MEM_CHECK_WRITE(x86seg *seg) static void MEM_CHECK_WRITE_W(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write_w*/ addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); @@ -3812,9 +3956,17 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) static void MEM_CHECK_WRITE_L(x86seg *seg) { CHECK_SEG_WRITE(seg); - addbyte(0x8b); /*MOVL ESI, seg->base*/ - addbyte(0x05 | (REG_ESI << 3)); - addlong((uint32_t)&seg->base); + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + { + addbyte(0x31); /*XOR ESI, ESI*/ + addbyte(0xf6); + } + else + { + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + } addbyte(0xe8); /*CALL mem_check_write_l*/ addlong(mem_check_write_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index e591adc95..c5214bd4b 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -22,6 +22,7 @@ #endif +int codegen_flat_ds, codegen_flat_ss; int codegen_flags_changed = 0; int codegen_fpu_entered = 0; int codegen_fpu_loaded_iq[8]; @@ -274,13 +275,13 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; - block->use32 = use32; - block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = 0; + block->status = cpu_cur_status; + block->was_recompiled = 0; recomp_page = block->phys & ~0xfff; @@ -386,6 +387,9 @@ void codegen_block_start_recompile(codeblock_t *block) codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; block->was_recompiled = 1; + + codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; + codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; } void codegen_block_remove() diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index a42b32104..82b8e5575 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -22,6 +22,7 @@ #include #endif +int codegen_flat_ds, codegen_flat_ss; int mmx_ebx_ecx_loaded; int codegen_flags_changed = 0; int codegen_fpu_entered = 0; @@ -1401,12 +1402,11 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; - block->use32 = use32; - block->stack32 = stack32; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = CODEBLOCK_STATIC_TOP; + block->status = cpu_cur_status; block->was_recompiled = 0; @@ -1487,6 +1487,9 @@ void codegen_block_start_recompile(codeblock_t *block) block->TOP = cpu_state.TOP; block->was_recompiled = 1; + + codegen_flat_ds = cpu_cur_status & CPU_STATUS_FLATDS; + codegen_flat_ss = cpu_cur_status & CPU_STATUS_FLATSS; } void codegen_block_remove() diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index a55e7e86e..cbb7161fb 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * Version: @(#)cpu.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include "../ibm.h" #include "cpu.h" #include "../model.h" @@ -74,7 +91,6 @@ int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; -int cpu_pci_speed; int hasfpu; @@ -84,6 +100,7 @@ int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_write_l; int cpu_prefetch_cycles, cpu_prefetch_width; int cpu_waitstates; int cpu_cache_int_enabled, cpu_cache_ext_enabled; +int cpu_pci_speed; int is286, is386; int israpidcad, is_pentium; @@ -408,7 +425,7 @@ CPU cpus_Cx486[] = {"6x86MX-PR300", CPU_Cx6x86MX, 18, 233333333, 3, 33333333, 0x600, 0x600, 0x0454, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 21,21,7,7}, {"6x86MX-PR333", CPU_Cx6x86MX, 18, 250000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 20,20,9,9}, {"6x86MX-PR366", CPU_Cx6x86MX, 18, 250000000, 3, 33333333, 0x600, 0x600, 0x0452, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 24,24,12,12}, - {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 31666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, + {"6x86MX-PR400", CPU_Cx6x86MX, 18, 285000000, 3, 41666667, 0x600, 0x600, 0x0453, CPU_SUPPORTS_DYNAREC | CPU_REQUIRES_DYNAREC, 18,18,9,9}, {"", -1, 0, 0, 0} }; @@ -609,7 +626,6 @@ void cpu_set() if (cpu_s->multi) cpu_busspeed = cpu_s->rspeed / cpu_s->multi; cpu_multi = cpu_s->multi; - cpu_pci_speed = cpu_s->pci_speed; cpu_hasrdtsc = 0; cpu_hasMMX = 0; cpu_hasMSR = 0; @@ -621,11 +637,6 @@ void cpu_set() if (enable_external_fpu) { hasfpu = 1; - if (cpu_s->cpu_type == CPU_i486SX) - { - /* The 487SX is a full implementation of the 486DX and takes over the entire CPU's operation. */ - cpu_s->cpu_type = CPU_i486DX; - } } } diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index d8d24b27a..ce0955b7f 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -1,6 +1,23 @@ -/* Copyright holders: Sarah Walker, Tenshi, leilei - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * CPU type handler. + * + * Version: @(#)cpu.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #ifndef _CPU_H_ #define _CPU_H_ @@ -117,7 +134,6 @@ extern int cpu_iscyrix; extern int cpu_16bitbus; extern int cpu_busspeed; extern int cpu_multi; -extern int cpu_pci_speed; extern int cpu_hasrdtsc; extern int cpu_hasMSR; @@ -139,6 +155,7 @@ extern int cpu_cycles_read, cpu_cycles_read_l, cpu_cycles_write, cpu_cycles_writ extern int cpu_prefetch_cycles, cpu_prefetch_width; extern int cpu_waitstates; extern int cpu_cache_int_enabled, cpu_cache_ext_enabled; +extern int cpu_pci_speed; extern uint64_t tsc; diff --git a/src/CPU/x86.h b/src/CPU/x86.h index 565d52591..deb210cb6 100644 --- a/src/CPU/x86.h +++ b/src/CPU/x86.h @@ -102,3 +102,6 @@ void x86gpf(char *s, uint16_t error); extern uint16_t zero; extern int x86_was_reset; + +extern int codegen_flat_ds; +extern int codegen_flat_ss; diff --git a/src/CPU/x86_ops_misc.h b/src/CPU/x86_ops_misc.h index a2b4f6f31..7734217eb 100644 --- a/src/CPU/x86_ops_misc.h +++ b/src/CPU/x86_ops_misc.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Miscellaneous x86 CPU Instructions. + * + * Version: @(#)x86_ops_misc.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + static int opCBW(uint32_t fetchdat) { AH = (AL & 0x80) ? 0xff : 0; @@ -755,9 +773,17 @@ static int opLOADALL(uint32_t fetchdat) ss = readmemw(0, 0x842) | (readmemb(0, 0x844) << 16); _ss.access = readmemb(0, 0x845); _ss.limit = readmemw(0, 0x846); + if (_ss.base == 0 && _ss.limit_low == 0 && _ss.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; ds = readmemw(0, 0x848) | (readmemb(0, 0x84A) << 16); _ds.access = readmemb(0, 0x84B); _ds.limit = readmemw(0, 0x84C); + if (_ds.base == 0 && _ds.limit_low == 0 && _ds.limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; gdt.base = readmemw(0, 0x84E) | (readmemb(0, 0x850) << 16); gdt.limit = readmemw(0, 0x852); ldt.base = readmemw(0, 0x854) | (readmemb(0, 0x856) << 16); @@ -797,8 +823,29 @@ static void loadall_load_segment(uint32_t addr, x86seg *s) if (s == &_cs) use32 = (segdat3 & 0x40) ? 0x300 : 0; if (s == &_ss) stack32 = (segdat3 & 0x40) ? 1 : 0; + cpu_cur_status &= ~(CPU_STATUS_USE32 | CPU_STATUS_STACK32); + if (use32) + cpu_cur_status |= CPU_STATUS_USE32; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; set_segment_limit(s, segdat3); + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } static int opLOADALL386(uint32_t fetchdat) diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index cc0cc6dbc..c200b3121 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -1,6 +1,21 @@ -/* Copyright holders: Sarah Walker, SA1988 - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 CPU segment emulation. + * + * Version: @(#)x86seg.c 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + #include #include #include @@ -159,6 +174,29 @@ void x86np(char *s, uint16_t error) } +static void set_stack32(int s) +{ + stack32 = s; + if (stack32) + cpu_cur_status |= CPU_STATUS_STACK32; + else + cpu_cur_status &= ~CPU_STATUS_STACK32; +} + +static void set_use32(int u) +{ + if (u) + { + use32 = 0x300; + cpu_cur_status |= CPU_STATUS_USE32; + } + else + { + use32 = 0; + cpu_cur_status &= ~CPU_STATUS_USE32; + } +} + void do_seg_load(x86seg *s, uint16_t *segdat) { s->limit = segdat[0] | ((segdat[3] & 0xF) << 16); @@ -179,6 +217,21 @@ void do_seg_load(x86seg *s, uint16_t *segdat) s->limit_high = (segdat[3] & 0x40) ? 0xffffffff : 0xffff; s->limit_low = s->limit + 1; } + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; + } } static void do_seg_v86_init(x86seg *s) @@ -251,6 +304,8 @@ void loadseg(uint16_t seg, x86seg *s) s->seg=0; s->access = 0x80; s->base=-1; + if (s == &_ds) + cpu_cur_status &= ~CPU_STATUS_FLATDS; return; } addr=seg&~7; @@ -303,7 +358,7 @@ void loadseg(uint16_t seg, x86seg *s) x86ss(NULL,seg&~3); return; } - stack32 = (segdat[3] & 0x40) ? 1 : 0; + set_stack32((segdat[3] & 0x40) ? 1 : 0); } else if (s!=&_cs) { @@ -349,6 +404,10 @@ void loadseg(uint16_t seg, x86seg *s) } #endif s->checked = 0; + if (s == &_ds) + codegen_flat_ds = 0; + if (s == &_ss) + codegen_flat_ss = 0; } else { @@ -358,6 +417,26 @@ void loadseg(uint16_t seg, x86seg *s) if (s == &_ss) stack32 = 0; s->checked = 1; + if (s == &_ds) + codegen_flat_ds = 0; + if (s == &_ss) + codegen_flat_ss = 0; + } + + if (s == &_ds) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATDS; + else + + cpu_cur_status &= ~CPU_STATUS_FLATDS; + } + if (s == &_ss) + { + if (s->base == 0 && s->limit_low == 0 && s->limit_high == 0xffffffff) + cpu_cur_status |= CPU_STATUS_FLATSS; + else + cpu_cur_status &= ~CPU_STATUS_FLATSS; } } @@ -426,8 +505,7 @@ void loadcs(uint16_t seg) x86np("Load CS not present", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3] & 0x40); CS=(seg&~3)|CPL; do_seg_load(&_cs, segdat); use32=(segdat[3]&0x40)?0x300:0; @@ -530,8 +608,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) x86np("Load CS JMP not present\n", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -544,7 +621,6 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; cycles -= timing_jmp_pm; } else /*System segment*/ @@ -642,8 +718,8 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - cpu_state.pc=newpc; + set_use32(segdat[3]&0x40); + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -828,8 +904,7 @@ void loadcscall(uint16_t seg) x86np("Load CS call not present", seg & 0xfffc); return; } - if (segdat[3]&0x40) use32=0x300; - else use32=0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -848,7 +923,6 @@ void loadcscall(uint16_t seg) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; if (csout) pclog("Complete\n"); cycles -= timing_call_pm; } @@ -1005,7 +1079,7 @@ void loadcscall(uint16_t seg) } if (!stack32) oldsp &= 0xFFFF; SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; @@ -1022,7 +1096,7 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3]&0x40); cpu_state.pc=newpc; if (output) pclog("Set access 2\n"); @@ -1101,8 +1175,8 @@ void loadcscall(uint16_t seg) CS=seg2; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - cpu_state.pc=newpc; + set_use32(segdat[3]&0x40); + cpu_state.pc=newpc; #ifdef CS_ACCESSED cpl_override = 1; @@ -1245,8 +1319,8 @@ void pmoderetf(int is32, uint16_t off) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; - + set_use32(segdat[3] & 0x40); + cycles -= timing_retf_pm; } else @@ -1353,7 +1427,7 @@ void pmoderetf(int is32, uint16_t off) return; } SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -1375,7 +1449,7 @@ void pmoderetf(int is32, uint16_t off) CS=seg; do_seg_load(&_cs, segdat); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3] & 0x40); if (stack32) ESP+=off; else SP+=off; @@ -1570,7 +1644,7 @@ void pmodeint(int num, int soft) return; } SS=newss; - stack32 = (segdat3[3] & 0x40) ? 1 : 0; + set_stack32((segdat3[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat3); @@ -1655,7 +1729,7 @@ void pmodeint(int num, int soft) if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); if (type>0x800) cpu_state.pc=segdat[0]|(segdat[3]<<16); else cpu_state.pc=segdat[0]; - use32=(segdat2[3]&0x40)?0x300:0; + set_use32(segdat2[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -1809,6 +1883,7 @@ void pmodeiret(int is32) do_seg_v86_init(&_es); loadseg(segs[1],&_ds); do_seg_v86_init(&_ds); + cpu_cur_status &= ~CPU_STATUS_FLATDS; loadseg(segs[2],&_fs); do_seg_v86_init(&_fs); loadseg(segs[3],&_gs); @@ -1826,7 +1901,9 @@ void pmodeiret(int is32) ESP=newsp; loadseg(newss,&_ss); do_seg_v86_init(&_ss); + cpu_cur_status &= ~CPU_STATUS_FLATSS; use32=0; + cpu_cur_status &= ~CPU_STATUS_USE32; flags=(tempflags&0xFFD5)|2; cycles -= timing_iret_v86; return; @@ -1913,7 +1990,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3]&0x40); #ifdef CS_ACCESSED cpl_override = 1; @@ -1996,7 +2073,7 @@ void pmodeiret(int is32) return; } SS=newss; - stack32 = (segdat2[3] & 0x40) ? 1 : 0; + set_stack32((segdat2[3] & 0x40) ? 1 : 0); if (stack32) ESP=newsp; else SP=newsp; do_seg_load(&_ss, segdat2); @@ -2018,7 +2095,7 @@ void pmodeiret(int is32) do_seg_load(&_cs, segdat); _cs.access = (_cs.access & ~(3 << 5)) | ((CS & 3) << 5); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat[3]&0x40)?0x300:0; + set_use32(segdat[3] & 0x40); check_seg_valid(&_ds); check_seg_valid(&_es); @@ -2208,7 +2285,7 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) CS=new_cs; do_seg_load(&_cs, segdat2); if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); - use32=(segdat2[3]&0x40)?0x300:0; + set_use32(segdat2[3] & 0x40); EAX=new_eax; ECX=new_ecx; diff --git a/src/CPU/x86seg.h b/src/CPU/x86seg.h index 4a36f360b..f4badadf4 100644 --- a/src/CPU/x86seg.h +++ b/src/CPU/x86seg.h @@ -1,4 +1,17 @@ -/* Copyright holders: Tenshi - see COPYING for more details -*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x86 CPU segment emulation. + * + * Version: @(#)x86seg.h 1.0.0 2017/05/30 + * + * Author: Miran Grca, + * Copyright 2016-2017 Miran Grca. + */ + void do_seg_load(x86seg *s, uint16_t *segdat); diff --git a/src/CPU/x87_ops.h b/src/CPU/x87_ops.h index e212c6ccb..b9320081f 100644 --- a/src/CPU/x87_ops.h +++ b/src/CPU/x87_ops.h @@ -1,3 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * leilei, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 leilei. + * Copyright 2016-2017 Miran Grca. + */ + #include #include diff --git a/src/CPU/x87_ops_loadstore.h b/src/CPU/x87_ops_loadstore.h index ed083b921..39a14c4fb 100644 --- a/src/CPU/x87_ops_loadstore.h +++ b/src/CPU/x87_ops_loadstore.h @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * x87 FPU instructions core. + * + * Version: @(#)x87_ops_loadstore.h 1.0.0 2017/05/30 + * + * Author: Sarah Walker, + * Miran Grca, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ + static int opFILDiw_a16(uint32_t fetchdat) { int16_t temp; diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 25963e1a1..8f310d9af 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -265,7 +265,14 @@ uint8_t sb_pro_mixer_read(uint16_t addr, void *p) if (!(addr & 1)) return mixer->index; - return mixer->regs[mixer->index]; + switch (mixer->index) + { + case 0x00: case 0x04: case 0x0a: case 0x0c: case 0x0e: + case 0x22: case 0x26: case 0x28: case 0x2e: + return mixer->regs[mixer->index]; + } + + return 0xff; } void sb_16_mixer_write(uint16_t addr, uint8_t val, void *p) diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 8c6f4a036..ba4e556f0 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -514,6 +514,10 @@ void sb_exec_command(sb_dsp_t *dsp) if (dsp->sb_type < SB16) break; sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); break; + case 0xF8: + if (dsp->sb_type < SB16) break; + sb_add_data(dsp, 0); + break; case 0xF9: if (dsp->sb_type < SB16) break; if (dsp->sb_data[0] == 0x0e) sb_add_data(dsp, 0xff); diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc index c5c111734..dc111bab1 100644 --- a/src/WIN/win_ddraw.cc +++ b/src/WIN/win_ddraw.cc @@ -137,6 +137,12 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) return; /*Nothing to do*/ } + if (h <= 0) + { + video_blit_complete(); + return; + } + memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); diff --git a/src/i430vx.c b/src/i430vx.c index bbe88865c..be47835fa 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -8,7 +8,7 @@ * * Implementation of the Intel 430VX PCISet chip. * - * Version: @(#)i430vx.c 1.0.0 2017/05/30 + * Version: @(#)i430vx.c 1.0.1 2017/06/02 * * Author: Sarah Walker, * Miran Grca, @@ -84,7 +84,7 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) i430vx_map(0xf0000, 0x10000, val >> 4); shadowbios = (val & 0x10); } - pclog("i430vx_write : PAM0 write %02X\n", val); + /* pclog("i430vx_write : PAM0 write %02X\n", val); */ break; case 0x5a: /*PAM1*/ if ((card_i430vx[0x5a] ^ val) & 0x0f) @@ -115,14 +115,14 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) i430vx_map(0xe0000, 0x04000, val & 0xf); if ((card_i430vx[0x5e] ^ val) & 0xf0) i430vx_map(0xe4000, 0x04000, val >> 4); - pclog("i430vx_write : PAM5 write %02X\n", val); + /* pclog("i430vx_write : PAM5 write %02X\n", val); */ break; case 0x5f: /*PAM6*/ if ((card_i430vx[0x5f] ^ val) & 0x0f) i430vx_map(0xe8000, 0x04000, val & 0xf); if ((card_i430vx[0x5f] ^ val) & 0xf0) i430vx_map(0xec000, 0x04000, val >> 4); - pclog("i430vx_write : PAM6 write %02X\n", val); + /* pclog("i430vx_write : PAM6 write %02X\n", val); */ break; } diff --git a/src/ibm.h b/src/ibm.h index 99e02db34..e2f9c8de5 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -177,6 +177,13 @@ struct #define cycles cpu_state._cycles +extern uint32_t cpu_cur_status; + +#define CPU_STATUS_USE32 (1 << 0) +#define CPU_STATUS_STACK32 (1 << 1) +#define CPU_STATUS_FLATDS (1 << 2) +#define CPU_STATUS_FLATSS (1 << 3) + #define cpu_rm cpu_state.rm_data.rm_mod_reg.rm #define cpu_mod cpu_state.rm_data.rm_mod_reg.mod #define cpu_reg cpu_state.rm_data.rm_mod_reg.reg diff --git a/src/pci.c b/src/pci.c index 022286669..f56c3de85 100644 --- a/src/pci.c +++ b/src/pci.c @@ -61,6 +61,20 @@ uint8_t pci_read(uint16_t port, void *priv) return 0xff; } +uint8_t elcr[2] = { 0, 0 }; + +void elcr_write(uint16_t port, uint8_t val, void *priv) +{ + pclog("ELCR%i: WRITE %02X\n", port & 1, val); + elcr[port & 1] = val; +} + +uint8_t elcr_read(uint16_t port, void *priv) +{ + pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); + return elcr[port & 1]; +} + void pci_type2_write(uint16_t port, uint8_t val, void *priv); uint8_t pci_type2_read(uint16_t port, void *priv); @@ -120,13 +134,38 @@ void pci_set_card_routing(int card, int pci_int) pci_irq_routing[card] = pci_int; } +void pci_issue_irq(int irq) +{ + int real_irq = irq & 7; + int irq_elcr = 0; + + if (irq > 7) + { + irq_elcr = elcr[1] & (1 << real_irq); + } + else + { + irq_elcr = elcr[0] & (1 << real_irq); + } + + if (irq_elcr) + { + picintlevel(1 << irq); + } + else + { + picint(1 << irq); + } +} + void pci_set_irq(int card, int pci_int) { if (pci_irq_routing[card]) { int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) - picint(1 << pci_irqs[irq]); + pci_issue_irq(pci_irqs[irq]); + /* picint(1 << pci_irqs[irq]); */ pci_irq_active[card] = 1; } } @@ -147,6 +186,8 @@ void pci_init(int type) int c; PCI = 1; + + io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL); if (type == PCI_CONFIG_TYPE_1) { diff --git a/src/piix.c b/src/piix.c index f2a38bf46..584f1ccc3 100644 --- a/src/piix.c +++ b/src/piix.c @@ -107,7 +107,8 @@ void piix_write(int func, int addr, uint8_t val, void *priv) } else { - if (addr >= 0x0f && addr < 0x4c) + /* pclog("PIIX writing value %02X to register %02X\n", val, addr); */ + if ((addr >= 0x0f) && (addr < 0x4c)) return; switch (addr) @@ -118,24 +119,28 @@ void piix_write(int func, int addr, uint8_t val, void *priv) return; case 0x60: + pclog("Set IRQ routing: INT A -> %02X\n", val); if (val & 0x80) pci_set_irq_routing(PCI_INTA, PCI_IRQ_DISABLED); else pci_set_irq_routing(PCI_INTA, val & 0xf); break; case 0x61: + pclog("Set IRQ routing: INT B -> %02X\n", val); if (val & 0x80) pci_set_irq_routing(PCI_INTB, PCI_IRQ_DISABLED); else pci_set_irq_routing(PCI_INTB, val & 0xf); break; case 0x62: + pclog("Set IRQ routing: INT C -> %02X\n", val); if (val & 0x80) pci_set_irq_routing(PCI_INTC, PCI_IRQ_DISABLED); else pci_set_irq_routing(PCI_INTC, val & 0xf); break; case 0x63: + pclog("Set IRQ routing: INT D -> %02X\n", val); if (val & 0x80) pci_set_irq_routing(PCI_INTD, PCI_IRQ_DISABLED); else @@ -632,7 +637,6 @@ void piix_reset(void) card_piix_ide[0x0d] = 0x00; card_piix_ide[0x0e] = 0x00; card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ - card_piix_ide[0x3c] = 14; /* Default IRQ */ card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; } @@ -672,7 +676,6 @@ void piix3_reset(void) card_piix_ide[0x0d] = 0x00; card_piix_ide[0x0e] = 0x00; card_piix_ide[0x20] = 0x01; card_piix_ide[0x21] = card_piix_ide[0x22] = card_piix_ide[0x23] = 0x00; /*Bus master interface base address*/ - card_piix_ide[0x3c] = 14; /* Default IRQ */ card_piix_ide[0x40] = card_piix_ide[0x41] = 0x00; card_piix_ide[0x42] = card_piix_ide[0x43] = 0x00; card_piix_ide[0x44] = 0x00; diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 207e8ea79..610bc39e4 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -528,7 +528,7 @@ BuslogicLog(const char *format, ...) } #endif } -/* #define pclog BuslogicLog */ +#define pclog BuslogicLog static void From 31a9b25465c6ac6568a77d274ffeb0f5d1370668 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 02:11:36 +0200 Subject: [PATCH 287/392] The sbTips array is now set to all 0's on initialization so that the functions to create tips no longer mistakenly think the pointers are non-null due to unpredictable data, should get rid of the start/setting changes crashes. --- src/WIN/win.c | 1 + src/pci.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index fe7e8fcd9..c7dbdabe7 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1088,6 +1088,7 @@ void update_status_bar_panes(HWND hwnds) memset(sb_part_icons, 0, sb_parts * sizeof(int)); memset(sb_icon_flags, 0, sb_parts * sizeof(int)); memset(sb_menu_handles, 0, sb_parts * sizeof(HMENU)); + memset(sbTips, 0, sb_parts * sizeof(WCHAR *)); sb_parts = 0; diff --git a/src/pci.c b/src/pci.c index f56c3de85..b48ac2072 100644 --- a/src/pci.c +++ b/src/pci.c @@ -65,13 +65,13 @@ uint8_t elcr[2] = { 0, 0 }; void elcr_write(uint16_t port, uint8_t val, void *priv) { - pclog("ELCR%i: WRITE %02X\n", port & 1, val); + /* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */ elcr[port & 1] = val; } uint8_t elcr_read(uint16_t port, void *priv) { - pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); + /* pclog("ELCR%i: READ %02X\n", port & 1, elcr[port & 1]); */ return elcr[port & 1]; } From d159eb26cb9abbeb21538f19c6125dbac99870bf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 02:16:59 +0200 Subject: [PATCH 288/392] The serial code now uses its own logger rather than pclog. --- src/serial.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/serial.c b/src/serial.c index ae376960a..1e0f2b0bc 100644 --- a/src/serial.c +++ b/src/serial.c @@ -140,6 +140,23 @@ static SERIAL serial1, /* serial port 1 data */ serial2; /* serial port 2 data */ +int serial_do_log = 0; + +void serial_log(const char *format, ...) +{ +#ifdef ENABLE_SERIAL_LOG + if (serial_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + + static void update_ints(SERIAL *sp) { @@ -239,7 +256,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) long speed; #if 0 - pclog("Serial%d: write(%04x, %02x)\n", sp->port, addr, val); + serial_log("Serial%d: write(%04x, %02x)\n", sp->port, addr, val); #endif switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ @@ -289,14 +306,14 @@ serial_write(uint16_t addr, uint8_t val, void *priv) if (baud > 0) { speed = 115200UL/baud; #if 0 - pclog("Serial%d: divisor %u, baudrate %ld\n", + serial_log("Serial%d: divisor %u, baudrate %ld\n", sp->port, baud, speed); #endif if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); #if 0 } else { - pclog("Serial%d: divisor %u invalid!\n", + serial_log("Serial%d: divisor %u invalid!\n", sp->port, baud); #endif } @@ -305,7 +322,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; #if 0 - pclog("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); + serial_log("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); #endif if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); @@ -323,7 +340,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) if (sp->rts_callback) { sp->rts_callback(sp->rts_callback_p); #if 0 - pclog("RTS raised; sending ID\n"); + serial_log("RTS raised; sending ID\n"); #endif } } @@ -338,7 +355,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) &sp->receive_delay, &sp->receive_delay, sp); #if 0 - pclog("Serial%d: RX timer started!\n",sp->port); + serial_log("Serial%d: RX timer started!\n",sp->port); #endif } } @@ -395,7 +412,7 @@ serial_rd_done(void *arg, int num) { SERIAL *sp = (SERIAL *)arg; #if 0 -pclog("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); +serial_log("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); #endif /* Stuff the byte in the FIFO and set intr. */ @@ -490,7 +507,7 @@ serial_setup(int port, uint16_t addr, int irq) { SERIAL *sp; - pclog("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); + serial_log("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); /* Grab the desired port block. */ sp = (port == 2) ? &serial2 : &serial1; @@ -594,14 +611,14 @@ serial_link(int port, char *arg) if (arg != NULL) { /* Make sure we're not already linked. */ if (sp->bh != NULL) { - pclog("Serial%d already linked!\n", port); + serial_log("Serial%d already linked!\n", port); return(-1); } /* Request a port from the host system. */ bh = bhtty_open(arg, 0); if (bh == NULL) { - pclog("Serial%d unable to link to '%s' !\n", port, arg); + serial_log("Serial%d unable to link to '%s' !\n", port, arg); return(-1); } sp->bh = bh; From e28bf400f592a98f522f59fcf26aaac1a5301642 Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 3 Jun 2017 01:05:47 -0400 Subject: [PATCH 289/392] Updates. --- src/mouse_bus.c | 10 +++---- src/serial.c | 69 +++++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 39 deletions(-) diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 5d5d5e97e..32063bfb0 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -32,7 +32,7 @@ * Based on an early driver for MINIX 1.5. * Based on the 86Box PS/2 mouse driver as a framework. * - * Version: @(#)mouse_bus.c 1.0.4 2017/05/17 + * Version: @(#)mouse_bus.c 1.0.5 2017/06/02 * * Author: Fred N. van Kempen, * Copyright 1989-2017 Fred N. van Kempen. @@ -108,7 +108,7 @@ typedef struct { static void ms_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { -#if 1 +#if 0 pclog("BUSMOUSE: ms_write(%d,%02x)\n", port, val); #endif @@ -151,7 +151,7 @@ lt_write(mouse_bus_t *ms, uint16_t port, uint8_t val) { uint8_t b = (ms->r_ctrl ^ val); -#if 1 +#if 0 pclog("BUSMOUSE: lt_write(%d,%02x)\n", port, val); #endif @@ -248,7 +248,7 @@ ms_read(mouse_bus_t *ms, uint16_t port) break; } -#if 1 +#if 0 pclog("BUSMOUSE: ms_read(%d): %02x\n", port, r); #endif @@ -367,7 +367,7 @@ lt_read(mouse_bus_t *ms, uint16_t port) break; } -#if 1 +#if 0 pclog("BUSMOUSE: lt_read(%d): %02x\n", port, r); #endif diff --git a/src/serial.c b/src/serial.c index 1e0f2b0bc..bed3e1a62 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,11 +33,12 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.5 2017/05/17 + * Version: @(#)serial.c 1.0.6 2017/06/02 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. */ +#include #include "ibm.h" #include "io.h" #include "pic.h" @@ -46,6 +47,11 @@ #include "plat_serial.h" +#ifdef WALTJE +# define ENABLE_SERIAL_LOG 2 +#endif + + enum { SERINT_LSR = 1, SERINT_RECEIVE = 2, @@ -138,21 +144,25 @@ enum { static SERIAL serial1, /* serial port 1 data */ serial2; /* serial port 2 data */ +#if ENABLE_SERIAL_LOG +static int serial_do_log = ENABLE_SERIAL_LOG; +#else +static int serial_do_log = 0; +#endif -int serial_do_log = 0; - -void serial_log(const char *format, ...) +static void +serial_log(int lvl, const char *fmt, ...) { #ifdef ENABLE_SERIAL_LOG - if (serial_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } + va_list ap; + + if (serial_do_log >= lvl) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); + } #endif } @@ -256,7 +266,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) long speed; #if 0 - serial_log("Serial%d: write(%04x, %02x)\n", sp->port, addr, val); + serial_log(2, "Serial%d: write(%04x, %02x)\n", sp->port, addr, val); #endif switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ @@ -305,25 +315,19 @@ serial_write(uint16_t addr, uint8_t val, void *priv) baud = ((sp->dlab2<<8) | sp->dlab1); if (baud > 0) { speed = 115200UL/baud; -#if 0 - serial_log("Serial%d: divisor %u, baudrate %ld\n", + serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", sp->port, baud, speed); -#endif if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); -#if 0 } else { - serial_log("Serial%d: divisor %u invalid!\n", + serial_log(1, "Serial%d: divisor %u invalid!\n", sp->port, baud); -#endif } } wl = (val & LCR_WLS) + 5; /* databits */ sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; -#if 0 - serial_log("Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); -#endif + serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); sp->lcr = val; @@ -339,9 +343,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) */ if (sp->rts_callback) { sp->rts_callback(sp->rts_callback_p); -#if 0 - serial_log("RTS raised; sending ID\n"); -#endif + serial_log(1, "RTS raised; sending ID\n"); } } @@ -354,9 +356,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) timer_add(serial_timer, &sp->receive_delay, &sp->receive_delay, sp); -#if 0 - serial_log("Serial%d: RX timer started!\n",sp->port); -#endif + serial_log(1, "Serial%d: RX timer started!\n",sp->port); } } sp->mctrl = val; @@ -411,9 +411,7 @@ static void serial_rd_done(void *arg, int num) { SERIAL *sp = (SERIAL *)arg; -#if 0 -serial_log("%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); -#endif +serial_log(0, "%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); /* Stuff the byte in the FIFO and set intr. */ serial_write_fifo(sp, sp->hold); @@ -507,7 +505,7 @@ serial_setup(int port, uint16_t addr, int irq) { SERIAL *sp; - serial_log("Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); + serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); /* Grab the desired port block. */ sp = (port == 2) ? &serial2 : &serial1; @@ -575,6 +573,9 @@ serial_init(void) memset(&serial1, 0x00, sizeof(SERIAL)); serial1.port = 1; serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); +#ifdef WALTJE + serial_link(1, "COM2"); +#endif memset(&serial2, 0x00, sizeof(SERIAL)); serial2.port = 2; @@ -611,14 +612,14 @@ serial_link(int port, char *arg) if (arg != NULL) { /* Make sure we're not already linked. */ if (sp->bh != NULL) { - serial_log("Serial%d already linked!\n", port); + serial_log(0, "Serial%d already linked!\n", port); return(-1); } /* Request a port from the host system. */ bh = bhtty_open(arg, 0); if (bh == NULL) { - serial_log("Serial%d unable to link to '%s' !\n", port, arg); + serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); return(-1); } sp->bh = bh; From 197aa051cf45b69a7a1b888b69aa73bb31a31479 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 14:24:19 +0200 Subject: [PATCH 290/392] Adjusted volume for DOSBox OPL. --- src/Makefile.mingw | 3 +++ src/SOUND/snd_sb.c | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index e716ff206..5593f9651 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -45,6 +45,9 @@ endif ifndef X64 X64 = n endif +ifndef RELEASE +RELEASE = n +endif ######################################################################### diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 8f310d9af..f6e773fe8 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -81,8 +81,8 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 47000) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 47000) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 55000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 55000) >> 16); if (sb->mixer.filter) { @@ -132,8 +132,8 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 47000) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 47000) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (opl3_type ? 47000 : 55000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (opl3_type ? 47000 : 55000)) >> 16); if (sb->mixer.filter) { From 42ffa5b9d24bd13b921d02d7facfdcd6c8686b9c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 14:34:32 +0200 Subject: [PATCH 291/392] Added a header so that snd_sb.c compiles correctly again; Fixed a bug in snd_dopl.cc. --- src/SOUND/snd_dbopl.cc | 2 +- src/SOUND/snd_sb.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SOUND/snd_dbopl.cc b/src/SOUND/snd_dbopl.cc index cecc1c35e..cf4bc1ebe 100644 --- a/src/SOUND/snd_dbopl.cc +++ b/src/SOUND/snd_dbopl.cc @@ -88,7 +88,7 @@ void opl_write(int nr, uint16_t addr, uint8_t val) if (!(addr & 1)) { if (!opl[nr].is_opl3 || !opl3_type) - opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & 0xff; + opl[nr].addr = (int)opl[nr].chip.WriteAddr(addr, val) & (opl[nr].is_opl3 ? 0x1ff : 0xff); else opl[nr].addr = (int)OPL3_WriteAddr(&opl[nr].opl3chip, addr, val) & 0x1ff; } diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index f6e773fe8..5e38a1437 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -26,6 +26,7 @@ #include "../rom.h" #include "../device.h" #include "sound.h" +#include "snd_dbopl.h" #include "snd_emu8k.h" #include "snd_mpu401.h" #include "snd_opl.h" From 8151f47135c06dc1e6a079ef83d51254e310aaf3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 16:03:27 +0200 Subject: [PATCH 292/392] All PCI boards now use the *correct* PCI slots; The SMC FDC37C665 Super I/O chip's IDE handler now does nothing for the PC Paternet MB500N as well, fixes the problem of its BIOS not detecting hard disks; DOSBox OPL volume changed from 55000 to 51000 per patch from James-F. --- src/SOUND/snd_sb.c | 8 ++-- src/fdc37c665.c | 2 +- src/model.c | 96 +++++++++++++++++++++++----------------------- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 5e38a1437..179a449ee 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -82,8 +82,8 @@ static void sb_get_buffer_opl2(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 55000) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 55000) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * 51000) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * 51000) >> 16); if (sb->mixer.filter) { @@ -133,8 +133,8 @@ static void sb_get_buffer_opl3(int32_t *buffer, int len, void *p) { int32_t out_l, out_r; - out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (opl3_type ? 47000 : 55000)) >> 16); - out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (opl3_type ? 47000 : 55000)) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (opl3_type ? 47000 : 51000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (opl3_type ? 47000 : 51000)) >> 16); if (sb->mixer.filter) { diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 7cc5889ce..00a80c429 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -46,7 +46,7 @@ static void write_lock(uint8_t val) static void ide_handler() { uint16_t or_value = 0; - if ((romset == ROM_440FX) || (romset == ROM_R418)) + if ((romset == ROM_440FX) || (romset == ROM_R418) || (romset == ROM_MB500N)) { return; } diff --git a/src/model.c b/src/model.c index 675e4d18a..6574f3eb1 100644 --- a/src/model.c +++ b/src/model.c @@ -687,12 +687,12 @@ void at_mb500n_init() { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430fx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0x14, 0x13, 0x12, 0x11); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -702,12 +702,12 @@ void at_p54tp4xe_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); + pci_slot(9); + pci_slot(10); + pci_slot(11); + pci_slot(12); i430fx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 12, 11, 10, 9); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -718,12 +718,12 @@ void at_ap53_init() memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0x11, 0x12, 0x13, 0x14); fdc37c669_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -735,12 +735,12 @@ void at_p55t2s_init() memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0x12, 0x13, 0x14, 0x11); pc87306_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -752,12 +752,12 @@ void at_acerm3a_init() memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xc); pci_slot(0xd); pci_slot(0xe); pci_slot(0xf); - pci_slot(0x10); i430hx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0xc, 0xd, 0xe, 0xf); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); @@ -769,12 +769,12 @@ void at_acerv35n_init() memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xc); pci_slot(0xd); pci_slot(0xe); pci_slot(0xf); - pci_slot(0x10); i430hx_init(); - piix_init(7, 0xd, 0xe, 0xf, 0x10); + piix_init(7, 0xc, 0xd, 0xe, 0xf); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); @@ -785,12 +785,12 @@ void at_p55t2p4_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_slot(9); + pci_slot(10); + pci_slot(11); + pci_slot(12); i430hx_init(); - piix3_init(7, 18, 17, 20, 19); + piix3_init(7, 12, 11, 10, 9); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -805,7 +805,7 @@ void at_i430vx_init() pci_slot(0x13); pci_slot(0x14); i430vx_init(); - piix3_init(7, 18, 17, 20, 19); + piix3_init(7, 17, 18, 20, 19); um8669f_init(); device_add(&intel_flash_bxt_device); } @@ -815,12 +815,12 @@ void at_p55tvp4_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_slot(9); + pci_slot(10); + pci_slot(11); + pci_slot(12); i430vx_init(); - piix3_init(7, 18, 17, 20, 19); + piix3_init(7, 12, 11, 10, 9); w83877f_init(); device_add(&intel_flash_bxt_device); } @@ -830,12 +830,12 @@ void at_p55va_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_slot(8); + pci_slot(9); + pci_slot(10); + pci_slot(11); i430vx_init(); - piix3_init(7, 18, 17, 20, 19); + piix3_init(7, 8, 9, 10, 11); fdc37c932fr_init(); device_add(&intel_flash_bxt_device); } @@ -845,12 +845,12 @@ void at_i440fx_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); - pci_slot(0x14); + pci_slot(0xb); + pci_slot(0xc); + pci_slot(0xd); + pci_slot(0xe); i430vx_init(); - piix3_init(7, 18, 17, 20, 19); + piix3_init(7, 0xe, 0xd, 0xc, 0xb); fdc37c665_init(); device_add(&intel_flash_bxt_device); } @@ -860,12 +860,12 @@ void at_s1668_init() at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); + pci_slot(0xb); + pci_slot(0xc); pci_slot(0xd); pci_slot(0xe); - pci_slot(0xf); - pci_slot(0x10); i440fx_init(); - piix3_init(7, 0xd, 0xe, 0xf, 0x10); + piix3_init(7, 0xe, 0xd, 0xc, 0xb); fdc37c665_init(); device_add(&intel_flash_bxt_device); } From ac18a8f539ff06226ea1ac472cd351733c4e205a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 16:34:40 +0200 Subject: [PATCH 293/392] Changed CPU cycles period tweak so it only affects the 486's; Applied Laser XT ROM BASIC and Laser XT EMS patches from Greatpsycho. --- src/CPU/386_dynarec.c | 24 +-------- src/Makefile.mingw | 5 +- src/laserxt.c | 121 ++++++++++++++++++++++++++++++++++++++++++ src/laserxt.h | 1 + src/mem.c | 96 +++++++++++++++++++++++++++------ src/mem.h | 1 + src/model.c | 12 ++++- 7 files changed, 217 insertions(+), 43 deletions(-) create mode 100644 src/laserxt.c create mode 100644 src/laserxt.h diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index 61db68737..a362f50da 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -1284,32 +1284,12 @@ static int cpu_cycle_period(void) { switch(cpu_pci_speed) { - case 16000000: - return 800; + case 333333333: + return is_pentium ? 1000 : 1333; break; - case 20000000: - case 40000000: - return 1000; - break; - case 25000000: default: return 1000; break; - case 27500000: - return 1100; - break; - case 30000000: - return 1200; - break; - case 333333333: - return 1333; - break; - case 37500000: - return 1500; - break; - case 41666667: - return 1041; - break; } } diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 5593f9651..24fb51f8b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,9 +8,9 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.21 2017/06/01 +# Version: @(#)Makefile.mingw 1.0.22 2017/06/01 # -# Authors: Kotori, +# Authors: Miran Grca, # Fred N. van Kempen, # Sarah Walker, # Richard G., @@ -128,6 +128,7 @@ SYSOBJ = model.o \ i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ neat.o \ ali1429.o \ + laserxt.o \ opti495.o \ scat.o \ sis496.o \ diff --git a/src/laserxt.c b/src/laserxt.c new file mode 100644 index 000000000..9ba6e3500 --- /dev/null +++ b/src/laserxt.c @@ -0,0 +1,121 @@ +/*This is the chipset used in the LaserXT series model*/ +#include "ibm.h" +#include "io.h" +#include "mem.h" + +static int laserxt_emspage[4]; +static int laserxt_emscontrol[4]; +static mem_mapping_t laserxt_ems_mapping[4]; +static int laserxt_ems_baseaddr_index = 0; + +uint32_t get_laserxt_ems_addr(uint32_t addr) +{ + if(laserxt_emspage[(addr >> 14) & 3] & 0x80) + { + addr = 0xA0000 + ((laserxt_emspage[(addr >> 14) & 3] & 0x0F) << 14) + ((laserxt_emspage[(addr >> 14) & 3] & 0x40) << 12) + (addr & 0x3FFF); + } + return addr; +} + +void laserxt_write(uint16_t port, uint8_t val, void *priv) +{ + int i; + uint32_t paddr, vaddr; + switch (port) + { + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + laserxt_emspage[port >> 14] = val; + paddr = 0xC0000 + (port & 0xC000) + (((laserxt_ems_baseaddr_index + (4 - (port >> 14))) & 0x0C) << 14); + if(val & 0x80) + { + mem_mapping_enable(&laserxt_ems_mapping[port >> 14]); + vaddr = get_laserxt_ems_addr(paddr); + //pclog("Mapping address %05X to %06X\n", paddr, vaddr); + mem_mapping_set_exec(&laserxt_ems_mapping[port >> 14], ram + vaddr); + } + else + { + //pclog("Unmap address %05X\n", paddr); + mem_mapping_disable(&laserxt_ems_mapping[port >> 14]); + } + //pclog("Write LaserXT port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); + flushmmucache(); + break; + case 0x0209: case 0x4209: case 0x8209: case 0xC209: + laserxt_emscontrol[port >> 14] = val; + laserxt_ems_baseaddr_index = 0; + for(i=0; i<4; i++) + { + laserxt_ems_baseaddr_index |= (laserxt_emscontrol[i] & 0x80) >> (7 - i); + } + //pclog("Set base_index to %d\n", laserxt_ems_baseaddr_index); + if(laserxt_ems_baseaddr_index < 3) + { + mem_mapping_disable(&romext_mapping); + } + else + { + mem_mapping_enable(&romext_mapping); + } + + mem_mapping_set_addr(&laserxt_ems_mapping[0], 0xC0000 + (((laserxt_ems_baseaddr_index + 4) & 0x0C) << 14), 0x4000); + mem_mapping_set_addr(&laserxt_ems_mapping[1], 0xC4000 + (((laserxt_ems_baseaddr_index + 3) & 0x0C) << 14), 0x4000); + mem_mapping_set_addr(&laserxt_ems_mapping[2], 0xC8000 + (((laserxt_ems_baseaddr_index + 2) & 0x0C) << 14), 0x4000); + mem_mapping_set_addr(&laserxt_ems_mapping[3], 0xCC000 + (((laserxt_ems_baseaddr_index + 1) & 0x0C) << 14), 0x4000); + //pclog("Write LaserXT port %04X to %02X at %04X:%04X\n", port, val, CS, cpu_state.pc); + flushmmucache(); + break; + } +} + +uint8_t laserxt_read(uint16_t port, void *priv) +{ + switch (port) + { + case 0x0208: case 0x4208: case 0x8208: case 0xC208: + //pclog("Read LaserXT port %04X at %04X:%04X\n", port, CS, cpu_state.pc); + return laserxt_emspage[port >> 14]; + case 0x0209: case 0x4209: case 0x8209: case 0xC209: + return laserxt_emscontrol[port >> 14]; + break; + } + return 0xff; +} + +void mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) +{ + addr = get_laserxt_ems_addr(addr); + if (addr < (mem_size << 10)) + ram[addr] = val; +} + +uint8_t mem_read_laserxtems(uint32_t addr, void *priv) +{ + uint8_t val = 0xFF; + addr = get_laserxt_ems_addr(addr); + if (addr < (mem_size << 10)) + val = ram[addr]; + return val; +} + +void laserxt_init() +{ + int i; + + if(mem_size > 640) + { + io_sethandler(0x0208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + io_sethandler(0x4208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + io_sethandler(0x8208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + io_sethandler(0xc208, 0x0002, laserxt_read, NULL, NULL, laserxt_write, NULL, NULL, NULL); + } + + for (i = 0; i < 4; i++) + { + laserxt_emspage[i] = 0x7F; + laserxt_emscontrol[i] = (i == 3) ? 0x00 : 0x80; + mem_mapping_add(&laserxt_ems_mapping[i], 0xE0000 + (i << 14), 0x4000, mem_read_laserxtems, NULL, NULL, mem_write_laserxtems, NULL, NULL, ram + 0xA0000 + (i << 14), 0, NULL); + mem_mapping_disable(&laserxt_ems_mapping[i]); + } + mem_set_mem_state(0x0c0000, 0x40000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); +} diff --git a/src/laserxt.h b/src/laserxt.h new file mode 100644 index 000000000..08919ff6a --- /dev/null +++ b/src/laserxt.h @@ -0,0 +1 @@ +void laserxt_init(); diff --git a/src/mem.c b/src/mem.c index 5da6f0866..a077c58be 100644 --- a/src/mem.c +++ b/src/mem.c @@ -44,7 +44,7 @@ static mem_mapping_t ram_mid_mapping; static mem_mapping_t ram_remapped_mapping; mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; -static mem_mapping_t romext_mapping; +mem_mapping_t romext_mapping; uint8_t *ram; uint32_t rammask; @@ -367,22 +367,32 @@ int loadbios() if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.f6",L"rb"); - if (!f) return 1; /*I don't really care if BASIC is there or not*/ - fread(rom+0x6000,8192,1,f); - fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.f8",L"rb"); - if (!f) break; /*But if some of it is there, then all of it must be*/ - fread(rom+0x8000,8192,1,f); - fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.fa",L"rb"); - if (!f) break; - fread(rom+0xA000,8192,1,f); - fclose(f); - f=romfopen(L"roms/ibmpc/basicc11.fc",L"rb"); - if (!f) break; - fread(rom+0xC000,8192,1,f); - fclose(f); + f=romfopen("roms/ibmpc/ibm-basic-1.10.rom","rb"); ++ if (!f) + { + f=romfopen("roms/ibmpc/basicc11.f6","rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom+0x6000,8192,1,f); + fclose(f); + f=romfopen("roms/ibmpc/basicc11.f8","rb"); + if (!f) break; /*But if some of it is there, then all of it must be*/ + fread(rom+0x8000,8192,1,f); + fclose(f); + f=romfopen("roms/ibmpc/basicc11.fa","rb"); + if (!f) break; + fread(rom+0xA000,8192,1,f); + fclose(f); + f=romfopen("roms/ibmpc/basicc11.fc","rb"); + if (!f) break; + fread(rom+0xC000,8192,1,f); + fclose(f); + } + else + { + fread(rom+0x6000,32768,1,f); + fclose(f); + } + return 1; case ROM_MEGAPC: @@ -516,6 +526,32 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); + f=romfopen("roms/ltxt/ibm-basic-1.10.rom","rb"); ++ if (!f) + { + f=romfopen("roms/ltxt/basicc11.f6","rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom+0x6000,8192,1,f); + fclose(f); + f=romfopen("roms/ltxt/basicc11.f8","rb"); + if (!f) break; /*But if some of it is there, then all of it must be*/ + fread(rom+0x8000,8192,1,f); + fclose(f); + f=romfopen("roms/ltxt/basicc11.fa","rb"); + if (!f) break; + fread(rom+0xA000,8192,1,f); + fclose(f); + f=romfopen("roms/ltxt/basicc11.fc","rb"); + if (!f) break; + fread(rom+0xC000,8192,1,f); + fclose(f); + } + else + { + fread(rom+0x6000,32768,1,f); + fclose(f); + } + return 1; case ROM_LXT3: @@ -523,6 +559,32 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); + f=romfopen("roms/lxt3/ibm-basic-1.10.rom","rb"); ++ if (!f) + { + f=romfopen("roms/lxt3/basicc11.f6","rb"); + if (!f) return 1; /*I don't really care if BASIC is there or not*/ + fread(rom+0x6000,8192,1,f); + fclose(f); + f=romfopen("roms/lxt3/basicc11.f8","rb"); + if (!f) break; /*But if some of it is there, then all of it must be*/ + fread(rom+0x8000,8192,1,f); + fclose(f); + f=romfopen("roms/lxt3/basicc11.fa","rb"); + if (!f) break; + fread(rom+0xA000,8192,1,f); + fclose(f); + f=romfopen("roms/lxt3/basicc11.fc","rb"); + if (!f) break; + fread(rom+0xC000,8192,1,f); + fclose(f); + } + else + { + fread(rom+0x6000,32768,1,f); + fclose(f); + } + return 1; case ROM_SPC4200P: /*Samsung SPC-4200P*/ diff --git a/src/mem.h b/src/mem.h index f4cef2a31..6bf127ecf 100644 --- a/src/mem.h +++ b/src/mem.h @@ -109,6 +109,7 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p); mem_mapping_t bios_mapping[8]; mem_mapping_t bios_high_mapping[8]; +mem_mapping_t romext_mapping; extern mem_mapping_t ram_high_mapping; diff --git a/src/model.c b/src/model.c index 6574f3eb1..5eb39a29c 100644 --- a/src/model.c +++ b/src/model.c @@ -136,6 +136,8 @@ void at_p55va_init(); void at_i440fx_init(); void at_s1668_init(); +void xt_laserxt_init(); + int model; int AMSTRAD, AT, PCI, TANDY; @@ -156,8 +158,8 @@ MODEL models[] = {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL}, {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, @@ -392,6 +394,12 @@ void olim24_init() if (joystick_type != 7) device_add(&gameport_device); } +void xt_laserxt_init() +{ + xt_init(); + laserxt_init(); +} + void at_init() { AT = 1; From 0f043d51345387f3692a9ca88c9f94167cd40e32 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 16:37:29 +0200 Subject: [PATCH 294/392] Fixed compile-breaking bugs in mem.c. --- src/mem.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/mem.c b/src/mem.c index a077c58be..bbf4e57d8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -367,22 +367,22 @@ int loadbios() if (!f) break; fread(rom+0xE000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/ibm-basic-1.10.rom","rb"); -+ if (!f) + f=romfopen(L"roms/ibmpc/ibm-basic-1.10.rom",L"rb"); + if (!f) { - f=romfopen("roms/ibmpc/basicc11.f6","rb"); + f=romfopen(L"roms/ibmpc/basicc11.f6",L"rb"); if (!f) return 1; /*I don't really care if BASIC is there or not*/ fread(rom+0x6000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.f8","rb"); + f=romfopen(L"roms/ibmpc/basicc11.f8",L"rb"); if (!f) break; /*But if some of it is there, then all of it must be*/ fread(rom+0x8000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.fa","rb"); + f=romfopen(L"roms/ibmpc/basicc11.fa",L"rb"); if (!f) break; fread(rom+0xA000,8192,1,f); fclose(f); - f=romfopen("roms/ibmpc/basicc11.fc","rb"); + f=romfopen(L"roms/ibmpc/basicc11.fc",L"rb"); if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); @@ -526,22 +526,22 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - f=romfopen("roms/ltxt/ibm-basic-1.10.rom","rb"); -+ if (!f) + f=romfopen(L"roms/ltxt/ibm-basic-1.10.rom",L"rb"); + if (!f) { - f=romfopen("roms/ltxt/basicc11.f6","rb"); + f=romfopen(L"roms/ltxt/basicc11.f6",L"rb"); if (!f) return 1; /*I don't really care if BASIC is there or not*/ fread(rom+0x6000,8192,1,f); fclose(f); - f=romfopen("roms/ltxt/basicc11.f8","rb"); + f=romfopen(L"roms/ltxt/basicc11.f8",L"rb"); if (!f) break; /*But if some of it is there, then all of it must be*/ fread(rom+0x8000,8192,1,f); fclose(f); - f=romfopen("roms/ltxt/basicc11.fa","rb"); + f=romfopen(L"roms/ltxt/basicc11.fa",L"rb"); if (!f) break; fread(rom+0xA000,8192,1,f); fclose(f); - f=romfopen("roms/ltxt/basicc11.fc","rb"); + f=romfopen(L"roms/ltxt/basicc11.fc",L"rb"); if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); @@ -559,22 +559,22 @@ int loadbios() if (!f) break; fread(rom + 0xE000, 8192, 1, f); fclose(f); - f=romfopen("roms/lxt3/ibm-basic-1.10.rom","rb"); -+ if (!f) + f=romfopen(L"roms/lxt3/ibm-basic-1.10.rom",L"rb"); + if (!f) { - f=romfopen("roms/lxt3/basicc11.f6","rb"); + f=romfopen(L"roms/lxt3/basicc11.f6",L"rb"); if (!f) return 1; /*I don't really care if BASIC is there or not*/ fread(rom+0x6000,8192,1,f); fclose(f); - f=romfopen("roms/lxt3/basicc11.f8","rb"); + f=romfopen(L"roms/lxt3/basicc11.f8",L"rb"); if (!f) break; /*But if some of it is there, then all of it must be*/ fread(rom+0x8000,8192,1,f); fclose(f); - f=romfopen("roms/lxt3/basicc11.fa","rb"); + f=romfopen(L"roms/lxt3/basicc11.fa",L"rb"); if (!f) break; fread(rom+0xA000,8192,1,f); fclose(f); - f=romfopen("roms/lxt3/basicc11.fc","rb"); + f=romfopen(L"roms/lxt3/basicc11.fc",L"rb"); if (!f) break; fread(rom+0xC000,8192,1,f); fclose(f); From 85714741ab228d7a96248db0a6942600d3309d3a Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 16:43:43 +0200 Subject: [PATCH 295/392] Added missing .H file. --- src/model.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/model.c b/src/model.c index 5eb39a29c..a96b0a906 100644 --- a/src/model.c +++ b/src/model.c @@ -57,6 +57,7 @@ #include "keyboard_olim24.h" #include "keyboard_pcjr.h" #include "keyboard_xt.h" +#include "laserxt.h" #include "lpt.h" #include "mem.h" #include "memregs.h" From 224368b7910b047e19af73c7783f95cf69bbb540 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 3 Jun 2017 20:32:58 +0200 Subject: [PATCH 296/392] Added a second S3 ViRGE/DX card, this one with VBE 2.0 BIOS; Added the ability to use a standalone MPU-401 if the selected sound card is not SB16 or AWE32. --- src/SOUND/snd_mpu401.c | 120 +++++++++++++++++++++++++++++++++++++++ src/SOUND/snd_mpu401.h | 5 ++ src/VIDEO/vid_s3_virge.c | 38 +++++++++++-- src/VIDEO/vid_s3_virge.h | 1 + src/VIDEO/video.c | 1 + src/WIN/86Box.rc | 18 ++++-- src/WIN/resource.h | 4 +- src/WIN/win_settings.c | 63 +++++++++++++++++++- src/config.c | 11 ++++ src/ibm.h | 1 + src/pc.c | 5 +- src/pci.c | 3 +- 12 files changed, 255 insertions(+), 15 deletions(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index c5c67611b..b85d646b1 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -21,12 +21,15 @@ */ #include "../ibm.h" +#include "../device.h" #include "../io.h" #include "../pic.h" #include "../timer.h" #include "../win/plat_midi.h" /*YUCK*/ +#include "sound.h" #include "snd_mpu401.h" +#include #include enum @@ -38,6 +41,8 @@ enum static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); static void MPU401_EOIHandlerDispatch(void *p); +int mpu401_standalone_enable = 0; + static int mpu401_event_callback = 0; static int mpu401_eoi_callback = 0; static int mpu401_reset_callback = 0; @@ -749,3 +754,118 @@ void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) MPU401_Reset(mpu); } + +void mpu401_device_add(void) +{ + char *n; + + if (!mpu401_standalone_enable) + { + return; + } + + n = sound_card_getname(sound_card_current); + if (n != NULL) + { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + { + return; + } + } + + device_add(&mpu401_device); +} + +void *mpu401_standalone_init() +{ + mpu_t *mpu; + + mpu = malloc(sizeof(mpu_t)); + memset(mpu, 0, sizeof(mpu_t)); + + pclog("mpu_init\n"); + mpu401_init(mpu, device_get_config_hex16("base"), device_get_config_int("irq"), device_get_config_int("mode")); + + return mpu; +} + +void mpu401_standalone_close(void *p) +{ + mpu_t *mpu = (mpu_t *)p; + + free(mpu); +} + +static device_config_t mpu401_standalone_config[] = +{ + { + "base", "MPU-401 Address", CONFIG_HEX16, "", 0x330, + { + { + "0x300", 0x300 + }, + { + "0x330", 0x330 + }, + { + "" + } + } + }, + { + "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, + { + "mode", "Mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + +device_t mpu401_device = +{ + "MPU-401 (Standalone)", + 0, + mpu401_standalone_init, + mpu401_standalone_close, + NULL, + NULL, + NULL, + NULL, + mpu401_standalone_config +}; diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h index 264f2ed97..86dfa2058 100644 --- a/src/SOUND/snd_mpu401.h +++ b/src/SOUND/snd_mpu401.h @@ -83,3 +83,8 @@ typedef struct mpu_t uint8_t MPU401_ReadData(mpu_t *mpu); void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode); + +extern int mpu401_standalone_enable; + +void mpu401_device_add(void); +device_t mpu401_device; diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index d742051ae..283346da5 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -3925,7 +3925,7 @@ static void *s3_virge_988_init() return virge; } -static void *s3_virge_375_init() +static void *s3_virge_375_init(wchar_t *romfn) { virge_t *virge = malloc(sizeof(virge_t)); memset(virge, 0, sizeof(virge_t)); @@ -3940,7 +3940,7 @@ static void *s3_virge_375_init() s3_virge_hwcursor_draw, s3_virge_overlay_draw); - rom_init(&virge->bios_rom, L"roms/86c375_1.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&virge->bios_rom, romfn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); if (PCI) mem_mapping_disable(&virge->bios_rom.mapping); @@ -4021,6 +4021,16 @@ static void *s3_virge_375_init() return virge; } +static void *s3_virge_375_1_init() +{ + return s3_virge_init(L"roms/86c375_1.bin"); +} + +static void *s3_virge_375_4_init() +{ + return s3_virge_init(L"roms/86c375_4.bin"); +} + static void s3_virge_close(void *p) { virge_t *virge = (virge_t *)p; @@ -4054,11 +4064,16 @@ static int s3_virge_988_available() return rom_present(L"roms/diamondstealth3000.VBI"); } -static int s3_virge_375_available() +static int s3_virge_375_1_available() { return rom_present(L"roms/86c375_1.bin"); } +static int s3_virge_375_4_available() +{ + return rom_present(L"roms/86c375_4.bin"); +} + static void s3_virge_speed_changed(void *p) { virge_t *virge = (virge_t *)p; @@ -4190,9 +4205,22 @@ device_t s3_virge_375_device = { "S3 ViRGE/DX", 0, - s3_virge_375_init, + s3_virge_375_1_init, s3_virge_close, - s3_virge_375_available, + s3_virge_375_1_available, + s3_virge_speed_changed, + s3_virge_force_redraw, + s3_virge_add_status_info, + s3_virge_config +}; + +device_t s3_virge_375_4_device = +{ + "S3 ViRGE/DX (VBE 2.0)", + 0, + s3_virge_375_4_init, + s3_virge_close, + s3_virge_375_4_available, s3_virge_speed_changed, s3_virge_force_redraw, s3_virge_add_status_info, diff --git a/src/VIDEO/vid_s3_virge.h b/src/VIDEO/vid_s3_virge.h index 2e8dfbe91..74ee6454b 100644 --- a/src/VIDEO/vid_s3_virge.h +++ b/src/VIDEO/vid_s3_virge.h @@ -4,3 +4,4 @@ extern device_t s3_virge_device; extern device_t s3_virge_988_device; extern device_t s3_virge_375_device; +extern device_t s3_virge_375_4_device; diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index ae9e56048..07531f033 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -101,6 +101,7 @@ static VIDEO_CARD video_cards[] = {"Phoenix S3 Trio64", "px_trio64", &s3_phoenix_trio64_device, GFX_PHOENIX_TRIO64}, {"Plantronics ColorPlus", "plantronics", &colorplus_device, GFX_COLORPLUS}, {"S3 ViRGE/DX", "virge375", &s3_virge_375_device, GFX_VIRGEDX}, + {"S3 ViRGE/DX (VBE 2.0)", "virge375_vbe20", &s3_virge_375_4_device, GFX_VIRGEDX4}, {"Trident TGUI9440", "tgui9440", &tgui9440_device, GFX_TGUI9440}, {"Trident TVGA8900D", "tvga8900d", &tvga8900d_device, GFX_TVGA}, {"Tseng ET4000AX", "et4000ax", &et4000_device, GFX_ET4000}, diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 380d8a423..0d8b6d8d2 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -327,7 +327,7 @@ BEGIN PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 END -CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 78 +CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 98 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN @@ -338,14 +338,20 @@ BEGIN COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "MIDI Out Device:",1801,7,26,59,10 - CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,87,43,80,10 + + CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MPU401,214,44,46,12 + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,43,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,63,94,10 + CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,63,94,10 + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,174,43,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10 CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,61,80,10 + BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 END CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 8541c17e1..73a8f97c4 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -8,7 +8,7 @@ * * Windows resource defines. * - * Version: @(#)resource.h 1.0.0 2017/05/30 + * Version: @(#)resource.h 1.0.1 2017/05/30 * * Author: Sarah Walker, * Miran Grca, @@ -51,7 +51,9 @@ #define IDC_CHECKNUKEDOPL 1018 #define IDC_COMBO_JOYSTICK 1018 #define IDC_CHECK_SYNC 1019 +#define IDC_CHECK_MPU401 1019 #define IDC_LIST_FLOPPY_DRIVES 1020 +#define IDC_CONFIGURE_MPU401 1020 #define IDC_LIST_CDROM_DRIVES 1021 #define IDC_CONFIGURE_MACHINE 1022 #define IDC_COMBO_LANG 1023 diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 31d1ff303..7c187fe89 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -37,6 +37,7 @@ #include "../network.h" #include "../sound/sound.h" #include "../sound/snd_dbopl.h" +#include "../sound/snd_mpu401.h" #include "../video/video.h" #include "../video/vid_voodoo.h" #include "../gameport.h" @@ -56,7 +57,7 @@ static int temp_gfxcard, temp_video_speed, temp_voodoo; static int temp_mouse, temp_joystick; /* Sound category */ -static int temp_sound_card, temp_midi_id, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; +static int temp_sound_card, temp_midi_id, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; /* Network category */ static int temp_net_type, temp_net_card; @@ -117,6 +118,7 @@ static void win_settings_init(void) /* Sound category */ temp_sound_card = sound_card_current; temp_midi_id = midi_id; + temp_mpu401 = mpu401_standalone_enable; temp_SSI2001 = SSI2001; temp_GAMEBLASTER = GAMEBLASTER; temp_GUS = GUS; @@ -180,6 +182,7 @@ static int win_settings_changed(void) /* Sound category */ i = i || (sound_card_current != temp_sound_card); i = i || (midi_id != temp_midi_id); + i = i || (mpu401_standalone_enable != temp_mpu401); i = i || (SSI2001 != temp_SSI2001); i = i || (GAMEBLASTER != temp_GAMEBLASTER); i = i || (GUS != temp_GUS); @@ -275,6 +278,7 @@ static void win_settings_save(void) /* Sound category */ sound_card_current = temp_sound_card; midi_id = temp_midi_id; + mpu401_standalone_enable = temp_mpu401; SSI2001 = temp_SSI2001; GAMEBLASTER = temp_GAMEBLASTER; GUS = temp_GUS; @@ -1102,6 +1106,38 @@ int find_irq_in_array(int irq, int def) static char midi_dev_name_buf[512]; +int mpu401_present(void) +{ + char *n; + + n = sound_card_getname(temp_sound_card); + if (n != NULL) + { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + { + return 1; + } + } + + return temp_mpu401 ? 1 : 0; +} + +int mpu401_standalone_allow(void) +{ + char *n; + + n = sound_card_getname(temp_sound_card); + if (n != NULL) + { + if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) + { + return 0; + } + } + + return 1; +} + static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; @@ -1174,6 +1210,13 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa if (c == temp_midi_id) SendMessage(h, CB_SETCURSEL, c, 0); } + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); h=GetDlgItem(hdlg, IDC_CHECKCMS); SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); @@ -1214,6 +1257,21 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa { EnableWindow(h, FALSE); } + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + break; + + case IDC_CHECK_MPU401: + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_MPU401: + deviceconfig_open(hdlg, (void *)&mpu401_device); break; } return FALSE; @@ -1225,6 +1283,9 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_COMBO_MIDI); temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECKCMS); temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); diff --git a/src/config.c b/src/config.c index c325c3a5d..2a7913629 100644 --- a/src/config.c +++ b/src/config.c @@ -30,6 +30,7 @@ #include "win/plat_joystick.h" #include "win/plat_midi.h" #include "sound/snd_dbopl.h" +#include "sound/snd_mpu401.h" #include "sound/snd_opl.h" #include "sound/sound.h" #include "video/video.h" @@ -976,6 +977,7 @@ static void loadconfig_sound(void) sound_card_current = 0; midi_id = config_get_int(cat, "midi_host_device", 0); + mpu401_standalone_enable = !!config_get_int(cat, "mpu401_standalone", 0); SSI2001 = !!config_get_int(cat, "ssi2001", 0); GAMEBLASTER = !!config_get_int(cat, "gameblaster", 0); @@ -2004,6 +2006,15 @@ static void saveconfig_sound(void) config_set_int(cat, "midi_host_device", midi_id); } + if (mpu401_standalone_enable == 0) + { + config_delete_var(cat, "mpu401_standalone"); + } + else + { + config_set_int(cat, "mpu401_standalone", mpu401_standalone_enable); + } + if (SSI2001 == 0) { config_delete_var(cat, "ssi2001"); diff --git a/src/ibm.h b/src/ibm.h index e2f9c8de5..658ca5513 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -528,6 +528,7 @@ enum GFX_OTI037, /*Oak OTI-037*/ GFX_VIRGEVX, /*S3 Virge/VX*/ + GFX_VIRGEDX4, /*S3 Virge/DX (VBE 2.0)*/ GFX_MAX }; diff --git a/src/pc.c b/src/pc.c index b85f401a1..544c5ee30 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.0 2017/05/30 + * Version: @(#)pc.c 1.0.1 2017/05/30 * * Author: Sarah Walker, * Miran Grca, @@ -64,6 +64,7 @@ #include "sound/sound.h" #include "sound/snd_cms.h" #include "sound/snd_dbopl.h" +#include "sound/snd_mpu401.h" #include "sound/snd_opl.h" #include "sound/snd_gus.h" #include "sound/snd_sb.h" @@ -522,6 +523,8 @@ void resetpchard(void) scsi_card_init(); sound_card_init(); + if (mpu401_standalone_enable) + mpu401_device_add(); if (GUS) device_add(&gus_device); if (GAMEBLASTER) diff --git a/src/pci.c b/src/pci.c index b48ac2072..4edd4b14f 100644 --- a/src/pci.c +++ b/src/pci.c @@ -150,7 +150,8 @@ void pci_issue_irq(int irq) if (irq_elcr) { - picintlevel(1 << irq); + /* picintlevel(1 << irq); */ + picint(1 << irq); } else { From fa174b79b2c3f9da2c22d5f0811142f902c6de5e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 02:14:27 +0200 Subject: [PATCH 297/392] Fixed a compile-breaking error; Added the ability to set each floppy drive to turbo speed which will make it opperate at an effective 8000 kbps @ 300 rpm, for those who want faster but less accurate floppy timings. --- src/Makefile.mingw | 9 +++++-- src/SOUND/snd_sb_dsp.c | 3 ++- src/SOUND/sound.c | 4 ++- src/WIN/86Box.rc | 16 ++++++++---- src/WIN/resource.h | 9 +++++-- src/WIN/win_settings.c | 56 +++++++++++++++++++++++++++++++++++++++++- src/config.c | 18 ++++++++++++++ src/disc.c | 7 +++++- src/fdd.c | 12 +++++++++ src/fdd.h | 2 ++ src/model.c | 12 +++++++++ 11 files changed, 135 insertions(+), 13 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 24fb51f8b..02c65792b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 MinGW 32-bit environment. # -# Version: @(#)Makefile.mingw 1.0.22 2017/06/01 +# Version: @(#)Makefile.mingw 1.0.23 2017/06/03 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -48,6 +48,9 @@ endif ifndef RELEASE RELEASE = n endif +ifndef USB +USB = n +endif ######################################################################### @@ -154,7 +157,9 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc_random.o disc_td0.o \ cdrom.o \ cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o +ifeq ($(USB), y) USBOBJ = usb.o +endif NETOBJ = network.o \ net_pcap.o net_slirp.o \ net_ne2000.o @@ -170,7 +175,7 @@ SNDOBJ = sound.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ snd_emu8k.o snd_gus.o snd_opl.o \ - snd_mpu401.o snd_pas16.o snd_resid.o \ + snd_mpu401.o snd_resid.o \ snd_sn76489.o snd_ssi2001.o snd_wss.o \ snd_ym7128.o VIDOBJ = video.o \ diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index ba4e556f0..3d7c95cf8 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -6,6 +6,7 @@ #include #include #include "../ibm.h" +#include "../device.h" #include "../io.h" #include "../pic.h" #include "../dma.h" @@ -515,7 +516,7 @@ void sb_exec_command(sb_dsp_t *dsp) sb_add_data(dsp, dsp->sb_asp_regs[dsp->sb_data[0]]); break; case 0xF8: - if (dsp->sb_type < SB16) break; + if (dsp->sb_type >= SB16) break; sb_add_data(dsp, 0); break; case 0xF9: diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index fb0237ac9..5a96ff15c 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -28,7 +28,7 @@ #include "snd_opl.h" #include "snd_adlib.h" #include "snd_adlibgold.h" -#include "snd_pas16.h" +/* #include "snd_pas16.h" */ #include "snd_sb.h" #include "snd_sb_dsp.h" #include "snd_wss.h" @@ -62,7 +62,9 @@ static SOUND_CARD sound_cards[] = {"Sound Blaster AWE32", "sbawe32", &sb_awe32_device}, {"Adlib Gold", "adlibgold", &adgold_device}, {"Windows Sound System", "wss", &wss_device}, +#if 0 {"Pro Audio Spectrum 16", "pas16", &pas16_device}, +#endif {"", "", NULL} }; diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 0d8b6d8d2..1020c2767 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -440,13 +440,15 @@ BEGIN LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,18,253,60 LTEXT "Floppy drives:",-1,7,7,43,8 + COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Type:",1803,7,86,24,8 + CONTROL "Turbo timings (no accuracy)",IDC_CHECKTURBO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,131,86,129,10 CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,116,253,60 LTEXT "CD-ROM drives:",-1,7,106,50,8 - COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Type:",1803,7,86,24,8 COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Bus:",1798,7,184,24,8 @@ -872,9 +874,13 @@ BEGIN IDS_2218 "&Image..." IDS_2219 "PCap failed to set up because it may not be initialized" IDS_2220 "Image (&Write-protected)..." - IDS_2221 "English (United States)" + IDS_2221 "Turbo" + IDS_2222 "On" + IDS_2223 "Off" + IDS_2224 "" + IDS_2225 "English (United States)" END -#define IDS_LANG_ENUS IDS_2221 +#define IDS_LANG_ENUS IDS_2225 #ifndef _MAC diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 73a8f97c4..52edb590a 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -66,6 +66,7 @@ #define IDC_BUTTON_HDD_ADD 1028 #define IDC_BUTTON_CDROM_REMOVE 1029 #define IDC_BUTTON_HDD_REMOVE 1029 +#define IDC_CHECKTURBO 1030 #define IDC_HDIMAGE_NEW 1035 #define IDC_HD_BUS 1036 #define IDC_HDIMAGE_EXISTING 1037 @@ -285,8 +286,12 @@ #define IDS_2219 2219 #define IDS_2220 2220 #define IDS_2221 2221 +#define IDS_2222 2222 +#define IDS_2223 2223 +#define IDS_2224 2224 +#define IDS_2225 2225 -#define IDS_LANG_ENUS IDS_2221 +#define IDS_LANG_ENUS IDS_2225 #define IDM_ABOUT 40001 @@ -473,4 +478,4 @@ # endif #endif -#define STRINGS_NUM 174 +#define STRINGS_NUM 178 diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 7c187fe89..b09e801fa 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -74,6 +74,7 @@ static hard_disk_t temp_hdc[HDC_NUM]; /* Removable devices category */ static int temp_fdd_types[FDD_NUM]; +static int temp_fdd_turbo[FDD_NUM]; static cdrom_drive_t temp_cdrom_drives[CDROM_NUM]; static HWND hwndParentDialog, hwndChildDialog; @@ -149,6 +150,7 @@ static void win_settings_init(void) for (i = 0; i < FDD_NUM; i++) { temp_fdd_types[i] = fdd_get_type(i); + temp_fdd_turbo[i] = fdd_get_turbo(i); } memcpy(temp_cdrom_drives, cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); } @@ -212,6 +214,7 @@ static int win_settings_changed(void) for (j = 0; j < FDD_NUM; j++) { i = i || (temp_fdd_types[j] != fdd_get_type(j)); + i = i || (temp_fdd_turbo[j] != fdd_get_turbo(j)); } i = i || memcmp(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); @@ -309,6 +312,7 @@ static void win_settings_save(void) for (i = 0; i < FDD_NUM; i++) { fdd_set_type(i, temp_fdd_types[i]); + fdd_set_turbo(i, temp_fdd_turbo[i]); } memcpy(cdrom_drives, temp_cdrom_drives, CDROM_NUM * sizeof(cdrom_drive_t)); @@ -3454,6 +3458,16 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) if (ListView_InsertItem(hwndList, &lvI) == -1) return FALSE; + + lvI.iSubItem = 1; + lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return FALSE; + } } return TRUE; @@ -3515,7 +3529,7 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) lvc.iSubItem = 0; lvc.pszText = win_language_get_string_from_id(2188); - lvc.cx = 392; + lvc.cx = 292; lvc.fmt = LVCFMT_LEFT; if (ListView_InsertColumn(hwndList, 0, &lvc) == -1) @@ -3523,6 +3537,17 @@ static BOOL win_settings_floppy_drives_init_columns(HWND hwndList) return FALSE; } + lvc.iSubItem = 1; + lvc.pszText = win_language_get_string_from_id(2221); + + lvc.cx = 100; + lvc.fmt = LVCFMT_LEFT; + + if (ListView_InsertColumn(hwndList, 1, &lvc) == -1) + { + return FALSE; + } + return TRUE; } @@ -3612,6 +3637,16 @@ static void win_settings_floppy_drives_update_item(HWND hwndList, int i) { return; } + + lvI.iSubItem = 1; + lvI.pszText = win_language_get_string_from_id(temp_fdd_turbo[i] ? 2222 : 2223); + lvI.iItem = i; + lvI.iImage = 0; + + if (ListView_SetItem(hwndList, &lvI) == -1) + { + return; + } } static void win_settings_cdrom_drives_update_item(HWND hwndList, int i) @@ -3796,6 +3831,9 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message } SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); + cdlv_current_sel = 0; h = GetDlgItem(hdlg, IDC_LIST_CDROM_DRIVES); win_settings_cdrom_drives_init_columns(h); @@ -3855,6 +3893,8 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 1; h = GetDlgItem(hdlg, IDC_COMBO_FD_TYPE); SendMessage(h, CB_SETCURSEL, temp_fdd_types[fdlv_current_sel], 0); + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + SendMessage(h, BM_SETCHECK, temp_fdd_turbo[fdlv_current_sel], 0); rd_ignore_change = 0; } else if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_LIST_CDROM_DRIVES)) @@ -3918,6 +3958,20 @@ static BOOL CALLBACK win_settings_removable_devices_proc(HWND hdlg, UINT message rd_ignore_change = 0; return FALSE; + case IDC_CHECKTURBO: + if (rd_ignore_change) + { + return FALSE; + } + + rd_ignore_change = 1; + h = GetDlgItem(hdlg, IDC_CHECKTURBO); + temp_fdd_turbo[fdlv_current_sel] = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_LIST_FLOPPY_DRIVES); + win_settings_floppy_drives_update_item(h, fdlv_current_sel); + rd_ignore_change = 0; + return FALSE; + case IDC_COMBO_CD_BUS: if (rd_ignore_change) { diff --git a/src/config.c b/src/config.c index 2a7913629..0b4dbce53 100644 --- a/src/config.c +++ b/src/config.c @@ -1480,6 +1480,8 @@ static void loadconfig_removable_devices(void) printf("Floppy: %ws\n", discfns[c]); sprintf(temps, "fdd_%02i_writeprot", c + 1); ui_writeprot[c] = !!config_get_int(cat, temps, 0); + sprintf(temps, "fdd_%02i_turbo", c + 1); + fdd_set_turbo(c, !!config_get_int(cat, temps, 0)); /* Check, whether each value is default, if yes, delete it so that only non-default values will later be saved. */ if (fdd_get_type(c) == ((c < 2) ? 2 : 0)) @@ -1499,6 +1501,12 @@ static void loadconfig_removable_devices(void) sprintf(temps, "fdd_%02i_writeprot", c + 1); config_delete_var(cat, temps); } + + if (fdd_get_turbo(c) == 0) + { + sprintf(temps, "fdd_%02i_turbo", c + 1); + config_delete_var(cat, temps); + } } memset(temps, 0, 512); @@ -2352,6 +2360,16 @@ static void saveconfig_removable_devices(void) { config_set_int(cat, temps, ui_writeprot[c]); } + + sprintf(temps, "fdd_%02i_turbo", c + 1); + if (fdd_get_turbo(c) == 0) + { + config_delete_var(cat, temps); + } + else + { + config_set_int(cat, temps, fdd_get_turbo(c)); + } } memset(temps, '\0', sizeof(temps)); diff --git a/src/disc.c b/src/disc.c index e7af927bd..46b2517c6 100644 --- a/src/disc.c +++ b/src/disc.c @@ -195,6 +195,11 @@ double disc_byteperiod(int drive) if (drives[drive].byteperiod) { + if (fdd_get_turbo(drive)) + { + return 1.0; + } + return drives[drive].byteperiod(drive); } else @@ -213,7 +218,7 @@ double disc_real_period(int drive) dusec = (double) TIMER_USEC; /* This is a giant hack but until the timings become even more correct, this is needed to make floppies work right on that BIOS. */ - if (romset == ROM_MRTHOR) + if ((romset == ROM_MRTHOR) && !fdd_get_turbo(drive)) { return (ddbp * dusec) / 4.0; } diff --git a/src/fdd.c b/src/fdd.c index 449bf02bd..dd6649ee2 100644 --- a/src/fdd.c +++ b/src/fdd.c @@ -30,6 +30,8 @@ static struct int densel; int head; + + int turbo; } fdd[FDD_NUM]; /* Flags: @@ -312,6 +314,16 @@ int fdd_get_head(int drive) return fdd[drive].head; } +void fdd_set_turbo(int drive, int turbo) +{ + fdd[drive].turbo = turbo; +} + +int fdd_get_turbo(int drive) +{ + return fdd[drive].turbo; +} + int fdd_get_densel(int drive) { if (drive_types[fdd[drive].type].flags & FLAG_INVERT_DENSEL) diff --git a/src/fdd.h b/src/fdd.h index 7b34c4a1a..e8de9db96 100644 --- a/src/fdd.h +++ b/src/fdd.h @@ -30,6 +30,8 @@ int fdd_is_ed(int drive); int fdd_is_double_sided(int drive); void fdd_set_head(int drive, int head); int fdd_get_head(int drive); +void fdd_set_turbo(int drive, int turbo); +int fdd_get_turbo(int drive); void fdd_set_type(int drive, int type); int fdd_get_type(int drive); diff --git a/src/model.c b/src/model.c index a96b0a906..209bbb017 100644 --- a/src/model.c +++ b/src/model.c @@ -123,14 +123,18 @@ void at_endeavor_init(); void at_dtk486_init(); void at_r418_init(); +#if 0 void at_586mc1_init(); +#endif void at_plato_init(); void at_mb500n_init(); void at_p54tp4xe_init(); void at_ap53_init(); void at_p55t2s_init(); void at_acerm3a_init(); +#if 0 void at_acerv35n_init(); +#endif void at_p55t2p4_init(); void at_p55tvp4_init(); void at_p55va_init(); @@ -204,7 +208,9 @@ MODEL models[] = {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_sis496_init, NULL}, {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_r418_init, NULL}, {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_batman_init, NULL}, +#if 0 {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_586mc1_init, NULL}, +#endif {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, @@ -215,7 +221,9 @@ MODEL models[] = {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_ap53_init, NULL}, {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2s_init, NULL}, {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerm3a_init, NULL}, +#if 0 {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerv35n_init, NULL}, +#endif {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2p4_init, NULL}, {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL}, {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL}, @@ -652,6 +660,7 @@ void at_batman_init() i430lx_init(); } +#if 0 void at_586mc1_init() { at_ide_init(); @@ -665,6 +674,7 @@ void at_586mc1_init() device_add(&intel_flash_bxt_device); secondary_ide_check(); } +#endif void at_plato_init() { @@ -772,6 +782,7 @@ void at_acerm3a_init() device_add(&intel_flash_bxb_device); } +#if 0 void at_acerv35n_init() { at_ide_init(); @@ -788,6 +799,7 @@ void at_acerv35n_init() acerm3a_io_init(); device_add(&intel_flash_bxb_device); } +#endif void at_p55t2p4_init() { From bbe2e485a85ea4d22b8f18681241cdb837a295f1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 02:34:44 +0200 Subject: [PATCH 298/392] The two S3 Virge 375 variants now call the correct initialization procedure; Fixed the bug that caused only one floppy drive to be listed in Settings. --- src/VIDEO/vid_s3_virge.c | 4 ++-- src/WIN/win_settings.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 283346da5..845c915d3 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -4023,12 +4023,12 @@ static void *s3_virge_375_init(wchar_t *romfn) static void *s3_virge_375_1_init() { - return s3_virge_init(L"roms/86c375_1.bin"); + return s3_virge_375_init(L"roms/86c375_1.bin"); } static void *s3_virge_375_4_init() { - return s3_virge_init(L"roms/86c375_4.bin"); + return s3_virge_375_init(L"roms/86c375_4.bin"); } static void s3_virge_close(void *p) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index b09e801fa..646248861 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -3439,10 +3439,11 @@ static BOOL win_settings_floppy_drives_recalc_list(HWND hwndList) WCHAR szText[256]; lvI.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE; - lvI.stateMask = lvI.iSubItem = lvI.state = 0; + lvI.stateMask = lvI.state = 0; for (i = 0; i < 4; i++) { + lvI.iSubItem = 0; if (temp_fdd_types[i] > 0) { strcpy(s, fdd_getname(temp_fdd_types[i])); From 3c1b0da73f3d80d31a288827c19f8ab67c579c8d Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 02:41:16 +0200 Subject: [PATCH 299/392] Fixed detection of whether or not standalone MPU-401 should be allowed. --- src/SOUND/snd_mpu401.c | 2 +- src/WIN/win_settings.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index b85d646b1..97fece713 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -764,7 +764,7 @@ void mpu401_device_add(void) return; } - n = sound_card_getname(sound_card_current); + n = sound_card_get_internal_name(sound_card_current); if (n != NULL) { if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 646248861..97cd7ed5b 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1114,7 +1114,7 @@ int mpu401_present(void) { char *n; - n = sound_card_getname(temp_sound_card); + n = sound_card_get_internal_name(temp_sound_card); if (n != NULL) { if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) @@ -1130,7 +1130,7 @@ int mpu401_standalone_allow(void) { char *n; - n = sound_card_getname(temp_sound_card); + n = sound_card_get_internal_name(temp_sound_card); if (n != NULL) { if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) From 8a57bd4bc0959719b0b5f7c6469bfdcb9cd64570 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 02:59:30 +0200 Subject: [PATCH 300/392] Got rid of the IRQ hacks for the BT-985D and the RTL8029AS because they are no longer needed, all the boards now give the cards IRQ's. --- src/net_ne2000.c | 36 +++++------------------------------- src/scsi_buslogic.c | 14 ++++---------- 2 files changed, 9 insertions(+), 41 deletions(-) diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 5c8f2c829..212353622 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -255,7 +255,7 @@ nelog(int lvl, const char *fmt, ...) static void nic_interrupt(nic_t *dev, int set) { - if (PCI && dev->is_pci) { + if ((PCI && dev->is_pci) && (dev->base_irq == 0xff)) { if (set) pci_set_irq(dev->card, PCI_INTA); else @@ -1635,15 +1635,11 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) nic_update_bios(dev); return; -#if 0 case 0x3C: /* PCI_ILR */ - if (val != 0xFF) { - nelog(1, "%s: IRQ now: %i\n", dev->name, val); - dev->base_irq = val; - } + nelog(1, "%s: IRQ now: %i\n", dev->name, val); + dev->base_irq = val; dev->pci_regs[addr] = dev->base_irq; return; -#endif } } @@ -1909,11 +1905,12 @@ nic_init(int board) if (dev->is_pci) { dev->base_address = 0x340; + dev->base_irq = 10; } else { dev->base_address = device_get_config_hex16("base"); dev->bios_addr = device_get_config_hex20("bios_addr"); + dev->base_irq = device_get_config_int("irq"); } - dev->base_irq = device_get_config_int("irq"); /* See if we have a local MAC address configured. */ mac = device_get_config_mac("mac", -1); @@ -2220,29 +2217,6 @@ static device_config_t ne2000_config[] = static device_config_t rtl8029as_config[] = { - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 3", 3 - }, - { - "IRQ 5", 5 - }, - { - "IRQ 7", 7 - }, - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "" - } - }, - }, #if 1 /* * WTF. diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 610bc39e4..8a03a52b2 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -534,10 +534,8 @@ BuslogicLog(const char *format, ...) static void BuslogicInterrupt(Buslogic_t *bl, int set) { -#if 0 - if (bl->chip != CHIP_BUSLOGIC_PCI) + if ((bl->chip != CHIP_BUSLOGIC_PCI) || (bl->Irq != 255)) { -#endif if (set) { picint(1 << bl->Irq); @@ -546,20 +544,18 @@ BuslogicInterrupt(Buslogic_t *bl, int set) { picintc(1 << bl->Irq); } -#if 0 } else { if (set) { - pci_set_irq(bl->Card, PCI_INTD); + pci_set_irq(bl->Card, PCI_INTA); } else { - pci_clear_irq(bl->Card, PCI_INTD); + pci_clear_irq(bl->Card, PCI_INTA); } } -#endif } @@ -2134,7 +2130,7 @@ BuslogicPCIRead(int func, int addr, void *p) case 0x3C: return bl->Irq; case 0x3D: - return 4; + return PCI_INTA; } return(0); @@ -2224,7 +2220,6 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } return; -#if 0 case 0x3C: buslogic_pci_regs[addr] = val; if (val != 0xFF) { @@ -2232,7 +2227,6 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) bl->Irq = val; } return; -#endif } } From cbfa682cb7892643c287e2211308842ef7f6f44c Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 4 Jun 2017 02:11:19 -0400 Subject: [PATCH 301/392] Changes, updates and fixes to fixes. Check the new warnings re timer_add(). Using stricter prototypes receiled more stuff.. --- src/86box.h | 27 +- src/CPU/cpu.c | 6 +- src/Makefile.mingw | 26 +- src/Makefile_AMD.mingw | 2 - src/Makefile_AMD.mingw64 | 2 - src/SOUND/snd_sb_dsp.c | 2 +- src/WIN/86Box.rc | 503 ++++++++++++++++----------------- src/WIN/resource.h | 587 ++++++++++++++++++++------------------- src/WIN/win.c | 52 ++-- src/WIN/win_d3d_fs.cc | 5 +- src/WIN/win_settings.c | 25 +- src/WIN/win_status.c | 2 +- src/cdrom.c | 17 +- src/cdrom.h | 95 +++---- src/cdrom_ioctl.c | 5 +- src/cdrom_ioctl.h | 26 +- src/cdrom_null.c | 7 +- src/cdrom_null.h | 18 +- src/device.c | 13 +- src/device.h | 79 +++--- src/disc.c | 11 +- src/disc.h | 84 +++--- src/dma.c | 7 +- src/dma.h | 47 ++-- src/ibm.h | 8 +- src/ide.c | 9 +- src/ide.h | 69 +++-- src/model.c | 220 +++++++-------- src/model.h | 62 +++-- src/mouse.h | 6 +- src/net_ne2000.c | 16 +- src/network.c | 12 +- src/network.h | 12 +- src/nvr.c | 15 +- src/nvr.h | 19 +- src/pc.c | 10 +- src/scsi_buslogic.c | 9 +- src/scsi_disk.c | 23 +- src/serial.c | 64 +++-- src/serial.h | 8 +- src/xtide.c | 13 +- src/xtide.h | 10 +- 42 files changed, 1139 insertions(+), 1094 deletions(-) delete mode 100644 src/Makefile_AMD.mingw delete mode 100644 src/Makefile_AMD.mingw64 diff --git a/src/86box.h b/src/86box.h index b14a9477a..9af4e6e55 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,13 +8,32 @@ * * Main emulator include file. * - * Version: @(#)86box.h 1.0.0 2017/05/30 + * Version: @(#)86box.h 1.0.1 2017/06/03 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. */ +#ifndef BOX_H +# define BOX_H -#define emulator_version "2.00" -#define emulator_version_w L"2.00" -#define CONFIG_FILE L"86box.cfg" +#if defined(ENABLE_BUSLOGIC_LOG) || \ + defined(ENABLE_CDROM_LOG) || \ + defined(ENABLE_D86F_LOG) || \ + defined(ENABLE_FDC_LOG) || \ + defined(ENABLE_IDE_LOG) || \ + defined(ENABLE_NIC_LOG) +# define ENABLE_LOG_TOGGLES 1 +#endif + + +#define EMU_VERSION "2.00" +#define EMU_VERSION_W L"2.00" + +#define EMU_NAME "86Box" +#define EMU_NAME_W L"86Box" + +#define CONFIG_FILE_W L"86box.cfg" + + +#endif /*BOX_H*/ diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index cbb7161fb..5f6f00b16 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -8,18 +8,18 @@ * * CPU type handler. * - * Version: @(#)cpu.c 1.0.0 2017/05/30 + * Version: @(#)cpu.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * leilei, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 leilei. * Copyright 2016-2017 Miran Grca. */ - #include "../ibm.h" #include "cpu.h" +#include "../device.h" #include "../model.h" #include "../io.h" #include "x86_ops.h" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 02c65792b..1a6f76df5 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -6,7 +6,7 @@ # # This file is part of the 86Box distribution. # -# Modified Makefile for Win32 MinGW 32-bit environment. +# Modified Makefile for Win32 (MinGW32) environment. # # Version: @(#)Makefile.mingw 1.0.23 2017/06/03 # @@ -29,8 +29,16 @@ STUFF = endif # Add feature selections here. -# -DBUGGER adds the ISA BusBugger emulation. # -DANSI_CFG forces the config file to ANSI encoding. +# -DENABLE_VRAM_DUMP enables Video Ram dumping. +# -DENABLE_LOG_BREAKPOINT enables extra logging. +# -DENABLE_BUSLOGIC_LOG enables extra logging. +# -DENABLE_CDROM_LOG enables extra logging. +# -DENABLE_D86F_LOG enables extra logging. +# -DENABLE_FDC_LOG enables extra logging. +# -DENABLE_IDE_LOG enables extra logging. +# -DENABLE_SERIAL_LOG enables extra logging. +# -DENABLE_NIC_LOG enables extra logging. ifndef EXTRAS EXTRAS = endif @@ -42,15 +50,15 @@ endif ifndef OPTIM OPTIM = n endif -ifndef X64 -X64 = n -endif ifndef RELEASE RELEASE = n endif ifndef USB USB = n endif +ifndef X64 +X64 = n +endif ######################################################################### @@ -131,11 +139,11 @@ SYSOBJ = model.o \ i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ neat.o \ ali1429.o \ - laserxt.o \ opti495.o \ scat.o \ sis496.o \ wd76c10.o \ + laserxt.o \ acer386sx.o acerm3a.o amstrad.o \ compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ tandy_eeprom.o tandy_rom.o @@ -157,7 +165,7 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc_random.o disc_td0.o \ cdrom.o \ cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o -ifeq ($(USB), y) +ifdef USB USBOBJ = usb.o endif NETOBJ = network.o \ @@ -175,7 +183,7 @@ SNDOBJ = sound.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ snd_emu8k.o snd_gus.o snd_opl.o \ - snd_mpu401.o snd_resid.o \ + snd_mpu401.o snd_pas16.o snd_resid.o \ snd_sn76489.o snd_ssi2001.o snd_wss.o \ snd_ym7128.o VIDOBJ = video.o \ @@ -265,7 +273,7 @@ clean: 86Box.res: 86Box.rc @echo Processing $< - @$(WINDRES) $(RFLAGS) -i win/86Box.rc -o 86Box.res + @$(WINDRES) $(RFLAGS) $(EXTRAS) -i win/86Box.rc -o 86Box.res pcap_if.res: pcap_if.rc @echo Processing $< diff --git a/src/Makefile_AMD.mingw b/src/Makefile_AMD.mingw deleted file mode 100644 index 436b11d5f..000000000 --- a/src/Makefile_AMD.mingw +++ /dev/null @@ -1,2 +0,0 @@ -include Makefile.mingw -CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign \ No newline at end of file diff --git a/src/Makefile_AMD.mingw64 b/src/Makefile_AMD.mingw64 deleted file mode 100644 index d891ed4a4..000000000 --- a/src/Makefile_AMD.mingw64 +++ /dev/null @@ -1,2 +0,0 @@ -include Makefile.mingw64 -CFLAGS = -O3 -march=amdfam10 -mtune=amdfam10 -fbranch-probabilities -fvpt -funroll-loops -fpeel-loops -ftracer -fomit-frame-pointer -ffast-math -msse -msse2 -msse3 -mfpmath=sse -mstackrealign \ No newline at end of file diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index 3d7c95cf8..a4cc3286b 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -6,12 +6,12 @@ #include #include #include "../ibm.h" -#include "../device.h" #include "../io.h" #include "../pic.h" #include "../dma.h" #include "../win/plat_midi.h" /*YUCK*/ #include "../timer.h" +#include "../device.h" #include "sound.h" #include "snd_mpu401.h" #include "snd_sb_dsp.h" diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 1020c2767..b4983a802 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -8,28 +8,19 @@ * * Windows resource script. * - * Version: @(#)86Box.rc 1.0.0 2017/05/30 + * Version: @(#)86Box.rc 1.0.1 2017/06/03 * - * Author: Miran Grca, + * Authors: Miran Grca, + * Fred N. van Kempen, * Copyright 2016-2017 Miran Grca. */ - #include - -//Microsoft Developer Studio generated resource script. -// #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// #define APSTUDIO_HIDDEN_SYMBOLS #include "windows.h" #undef APSTUDIO_HIDDEN_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// @@ -46,14 +37,12 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Menu // -STATUSBARMENU MENU DISCARDABLE -BEGIN -END - MAINMENU MENU DISCARDABLE BEGIN POPUP "&Action" BEGIN + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT + MENUITEM SEPARATOR MENUITEM "&Hard Reset", IDM_FILE_HRESET MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD MENUITEM SEPARATOR @@ -68,7 +57,7 @@ BEGIN MENUITEM SEPARATOR POPUP "&Video" BEGIN - MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "&Resizeable window", IDM_VID_RESIZE MENUITEM "R&emember size && position", IDM_VID_REMEMBER MENUITEM SEPARATOR MENUITEM "&DirectDraw", IDM_VID_DDRAW @@ -100,42 +89,38 @@ BEGIN MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END MENUITEM "S&tatus", IDM_STATUS -#ifdef ENABLE_LOG_TOGGLES -# if defined(ENABLE_BUSLOGIC_LOG) || defined(ENABLE_CDROM_LOG) || \ - defined(ENABLE_D86F_LOG) || defined(ENABLE_FDC_LOG) || \ - defined(ENABLE_IDE_LOG) || defined(ENABLE_NE2000_LOG) - MENUITEM SEPARATOR -# endif + END + POPUP "&Logging" + BEGIN #ifdef ENABLE_BUSLOGIC_LOG - MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC + MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC #endif #ifdef ENABLE_CDROM_LOG - MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM + MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM #endif #ifdef ENABLE_D86F_LOG - MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F + MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F #endif #ifdef ENABLE_FDC_LOG - MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC + MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC #endif #ifdef ENABLE_IDE_LOG - MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE + MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE #endif -#ifdef ENABLE_NE2000_LOG - MENUITEM "Enable NE2000 logs\tCtrl+F9", IDM_LOG_NE2000 +#ifdef ENABLE_SERIAL_LOG + MENUITEM "Enable Serial Port logs\tCtrl+F3", IDM_LOG_SERIAL #endif +#ifdef ENABLE_NIC_LOG + MENUITEM "Enable Network logs\tCtrl+F9", IDM_LOG_NIC #endif -#ifdef ENABLE_LOG_BREAKPOINT - MENUITEM SEPARATOR - MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT -#ifdef ENABLE_VRAM_DUMP - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif -#else -#ifdef ENABLE_VRAM_DUMP - MENUITEM SEPARATOR - MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM -#endif +#if defined(ENABLE_LOG_BREAKPOINT) || defined(ENABLE_VRAM_DUMP) + MENUITEM SEPARATOR +# ifdef ENABLE_LOG_BREAKPOINT + MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT +# endif +# ifdef ENABLE_VRAM_DUMP + MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +# endif #endif END POPUP "&Help" @@ -153,30 +138,33 @@ END MAINACCEL ACCELERATORS MOVEABLE PURE BEGIN #ifdef ENABLE_VRAM_DUMP - VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY + VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY #endif #ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG - VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_CDROM_LOG - VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_D86F_LOG - VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_FDC_LOG - VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_IDE_LOG - VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY -#endif -#ifdef ENABLE_NE2000_LOG - VK_F9, IDM_LOG_NE2000, CONTROL, VIRTKEY -#endif +# ifdef ENABLE_SERIAL_LOG + VK_F3, IDM_LOG_SERIAL, CONTROL, VIRTKEY +# endif +# ifdef ENABLE_BUSLOGIC_LOG + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY +# endif +# ifdef ENABLE_CDROM_LOG + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY +# endif +# ifdef ENABLE_D86F_LOG + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY +# endif +# ifdef ENABLE_FDC_LOG + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY +# endif +# ifdef ENABLE_IDE_LOG + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY +# endif +# ifdef ENABLE_NIC_LOG + VK_F9, IDM_LOG_NIC, CONTROL, VIRTKEY +# endif #endif #ifdef ENABLE_LOG_BREAKPOINT - VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY #endif VK_PRIOR, IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL @@ -188,8 +176,30 @@ END // // Dialog // +DLG_ABOUT DIALOG DISCARDABLE 0, 0, 209, 114 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About 86Box" +FONT 9, "Segoe UI" +BEGIN + DEFPUSHBUTTON "OK",IDOK,129,94,71,12 + ICON 100,IDC_ABOUT_ICON,7,7,20,20 + LTEXT "86Box v2.00 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + IDC_ABOUT_ICON,54,7,146,73 + CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, + 86,208,1 +END -CONFIGUREDLG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 +DLG_STATUS DIALOG DISCARDABLE 0, 0, 186, 386 +STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Status" +FONT 9, "Segoe UI" +BEGIN + LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 + LTEXT "1",IDC_STEXT1,16,186,180,1000 +END + + +DLG_CFG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "86Box Settings" FONT 9, "Segoe UI" @@ -199,12 +209,180 @@ BEGIN CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,197 CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 - LTEXT "Language:",2047,7,222,41,10 + LTEXT "Language:",IDS_LANG_ENUS,7,222,41,10 COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP END -CONFIGUREDLG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 +DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Machine:",1794,7,8,60,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 + COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU type:",1796,7,26,59,10 + COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",1798,7,45,60,10 + COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "CPU:",1797,124,26,18,10 + CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,147,80,113,10 + EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, + 12,12 + LTEXT "MB",IDC_TEXT_MB,123,64,10,10 + LTEXT "Memory:",1802,7,64,30,10 + CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 +END + +DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video:",1795,7,8,55,10 + COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Video speed:",1800,7,26,58,10 + CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 + PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 +END + +DLG_CFG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Mouse :",IDC_STATIC,7,8,57,10 + COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | + WS_TABSTOP + LTEXT "Joystick :",1793,7,26,58,10 + COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 + PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 + DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 + PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 +END + +DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 98 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Sound card:",1800,7,8,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 + COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "MIDI Out Device:",1801,7,26,59,10 + + CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MPU401,214,44,46,12 + + CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,63,94,10 + CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,63,94,10 + + CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10 + CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 +END + +DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "Network type:",1800,7,8,59,10 + COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "PCap device:",1801,7,26,59,10 + COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + + LTEXT "Network adapter:",1802,7,44,59,10 + COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 +END + +DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + LTEXT "SCSI Controller:",1804,7,8,59,10 + COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 + + LTEXT "HD Controller:",1799,7,26,61,10 + COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Tertiary IDE:",1802,7,44,61,10 + COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + LTEXT "Quaternary IDE:",1803,7,62,61,10 + COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + + CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 + CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 + + CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 + CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 +END + +DLG_CFG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 +STYLE DS_CONTROL | WS_CHILD +FONT 9, "Segoe UI" +BEGIN + CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | + LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | + WS_TABSTOP,7,18,253,92 + LTEXT "Hard disks:",-1,7,7,34,8 + PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 + PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 + PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 + COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Bus:",1798,7,118,24,8 + COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1799,131,118,38,8 + COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "ID:",1800,131,118,38,8 + COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "LUN:",1801,200,118,38,8 + COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | + WS_VSCROLL | WS_TABSTOP + LTEXT "Channel:",1802,131,118,38,8 +END + +DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Add Hard Disk" FONT 9, "Segoe UI" @@ -242,197 +420,7 @@ BEGIN LTEXT "Channel:",1802,99,72,34,8 END -STATUSDLG DIALOG DISCARDABLE 0, 0, 186, 386 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Status" -FONT 9, "Segoe UI" -BEGIN - LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 - LTEXT "1",IDC_STEXT1,16,186,180,1000 -END - -ABOUTDLG DIALOG DISCARDABLE 0, 0, 209, 114 -STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "About 86Box" -FONT 9, "Segoe UI" -BEGIN - DEFPUSHBUTTON "OK",IDOK,129,94,71,12 - ICON 100,IDC_ABOUT_ICON,7,7,20,20 - LTEXT "86Box v1.20 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", - IDC_ABOUT_ICON,54,7,146,73 - CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, - 86,208,1 -END - -CONFIGUREDLG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Machine:",1794,7,8,60,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 - COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU type:",1796,7,26,59,10 - COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Wait states:",1798,7,45,60,10 - COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "CPU:",1797,124,26,18,10 - CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,147,80,113,10 - EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER - CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, - 12,12 - LTEXT "MB",IDC_TEXT_MB,123,64,10,10 - LTEXT "Memory:",1802,7,64,30,10 - CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 -END - -CONFIGUREDLG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video:",1795,7,8,55,10 - COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Video speed:",1800,7,26,58,10 - CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 - PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 -END - -CONFIGUREDLG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Mouse :",IDC_STATIC,7,8,57,10 - COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | - WS_TABSTOP - LTEXT "Joystick :",1793,7,26,58,10 - COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 - PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 - PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 -END - -CONFIGUREDLG_SOUND DIALOG DISCARDABLE 97, 0, 267, 98 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Sound card:",1800,7,8,59,10 - PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 - COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "MIDI Out Device:",1801,7,26,59,10 - - CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_MPU401,214,44,46,12 - - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,63,94,10 - CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,63,94,10 - - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10 - CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 -END - -CONFIGUREDLG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "Network type:",1800,7,8,59,10 - COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "PCap device:",1801,7,26,59,10 - COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - - LTEXT "Network adapter:",1802,7,44,59,10 - COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 -END - -CONFIGUREDLG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - LTEXT "SCSI Controller:",1804,7,8,59,10 - COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 - - LTEXT "HD Controller:",1799,7,26,61,10 - COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Tertiary IDE:",1802,7,44,61,10 - COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - LTEXT "Quaternary IDE:",1803,7,62,61,10 - COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - - CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 - - CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 - CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 -END - -CONFIGUREDLG_HARD_DISKS DIALOG DISCARDABLE 97, 0, 267, 154 -STYLE DS_CONTROL | WS_CHILD -FONT 9, "Segoe UI" -BEGIN - CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | - LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | - WS_TABSTOP,7,18,253,92 - LTEXT "Hard disks:",-1,7,7,34,8 - PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 - PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 - PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 - COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,118,24,8 - COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,131,118,38,8 - COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,118,38,8 - COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,118,38,8 - COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,118,38,8 -END - -CONFIGUREDLG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 +DLG_CFG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN @@ -829,7 +817,7 @@ BEGIN IDS_2173"All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" IDS_2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" IDS_2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" - IDS_2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + IDS_2176 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" IDS_2177 "Olivetti M24 mouse" IDS_2178 "This image exists and will be overwritten.\nAre you sure you want to use it?" IDS_2179 "Floppy %i (%s): %ws" @@ -846,7 +834,7 @@ BEGIN IDS_2190 "ATAPI (PIO and DMA)" IDS_2191 "ATAPI (PIO-only) (%01i:%01i)" IDS_2192 "ATAPI (PIO and DMA) (%01i:%01i)" - IDS_2193 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" + IDS_2193 "Use CTRL+ALT+PAGE DOWN to return to windowed mode" IDS_2194 "Unable to create bitmap file: %s" IDS_2195 "IDE (PIO-only) (%01i:%01i)" IDS_2196 "Add New Hard Disk" @@ -942,4 +930,3 @@ END ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED - diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 52edb590a..b89a90fd3 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -8,31 +8,38 @@ * * Windows resource defines. * - * Version: @(#)resource.h 1.0.1 2017/05/30 + * NOTE: Strings 2176 and 2193 are same. * - * Author: Sarah Walker, + * Version: @(#)resource.h 1.0.2 2017/06/03 + * + * Authors: Sarah Walker, * Miran Grca, + * Fred N. van Kempem, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef WIN_RESOURCE_H +# define WIN_RESOURCE_H + /* {{NO_DEPENDENCIES}} Microsoft Developer Studio generated include file. Used by 86Box.rc */ -#define IDHDCONFIG 3 -#define IDCDCONFIG 4 -#define CONFIGUREDLG_MACHINE 101 -#define CONFIGUREDLG_VIDEO 102 -#define CONFIGUREDLG_INPUT 103 -#define CONFIGUREDLG_SOUND 104 -#define CONFIGUREDLG_NETWORK 105 -#define CONFIGUREDLG_PERIPHERALS 106 -#define CONFIGUREDLG_HARD_DISKS 107 -#define CONFIGUREDLG_REMOVABLE_DEVICES 108 -#define ABOUTDLG 109 -#define CONFIGUREDLG_HARD_DISKS_ADD 110 -#define CONFIGUREDLG_MAIN 117 + +#define DLG_ABOUT 101 +#define DLG_STATUS 102 +#define DLG_CONFIG 110 +#define DLG_CFG_MACHINE 111 +#define DLG_CFG_VIDEO 112 +#define DLG_CFG_INPUT 113 +#define DLG_CFG_SOUND 114 +#define DLG_CFG_NETWORK 115 +#define DLG_CFG_PERIPHERALS 116 +#define DLG_CFG_HARD_DISKS 117 +#define DLG_CFG_HARD_DISKS_ADD 118 +#define DLG_CFG_REMOVABLE_DEVICES 119 + #define IDC_SETTINGSCATLIST 1004 #define IDC_LIST_HARD_DISKS 1005 #define IDC_COMBO_MACHINE 1006 @@ -66,7 +73,7 @@ #define IDC_BUTTON_HDD_ADD 1028 #define IDC_BUTTON_CDROM_REMOVE 1029 #define IDC_BUTTON_HDD_REMOVE 1029 -#define IDC_CHECKTURBO 1030 +#define IDC_CHECKTURBO 1030 #define IDC_HDIMAGE_NEW 1035 #define IDC_HD_BUS 1036 #define IDC_HDIMAGE_EXISTING 1037 @@ -102,196 +109,186 @@ #define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 #define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 -#define IDS_STRINGS 2048 -#define IDS_2049 2049 -#define IDS_2050 2050 -#define IDS_2051 2051 -#define IDS_2052 2052 -#define IDS_2053 2053 -#define IDS_2054 2054 -#define IDS_2055 2055 -#define IDS_2056 2056 -#define IDS_2057 2057 -#define IDS_2058 2058 -#define IDS_2059 2059 -#define IDS_2060 2060 -#define IDS_2061 2061 -#define IDS_2062 2062 -#define IDS_2063 2063 -#define IDS_2064 2064 -#define IDS_2065 2065 -#define IDS_2066 2066 -#define IDS_2067 2067 -#define IDS_2068 2068 -#define IDS_2069 2069 -#define IDS_2070 2070 -#define IDS_2071 2071 -#define IDS_2072 2072 -#define IDS_2073 2073 -#define IDS_2074 2074 -#define IDS_2075 2075 -#define IDS_2076 2076 -#define IDS_2077 2077 -#define IDS_2078 2078 -#define IDS_2079 2079 -#define IDS_2080 2080 -#define IDS_2081 2081 -#define IDS_2082 2082 -#define IDS_2083 2083 -#define IDS_2084 2084 -#define IDS_2085 2085 -#define IDS_2086 2086 -#define IDS_2087 2087 -#define IDS_2088 2088 -#define IDS_2089 2089 -#define IDS_2090 2090 -#define IDS_2091 2091 -#define IDS_2092 2092 -#define IDS_2093 2093 -#define IDS_2094 2094 -#define IDS_2095 2095 -#define IDS_2096 2096 -#define IDS_2097 2097 -#define IDS_2098 2098 -#define IDS_2099 2099 -#define IDS_2100 2100 -#define IDS_2101 2101 -#define IDS_2102 2102 -#define IDS_2103 2103 -#define IDS_2104 2104 -#define IDS_2105 2105 -#define IDS_2106 2106 -#define IDS_2107 2107 -#define IDS_2108 2108 -#define IDS_2109 2109 -#define IDS_2110 2110 -#define IDS_2111 2111 -#define IDS_2112 2112 -#define IDS_2113 2113 -#define IDS_2114 2114 -#define IDS_2115 2115 -#define IDS_2116 2116 -#define IDS_2117 2117 -#define IDS_2118 2118 -#define IDS_2119 2119 -#define IDS_2120 2120 -#define IDS_2121 2121 -#define IDS_2122 2122 -#define IDS_2123 2123 -#define IDS_2124 2124 -#define IDS_2125 2125 -#define IDS_2126 2126 -#define IDS_2127 2127 -#define IDS_2128 2128 -#define IDS_2129 2129 -#define IDS_2130 2130 -#define IDS_2131 2131 -#define IDS_2132 2132 -#define IDS_2133 2133 -#define IDS_2134 2134 -#define IDS_2135 2135 -#define IDS_2136 2136 -#define IDS_2137 2137 -#define IDS_2138 2138 -#define IDS_2139 2139 -#define IDS_2140 2140 -#define IDS_2141 2141 -#define IDS_2142 2142 -#define IDS_2143 2143 -#define IDS_2144 2144 -#define IDS_2145 2145 -#define IDS_2146 2146 -#define IDS_2147 2147 -#define IDS_2148 2148 -#define IDS_2149 2149 -#define IDS_2150 2150 -#define IDS_2151 2151 -#define IDS_2152 2152 -#define IDS_2153 2153 -#define IDS_2154 2154 -#define IDS_2155 2155 -#define IDS_2156 2156 -#define IDS_2157 2157 -#define IDS_2158 2158 -#define IDS_2159 2159 -#define IDS_2160 2160 -#define IDS_2161 2161 -#define IDS_2162 2162 -#define IDS_2163 2163 -#define IDS_2164 2164 -#define IDS_2165 2165 -#define IDS_2166 2166 -#define IDS_2167 2167 -#define IDS_2168 2168 -#define IDS_2169 2169 -#define IDS_2170 2170 -#define IDS_2171 2171 -#define IDS_2172 2172 -#define IDS_2173 2173 -#define IDS_2174 2174 -#define IDS_2175 2175 -#define IDS_2176 2176 -#define IDS_2177 2177 -#define IDS_2178 2178 -#define IDS_2179 2179 -#define IDS_2180 2180 -#define IDS_2181 2181 -#define IDS_2182 2182 -#define IDS_2183 2183 -#define IDS_2184 2184 -#define IDS_2185 2185 -#define IDS_2186 2186 -#define IDS_2187 2187 -#define IDS_2188 2188 -#define IDS_2189 2189 -#define IDS_2190 2190 -#define IDS_2191 2191 -#define IDS_2192 2192 -#define IDS_2193 2193 -#define IDS_2194 2194 -#define IDS_2195 2195 -#define IDS_2196 2196 -#define IDS_2197 2197 -#define IDS_2198 2198 -#define IDS_2199 2199 -#define IDS_2200 2200 -#define IDS_2201 2201 -#define IDS_2202 2202 -#define IDS_2203 2203 -#define IDS_2204 2204 -#define IDS_2205 2205 -#define IDS_2206 2206 -#define IDS_2207 2207 -#define IDS_2208 2208 -#define IDS_2209 2209 -#define IDS_2200 2200 -#define IDS_2201 2201 -#define IDS_2202 2202 -#define IDS_2203 2203 -#define IDS_2204 2204 -#define IDS_2205 2205 -#define IDS_2206 2206 -#define IDS_2207 2207 -#define IDS_2208 2208 -#define IDS_2209 2209 -#define IDS_2210 2210 -#define IDS_2211 2211 -#define IDS_2212 2212 -#define IDS_2213 2213 -#define IDS_2214 2214 -#define IDS_2215 2215 -#define IDS_2216 2216 -#define IDS_2217 2217 -#define IDS_2218 2218 -#define IDS_2219 2219 -#define IDS_2220 2220 -#define IDS_2221 2221 -#define IDS_2222 2222 -#define IDS_2223 2223 -#define IDS_2224 2224 -#define IDS_2225 2225 +#define IDS_STRINGS 2048 // "86Box" +#define IDS_2049 2049 // "86Box Error" +#define IDS_2050 2050 // "86Box Fatal Error" +#define IDS_2051 2051 // "This will reset 86Box.." +#define IDS_2052 2052 // "DirectDraw Screenshot Error" +#define IDS_2053 2053 // "Invalid number of sectors.." +#define IDS_2054 2054 // "Invalid number of heads.." +#define IDS_2055 2055 // "Invalid number of cylinders.." +#define IDS_2056 2056 // "Please enter a valid file name" +#define IDS_2057 2057 // "Unable to open the file for write" +#define IDS_2058 2058 // "Attempting to create a HDI.." +#define IDS_2059 2059 // "Remember to partition and.." +#define IDS_2060 2060 // "Unable to open the file.." +#define IDS_2061 2061 // "HDI or HDX image with a.." +#define IDS_2062 2062 // "86Box was unable to find any.." +#define IDS_2063 2063 // "Configured ROM set not avai.." +#define IDS_2064 2064 // "Configured video BIOS not.." +#define IDS_2065 2065 // "Machine" +#define IDS_2066 2066 // "Video" +#define IDS_2067 2067 // "Input devices" +#define IDS_2068 2068 // "Sound" +#define IDS_2069 2069 // "Network" +#define IDS_2070 2070 // "Other peripherals" +#define IDS_2071 2071 // "Hard disks" +#define IDS_2072 2072 // "Removable devices" +#define IDS_2073 2073 // "%i"" floppy drive: %s" +#define IDS_2074 2074 // "Disabled CD-ROM drive" +#define IDS_2075 2075 // "%s CD-ROM drive: %s" +#define IDS_2076 2076 // "Host CD/DVD Drive (%c:)" +#define IDS_2077 2077 // "Click to capture mouse" +#define IDS_2078 2078 // "Press F12-F8 to release mouse" +#define IDS_2079 2079 // "Press F12-F8 or middle button.." +#define IDS_2080 2080 // "Drive" +#define IDS_2081 2081 // "Location" +#define IDS_2082 2082 // "Bus" +#define IDS_2083 2083 // "File" +#define IDS_2084 2084 // "C" +#define IDS_2085 2085 // "H" +#define IDS_2086 2086 // "S" +#define IDS_2087 2087 // "MB" +#define IDS_2088 2088 // "%i" +#define IDS_2089 2089 // "Enabled" +#define IDS_2090 2090 // "Mute" +#define IDS_2091 2091 // "Type" +#define IDS_2092 2092 // "Bus" +#define IDS_2093 2093 // "DMA" +#define IDS_2094 2094 // "KB" +#define IDS_2095 2095 // "MFM, RLL, or ESDI CD-ROM.." +#define IDS_2096 2096 // "Slave" +#define IDS_2097 2097 // "SCSI (ID %s, LUN %s)" +#define IDS_2098 2098 // "Adapter Type" +#define IDS_2099 2099 // "Base Address" +#define IDS_2100 2100 // "IRQ" +#define IDS_2101 2101 // "8-bit DMA" +#define IDS_2102 2102 // "16-bit DMA" +#define IDS_2103 2103 // "BIOS" +#define IDS_2104 2104 // "Network Type" +#define IDS_2105 2105 // "Surround Module" +#define IDS_2106 2106 // "MPU-401 Base Address" +#define IDS_2107 2107 // "No PCap devices found" +#define IDS_2108 2108 // "On-board RAM" +#define IDS_2109 2109 // "Memory Size" +#define IDS_2110 2110 // "Display Type" +#define IDS_2111 2111 // "RGB" +#define IDS_2112 2112 // "Composite" +#define IDS_2113 2113 // "Composite Type" +#define IDS_2114 2114 // "Old" +#define IDS_2115 2115 // "New" +#define IDS_2116 2116 // "RGB Type" +#define IDS_2117 2117 // "Color" +#define IDS_2118 2118 // "Monochrome (Green)" +#define IDS_2119 2119 // "Monochrome (Amber)" +#define IDS_2120 2120 // "Monochrome (Gray)" +#define IDS_2121 2121 // "Color (no brown)" +#define IDS_2122 2122 // "Monochrome (Default)" +#define IDS_2123 2123 // "Snow Emulation" +#define IDS_2124 2124 // "Bilinear Filtering" +#define IDS_2125 2125 // "Dithering" +#define IDS_2126 2126 // "Framebuffer Memory Size" +#define IDS_2127 2127 // "Texture Memory Size" +#define IDS_2128 2128 // "Screen Filter" +#define IDS_2129 2129 // "Render Threads" +#define IDS_2130 2130 // "Recompiler" +#define IDS_2131 2131 // "System Default" +#define IDS_2132 2132 // "%i Wait state(s)" +#define IDS_2133 2133 // "8-bit" +#define IDS_2134 2134 // "Slow 16-bit" +#define IDS_2135 2135 // "Fast 16-bit" +#define IDS_2136 2136 // "Slow VLB/PCI" +#define IDS_2137 2137 // "Mid VLB/PCI" +#define IDS_2138 2138 // "Fast VLB/PCI" +#define IDS_2139 2139 // "Microsoft 2-button mouse (serial)" +#define IDS_2140 2140 // "Mouse Systems mouse (serial)" +#define IDS_2141 2141 // "2-button mouse (PS/2)" +#define IDS_2142 2142 // "Microsoft Intellimouse (PS/2)" +#define IDS_2143 2143 // "Bus mouse" +#define IDS_2144 2144 // "Standard 2-button joystick(s)" +#define IDS_2145 2145 // "Standard 4-button joystick" +#define IDS_2146 2146 // "Standard 6-button joystick" +#define IDS_2147 2147 // "Standard 8-button joystick" +#define IDS_2148 2148 // "CH Flightstick Pro" +#define IDS_2149 2149 // "Microsoft SideWinder Pad" +#define IDS_2150 2150 // "Thrustmaster Flight Control System" +#define IDS_2151 2151 // "Disabled" +#define IDS_2152 2152 // "None" +#define IDS_2153 2153 // "AT Fixed Disk Adapter" +#define IDS_2154 2154 // "Internal IDE" +#define IDS_2155 2155 // "IRQ %i" +#define IDS_2156 2156 // "MFM (%01i:%01i)" +#define IDS_2157 2157 // "IDE (PIO+DMA) (%01i:%01i)" +#define IDS_2158 2158 // "SCSI (%02i:%02i)" +#define IDS_2159 2159 // "Invalid number of cylinders.." +#define IDS_2160 2160 // "%" PRIu64 +#define IDS_2161 2161 // "Genius Bus mouse" +#define IDS_2162 2162 // "Amstrad mouse" +#define IDS_2163 2163 // "Attempting to create a spuriously.." +#define IDS_2164 2164 // "Invalid number of sectors.." +#define IDS_2165 2165 // "MFM" +#define IDS_2166 2166 // "XT IDE" +#define IDS_2167 2167 // "RLL" +#define IDS_2168 2168 // "IDE (PIO-only)" +#define IDS_2169 2169 // "%01i:%01i" +#define IDS_2170 2170 // "Custom..." +#define IDS_2171 2171 // "%" PRIu64 " MB (CHS: %" .. +#define IDS_2172 2172 // "Hard disk images .." +#define IDS_2173 2173 // "All floppy images .." +#define IDS_2174 2174 // "Configuration files .." +#define IDS_2175 2175 // "CD-ROM image .." +#define IDS_2176 2176 // "Use CTRL+ALT+PAGE DOWN .." +#define IDS_2177 2177 // "Olivetti M24 mouse" +#define IDS_2178 2178 // "This image exists and will.." +#define IDS_2179 2179 // "Floppy %i (%s): %ws" +#define IDS_2180 2180 // "CD-ROM %i: %ws" +#define IDS_2181 2181 // "MFM hard disk" +#define IDS_2182 2182 // "IDE hard disk (PIO-only)" +#define IDS_2183 2183 // "IDE hard disk (PIO and DMA)" +#define IDS_2184 2184 // "SCSI hard disk" +#define IDS_2185 2185 // "(empty)" +#define IDS_2186 2186 // "(host drive %c:)" +#define IDS_2187 2187 // "Custom (large)..." +#define IDS_2188 2188 // "Type" +#define IDS_2189 2189 // "ATAPI (PIO-only)" +#define IDS_2190 2190 // "ATAPI (PIO and DMA)" +#define IDS_2191 2191 // "ATAPI (PIO-only) (%01i:%01i)" +#define IDS_2192 2192 // "ATAPI (PIO and DMA) (%01i:%01i)" +#define IDS_2193 2193 // "Use CTRL+ALT+PAGE DOWN to .." +#define IDS_2194 2194 // "Unable to create bitmap file: %s" +#define IDS_2195 2195 // "IDE (PIO-only) (%01i:%01i)" +#define IDS_2196 2196 // "Add New Hard Disk" +#define IDS_2197 2197 // "Add Existing Hard Disk" +#define IDS_2198 2198 // "SCSI removable disk %i: %s" +#define IDS_2199 2199 // "USB is not yet supported" +#define IDS_2200 2200 // "Invalid PCap device" +#define IDS_2201 2201 // "&Notify disk change" +#define IDS_2202 2202 // "SCSI (removable)" +#define IDS_2203 2203 // "SCSI (removable) (%02i:%02i)" +#define IDS_2204 2204 // "Pcap Library Not Available" +#define IDS_2205 2205 // "RLL (%01i:%01i)" +#define IDS_2206 2206 // "XT IDE (%01i:%01i)" +#define IDS_2207 2207 // "RLL hard disk" +#define IDS_2208 2208 // "XT IDE hard disk" +#define IDS_2209 2209 // "IDE (PIO and DMA)" +#define IDS_2210 2210 // "SCSI" +#define IDS_2211 2211 // "&New image..." +#define IDS_2212 2212 // "Existing image..." +#define IDS_2213 2213 // "Existing image (&Write-.." +#define IDS_2214 2214 // "E&ject" +#define IDS_2215 2215 // "&Mute" +#define IDS_2216 2216 // "E&mpty" +#define IDS_2217 2217 // "&Reload previous image" +#define IDS_2218 2218 // "&Image..." +#define IDS_2219 2219 // "PCap failed to set up .." +#define IDS_2220 2220 // "Image (&Write-protected)..." +#define IDS_2221 2221 // "Turbo" +#define IDS_2222 2222 // "On" +#define IDS_2223 2223 // "Off" +#define IDS_2224 2224 // "" +#define IDS_2225 2225 // "English (United States)" -#define IDS_LANG_ENUS IDS_2225 +#define IDS_LANG_ENUS IDS_2225 #define IDM_ABOUT 40001 @@ -341,25 +338,26 @@ #define IDM_IDE_QUA_IRQ14 44033 #define IDM_IDE_QUA_IRQ15 44035 -#ifdef ENABLE_LOG_TOGGLES -# ifdef ENABLE_BUSLOGIC_LOG -# define IDM_LOG_BUSLOGIC 51200 -# endif -# ifdef ENABLE_CDROM_LOG -# define IDM_LOG_CDROM 51201 -# endif -# ifdef ENABLE_D86F_LOG -# define IDM_LOG_D86F 51202 -# endif -# ifdef ENABLE_FDC_LOG -# define IDM_LOG_FDC 51203 -# endif -# ifdef ENABLE_IDE_LOG -# define IDM_LOG_IDE 51204 -# endif -# ifdef ENABLE_NE2000_LOG -# define IDM_LOG_NE2000 51205 -# endif +#ifdef ENABLE_BUSLOGIC_LOG +# define IDM_LOG_BUSLOGIC 51200 +#endif +#ifdef ENABLE_CDROM_LOG +# define IDM_LOG_CDROM 51201 +#endif +#ifdef ENABLE_D86F_LOG +# define IDM_LOG_D86F 51202 +#endif +#ifdef ENABLE_FDC_LOG +# define IDM_LOG_FDC 51203 +#endif +#ifdef ENABLE_IDE_LOG +# define IDM_LOG_IDE 51204 +#endif +#ifdef ENABLE_NIC_LOG +# define IDM_LOG_NIC 51205 +#endif +#ifdef ENABLE_SERIAL_LOG +# define IDM_LOG_SERIAL 51208 #endif #ifdef ENABLE_LOG_BREAKPOINT # define IDM_LOG_BREAKPOINT 51206 @@ -368,81 +366,81 @@ # define IDM_DUMP_VRAM 51207 #endif -#define IDC_COMBO1 1000 -#define IDC_COMBOVID 1001 -#define IDC_COMBO3 1002 -#define IDC_COMBO4 1003 -#define IDC_COMBO5 1004 -#define IDC_COMBO386 1005 -#define IDC_COMBO486 1006 -#define IDC_COMBOSND 1007 -#define IDC_COMBONETTYPE 1008 -#define IDC_COMBOPCAP 1009 -#define IDC_COMBONET 1010 -#define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODR1 1062 -#define IDC_COMBODR2 1063 -#define IDC_COMBODR3 1064 -#define IDC_COMBODR4 1065 -#define IDC_COMBOJOY 1066 -#define IDC_COMBOWS 1067 -#define IDC_COMBOMOUSE 1068 -#define IDC_COMBOHDD 1069 -#define IDC_CHECK1 1010 -#define IDC_CHECK2 1011 -#define IDC_CHECK3 1012 -#define IDC_CHECKSSI 1014 -#define IDC_CHECKVOODOO 1015 -#define IDC_CHECKDYNAREC 1016 -#define IDC_CHECKBUSLOGIC 1017 -#define IDC_CHECKSYNC 1024 -#define IDC_CHECKXTIDE 1025 -#define IDC_CHECKFPU 1026 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_COMBOHDT 1036 +#define IDC_COMBO1 1000 +#define IDC_COMBOVID 1001 +#define IDC_COMBO3 1002 +#define IDC_COMBO4 1003 +#define IDC_COMBO5 1004 +#define IDC_COMBO386 1005 +#define IDC_COMBO486 1006 +#define IDC_COMBOSND 1007 +#define IDC_COMBONETTYPE 1008 +#define IDC_COMBOPCAP 1009 +#define IDC_COMBONET 1010 /*FIXME*/ +#define IDC_CHECK1 1010 /*FIXME*/ +#define IDC_CHECK2 1011 +#define IDC_CHECK3 1012 +#define IDC_CHECKSSI 1014 +#define IDC_CHECKVOODOO 1015 +#define IDC_CHECKDYNAREC 1016 +#define IDC_CHECKBUSLOGIC 1017 +#define IDC_CHECKSYNC 1024 +#define IDC_CHECKXTIDE 1025 +#define IDC_CHECKFPU 1026 +#define IDC_EDIT1 1030 +#define IDC_EDIT2 1031 +#define IDC_EDIT3 1032 +#define IDC_EDIT4 1033 +#define IDC_EDIT5 1034 +#define IDC_EDIT6 1035 +#define IDC_COMBOHDT 1036 +#define IDC_COMBOCPUM 1060 +#define IDC_COMBOSPD 1061 +#define IDC_COMBODR1 1062 +#define IDC_COMBODR2 1063 +#define IDC_COMBODR3 1064 +#define IDC_COMBODR4 1065 +#define IDC_COMBOJOY 1066 +#define IDC_COMBOWS 1067 +#define IDC_COMBOMOUSE 1068 +#define IDC_COMBOHDD 1069 -#define IDC_CFILE 1060 +#define IDC_CFILE 1060 -#define IDC_HDTYPE 1280 +#define IDC_HDTYPE 1280 -#define IDC_RENDER 1281 -#define IDC_STATUS 1282 +#define IDC_RENDER 1281 +#define IDC_STATUS 1282 -#define IDC_MEMSPIN 1100 -#define IDC_MEMTEXT 1101 -#define IDC_STEXT1 1102 -#define IDC_STEXT2 1103 -#define IDC_STEXT3 1104 -#define IDC_STEXT4 1105 -#define IDC_STEXT5 1106 -#define IDC_STEXT6 1107 -#define IDC_STEXT7 1108 -#define IDC_STEXT8 1109 -#define IDC_STEXT_DEVICE 1110 -#define IDC_TEXT_MB 1111 -#define IDC_TEXT1 1115 -#define IDC_TEXT2 1116 +#define IDC_MEMSPIN 1100 +#define IDC_MEMTEXT 1101 +#define IDC_STEXT1 1102 +#define IDC_STEXT2 1103 +#define IDC_STEXT3 1104 +#define IDC_STEXT4 1105 +#define IDC_STEXT5 1106 +#define IDC_STEXT6 1107 +#define IDC_STEXT7 1108 +#define IDC_STEXT8 1109 +#define IDC_STEXT_DEVICE 1110 +#define IDC_TEXT_MB 1111 +#define IDC_TEXT1 1115 +#define IDC_TEXT2 1116 -#define IDC_CONFIGUREVID 1200 -#define IDC_CONFIGURESND 1201 -#define IDC_CONFIGUREVOODOO 1202 -#define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENETTYPE 1204 -#define IDC_CONFIGUREBUSLOGIC 1205 -#define IDC_CONFIGUREPCAP 1206 -#define IDC_CONFIGURENET 1207 -#define IDC_JOY1 1210 -#define IDC_JOY2 1211 -#define IDC_JOY3 1212 -#define IDC_JOY4 1213 +#define IDC_CONFIGUREVID 1200 +#define IDC_CONFIGURESND 1201 +#define IDC_CONFIGUREVOODOO 1202 +#define IDC_CONFIGUREMOD 1203 +#define IDC_CONFIGURENETTYPE 1204 +#define IDC_CONFIGUREBUSLOGIC 1205 +#define IDC_CONFIGUREPCAP 1206 +#define IDC_CONFIGURENET 1207 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 -#define IDC_CONFIG_BASE 1200 +#define IDC_CONFIG_BASE 1200 /* The biggest amount of low bits needed for CD-ROMS (2 bits for ID and 5 bits for host drive, so 7 bits), and removable disks (5 bits for ID), so we choose an 256-entry spacing for convenience. */ @@ -479,3 +477,6 @@ #endif #define STRINGS_NUM 178 + + +#endif /*WIN_RESOURCE_H*/ diff --git a/src/WIN/win.c b/src/WIN/win.c index c7dbdabe7..410774cf8 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -8,7 +8,7 @@ * * The Emulator's Windows core. * - * Version: @(#)win.c 1.0.0 2017/05/30 + * Version: @(#)win.c 1.0.1 2017/06/03 * * Authors: Sarah Walker, * Miran Grca, @@ -1407,7 +1407,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz menu = LoadMenu(hThisInstance, TEXT("MainMenu")); - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + _swprintf(emulator_title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); /* The class is registered, let's create the program*/ hwnd = CreateWindowEx ( @@ -1484,24 +1484,28 @@ int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpsz else SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX&~WS_MINIMIZEBOX)|WS_VISIBLE); #ifdef ENABLE_LOG_TOGGLES -#ifdef ENABLE_BUSLOGIC_LOG +# ifdef ENABLE_BUSLOGIC_LOG CheckMenuItem(menu, IDM_LOG_BUSLOGIC, buslogic_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_CDROM_LOG +# endif +# ifdef ENABLE_CDROM_LOG CheckMenuItem(menu, IDM_LOG_CDROM, cdrom_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_D86F_LOG +# endif +# ifdef ENABLE_D86F_LOG CheckMenuItem(menu, IDM_LOG_D86F, d86f_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_FDC_LOG +# endif +# ifdef ENABLE_FDC_LOG CheckMenuItem(menu, IDM_LOG_FDC, fdc_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_IDE_LOG +# endif +# ifdef ENABLE_IDE_LOG CheckMenuItem(menu, IDM_LOG_IDE, ide_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif -#ifdef ENABLE_NE2000_LOG - CheckMenuItem(menu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); -#endif +# endif +# ifdef ENABLE_SERIAL_LOG + CheckMenuItem(menu, IDM_LOG_SERIAL, serial_do_log ? MF_CHECKED : MF_UNCHECKED); +# endif +# ifdef ENABLE_NIC_LOG + /*FIXME: should be network_setlog(1:0) */ + CheckMenuItem(menu, IDM_LOG_NIC, nic_do_log ? MF_CHECKED : MF_UNCHECKED); +# endif #endif CheckMenuItem(menu, IDM_VID_FORCE43, force_43 ? MF_CHECKED : MF_UNCHECKED); @@ -1754,7 +1758,7 @@ static BOOL CALLBACK about_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARA void about_open(HWND hwnd) { - DialogBox(hinstance, (LPCTSTR) ABOUTDLG, hwnd, about_dlgproc); + DialogBox(hinstance, (LPCTSTR)DLG_ABOUT, hwnd, about_dlgproc); } static void win_pc_reset(int hard) @@ -1982,10 +1986,18 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; #endif -#ifdef ENABLE_NE2000_LOG - case IDM_LOG_NE2000: - ne2000_do_log ^= 1; - CheckMenuItem(hmenu, IDM_LOG_NE2000, ne2000_do_log ? MF_CHECKED : MF_UNCHECKED); +#ifdef ENABLE_SERIAL_LOG + case IDM_LOG_SERIAL: + serial_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_SERIAL, serial_do_log ? MF_CHECKED : MF_UNCHECKED); + break; +#endif + +#ifdef ENABLE_NIC_LOG + case IDM_LOG_NIC: + /*FIXME: should be network_setlog() */ + nic_do_log ^= 1; + CheckMenuItem(hmenu, IDM_LOG_NIC, nic_do_log ? MF_CHECKED : MF_UNCHECKED); break; #endif #endif diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 811dec696..0f894dc34 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -8,7 +8,7 @@ * * Direct3D 9 full screen rendererer and screenshots taking. * - * Version: @(#)win_d3d_fs.cc 1.0.0 2017/05/30 + * Version: @(#)win_d3d_fs.cc 1.0.1 2017/06/03 * * Authors: Sarah Walker, * Miran Grca, @@ -168,7 +168,8 @@ int d3d_fs_init(HWND h) d3d_hwnd = h; - _swprintf(emulator_title, L"86Box v%s", emulator_version_w); + /*FIXME: should be done once, in win.c */ + _swprintf(emulator_title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); d3d_device_window = CreateWindowEx ( 0, szSubClassName, diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 97cd7ed5b..392477e9d 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_midi.c 1.0.0 2017/05/30 + * Version: @(#)win_settings.c 1.0.1 2017/06/03 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -25,8 +25,8 @@ #include "../mem.h" #include "../cpu/cpu.h" #include "../nvr.h" -#include "../model.h" #include "../device.h" +#include "../model.h" #include "../cdrom.h" #include "../disc.h" #include "../fdd.h" @@ -3118,7 +3118,8 @@ void hard_disk_add_open(HWND hwnd, int is_existing) existing = is_existing; hard_disk_added = 0; - ret = DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); + ret = DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, + hwnd, win_settings_hard_disks_add_proc); } int ignore_change = 0; @@ -4077,28 +4078,28 @@ void win_settings_show_child(HWND hwndParent, DWORD child_id) switch(child_id) { case 0: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_MACHINE, hwndParent, win_settings_machine_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_MACHINE, hwndParent, win_settings_machine_proc); break; case 1: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_VIDEO, hwndParent, win_settings_video_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_VIDEO, hwndParent, win_settings_video_proc); break; case 2: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_INPUT, hwndParent, win_settings_input_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_INPUT, hwndParent, win_settings_input_proc); break; case 3: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_SOUND, hwndParent, win_settings_sound_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_SOUND, hwndParent, win_settings_sound_proc); break; case 4: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_NETWORK, hwndParent, win_settings_network_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_NETWORK, hwndParent, win_settings_network_proc); break; case 5: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_PERIPHERALS, hwndParent, win_settings_peripherals_proc); break; case 6: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS, hwndParent, win_settings_hard_disks_proc); break; case 7: - hwndChildDialog = CreateDialog(hinstance, (LPCWSTR) CONFIGUREDLG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); + hwndChildDialog = CreateDialog(hinstance, (LPCWSTR)DLG_CFG_REMOVABLE_DEVICES, hwndParent, win_settings_removable_devices_proc); break; default: fatal("Invalid child dialog ID\n"); @@ -4239,5 +4240,5 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar void win_settings_open(HWND hwnd) { - DialogBox(hinstance, (LPCWSTR) CONFIGUREDLG_MAIN, hwnd, win_settings_main_proc); + DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); } diff --git a/src/WIN/win_status.c b/src/WIN/win_status.c index 32012cb75..fbc1949ad 100644 --- a/src/WIN/win_status.c +++ b/src/WIN/win_status.c @@ -89,6 +89,6 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR void status_open(HWND hwnd) { - status_hwnd = CreateDialog(hinstance, TEXT("StatusDlg"), hwnd, status_dlgproc); + status_hwnd = CreateDialog(hinstance, (LPCSTR)DLG_STATUS, hwnd, status_dlgproc); ShowWindow(status_hwnd, SW_SHOW); } diff --git a/src/cdrom.c b/src/cdrom.c index 2f02f42cd..2bcfc20cc 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -9,12 +9,11 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.c 1.0.0 2017/05/30 + * Version: @(#)cdrom.c 1.0.1 2017/06/03 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. */ - #include #include #include @@ -28,7 +27,7 @@ #include "piix.h" #include "scsi.h" #include "timer.h" -#include "WIN/plat_iodev.h" +#include "win/plat_iodev.h" /* Bits of 'status' */ #define ERR_STAT 0x01 @@ -2341,9 +2340,9 @@ void cdrom_command(uint8_t id, uint8_t *cdb) device_identify[7] = id + 0x30; device_identify_ex[7] = id + 0x30; - device_identify_ex[10] = emulator_version[0]; - device_identify_ex[12] = emulator_version[2]; - device_identify_ex[13] = emulator_version[3]; + device_identify_ex[10] = EMU_VERSION[0]; + device_identify_ex[12] = EMU_VERSION[2]; + device_identify_ex[13] = EMU_VERSION[3]; cdrom[id].data_pos = 0; @@ -3196,7 +3195,7 @@ cdrom_readtoc_fallback: cdbufferb[idx++] = 0x01; cdbufferb[idx++] = 0x00; cdbufferb[idx++] = 68; - ide_padstr8(cdbufferb + idx, 8, "86Box"); /* Vendor */ + ide_padstr8(cdbufferb + idx, 8, EMU_NAME); /* Vendor */ idx += 8; ide_padstr8(cdbufferb + idx, 40, device_identify_ex); /* Product */ idx += 40; @@ -3221,9 +3220,9 @@ cdrom_readtoc_fallback: cdbufferb[3] = (cdrom_drives[id].bus_type == CDROM_BUS_SCSI) ? 0x02 : 0x21; cdbufferb[4] = 31; - ide_padstr8(cdbufferb + 8, 8, "86Box"); /* Vendor */ + ide_padstr8(cdbufferb + 8, 8, EMU_NAME); /* Vendor */ ide_padstr8(cdbufferb + 16, 16, device_identify); /* Product */ - ide_padstr8(cdbufferb + 32, 4, emulator_version); /* Revision */ + ide_padstr8(cdbufferb + 32, 4, EMU_VERSION); /* Revision */ idx = 36; } diff --git a/src/cdrom.h b/src/cdrom.h index 871dc1f02..5b7cb1f8b 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -9,17 +9,16 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)cdrom.h 1.0.0 2017/05/30 + * Version: @(#)cdrom.h 1.0.1 2017/06/03 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_CDROM_H +#define EMU_CDROM_H -#ifndef __CDROM_H__ -#define __CDROM_H__ -/*CD-ROM stuff*/ -#define CDROM_NUM 4 +#define CDROM_NUM 4 #define CDROM_PHASE_IDLE 0 #define CDROM_PHASE_COMMAND 1 @@ -37,8 +36,8 @@ #define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) #define CDROM_TIME (5 * 100 * (1 << TIMER_SHIFT)) -typedef struct CDROM -{ + +typedef struct { int (*ready)(uint8_t id); int (*medium_changed)(uint8_t id); int (*media_type_id)(uint8_t id); @@ -62,13 +61,8 @@ typedef struct CDROM void (*exit)(uint8_t id); } CDROM; -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute__((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { uint8_t previous_command; int toctimes; @@ -136,19 +130,10 @@ typedef struct __attribute__((__packed__)) int init_length; } cdrom_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -extern cdrom_t cdrom[CDROM_NUM]; - -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct -#else -typedef struct __attribute__((__packed__)) -#endif -{ +#pragma pack(push,1) +typedef struct { int max_blocks_at_once; CDROM *handler; @@ -168,22 +153,9 @@ typedef struct __attribute__((__packed__)) unsigned int sound_on; unsigned int atapi_dma; } cdrom_drive_t; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -extern cdrom_drive_t cdrom_drives[CDROM_NUM]; - -extern uint8_t atapi_cdrom_drives[8]; - -extern uint8_t scsi_cdrom_drives[16][8]; - -extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); -extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); -extern void (*ide_bus_master_set_irq)(int channel); - -typedef struct -{ +typedef struct { int image_is_iso; uint32_t last_block; @@ -200,10 +172,7 @@ typedef struct int cd_buflen; } cdrom_image_t; -cdrom_image_t cdrom_image[CDROM_NUM]; - -typedef struct -{ +typedef struct { uint32_t last_block; uint32_t cdrom_capacity; int ioctl_inited; @@ -223,20 +192,29 @@ typedef struct int last_subchannel_pos; } cdrom_ioctl_t; -void ioctl_close(uint8_t id); -cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; +extern cdrom_t cdrom[CDROM_NUM]; +extern cdrom_drive_t cdrom_drives[CDROM_NUM]; +extern uint8_t atapi_cdrom_drives[8]; +extern uint8_t scsi_cdrom_drives[16][8]; + cdrom_image_t cdrom_image[CDROM_NUM]; + cdrom_ioctl_t cdrom_ioctl[CDROM_NUM]; -uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel); -uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel); -void build_atapi_cdrom_map(); -void build_scsi_cdrom_map(); -int cdrom_CDROM_PHASE_to_scsi(uint8_t id); -int cdrom_atapi_phase_to_scsi(uint8_t id); -void cdrom_command(uint8_t id, uint8_t *cdb); -void cdrom_phase_callback(uint8_t id); -uint32_t cdrom_read(uint8_t channel, int length); -void cdrom_write(uint8_t channel, uint32_t val, int length); +extern int (*ide_bus_master_read)(int channel, uint8_t *data, int transfer_length); +extern int (*ide_bus_master_write)(int channel, uint8_t *data, int transfer_length); +extern void (*ide_bus_master_set_irq)(int channel); +extern void ioctl_close(uint8_t id); + +extern uint32_t cdrom_mode_sense_get_channel(uint8_t id, int channel); +extern uint32_t cdrom_mode_sense_get_volume(uint8_t id, int channel); +extern void build_atapi_cdrom_map(void); +extern void build_scsi_cdrom_map(void); +extern int cdrom_CDROM_PHASE_to_scsi(uint8_t id); +extern int cdrom_atapi_phase_to_scsi(uint8_t id); +extern void cdrom_command(uint8_t id, uint8_t *cdb); +extern void cdrom_phase_callback(uint8_t id); +extern uint32_t cdrom_read(uint8_t channel, int length); +extern void cdrom_write(uint8_t channel, uint32_t val, int length); #ifdef __cplusplus extern "C" { @@ -262,4 +240,5 @@ int find_cdrom_for_scsi_id(uint8_t scsi_id, uint8_t scsi_lun); #define cdrom_ascq cdrom[id].sense[13] #define cdrom_drive cdrom_drives[id].host_drive -#endif \ No newline at end of file + +#endif /*EMU_CDROM_H*/ diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index 408f691b7..201753e47 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -9,14 +9,13 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)cdrom_ioctl.c 1.0.1 2017/05/31 + * Version: @(#)cdrom_ioctl.c 1.0.2 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2016 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #define WINVER 0x0600 #include #include diff --git a/src/cdrom_ioctl.h b/src/cdrom_ioctl.h index a5c710230..b57689bf9 100644 --- a/src/cdrom_ioctl.h +++ b/src/cdrom_ioctl.h @@ -9,25 +9,27 @@ * Implementation of the CD-ROM host drive IOCTL interface for * Windows using SCSI Passthrough Direct. * - * Version: @(#)cdrom_ioctl.h 1.0.0 2017/05/30 + * This file lists the functions provided by various platform- + * specific cdrom-ioctl files. * - * Author: Sarah Walker, + * Version: @(#)cdrom_ioctl.h 1.0.1 2017/06/03 + * + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2016 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_CDROM_IOCTL_H +#define EMU_CDROM_IOCTL_H -#ifndef CDROM_IOCTL_H -#define CDROM_IOCTL_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ extern uint32_t cdrom_capacity; - -extern int ioctl_open(uint8_t id, char d); -extern void ioctl_reset(uint8_t id); -extern void ioctl_close(uint8_t id); -#endif /* ! CDROM_IOCTL_H */ +extern int ioctl_open(uint8_t id, char d); +extern void ioctl_reset(uint8_t id); + +extern void ioctl_close(uint8_t id); + + +#endif /*EMU_CDROM_IOCTL_H */ diff --git a/src/cdrom_null.c b/src/cdrom_null.c index c9d759bba..91acaf92f 100644 --- a/src/cdrom_null.c +++ b/src/cdrom_null.c @@ -9,20 +9,21 @@ * Implementation of the CD-ROM null interface for unmounted * guest CD-ROM drives. * - * Version: @(#)cdrom_null.c 1.0.0 2017/05/30 + * Version: @(#)cdrom_null.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2016 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include "ibm.h" #include "cdrom.h" #include "cdrom_ioctl.h" + static CDROM null_cdrom; + static int null_ready(uint8_t id) { return 0; diff --git a/src/cdrom_null.h b/src/cdrom_null.h index 69117d43f..75cc71da5 100644 --- a/src/cdrom_null.h +++ b/src/cdrom_null.h @@ -9,22 +9,20 @@ * Implementation of the CD-ROM null interface for unmounted * guest CD-ROM drives. * - * Version: @(#)cdrom_null.h 1.0.0 2017/05/30 + * Version: @(#)cdrom_null.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2016 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_CDROM_NULL_H +#define EMU_CDROM_NULL_H -#ifndef CDROM_NULL_H -#define CDROM_NULL_H -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ +extern int cdrom_null_open(uint8_t id, char d); +extern void cdrom_null_reset(uint8_t id); +extern void null_close(uint8_t id); -int cdrom_null_open(uint8_t id, char d); -void cdrom_null_reset(uint8_t id); -void null_close(uint8_t id); -#endif /* ! CDROM_NULL_H */ +#endif /*EMU_CDROM_NULL_H*/ diff --git a/src/device.c b/src/device.c index 1f7e5b577..9b90c9ea1 100644 --- a/src/device.c +++ b/src/device.c @@ -9,14 +9,13 @@ * Implementation of the generic device interface to handle * all devices attached to the emulator. * - * Version: @(#)device.c 1.0.0 2017/05/30 + * Version: @(#)device.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2016 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include "ibm.h" #include "cpu/cpu.h" #include "config.h" @@ -27,10 +26,10 @@ static void *device_priv[256]; static device_t *devices[256]; - static device_t *current_device; -void device_init() + +void device_init(void) { memset(devices, 0, sizeof(devices)); } @@ -86,7 +85,7 @@ int device_available(device_t *d) return 1; } -void device_speed_changed() +void device_speed_changed(void) { int c; @@ -104,7 +103,7 @@ void device_speed_changed() sound_speed_changed(); } -void device_force_redraw() +void device_force_redraw(void) { int c; diff --git a/src/device.h b/src/device.h index acb875dcc..5a2f9b17e 100644 --- a/src/device.h +++ b/src/device.h @@ -9,21 +9,35 @@ * Implementation of the generic device interface to handle * all devices attached to the emulator. * - * Version: @(#)device.h 1.0.0 2017/05/30 + * Version: @(#)device.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2016 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_DEVICE_H +# define EMU_DEVICE_H -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 + +#define CONFIG_STRING 0 +#define CONFIG_INT 1 +#define CONFIG_BINARY 2 #define CONFIG_SELECTION 3 -#define CONFIG_HEX16 4 -#define CONFIG_HEX20 5 -#define CONFIG_MAC 6 +#define CONFIG_HEX16 4 +#define CONFIG_HEX20 5 +#define CONFIG_MAC 6 + + +enum +{ + DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ + DEVICE_AT = 2, /*Device requires an AT-compatible system*/ + DEVICE_PS2 = 4, /*Device requires a PS/1 or PS/2 system*/ + DEVICE_MCA = 0x20, /*Device requires the MCA bus*/ + DEVICE_PCI = 0x40 /*Device requires the PCI bus*/ +}; + typedef struct device_config_selection_t { @@ -54,33 +68,28 @@ typedef struct device_t device_config_t *config; } device_t; -void device_init(); -void device_add(device_t *d); -void device_close_all(); -int device_available(device_t *d); -void device_speed_changed(); -void device_force_redraw(); -char *device_add_status_info(char *s, int max_len); -int device_get_config_int(char *name); -int device_get_config_int_ex(char *s, int default_int); -int device_get_config_hex16(char *name); -int device_get_config_hex20(char *name); -int device_get_config_mac(char *name, int default_int); -void device_set_config_int(char *s, int val); -void device_set_config_hex16(char *s, int val); -void device_set_config_hex20(char *s, int val); -void device_set_config_mac(char *s, int val); -char *device_get_config_string(char *name); +extern void device_init(void); +extern void device_add(device_t *d); +extern void device_close_all(void); +extern int device_available(device_t *d); +extern void device_speed_changed(void); +extern void device_force_redraw(void); +extern char *device_add_status_info(char *s, int max_len); -enum -{ - DEVICE_NOT_WORKING = 1, /*Device does not currently work correctly and will be disabled in a release build*/ - DEVICE_AT = 2, /*Device requires an AT-compatible system*/ - DEVICE_PS2 = 4, /*Device requires a PS/1 or PS/2 system*/ - DEVICE_MCA = 0x20, /*Device requires the MCA bus*/ - DEVICE_PCI = 0x40 /*Device requires the PCI bus*/ -}; +extern int device_get_config_int(char *name); +extern int device_get_config_int_ex(char *s, int default_int); +extern int device_get_config_hex16(char *name); +extern int device_get_config_hex20(char *name); +extern int device_get_config_mac(char *name, int default_int); +extern void device_set_config_int(char *s, int val); +extern void device_set_config_hex16(char *s, int val); +extern void device_set_config_hex20(char *s, int val); +extern void device_set_config_mac(char *s, int val); +extern char *device_get_config_string(char *name); -int model_get_config_int(char *s); -char *model_get_config_string(char *s); +extern int model_get_config_int(char *s); +extern char *model_get_config_string(char *s); + + +#endif /*EMU_DEVICE_H*/ diff --git a/src/disc.c b/src/disc.c index 46b2517c6..015f4ff11 100644 --- a/src/disc.c +++ b/src/disc.c @@ -9,19 +9,17 @@ * Generic floppy disk interface that communicates with the * other handlers. * - * Version: @(#)disc.c 1.0.0 2017/05/30 + * Version: @(#)disc.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #define UNICODE #include #include "ibm.h" - #include "config.h" #include "disc.h" #include "disc_fdi.h" @@ -33,6 +31,7 @@ #include "fdd.h" #include "timer.h" + wchar_t discfns[4][256]; extern int driveempty[4]; @@ -76,14 +75,14 @@ int (*fdc_getdata)(int last); void (*fdc_sectorid)(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2); void (*fdc_indexpulse)();*/ + static struct { wchar_t *ext; void (*load)(int drive, wchar_t *fn); void (*close)(int drive); int size; -} -loaders[]= +} loaders[]= { {L"001", img_load, img_close, -1}, {L"002", img_load, img_close, -1}, diff --git a/src/disc.h b/src/disc.h index 62ba83d83..b065b4b53 100644 --- a/src/disc.h +++ b/src/disc.h @@ -9,16 +9,20 @@ * Generic floppy disk interface that communicates with the * other handlers. * - * Version: @(#)disc.h 1.0.0 2017/05/30 + * Version: @(#)disc.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_DISC_H +# define EMU_DISC_H + #define FDD_NUM 4 + typedef struct { void (*seek)(int drive, int track); @@ -33,42 +37,49 @@ typedef struct void (*poll)(int drive); } DRIVE; -extern DRIVE drives[FDD_NUM]; -extern int curdrive; +extern DRIVE drives[FDD_NUM]; +extern int curdrive; -void disc_load(int drive, wchar_t *fn); -void disc_new(int drive, char *fn); -void disc_close(int drive); -void disc_init(); -void disc_reset(); -void disc_poll(int drive); -void disc_poll_0(); -void disc_poll_1(); -void disc_seek(int drive, int track); -void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size); -void disc_writesector(int drive, int sector, int track, int side, int density, int sector_size); -void disc_comparesector(int drive, int sector, int track, int side, int density, int sector_size); -void disc_readaddress(int drive, int side, int density); -void disc_format(int drive, int side, int density, uint8_t fill); -int disc_hole(int drive); -double disc_byteperiod(int drive); -void disc_stop(int drive); -int disc_empty(int drive); -void disc_set_rate(int drive, int drvden, int rate); -extern int disc_time; -extern int disc_poll_time[FDD_NUM]; +extern int disc_time; +extern int disc_poll_time[FDD_NUM]; + + +extern void disc_load(int drive, wchar_t *fn); +extern void disc_new(int drive, char *fn); +extern void disc_close(int drive); +extern void disc_init(void); +extern void disc_reset(void); +extern void disc_poll(int drive); +extern void disc_poll_0(void); +extern void disc_poll_1(void); +extern void disc_seek(int drive, int track); +extern void disc_readsector(int drive, int sector, int track, + int side, int density, int sector_size); +extern void disc_writesector(int drive, int sector, int track, + int side, int density, int sector_size); +extern void disc_comparesector(int drive, int sector, int track, + int side, int density, int sector_size); +extern void disc_readaddress(int drive, int side, int density); +extern void disc_format(int drive, int side, int density, uint8_t fill); +extern int disc_hole(int drive); +extern double disc_byteperiod(int drive); +extern void disc_stop(int drive); +extern int disc_empty(int drive); +extern void disc_set_rate(int drive, int drvden, int rate); + +extern void fdc_callback(void); +extern int fdc_data(uint8_t dat); +extern void fdc_spindown(void); +extern void fdc_finishread(void); +extern void fdc_datacrcerror(void); +extern void fdc_headercrcerror(void); +extern void fdc_writeprotect(void); +extern int fdc_getdata(int last); +extern void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, + uint8_t size, uint8_t crc1, uint8_t crc2); +extern void fdc_indexpulse(void); -void fdc_callback(); -int fdc_data(uint8_t dat); -void fdc_spindown(); -void fdc_finishread(); -void fdc_datacrcerror(); -void fdc_headercrcerror(); -void fdc_writeprotect(); -int fdc_getdata(int last); -void fdc_sectorid(uint8_t track, uint8_t side, uint8_t sector, uint8_t size, uint8_t crc1, uint8_t crc2); -void fdc_indexpulse(); /*extern int fdc_time; extern int fdc_ready; extern int fdc_indexcount;*/ @@ -217,3 +228,6 @@ typedef union uint8_t byte_array[4]; sector_id_fields_t id; } sector_id_t; + + +#endif /*EMU_DISC_H*/ diff --git a/src/dma.c b/src/dma.c index a90156a6d..1e2982adf 100644 --- a/src/dma.c +++ b/src/dma.c @@ -8,14 +8,13 @@ * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.c 1.0.0 2017/05/30 + * Version: @(#)dma.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include "ibm.h" #include "cpu/x86.h" #include "mem.h" @@ -505,7 +504,7 @@ void dma_alias_remove_piix(void) io_removehandler(0x009C, 0x0003, dma_page_read, NULL, NULL, dma_page_write, NULL, NULL, NULL); } -void ps2_dma_init() +void ps2_dma_init(void) { io_sethandler(0x0018, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); io_sethandler(0x001a, 0x0001, dma_ps2_read, NULL, NULL, dma_ps2_write, NULL, NULL, NULL); diff --git a/src/dma.h b/src/dma.h index 947d80425..29b3bba23 100644 --- a/src/dma.h +++ b/src/dma.h @@ -8,37 +8,46 @@ * * Implementation of the Intel DMA controllers. * - * Version: @(#)dma.h 1.0.0 2017/05/30 + * Version: @(#)dma.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_DMA_H +# define EMU_DMA_H -void dma_init(void); -void dma16_init(void); -void ps2_dma_init(void); -void dma_reset(void); -int dma_mode(int channel); #define DMA_NODATA -1 #define DMA_OVER 0x10000 #define DMA_VERIFY 0x20000 -void readdma0(void); -int readdma1(void); -uint8_t readdma2(void); -int readdma3(void); -void writedma2(uint8_t temp); +extern void dma_init(void); +extern void dma16_init(void); +extern void ps2_dma_init(void); +extern void dma_reset(void); +extern int dma_mode(int channel); -int dma_channel_read(int channel); -int dma_channel_write(int channel, uint16_t val); +extern void readdma0(void); +extern int readdma1(void); +extern uint8_t readdma2(void); +extern int readdma3(void); -void dma_alias_set(void); -void dma_alias_remove(void); -void dma_alias_remove_piix(void); +extern void writedma2(uint8_t temp); -void DMAPageRead(uint32_t PhysAddress, char *DataRead, uint32_t TotalSize); -void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, uint32_t TotalSize); +extern int dma_channel_read(int channel); +extern int dma_channel_write(int channel, uint16_t val); + +extern void dma_alias_set(void); +extern void dma_alias_remove(void); +extern void dma_alias_remove_piix(void); + +extern void DMAPageRead(uint32_t PhysAddress, char *DataRead, + uint32_t TotalSize); +extern void DMAPageWrite(uint32_t PhysAddress, const char *DataWrite, + uint32_t TotalSize); + + +#endif /*EMU_DMA_H*/ diff --git a/src/ibm.h b/src/ibm.h index 658ca5513..4291d095e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -8,14 +8,13 @@ * * General include file. * - * Version: @(#)ibm.h 1.0.0 2017/05/30 + * Version: @(#)ibm.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include #include @@ -703,7 +702,8 @@ extern int cdrom_do_log; extern int d86f_do_log; extern int fdc_do_log; extern int ide_do_log; -extern int ne2000_do_log; +extern int serial_do_log; +extern int nic_do_log; #endif extern int suppress_overscan; diff --git a/src/ide.c b/src/ide.c index b83a84fd6..87822a628 100644 --- a/src/ide.c +++ b/src/ide.c @@ -9,16 +9,15 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)ide.c 1.0.0 2017/05/30 + * Version: @(#)ide.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * TheCollector1995, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. * Copyright 2016-2017 TheCollector1995. */ - #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _GNU_SOURCE @@ -394,7 +393,7 @@ static void ide_identify(IDE *ide) ide->buffer[3] = hdc[ide->hdc_num].hpc; /* Heads */ ide->buffer[6] = hdc[ide->hdc_num].spt; /* Sectors */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[20] = 3; /*Buffer type*/ ide->buffer[21] = 512; /*Buffer size*/ @@ -465,7 +464,7 @@ static void ide_atapi_identify(IDE *ide) ide->buffer[0] = 0x8000 | (5<<8) | 0x80 | (2<<5); /* ATAPI device, CD-ROM drive, removable media, accelerated DRQ */ ide_padstr((char *) (ide->buffer + 10), "", 20); /* Serial Number */ - ide_padstr((char *) (ide->buffer + 23), emulator_version, 8); /* Firmware */ + ide_padstr((char *) (ide->buffer + 23), EMU_VERSION, 8); /* Firmware */ ide_padstr((char *) (ide->buffer + 27), device_identify, 40); /* Model */ ide->buffer[49] = 0x200; /* LBA supported */ diff --git a/src/ide.h b/src/ide.h index be7fe0c50..003cbbb07 100644 --- a/src/ide.h +++ b/src/ide.h @@ -18,17 +18,12 @@ * Copyright 2016-2017 Miran Grca. * Copyright 2016-2017 TheCollector1995. */ +#ifndef EMU_IDE_H +# define EMU_IDE_H -#ifndef __IDE__ -#define __IDE__ -#ifdef __MSC__ -# pragma pack(push,1) -typedef struct IDE -#else -typedef struct __attribute__((__packed__)) IDE -#endif -{ +#pragma pack(push,1) +typedef struct { int type; int board; uint8_t atastat; @@ -58,50 +53,50 @@ typedef struct __attribute__((__packed__)) IDE uint8_t specify_success; int mdma_mode; } IDE; -#ifdef __MSC__ -# pragma pack(pop) -#endif +#pragma pack(pop) -extern void writeide(int ide_board, uint16_t addr, uint8_t val); -extern void writeidew(int ide_board, uint16_t val); -extern uint8_t readide(int ide_board, uint16_t addr); -extern uint16_t readidew(int ide_board); -extern void callbackide(int ide_board); -extern void resetide(void); -extern void ide_init(); -extern void ide_xtide_init(); -extern void ide_ter_init(); -extern void ide_qua_init(); -extern void ide_pri_enable(); -extern void ide_sec_enable(); -extern void ide_ter_enable(); -extern void ide_qua_enable(); -extern void ide_pri_disable(); -extern void ide_sec_disable(); -extern void ide_ter_disable(); -extern void ide_qua_disable(); -extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)); extern int ideboard; extern int ide_enable[5]; extern int ide_irq[5]; +IDE ide_drives[IDE_NUM + XTIDE_NUM]; + + extern int idecallback[5]; +extern void writeide(int ide_board, uint16_t addr, uint8_t val); +extern void writeidew(int ide_board, uint16_t val); +extern uint8_t readide(int ide_board, uint16_t addr); +extern uint16_t readidew(int ide_board); +extern void callbackide(int ide_board); +extern void resetide(void); +extern void ide_init(void); +extern void ide_xtide_init(void); +extern void ide_ter_init(void); +extern void ide_qua_init(void); +extern void ide_pri_enable(void); +extern void ide_sec_enable(void); +extern void ide_ter_enable(void); +extern void ide_qua_enable(void); +extern void ide_pri_disable(void); +extern void ide_sec_disable(void); +extern void ide_ter_disable(void); +extern void ide_qua_disable(void); +extern void ide_set_bus_master(int (*read)(int channel, uint8_t *data, int transfer_length), int (*write)(int channel, uint8_t *data, int transfer_length), void (*set_irq)(int channel)); void ide_irq_raise(IDE *ide); void ide_irq_lower(IDE *ide); -IDE ide_drives[IDE_NUM + XTIDE_NUM]; - void ide_padstr8(uint8_t *buf, int buf_size, const char *src); void win_cdrom_eject(uint8_t id); void win_cdrom_reload(uint8_t id); -#endif - -void ide_pri_disable(); -void ide_pri_enable_ex(); +void ide_pri_disable(void); +void ide_pri_enable_ex(void); void ide_set_base(int controller, uint16_t port); void ide_set_side(int controller, uint16_t port); + + +#endif /*EMU_IDE_H*/ diff --git a/src/model.c b/src/model.c index 209bbb017..b08d3a01f 100644 --- a/src/model.c +++ b/src/model.c @@ -8,21 +8,22 @@ * * Handling of the emulated machines. * - * Version: @(#)model.c 1.0.0 2017/05/30 + * Version: @(#)model.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include + #include "ibm.h" #include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "rom.h" +#include "device.h" #include "model.h" #include "mouse.h" #include "mouse_ps2.h" @@ -32,7 +33,6 @@ #include "ali1429.h" #include "amstrad.h" #include "compaq.h" -#include "device.h" #include "disc.h" #include "dma.h" #include "fdc.h" @@ -92,56 +92,57 @@ #include "xtide.h" #include "bugger.h" -void xt_init(); -void pcjr_init(); -void tandy1k_init(); -void tandy1ksl2_init(); -void ams_init(); -void europc_init(); -void olim24_init(); -void at_init(); -void ibm_at_init(); -void at_ide_init(); -void deskpro386_init(); -void ps1_m2011_init(); -void ps1_m2121_init(); -void ps1_m2133_init(); -void ps2_m30_286_init(); -void ps2_model_50_init(); -void ps2_model_55sx_init(); -void ps2_model_80_init(); -void at_neat_init(); -void at_scat_init(); -void at_wd76c10_init(); -void at_ali1429_init(); -void at_headland_init(); -void at_opti495_init(); -void at_sis496_init(); -void at_i430vx_init(); -void at_batman_init(); -void at_endeavor_init(); -void at_dtk486_init(); -void at_r418_init(); -#if 0 -void at_586mc1_init(); -#endif -void at_plato_init(); -void at_mb500n_init(); -void at_p54tp4xe_init(); -void at_ap53_init(); -void at_p55t2s_init(); -void at_acerm3a_init(); -#if 0 -void at_acerv35n_init(); -#endif -void at_p55t2p4_init(); -void at_p55tvp4_init(); -void at_p55va_init(); -void at_i440fx_init(); -void at_s1668_init(); +extern void xt_init(void); +extern void pcjr_init(void); +extern void tandy1k_init(void); +extern void tandy1ksl2_init(void); +extern void ams_init(void); +extern void europc_init(void); +extern void olim24_init(void); +extern void at_init(void); +extern void ibm_at_init(void); +extern void at_ide_init(void); +extern void deskpro386_init(void); +extern void ps1_m2011_init(void); +extern void ps1_m2121_init(void); +extern void ps1_m2133_init(void); +extern void ps2_m30_286_init(void); +extern void ps2_model_50_init(void); +extern void ps2_model_55sx_init(void); +extern void ps2_model_80_init(void); +extern void at_neat_init(void); +extern void at_scat_init(void); +extern void at_wd76c10_init(void); +extern void at_ali1429_init(void); +extern void at_headland_init(void); +extern void at_opti495_init(void); +extern void at_sis496_init(void); +extern void at_i430vx_init(void); +extern void at_batman_init(void); +extern void at_endeavor_init(void); -void xt_laserxt_init(); +extern void at_dtk486_init(void); +extern void at_r418_init(void); +#if 0 +extern void at_586mc1_init(void); +#endif +extern void at_plato_init(void); +extern void at_mb500n_init(void); +extern void at_p54tp4xe_init(void); +extern void at_ap53_init(void); +extern void at_p55t2s_init(void); +extern void at_acerm3a_init(void); +#if 0 +extern void at_acerv35n_init(void); +#endif +extern void at_p55t2p4_init(void); +extern void at_p55tvp4_init(void); +extern void at_p55va_init(void); +extern void at_i440fx_init(void); +extern void at_s1668_init(void); + +extern void xt_laserxt_init(void); int model; @@ -233,12 +234,13 @@ MODEL models[] = {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} }; -int model_count() + +int model_count(void) { return (sizeof(models) / sizeof(MODEL)) - 1; } -int model_getromset() +int model_getromset(void) { return models[model].id; } @@ -273,7 +275,7 @@ device_t *model_getdevice(int model) return models[model].device; } -char *model_get_internal_name() +char *model_get_internal_name(void) { return models[model].internal_name; } @@ -292,7 +294,7 @@ int model_get_model_from_internal_name(char *s) return 0; } -void common_init() +void common_init(void) { dma_init(); fdc_add(); @@ -312,7 +314,7 @@ void common_init() } } -void xt_init() +void xt_init(void) { common_init(); mem_add_bios(); @@ -326,7 +328,7 @@ void xt_init() } } -void pcjr_init() +void pcjr_init(void) { mem_add_bios(); fdc_add_pcjr(); @@ -342,7 +344,7 @@ void pcjr_init() nmi_mask = 0x80; } -void tandy1k_init() +void tandy1k_init(void) { TANDY = 1; common_init(); @@ -357,7 +359,7 @@ void tandy1k_init() device_add(&tandy_eeprom_device); if (joystick_type != 7) device_add(&gameport_device); } -void tandy1ksl2_init() +void tandy1ksl2_init(void) { common_init(); mem_add_bios(); @@ -369,7 +371,7 @@ void tandy1ksl2_init() if (joystick_type != 7) device_add(&gameport_device); } -void ams_init() +void ams_init(void) { AMSTRAD = 1; common_init(); @@ -382,7 +384,7 @@ void ams_init() if (joystick_type != 7) device_add(&gameport_device); } -void europc_init() +void europc_init(void) { common_init(); mem_add_bios(); @@ -392,7 +394,7 @@ void europc_init() if (joystick_type != 7) device_add(&gameport_device); } -void olim24_init() +void olim24_init(void) { common_init(); mem_add_bios(); @@ -403,13 +405,13 @@ void olim24_init() if (joystick_type != 7) device_add(&gameport_device); } -void xt_laserxt_init() +void xt_laserxt_init(void) { xt_init(); laserxt_init(); } -void at_init() +void at_init(void) { AT = 1; common_init(); @@ -430,25 +432,25 @@ void at_init() } } -void ibm_at_init() +void ibm_at_init(void) { at_init(); mem_remap_top_384k(); } -void at_ide_init() +void at_ide_init(void) { at_init(); ide_init(); } -void deskpro386_init() +void deskpro386_init(void) { at_init(); compaq_init(); } -void ps1_common_init() +void ps1_common_init(void) { AT = 1; common_init(); @@ -471,26 +473,26 @@ void ps1_common_init() if (joystick_type != 7) device_add(&gameport_201_device); } -void ps1_m2011_init() +void ps1_m2011_init(void) { ps1_common_init(); ps1mb_init(); } -void ps1_m2121_init() +void ps1_m2121_init(void) { ps1_common_init(); ps1mb_m2121_init(); fdc_set_ps1(); } -void ps1_m2133_init() +void ps1_m2133_init(void) { ps1_common_init(); ps1mb_m2133_init(); } -void ps2_m30_286_init() +void ps2_m30_286_init(void) { AT = 1; common_init(); @@ -505,7 +507,7 @@ void ps2_m30_286_init() fdc_set_ps1(); } -static void ps2_common_init() +static void ps2_common_init(void) { AT = 1; common_init(); @@ -522,67 +524,67 @@ static void ps2_common_init() pit_ps2_init(); } -void ps2_model_50_init() +void ps2_model_50_init(void) { ps2_common_init(); ps2_mca_board_model_50_init(); } -void ps2_model_55sx_init() +void ps2_model_55sx_init(void) { ps2_common_init(); ps2_mca_board_model_55sx_init(); } -void ps2_model_80_init() +void ps2_model_80_init(void) { ps2_common_init(); ps2_mca_board_model_80_type2_init(); } -void at_neat_init() +void at_neat_init(void) { at_ide_init(); neat_init(); } -void at_scat_init() +void at_scat_init(void) { at_ide_init(); scat_init(); } -/* void at_acer386sx_init() +/* void at_acer386sx_init(void) { at_ide_init(); acer386sx_init(); } -void at_82335_init() +void at_82335_init(void) { at_ide_init(); i82335_init(); } */ -void at_wd76c10_init() +void at_wd76c10_init(void) { at_ide_init(); wd76c10_init(); } -void at_headland_init() +void at_headland_init(void) { at_ide_init(); headland_init(); } -void at_opti495_init() +void at_opti495_init(void) { at_ide_init(); opti495_init(); } -void secondary_ide_check() +void secondary_ide_check(void) { int i = 0; int secondary_cdroms = 0; @@ -597,7 +599,7 @@ void secondary_ide_check() if (!secondary_cdroms) ide_sec_disable(); } -void at_ali1429_init() +void at_ali1429_init(void) { ali1429_reset(); @@ -607,14 +609,14 @@ void at_ali1429_init() secondary_ide_check(); } -/* void at_um8881f_init() +/* void at_um8881f_init(void) { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1, 0, 31); um8881f_init(); } */ -void at_dtk486_init() +void at_dtk486_init(void) { at_ide_init(); memregs_init(); @@ -622,7 +624,7 @@ void at_dtk486_init() secondary_ide_check(); } -void at_sis496_init() +void at_sis496_init(void) { at_ide_init(); memregs_init(); @@ -634,13 +636,13 @@ void at_sis496_init() trc_init(); } -void at_r418_init() +void at_r418_init(void) { at_sis496_init(); fdc37c665_init(); } -void at_premiere_common_init() +void at_premiere_common_init(void) { at_ide_init(); memregs_init(); @@ -654,14 +656,14 @@ void at_premiere_common_init() device_add(&intel_flash_bxt_ami_device); } -void at_batman_init() +void at_batman_init(void) { at_premiere_common_init(); i430lx_init(); } #if 0 -void at_586mc1_init() +void at_586mc1_init(void) { at_ide_init(); memregs_init(); @@ -676,13 +678,13 @@ void at_586mc1_init() } #endif -void at_plato_init() +void at_plato_init(void) { at_premiere_common_init(); i430nx_init(); } -void at_advanced_common_init() +void at_advanced_common_init(void) { at_ide_init(); memregs_init(); @@ -696,13 +698,13 @@ void at_advanced_common_init() pc87306_init(); } -void at_endeavor_init() +void at_endeavor_init(void) { at_advanced_common_init(); device_add(&intel_flash_bxt_ami_device); } -void at_mb500n_init() +void at_mb500n_init(void) { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1); @@ -716,7 +718,7 @@ void at_mb500n_init() device_add(&intel_flash_bxt_device); } -void at_p54tp4xe_init() +void at_p54tp4xe_init(void) { at_ide_init(); memregs_init(); @@ -731,7 +733,7 @@ void at_p54tp4xe_init() device_add(&intel_flash_bxt_device); } -void at_ap53_init() +void at_ap53_init(void) { at_ide_init(); memregs_init(); @@ -748,7 +750,7 @@ void at_ap53_init() device_add(&intel_flash_bxt_device); } -void at_p55t2s_init() +void at_p55t2s_init(void) { at_ide_init(); memregs_init(); @@ -765,7 +767,7 @@ void at_p55t2s_init() device_add(&intel_flash_bxt_device); } -void at_acerm3a_init() +void at_acerm3a_init(void) { at_ide_init(); memregs_init(); @@ -783,7 +785,7 @@ void at_acerm3a_init() } #if 0 -void at_acerv35n_init() +void at_acerv35n_init(void) { at_ide_init(); memregs_init(); @@ -801,7 +803,7 @@ void at_acerv35n_init() } #endif -void at_p55t2p4_init() +void at_p55t2p4_init(void) { at_ide_init(); memregs_init(); @@ -816,7 +818,7 @@ void at_p55t2p4_init() device_add(&intel_flash_bxt_device); } -void at_i430vx_init() +void at_i430vx_init(void) { at_ide_init(); memregs_init(); @@ -831,7 +833,7 @@ void at_i430vx_init() device_add(&intel_flash_bxt_device); } -void at_p55tvp4_init() +void at_p55tvp4_init(void) { at_ide_init(); memregs_init(); @@ -846,7 +848,7 @@ void at_p55tvp4_init() device_add(&intel_flash_bxt_device); } -void at_p55va_init() +void at_p55va_init(void) { at_ide_init(); memregs_init(); @@ -861,7 +863,7 @@ void at_p55va_init() device_add(&intel_flash_bxt_device); } -void at_i440fx_init() +void at_i440fx_init(void) { at_ide_init(); memregs_init(); @@ -876,7 +878,7 @@ void at_i440fx_init() device_add(&intel_flash_bxt_device); } -void at_s1668_init() +void at_s1668_init(void) { at_ide_init(); memregs_init(); @@ -891,7 +893,7 @@ void at_s1668_init() device_add(&intel_flash_bxt_device); } -void model_init() +void model_init(void) { pclog("Initializing as %s\n", model_getname()); AMSTRAD = AT = PCI = TANDY = 0; diff --git a/src/model.h b/src/model.h index a337b122b..f483cd1aa 100644 --- a/src/model.h +++ b/src/model.h @@ -8,13 +8,16 @@ * * Handling of the emulated machines. * - * Version: @(#)model.h 1.0.0 2017/05/30 + * Version: @(#)model.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_MODEL_H +# define EMU_MODEL_H + #define MODEL_AT 1 #define MODEL_PS2 2 @@ -28,34 +31,37 @@ #define MODEL_FUJITSU 512 #define MODEL_RM 1024 -typedef struct -{ - char name[32]; - int id; - char internal_name[24]; - struct - { - char name[16]; - CPU *cpus; - } cpu[5]; - int fixed_gfxcard; - int flags; - int min_ram, max_ram; - int ram_granularity; - void (*init)(); - struct device_t *device; + +typedef struct { + char name[32]; + int id; + char internal_name[24]; + struct { + char name[16]; + CPU *cpus; + } cpu[5]; + int fixed_gfxcard; + int flags; + int min_ram, max_ram; + int ram_granularity; + void (*init)(void); + device_t *device; } MODEL; -extern MODEL models[]; +extern MODEL models[]; extern int model; -int model_count(); -int model_getromset(); -int model_getmodel(int romset); -char *model_getname(); -char *model_get_internal_name(); -int model_get_model_from_internal_name(char *s); -void model_init(); -struct device_t *model_getdevice(int model); -int model_getromset_ex(int m); + +extern int model_count(void); +extern int model_getromset(void); +extern int model_getmodel(int romset); +extern char *model_getname(void); +extern char *model_get_internal_name(void); +extern int model_get_model_from_internal_name(char *s); +extern void model_init(void); +extern device_t *model_getdevice(int model); +extern int model_getromset_ex(int m); + + +#endif /*EMU_MODEL_H*/ diff --git a/src/mouse.h b/src/mouse.h index 4ae2d8d76..25aa07888 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -1,5 +1,5 @@ -#ifndef MOUSE_H -# define MOUSE_H +#ifndef EMU_MOUSE_H +# define EMU_MOUSE_H #define MOUSE_TYPE_SERIAL 0 /* Serial Mouse */ @@ -38,4 +38,4 @@ extern int mouse_get_type(int mouse); extern int mouse_get_ndev(void); -#endif /*MOUSE_H*/ +#endif /*EMU_MOUSE_H*/ diff --git a/src/net_ne2000.c b/src/net_ne2000.c index 212353622..7194adf68 100644 --- a/src/net_ne2000.c +++ b/src/net_ne2000.c @@ -10,7 +10,7 @@ * * NOTE: The file will also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.9 2017/06/02 + * Version: @(#)net_ne2000.c 1.0.10 2017/06/03 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -38,11 +38,6 @@ #include "bswap.h" -#ifdef WALTJE -# define ENABLE_NE2000_LOG 2 -#endif - - /* ROM BIOS file paths. */ #define ROM_PATH_NE1000 L"roms/network/ne1000/ne1000.rom" #define ROM_PATH_NE2000 L"roms/network/ne2000/ne2000.rom" @@ -61,13 +56,6 @@ typedef union { } bar_t; -#if ENABLE_NE2000_LOG -static int nic_do_log = ENABLE_NE2000_LOG; -#else -static int nic_do_log = 0; -#endif - - /* Never completely fill the ne2k ring so that we never hit the unclear completely full buffer condition. */ #define NE2K_NEVER_FULL_RING (1) @@ -239,7 +227,7 @@ static void nic_tx(nic_t *, uint32_t); static void nelog(int lvl, const char *fmt, ...) { -#ifdef ENABLE_NE2000_LOG +#ifdef ENABLE_NIC_LOG va_list ap; if (nic_do_log >= lvl) { diff --git a/src/network.c b/src/network.c index be58eaac2..cd6cc3ea5 100644 --- a/src/network.c +++ b/src/network.c @@ -12,10 +12,9 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.7 2017/05/29 + * Version: @(#)network.c 1.0.9 2017/06/03 * - * Authors: Kotori, - * Fred N. van Kempen, + * Author: Fred N. van Kempen, */ #include #include @@ -47,6 +46,7 @@ static netcard_t net_cards[] = { int network_card; int network_type; int network_ndev; +int nic_do_log; netdev_t network_devs[32]; char network_pcap[512]; @@ -63,6 +63,12 @@ network_init(void) { int i; +#if ENABLE_NIC_LOG + nic_do_log = ENABLE_NIC_LOG; +#else + nic_do_log = 0; +#endif + #if 0 network_type = NET_TYPE_NONE; network_card = 0; diff --git a/src/network.h b/src/network.h index f36c87a5e..1c3e748a1 100644 --- a/src/network.h +++ b/src/network.h @@ -8,13 +8,12 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.5 2017/05/21 + * Version: @(#)network.h 1.0.7 2017/06/03 * - * Authors: Kotori, - * Fred N. van Kempen, + * Author: Fred N. van Kempen, */ -#ifndef NETWORK_H -# define NETWORK_H +#ifndef EMU_NETWORK_H +# define EMU_NETWORK_H # include @@ -48,6 +47,7 @@ typedef struct { /* Global variables. */ +extern int nic_do_log; extern int network_card; extern int network_type; extern int network_ndev; @@ -81,4 +81,4 @@ extern int network_card_get_from_internal_name(char *); extern device_t *network_card_getdevice(int); -#endif /*NETWORK_H*/ +#endif /*EMU_NETWORK_H*/ diff --git a/src/nvr.c b/src/nvr.c index 5888c1005..8862ec08f 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -8,16 +8,15 @@ * * CMOS NVRAM emulation. * - * Version: @(#)nvr.c 1.0.0 2017/05/30 + * Version: @(#)nvr.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Mahod, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. * Copyright 2016-2017 Mahod. */ - #include #include "ibm.h" #include "io.h" @@ -39,12 +38,12 @@ static int nvr_onesec_time = 0, nvr_onesec_cnt = 0; static int rtctime; -void getnvrtime() +void getnvrtime(void) { time_get(nvrram); } -void nvr_recalc() +void nvr_recalc(void) { int c; int newrtctime; @@ -204,7 +203,7 @@ uint8_t readnvr(uint16_t addr, void *priv) return nvraddr; } -void loadnvr() +void loadnvr(void) { FILE *f; int c; @@ -292,7 +291,7 @@ void loadnvr() c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); } -void savenvr() +void savenvr(void) { FILE *f; switch (oldromset) @@ -357,7 +356,7 @@ void savenvr() fclose(f); } -void nvr_init() +void nvr_init(void) { io_sethandler(0x0070, 0x0002, readnvr, NULL, NULL, writenvr, NULL, NULL, NULL); timer_add(nvr_rtc, &rtctime, TIMER_ALWAYS_ENABLED, NULL); diff --git a/src/nvr.h b/src/nvr.h index 46eaa07ec..0c7780240 100644 --- a/src/nvr.h +++ b/src/nvr.h @@ -8,25 +8,28 @@ * * CMOS NVRAM emulation. * - * Version: @(#)nvr.h 1.0.0 2017/05/30 + * Version: @(#)nvr.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Mahod, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. * Copyright 2016-2017 Mahod. */ +#ifndef EMU_NVR_H +# define EMU_NVR_H -void nvr_init(); extern int enable_sync; - extern int nvr_dosave; -void time_get(char *nvrram); -void nvr_recalc(); +extern void nvr_init(void); +extern void time_get(char *nvrram); +extern void nvr_recalc(void); +extern void loadnvr(void); +extern void savenvr(void); -void loadnvr(); -void savenvr(); + +#endif /*EMU_NVR_H*/ diff --git a/src/pc.c b/src/pc.c index 544c5ee30..f60a03a3e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,17 +8,17 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.1 2017/05/30 + * Version: @(#)pc.c 1.0.3 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include #include + #include "86box.h" #include "ibm.h" #include "mem.h" @@ -348,7 +348,7 @@ void initpc(int argc, wchar_t *argv[]) if (config_file == NULL) { - append_filename_w(config_file_default, pcempath, L"86box.cfg", 511); + append_filename_w(config_file_default, pcempath, CONFIG_FILE_W, 511); } else { @@ -659,7 +659,7 @@ void runpc(void) win_title_update=0; mbstowcs(wmodel, model_getname(), strlen(model_getname()) + 1); mbstowcs(wcpu, models[model].cpu[cpu_manufacturer].cpus[cpu].name, strlen(models[model].cpu[cpu_manufacturer].cpus[cpu].name) + 1); - _swprintf(s, L"86Box v%s - %i%% - %s - %s - %s", emulator_version_w, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); + _swprintf(s, L"%s v%s - %i%% - %s - %s - %s", EMU_NAME_W, EMU_VERSION_W, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); set_window_title(s); } done++; diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 8a03a52b2..b88e7de99 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -10,9 +10,9 @@ * 0 - BT-542B ISA; * 1 - BT-958 PCI (but BT-542B ISA on non-PCI machines) * - * Version: @(#)scsi_buslogic.c 1.0.2 2017/06/02 + * Version: @(#)scsi_buslogic.c 1.0.3 2017/06/03 * - * Author: TheCollector1995, + * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, * Copyright 2008-2017 Sarah Walker. @@ -506,12 +506,7 @@ enum { }; -#ifdef WALTJE -int buslogic_do_log = 1; -# define ENABLE_BUSLOGIC_LOG -#else int buslogic_do_log = 0; -#endif static void diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 33b88a4bb..69726cf0b 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -6,15 +6,16 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.0 2017/05/30 + * Version: @(#)scsi_disk.c 1.0.1 2017/06/03 * * Author: Miran Grca, * Copyright 2017-2017 Miran Grca. */ - #define _LARGEFILE_SOURCE #define _LARGEFILE64_SOURCE #define _GNU_SOURCE +#include +#include #include #include #include @@ -22,10 +23,6 @@ #include #include -#include - -#include - #include "86box.h" #include "cdrom.h" #include "ibm.h" @@ -34,7 +31,7 @@ #include "scsi.h" #include "scsi_disk.h" #include "timer.h" -#include "WIN/plat_iodev.h" +#include "win/plat_iodev.h" /* Bits of 'status' */ #define ERR_STAT 0x01 @@ -1200,9 +1197,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) device_identify_ex[6] = (id / 10) + 0x30; device_identify_ex[7] = (id % 10) + 0x30; - device_identify_ex[10] = emulator_version[0]; - device_identify_ex[12] = emulator_version[2]; - device_identify_ex[13] = emulator_version[3]; + device_identify_ex[10] = EMU_VERSION[0]; + device_identify_ex[12] = EMU_VERSION[2]; + device_identify_ex[13] = EMU_VERSION[3]; if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) { @@ -1508,7 +1505,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) tempbuffer[idx++] = 0x01; tempbuffer[idx++] = 0x00; tempbuffer[idx++] = 68; - ide_padstr8(tempbuffer + idx, 8, "86Box"); /* Vendor */ + ide_padstr8(tempbuffer + idx, 8, EMU_NAME); /* Vendor */ idx += 8; ide_padstr8(tempbuffer + idx, 40, device_identify_ex); /* Product */ idx += 40; @@ -1540,9 +1537,9 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) tempbuffer[3] = 0x02; tempbuffer[4] = 31; - ide_padstr8(tempbuffer + 8, 8, "86Box"); /* Vendor */ + ide_padstr8(tempbuffer + 8, 8, EMU_NAME); /* Vendor */ ide_padstr8(tempbuffer + 16, 16, device_identify); /* Product */ - ide_padstr8(tempbuffer + 32, 4, emulator_version); /* Revision */ + ide_padstr8(tempbuffer + 32, 4, EMU_VERSION); /* Revision */ idx = 36; } diff --git a/src/serial.c b/src/serial.c index bed3e1a62..bf6e6a45c 100644 --- a/src/serial.c +++ b/src/serial.c @@ -47,11 +47,6 @@ #include "plat_serial.h" -#ifdef WALTJE -# define ENABLE_SERIAL_LOG 2 -#endif - - enum { SERINT_LSR = 1, SERINT_RECEIVE = 2, @@ -144,11 +139,7 @@ enum { static SERIAL serial1, /* serial port 1 data */ serial2; /* serial port 2 data */ -#if ENABLE_SERIAL_LOG -static int serial_do_log = ENABLE_SERIAL_LOG; -#else -static int serial_do_log = 0; -#endif + int serial_do_log; static void @@ -231,6 +222,16 @@ serial_write_fifo(SERIAL *sp, uint8_t dat) } +#ifdef WALTJE +static void +serial_write_str(SERIAL *sp, const char *str) +{ + while (*str) + serial_write_fifo(sp, (uint8_t)*str++); +} +#endif + + static uint8_t read_fifo(SERIAL *sp) { @@ -265,7 +266,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) uint16_t baud; long speed; -#if 0 +#if ENABLE_SERIAL_LOG serial_log(2, "Serial%d: write(%04x, %02x)\n", sp->port, addr, val); #endif switch (addr & 0x07) { @@ -348,15 +349,23 @@ serial_write(uint16_t addr, uint8_t val, void *priv) } if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { - if (sp->bh != NULL) { - /* Linked, start reading from host port. */ - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); - } else { + if (sp->bh == NULL) { /* Not linked, start RX timer. */ timer_add(serial_timer, &sp->receive_delay, &sp->receive_delay, sp); - serial_log(1, "Serial%d: RX timer started!\n",sp->port); + + /* Fake CTS, DSR and DCD (for now.) */ + sp->msr = (MSR_CTS | MSR_DCTS | + MSR_DSR | MSR_DDSR | + MSR_DCD | MSR_DDCD); + sp->int_status |= SERINT_MSR; + update_ints(sp); + +#ifdef WALTJE + /* For testing. */ + serial_write_str(sp, "Welcome!\r\n"); +#endif } } sp->mctrl = val; @@ -411,14 +420,12 @@ static void serial_rd_done(void *arg, int num) { SERIAL *sp = (SERIAL *)arg; +#ifdef WALTJE serial_log(0, "%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); +#endif /* Stuff the byte in the FIFO and set intr. */ serial_write_fifo(sp, sp->hold); - - /* Start up the next read from the real port. */ - if (sp->bh != NULL) - (void)bhtty_read((BHTTY *)sp->bh, &sp->hold, 1); } @@ -553,7 +560,8 @@ serial_remove(int port) #endif /* Close the host device. */ - (void)serial_link(port, NULL); + if (sp->bh != NULL) + (void)serial_link(port, NULL); /* Release our I/O range. */ if (sp->addr != 0x0000) { @@ -570,16 +578,22 @@ serial_remove(int port) void serial_init(void) { +#if ENABLE_SERIAL_LOG + serial_do_log = ENABLE_SERIAL_LOG; +#endif memset(&serial1, 0x00, sizeof(SERIAL)); serial1.port = 1; - serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); -#ifdef WALTJE - serial_link(1, "COM2"); + serial_setup(serial1.port, SERIAL1_ADDR, SERIAL1_IRQ); +#ifdef xWALTJE + serial_link(serial1.port, "COM1"); #endif memset(&serial2, 0x00, sizeof(SERIAL)); serial2.port = 2; - serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); + serial_setup(serial2.port, SERIAL2_ADDR, SERIAL2_IRQ); +#ifdef xWALTJE + serial_link(serial2.port, "COM2"); +#endif } diff --git a/src/serial.h b/src/serial.h index bf361a0b1..4602429f0 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,13 +8,13 @@ * * Definitions for the SERIAL card. * - * Version: @(#)serial.h 1.0.3 2017/05/07 + * Version: @(#)serial.h 1.0.4 2017/06/03 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. */ -#ifndef SERIAL_H -# define SERIAL_H +#ifndef EMU_SERIAL_H +# define EMU_SERIAL_H /* Default settings for the standard ports. */ @@ -61,4 +61,4 @@ extern int serial_link(int, char *); extern void serial_write_fifo(SERIAL *, uint8_t); -#endif /*SERIAL_H*/ +#endif /*EMU_SERIAL_H*/ diff --git a/src/xtide.c b/src/xtide.c index b6deef1a5..e7997d8fa 100644 --- a/src/xtide.c +++ b/src/xtide.c @@ -8,14 +8,13 @@ * * XT IDE controller emulation. * - * Version: @(#)xtide.c 1.0.0 2017/05/30 + * Version: @(#)xtide.c 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include "ibm.h" #include "io.h" @@ -26,6 +25,10 @@ #include "xtide.h" +#define XTIDE_ROM_PATH L"roms/ide_xt.bin" +#define ATIDE_ROM_PATH L"roms/ide_at.bin" + + typedef struct xtide_t { uint8_t data_high; @@ -92,7 +95,7 @@ static void *xtide_init(void) xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, L"roms/ide_xt.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, XTIDE_ROM_PATH, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_xtide_init(); io_sethandler(0x0300, 0x0010, xtide_read, NULL, NULL, xtide_write, NULL, NULL, xtide); @@ -105,7 +108,7 @@ static void *xtide_at_init(void) xtide_t *xtide = malloc(sizeof(xtide_t)); memset(xtide, 0, sizeof(xtide_t)); - rom_init(&xtide->bios_rom, L"roms/ide_at.bin", 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); + rom_init(&xtide->bios_rom, ATIDE_ROM_PATH, 0xc8000, 0x4000, 0x3fff, 0, MEM_MAPPING_EXTERNAL); ide_init(); return xtide; diff --git a/src/xtide.h b/src/xtide.h index 925d96568..f1f0a3da2 100644 --- a/src/xtide.h +++ b/src/xtide.h @@ -8,15 +8,21 @@ * * XT IDE controller emulation. * - * Version: @(#)xtide.h 1.0.0 2017/05/30 + * Version: @(#)xtide.h 1.0.1 2017/06/03 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ +#ifndef EMU_XTIDE_H +# define EMU_XTIDE_H + extern device_t xtide_device; extern device_t xtide_at_device; extern device_t xtide_ps2_device; extern device_t xtide_at_ps2_device; + + +#endif /*EMU_XTIDE_H*/ From 9c79acd3c8a57be45e851461ce680083880320e4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 15:08:10 +0200 Subject: [PATCH 302/392] Fixed the settings dialog, now it shows again. --- src/WIN/86Box.rc | 2 ++ src/WIN/resource.h | 2 +- src/WIN/win_settings.c | 2 +- src/disc.c | 8 ++++---- src/disc.h | 8 +++++--- src/fdc.c | 22 +++++++++++----------- 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index b4983a802..66d42bb21 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -90,6 +90,7 @@ BEGIN END MENUITEM "S&tatus", IDM_STATUS END +#ifdef ENABLE_LOG_TOGGLES POPUP "&Logging" BEGIN #ifdef ENABLE_BUSLOGIC_LOG @@ -123,6 +124,7 @@ BEGIN # endif #endif END +#endif POPUP "&Help" BEGIN MENUITEM "&About 86Box...", IDM_ABOUT diff --git a/src/WIN/resource.h b/src/WIN/resource.h index b89a90fd3..3dcf6b3be 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -29,7 +29,7 @@ #define DLG_ABOUT 101 #define DLG_STATUS 102 -#define DLG_CONFIG 110 +#define DLG_CFG_MAIN 110 #define DLG_CFG_MACHINE 111 #define DLG_CFG_VIDEO 112 #define DLG_CFG_INPUT 113 diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 392477e9d..1ca1a4a13 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -4240,5 +4240,5 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar void win_settings_open(HWND hwnd) { - DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); + DialogBox(hinstance, (LPCWSTR)DLG_CFG_MAIN, hwnd, win_settings_main_proc); } diff --git a/src/disc.c b/src/disc.c index 015f4ff11..bdede24ed 100644 --- a/src/disc.c +++ b/src/disc.c @@ -247,22 +247,22 @@ void disc_poll(int drive) } } -void disc_poll_0() +void disc_poll_0(void *priv) { disc_poll(0); } -void disc_poll_1() +void disc_poll_1(void *priv) { disc_poll(1); } -void disc_poll_2() +void disc_poll_2(void *priv) { disc_poll(2); } -void disc_poll_3() +void disc_poll_3(void *priv) { disc_poll(3); } diff --git a/src/disc.h b/src/disc.h index b065b4b53..eb5c7a1bd 100644 --- a/src/disc.h +++ b/src/disc.h @@ -51,8 +51,10 @@ extern void disc_close(int drive); extern void disc_init(void); extern void disc_reset(void); extern void disc_poll(int drive); -extern void disc_poll_0(void); -extern void disc_poll_1(void); +extern void disc_poll_0(void* priv); +extern void disc_poll_1(void* priv); +extern void disc_poll_2(void* priv); +extern void disc_poll_3(void* priv); extern void disc_seek(int drive, int track); extern void disc_readsector(int drive, int sector, int track, int side, int density, int sector_size); @@ -68,7 +70,7 @@ extern void disc_stop(int drive); extern int disc_empty(int drive); extern void disc_set_rate(int drive, int drvden, int rate); -extern void fdc_callback(void); +extern void fdc_callback(void *priv); extern int fdc_data(uint8_t dat); extern void fdc_spindown(void); extern void fdc_finishread(void); diff --git a/src/fdc.c b/src/fdc.c index eed50ca13..e7f110440 100644 --- a/src/fdc.c +++ b/src/fdc.c @@ -150,7 +150,7 @@ int disctime; static FDC fdc; -void fdc_callback(); +void fdc_callback(void *priv); int timetolive; int lastbyte=0; uint8_t disc_3f7; @@ -848,7 +848,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = 8; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 10: /*Read sector ID*/ fdc.pnum=0; @@ -874,13 +874,13 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = 0x0e; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 0x10: /*Get version*/ fdc.lastdrive = fdc.drive; discint = 0x10; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 0x12: /*Set perpendicular mode*/ if (!AT || fdc.pcjr || fdc.ps1) goto bad_command; @@ -900,7 +900,7 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = fdc.command; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); break; case 0x18: @@ -908,10 +908,10 @@ void fdc_write(uint16_t addr, uint8_t val, void *priv) fdc.lastdrive = fdc.drive; discint = 0x10; fdc.pos = 0; - fdc_callback(); + fdc_callback(NULL); /* fdc.stat = 0x10; discint = 0xfc; - fdc_callback(); */ + fdc_callback(NULL); */ break; default: @@ -1473,7 +1473,7 @@ void fdc_no_dma_end(int compare) fdc_poll_common_finish(compare, 0x80); } -void fdc_callback() +void fdc_callback(void *priv) { int compare = 0; int drive_num = 0; @@ -2000,7 +2000,7 @@ void fdc_track_finishread(int condition) fdc.stat = 0x10; fdc.satisfying_sectors |= condition; fdc.inread = 0; - fdc_callback(); + fdc_callback(NULL); } void fdc_sector_finishcompare(int satisfying) @@ -2008,14 +2008,14 @@ void fdc_sector_finishcompare(int satisfying) fdc.stat = 0x10; fdc.satisfying_sectors++; fdc.inread = 0; - fdc_callback(); + fdc_callback(NULL); } void fdc_sector_finishread() { fdc.stat = 0x10; fdc.inread = 0; - fdc_callback(); + fdc_callback(NULL); } /* There is no sector ID. */ From 95cfba9715c9913d3b66513cf68ada24cab91728 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 16:19:11 +0200 Subject: [PATCH 303/392] MPU-401 reset now sends ACK also in UART mode, fixes MEGAMID and possibly other programs. --- src/SOUND/snd_mpu401.c | 12 +++++++++++- src/SOUND/snd_mpu401.h | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 97fece713..60e3bd1c6 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -162,7 +162,7 @@ static void MPU401_ResetDone(void *p) static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) { uint8_t i; - + if (mpu->state.reset) { mpu->state.cmd_pending=val+1; @@ -301,7 +301,9 @@ static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val) mpu401_reset_callback = MPU401_RESETBUSY * 33 * TIMER_USEC; mpu->state.reset=1; MPU401_Reset(mpu); +#if 0 if (mpu->mode==M_UART) return;//do not send ack in UART mode +#endif break; case 0x3f: /* UART mode */ pclog("MPU-401:Set UART mode %X\n",val); @@ -733,6 +735,14 @@ next_event: void mpu401_init(mpu_t *mpu, uint16_t addr, int irq, int mode) { +#if 0 + if (mode != M_INTELLIGENT) + { + mpu401_uart_init(mpu, addr); + return; + } +#endif + mpu->status = STATUS_INPUT_NOT_READY; mpu->irq = irq; mpu->queue_used = 0; diff --git a/src/SOUND/snd_mpu401.h b/src/SOUND/snd_mpu401.h index 86dfa2058..41c1e9240 100644 --- a/src/SOUND/snd_mpu401.h +++ b/src/SOUND/snd_mpu401.h @@ -43,6 +43,8 @@ typedef enum MpuDataType {T_OVERFLOW,T_MARK,T_MIDI_SYS,T_MIDI_NORM,T_COMMAND} Mp typedef struct mpu_t { + int uart_mode; + uint8_t rx_data; int intelligent; MpuMode mode; int irq; @@ -88,3 +90,5 @@ extern int mpu401_standalone_enable; void mpu401_device_add(void); device_t mpu401_device; + +void mpu401_uart_init(mpu_t *mpu, uint16_t addr); From 8ca0565864d3a357345d7f55d77cedd13ee07aa2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 16:22:21 +0200 Subject: [PATCH 304/392] The standalone MPU-401 checkbox in Settings is now actually set if standalone MPU-401 is enabled. --- src/WIN/win_settings.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 1ca1a4a13..cd0e3007a 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1217,6 +1217,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa EnableWindow(h, mpu401_present() ? TRUE : FALSE); h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); From c7f33590102cfe730274ca057504fa18346fbf7c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 17:34:29 +0200 Subject: [PATCH 305/392] The MIDI OUT device selection box is now enabled when standalone MPU-401 is enabled in Settings. --- src/WIN/win_settings.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index cd0e3007a..6dc8ef98f 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1273,6 +1273,9 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); EnableWindow(h, mpu401_present() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); break; case IDC_CONFIGURE_MPU401: From ec733714b58dc5555d6830ef563970998376e4bc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 21:43:29 +0200 Subject: [PATCH 306/392] Reverted the ATi Mach64 emulation completely to mainline PCem (+ cleanups). --- src/VIDEO/vid_ati_mach64.c | 196 ++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 102 deletions(-) diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index 6ac27c4d4..a2ddb1d2d 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -18,12 +18,12 @@ #include #include "../ibm.h" +#include "../device.h" #include "../io.h" #include "../mem.h" #include "../pci.h" #include "../rom.h" #include "../thread.h" -#include "../device.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" @@ -31,6 +31,9 @@ #include "vid_ati_eeprom.h" #include "vid_ics2595.h" +#ifdef CLAMP +#undef CLAMP +#endif #define FIFO_SIZE 65536 #define FIFO_MASK (FIFO_SIZE - 1) @@ -79,8 +82,8 @@ typedef struct mach64_t uint8_t regs[256]; int index; - - int type; + + int type; uint8_t pci_regs[256]; uint8_t int_line; @@ -212,7 +215,7 @@ typedef struct mach64_t uint32_t config_chip_id; uint32_t block_decoded_io; int use_block_decoded_io; - + int pll_addr; uint8_t pll_regs[16]; double pll_freq[4]; @@ -486,7 +489,7 @@ void mach64_updatemapping(mach64_t *mach64) if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { - pclog("Update mapping - PCI disabled\n"); + /* pclog("Update mapping - PCI disabled\n"); */ mem_mapping_disable(&svga->mapping); mem_mapping_disable(&mach64->linear_mapping); mem_mapping_disable(&mach64->mmio_mapping); @@ -501,7 +504,7 @@ void mach64_updatemapping(mach64_t *mach64) case 0x0: /*128k at A0000*/ mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, NULL, NULL, mach64_write, NULL, NULL); mem_mapping_set_p(&mach64->svga.mapping, mach64); - mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x1fc00); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_enable(&mach64->mmio_mapping); svga->banked_mask = 0xffff; break; @@ -520,37 +523,34 @@ void mach64_updatemapping(mach64_t *mach64) case 0xC: /*32k at B8000*/ mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); mem_mapping_set_p(&mach64->svga.mapping, svga); - mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x07c00); + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; } if (mach64->linear_base) { - if (mach64->type == MACH64_GX) - { - if ((mach64->config_cntl & 3) == 2) - { - /*8 MB aperture*/ - pclog("8 MB aperture\n"); - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x007FFC00); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x007FFC00, 0x400); - } - else - { - /*4 MB aperture*/ - pclog("4 MB aperture\n"); - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, 0x003FFC00); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + 0x003FFC00, 0x400); - } - svga->linear_base = mach64->linear_base; - } - else - { + if (mach64->type == MACH64_GX) + { + if ((mach64->config_cntl & 3) == 2) + { + /*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + } + else + { + /*4 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); + } + } + else + { /*2*8 MB aperture*/ mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); - } + } } else { @@ -562,11 +562,6 @@ void mach64_updatemapping(mach64_t *mach64) static void mach64_update_irqs(mach64_t *mach64) { - if (!PCI) - { - return; - } - if ((mach64->crtc_int_cntl & 0xaa0024) & ((mach64->crtc_int_cntl << 1) & 0xaa0024)) pci_set_irq(mach64->card, PCI_INTA); else @@ -627,8 +622,8 @@ static void mach64_accel_write_fifo(mach64_t *mach64, uint32_t addr, uint8_t val case 0x11e: case 0x11f: WRITE8(addr, mach64->dst_height_width, val); case 0x113: - if (((addr & 0x3ff) == 0x11b) || ((addr & 0x3ff) == 0x11f) || - (((addr & 0x3ff) == 0x113) && !(val & 0x80))) + if (((addr & 0x3ff) == 0x11b || (addr & 0x3ff) == 0x11f || + (addr & 0x3ff) == 0x113) && !(val & 0x80)) { mach64_start_fill(mach64); #ifdef MACH64_DEBUG @@ -870,10 +865,6 @@ static void mach64_accel_write_fifo_l(mach64_t *mach64, uint32_t addr, uint32_t static void fifo_thread(void *param) { mach64_t *mach64 = (mach64_t *)param; - fifo_entry_t *fifo; - - uint64_t start_time = 0; - uint64_t end_time = 0; while (1) { @@ -883,8 +874,9 @@ static void fifo_thread(void *param) mach64->blitter_busy = 1; while (!FIFO_EMPTY) { - start_time = timer_read(); - fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; + uint64_t start_time = timer_read(); + uint64_t end_time; + fifo_entry_t *fifo = &mach64->fifo[mach64->fifo_read_idx & FIFO_MASK]; switch (fifo->addr_type & FIFO_TYPE) { @@ -936,8 +928,7 @@ static void mach64_queue(mach64_t *mach64, uint32_t addr, uint32_t val, uint32_t void mach64_cursor_dump(mach64_t *mach64) { -/* pclog("Mach64 cursor :\n"); - pclog("Ena = %i X = %i Y = %i Addr = %05X Xoff = %i Yoff = %i\n", svga->hwcursor.ena, svga->hwcursor.x, svga->hwcursor.y, svga->hwcursor.addr, svga->hwcursor.xoff, svga->hwcursor.yoff);*/ + return; } void mach64_start_fill(mach64_t *mach64) @@ -1000,7 +991,7 @@ void mach64_start_fill(mach64_t *mach64) mach64->accel.dst_size = mach64_width[mach64->accel.dst_pix_width]; mach64->accel.src_size = mach64_width[mach64->accel.src_pix_width]; mach64->accel.host_size = mach64_width[mach64->accel.host_pix_width]; - + if (mach64->accel.src_size == WIDTH_1BIT) mach64->accel.src_offset <<= 3; else @@ -1011,11 +1002,12 @@ void mach64_start_fill(mach64_t *mach64) else mach64->accel.dst_offset >>= mach64->accel.dst_size; - mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; - mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; + mach64->accel.xinc = (mach64->dst_cntl & DST_X_DIR) ? 1 : -1; + mach64->accel.yinc = (mach64->dst_cntl & DST_Y_DIR) ? 1 : -1; mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); - + + for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) @@ -1029,6 +1021,9 @@ void mach64_start_fill(mach64_t *mach64) mach64->accel.sc_right = (mach64->sc_left_right >> 16) & 0x1fff; mach64->accel.sc_top = mach64->sc_top_bottom & 0x7fff; mach64->accel.sc_bottom = (mach64->sc_top_bottom >> 16) & 0x7fff; + +/* mach64->accel.sc_left *= mach64_inc[mach64->accel.dst_pix_width]; + mach64->accel.sc_right *= mach64_inc[mach64->accel.dst_pix_width];*/ mach64->accel.dp_frgd_clr = mach64->dp_frgd_clr; mach64->accel.dp_bkgd_clr = mach64->dp_bkgd_clr; @@ -1192,8 +1187,8 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) while (count) { uint32_t src_dat, dest_dat; - uint32_t host_dat; - int mix; + uint32_t host_dat = 0; + int mix = 0; int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; int src_x; @@ -1396,9 +1391,9 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) case OP_LINE: while (count) { - uint32_t src_dat, dest_dat; - uint32_t host_dat; - int mix; + uint32_t src_dat = 0, dest_dat; + uint32_t host_dat = 0; + int mix = 0; int draw_pixel = !(mach64->dst_cntl & DST_POLYGON_EN); if (mach64->accel.source_host) @@ -1473,7 +1468,7 @@ void mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } READ(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, dest_dat, mach64->accel.dst_size); - + switch (mach64->accel.clr_cmp_fn) { case 1: /*TRUE*/ @@ -1644,18 +1639,18 @@ static void pll_write(mach64_t *mach64, uint32_t addr, uint8_t val) break; case 2: /*Data*/ mach64->pll_regs[mach64->pll_addr] = val; - pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); + /* pclog("pll_write %02x,%02x\n", mach64->pll_addr, val); */ - for (c = 0; c < 4; c++) + for (c = 0; c < 4; c++) { double m = (double)mach64->pll_regs[PLL_REF_DIV]; double n = (double)mach64->pll_regs[VCLK0_FB_DIV+c]; double r = 14318184.0; double p = (double)(1 << ((mach64->pll_regs[VCLK_POST_DIV] >> (c*2)) & 3)); - pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); + /* pclog("PLLfreq %i = %g %g m=%02x n=%02x p=%02x\n", c, (2.0 * r * n) / (m * p), p, mach64->pll_regs[PLL_REF_DIV], mach64->pll_regs[VCLK0_FB_DIV+c], mach64->pll_regs[VCLK_POST_DIV]); */ mach64->pll_freq[c] = (2.0 * r * n) / (m * p); - pclog(" %g\n", mach64->pll_freq[c]); + /* pclog(" %g\n", mach64->pll_freq[c]); */ } break; } @@ -1666,9 +1661,9 @@ static void mach64_vblank_start(svga_t *svga) { mach64_t *mach64 = (mach64_t *)svga->p; int overlay_cmp_mix = (mach64->overlay_key_cntl >> 8) & 0xf; - + mach64->crtc_int_cntl |= 4; - mach64_update_irqs(mach64); + mach64_update_irqs(mach64); svga->overlay.x = (mach64->overlay_y_x_start >> 16) & 0x7ff; svga->overlay.y = mach64->overlay_y_x_start & 0x7ff; @@ -1691,7 +1686,10 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) uint8_t ret; if (!(addr & 0x400)) { - switch (addr & 0x3ff) +#ifdef MACH64_DEBUG + pclog("nmach64_ext_readb: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); +#endif + switch (addr & 0x3ff) { case 0x00: case 0x01: case 0x02: case 0x03: READ8(addr, mach64->overlay_y_x_start); @@ -1790,6 +1788,10 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->cur_horz_vert_off); break; + case 0x79: + ret = 0x30; + break; + case 0x80: case 0x81: case 0x82: case 0x83: READ8(addr, mach64->scratch_reg0); break; @@ -1797,10 +1799,6 @@ uint8_t mach64_ext_readb(uint32_t addr, void *p) READ8(addr, mach64->scratch_reg1); break; - case 0x79: - ret = 0x30; - break; - case 0x90: case 0x91: case 0x92: case 0x93: READ8(addr, mach64->clock_cntl); break; @@ -2090,7 +2088,10 @@ uint32_t mach64_ext_readl(uint32_t addr, void *p) uint32_t ret; if (!(addr & 0x400)) { - ret = 0xffffffff; +#ifdef MACH64_DEBUG + pclog("nmach64_ext_readl: addr=%04x %04x(%08x):%08x\n", addr, CS, cs, cpu_state.pc); +#endif + ret = 0xffffffff; } else switch (addr & 0x3ff) { @@ -2220,7 +2221,7 @@ void mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) mach64->crtc_int_cntl = (mach64->crtc_int_cntl & 0x75) | (val & ~0x75); if (val & 4) mach64->crtc_int_cntl &= ~4; - mach64_update_irqs(mach64); + mach64_update_irqs(mach64); break; case 0x1c: case 0x1d: case 0x1e: case 0x1f: @@ -2527,6 +2528,7 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) case 0x72ec: case 0x72ed: case 0x72ee: case 0x72ef: ret = mach64_ext_readb(0x400 | 0xe4 | (port & 3), p); + break; default: ret = 0; @@ -2713,7 +2715,7 @@ void mach64_ext_outw(uint16_t port, uint16_t val, void *p) } void mach64_ext_outl(uint16_t port, uint32_t val, void *p) { - pclog("mach64_ext_outl : port %04X val %08X\n", port, val); + /* pclog("mach64_ext_outl : port %04X val %08X\n", port, val); */ switch (port) { default: @@ -3015,7 +3017,7 @@ void mach64_overlay_draw(svga_t *svga, int displine) break; default: - pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); + /* pclog("Unknown Mach64 scaler format %x\n", mach64->scaler_format); */ /*Fill buffer with something recognisably wrong*/ for (x = 0; x < mach64->svga.overlay_latch.xsize; x++) mach64->overlay_dat[x] = 0xff00ff; @@ -3131,17 +3133,17 @@ static void mach64_io_set(mach64_t *mach64) mach64_io_remove(mach64); io_sethandler(0x03c0, 0x0020, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); - - if (!mach64->use_block_decoded_io) - { - for (c = 0; c < 8; c++) - { - io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); - } - } + + if (!mach64->use_block_decoded_io) + { + for (c = 0; c < 8; c++) + { + io_sethandler((c * 0x1000) + 0x2ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0x6ec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xaec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + io_sethandler((c * 0x1000) + 0xeec, 0x0004, mach64_ext_inb, mach64_ext_inw, mach64_ext_inl, mach64_ext_outb, mach64_ext_outw, mach64_ext_outl, mach64); + } + } io_sethandler(0x01ce, 0x0002, mach64_in, NULL, NULL, mach64_out, NULL, NULL, mach64); @@ -3173,12 +3175,12 @@ uint8_t mach64_pci_read(int func, int addr, void *p) case 0x09: return 0; /*Programming interface*/ - case 0x0a: return 0x00; + case 0x0a: return 0x01; /*Supports VGA interface, XGA compatible*/ case 0x0b: return 0x03; case 0x10: return 0x00; /*Linear frame buffer address*/ case 0x11: return 0x00; - case 0x12: return 0x00; + case 0x12: return mach64->linear_base >> 16; case 0x13: return mach64->linear_base >> 24; case 0x14: return 0x01; /*Block decoded IO address*/ @@ -3199,35 +3201,29 @@ uint8_t mach64_pci_read(int func, int addr, void *p) return 0; } -uint32_t bios_base = 0x000c0000; - void mach64_pci_write(int func, int addr, uint8_t val, void *p) { mach64_t *mach64 = (mach64_t *)p; - + switch (addr) { case PCI_REG_COMMAND: mach64->pci_regs[PCI_REG_COMMAND] = val & 0x27; - if (val & PCI_COMMAND_IO) mach64_io_set(mach64); else mach64_io_remove(mach64); - mach64_updatemapping(mach64); break; - case 0x12: - if (mach64->type == MACH64_VT2) - val = 0; - break; - /* case 0x12: + case 0x12: + if (mach64->type == MACH64_VT2) + val = 0; mach64->linear_base = (mach64->linear_base & 0xff000000) | ((val & 0x80) << 16); mach64_updatemapping(mach64); - break; */ + break; case 0x13: - mach64->linear_base = (val << 24); + mach64->linear_base = (mach64->linear_base & 0x800000) | (val << 24); mach64_updatemapping(mach64); break; @@ -3267,13 +3263,12 @@ void mach64_pci_write(int func, int addr, uint8_t val, void *p) if (mach64->pci_regs[0x30] & 0x01) { uint32_t addr = (mach64->pci_regs[0x32] << 16) | (mach64->pci_regs[0x33] << 24); - bios_base = addr; - pclog("Mach64 bios_rom enabled at %08x\n", addr); + /* pclog("Mach64 bios_rom enabled at %08x\n", addr); */ mem_mapping_set_addr(&mach64->bios_rom.mapping, addr, 0x8000); } else { - pclog("Mach64 bios_rom disabled\n"); + /* pclog("Mach64 bios_rom disabled\n"); */ mem_mapping_disable(&mach64->bios_rom.mapping); } return; @@ -3328,7 +3323,7 @@ static void *mach64_common_init() mach64->pci_regs[0x33] = 0x00; ati68860_ramdac_init(&mach64->ramdac); - + mach64->dst_cntl = 3; mach64->wake_fifo_thread = thread_create_event(); @@ -3368,9 +3363,8 @@ static void *mach64vt2_init() mach64->config_chip_id = 0x40005654; mach64->dac_cntl = 1 << 16; /*Internal 24-bit DAC*/ mach64->config_stat0 = 4; - - mach64->use_block_decoded_io = PCI ? 4 : 0; - + mach64->use_block_decoded_io = PCI ? 4 : 0; + ati_eeprom_load(&mach64->eeprom, L"mach64vt.nvr", 1); rom_init(&mach64->bios_rom, L"roms/atimach64vt2pci.bin", 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); @@ -3384,7 +3378,6 @@ int mach64gx_available() { return rom_present(L"roms/mach64gx/bios.bin"); } - int mach64vt2_available() { return rom_present(L"roms/atimach64vt2pci.bin"); @@ -3522,7 +3515,6 @@ device_t mach64gx_device = mach64_add_status_info, mach64gx_config }; - device_t mach64vt2_device = { "ATI Mach64VT2", From 3d7e05aa0a1ababee5eb6d6e8562ed6d1ca5bbc0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 4 Jun 2017 22:55:43 +0200 Subject: [PATCH 307/392] SVGA linear frame bufferbase is now set by the Mach64 code, fixes the AMIDIAG video memory test. --- src/VIDEO/vid_ati_mach64.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index a2ddb1d2d..8668d21e7 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -551,6 +551,7 @@ void mach64_updatemapping(mach64_t *mach64) mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); } + svga->linear_base = mach64->linear_base; } else { From 0a457f8167333d03fcc5d8406da2123f2fb2f3c3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 5 Jun 2017 00:32:40 +0200 Subject: [PATCH 308/392] Fixed the AT keyboard input port operation, fixes the Password cleared by jumper message on the Award 430VX PCI. --- src/keyboard_at.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/keyboard_at.c b/src/keyboard_at.c index 06fba2399..fbd9c02e1 100644 --- a/src/keyboard_at.c +++ b/src/keyboard_at.c @@ -645,7 +645,8 @@ bad_command: break; case 0xc0: /*Read input port*/ - keyboard_at_adddata((keyboard_at.input_port & 0xfc) | 0x84 | fdc_ps1_525()); + keyboard_at_adddata(keyboard_at.input_port | 4 | fdc_ps1_525()); + keyboard_at.input_port = ((keyboard_at.input_port + 1) & 3) | (keyboard_at.input_port & 0xfc) | fdc_ps1_525(); break; case 0xc1: /*Copy bits 0 to 3 of input port to status bits 4 to 7*/ From 07e72f72efc4cd8629b0f29b7e9e50f1fa530d84 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 5 Jun 2017 01:33:14 +0200 Subject: [PATCH 309/392] Applied the remaining mainline PCem commits. --- src/CPU/386_common.h | 42 ++----- src/CPU/codegen_ops_x86-64.h | 229 +++++++++++++++-------------------- src/CPU/codegen_x86.c | 216 ++++++++++++++++----------------- src/CPU/cpu.c | 40 +++++- src/CPU/cpu.h | 5 + src/ibm.h | 4 +- src/mem.c | 208 ++++++++++++++++++------------- src/model.c | 2 +- 8 files changed, 381 insertions(+), 365 deletions(-) diff --git a/src/CPU/386_common.h b/src/CPU/386_common.h index 6042cc151..562c2445d 100644 --- a/src/CPU/386_common.h +++ b/src/CPU/386_common.h @@ -23,39 +23,15 @@ extern uint16_t ea_rseg; #define readmemb(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[(uint32_t)((s)+(a))>>12] + (uint32_t)((s) + (a))) ) -#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8)?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemq(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7))?readmemql(s,a):*(uint64_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) #define writememb(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememw(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1)) writememwl(s,a,v); else *(uint16_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememl(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3)) writememll(s,a,v); else *(uint32_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v +#define writememq(s,a,v) if (writelookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 7)) writememql(s,a,v); else *(uint64_t *)(writelookup2[(uint32_t)((s) + (a)) >> 12] + (uint32_t)((s) + (a))) = v -#if 0 -#define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ - { \ - int tempi = checkio(port); \ - if (cpu_state.abrt) return 1; \ - if (tempi) \ - { \ - x86gpf("check_io_perm(): no permission",0); \ - return 1; \ - } \ - } - -#define checkio_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ - { \ - tempi = checkio(port); \ - if (cpu_state.abrt) break; \ - if (tempi) \ - { \ - x86gpf("checkio_perm(): no permission",0); \ - break; \ - } \ - } -#endif - #define check_io_perm(port) if (msw&1 && ((CPL > IOPL) || (eflags&VM_FLAG))) \ { \ int tempi = checkio(port); \ @@ -153,8 +129,8 @@ static __inline uint16_t fastreadw(uint32_t a) uint16_t val; if ((a&0xFFF)>0xFFE) { - val = readmemb(0, a); - val |= (readmemb(0, a + 1) << 8); + val = fastreadb(a); + val |= (fastreadb(a + 1) << 8); return val; } if ((a>>12)==pccache) return *((uint16_t *)&pccache2[a]); @@ -184,10 +160,8 @@ static __inline uint32_t fastreadl(uint32_t a) } return *((uint32_t *)&pccache2[a]); } - val =readmemb(0,a); - val |=(readmemb(0,a+1)<<8); - val |=(readmemb(0,a+2)<<16); - val |=(readmemb(0,a+3)<<24); + val = fastreadw(a); + val |= (fastreadw(a + 2) << 16); return val; } diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index f08db0b31..e85f5315f 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -1066,16 +1066,14 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -1095,18 +1093,17 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x66); /*MOV AX,-1[RDI+RSI]*/ + addbyte(4+2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ addbyte(0x8b); - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12+4+6); /*slowpath:*/ @@ -1155,16 +1152,14 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -1184,17 +1179,16 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); - addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ - addbyte(0x44); + addbyte(3+2); + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12+4+6); /*slowpath:*/ @@ -1236,16 +1230,14 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 7[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -1265,18 +1257,17 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x48); /*MOV RAX,-7[RDI+RSI]*/ + addbyte(4+2); + addbyte(0x48); /*MOV RAX,[RDI+RSI]*/ addbyte(0x8b); - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12+4+6); /*slowpath:*/ @@ -1444,16 +1435,14 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -1473,29 +1462,27 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 6:5)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 5:4)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 6:5)+2); + addbyte(((host_reg & 8) ? 5:4)+2); if (host_reg & 8) { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x44); addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } else { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12+4+6); @@ -1539,16 +1526,14 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -1568,27 +1553,25 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 4:3)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); + addbyte(((host_reg & 8) ? 4:3)+2); if (host_reg & 8) { addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } else { addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12+4+6); @@ -1632,16 +1615,14 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 7[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -1661,28 +1642,26 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); + addbyte(4+2); if (host_reg & 8) { - addbyte(0x4c); /*MOV -7[RDI+RSI],host_reg*/ + addbyte(0x4c); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); } else { - addbyte(0x48); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x48); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12+4+6); @@ -5818,16 +5797,14 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -5847,18 +5824,17 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+2); + addbyte(0x75); /*JE slowpath*/ + addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+2); - addbyte(0x66); /*MOV AX,-1[RDI+RSI]*/ + addbyte(4+2); + addbyte(0x66); /*MOV AX,[RDI+RSI]*/ addbyte(0x8b); - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12); /*slowpath:*/ @@ -5899,16 +5875,14 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x8d); addbyte(0x34); addbyte(0x08); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(readlookup2)) { addbyte(0x67); /*MOV RSI, readlookup2[ESI*8]*/ @@ -5928,17 +5902,16 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+2); + addbyte(0x54); /*JNE slowpath*/ + addbyte(3+2+3+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+2); + addbyte(3+2); addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ - addbyte(0x44); + addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xeb); /*JMP done*/ addbyte(2+2+12); /*slowpath:*/ @@ -6081,16 +6054,14 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x18); - addbyte(0x67); /*LEA EDI, 1[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -6110,29 +6081,27 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 6:5)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 5:4)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 6:5)+2); + addbyte(((host_reg & 8) ? 5:4)+2); if (host_reg & 8) { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x44); addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } else { - addbyte(0x66); /*MOV -1[RDI+RSI],host_reg*/ + addbyte(0x66); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | (host_reg << 3)); + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12); @@ -6170,16 +6139,14 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8d); addbyte(0x34); addbyte(0x18); - addbyte(0x67); /*LEA EDI, 3[ESI]*/ - addbyte(0x8d); - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); if (IS_32_ADDR(writelookup2)) { addbyte(0x67); /*MOV RSI, writelookup2[ESI*8]*/ @@ -6199,27 +6166,25 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+((host_reg & 8) ? 5:4)+2); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+((host_reg & 8) ? 4:3)+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(((host_reg & 8) ? 5:4)+2); + addbyte(((host_reg & 8) ? 4:3)+2); if (host_reg & 8) { - addbyte(0x44); /*MOV -3[RDI+RSI],host_reg*/ + addbyte(0x44); /*MOV [RDI+RSI],host_reg*/ addbyte(0x89); - addbyte(0x44 | ((host_reg & 7) << 3)); + addbyte(0x04 | ((host_reg & 7) << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } else { - addbyte(0x89); /*MOV -3[RDI+RSI],host_reg*/ - addbyte(0x44 | (host_reg << 3)); + addbyte(0x89); /*MOV [RDI+RSI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); } addbyte(0xeb); /*JMP done*/ addbyte(2+2+3+12); diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index 82b8e5575..a4f0ffe59 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -136,31 +136,29 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 1[EDX]*/ - addbyte(0x7a); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x0f); /*MOVZX EAX, -1[EDX+EDI]W*/ + addbyte(4+1); + addbyte(0x0f); /*MOVZX EAX, [EDX+EDI]W*/ addbyte(0xb7); - addbyte(0x44); + addbyte(0x04); addbyte(0x3a); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -193,30 +191,28 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 3[EDX]*/ - addbyte(0x7a); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x8b); /*MOV EAX, -3[EDX+EDI]*/ - addbyte(0x44); + addbyte(3+1); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); addbyte(0x3a); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -246,34 +242,32 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_Q() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 7[EDX]*/ - addbyte(0x7a); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+4+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+4+1); + addbyte(3+4+1); addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ - addbyte(0x44); + addbyte(0x04); addbyte(0x3a); - addbyte(-7); addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ addbyte(0x54); addbyte(0x3a); - addbyte(-7+4); + addbyte(4); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -352,31 +346,29 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 1[ESI]*/ - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ + addbyte(4+1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ addbyte(0x89); - addbyte(0x44 | (REG_CX << 3)); + addbyte(0x04 | (REG_CX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -408,30 +400,28 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 3[ESI]*/ - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ - addbyte(0x44 | (REG_ECX << 3)); + addbyte(3+1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -463,34 +453,32 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q() addbyte(0xf2); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 7[ESI]*/ - addbyte(0x7e); - addbyte(0x07); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xf7); /*TEST EDI, 7*/ addbyte(0xc7); - addlong(0xff8); + addlong(7); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+4+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+4+1); - addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ - addbyte(0x44 | (REG_EBX << 3)); + addbyte(3+4+1); + addbyte(0x89); /*MOV [EDI+ESI],EBX*/ + addbyte(0x04 | (REG_EBX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7); - addbyte(0x89); /*MOV -7[EDI+ESI],EBX*/ + addbyte(0x89); /*MOV 4[EDI+ESI],EBX*/ addbyte(0x44 | (REG_ECX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-7+4); + addbyte(4); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -514,7 +502,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_LOAD_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_B_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -576,7 +566,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_LOAD_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_W_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -585,31 +577,29 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 1[EDX]*/ - addbyte(0x7a); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x0f); /*MOVZX EEX, -1[EDX+EDI]W*/ + addbyte(4+1); + addbyte(0x0f); /*MOVZX ECX, [EDX+EDI]W*/ addbyte(0xb7); - addbyte(0x4c); + addbyte(0x0c); addbyte(0x3a); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -645,7 +635,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_LOAD_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_LOAD_ADDR_EA_L_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -654,30 +646,28 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() addbyte(0xd6); addbyte(0x01); /*ADDL EDX, EAX*/ addbyte(0xc2); - addbyte(0x8d); /*LEA EDI, 3[EDX]*/ - addbyte(0x7a); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); addbyte(0xc1); /*SHR EDX, 12*/ addbyte(0xea); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x8b); /*MOV ECX, -3[EDX+EDI]*/ - addbyte(0x4c); + addbyte(3+1); + addbyte(0x8b); /*MOV ECX, [EDX+EDI]*/ + addbyte(0x0c); addbyte(0x3a); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x50); /*slowpath: PUSH EAX*/ @@ -713,7 +703,9 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_STORE_ADDR_EA_B_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_B_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -771,7 +763,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_W_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -781,31 +775,29 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 1[ESI]*/ - addbyte(0x7e); - addbyte(0x01); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xfff*/ + addbyte(0xf7); /*TEST EDI, 1*/ addbyte(0xc7); - addlong(0xfff); + addlong(1); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+5+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+4+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(5+1); - addbyte(0x66); /*MOV -1[EDI+ESI],CX*/ + addbyte(4+1); + addbyte(0x66); /*MOV [EDI+ESI],CX*/ addbyte(0x89); - addbyte(0x44 | (REG_CX << 3)); + addbyte(0x04 | (REG_CX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-1); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ @@ -837,7 +829,9 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() return addr; } +#ifndef RELEASE_BUILD static char gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err[] = "gen_MEM_STORE_ADDR_EA_L_NO_ABRT aborted\n"; +#endif static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() { uint32_t addr = (uint32_t)&codeblock[block_current].data[block_pos]; @@ -847,30 +841,28 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() addbyte(0xf3); addbyte(0x01); /*ADDL ESI, EAX*/ addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); - addbyte(0x8d); /*LEA EDI, 3[ESI]*/ - addbyte(0x7e); - addbyte(0x03); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xf7); addbyte(0xc1); /*SHR ESI, 12*/ addbyte(0xe8 | REG_ESI); addbyte(12); - addbyte(0xf7); /*TEST EDI, 0xffc*/ + addbyte(0xf7); /*TEST EDI, 3*/ addbyte(0xc7); - addlong(0xffc); + addlong(3); addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ addbyte(0x04 | (REG_ESI << 3)); addbyte(0x85 | (REG_ESI << 3)); addlong((uint32_t)writelookup2); - addbyte(0x74); /*JE slowpath*/ - addbyte(3+2+4+1); + addbyte(0x75); /*JNE slowpath*/ + addbyte(3+2+3+1); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ - addbyte(4+1); - addbyte(0x89); /*MOV -3[EDI+ESI],ECX*/ - addbyte(0x44 | (REG_ECX << 3)); + addbyte(3+1); + addbyte(0x89); /*MOV [EDI+ESI],ECX*/ + addbyte(0x04 | (REG_ECX << 3)); addbyte(REG_EDI | (REG_ESI << 3)); - addbyte(-3); addbyte(0xc3); /*RET*/ addbyte(0x51); /*slowpath: PUSH ECX*/ diff --git a/src/CPU/cpu.c b/src/CPU/cpu.c index 5f6f00b16..0f12a59f1 100644 --- a/src/CPU/cpu.c +++ b/src/CPU/cpu.c @@ -91,6 +91,7 @@ int cpu_hasrdtsc; int cpu_hasMMX, cpu_hasMSR; int cpu_hasCR4; int cpu_use_dynarec; +int cpu_cyrix_alignment; int hasfpu; @@ -152,6 +153,7 @@ int timing_iret_rm, timing_iret_v86, timing_iret_pm, timing_iret_pm_outer; int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_gate_inner; int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; +int timing_misaligned; static struct { @@ -203,6 +205,15 @@ CPU cpus_pcjr[] = {"", -1, 0, 0, 0, 0, 0,0,0,0} }; +CPU cpus_europc[] = +{ + /*8088 EuroPC*/ + {"8088/4.77", CPU_8088, 0, 4772728, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8088/7.16", CPU_8088, 1, 14318184/2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"8088/9.54", CPU_8088, 1, 4772728*2, 1, 0, 0, 0, 0, 0, 0,0,0,0}, + {"", -1, 0, 0, 0, 0} +}; + CPU cpus_8086[] = { /*8086 standard*/ @@ -746,7 +757,10 @@ void cpu_set() } memset(&msr, 0, sizeof(msr)); - + + timing_misaligned = 0; + cpu_cyrix_alignment = 0; + switch (cpu_s->cpu_type) { case CPU_8088: @@ -940,6 +954,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_486DLC: @@ -973,6 +988,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_i486SX: @@ -1006,6 +1022,7 @@ void cpu_set() timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_Am486SX: @@ -1040,6 +1057,7 @@ void cpu_set() timing_jmp_rm = 17; timing_jmp_pm = 19; timing_jmp_pm_gate = 32; + timing_misaligned = 3; break; case CPU_Cx486S: @@ -1073,6 +1091,7 @@ void cpu_set() timing_jmp_rm = 9; timing_jmp_pm = 26; timing_jmp_pm_gate = 37; + timing_misaligned = 3; break; case CPU_Cx5x86: @@ -1105,6 +1124,8 @@ void cpu_set() timing_jmp_rm = 5; timing_jmp_pm = 7; timing_jmp_pm_gate = 17; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; break; case CPU_WINCHIP: @@ -1143,6 +1164,8 @@ void cpu_set() timing_jmp_pm = 7; timing_jmp_pm_gate = 17; codegen_timing_set(&codegen_timing_winchip); + timing_misaligned = 2; + cpu_cyrix_alignment = 1; break; case CPU_PENTIUM: @@ -1175,6 +1198,7 @@ void cpu_set() timing_jmp_rm = 3; timing_jmp_pm = 3; timing_jmp_pm_gate = 18; + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1214,6 +1238,7 @@ void cpu_set() timing_jmp_rm = 3; timing_jmp_pm = 3; timing_jmp_pm_gate = 18; + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1252,6 +1277,8 @@ void cpu_set() timing_jmp_rm = 1; timing_jmp_pm = 4; timing_jmp_pm_gate = 14; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1290,6 +1317,8 @@ void cpu_set() timing_jmp_rm = 1; timing_jmp_pm = 4; timing_jmp_pm_gate = 14; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1311,6 +1340,8 @@ void cpu_set() timing_mml = 2; timing_bt = 5-1; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1362,6 +1393,8 @@ void cpu_set() timing_jmp_rm = 1; timing_jmp_pm = 4; timing_jmp_pm_gate = 14; + timing_misaligned = 2; + cpu_cyrix_alignment = 1; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1384,6 +1417,7 @@ void cpu_set() timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1403,6 +1437,7 @@ void cpu_set() timing_mml = 3; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1435,6 +1470,7 @@ void cpu_set() timing_mml = 1; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 0; @@ -1468,6 +1504,7 @@ void cpu_set() timing_mml = 1; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; @@ -1501,6 +1538,7 @@ void cpu_set() timing_mml = 1; timing_bt = 0; /*branch taken*/ timing_bnt = 1; /*branch not taken*/ + timing_misaligned = 3; cpu_hasrdtsc = 1; msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21); cpu_hasMMX = 1; diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index ce0955b7f..b792b36b8 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -82,6 +82,8 @@ extern int timing_call_rm, timing_call_pm, timing_call_pm_gate, timing_call_pm_g extern int timing_retf_rm, timing_retf_pm, timing_retf_pm_outer; extern int timing_jmp_rm, timing_jmp_pm, timing_jmp_pm_gate; +extern int timing_misaligned; + typedef struct { @@ -124,6 +126,7 @@ extern CPU cpus_Pentium2[]; extern CPU cpus_Pentium2D[]; extern CPU cpus_pcjr[]; +extern CPU cpus_europc[]; extern CPU cpus_pc1512[]; extern CPU cpus_ibmat[]; extern CPU cpus_ps1_m2011[]; @@ -134,6 +137,8 @@ extern int cpu_iscyrix; extern int cpu_16bitbus; extern int cpu_busspeed; extern int cpu_multi; +/*Cyrix 5x86/6x86 only has data misalignment penalties when crossing 8-byte boundaries*/ +extern int cpu_cyrix_alignment; extern int cpu_hasrdtsc; extern int cpu_hasMSR; diff --git a/src/ibm.h b/src/ibm.h index 4291d095e..a95d3635e 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -36,8 +36,8 @@ extern int writelnext; extern int mmu_perm; #define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) -#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE)?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) -#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC)?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmemw(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 1))?readmemwl(s,a):*(uint16_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) +#define readmeml(s,a) ((readlookup2[(uint32_t)((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a)) & 3))?readmemll(s,a):*(uint32_t *)(readlookup2[(uint32_t)((s)+(a))>>12]+(uint32_t)((s)+(a)))) extern uint8_t readmembl(uint32_t addr); extern void writemembl(uint32_t addr, uint8_t val); diff --git a/src/mem.c b/src/mem.c index bbf4e57d8..17b564a9e 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1281,25 +1281,29 @@ void writememb386l(uint32_t seg, uint32_t addr, uint8_t val) uint16_t readmemwl(uint32_t seg, uint32_t addr) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFE) - { - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14] && ram_mapped_addr[(addr2+1) >> 14]) - { - return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); - } - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; - if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; - } - if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); - else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); - } + if (seg==-1) { x86gpf("NULL segment", 0); return -1; } + if (addr2 & 1) + { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFFE) + { + if (cr0 >> 31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffff; + if (mmutranslate_read(addr2+1) == 0xffffffff) return 0xffff; + } + if (is386) return readmemb386l(seg,addr)|(readmemb386l(seg,addr+1)<<8); + else return readmembl(seg+addr)|(readmembl(seg+addr+1)<<8); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint16_t *)(readlookup2[addr2 >> 12] + addr2); + } if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) { addr = (ram_mapped_addr[addr2 >> 14] & MEM_MAP_TO_SHADOW_RAM_MASK) ? addr2 : (ram_mapped_addr[addr2 >> 14] & ~0x3FFF) + (addr2 & 0x3FFF); @@ -1327,31 +1331,6 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr) void writememwl(uint32_t seg, uint32_t addr, uint16_t val) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFE) - { - if (addr2 < 0x100000 && ram_mapped_addr[addr2 >> 14]) - { - writemembl(seg+addr,val); - writemembl(seg+addr+1,val>>8); - return; - } - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+1) == 0xffffffff) return; - } - if (is386) - { - writememb386l(seg,addr,val); - writememb386l(seg,addr+1,val>>8); - } - else - { - writemembl(seg+addr,val); - writemembl(seg+addr+1,val>>8); - } - return; - } if (seg==-1) { @@ -1364,6 +1343,37 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) if(addr < mem_size * 1024) *((uint16_t *)&ram[addr]) = val; return; } + + if (addr2 & 1) + { + if (!cpu_cyrix_alignment || (addr2 & 7) == 7) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFFE) + { + if (cr0 >> 31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+1) == 0xffffffff) return; + } + if (is386) + { + writememb386l(seg,addr,val); + writememb386l(seg,addr+1,val>>8); + } + else + { + writemembl(seg+addr,val); + writemembl(seg+addr+1,val>>8); + } + return; + } + else if (writelookup2[addr2 >> 12] != -1) + { + *(uint16_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } + if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_w(addr2, val, page_lookup[addr2>>12]); @@ -1397,19 +1407,6 @@ void writememwl(uint32_t seg, uint32_t addr, uint16_t val) uint32_t readmemll(uint32_t seg, uint32_t addr) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFC) - { - if (addr2 < 0x100000 && (ram_mapped_addr[addr2 >> 14] || ram_mapped_addr[(addr2+3) >> 14])) - { - return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); - } - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; - } - return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); - } if (seg==-1) { @@ -1423,6 +1420,24 @@ uint32_t readmemll(uint32_t seg, uint32_t addr) if(addr < mem_size * 1024) return *((uint32_t *)&ram[addr]); return 0xFFFFFFFF; } + + if (addr2 & 3) + { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + cycles -= timing_misaligned; + if ((addr2&0xFFF)>0xFFC) + { + if (cr0>>31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+3) == 0xffffffff) return 0xffffffff; + } + return readmemwl(seg,addr)|(readmemwl(seg,addr+2)<<16); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint32_t *)(readlookup2[addr2 >> 12] + addr2); + } + if (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1444,17 +1459,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFFC) - { - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+3) == 0xffffffff) return; - } - writememwl(seg,addr,val); - writememwl(seg,addr+2,val>>16); - return; - } if (seg==-1) { x86gpf("NULL segment", 0); @@ -1466,6 +1470,27 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) if(addr < mem_size * 1024) *((uint32_t *)&ram[addr]) = val; return; } + if (addr2 & 3) + { + if (!cpu_cyrix_alignment || (addr2 & 7) > 4) + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFFC) + { + if (cr0>>31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+3) == 0xffffffff) return; + } + writememwl(seg,addr,val); + writememwl(seg,addr+2,val>>16); + return; + } + else if (writelookup2[addr2 >> 12] != -1) + { + *(uint32_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); @@ -1503,15 +1528,6 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) uint64_t readmemql(uint32_t seg, uint32_t addr) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2&0xFFF)>0xFF8) - { - if (cr0>>31) - { - if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; - if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; - } - return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); - } if (seg==-1) { @@ -1525,6 +1541,23 @@ uint64_t readmemql(uint32_t seg, uint32_t addr) if(addr < mem_size * 1024) return *((uint64_t *)&ram[addr]); return -1; } + + if (addr2 & 7) + { + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFF8) + { + if (cr0>>31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + } + return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + } + else if (readlookup2[addr2 >> 12] != -1) + return *(uint64_t *)(readlookup2[addr2 >> 12] + addr2); + } + if (cr0>>31) { addr2 = mmutranslate_read(addr2); @@ -1544,17 +1577,6 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) { uint32_t addr2 = mem_logical_addr = seg + addr; - if ((addr2 & 0xFFF) > 0xFF8) - { - if (cr0>>31) - { - if (mmutranslate_write(addr2) == 0xffffffff) return; - if (mmutranslate_write(addr2+7) == 0xffffffff) return; - } - writememll(seg, addr, val); - writememll(seg, addr+4, val >> 32); - return; - } if (seg==-1) { x86gpf("NULL segment", 0); @@ -1566,6 +1588,26 @@ void writememql(uint32_t seg, uint32_t addr, uint64_t val) if(addr < mem_size * 1024) *((uint64_t *)&ram[addr]) = val; return; } + if (addr2 & 7) + { + cycles -= timing_misaligned; + if ((addr2 & 0xFFF) > 0xFF8) + { + if (cr0>>31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+7) == 0xffffffff) return; + } + writememll(seg, addr, val); + writememll(seg, addr+4, val >> 32); + return; + } + else if (writelookup2[addr2 >> 12] != -1) + { + *(uint64_t *)(writelookup2[addr2 >> 12] + addr2) = val; + return; + } + } if (page_lookup[addr2>>12]) { page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); diff --git a/src/model.c b/src/model.c index b08d3a01f..9e4dc6b7e 100644 --- a/src/model.c +++ b/src/model.c @@ -173,7 +173,7 @@ MODEL models[] = {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Euro PC", ROM_EUROPC, "europc", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, + {"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, From 0347b6d46b7c7f904847d618cb0f1c42b6177cbe Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 5 Jun 2017 01:36:39 +0200 Subject: [PATCH 310/392] BusLogic base address is now read from the correct configuration variable. --- src/scsi_buslogic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index b88e7de99..d5113e000 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -2243,7 +2243,7 @@ BuslogicInit(int chip) chip = CHIP_BUSLOGIC_ISA; } bl->chip = chip; - bl->Base = device_get_config_hex16("addr"); + bl->Base = device_get_config_hex16("base"); bl->PCIBase = 0; bl->MMIOBase = 0; bl->Irq = device_get_config_int("irq"); From 175019550ce16e62fcd171c11bdc92cc53c17ca8 Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 4 Jun 2017 22:18:41 -0400 Subject: [PATCH 311/392] Remove all old Win UI stuff no longer used, rename constants for consistency, renumber most of them (see resource.h comments) and move Screenshot to the Action menu. --- src/86box.h | 5 +- src/WIN/86Box.rc | 286 ++++++++++++++----------- src/WIN/resource.h | 463 +++++++++++++++++++---------------------- src/WIN/win.c | 14 +- src/WIN/win_settings.c | 154 +++++++------- src/WIN/win_status.c | 4 +- 6 files changed, 475 insertions(+), 451 deletions(-) diff --git a/src/86box.h b/src/86box.h index 9af4e6e55..516356138 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main emulator include file. * - * Version: @(#)86box.h 1.0.1 2017/06/03 + * Version: @(#)86box.h 1.0.2 2017/06/04 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -26,6 +26,9 @@ # define ENABLE_LOG_TOGGLES 1 #endif +#if defined(ENABLE_LOG_BREAKPOINT) || defined(ENABLE_VRAM_DUMP) +# define ENABLE_LOG_COMMANDS 1 +#endif #define EMU_VERSION "2.00" #define EMU_VERSION_W L"2.00" diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 66d42bb21..e5b19e765 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -8,14 +8,17 @@ * * Windows resource script. * - * Version: @(#)86Box.rc 1.0.1 2017/06/03 + * Version: @(#)86Box.rc 1.0.2 2017/06/04 * * Authors: Miran Grca, * Fred N. van Kempen, * Copyright 2016-2017 Miran Grca. */ #include +#define IN_RESOURCE_H #include "resource.h" +#include "../86box.h" +#undef IN_RESOURCE_H #define APSTUDIO_READONLY_SYMBOLS #define APSTUDIO_HIDDEN_SYMBOLS @@ -41,12 +44,12 @@ MAINMENU MENU DISCARDABLE BEGIN POPUP "&Action" BEGIN - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT MENUITEM SEPARATOR - MENUITEM "&Hard Reset", IDM_FILE_HRESET - MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_FILE_RESET_CAD + MENUITEM "&Hard Reset", IDM_ACTION_HRESET + MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR - MENUITEM "E&xit", IDM_FILE_EXIT + MENUITEM "E&xit", IDM_ACTION_EXIT END POPUP "&Tools" BEGIN @@ -85,44 +88,44 @@ BEGIN MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON - MENUITEM SEPARATOR - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_VID_SCREENSHOT END MENUITEM "S&tatus", IDM_STATUS END -#ifdef ENABLE_LOG_TOGGLES +#if defined(ENABLE_LOG_TOGGLES) || defined(ENABLE_LOG_COMMANDS) POPUP "&Logging" BEGIN -#ifdef ENABLE_BUSLOGIC_LOG +# ifdef ENABLE_BUSLOGIC_LOG MENUITEM "Enable BusLogic logs\tCtrl+F4", IDM_LOG_BUSLOGIC -#endif -#ifdef ENABLE_CDROM_LOG +# endif +# ifdef ENABLE_CDROM_LOG MENUITEM "Enable CD-ROM logs\tCtrl+F5", IDM_LOG_CDROM -#endif -#ifdef ENABLE_D86F_LOG +# endif +# ifdef ENABLE_D86F_LOG MENUITEM "Enable floppy (86F) logs\tCtrl+F6", IDM_LOG_D86F -#endif -#ifdef ENABLE_FDC_LOG +# endif +# ifdef ENABLE_FDC_LOG MENUITEM "Enable floppy controller logs\tCtrl+F7", IDM_LOG_FDC -#endif -#ifdef ENABLE_IDE_LOG +# endif +# ifdef ENABLE_IDE_LOG MENUITEM "Enable IDE logs\tCtrl+F8", IDM_LOG_IDE -#endif -#ifdef ENABLE_SERIAL_LOG +# endif +# ifdef ENABLE_SERIAL_LOG MENUITEM "Enable Serial Port logs\tCtrl+F3", IDM_LOG_SERIAL -#endif -#ifdef ENABLE_NIC_LOG +# endif +# ifdef ENABLE_NIC_LOG MENUITEM "Enable Network logs\tCtrl+F9", IDM_LOG_NIC -#endif -#if defined(ENABLE_LOG_BREAKPOINT) || defined(ENABLE_VRAM_DUMP) +# endif +# ifdef ENABLE_LOG_COMMANDS +# ifdef ENABLE_LOG_TOGGLES MENUITEM SEPARATOR -# ifdef ENABLE_LOG_BREAKPOINT +# endif +# ifdef ENABLE_LOG_BREAKPOINT MENUITEM "&Log breakpoint\tCtrl+F10", IDM_LOG_BREAKPOINT -# endif -# ifdef ENABLE_VRAM_DUMP +# endif +# ifdef ENABLE_VRAM_DUMP MENUITEM "Dump &video RAM\tCtrl+F1", IDM_DUMP_VRAM +# endif # endif -#endif END #endif POPUP "&Help" @@ -140,37 +143,35 @@ END MAINACCEL ACCELERATORS MOVEABLE PURE BEGIN #ifdef ENABLE_VRAM_DUMP - VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY + VK_F1, IDM_DUMP_VRAM, CONTROL, VIRTKEY #endif -#ifdef ENABLE_LOG_TOGGLES -# ifdef ENABLE_SERIAL_LOG - VK_F3, IDM_LOG_SERIAL, CONTROL, VIRTKEY -# endif -# ifdef ENABLE_BUSLOGIC_LOG - VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY -# endif -# ifdef ENABLE_CDROM_LOG - VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY -# endif -# ifdef ENABLE_D86F_LOG - VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY -# endif -# ifdef ENABLE_FDC_LOG - VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY -# endif -# ifdef ENABLE_IDE_LOG - VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY -# endif -# ifdef ENABLE_NIC_LOG - VK_F9, IDM_LOG_NIC, CONTROL, VIRTKEY -# endif +#ifdef ENABLE_SERIAL_LOG + VK_F3, IDM_LOG_SERIAL, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_BUSLOGIC_LOG + VK_F4, IDM_LOG_BUSLOGIC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_CDROM_LOG + VK_F5, IDM_LOG_CDROM, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_D86F_LOG + VK_F6, IDM_LOG_D86F, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_FDC_LOG + VK_F7, IDM_LOG_FDC, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_IDE_LOG + VK_F8, IDM_LOG_IDE, CONTROL, VIRTKEY +#endif +#ifdef ENABLE_NIC_LOG + VK_F9, IDM_LOG_NIC, CONTROL, VIRTKEY #endif #ifdef ENABLE_LOG_BREAKPOINT - VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY + VK_F10, IDM_LOG_BREAKPOINT, CONTROL, VIRTKEY #endif - VK_PRIOR, IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT - VK_F11, IDM_VID_SCREENSHOT, VIRTKEY, CONTROL - VK_F12, IDM_FILE_RESET_CAD, VIRTKEY, CONTROL + VK_PRIOR,IDM_VID_FULLSCREEN, VIRTKEY, CONTROL , ALT + VK_F11, IDM_ACTION_SCREENSHOT, VIRTKEY, CONTROL + VK_F12, IDM_ACTION_RESET_CAD, VIRTKEY, CONTROL END @@ -196,12 +197,11 @@ STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Status" FONT 9, "Segoe UI" BEGIN - LTEXT "1",IDC_STEXT_DEVICE,16,16,180,1000 - LTEXT "1",IDC_STEXT1,16,186,180,1000 + LTEXT "1",IDT_SDEVICE,16,16,180,1000 + LTEXT "1",IDT_STEXT,16,186,180,1000 END - -DLG_CFG_MAIN DIALOG DISCARDABLE 0, 0, 366, 241 +DLG_CONFIG DIALOG DISCARDABLE 0, 0, 366, 241 STYLE DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "86Box Settings" FONT 9, "Segoe UI" @@ -211,7 +211,7 @@ BEGIN CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,197 CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 - LTEXT "Language:",IDS_LANG_ENUS,7,222,41,10 + LTEXT "Language:",IDT_1700,7,222,41,10 COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP END @@ -222,17 +222,17 @@ FONT 9, "Segoe UI" BEGIN COMBOBOX IDC_COMBO_MACHINE,71,7,138,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Machine:",1794,7,8,60,10 + LTEXT "Machine:",IDT_1701,7,8,60,10 PUSHBUTTON "Configure",IDC_CONFIGURE_MACHINE,214,7,46,12 COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "CPU type:",1796,7,26,59,10 + LTEXT "CPU type:",IDT_1702,7,26,59,10 COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Wait states:",1798,7,45,60,10 + LTEXT "Wait states:",IDT_1703,7,45,60,10 COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "CPU:",1797,124,26,18,10 + LTEXT "CPU:",IDT_1704,124,26,18,10 CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | @@ -241,8 +241,8 @@ BEGIN CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, 12,12 - LTEXT "MB",IDC_TEXT_MB,123,64,10,10 - LTEXT "Memory:",1802,7,64,30,10 + LTEXT "MB",IDT_1705,123,64,10,10 + LTEXT "Memory:",IDT_1706,7,64,30,10 CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 END @@ -251,31 +251,31 @@ DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN + LTEXT "Video:",IDT_1707,7,8,55,10 COMBOBOX IDC_COMBO_VIDEO,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Video:",1795,7,8,55,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_VID,214,7,46,12 COMBOBOX IDC_COMBO_VIDEO_SPEED,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Video speed:",1800,7,26,58,10 + LTEXT "Video speed:",IDT_1708,7,26,58,10 CONTROL "Voodoo Graphics",IDC_CHECK_VOODOO,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 - PUSHBUTTON "Configure",IDC_CONFIGURE_VOODOO,214,44,46,12 - PUSHBUTTON "Configure",IDC_CONFIGUREVID,214,7,46,12 + PUSHBUTTON "Configure",IDC_BUTTON_VOODOO,214,44,46,12 END DLG_CFG_INPUT DIALOG DISCARDABLE 97, 0, 267, 65 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - LTEXT "Mouse :",IDC_STATIC,7,8,57,10 + LTEXT "Mouse :",IDT_1709,7,8,57,10 COMBOBOX IDC_COMBO_MOUSE,71,7,189,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Joystick :",1793,7,26,58,10 + LTEXT "Joystick :",IDT_1710,7,26,58,10 COMBOBOX IDC_COMBO_JOYSTICK,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - DEFPUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 + PUSHBUTTON "Joystick 1...",IDC_JOY1,7,44,50,14 PUSHBUTTON "Joystick 2...",IDC_JOY2,74,44,50,14 - DEFPUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 + PUSHBUTTON "Joystick 3...",IDC_JOY3,141,44,50,14 PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 END @@ -283,26 +283,26 @@ DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 98 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - COMBOBOX IDC_COMBOSND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + COMBOBOX IDC_COMBO_SOUND,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Sound card:",1800,7,8,59,10 - PUSHBUTTON "Configure",IDC_CONFIGURESND,214,7,46,12 + LTEXT "Sound card:",IDT_1711,7,8,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_SND,214,7,46,12 COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "MIDI Out Device:",1801,7,26,59,10 + LTEXT "MIDI Out Device:",IDT_1712,7,26,59,10 CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 PUSHBUTTON "Configure",IDC_CONFIGURE_MPU401,214,44,46,12 - CONTROL "Innovation SSI-2001",IDC_CHECKSSI,"Button", + CONTROL "Innovation SSI-2001",IDC_CHECK_SSI,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,63,94,10 - CONTROL "CMS / Game Blaster",IDC_CHECKCMS,"Button", + CONTROL "CMS / Game Blaster",IDC_CHECK_CMS,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,147,63,94,10 - CONTROL "Gravis Ultrasound",IDC_CHECKGUS,"Button", + CONTROL "Gravis Ultrasound",IDC_CHECK_GUS,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10 - CONTROL "Use Nuked OPL",IDC_CHECKNUKEDOPL,"Button", + CONTROL "Use Nuked OPL",IDC_CHECK_NUKEDOPL,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 END @@ -310,49 +310,49 @@ DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - LTEXT "Network type:",1800,7,8,59,10 - COMBOBOX IDC_COMBONETTYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "Network type:",IDT_1713,7,8,59,10 + COMBOBOX IDC_COMBO_NET_TYPE,71,7,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "PCap device:",1801,7,26,59,10 - COMBOBOX IDC_COMBOPCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "PCap device:",IDT_1714,7,26,59,10 + COMBOBOX IDC_COMBO_PCAP,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Network adapter:",1802,7,44,59,10 - COMBOBOX IDC_COMBONET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "Network adapter:",IDT_1715,7,44,59,10 + COMBOBOX IDC_COMBO_NET,71,43,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Configure",IDC_CONFIGURENET,214,43,46,12 + PUSHBUTTON "Configure",IDC_CONFIGURE_NET,214,43,46,12 END DLG_CFG_PERIPHERALS DIALOG DISCARDABLE 97, 0, 267, 115 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN - LTEXT "SCSI Controller:",1804,7,8,59,10 + LTEXT "SCSI Controller:",IDT_1716,7,8,59,10 COMBOBOX IDC_COMBO_SCSI,71,7,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Configure",IDC_CONFIGURE_SCSI,214,7,46,12 - LTEXT "HD Controller:",1799,7,26,61,10 + LTEXT "HD Controller:",IDT_1717,7,26,61,10 COMBOBOX IDC_COMBO_HDC,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Tertiary IDE:",1802,7,44,61,10 + LTEXT "Tertiary IDE:",IDT_1718,7,44,61,10 COMBOBOX IDC_COMBO_IDE_TER,71,43,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Quaternary IDE:",1803,7,62,61,10 + LTEXT "Quaternary IDE:",IDT_1719,7,62,61,10 COMBOBOX IDC_COMBO_IDE_QUA,71,61,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - CONTROL "Serial port 1",IDC_CHECKSERIAL1,"Button", + CONTROL "Serial port 1",IDC_CHECK_SERIAL1,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Serial port 2",IDC_CHECKSERIAL2,"Button", + CONTROL "Serial port 2",IDC_CHECK_SERIAL2,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,147,80,94,10 - CONTROL "Parallel port",IDC_CHECKPARALLEL,"Button", + CONTROL "Parallel port",IDC_CHECK_PARALLEL,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,98,94,10 - CONTROL "ISABugger device",IDC_CHECKBUGGER,"Button", + CONTROL "ISABugger device",IDC_CHECK_BUGGER,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,147,98,94,10 END @@ -363,25 +363,25 @@ BEGIN CONTROL "List1",IDC_LIST_HARD_DISKS,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,18,253,92 - LTEXT "Hard disks:",-1,7,7,34,8 + LTEXT "Hard disks:",IDT_1720,7,7,34,8 PUSHBUTTON "&New...",IDC_BUTTON_HDD_ADD_NEW,60,137,62,10 PUSHBUTTON "&Existing...",IDC_BUTTON_HDD_ADD,129,137,62,10 PUSHBUTTON "&Remove",IDC_BUTTON_HDD_REMOVE,198,137,62,10 COMBOBOX IDC_COMBO_HD_BUS,33,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,118,24,8 + LTEXT "Bus:",IDT_1721,7,118,24,8 COMBOBOX IDC_COMBO_HD_CHANNEL,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,131,118,38,8 + LTEXT "Channel:",IDT_1722,131,118,38,8 COMBOBOX IDC_COMBO_HD_ID,170,117,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,118,38,8 + LTEXT "ID:",IDT_1723,131,118,38,8 COMBOBOX IDC_COMBO_HD_LUN,239,117,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,118,38,8 + LTEXT "LUN:",IDT_1724,200,118,38,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,118,38,8 + LTEXT "Channel:",IDT_1725,131,118,38,8 END DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 @@ -399,29 +399,75 @@ BEGIN EDITTEXT IDC_EDIT_HD_SIZE,42,52,28,12 COMBOBOX IDC_COMBO_HD_TYPE,113,52,98,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Sectors:",IDC_STATIC,154,35,27,10 - LTEXT "Heads:",1793,81,35,29,8 - LTEXT "Cylinders:",1794,7,35,32,12 - LTEXT "Size (MB):",1795,7,54,33,8 - LTEXT "Type:",1797,86,54,24,8 - LTEXT "File name:",-1,7,7,204,9 + LTEXT "Sectors:",IDT_1726,154,35,27,10 + LTEXT "Heads:",IDT_1727,81,35,29,8 + LTEXT "Cylinders:",IDT_1728,7,35,32,12 + LTEXT "Size (MB):",IDT_1729,7,54,33,8 + LTEXT "Type:",IDT_1730,86,54,24,8 + LTEXT "File name:",IDT_1731,7,7,204,9 COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,72,24,8 + LTEXT "Bus:",IDT_1732,7,72,24,8 COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1799,99,72,34,8 + LTEXT "Channel:",IDT_1733,99,72,34,8 COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,117,72,15,8 + LTEXT "ID:",IDT_1734,117,72,15,8 COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,168,72,15,8 + LTEXT "LUN:",IDT_1735,168,72,15,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,99,72,34,8 + LTEXT "Channel:",IDT_1736,99,72,34,8 END +/* Static text label IDs. */ +#define IDT_1700 1700 // Language: +#define IDT_1701 1701 // Machine: +#define IDT_1702 1702 // CPU type: +#define IDT_1703 1703 // Wait states: +#define IDT_1704 1704 // CPU: +#define IDT_1705 1705 // MB == IDC_TEXT_MB +#define IDT_1706 1706 // Memory: +#define IDT_1707 1707 // Video: +#define IDT_1708 1708 // Video speed: +#define IDT_1709 1709 // Mouse: +#define IDT_1710 1710 // Joystick: +#define IDT_1711 1711 // Sound card: +#define IDT_1712 1712 // MIDI Out Device: +#define IDT_1713 1713 // Network type: +#define IDT_1714 1714 // PCap device: +#define IDT_1715 1715 // Network adapter: +#define IDT_1716 1716 // SCSI Controller: +#define IDT_1717 1717 // HD Controller: +#define IDT_1718 1718 // Tertiary IDE: +#define IDT_1719 1719 // Quaternary IDE: +#define IDT_1720 1720 // Hard disks: +#define IDT_1721 1721 // Bus: +#define IDT_1722 1722 // Channel: +#define IDT_1723 1723 // ID: +#define IDT_1724 1724 // LUN: +#define IDT_1725 1725 // Channel: +#define IDT_1726 1726 // Sectors: +#define IDT_1727 1727 // Heads: +#define IDT_1728 1728 // Cylinders: +#define IDT_1729 1729 // Size (MB): +#define IDT_1730 1730 // Type: +#define IDT_1731 1731 // File name: +#define IDT_1732 1732 // Bus: +#define IDT_1733 1733 // Channel: +#define IDT_1734 1734 // ID: +#define IDT_1735 1735 // LUN: +#define IDT_1736 1736 // Channel: +#define IDT_1737 1737 // Floppy drives: +#define IDT_1738 1738 // Type: +#define IDT_1739 1739 // CD-ROM drives: +#define IDT_1740 1740 // Bus: +#define IDT_1741 1741 // ID: +#define IDT_1742 1742 // LUN: +#define IDT_1743 1743 // Channel: + DLG_CFG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" @@ -429,28 +475,28 @@ BEGIN CONTROL "List1",IDC_LIST_FLOPPY_DRIVES,"SysListView32", LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,18,253,60 - LTEXT "Floppy drives:",-1,7,7,43,8 + LTEXT "Floppy drives:",IDT_1737,7,7,43,8 COMBOBOX IDC_COMBO_FD_TYPE,33,85,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Type:",1803,7,86,24,8 + LTEXT "Type:",IDT_1738,7,86,24,8 CONTROL "Turbo timings (no accuracy)",IDC_CHECKTURBO,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,131,86,129,10 CONTROL "List1",IDC_LIST_CDROM_DRIVES,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,116,253,60 - LTEXT "CD-ROM drives:",-1,7,106,50,8 + LTEXT "CD-ROM drives:",IDT_1739,7,106,50,8 COMBOBOX IDC_COMBO_CD_BUS,33,183,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",1798,7,184,24,8 + LTEXT "Bus:",IDT_1740,7,184,24,8 COMBOBOX IDC_COMBO_CD_ID,170,183,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",1800,131,184,38,8 + LTEXT "ID:",IDT_1741,131,184,38,8 COMBOBOX IDC_COMBO_CD_LUN,239,183,22,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",1801,200,184,38,8 + LTEXT "LUN:",IDT_1742,200,184,38,8 COMBOBOX IDC_COMBO_CD_CHANNEL_IDE,170,183,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",1802,131,184,38,8 + LTEXT "Channel:",IDT_1743,131,184,38,8 END diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 3dcf6b3be..47c92c31c 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -8,9 +8,9 @@ * * Windows resource defines. * - * NOTE: Strings 2176 and 2193 are same. + * NOTE: FIXME: Strings 2176 and 2193 are same. * - * Version: @(#)resource.h 1.0.2 2017/06/03 + * Version: @(#)resource.h 1.0.3 2017/06/04 * * Authors: Sarah Walker, * Miran Grca, @@ -22,93 +22,180 @@ # define WIN_RESOURCE_H -/* {{NO_DEPENDENCIES}} - Microsoft Developer Studio generated include file. - Used by 86Box.rc -*/ +/* Dialog IDs. */ +#define DLG_ABOUT 101 /* top-level dialog */ +#define DLG_STATUS 102 /* top-level dialog */ +#define DLG_CONFIG 110 /* top-level dialog */ +#define DLG_CFG_MACHINE 111 /* sub-dialog of config */ +#define DLG_CFG_VIDEO 112 /* sub-dialog of config */ +#define DLG_CFG_INPUT 113 /* sub-dialog of config */ +#define DLG_CFG_SOUND 114 /* sub-dialog of config */ +#define DLG_CFG_NETWORK 115 /* sub-dialog of config */ +#define DLG_CFG_PERIPHERALS 116 /* sub-dialog of config */ +#define DLG_CFG_HARD_DISKS 117 /* sub-dialog of config */ +#define DLG_CFG_HARD_DISKS_ADD 118 /* sub-dialog of config */ +#define DLG_CFG_REMOVABLE_DEVICES 119 /* sub-dialog of config */ -#define DLG_ABOUT 101 -#define DLG_STATUS 102 -#define DLG_CFG_MAIN 110 -#define DLG_CFG_MACHINE 111 -#define DLG_CFG_VIDEO 112 -#define DLG_CFG_INPUT 113 -#define DLG_CFG_SOUND 114 -#define DLG_CFG_NETWORK 115 -#define DLG_CFG_PERIPHERALS 116 -#define DLG_CFG_HARD_DISKS 117 -#define DLG_CFG_HARD_DISKS_ADD 118 -#define DLG_CFG_REMOVABLE_DEVICES 119 +/* Static text label IDs. */ +#define IDT_1700 1700 // Language: +#define IDT_1701 1701 // Machine: +#define IDT_1702 1702 // CPU type: +#define IDT_1703 1703 // Wait states: +#define IDT_1704 1704 // CPU: +#define IDT_1705 1705 // MB == IDC_TEXT_MB +#define IDT_1706 1706 // Memory: +#define IDT_1707 1707 // Video: +#define IDT_1708 1708 // Video speed: +#define IDT_1709 1709 // Mouse: +#define IDT_1710 1710 // Joystick: +#define IDT_1711 1711 // Sound card: +#define IDT_1712 1712 // MIDI Out Device: +#define IDT_1713 1713 // Network type: +#define IDT_1714 1714 // PCap device: +#define IDT_1715 1715 // Network adapter: +#define IDT_1716 1716 // SCSI Controller: +#define IDT_1717 1717 // HD Controller: +#define IDT_1718 1718 // Tertiary IDE: +#define IDT_1719 1719 // Quaternary IDE: +#define IDT_1720 1720 // Hard disks: +#define IDT_1721 1721 // Bus: +#define IDT_1722 1722 // Channel: +#define IDT_1723 1723 // ID: +#define IDT_1724 1724 // LUN: +#define IDT_1725 1725 // Channel: +#define IDT_1726 1726 // Sectors: +#define IDT_1727 1727 // Heads: +#define IDT_1728 1728 // Cylinders: +#define IDT_1729 1729 // Size (MB): +#define IDT_1730 1730 // Type: +#define IDT_1731 1731 // File name: +#define IDT_1732 1732 // Bus: +#define IDT_1733 1733 // Channel: +#define IDT_1734 1734 // ID: +#define IDT_1735 1735 // LUN: +#define IDT_1736 1736 // Channel: +#define IDT_1737 1737 // Floppy drives: +#define IDT_1738 1738 // Type: +#define IDT_1739 1739 // CD-ROM drives: +#define IDT_1740 1740 // Bus: +#define IDT_1741 1741 // ID: +#define IDT_1742 1742 // LUN: +#define IDT_1743 1743 // Channel: +#define IDT_STEXT 1744 // text in status window +#define IDT_SDEVICE 1745 // text in status window -#define IDC_SETTINGSCATLIST 1004 -#define IDC_LIST_HARD_DISKS 1005 -#define IDC_COMBO_MACHINE 1006 -#define IDC_COMBO_CPU_TYPE 1007 -#define IDC_COMBO_CPU 1008 -#define IDC_COMBO_WS 1009 -#define IDC_CHECK_DYNAREC 1010 -#define IDC_CHECK_FPU 1011 -#define IDC_COMBO_SCSI 1012 -#define IDC_CONFIGURE_SCSI 1013 -#define IDC_COMBO_VIDEO 1014 -#define IDC_COMBO_VIDEO_SPEED 1015 -#define IDC_CHECK_VOODOO 1016 -#define IDC_CHECKCMS 1016 -#define IDC_CONFIGURE_VOODOO 1017 -#define IDC_CHECKNUKEDOPL 1018 -#define IDC_COMBO_JOYSTICK 1018 -#define IDC_CHECK_SYNC 1019 -#define IDC_CHECK_MPU401 1019 -#define IDC_LIST_FLOPPY_DRIVES 1020 -#define IDC_CONFIGURE_MPU401 1020 -#define IDC_LIST_CDROM_DRIVES 1021 -#define IDC_CONFIGURE_MACHINE 1022 -#define IDC_COMBO_LANG 1023 -#define IDC_BUTTON_FDD_ADD 1024 -#define IDC_BUTTON_FDD_EDIT 1025 -#define IDC_BUTTON_FDD_REMOVE 1026 -#define IDC_BUTTON_CDROM_ADD 1027 -#define IDC_BUTTON_HDD_ADD_NEW 1027 -#define IDC_BUTTON_CDROM_EDIT 1028 -#define IDC_BUTTON_HDD_ADD 1028 -#define IDC_BUTTON_CDROM_REMOVE 1029 -#define IDC_BUTTON_HDD_REMOVE 1029 -#define IDC_CHECKTURBO 1030 -#define IDC_HDIMAGE_NEW 1035 -#define IDC_HD_BUS 1036 -#define IDC_HDIMAGE_EXISTING 1037 -#define IDC_COMBO_HD_BUS 1038 -#define IDC_EDIT_HD_FILE_NAME 1039 -#define IDC_EDIT_HD_CYL 1040 -#define IDC_EDIT_HD_HPC 1041 -#define IDC_EDIT_HD_SPT 1042 -#define IDC_EDIT_HD_SIZE 1043 -#define IDC_COMBO_HD_TYPE 1044 -#define IDC_COMBO_HD_LOCATION 1045 -#define IDC_CHECKGUS 1046 -#define IDC_COMBO_HD_CHANNEL 1047 -#define IDC_COMBO_HD_CHANNEL_IDE 1048 -#define IDC_COMBO_HD_ID 1050 -#define IDC_COMBO_HD_LUN 1051 -#define IDC_CHECKBUGGER 1052 -#define IDC_CHECKSERIAL1 1053 -#define IDC_CHECKPARALLEL 1054 -#define IDC_CHECKSERIAL2 1055 -#define IDC_COMBO_HDC 1068 -#define IDC_COMBO_MOUSE 1069 -#define IDC_COMBO_IDE_TER 1069 -#define IDC_COMBO_IDE_QUA 1070 -#define IDC_COMBO_FD_TYPE 1071 -#define IDC_COMBO_CD_BUS 1072 -#define IDC_COMBO_CD_CHANNEL_IDE 1073 -#define IDC_COMBO_CD_ID 1074 -#define IDC_COMBO_CD_LUN 1075 -#define IDC_COMBO_MIDI 1076 -#define IDC_CHECK_CDROM_1_AUDIO_ENABLED 1584 -#define IDC_CHECK_CDROM_2_AUDIO_ENABLED 1585 -#define IDC_CHECK_CDROM_3_AUDIO_ENABLED 1586 -#define IDC_CHECK_CDROM_4_AUDIO_ENABLED 1587 +/* + * To try to keep these organized, we now group the + * constants per dialog, as this allows easy adding + * and deleting items. + */ +#define IDC_SETTINGSCATLIST 1001 /* generic config */ +#define IDC_CFILE 1002 /* Select File dialog */ +#define IDC_CHECK_SYNC 1008 +#define IDC_COMBO_LANG 1009 + +#define IDC_COMBO_MACHINE 1010 /* machine/cpu config */ +#define IDC_CONFIGURE_MACHINE 1011 +#define IDC_COMBO_CPU_TYPE 1012 +#define IDC_COMBO_CPU 1013 +#define IDC_CHECK_FPU 1014 +#define IDC_COMBO_WS 1015 +#define IDC_CHECK_DYNAREC 1016 +#define IDC_MEMTEXT 1017 +#define IDC_MEMSPIN 1018 +#define IDC_TEXT_MB IDT_1705 + +#define IDC_VIDEO 1030 /* video config */ +#define IDC_COMBO_VIDEO 1031 +#define IDC_COMBO_VIDEO_SPEED 1032 +#define IDC_CHECK_VOODOO 1033 +#define IDC_BUTTON_VOODOO 1034 + +#define IDC_INPUT 1050 /* input config */ +#define IDC_COMBO_MOUSE 1051 +#define IDC_COMBO_JOYSTICK 1052 +#define IDC_COMBO_JOY 1053 + +#define IDC_SOUND 1070 /* sound config */ +#define IDC_COMBO_SOUND 1071 +#define IDC_CHECK_SSI 1072 +#define IDC_CHECK_CMS 1073 +#define IDC_CHECK_GUS 1074 +#define IDC_CHECK_NUKEDOPL 1075 +#define IDC_COMBO_MIDI 1076 +#define IDC_CHECK_MPU401 1077 +#define IDC_CONFIGURE_MPU401 1078 + +#define IDC_COMBO_NET_TYPE 1090 /* network config */ +#define IDC_COMBO_PCAP 1091 +#define IDC_COMBO_NET 1092 + +#define IDC_OTHER_PERIPH 1110 /* other periph config */ +#define IDC_COMBO_SCSI 1111 +#define IDC_CONFIGURE_SCSI 1112 +#define IDC_COMBO_HDC 1113 +#define IDC_COMBO_IDE_TER 1114 +#define IDC_COMBO_IDE_QUA 1115 +#define IDC_CHECK_SERIAL1 1116 +#define IDC_CHECK_SERIAL2 1117 +#define IDC_CHECK_PARALLEL 1118 +#define IDC_CHECK_BUGGER 1119 + +#define IDC_HARD_DISKS 1130 /* hard disk config */ +#define IDC_LIST_HARD_DISKS 1131 +#define IDC_BUTTON_HDD_ADD_NEW 1132 +#define IDC_BUTTON_HDD_ADD 1133 +#define IDC_BUTTON_HDD_REMOVE 1134 +#define IDC_COMBO_HD_BUS 1135 +#define IDC_COMBO_HD_CHANNEL 1136 +#define IDC_COMBO_HD_ID 1137 +#define IDC_COMBO_HD_LUN 1138 +#define IDC_COMBO_HD_CHANNEL_IDE 1139 +#define IDC_EDIT_HD_FILE_NAME 1140 +#define IDC_EDIT_HD_SPT 1141 +#define IDC_EDIT_HD_HPC 1142 +#define IDC_EDIT_HD_CYL 1143 +#define IDC_EDIT_HD_SIZE 1144 +#define IDC_COMBO_HD_TYPE 1145 + +#define IDC_REMOV_DEVICES 1150 /* removable dev config */ +#define IDC_LIST_FLOPPY_DRIVES 1151 +#define IDC_COMBO_FD_TYPE 1152 +#define IDC_CHECKTURBO 1153 +#define IDC_BUTTON_FDD_ADD 1154 // status bar menu +#define IDC_BUTTON_FDD_EDIT 1155 // status bar menu +#define IDC_BUTTON_FDD_REMOVE 1156 // status bar menu +#define IDC_LIST_CDROM_DRIVES 1157 +#define IDC_COMBO_CD_BUS 1158 +#define IDC_COMBO_CD_ID 1159 +#define IDC_COMBO_CD_LUN 1160 +#define IDC_COMBO_CD_CHANNEL_IDE 1161 +#define IDC_BUTTON_CDROM_ADD 1162 // status bar menu +#define IDC_BUTTON_CDROM_EDIT 1163 // status bar menu +#define IDC_BUTTON_CDROM_REMOVE 1164 // status bar menu + + +/* For the DeviceConfig code, re-do later. */ +#define IDC_CONFIG_BASE 1200 +#define IDC_CONFIGURE_VID 1200 +#define IDC_CONFIGURE_SND 1201 +#define IDC_CONFIGURE_VOODOO 1202 +#define IDC_CONFIGURE_MOD 1203 +#define IDC_CONFIGURE_NET_TYPE 1204 +#define IDC_CONFIGURE_BUSLOGIC 1205 +#define IDC_CONFIGURE_PCAP 1206 +#define IDC_CONFIGURE_NET 1207 +#define IDC_JOY1 1210 +#define IDC_JOY2 1211 +#define IDC_JOY3 1212 +#define IDC_JOY4 1213 +#define IDC_HDTYPE 1280 +#define IDC_RENDER 1281 +#define IDC_STATUS 1282 + + +/* String IDs. */ #define IDS_STRINGS 2048 // "86Box" #define IDS_2049 2049 // "86Box Error" #define IDS_2050 2050 // "86Box Fatal Error" @@ -289,162 +376,53 @@ #define IDS_2225 2225 // "English (United States)" #define IDS_LANG_ENUS IDS_2225 +#define STRINGS_NUM 178 -#define IDM_ABOUT 40001 -#define IDC_ABOUT_ICON 65535 -#define IDM_FILE_RESET 40015 -#define IDM_FILE_HRESET 40016 -#define IDM_FILE_EXIT 40017 -#define IDM_FILE_RESET_CAD 40018 -#define IDM_HDCONF 40019 -#define IDM_CONFIG 40020 -#define IDM_CONFIG_LOAD 40021 -#define IDM_CONFIG_SAVE 40022 -#define IDM_USE_NUKEDOPL 40023 -#define IDM_STATUS 40030 -#define IDM_VID_RESIZE 40050 -#define IDM_VID_REMEMBER 40051 -#define IDM_VID_DDRAW 40060 -#define IDM_VID_D3D 40061 -#define IDM_VID_SCALE_1X 40064 -#define IDM_VID_SCALE_2X 40065 -#define IDM_VID_SCALE_3X 40066 -#define IDM_VID_SCALE_4X 40067 -#define IDM_VID_FULLSCREEN 40070 -#define IDM_VID_FS_FULL 40071 -#define IDM_VID_FS_43 40072 -#define IDM_VID_FS_SQ 40073 -#define IDM_VID_FS_INT 40074 -#define IDM_VID_FORCE43 40075 -#define IDM_VID_OVERSCAN 40076 -#define IDM_VID_FLASH 40077 -#define IDM_VID_SCREENSHOT 40078 -#define IDM_VID_INVERT 40079 -#define IDM_VID_CGACON 40080 +#define IDM_ABOUT 40001 +#define IDC_ABOUT_ICON 65535 +#define IDM_ACTION_SCREENSHOT 40011 +#define IDM_ACTION_HRESET 40012 +#define IDM_ACTION_RESET_CAD 40013 +#define IDM_ACTION_EXIT 40014 +#define IDM_CONFIG 40020 +#define IDM_CONFIG_LOAD 40021 +#define IDM_CONFIG_SAVE 40022 +#define IDM_STATUS 40030 +#define IDM_VID_RESIZE 40050 +#define IDM_VID_REMEMBER 40051 +#define IDM_VID_DDRAW 40060 +#define IDM_VID_D3D 40061 +#define IDM_VID_SCALE_1X 40064 +#define IDM_VID_SCALE_2X 40065 +#define IDM_VID_SCALE_3X 40066 +#define IDM_VID_SCALE_4X 40067 +#define IDM_VID_FULLSCREEN 40070 +#define IDM_VID_FS_FULL 40071 +#define IDM_VID_FS_43 40072 +#define IDM_VID_FS_SQ 40073 +#define IDM_VID_FS_INT 40074 +#define IDM_VID_FORCE43 40075 +#define IDM_VID_OVERSCAN 40076 +#define IDM_VID_INVERT 40079 +#define IDM_VID_CGACON 40080 -#define IDM_IDE_TER_ENABLED 44000 -#define IDM_IDE_TER_IRQ9 44009 -#define IDM_IDE_TER_IRQ10 44010 -#define IDM_IDE_TER_IRQ11 44011 -#define IDM_IDE_TER_IRQ12 44012 -#define IDM_IDE_TER_IRQ14 44014 -#define IDM_IDE_TER_IRQ15 44015 -#define IDM_IDE_QUA_ENABLED 44020 -#define IDM_IDE_QUA_IRQ9 44029 -#define IDM_IDE_QUA_IRQ10 44030 -#define IDM_IDE_QUA_IRQ11 44031 -#define IDM_IDE_QUA_IRQ12 44032 -#define IDM_IDE_QUA_IRQ14 44033 -#define IDM_IDE_QUA_IRQ15 44035 +#define IDM_LOG_BREAKPOINT 51201 +#define IDM_DUMP_VRAM 51202 // should be an Action -#ifdef ENABLE_BUSLOGIC_LOG -# define IDM_LOG_BUSLOGIC 51200 -#endif -#ifdef ENABLE_CDROM_LOG -# define IDM_LOG_CDROM 51201 -#endif -#ifdef ENABLE_D86F_LOG -# define IDM_LOG_D86F 51202 -#endif -#ifdef ENABLE_FDC_LOG -# define IDM_LOG_FDC 51203 -#endif -#ifdef ENABLE_IDE_LOG -# define IDM_LOG_IDE 51204 -#endif -#ifdef ENABLE_NIC_LOG -# define IDM_LOG_NIC 51205 -#endif -#ifdef ENABLE_SERIAL_LOG -# define IDM_LOG_SERIAL 51208 -#endif -#ifdef ENABLE_LOG_BREAKPOINT -# define IDM_LOG_BREAKPOINT 51206 -#endif -#ifdef ENABLE_VRAM_DUMP -# define IDM_DUMP_VRAM 51207 -#endif - -#define IDC_COMBO1 1000 -#define IDC_COMBOVID 1001 -#define IDC_COMBO3 1002 -#define IDC_COMBO4 1003 -#define IDC_COMBO5 1004 -#define IDC_COMBO386 1005 -#define IDC_COMBO486 1006 -#define IDC_COMBOSND 1007 -#define IDC_COMBONETTYPE 1008 -#define IDC_COMBOPCAP 1009 -#define IDC_COMBONET 1010 /*FIXME*/ -#define IDC_CHECK1 1010 /*FIXME*/ -#define IDC_CHECK2 1011 -#define IDC_CHECK3 1012 -#define IDC_CHECKSSI 1014 -#define IDC_CHECKVOODOO 1015 -#define IDC_CHECKDYNAREC 1016 -#define IDC_CHECKBUSLOGIC 1017 -#define IDC_CHECKSYNC 1024 -#define IDC_CHECKXTIDE 1025 -#define IDC_CHECKFPU 1026 -#define IDC_EDIT1 1030 -#define IDC_EDIT2 1031 -#define IDC_EDIT3 1032 -#define IDC_EDIT4 1033 -#define IDC_EDIT5 1034 -#define IDC_EDIT6 1035 -#define IDC_COMBOHDT 1036 -#define IDC_COMBOCPUM 1060 -#define IDC_COMBOSPD 1061 -#define IDC_COMBODR1 1062 -#define IDC_COMBODR2 1063 -#define IDC_COMBODR3 1064 -#define IDC_COMBODR4 1065 -#define IDC_COMBOJOY 1066 -#define IDC_COMBOWS 1067 -#define IDC_COMBOMOUSE 1068 -#define IDC_COMBOHDD 1069 - -#define IDC_CFILE 1060 - -#define IDC_HDTYPE 1280 - -#define IDC_RENDER 1281 -#define IDC_STATUS 1282 - -#define IDC_MEMSPIN 1100 -#define IDC_MEMTEXT 1101 -#define IDC_STEXT1 1102 -#define IDC_STEXT2 1103 -#define IDC_STEXT3 1104 -#define IDC_STEXT4 1105 -#define IDC_STEXT5 1106 -#define IDC_STEXT6 1107 -#define IDC_STEXT7 1108 -#define IDC_STEXT8 1109 -#define IDC_STEXT_DEVICE 1110 -#define IDC_TEXT_MB 1111 -#define IDC_TEXT1 1115 -#define IDC_TEXT2 1116 - -#define IDC_CONFIGUREVID 1200 -#define IDC_CONFIGURESND 1201 -#define IDC_CONFIGUREVOODOO 1202 -#define IDC_CONFIGUREMOD 1203 -#define IDC_CONFIGURENETTYPE 1204 -#define IDC_CONFIGUREBUSLOGIC 1205 -#define IDC_CONFIGUREPCAP 1206 -#define IDC_CONFIGURENET 1207 -#define IDC_JOY1 1210 -#define IDC_JOY2 1211 -#define IDC_JOY3 1212 -#define IDC_JOY4 1213 - -#define IDC_CONFIG_BASE 1200 - -/* The biggest amount of low bits needed for CD-ROMS (2 bits for ID and 5 bits for host drive, so 7 bits), - and removable disks (5 bits for ID), so we choose an 256-entry spacing for convenience. */ +#define IDM_LOG_SERIAL 51211 +#define IDM_LOG_D86F 51212 +#define IDM_LOG_FDC 51213 +#define IDM_LOG_IDE 51214 +#define IDM_LOG_CDROM 51215 +#define IDM_LOG_NIC 51216 +#define IDM_LOG_BUSLOGIC 51217 +/* + * We need 7 bits for CDROM (2 bits ID and 5 bits for host drive), + * and 5 bits for Removable Disks (5 bits for ID), so we use an + * 8bit (256 entries) space for these devices. + */ #define IDM_FLOPPY_IMAGE_NEW 0x1200 #define IDM_FLOPPY_IMAGE_EXISTING 0x1300 #define IDM_FLOPPY_IMAGE_EXISTING_WP 0x1400 @@ -463,20 +441,17 @@ #define IDM_RDISK_IMAGE 0x3500 #define IDM_RDISK_IMAGE_WP 0x3600 -#define IDC_STATIC 1792 /* Next default values for new objects */ #ifdef APSTUDIO_INVOKED # ifndef APSTUDIO_READONLY_SYMBOLS # define _APS_NO_MFC 1 -# define _APS_NEXT_RESOURCE_VALUE 111 -# define _APS_NEXT_COMMAND_VALUE 40002 -# define _APS_NEXT_CONTROL_VALUE 1055 -# define _APS_NEXT_SYMED_VALUE 101 +# define _APS_NEXT_RESOURCE_VALUE 1400 +# define _APS_NEXT_COMMAND_VALUE 55000 +# define _APS_NEXT_CONTROL_VALUE 1800 +# define _APS_NEXT_SYMED_VALUE 200 # endif #endif -#define STRINGS_NUM 178 - #endif /*WIN_RESOURCE_H*/ diff --git a/src/WIN/win.c b/src/WIN/win.c index 410774cf8..975aaf0c9 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1806,15 +1806,19 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM hmenu=GetMenu(hwnd); switch (LOWORD(wParam)) { - case IDM_FILE_HRESET: + case IDM_ACTION_SCREENSHOT: + take_screenshot(); + break; + + case IDM_ACTION_HRESET: win_pc_reset(1); break; - case IDM_FILE_RESET_CAD: + case IDM_ACTION_RESET_CAD: win_pc_reset(0); break; - case IDM_FILE_EXIT: + case IDM_ACTION_EXIT: PostQuitMessage (0); /* send a WM_QUIT to the message queue */ break; @@ -1939,10 +1943,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM video_toggle_option(hmenu, &enable_overscan, IDM_VID_OVERSCAN); break; - case IDM_VID_SCREENSHOT: - take_screenshot(); - break; - case IDM_VID_CGACON: vid_cga_contrast = !vid_cga_contrast; CheckMenuItem(menu, IDM_VID_CGACON, vid_cga_contrast ? MF_CHECKED : MF_UNCHECKED); diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 6dc8ef98f..702b8b5d5 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.1 2017/06/03 + * Version: @(#)win_settings.c 1.0.2 2017/06/04 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -491,13 +491,13 @@ static void win_settings_machine_recalc_model(HWND hdlg) { SendMessage(h, UDM_SETPOS, 0, temp_mem_size); h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2094)); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(IDS_2094)); } else { SendMessage(h, UDM_SETPOS, 0, temp_mem_size / 1024); h = GetDlgItem(hdlg, IDC_TEXT_MB); - SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(2087)); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) win_language_get_string_from_id(IDS_2087)); } free(lptsTemp); @@ -541,7 +541,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w SendMessage(h, CB_SETCURSEL, modeltolist[temp_model], 0); h = GetDlgItem(hdlg, IDC_COMBO_WS); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2131)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2131)); for (c = 0; c < 8; c++) { @@ -693,7 +693,7 @@ static void recalc_vid_list(HWND hdlg) h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); EnableWindow(h, (models[model].flags & MODEL_PCI) ? TRUE : FALSE); - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); EnableWindow(h, ((models[model].flags & MODEL_PCI) && temp_voodoo) ? TRUE : FALSE); } @@ -714,12 +714,12 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa recalc_vid_list(hdlg); h = GetDlgItem(hdlg, IDC_COMBO_VIDEO_SPEED); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2133)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2134)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2135)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2136)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2137)); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2138)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2133)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2134)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2135)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2136)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2137)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2138)); SendMessage(h, CB_SETCURSEL, temp_video_speed, 0); h=GetDlgItem(hdlg, IDC_CHECK_VOODOO); @@ -730,7 +730,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa wcstombs(stransi, lptsTemp, (wcslen(lptsTemp) * 2) + 2); gfx = video_card_getid(stransi); - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); if (video_card_has_config(gfx)) { EnableWindow(h, TRUE); @@ -758,7 +758,7 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa gfx = video_card_getid(stransi); temp_gfxcard = video_new_to_old(gfx); - h = GetDlgItem(hdlg, IDC_CONFIGUREVID); + h = GetDlgItem(hdlg, IDC_CONFIGURE_VID); if (video_card_has_config(gfx)) { EnableWindow(h, TRUE); @@ -776,15 +776,15 @@ static BOOL CALLBACK win_settings_video_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CHECK_VOODOO); temp_voodoo = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CONFIGURE_VOODOO); + h = GetDlgItem(hdlg, IDC_BUTTON_VOODOO); EnableWindow(h, temp_voodoo ? TRUE : FALSE); break; - case IDC_CONFIGURE_VOODOO: + case IDC_BUTTON_VOODOO: deviceconfig_open(hdlg, (void *)&voodoo_device); break; - case IDC_CONFIGUREVID: + case IDC_CONFIGURE_VID: lptsTemp = (LPTSTR) malloc(512); stransi = (char *) malloc(512); @@ -866,28 +866,28 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa { case 0: /* MS Serial */ default: - str_id = 2139; + str_id = IDS_2139; break; case 1: /* PS2 2b */ - str_id = 2141; + str_id = IDS_2141; break; case 2: /* PS2 intelli 3b */ - str_id = 2142; + str_id = IDS_2142; break; case 3: /* MS/logi bus 2b */ - str_id = 2143; + str_id = IDS_2143; break; case 4: /* Amstrad */ - str_id = 2162; + str_id = IDS_2162; break; case 5: /* Olivetti M24 */ - str_id = 2177; + str_id = IDS_2177; break; case 6: /* MouseSystems */ - str_id = 2140; + str_id = IDS_2140; break; case 7: /* Genius Bus */ - str_id = 2161; + str_id = IDS_2161; break; } @@ -942,25 +942,25 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa break; case IDC_JOY1: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 0, temp_joystick); break; case IDC_JOY2: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 1, temp_joystick); break; case IDC_JOY3: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 2, temp_joystick); break; case IDC_JOY4: - h = GetDlgItem(hdlg, IDC_COMBOJOY); + h = GetDlgItem(hdlg, IDC_COMBO_JOY); temp_joystick = SendMessage(h, CB_GETCURSEL, 0, 0); joystickconfig_open(hdlg, 3, temp_joystick); break; @@ -1001,7 +1001,7 @@ static void recalc_hdd_list(HWND hdlg, int model, int use_selected_hdd) hdc_ignore = 1; SendMessage(h, CB_RESETCONTENT, 0, 0); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2154)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2154)); EnableWindow(h, FALSE); SendMessage(h, CB_SETCURSEL, 0, 0); } @@ -1156,7 +1156,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa case WM_INITDIALOG: lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBOSND); + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); c = d = 0; while (1) { @@ -1177,7 +1177,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa { if (c == 0) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2152)); } else { @@ -1193,7 +1193,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa } SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_sound_card], 0); - h = GetDlgItem(hdlg, IDC_CONFIGURESND); + h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); if (sound_card_has_config(temp_sound_card)) { EnableWindow(h, TRUE); @@ -1223,16 +1223,16 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); - h=GetDlgItem(hdlg, IDC_CHECKCMS); + h=GetDlgItem(hdlg, IDC_CHECK_CMS); SendMessage(h, BM_SETCHECK, temp_GAMEBLASTER, 0); - h=GetDlgItem(hdlg, IDC_CHECKGUS); + h=GetDlgItem(hdlg, IDC_CHECK_GUS); SendMessage(h, BM_SETCHECK, temp_GUS, 0); - h=GetDlgItem(hdlg, IDC_CHECKSSI); + h=GetDlgItem(hdlg, IDC_CHECK_SSI); SendMessage(h, BM_SETCHECK, temp_SSI2001, 0); - h=GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + h=GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); free(lptsTemp); @@ -1242,18 +1242,18 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa case WM_COMMAND: switch (LOWORD(wParam)) { - case IDC_CONFIGURESND: - h = GetDlgItem(hdlg, IDC_COMBOSND); + case IDC_CONFIGURE_SND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); break; - case IDC_COMBOSND: - h = GetDlgItem(hdlg, IDC_COMBOSND); + case IDC_COMBO_SOUND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - h = GetDlgItem(hdlg, IDC_CONFIGURESND); + h = GetDlgItem(hdlg, IDC_CONFIGURE_SND); if (sound_card_has_config(temp_sound_card)) { EnableWindow(h, TRUE); @@ -1285,7 +1285,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa return FALSE; case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBOSND); + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; h = GetDlgItem(hdlg, IDC_COMBO_MIDI); @@ -1294,16 +1294,16 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CHECK_MPU401); temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKCMS); + h = GetDlgItem(hdlg, IDC_CHECK_CMS); temp_GAMEBLASTER = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKGUS); + h = GetDlgItem(hdlg, IDC_CHECK_GUS); temp_GUS = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKSSI); + h = GetDlgItem(hdlg, IDC_CHECK_SSI); temp_SSI2001 = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKNUKEDOPL); + h = GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); default: @@ -1348,7 +1348,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR { if (c == 0) { - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2152)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2152)); } else { @@ -1381,7 +1381,7 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR for (c = 0; c < 11; c++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_2155), valid_ide_irqs[c]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } @@ -1395,11 +1395,11 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR } h=GetDlgItem(hdlg, IDC_COMBO_IDE_QUA); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(2151)); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2151)); for (c = 0; c < 11; c++) { - wsprintf(lptsTemp, win_language_get_string_from_id(2155), valid_ide_irqs[c]); + wsprintf(lptsTemp, win_language_get_string_from_id(IDS_2155), valid_ide_irqs[c]); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); } @@ -1412,16 +1412,16 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR SendMessage(h, CB_SETCURSEL, 0, 0); } - h=GetDlgItem(hdlg, IDC_CHECKSERIAL1); + h=GetDlgItem(hdlg, IDC_CHECK_SERIAL1); SendMessage(h, BM_SETCHECK, temp_serial[0], 0); - h=GetDlgItem(hdlg, IDC_CHECKSERIAL2); + h=GetDlgItem(hdlg, IDC_CHECK_SERIAL2); SendMessage(h, BM_SETCHECK, temp_serial[1], 0); - h=GetDlgItem(hdlg, IDC_CHECKPARALLEL); + h=GetDlgItem(hdlg, IDC_CHECK_PARALLEL); SendMessage(h, BM_SETCHECK, temp_lpt, 0); - h=GetDlgItem(hdlg, IDC_CHECKBUGGER); + h=GetDlgItem(hdlg, IDC_CHECK_BUGGER); SendMessage(h, BM_SETCHECK, temp_bugger, 0); free(lptsTemp); @@ -1493,16 +1493,16 @@ static BOOL CALLBACK win_settings_peripherals_proc(HWND hdlg, UINT message, WPAR temp_ide_qua = 1; } - h = GetDlgItem(hdlg, IDC_CHECKSERIAL1); + h = GetDlgItem(hdlg, IDC_CHECK_SERIAL1); temp_serial[0] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKSERIAL2); + h = GetDlgItem(hdlg, IDC_CHECK_SERIAL2); temp_serial[1] = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKPARALLEL); + h = GetDlgItem(hdlg, IDC_CHECK_PARALLEL); temp_lpt = SendMessage(h, BM_GETCHECK, 0, 0); - h = GetDlgItem(hdlg, IDC_CHECKBUGGER); + h = GetDlgItem(hdlg, IDC_CHECK_BUGGER); temp_bugger = SendMessage(h, BM_GETCHECK, 0, 0); default: @@ -1520,7 +1520,7 @@ static void network_recalc_combos(HWND hdlg) net_ignore_message = 1; - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); if (temp_net_type == NET_TYPE_PCAP) { EnableWindow(h, TRUE); @@ -1530,7 +1530,7 @@ static void network_recalc_combos(HWND hdlg) EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); if (temp_net_type == NET_TYPE_SLIRP) { EnableWindow(h, TRUE); @@ -1545,7 +1545,7 @@ static void network_recalc_combos(HWND hdlg) EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_CONFIGURENET); + h = GetDlgItem(hdlg, IDC_CONFIGURE_NET); if (network_card_has_config(temp_net_card) && (temp_net_type == NET_TYPE_SLIRP)) { @@ -1577,13 +1577,13 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w case WM_INITDIALOG: lptsTemp = (LPTSTR) malloc(512); - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"None"); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"PCap"); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) L"SLiRP"); SendMessage(h, CB_SETCURSEL, temp_net_type, 0); - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); if (temp_net_type == NET_TYPE_PCAP) { EnableWindow(h, TRUE); @@ -1593,7 +1593,7 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); for (c = 0; c < network_ndev; c++) { mbstowcs(lptsTemp, network_devs[c].description, strlen(network_devs[c].description) + 1); @@ -1602,7 +1602,7 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w SendMessage(h, CB_SETCURSEL, network_dev_to_id(temp_pcap_dev), 0); /*NIC config*/ - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); c = d = 0; while (1) { @@ -1643,50 +1643,50 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w case WM_COMMAND: switch (LOWORD(wParam)) { - case IDC_COMBONETTYPE: + case IDC_COMBO_NET_TYPE: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); network_recalc_combos(hdlg); break; - case IDC_COMBOPCAP: + case IDC_COMBO_PCAP: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); network_recalc_combos(hdlg); break; - case IDC_COMBONET: + case IDC_COMBO_NET: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; network_recalc_combos(hdlg); break; - case IDC_CONFIGURENET: + case IDC_CONFIGURE_NET: if (net_ignore_message) { return FALSE; } - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; deviceconfig_open(hdlg, (void *)network_card_getdevice(temp_net_card)); @@ -1695,14 +1695,14 @@ static BOOL CALLBACK win_settings_network_proc(HWND hdlg, UINT message, WPARAM w return FALSE; case WM_SAVESETTINGS: - h = GetDlgItem(hdlg, IDC_COMBONETTYPE); + h = GetDlgItem(hdlg, IDC_COMBO_NET_TYPE); temp_net_type = SendMessage(h, CB_GETCURSEL, 0, 0); - h = GetDlgItem(hdlg, IDC_COMBOPCAP); + h = GetDlgItem(hdlg, IDC_COMBO_PCAP); memset(temp_pcap_dev, '\0', sizeof(temp_pcap_dev)); strcpy(temp_pcap_dev, network_devs[SendMessage(h, CB_GETCURSEL, 0, 0)].device); - h = GetDlgItem(hdlg, IDC_COMBONET); + h = GetDlgItem(hdlg, IDC_COMBO_NET); temp_net_card = settings_list_to_network[SendMessage(h, CB_GETCURSEL, 0, 0)]; default: @@ -4244,5 +4244,5 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar void win_settings_open(HWND hwnd) { - DialogBox(hinstance, (LPCWSTR)DLG_CFG_MAIN, hwnd, win_settings_main_proc); + DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); } diff --git a/src/WIN/win_status.c b/src/WIN/win_status.c index fbc1949ad..0a0fc659c 100644 --- a/src/WIN/win_status.c +++ b/src/WIN/win_status.c @@ -64,11 +64,11 @@ static BOOL CALLBACK status_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPAR ((double)cpu_recomp_ins_latched / 1000000.0) / ((double)main_time / timer_freq) ); main_time = 0; - SendDlgItemMessage(hdlg, IDC_STEXT_DEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + SendDlgItemMessage(hdlg, IDT_SDEVICE, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); device_s[0] = 0; device_add_status_info(device_s, 4096); - SendDlgItemMessage(hdlg, IDC_STEXT1, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); + SendDlgItemMessage(hdlg, IDT_STEXT, WM_SETTEXT, (WPARAM)NULL, (LPARAM)device_s); } return TRUE; From 584fa078d321114427877570394837cd6549d976 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 5 Jun 2017 00:36:03 -0400 Subject: [PATCH 312/392] Updated pcap_if.exe to also use the dynamic loader, removed the pcap/ subfolder now. --- src/Makefile.mingw | 11 +++---- src/pcap/libwpcapdelay.a | Bin 88406 -> 0 bytes src/pcap_if.c | 65 +++++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 17 deletions(-) delete mode 100644 src/pcap/libwpcapdelay.a diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 1a6f76df5..83987d9c4 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.23 2017/06/03 +# Version: @(#)Makefile.mingw 1.0.24 2017/06/04 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -249,17 +249,14 @@ all: $(PROG).exe pcap_if.exe $(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe \ - $(OBJ) $(LZFOBJ) $(SLIRPOBJ) \ - $(LIBS) #-static -Lpcap -lwpcapdelay + @$(CC) -o $(PROG).exe $(OBJ) $(LZFOBJ) $(SLIRPOBJ) $(LIBS) ifneq ($(DEBUG), y) @strip $(PROG).exe endif -pcap_if.exe: pcap_if.o pcap_if.res +pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res @echo Linking pcap_if.exe .. - @$(CC) -o pcap_if.exe \ - pcap_if.o pcap_if.res -static -Lpcap -lwpcapdelay + @$(CC) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res ifneq ($(DEBUG), y) @strip pcap_if.exe endif diff --git a/src/pcap/libwpcapdelay.a b/src/pcap/libwpcapdelay.a deleted file mode 100644 index c9d175845d939ebb7aae9a6882df7445d9e7efe9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 88406 zcmeI54U8m5b%1Nbm^^@s%Q7r>zc0Wuiw0?S6zMMv3xq%xb5=yEV|plrPY|x^Gpa55o6gdf<0OI{6vK zFg*(2f$6bBB7NlhjA8m1=wW*Df=KxjjA0tWNn=|7FOkZ>U<}jfOCnXDVhq#tq)1y= zF^1{f---0hR~f_f6VHouVaOP!pS(__pZX4Cn4bF=k$x6*F@5&DNI&-sW0+n%Cer8r zi7`w+|87&&~})9>l-5d&a;eR z`q~MReh9)aNd~yCf*H=`XKm4AVD3 z2h(5wwn*QC`eFK8I2TOcxlN?+z6MZ&^!L!ln7;Q}k^cD}#xVWs%_9AKk1I{of+J?(1v;(;Hq8>8ev~0n;_t ziuC4hu?0-m{jx|mtg!`5H{C4K{%^7cOz(i>F}-Ul(z`d<0;c|bA|1YhEnqtGry{Ms z$QCfY?}SLVUB?zM9fz_o-T4`j?)fNNz;r+4Vfx@-iS*!eYys259}wx$e`5=n9{Vz; zEE|<;=O%-EGAu^<(^;OC<9xGVS(ep#IeMU&o+*44$h_27gb|7o3OJo&y0*2xUU+BZ<|yqMT((g;KI49CQ5(6^ z99QGD5wPHE8oAQktcD1ox$?837Ba0-j_YbrO`Zb^OkSUGKLd@56^ZX+wa2n;zCl<~_9cC$*W6RB=+VUZI-h^P)9A-n&swZF)Z`C$eJ!MTx>U6A2-bF8~_Wj$xMdU z71(C8@|l32%*m5SjEA4tDz@O(p627(re~sNMVRd!$B*{vt`3rU-VtDD>S^U;tB%pR z-ck7oZk(3yk$L)vNj^AR_$Z8rO3d}9#b#9(`Je`yJ#%&aEKh$hs%CE6nge8Ba72-h zw6XorKsIvON8UdWkx4z0Go5O|$J{8vHPNIYK*ss!iL?;o76B za*dM^sJydV6KFN(^guyLEv;d(-Jr##LJMx{Y`6tZF8r<(a7S72;tlWQxkohX%4?1m zTp22KpJ$$SkSogux%vfdIK;}5`fH8t4;=_2=bGg#o1M!i6R(Q4Sm=$P0*A{v*;0yl z{)TNG33iU8AC~N#fK!HSU$8>PL$$7%Bj@FUq}cY&h!JX?se5ap28vX^x|o)u=YDO2 zf<87cr~L1Yd^{YvrUkwy^Rv0``m`tpzRPWdS_eE0z}bZb)wEn|sxu6EM13#U9A!ag z)tDb*WeNRqJe1$-8~AlE%hz|VxTP$w0Q|NTW7l>mku1q;SIm{i7Wi|KZ9s3X_IzhA zhnFN|d9$hzb3JY}_}zfF)z~#1VWxYGQ(LVp&zJwdUKb;`TWgC=Y3q0jVR2Gy>5aB# z8x49wZ0YfKvo5swTGN{R|Ip#I#k#cM`&13f*(9$A-uY;uI9~QJS_d8!e6B*{vCcSx zT{rJL96h%r`~hwnY|v-nD7eRRcckfSjh~{5aa&AxvUqueX#pLz2B+E0uymc$gqFMl zgKBdE*EAbfsP5`{S)x24Y*JJu27M5_=P}5~!VeAluU-!Swl%2f*}w&`q+APnO64}R zh;vd#D14x7xTf+g!P;aUu_>Y1_2I4z|0_3h;|N*;{L^)IZ3+I3cZ2#`{XZL4!?X2) zN)Ot%jn*IR_m`KK7Z;DLtjgj2)0dxExD-al8M}6YvDfpzUa@eXMu6sTi>!b80Ma#I zjU8wGmkzAWW;>{{3#f$bgZ_)`tDo6 zy}QZw=z|^#%{MC>y zWv_z$m5{FDy4b##u~+gv{)KnRYx#dyz#eVFWu&_S6!mv=(ow)}lv2(kmmqq0E}T9V z-a~JIJUrfP;XM@A(Y7(I_mFjkv4njKi?Daginxckof7wuTLu)$w+G}WULjGVr=$e+ zh2%vk!4Dz%iX-_3{0Bjp6DP9!?s)L76L|-4no!uO&^{ogXdga;%?uk}{U-asGre7u zeGvDv{x$K6lK<*oF~>d}gLB)K=O;e29;XNoMkdgHDSPATEz2)pZ-hV4F1g#{OFwu! zO1_4>f5aVtB3zdkf-6C=6=ie! zW*wpVCdsX#`5r03j~*MqUeMgu5cVKryUv`S07H78M*2#BC9u`MNFZJLau+M<_M&3c-2?1jXTJ`$ws31Z#w$Z=EwH)GLn5dyyNvAf|@Sae-+8)ZvK zVt0ke?o!BZ>QV03>|#GEhTXG@T{CO3BbNDUNvq)(rVi_^$7hi%eof_Fgl##A;$tm_?qMRkN5YZ0&w}~cslWDw?B`sp{k3Q0`FWN!=&wE7tf##N^z>pZ z?itCh^IQzKN-BQx|2dL!Ez|@zV|ndxbdNm*dD8Ma4d8(6<&bD5#{@%5oO*D^636!7 z)-}!g$*qp~5D`5%`>{1EDhQ7?=td#>6V$k18i(Lk#O)-B|vLgiJEEU|0M}e_Wwe{GY@Tc}Dnw}ArG6K2% zqts~Kk%Pe~MDijGxv}-& z+6a!d#JMKeEMTz*EwQP*XNm0$63672T=Inx z2HAv$>f@?W;j_m+4*P&=(+DkS+X^JUsS&+2dd#nmcOPiJV}0h2TYSrv(>mgBTrDX! zT({0*gH=NGvT?4@VaZ7pr$}BCoq?6Uu!EJ3rT7U$v0Bw{Pg1NZ?;B+!Cs9m}0;UL*KW2iYXHsZqWZBjHzOw=DEW4BL8Dv~KtqQPFC>4k%2Pch+3DGe{g$ zV|{6)c`nDXBh4Q+9NVj$cf{L>8)>#1z{lCmBN0uF`X#SpF43`G$770UwKBe5p?@!W z9YG_wU^irw*iLc5CT4^2xo3A6pNqBDAM)82Z;IH1)>?r}c#Q_-DZc(HH7>XuK0A{7 zh(CNE@sv+AEU&}gasu~PH~eXgl;UQ_?A|K`eBWaqhELT;R8*@*Xg1a+mt?D{5y9kH z^DENULyWc6kNRYbx9xO<>KM;jQ7syvnQ4_rBAOf>4Cm9OxQemWv2m404AJtHP+hUn zVzp@7M&Ih#==&WTt=@;_jCh#WWYPQ$YHaXG=x?N%b%tS#C&Y|NKP(tFZxQ2fG3yG) zZ=Uqg3EAg9M3)*O2cU>oHii)53jk;3F<@N2YNUdBnEXYoFZJ?CW@Xv4R@gn1OA zSEy0L)FYfrbnN)uLm|=PJ&)Xib>TTGdXLa1m-H%3lJBuXjTtV7>ue?8!}uPtJ;Dcl zvgON2yD`r3R&E7sA9__v@T12*1bZ>gVW?JbW3@c#hD?&Rrp6BshjZ=HdIN^(*tO#x z5KPP0=61!8#<#}cX8h>=LcsSub_aY4meu=$ErPX(#4R;Sm}c1Vwr}&BV`n;_klb2t za_)%FOrK%ryvEuF*lHBgnnnE;Vmxr=U^trbMYyCpJykUkm;IuBstUa#+&nsU=Uc7& z{rP6SWpOlPIGZ4SQjk35{ZpdXUsf7M&VN zOf&NMmGkZyeJ{jX^dAfFg^pNs`iwjqVrNF4mqFr~8aGVq$IRt8Hp+6p#WB9z9SiS9 z4-xNZ+>GsRdwPZA$}1n3XelKTOpFt*^h2*Cy?4s=3GuBPFqMBinIKC{<}wj01F+RY;oO^p?%xp(~6 zv5n}fAveaSxKk3nzCJ3)MW&a>?S^MepLHSmun(US(zQZQB-YBNU7<}cf5R9G{ zZie7PLcsU-`=YUD4CRq!j(Msw^~#c@OPo*Sz`f}ODnDIoDmj_`%? zk@Osu8LPm!R*WBfyW}t+9iBZ1g^yCS@ zHf>fnc6{PChvI6A%WRw}x+4 zHbH;B)zIvE6~Zh7$kaFpHEx%Bc5|(A>=@fIo8fU$=fmL?zn~i&NA&DCu&Mz$#zTSInf(y~v>xM0+&q@{q%gTok>kJadDR$Sy=MopfPCaSztmx*oavbYd z9JM({r=lFM!>~n1{0e&PPOz*SAf(yKBJoU(-7TfQ9x~oGdJ*ectol56hUM749`7ME zb4={(9Z69S_1p%qQTB647MU8wOCuKu zn@{~R7s4*q!&sIy=TGf%nw z+u%w8iC1bgFO9U#GugKLST=aNBvL4KS6J_u$o162au?UAPia zir)S3(YwPo!NX!3ule327%LwVETklYsj<5>qXHpo^?+k%R2-57!$besaBFjt72{zs z>1%RwH6=%p0DYa%rmp}4TasBx@UanK_gPh!v6WJRoNlPxKUU~2p> ztw!5Kx*nB?U5&P{2%f>a&1ZEER=Iw9QsANv9U+;%8Z9oB?lyvJnZsNX*(sveL~LN2 zcRQl@9*b=C3QNSg8}^wV(c@H`1_+S0vq(IXBYJ68J%Zmh;)eb9m|67)6whlW7Saut zaU>l#GlJ1JtA13P%DW)jauUVVm|luY^J~*aajeJuZb5N5%Vy{D$ppK99kIytxU^My z8)8RHVwf7qOKXD9WjJW z_ztfa58_7!w;T3isoh??Q27zYvv`tQ0wb}OSW{w7GH@sI&8)Z!4;>~)?;_W zpTY|PQbol*e3g*G?qO;yF!c)gC1|t2vAx1~7zqnmy1Z;QX_yX z;k=?3;3Dp{67p$rp)cBZ?0ia|pT}bmCwZ<}Pe%YT-WAg;yjgRrVqazn`))9N1HaF0 z`+HnU@T12*4ts5X!$$CkZc-reO^pMtgrgpbZ{t(MM!4T@_|D7eWROp?jeI;D75v(F z;eD%bLyTcF{>3pN;QJnX96k--UL*K)2iYXHsWHLiFY{~S*?4WcWBuj*g6;KbQ4FeK z(Gj16?l0?#+Z0RoH$?gW@b~``<3rC+*#Lrme*r>_%isDf* z?#_B!^r#8EBnT_+T45=oaC?Xv?Mv%lG+F6oE`(j|`WJ6A+;+r+ps#;{%m&1QfW#{` z%9m!l&E+-L`@K%^THqUBvW;q1*L!m_;qQUQ4ve3hwy;H-+u2ew#=NeojX zcZuO$W%wGKVRS9_EW^C=A;VHkVwf7OOAPNS!&lo3kG5tTdzN8d`H*2LCNWHo&?Rpe zA>J)t;!QTgIA+=zh9kY-7-ATiL@+fvm#i>Cwrd1mWf43WRkQBQnWvAlaaKj; z11qe=6owC`NL>?~!90ocJ3QYM8>zd}Fx-)z96eHp>;}US#7NyiYNReb)6vAWjx5JM z)A2^hYdM?b^$AeOWA3X-k%c%IBhq2ul^Kf_dNLHO1)k{{L zUn}qK(A39T_1AmUqd7;j4%U6|T6Mb-8ZmbjNPJUce(4?7bNR;6sTiyNI*;$-d{waJ*e@%WP|6j8*77K zBiJ2Gi@Yvo)4{Bsc7$KL4R$JT+h8w)WP_}OGU?o*?Fhr^M& z^jxW#i5%+-zsljcD|Q%Xv*KoEA**pZl=j%2uotuHCC9EI7621H;XXP37d{t~$Tj4~ zdJwOa9CZdy^3GeUIG^pORc&amVmV3CZ44BY)}nQr_}yW5luk!)21% ze4NdSI-9O7{1`&XDsNM4OGyM%V|HmQm|vGRf@A&PR|tahL0xXch+0SJrH=*cires7LK3^w zcwAarWiGq1Gd3?_#bjDRfO)vq5pGE{Hch1^v$lZ5D>?3##u^aV-Lkd&*xFiLECikxPxbB}==jmbS;qEjRNsUGWe|mKF&Wm9~&o0ury}=vo>Z zn`dcb$Ho>oukbh-ylM!`?S`c#jg29*vf>uBT0)|h8e2OQjwXB>ek^yIHGES1pkB0Z zSQ^Xo^M3b(S;M>i1QO%a@@H{6LM-05xS3Ie>xF>td+dGinIW */ #include #include +#include #include #include +#include "plat_dynld.h" + + +static void *pcap_handle; /* handle to WinPcap DLL */ + + +/* Pointers to the real functions. */ +static int (*f_pcap_findalldevs)(pcap_if_t **,char *); +static void (*f_pcap_freealldevs)(pcap_if_t *); +static pcap_t *(*f_pcap_open_live)(const char *,int,int,int,char *); +static int (*f_pcap_next_ex)(pcap_t*,struct pcap_pkthdr**,const unsigned char**); +static void (*f_pcap_close)(pcap_t *); +static dllimp_t pcap_imports[] = { + { "pcap_findalldevs", &f_pcap_findalldevs }, + { "pcap_freealldevs", &f_pcap_freealldevs }, + { "pcap_open_live", &f_pcap_open_live }, + { "pcap_next_ex", &f_pcap_next_ex }, + { "pcap_close", &f_pcap_close }, + { NULL, NULL }, +}; typedef struct { @@ -35,7 +56,7 @@ get_devlist(dev_t *list) int i = 0; /* Retrieve the device list from the local machine */ - if (pcap_findalldevs(&devlist, errbuf) == -1) { + if (f_pcap_findalldevs(&devlist, errbuf) == -1) { fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf); return(-1); } @@ -51,7 +72,7 @@ get_devlist(dev_t *list) } /* Release the memory. */ - pcap_freealldevs(devlist); + f_pcap_freealldevs(devlist); return(i); } @@ -130,11 +151,11 @@ start_cap(char *dev) int rc; /* Open the device for reading from it. */ - pcap = pcap_open_live(dev, - 1518, /* MTU */ - 1, /* promisc mode */ - 10, /* timeout */ - temp); + pcap = f_pcap_open_live(dev, + 1518, /* MTU */ + 1, /* promisc mode */ + 10, /* timeout */ + temp); if (pcap == NULL) { fprintf(stderr, "Pcap: open_live(%s): %s\n", dev, temp); return(2); @@ -142,7 +163,7 @@ start_cap(char *dev) printf("Listening on '%s'..\n", dev); for (;;) { - rc = pcap_next_ex(pcap, &hdr, &pkt); + rc = f_pcap_next_ex(pcap, &hdr, &pkt); if (rc < 0) break; /* Did we time out? */ @@ -161,7 +182,7 @@ start_cap(char *dev) } /* All done, close up. */ - pcap_close(pcap); + f_pcap_close(pcap); return(0); } @@ -191,6 +212,17 @@ show_devs(dev_t *list, int num) } +void +pclog(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); +} + + int main(int argc, char **argv) { @@ -198,6 +230,13 @@ main(int argc, char **argv) dev_t *dev = interfaces; int numdev, i; + /* Try loading the DLL. */ + pcap_handle = dynld_module("wpcap.dll", pcap_imports); + if (pcap_handle == NULL) { + fprintf(stderr, "Unable to load WinPcap DLL !\n"); + return(1); + } + /* Get the list. */ numdev = get_devlist(interfaces); @@ -205,6 +244,8 @@ main(int argc, char **argv) /* No arguments, just show the list. */ show_devs(interfaces, numdev); + dynld_close(pcap_handle); + return(numdev); } @@ -213,11 +254,15 @@ main(int argc, char **argv) if (i < 0 || i > numdev) { fprintf(stderr, "Invalid interface number %d !\n", i); + dynld_close(pcap_handle); + return(1); } /* Looks good, go and listen.. */ i = start_cap(interfaces[i-1].device); + dynld_close(pcap_handle); + return(i); } From 2ed2e09650fcfb6ae790352adc43e213663873b2 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 5 Jun 2017 01:20:51 -0400 Subject: [PATCH 313/392] Textual updates, moved thread.h to win/plat_thread.h (and thread.c to new lnx/ folder) to clean that up. --- src/Makefile.mingw | 6 +- src/SOUND/sound.c | 54 ++++++++------- src/VIDEO/vid_ati_mach64.c | 7 +- src/VIDEO/vid_et4000w32.c | 2 +- src/VIDEO/vid_nv_riva128.c | 2 +- src/VIDEO/vid_s3.c | 7 +- src/VIDEO/vid_s3_virge.c | 2 +- src/VIDEO/vid_tgui9440.c | 2 +- src/VIDEO/vid_voodoo.c | 2 +- src/VIDEO/video.c | 2 +- src/WIN/win.c | 5 +- src/{ => lnx}/cdrom_ioctl_linux.c | 0 src/lnx/lnx_thread.c | 108 ++++++++++++++++++++++++++++++ src/lnx/plat_thread.h | 24 +++++++ src/net_pcap.c | 4 +- src/net_slirp.c | 2 +- src/thread-pthread.c | 92 ------------------------- src/thread.h | 15 ----- 18 files changed, 181 insertions(+), 155 deletions(-) rename src/{ => lnx}/cdrom_ioctl_linux.c (100%) create mode 100644 src/lnx/lnx_thread.c create mode 100644 src/lnx/plat_thread.h delete mode 100644 src/thread-pthread.c delete mode 100644 src/thread.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 83987d9c4..20374043e 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.24 2017/06/04 +# Version: @(#)Makefile.mingw 1.0.25 2017/06/04 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -143,9 +143,9 @@ SYSOBJ = model.o \ scat.o \ sis496.o \ wd76c10.o \ - laserxt.o \ acer386sx.o acerm3a.o amstrad.o \ - compaq.o olivetti_m24.o jim.o ps1.o ps2.o ps2_mca.o \ + compaq.o laserxt.o jim.o \ + olivetti_m24.o ps1.o ps2.o ps2_mca.o \ tandy_eeprom.o tandy_rom.o DEVOBJ = bugger.o lpt.o serial.o \ um8669f.o pc87306.o sis85c471.o w83877f.o \ diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 5a96ff15c..c233c0966 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -8,27 +8,28 @@ * * Sound emulation core. * - * Version: @(#)sound.c 1.0.0 2017/05/30 + * Version: @(#)sound.c 1.0.1 2017/06/04 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include #include #include "../ibm.h" #include "../device.h" #include "../timer.h" -#include "../thread.h" #include "../cdrom.h" +#include "../win/plat_thread.h" #include "sound.h" #include "snd_opl.h" #include "snd_adlib.h" #include "snd_adlibgold.h" -/* #include "snd_pas16.h" */ +#if 0 +#include "snd_pas16.h" +#endif #include "snd_sb.h" #include "snd_sb_dsp.h" #include "snd_wss.h" @@ -48,26 +49,27 @@ typedef struct static SOUND_CARD sound_cards[] = { - {"None", "none", NULL}, - {"Adlib", "adlib", &adlib_device}, - {"Adlib MCA", "adlib_mca", &adlib_mca_device}, - {"Sound Blaster 1.0", "sb", &sb_1_device}, - {"Sound Blaster 1.5", "sb1.5", &sb_15_device}, - {"Sound Blaster MCV", "sbmcv", &sb_mcv_device}, - {"Sound Blaster 2.0", "sb2.0", &sb_2_device}, - {"Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device}, - {"Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device}, - {"Sound Blaster Pro MCV", "sbpromcv", &sb_pro_mcv_device}, - {"Sound Blaster 16", "sb16", &sb_16_device}, - {"Sound Blaster AWE32", "sbawe32", &sb_awe32_device}, - {"Adlib Gold", "adlibgold", &adgold_device}, - {"Windows Sound System", "wss", &wss_device}, + { "None", "none", NULL }, + { "Adlib", "adlib", &adlib_device }, + { "Adlib MCA", "adlib_mca", &adlib_mca_device }, + { "Sound Blaster 1.0", "sb", &sb_1_device }, + { "Sound Blaster 1.5", "sb1.5", &sb_15_device }, + { "Sound Blaster MCV", "sbmcv", &sb_mcv_device }, + { "Sound Blaster 2.0", "sb2.0", &sb_2_device }, + { "Sound Blaster Pro v1", "sbprov1", &sb_pro_v1_device }, + { "Sound Blaster Pro v2", "sbprov2", &sb_pro_v2_device }, + { "Sound Blaster Pro MCV", "sbpromcv", &sb_pro_mcv_device }, + { "Sound Blaster 16", "sb16", &sb_16_device }, + { "Sound Blaster AWE32", "sbawe32", &sb_awe32_device }, + { "Adlib Gold", "adlibgold", &adgold_device }, + { "Windows Sound System", "wss", &wss_device }, #if 0 - {"Pro Audio Spectrum 16", "pas16", &pas16_device}, + { "Pro Audio Spectrum 16", "pas16", &pas16_device }, #endif - {"", "", NULL} + { "", "", NULL } }; + int sound_card_available(int card) { if (sound_cards[card].device) @@ -112,7 +114,7 @@ int sound_card_get_from_internal_name(char *s) return 0; } -void sound_card_init() +void sound_card_init(void) { if (sound_cards[sound_card_current].device) device_add(sound_cards[sound_card_current].device); @@ -235,7 +237,7 @@ static float *outbuffer_ex; static int cd_thread_enable = 0; -void sound_init() +void sound_init(void) { int i = 0; int available_cdrom_drives = 0; @@ -306,12 +308,12 @@ void sound_poll(void *priv) } } -void sound_speed_changed() +void sound_speed_changed(void) { sound_poll_latch = (int)((double)TIMER_USEC * (1000000.0 / 48000.0)); } -void sound_reset() +void sound_reset(void) { int i = 0; @@ -330,7 +332,7 @@ void sound_reset() } } -void sound_cd_thread_reset() +void sound_cd_thread_reset(void) { int i = 0; int available_cdrom_drives = 0; diff --git a/src/VIDEO/vid_ati_mach64.c b/src/VIDEO/vid_ati_mach64.c index 8668d21e7..4d530c7b9 100644 --- a/src/VIDEO/vid_ati_mach64.c +++ b/src/VIDEO/vid_ati_mach64.c @@ -8,14 +8,13 @@ * * ATi Mach64 graphics card emulation. * - * Version: @(#)vid_ati_mach64.c 1.0.0 2017/05/30 + * Version: @(#)vid_ati_mach64.c 1.0.1 2017/06/04 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include "../ibm.h" #include "../device.h" @@ -23,7 +22,7 @@ #include "../mem.h" #include "../pci.h" #include "../rom.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/VIDEO/vid_et4000w32.c b/src/VIDEO/vid_et4000w32.c index 7a4d84659..254fe8072 100644 --- a/src/VIDEO/vid_et4000w32.c +++ b/src/VIDEO/vid_et4000w32.c @@ -10,7 +10,7 @@ #include "../pci.h" #include "../rom.h" #include "../device.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_icd2061.h" diff --git a/src/VIDEO/vid_nv_riva128.c b/src/VIDEO/vid_nv_riva128.c index d6bcd839b..c5b61a3e6 100644 --- a/src/VIDEO/vid_nv_riva128.c +++ b/src/VIDEO/vid_nv_riva128.c @@ -9,9 +9,9 @@ #include "../pci.h" #include "../pic.h" #include "../rom.h" -#include "../thread.h" #include "../timer.h" #include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_nv_riva128.h" #include "vid_svga.h" diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index c44021f04..8b762aeb9 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -9,22 +9,21 @@ * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 * graphics cards. * - * Version: @(#)vid_s3.c 1.0.0 2017/05/30 + * Version: @(#)vid_s3.c 1.0.1 2017/06/04 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include #include "../ibm.h" #include "../io.h" #include "../mem.h" #include "../pci.h" #include "../rom.h" -#include "../thread.h" #include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_s3.h" #include "vid_svga.h" diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 845c915d3..95f040128 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -9,7 +9,7 @@ #include "../pci.h" #include "../rom.h" #include "../device.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_s3_virge.h" #include "vid_svga.h" diff --git a/src/VIDEO/vid_tgui9440.c b/src/VIDEO/vid_tgui9440.c index e365ed4ac..d0a11d317 100644 --- a/src/VIDEO/vid_tgui9440.c +++ b/src/VIDEO/vid_tgui9440.c @@ -9,7 +9,7 @@ #include "../pci.h" #include "../rom.h" #include "../device.h" -#include "../thread.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" diff --git a/src/VIDEO/vid_voodoo.c b/src/VIDEO/vid_voodoo.c index 38d789a87..9b823e1a2 100644 --- a/src/VIDEO/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -6,9 +6,9 @@ #include "../mem.h" #include "../rom.h" #include "../pci.h" -#include "../thread.h" #include "../timer.h" #include "../device.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #include "vid_voodoo.h" diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index 07531f033..fa541958c 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -12,8 +12,8 @@ #include "../rom.h" #include "../config.h" #include "../device.h" -#include "../thread.h" #include "../timer.h" +#include "../win/plat_thread.h" #include "video.h" #include "vid_svga.h" #ifndef __unix diff --git a/src/WIN/win.c b/src/WIN/win.c index 975aaf0c9..5a76bcc94 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -8,10 +8,11 @@ * * The Emulator's Windows core. * - * Version: @(#)win.c 1.0.1 2017/06/03 + * Version: @(#)win.c 1.0.2 2017/06/04 * * Authors: Sarah Walker, * Miran Grca, + * Fred N. van Kempen, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ @@ -29,7 +30,6 @@ #include "../mem.h" #include "../rom.h" #include "../nvr.h" -#include "../thread.h" #include "../config.h" #include "../model.h" #include "../ide.h" @@ -48,6 +48,7 @@ #include "plat_iodev.h" #include "plat_mouse.h" #include "plat_midi.h" +#include "plat_thread.h" #include "win.h" #include "win_cgapal.h" diff --git a/src/cdrom_ioctl_linux.c b/src/lnx/cdrom_ioctl_linux.c similarity index 100% rename from src/cdrom_ioctl_linux.c rename to src/lnx/cdrom_ioctl_linux.c diff --git a/src/lnx/lnx_thread.c b/src/lnx/lnx_thread.c new file mode 100644 index 000000000..d9f16a0ef --- /dev/null +++ b/src/lnx/lnx_thread.c @@ -0,0 +1,108 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#include +#include +#include +#include +#include "plat_thread.h" + + +typedef struct { + pthread_cond_t cond; + pthread_mutex_t mutex; +} event_pthread_t; + + +thread_t *thread_create(void (*thread_rout)(void *param), void *param) +{ + pthread_t *thread = malloc(sizeof(pthread_t)); + + if (thread != NULL) + pthread_create(thread, NULL, thread_rout, param); + + return(thread); +} + + +void thread_kill(thread_t *handle) +{ + pthread_t *thread = (pthread_t *)handle; + + if (thread != NULL) { + pthread_cancel(*thread); + pthread_join(*thread, NULL); + + free(thread); + } +} + + +event_t *thread_create_event(void) +{ + event_pthread_t *event = malloc(sizeof(event_pthread_t)); + + if (event != NULL) { + pthread_cond_init(&event->cond, NULL); + pthread_mutex_init(&event->mutex, NULL); + } + + return((event_t *)event); +} + + +void thread_set_event(event_t *handle) +{ + event_pthread_t *event = (event_pthread_t *)handle; + + if (event != NULL) { + pthread_mutex_lock(&event->mutex); + pthread_cond_broadcast(&event->cond); + pthread_mutex_unlock(&event->mutex); + } +} + + +void thread_reset_event(event_t *handle) +{ +} + + +int thread_wait_event(event_t *handle, int timeout) +{ + event_pthread_t *event = (event_pthread_t *)handle; + struct timespec abstime; + + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_nsec += (timeout % 1000) * 1000000; + abstime.tv_sec += (timeout / 1000); + if (abstime.tv_nsec > 1000000000) { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } + + pthread_mutex_lock(&event->mutex); + pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); + pthread_mutex_unlock(&event->mutex); + + return(0); +} + + +void thread_destroy_event(event_t *handle) +{ + event_pthread_t *event = (event_pthread_t *)handle; + + if (event != NULL) { + pthread_cond_destroy(&event->cond); + pthread_mutex_destroy(&event->mutex); + + free(event); + } +} + + +void thread_sleep(int t) +{ + usleep(t * 1000); +} diff --git a/src/lnx/plat_thread.h b/src/lnx/plat_thread.h new file mode 100644 index 000000000..dfb3a9c26 --- /dev/null +++ b/src/lnx/plat_thread.h @@ -0,0 +1,24 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifndef PLAT_THREAD_H +# define PLAT_THREAD_H + + +typedef void thread_t; +typedef void event_t; + + +extern thread_t *thread_create(void (*thread_rout)(void *param), void *param); +extern void thread_kill(thread_t *handle); + +extern event_t *thread_create_event(void); +extern void thread_set_event(event_t *event); +extern void thread_reset_event(event_t *_event); +extern int thread_wait_event(event_t *event, int timeout); +extern void thread_destroy_event(event_t *_event); + +extern void thread_sleep(int t); + + +#endif /*PLAT_THREAD_H*/ diff --git a/src/net_pcap.c b/src/net_pcap.c index 3e6affcd9..8e2860be2 100644 --- a/src/net_pcap.c +++ b/src/net_pcap.c @@ -8,7 +8,7 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.4 2017/05/23 + * Version: @(#)net_pcap.c 1.0.5 2017/06/04 * * Author: Fred N. van Kempen, */ @@ -19,10 +19,10 @@ #include #include "ibm.h" #include "config.h" -#include "thread.h" #include "device.h" #include "network.h" #include "plat_dynld.h" +#include "plat_thread.h" static void *pcap_handle; /* handle to WinPcap DLL */ diff --git a/src/net_slirp.c b/src/net_slirp.c index 4659d3d45..f49167cbd 100644 --- a/src/net_slirp.c +++ b/src/net_slirp.c @@ -21,8 +21,8 @@ #include "ibm.h" #include "config.h" #include "device.h" -#include "thread.h" #include "network.h" +#include "plat_thread.h" static queueADT slirpq; /* SLiRP library handle */ diff --git a/src/thread-pthread.c b/src/thread-pthread.c deleted file mode 100644 index dd56ef896..000000000 --- a/src/thread-pthread.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include -#include -#include -#include -#include "thread.h" - -typedef struct event_pthread_t -{ - pthread_cond_t cond; - pthread_mutex_t mutex; -} event_pthread_t; - -thread_t *thread_create(void (*thread_rout)(void *param), void *param) -{ - pthread_t *thread = malloc(sizeof(pthread_t)); - - pthread_create(thread, NULL, thread_rout, param); - - return thread; -} - -void thread_kill(thread_t *handle) -{ - pthread_t *thread = (pthread_t *)handle; - - pthread_cancel(*thread); - pthread_join(*thread, NULL); - - free(thread); -} - -event_t *thread_create_event() -{ - event_pthread_t *event = malloc(sizeof(event_pthread_t)); - - pthread_cond_init(&event->cond, NULL); - pthread_mutex_init(&event->mutex, NULL); - - return (event_t *)event; -} - -void thread_set_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; - - pthread_mutex_lock(&event->mutex); - pthread_cond_broadcast(&event->cond); - pthread_mutex_unlock(&event->mutex); -} - -void thread_reset_event(event_t *handle) -{ -} - -int thread_wait_event(event_t *handle, int timeout) -{ - event_pthread_t *event = (event_pthread_t *)handle; - struct timespec abstime; - - clock_gettime(CLOCK_REALTIME, &abstime); - abstime.tv_nsec += (timeout % 1000) * 1000000; - abstime.tv_sec += (timeout / 1000); - if (abstime.tv_nsec > 1000000000) - { - abstime.tv_nsec -= 1000000000; - abstime.tv_sec++; - } - - pthread_mutex_lock(&event->mutex); - pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); - pthread_mutex_unlock(&event->mutex); - - return 0; -} - -void thread_destroy_event(event_t *handle) -{ - event_pthread_t *event = (event_pthread_t *)handle; - - pthread_cond_destroy(&event->cond); - pthread_mutex_destroy(&event->mutex); - - free(event); -} - -void thread_sleep(int t) -{ - usleep(t * 1000); -} diff --git a/src/thread.h b/src/thread.h deleted file mode 100644 index 3397760fe..000000000 --- a/src/thread.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -typedef void thread_t; -thread_t *thread_create(void (*thread_rout)(void *param), void *param); -void thread_kill(thread_t *handle); - -typedef void event_t; -event_t *thread_create_event(); -void thread_set_event(event_t *event); -void thread_reset_event(event_t *_event); -int thread_wait_event(event_t *event, int timeout); -void thread_destroy_event(event_t *_event); - -void thread_sleep(int t); From e5acdbbeabe348c46c1ec49fb4f2ff2e5ec5f4e6 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 5 Jun 2017 01:33:23 -0400 Subject: [PATCH 314/392] Forgot one.. --- src/WIN/plat_thread.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/WIN/plat_thread.h diff --git a/src/WIN/plat_thread.h b/src/WIN/plat_thread.h new file mode 100644 index 000000000..dfb3a9c26 --- /dev/null +++ b/src/WIN/plat_thread.h @@ -0,0 +1,24 @@ +/* Copyright holders: Sarah Walker + see COPYING for more details +*/ +#ifndef PLAT_THREAD_H +# define PLAT_THREAD_H + + +typedef void thread_t; +typedef void event_t; + + +extern thread_t *thread_create(void (*thread_rout)(void *param), void *param); +extern void thread_kill(thread_t *handle); + +extern event_t *thread_create_event(void); +extern void thread_set_event(event_t *event); +extern void thread_reset_event(event_t *_event); +extern int thread_wait_event(event_t *event, int timeout); +extern void thread_destroy_event(event_t *_event); + +extern void thread_sleep(int t); + + +#endif /*PLAT_THREAD_H*/ From b2e2e2f4cc67824550421c958bbf860d6240afb3 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 5 Jun 2017 05:00:28 -0400 Subject: [PATCH 315/392] Updated serial port code to be multi-threaded. Interrupts still get lost, gotta dig more. --- src/WIN/plat_serial.h | 9 +- src/WIN/win_serial.c | 299 +++++++++++++++++++----------------------- src/serial.c | 177 ++++++++++++------------- 3 files changed, 224 insertions(+), 261 deletions(-) diff --git a/src/WIN/plat_serial.h b/src/WIN/plat_serial.h index cf87192c0..56cf08126 100644 --- a/src/WIN/plat_serial.h +++ b/src/WIN/plat_serial.h @@ -8,7 +8,7 @@ * * Definitions for the Bottom Half of the SERIAL card. * - * Version: @(#)plat_serial.h 1.0.3 2017/05/17 + * Version: @(#)plat_serial.h 1.0.5 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -18,7 +18,7 @@ typedef struct { - char name[79]; /* name of open port */ + char name[80]; /* name of open port */ void (*rd_done)(void *, int); void *rd_arg; #ifdef BHTTY_C @@ -28,6 +28,9 @@ typedef struct { int tmo; /* current timeout value */ DCB dcb, /* terminal settings */ odcb; + thread_t *tid; /* pointer to receiver thread */ + char buff[1024]; + int icnt, ihead, itail; #endif } BHTTY; @@ -41,7 +44,7 @@ extern int bhtty_params(BHTTY *, char __dbit, char __par, char __sbit); extern int bhtty_sstate(BHTTY *, void *__arg); extern int bhtty_gstate(BHTTY *, void *__arg); extern int bhtty_crtscts(BHTTY *, char __yesno); - +extern int bhtty_active(BHTTY *, int); extern int bhtty_write(BHTTY *, unsigned char); extern int bhtty_read(BHTTY *, unsigned char *, int); diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c index cfe8f0b43..1db962177 100644 --- a/src/WIN/win_serial.c +++ b/src/WIN/win_serial.c @@ -12,7 +12,7 @@ * Windows and UNIX systems, with support for FTDI and Prolific * USB ports. Support for these has been removed. * - * Version: @(#)win_serial.c 1.0.2 2017/05/17 + * Version: @(#)win_serial.c 1.0.3 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -21,6 +21,7 @@ #include #include #include +#include "plat_thread.h" #define BHTTY_C #include "plat_serial.h" @@ -28,6 +29,60 @@ extern void pclog(char *__fmt, ...); +/* Handle the receiving of data from the host port. */ +static void +bhtty_reader(void *arg) +{ + BHTTY *pp = (BHTTY *)arg; + unsigned char b; + DWORD n; + + pclog("%s: thread started\n", pp->name); + + /* As long as the channel is open.. */ + while (pp->tid != NULL) { + /* Post a READ on the device. */ + n = 0; + if (ReadFile(pp->handle, &b, (DWORD)1, &n, &pp->rov) == FALSE) { + n = GetLastError(); + if (n != ERROR_IO_PENDING) { + /* Not good, we got an error. */ + pclog("%s: I/O error %d in read!\n", pp->name, n); + break; + } + + /* The read is pending, wait for it.. */ + if (GetOverlappedResult(pp->handle, &pp->rov, &n, TRUE) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in read!\n", pp->name, n); + break; + } + } + +pclog("%s: got %d bytes of data\n", pp->name, n); + if (n == 1) { + /* We got data, update stuff. */ + if (pp->icnt < sizeof(pp->buff)) { +pclog("%s: queued byte %02x (%d)\n", pp->name, b, pp->icnt+1); + pp->buff[pp->ihead++] = b; + pp->ihead &= (sizeof(pp->buff)-1); + pp->icnt++; + + /* Do a callback to let them know. */ + if (pp->rd_done != NULL) + pp->rd_done(pp->rd_arg, n); + } else { + pclog("%s: RX buffer overrun!\n", pp->name); + } + } + } + + /* Error or done, clean up. */ + pp->tid = NULL; + pclog("%s: thread stopped.\n", pp->name); +} + + /* Set the state of a port. */ int bhtty_sstate(BHTTY *pp, void *arg) @@ -35,8 +90,8 @@ bhtty_sstate(BHTTY *pp, void *arg) int i = 0; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid argument\n"); + if (arg == NULL) { + pclog("%s: invalid argument\n", pp->name); return(-1); } @@ -57,8 +112,8 @@ bhtty_gstate(BHTTY *pp, void *arg) int i = 0; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("BHTTY: invalid argument\n"); + if (arg == NULL) { + pclog("%s: invalid argument\n", pp->name); return(-1); } @@ -76,12 +131,6 @@ bhtty_gstate(BHTTY *pp, void *arg) int bhtty_crtscts(BHTTY *pp, char yesno) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -124,12 +173,6 @@ bhtty_crtscts(BHTTY *pp, char yesno) int bhtty_params(BHTTY *pp, char dbit, char par, char sbit) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -220,8 +263,8 @@ bhtty_raw(BHTTY *pp, void *arg) DCB *dcb = (DCB *)arg; /* Make sure we can do this. */ - if (pp == NULL || arg == NULL) { - pclog("invalid parameter\n"); + if (arg == NULL) { + pclog("%s: invalid parameter\n", pp->name); return; } @@ -263,12 +306,6 @@ bhtty_speed(BHTTY *pp, long speed) { int i; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* Get the current mode and speed. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -296,12 +333,6 @@ bhtty_flush(BHTTY *pp) COMSTAT cs; int i = 0; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid handle\n"); - return(-1); - } - /* First, clear any errors. */ (void)ClearCommError(pp->handle, &dwErrs, &cs); @@ -327,13 +358,18 @@ bhtty_flush(BHTTY *pp) void bhtty_close(BHTTY *pp) { - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("BHTTY: invalid handle\n"); - return; - } + /* If the polling thread is running, stop it. */ + (void)bhtty_active(pp, 0); + + /* Close the event handles. */ + if (pp->rov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(pp->rov.hEvent); + if (pp->wov.hEvent != INVALID_HANDLE_VALUE) + CloseHandle(pp->wov.hEvent); if (pp->handle != INVALID_HANDLE_VALUE) { + pclog("%s: closing host port\n", pp->name); + /* Restore the previous port state, if any. */ (void)bhtty_sstate(pp, &pp->odcb); @@ -351,20 +387,11 @@ bhtty_close(BHTTY *pp) BHTTY * bhtty_open(char *port, int tmo) { - char buff[64]; + char temp[64]; COMMTIMEOUTS to; -#if 0 COMMCONFIG conf; - DWORD d; -#endif BHTTY *pp; - int i = 0; - - /* Make sure we can do this. */ - if (port == NULL) { - pclog("invalid argument!\n"); - return(NULL); - } + DWORD d; /* First things first... create a control block. */ if ((pp = (BHTTY *)malloc(sizeof(BHTTY))) == NULL) { @@ -375,45 +402,53 @@ bhtty_open(char *port, int tmo) strncpy(pp->name, port, sizeof(pp->name)-1); /* Try a regular Win32 serial port. */ - sprintf(buff, "\\\\.\\%s", pp->name); - pp->handle = CreateFile(buff, - (GENERIC_READ|GENERIC_WRITE), - 0, NULL, OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0); - if (pp->handle == INVALID_HANDLE_VALUE) { + sprintf(temp, "\\\\.\\%s", pp->name); + if ((pp->handle = CreateFile(temp, + (GENERIC_READ|GENERIC_WRITE), + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0)) == INVALID_HANDLE_VALUE) { pclog("%s: open port: %d\n", pp->name, GetLastError()); free(pp); return(NULL); } -#if 0 + /* Create event handles. */ + pp->rov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + pp->wov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + /* Set up buffer size of the port. */ if (SetupComm(pp->handle, 32768L, 32768L) == FALSE) { /* This fails on FTDI-based devices. */ pclog("%s: set buffers: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); +#if 0 + CloseHandle(pp->handle); + free(pp); + return(NULL); +#endif } /* Grab default config for the driver and set it. */ d = sizeof(COMMCONFIG); memset(&conf, 0x00, d); conf.dwSize = d; - if (GetDefaultCommConfig(pp->name, &conf, &d) == TRUE) { + if (GetDefaultCommConfig(temp, &conf, &d) == TRUE) { /* Change config here... */ /* Set new configuration. */ if (SetCommConfig(pp->handle, &conf, d) == FALSE) { /* This fails on FTDI-based devices. */ pclog("%s: set configuration: %d\n", pp->name, GetLastError()); -// CloseHandle(pp->handle); -// free(pp); -// return(NULL); +#if 0 + CloseHandle(pp->handle); + free(pp); + return(NULL); +#endif } } -#endif + pclog("%s: host port '%s' open\n", pp->name, temp); /* * We now have an open port. To allow for clean exit @@ -460,8 +495,7 @@ bhtty_open(char *port, int tmo) to.ReadTotalTimeoutConstant = tmo; } if (SetCommTimeouts(pp->handle, &to) == FALSE) { - pclog("%s: error %d while setting TO\n", - pp->name, GetLastError()); + pclog("%s: error %d while setting TO\n", pp->name, GetLastError()); (void)bhtty_close(pp); return(NULL); } @@ -476,25 +510,22 @@ bhtty_open(char *port, int tmo) } -/* A pending WRITE has finished, handle it. */ -static VOID CALLBACK -bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) +/* Activate the I/O for this port. */ +int +bhtty_active(BHTTY *pp, int flg) { - BHTTY *pp = (BHTTY *)priv->hEvent; + if (flg) { + pclog("%s: starting thread..\n", pp->name); + pp->tid = thread_create(bhtty_reader, pp); + } else { + if (pp->tid != NULL) { + pclog("%s: stopping thread..\n", pp->name); + thread_kill(pp->tid); + pp->tid = NULL; + } + } -//pclog("%s: write complete, status %d, num %d\n", pp->name, err, num); -#if 0 - if ( - if (GetOverlappedResult(p->handle, - &p->rov, &mst, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - sprintf(serial_errmsg, - "%s: I/O read error!", p->name); - return(-1); - } -#endif + return(0); } @@ -502,56 +533,26 @@ bhtty_write_comp(DWORD err, DWORD num, OVERLAPPED *priv) int bhtty_write(BHTTY *pp, unsigned char val) { - DWORD n; + DWORD n = 0; - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); - } -//pclog("BHwrite(%08lx, %02x, '%c')\n", pp->handle, val, val); - - /* Save the control pointer for later use. */ - pp->wov.hEvent = (HANDLE)pp; - - if (WriteFileEx(pp->handle, - &val, 1, - &pp->wov, - bhtty_write_comp) == FALSE) { +pclog("%s: writing byte %02x\n", pp->name, val); + if (WriteFile(pp->handle, &val, 1, &n, &pp->wov) == FALSE) { n = GetLastError(); - pclog("%s: I/O error %d in write!\n", pp->name, n); - return(-1); + if (n != ERROR_IO_PENDING) { + /* Not good, we got an error. */ + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } + + /* The write is pending, wait for it.. */ + if (GetOverlappedResult(pp->handle, &pp->wov, &n, TRUE) == FALSE) { + n = GetLastError(); + pclog("%s: I/O error %d in write!\n", pp->name, n); + return(-1); + } } - /* Its pending, so handled in the completion routine. */ - SleepEx(1, TRUE); - - return(0); -} - - -/* - * A pending READ has finished, handle it. - */ -static VOID CALLBACK -bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) -{ - BHTTY *pp = (BHTTY *)priv->hEvent; - DWORD r; -//pclog("%s: read complete, status %d, num %d\n", pp->name, err, num); - - if (GetOverlappedResult(pp->handle, &pp->rov, &r, TRUE) == FALSE) { - r = GetLastError(); - if (r != ERROR_OPERATION_ABORTED) - /* OK, we're being shut down. */ - pclog("%s: I/O read error!", pp->name); - return; - } -//pclog("%s: read done, num=%d (%d)\n", pp->name, num, r); - - /* Do a callback to let them know. */ - if (pp->rd_done != NULL) - pp->rd_done(pp->rd_arg, num); + return((int)n); } @@ -561,46 +562,18 @@ bhtty_read_comp(DWORD err, DWORD num, OVERLAPPED *priv) * For now, we will use one byte per call. Eventually, * we should go back to loading a buffer full of data, * just to speed things up a bit. --FvK - * - * Also, not that we do not wait here. We just POST a - * read operation, and the completion routine will do - * the clean-up and notify the caller. */ int bhtty_read(BHTTY *pp, unsigned char *bufp, int max) { - DWORD r; + if (pp->icnt == 0) return(0); - /* Just one byte. */ - max = 1; - - /* Make sure we can do this. */ - if (pp == NULL) { - pclog("invalid parameter\n"); - return(-1); + while (max-- > 0) { + *bufp++ = pp->buff[pp->itail++]; +pclog("%s: dequeued byte %02x (%d)\n", pp->name, *(bufp-1), pp->icnt); + pp->itail &= (sizeof(pp->buff)-1); + if (--pp->icnt == 0) break; } - /* Save the control pointer for later use. */ - pp->rov.hEvent = (HANDLE)pp; -//pclog("%s: read(%08lx, %d)\n", pp->name, pp->handle, max); - - /* Post a READ on the device. */ - if (ReadFileEx(pp->handle, - bufp, (DWORD)max, - &pp->rov, - bhtty_read_comp) == FALSE) { - r = GetLastError(); - if (r != ERROR_IO_PENDING) { - /* OK, we're being shut down. */ - if (r != ERROR_INVALID_HANDLE) - pclog("%s: I/O read error!\n", pp->name); - return(-1); - } - } - - /* Make ourself alertable. */ - SleepEx(1, TRUE); - - /* OK, it's pending, so we are good for now. */ - return(0); + return(max); } diff --git a/src/serial.c b/src/serial.c index bf6e6a45c..c89b9be1b 100644 --- a/src/serial.c +++ b/src/serial.c @@ -33,7 +33,7 @@ * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.6 2017/06/02 + * Version: @(#)serial.c 1.0.7 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -47,6 +47,9 @@ #include "plat_serial.h" +#define NUM_SERIAL 2 /* we support 2 ports */ + + enum { SERINT_LSR = 1, SERINT_RECEIVE = 2, @@ -137,8 +140,7 @@ enum { #define MSR_MASK (0x0f) -static SERIAL serial1, /* serial port 1 data */ - serial2; /* serial port 2 data */ +static SERIAL ports[NUM_SERIAL]; /* serial port data */ int serial_do_log; @@ -222,16 +224,6 @@ serial_write_fifo(SERIAL *sp, uint8_t dat) } -#ifdef WALTJE -static void -serial_write_str(SERIAL *sp, const char *str) -{ - while (*str) - serial_write_fifo(sp, (uint8_t)*str++); -} -#endif - - static uint8_t read_fifo(SERIAL *sp) { @@ -244,19 +236,6 @@ read_fifo(SERIAL *sp) } -/* BHTTY WRITE COMPLETE handler. */ -static void -serial_wr_done(void *arg) -{ - SERIAL *sp = (SERIAL *)arg; - - /* The WRITE completed, we are ready for more. */ - sp->lsr |= LSR_THRE; - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); -} - - /* Handle a WRITE operation to one of our registers. */ static void serial_write(uint16_t addr, uint8_t val, void *priv) @@ -278,13 +257,12 @@ serial_write(uint16_t addr, uint8_t val, void *priv) sp->thr = val; if (sp->bh != NULL) { /* We are linked, so send to BH layer. */ -#if 0 - bhtty_write((BHTTY *)sp->bh, - sp->thr, serial_wr_done, sp); -#else bhtty_write((BHTTY *)sp->bh, sp->thr); - serial_wr_done(sp); -#endif + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); } else { /* Not linked. Just fake LOOPBACK mode. */ if (! (sp->mctrl & MCR_LMS)) @@ -316,19 +294,25 @@ serial_write(uint16_t addr, uint8_t val, void *priv) baud = ((sp->dlab2<<8) | sp->dlab1); if (baud > 0) { speed = 115200UL/baud; +#ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", +#endif sp->port, baud, speed); if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); } else { +#ifdef ENABLE_SERIAL_LOG serial_log(1, "Serial%d: divisor %u invalid!\n", sp->port, baud); +#endif } } wl = (val & LCR_WLS) + 5; /* databits */ sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; +#ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); +#endif if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); sp->lcr = val; @@ -344,12 +328,17 @@ serial_write(uint16_t addr, uint8_t val, void *priv) */ if (sp->rts_callback) { sp->rts_callback(sp->rts_callback_p); +#ifdef ENABLE_SERIAL_LOG serial_log(1, "RTS raised; sending ID\n"); +#endif } } if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { - if (sp->bh == NULL) { + if (sp->bh != NULL) { + /* Linked, start host port. */ + (void)bhtty_active(sp->bh, 1); + } else { /* Not linked, start RX timer. */ timer_add(serial_timer, &sp->receive_delay, @@ -361,11 +350,6 @@ serial_write(uint16_t addr, uint8_t val, void *priv) MSR_DCD | MSR_DDCD); sp->int_status |= SERINT_MSR; update_ints(sp); - -#ifdef WALTJE - /* For testing. */ - serial_write_str(sp, "Welcome!\r\n"); -#endif } } sp->mctrl = val; @@ -420,12 +404,15 @@ static void serial_rd_done(void *arg, int num) { SERIAL *sp = (SERIAL *)arg; -#ifdef WALTJE -serial_log(0, "%04x: %d bytes available: %02x (%c)\n",sp->addr,num,sp->hold,sp->hold); -#endif - /* Stuff the byte in the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); + /* We can do at least 'num' bytes.. */ + while (num-- > 0) { + /* Get a byte from them. */ + if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; + + /* Stuff it into the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + } } @@ -440,21 +427,19 @@ serial_read(uint16_t addr, void *priv) case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { ret = sp->dlab1; - break; + } else { + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; } - sp->lsr &= ~LSR_DR; - sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); - if ((sp->bh == NULL) && (sp->fifo_read != sp->fifo_write)) - sp->receive_delay = 1000 * TIMER_USEC; break; case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) - ret = sp->dlab2; - else - ret = sp->ier; + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; break; case 2: /* IIR */ @@ -463,9 +448,8 @@ serial_read(uint16_t addr, void *priv) sp->int_status &= ~SERINT_TRANSMIT; update_ints(sp); } - if (sp->fcr & 0x01) { + if (sp->fcr & 0x01) ret |= 0xc0; - } break; case 3: /* LCR */ @@ -512,32 +496,25 @@ serial_setup(int port, uint16_t addr, int irq) { SERIAL *sp; +#ifdef ENABLE_SERIAL_LOG serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); +#endif /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; /* Set up the basic info. */ if (sp->addr != 0x0000) { /* Unlink the previous handler. Just in case. */ io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } sp->addr = addr; sp->irq = irq; /* Request an I/O range. */ io_sethandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); - -#if 1 - /* Do not disable here, it breaks the SIO chips. */ -#else - /* No DTR/RTS callback for now. */ - sp->rts_callback = NULL; -#endif + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } @@ -548,17 +525,10 @@ serial_remove(int port) SERIAL *sp; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; // FIXME: stop timer, if enabled! -#if 1 - /* Do not disable here, it breaks the SIO chips. */ -#else - /* Remove any callbacks. */ - sp->rts_callback = NULL; -#endif - /* Close the host device. */ if (sp->bh != NULL) (void)serial_link(port, NULL); @@ -566,8 +536,7 @@ serial_remove(int port) /* Release our I/O range. */ if (sp->addr != 0x0000) { io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, - serial_write, NULL, NULL, sp); + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); } sp->addr = 0x0000; sp->irq = 0; @@ -578,21 +547,31 @@ serial_remove(int port) void serial_init(void) { + SERIAL *sp; + int i; + #if ENABLE_SERIAL_LOG serial_do_log = ENABLE_SERIAL_LOG; #endif - memset(&serial1, 0x00, sizeof(SERIAL)); - serial1.port = 1; - serial_setup(serial1.port, SERIAL1_ADDR, SERIAL1_IRQ); -#ifdef xWALTJE - serial_link(serial1.port, "COM1"); -#endif - memset(&serial2, 0x00, sizeof(SERIAL)); - serial2.port = 2; - serial_setup(serial2.port, SERIAL2_ADDR, SERIAL2_IRQ); -#ifdef xWALTJE - serial_link(serial2.port, "COM2"); + /* FIXME: we should probably initialize the platform module here. */ + + /* Initialize each port. */ + for (i=0; iport = (i+1); + + if (i == 0) + serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); + } + +#ifdef WALTJE + /* Link to host port. */ + serial_link(1, "COM1"); + serial_link(2, "COM2"); #endif } @@ -605,11 +584,15 @@ serial_init(void) void serial_reset(void) { - serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; - serial1.fifo_read = serial1.fifo_write = 0; + SERIAL *sp; + int i; - serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; - serial2.fifo_read = serial2.fifo_write = 0; + for (i=0; iiir = sp->ier = sp->lcr = sp->mctrl = 0x00; + sp->fifo_read = sp->fifo_write = 0x00; + } } @@ -621,19 +604,23 @@ serial_link(int port, char *arg) BHTTY *bh; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; if (arg != NULL) { /* Make sure we're not already linked. */ if (sp->bh != NULL) { +#if ENABLE_SERIAL_LOG serial_log(0, "Serial%d already linked!\n", port); +#endif return(-1); } /* Request a port from the host system. */ bh = bhtty_open(arg, 0); if (bh == NULL) { +#if ENABLE_SERIAL_LOG serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); +#endif return(-1); } sp->bh = bh; @@ -661,7 +648,7 @@ serial_attach(int port, void *func, void *arg) SERIAL *sp; /* Grab the desired port block. */ - sp = (port == 2) ? &serial2 : &serial1; + sp = &ports[port-1]; /* Set up callback info. */ sp->rts_callback = func; From 6a345aa804d21ced5b073d6f106af8ffea72cac6 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 5 Jun 2017 05:05:20 -0400 Subject: [PATCH 316/392] OK, and now with a file that compiles if logging not enabled.. --- src/serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serial.c b/src/serial.c index c89b9be1b..035e443f2 100644 --- a/src/serial.c +++ b/src/serial.c @@ -296,8 +296,8 @@ serial_write(uint16_t addr, uint8_t val, void *priv) speed = 115200UL/baud; #ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", -#endif sp->port, baud, speed); +#endif if ((sp->bh != NULL) && (speed > 0)) bhtty_speed((BHTTY *)sp->bh, speed); } else { From 172ab6839f872d1d30db9bf8635a78b624d80e2d Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 6 Jun 2017 22:48:59 +0200 Subject: [PATCH 317/392] Reverted DMA reset to old operation, fixes MCA PS/2's. --- src/dma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dma.c b/src/dma.c index 1e2982adf..96f98bd96 100644 --- a/src/dma.c +++ b/src/dma.c @@ -31,7 +31,7 @@ DMA dma, dma16; void dma_reset(void) { -#if 0 +#if 1 int c; dma.wp = 0; for (c = 0; c < 16; c++) @@ -58,12 +58,13 @@ void dma_reset(void) dma16.cb[c] = 0; } dma16.m = 0; -#endif +#else memset(dmaregs, 0, 16); memset(dma16regs, 0, 16); memset(dmapages, 0, 16); memset(&dma, 0, sizeof(DMA)); memset(&dma16, 0, sizeof(DMA)); +#endif } uint8_t dma_read(uint16_t addr, void *priv) From 112ee420a5fd7d94b8708234c37f6f3a21660999 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 8 Jun 2017 00:01:10 +0200 Subject: [PATCH 318/392] Applied mainline PCem commit that fixed the AWE32 OPL volume; Removed the Award 430VX PCI and all UMC Super I/O chip emulation (that was pure guesswork anyway). --- src/Makefile.mingw | 2 +- src/SOUND/snd_sb.c | 4 +- src/intel_flash.c | 4 ++ src/mem.c | 6 ++ src/model.c | 8 +++ src/nvr.c | 12 ++++ src/um8669f.c | 172 --------------------------------------------- src/um8669f.h | 19 ----- src/um8881f.c | 73 ------------------- src/um8881f.h | 4 -- 10 files changed, 33 insertions(+), 271 deletions(-) delete mode 100644 src/um8669f.c delete mode 100644 src/um8669f.h delete mode 100644 src/um8881f.c delete mode 100644 src/um8881f.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 20374043e..1289db48f 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -148,7 +148,7 @@ SYSOBJ = model.o \ olivetti_m24.o ps1.o ps2.o ps2_mca.o \ tandy_eeprom.o tandy_rom.o DEVOBJ = bugger.o lpt.o serial.o \ - um8669f.o pc87306.o sis85c471.o w83877f.o \ + pc87306.o sis85c471.o w83877f.o \ keyboard.o \ keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ keyboard_amstrad.o keyboard_olim24.o \ diff --git a/src/SOUND/snd_sb.c b/src/SOUND/snd_sb.c index 179a449ee..317d066e2 100644 --- a/src/SOUND/snd_sb.c +++ b/src/SOUND/snd_sb.c @@ -187,8 +187,8 @@ static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p) int c_emu8k = (((c/2) * 44100) / 48000)*2; int32_t out_l, out_r; - out_l = (((int32_t)sb->opl.buffer[c] * (int32_t)mixer->fm_l) >> 16); - out_r = (((int32_t)sb->opl.buffer[c + 1] * (int32_t)mixer->fm_r) >> 16); + out_l = ((((sb->opl.buffer[c] * mixer->fm_l) >> 16) * (opl3_type ? 47000 : 51000)) >> 16); + out_r = ((((sb->opl.buffer[c + 1] * mixer->fm_r) >> 16) * (opl3_type ? 47000 : 51000)) >> 16); out_l += ((sb->emu8k.buffer[c_emu8k] * mixer->fm_l) >> 16); out_r += ((sb->emu8k.buffer[c_emu8k + 1] * mixer->fm_l) >> 16); diff --git a/src/intel_flash.c b/src/intel_flash.c index 6ded787ef..cbab0384f 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -179,9 +179,11 @@ void *intel_flash_init(uint8_t type) case ROM_REVENGE: wcscpy(flash_path, L"revenge.bin"); break; +#if 0 case ROM_586MC1: wcscpy(flash_path, L"586mc1.bin"); break; +#endif case ROM_PLATO: wcscpy(flash_path, L"plato.bin"); break; @@ -203,12 +205,14 @@ void *intel_flash_init(uint8_t type) case ROM_ACERM3A: wcscpy(flash_path, L"acerm3a.bin"); break; +#if 0 case ROM_ACERV35N: wcscpy(flash_path, L"acerv35n.bin"); break; case ROM_430VX: wcscpy(flash_path, L"430vx.bin"); break; +#endif case ROM_P55VA: wcscpy(flash_path, L"p55va.bin"); break; diff --git a/src/mem.c b/src/mem.c index 17b564a9e..5fd0cf5a2 100644 --- a/src/mem.c +++ b/src/mem.c @@ -434,6 +434,7 @@ int loadbios() pclog("Load SIS496 %x %x\n", rom[0x1fff0], rom[0xfff0]); return 1; +#if 0 case ROM_430VX: f = romfopen(L"roms/430vx/55XWUQ0E.BIN", L"rb"); if (!f) break; @@ -441,6 +442,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; +#endif case ROM_REVENGE: f = romfopen(L"roms/revenge/1009AF2_.BIO", L"rb"); @@ -650,6 +652,7 @@ int loadbios() pclog("Load R418 %x %x\n", rom[0x1fff0], rom[0xfff0]); return 1; +#if 0 case ROM_586MC1: f = romfopen(L"roms/586mc1/IS.34", L"rb"); if (!f) break; @@ -657,6 +660,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; +#endif case ROM_PLATO: f = romfopen(L"roms/plato/1016AX1_.BIO", L"rb"); @@ -712,6 +716,7 @@ int loadbios() biosmask = 0x1ffff; return 1; +#if 0 case ROM_ACERV35N: f = romfopen(L"roms/acerv35n/V35ND1S1.BIN", L"rb"); if (!f) break; @@ -719,6 +724,7 @@ int loadbios() fclose(f); biosmask = 0x1ffff; return 1; +#endif case ROM_P55VA: f = romfopen(L"roms/p55va/VA021297.BIN", L"rb"); diff --git a/src/model.c b/src/model.c index 9e4dc6b7e..9abbe7e14 100644 --- a/src/model.c +++ b/src/model.c @@ -84,7 +84,9 @@ #include "sound/snd_sn76489.h" #include "tandy_eeprom.h" #include "tandy_rom.h" +#if 0 #include "um8669f.h" +#endif #include "video/vid_pcjr.h" #include "video/vid_tandy.h" #include "w83877f.h" @@ -118,7 +120,9 @@ extern void at_ali1429_init(void); extern void at_headland_init(void); extern void at_opti495_init(void); extern void at_sis496_init(void); +#if 0 extern void at_i430vx_init(void); +#endif extern void at_batman_init(void); extern void at_endeavor_init(void); @@ -226,7 +230,9 @@ MODEL models[] = {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerv35n_init, NULL}, #endif {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2p4_init, NULL}, +#if 0 {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL}, +#endif {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL}, {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55tvp4_init, NULL}, {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i440fx_init, NULL}, @@ -818,6 +824,7 @@ void at_p55t2p4_init(void) device_add(&intel_flash_bxt_device); } +#if 0 void at_i430vx_init(void) { at_ide_init(); @@ -832,6 +839,7 @@ void at_i430vx_init(void) um8669f_init(); device_add(&intel_flash_bxt_device); } +#endif void at_p55tvp4_init(void) { diff --git a/src/nvr.c b/src/nvr.c index 8862ec08f..44a909627 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -240,7 +240,9 @@ void loadnvr(void) case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"rb"); nvrmask = 127; break; case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"rb"); nvrmask = 127; break; case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"rb"); nvrmask = 127; break; +#if 0 case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"rb"); nvrmask = 127; break; +#endif case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"rb"); nvrmask = 127; break; case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"rb"); nvrmask = 127; break; case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"rb"); nvrmask = 127; break; @@ -248,14 +250,18 @@ void loadnvr(void) case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"rb"); nvrmask = 127; break; case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"rb"); nvrmask = 127; break; case ROM_R418: f = nvrfopen(L"r418.nvr", L"rb"); nvrmask = 127; break; +#if 0 case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"rb"); nvrmask = 127; break; +#endif case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"rb"); nvrmask = 127; break; case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"rb"); nvrmask = 127; break; case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"rb"); nvrmask = 127; break; case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"rb"); nvrmask = 127; break; case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"rb"); nvrmask = 127; break; case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"rb"); nvrmask = 127; break; +#if 0 case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"rb"); nvrmask = 127; break; +#endif case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"rb"); nvrmask = 127; break; case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"rb"); nvrmask = 127; break; case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"rb"); nvrmask = 127; break; @@ -325,7 +331,9 @@ void savenvr(void) case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"wb"); break; case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"wb"); break; case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"wb"); break; +#if 0 case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"wb"); break; +#endif case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"wb"); break; case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"wb"); break; case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"wb"); break; @@ -333,14 +341,18 @@ void savenvr(void) case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"wb"); break; case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"wb"); break; case ROM_R418: f = nvrfopen(L"r418.nvr", L"wb"); break; +#if 0 case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"wb"); break; +#endif case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"wb"); break; case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"wb"); break; case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"wb"); break; case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"wb"); break; case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"wb"); break; case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"wb"); break; +#if 0 case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"wb"); break; +#endif case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"wb"); break; case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"wb"); break; case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"wb"); break; diff --git a/src/um8669f.c b/src/um8669f.c deleted file mode 100644 index 964f2613a..000000000 --- a/src/um8669f.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the UMC UM8669F Super I/O Chip. - * - * Version: @(#)um8669f.c 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -/*um8669f : - - aa to 108 unlocks - next 108 write is register select (Cx?) - data read/write to 109 - 55 to 108 locks - - - - -C0 -bit 3 = LPT1 enable -bit 2 = COM2 enable -bit 1 = COM1 enable -bit 0 = FDC enable - -C1 -bits 7-6 = LPT1 mode : 11 = ECP/EPP, 01 = EPP, 10 = SPP -bit 3 = clear when LPT1 = 278 - -Added by OBattler based on more sources: - C2 - bit 2 = I430FX: floppy drive swap (1 = swap, 0 = do not swap) - I430VX: DENSEL polarity - bits 3-6 = IR stuff - bits 3-4 = 00 = Normal, 01 = Infrared (HPSIR), 10 - Amplitude Shift Keyed IR (ASKIR), 11 - Reserved - -C3 -bits 7-6 = LPT1 DMA mode : 11 = ECP/EPP DMA1, 10 = ECP/EPP DMA3, 01 = EPP/SPP, 00 = ECP -bits 5-4 = LPT1 addr : 10 = 278/IRQ5, 01 = 3BC/IRQ7, 00 = 378/IRQ7 - -COM1 : -3f8, IRQ4 - C1 = BF, C3 = 00 -2f8, IRQ3 - C1 = BF, C3 = 03 -3e8, IRQ4 - C1 = BD, C3 = 00 -2e8, IRQ3 - B1 = BD, C3 = 03 - -COM2 : -3f8, IRQ4 - C1 = BF, C3 = 0C -2f8, IRQ3 - C1 = BF, C3 = 00 -3e8, IRQ4 - C1 = BB, C3 = 0C -2e8, IRQ3 - C1 = BB, C3 = 00 - - */ - -#include "ibm.h" - -#include "disc.h" -#include "fdc.h" -#include "fdd.h" -#include "io.h" -#include "lpt.h" -#include "serial.h" -#include "um8669f.h" - -static int um8669f_locked; -static int um8669f_curreg; -static uint8_t um8669f_regs[256]; - -void um8669f_write(uint16_t port, uint8_t val, void *priv) -{ - int temp; - if (um8669f_locked) - { - if (port == 0x108 && val == 0xaa) - um8669f_locked = 0; - } - else - { - if (port == 0x108) - { - if (val == 0x55) - um8669f_locked = 1; - else - um8669f_curreg = val; - } - else - { - um8669f_regs[um8669f_curreg] = val; - - fdc_remove(); - if (um8669f_regs[0xc0] & 1) - fdc_add(); - - if (um8669f_regs[0xc0] & 2) - { - temp = um8669f_regs[0xc3] & 1; /*might be & 2*/ - if (!(um8669f_regs[0xc1] & 2)) - temp |= 2; - switch (temp) - { - case 0: serial_setup(1, 0x3f8, 4); break; - case 1: serial_setup(1, 0x2f8, 4); break; - case 2: serial_setup(1, 0x3e8, 4); break; - case 3: serial_setup(1, 0x2e8, 4); break; - } - } - - if (um8669f_regs[0xc0] & 4) - { - temp = (um8669f_regs[0xc3] & 4) ? 0 : 1; /*might be & 8*/ - if (!(um8669f_regs[0xc1] & 4)) - temp |= 2; - switch (temp) - { - case 0: serial_setup(2, 0x3f8, 3); break; - case 1: serial_setup(2, 0x2f8, 3); break; - case 2: serial_setup(2, 0x3e8, 3); break; - case 3: serial_setup(2, 0x2e8, 3); break; - } - } - - if (um8669f_curreg == 0xC2) - { - /* Make sure to invert this. */ - if (romset == ROM_430VX) - { - fdc_update_densel_polarity(val & 4 ? 0 : 1); - } - else - { - fdd_setswap(val & 4 ? 1 : 0); - } - } - - lpt1_remove(); - lpt2_remove(); - temp = (um8669f_regs[0xc3] >> 4) & 3; - switch (temp) - { - case 0: lpt1_init(0x378); break; - case 1: lpt1_init(0x3bc); break; - case 2: lpt1_init(0x278); break; - } - } - } -} - -uint8_t um8669f_read(uint16_t port, void *priv) -{ - if (um8669f_locked) - return 0xff; - - if (port == 0x108) - return um8669f_curreg; /*???*/ - else - return um8669f_regs[um8669f_curreg]; -} - -void um8669f_init() -{ - io_sethandler(0x0108, 0x0002, um8669f_read, NULL, NULL, um8669f_write, NULL, NULL, NULL); - um8669f_locked = 1; -} diff --git a/src/um8669f.h b/src/um8669f.h deleted file mode 100644 index 92052a151..000000000 --- a/src/um8669f.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the UMC UM8669F Super I/O Chip. - * - * Version: @(#)um8669f.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -extern void um8669f_init(); diff --git a/src/um8881f.c b/src/um8881f.c deleted file mode 100644 index c39c21b11..000000000 --- a/src/um8881f.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -#include "ibm.h" -#include "io.h" -#include "mem.h" -#include "pci.h" - -#include "um8881f.h" - -static uint8_t card_16[256]; -static uint8_t card_18[256]; - -void um8881f_write(int func, int addr, uint8_t val, void *priv) -{ -// pclog("um8881f_write : addr=%02x val=%02x %04x:%04x\n", addr, val, CS, pc); - if (addr == 0x54) - { -/* if ((card_16[0x54] ^ val) & 0x01) - { - if (val & 1) - mem_bios_set_state(0xe0000, 0x10000, 1, 1); - else - mem_bios_set_state(0xe0000, 0x10000, 0, 0); - }*/ - flushmmucache_nopc(); - } - if (addr == 0x55) - { - if ((card_16[0x55] ^ val) & 0xc0) - { -/* switch (val & 0xc0) - { - case 0x00: mem_bios_set_state(0xf0000, 0x10000, 0, 1); break; - case 0x40: mem_bios_set_state(0xf0000, 0x10000, 0, 0); break; - case 0x80: mem_bios_set_state(0xf0000, 0x10000, 1, 1); break; - case 0xc0: mem_bios_set_state(0xf0000, 0x10000, 1, 0); break; - }*/ - shadowbios = val & 0x80; - shadowbios_write = !(val & 0x40); - flushmmucache_nopc(); - } - } - if (addr >= 4) - card_16[addr] = val; -} - -uint8_t um8881f_read(int func, int addr, void *priv) -{ - return card_16[addr]; -} - -void um8886f_write(int func, int addr, uint8_t val, void *priv) -{ - if (addr >= 4) - card_18[addr] = val; -} - -uint8_t um8886f_read(int func, int addr, void *priv) -{ - return card_18[addr]; -} - -void um8881f_init() -{ - pci_add_specific(16, um8881f_read, um8881f_write, NULL); - pci_add_specific(18, um8886f_read, um8886f_write, NULL); - - card_16[0] = card_18[0] = 0x60; /*UMC*/ - card_16[1] = card_18[1] = 0x10; - card_16[2] = 0x81; card_16[3] = 0x88; /*UM8881 Host - PCI bridge*/ - card_18[2] = 0x86; card_18[3] = 0x88; /*UM8886 PCI - ISA bridge*/ -} diff --git a/src/um8881f.h b/src/um8881f.h deleted file mode 100644 index 4ee34640d..000000000 --- a/src/um8881f.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void um8881f_init(); From c1b7fe015daf38980734b71ebb89688dbc95f8c0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 8 Jun 2017 00:58:47 +0200 Subject: [PATCH 319/392] Flash and NVR file names are now generated from the model's internal name; NVR masks are now stored in the model struct; More AX JEGA work, still not hooked anywhere; Fixed a stray wsprintf() in win.c to the correct _swprintf() instead; Loading a configuration file from the menu now causes the status bar to be updated. --- src/VIDEO/vid_ega.c | 32 +++-- src/VIDEO/vid_ega.h | 12 +- src/VIDEO/vid_ega_render.c | 233 ++++++++++++++++++++++++++++++++++++- src/VIDEO/vid_ega_render.h | 4 +- src/WIN/win.c | 3 +- src/intel_flash.c | 82 +++---------- src/model.c | 162 ++++++++++++-------------- src/model.h | 4 +- src/nvr.c | 183 +++++++++-------------------- 9 files changed, 416 insertions(+), 299 deletions(-) diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index 55f46f17e..378db12e8 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA, Chips & Technologies SuperEGA, and * AX JEGA graphics cards. * - * Version: @(#)vid_ega.c 1.0.1 2017/06/01 + * Version: @(#)vid_ega.c 1.0.2 2017/06/05 * * Author: Sarah Walker, * Miran Grca, @@ -45,15 +45,8 @@ static int old_overscan_color = 0; int update_overscan = 0; -#define SBCS 0 -#define DBCS 1 -#define ID_LEN 6 -#define NAME_LEN 8 -#define SBCS19_LEN 256 * 19 -#define DBCS16_LEN 65536 * 32 - -uint8_t jfont_sbcs_19[SBCS19_LEN];//256 * 19( * 8) -uint8_t jfont_dbcs_16[DBCS16_LEN];//65536 * 16 * 2 (* 8) +uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ +uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ typedef struct { char id[ID_LEN]; @@ -68,6 +61,16 @@ typedef struct { uint16_t end; } fontxTbl; +static __inline int ega_jega_enabled(ega_t *ega) +{ + if (!ega->is_jega) + { + return 0; + } + + return !(ega->RMOD1 & 0x40); +} + void ega_jega_write_font(ega_t *ega) { unsigned int chr = ega->RDFFB; @@ -529,7 +532,14 @@ void ega_poll(void *p) } else if (!(ega->gdcreg[6] & 1)) { - ega_render_text_standard(ega, drawcursor); + if (ega_jega_enabled(ega)) + { + ega_render_text_jega(ega, drawcursor); + } + else + { + ega_render_text_standard(ega, drawcursor); + } } else { diff --git a/src/VIDEO/vid_ega.h b/src/VIDEO/vid_ega.h index 2fef2c0ca..90ddf17a4 100644 --- a/src/VIDEO/vid_ega.h +++ b/src/VIDEO/vid_ega.h @@ -9,7 +9,7 @@ * Emulation of the EGA, Chips & Technologies SuperEGA, and * AX JEGA graphics cards. * - * Version: @(#)vid_ega.h 1.0.0 2017/05/30 + * Version: @(#)vid_ega.h 1.0.1 2017/06/05 * * Author: Sarah Walker, * Miran Grca, @@ -110,3 +110,13 @@ void ega_init(ega_t *ega); extern device_t ega_device; extern device_t cpqega_device; extern device_t sega_device; + +#define SBCS 0 +#define DBCS 1 +#define ID_LEN 6 +#define NAME_LEN 8 +#define SBCS19_LEN 256 * 19 +#define DBCS16_LEN 65536 * 32 + +extern uint8_t jfont_sbcs_19[SBCS19_LEN]; /* 256 * 19( * 8) */ +extern uint8_t jfont_dbcs_16[DBCS16_LEN]; /* 65536 * 16 * 2 (* 8) */ diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c index f100b3c64..bd4b6a358 100644 --- a/src/VIDEO/vid_ega_render.c +++ b/src/VIDEO/vid_ega_render.c @@ -8,7 +8,7 @@ * * EGA renderers. * - * Version: @(#)vid_ega_render.c 1.0.0 2017/05/30 + * Version: @(#)vid_ega_render.c 1.0.1 2017/06/05 * * Author: Sarah Walker, * Miran Grca, @@ -147,6 +147,237 @@ void ega_render_text_standard(ega_t *ega, int drawcursor) } } +static __inline int is_kanji1(uint8_t chr) +{ + return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); +} + +static __inline int is_kanji2(uint8_t chr) +{ + return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); +} + +void ega_jega_render_blit_text(ega_t *ega, int x, int dl, int start, int width, uint16_t dat, int cw, uint32_t fg, uint32_t bg) +{ + int x_add = (enable_overscan) ? 8 : 0; + + int xx = 0; + int xxx = 0; + + if (ega->seqregs[1] & 8) + { + for (xx = start; xx < (start + width); xx++) + for (xxx = 0; xxx < cw; xxx++) + ((uint32_t *)buffer32->line[dl])[(((x * width) + 32 + (xxx << 1) + ((xx << 1) * cw)) & 2047) + x_add] = + ((uint32_t *)buffer32->line[dl])[(((x * width) + 33 + (xxx << 1) + ((xx << 1) * cw)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } + else + { + for (xx = start; xx < (start + width); xx++) + ((uint32_t *)buffer32->line[dl])[(((x * width) + 32 + xxx + (xx * cw)) & 2047) + x_add] = (dat & (0x80 >> xx)) ? fg : bg; + } +} + +void ega_render_text_jega(ega_t *ega, int drawcursor) +{ + int x_add = (enable_overscan) ? 8 : 0; + int dl = ega_display_line(ega); + uint8_t chr, attr; + uint16_t dat, dat2; + uint32_t charaddr; + int x, xx; + uint32_t fg, bg; + + /* Temporary for DBCS. */ + unsigned int chr_left; + unsigned int bsattr; + int chr_wide = 0; + uint32_t bg_ex = 0; + uint32_t fg_ex = 0; + + int blocks = ega->hdisp; + int fline; + + unsigned int pad_y, exattr; + + if (fullchange) + { + for (x = 0; x < ega->hdisp; x++) + { + drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); + chr = ega->vram[(ega->ma << 1) & ega->vrammask]; + attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; + + if (chr_wide = 0) + { + if (ega->RMOD2 & 0x80) + { + fg_ex = ega->pallook[ega->egapal[attr & 15]]; + + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + bg_ex = ega->pallook[ega->egapal[(attr >> 4) & 7]]; + } + else + { + bg_ex = ega->pallook[ega->egapal[attr >> 4]]; + } + } + else + { + if (attr & 0x40) + { + /* Reversed in JEGA mode */ + bg_ex = ega->pallook[ega->egapal[attr & 15]]; + fg_ex = ega->pallook[0]; + } + else + { + /* Reversed in JEGA mode */ + fg_ex = ega->pallook[ega->egapal[attr & 15]]; + bg_ex = ega->pallook[0]; + } + } + + if (drawcursor) + { + bg = fg_ex; + fg = bg_ex; + } + else + { + fg = fg_ex; + bg = bg_ex; + } + + if (attr & 0x80 && ega->attrregs[0x10] & 8) + { + if (ega->blink & 16) + fg = bg; + } + + /* Stay drawing if the char code is DBCS and not at last column. */ + if (is_kanji1(dat) && (blocks > 1)) + { + /* Set the present char/attr code to the next loop. */ + chr_left = chr; + chr_wide = 1; + } + else + { + /* The char code is ANK (8 dots width). */ + dat = jfont_sbcs_19[chr*19+(ega->sc)]; /* w8xh19 font */ + ega_jega_render_blit_text(ega, x, dl, 0, 8, dat, 1, fg, bg); + if (bsattr & 0x20) + { + /* Vertical line. */ + dat = 0x18; + ega_jega_render_blit_text(ega, x, fline, 0, 8, dat, 1, fg, bg); + } + if (ega->sc == 18 && bsattr & 0x10) + { + /* Underline. */ + dat = 0xff; + ega_jega_render_blit_text(ega, x, fline, 0, 8, dat, 1, fg, bg); + } + chr_wide = 0; + blocks--; + } + } + else + { + /* The char code may be in DBCS. */ + pad_y = ega->RPSSC; + exattr = 0; + + /* Note: The second column should be applied its basic attribute. */ + if (ega->RMOD2 & 0x40) + { + /* If JEGA Extended Attribute is enabled. */ + exattr = attr; + if ((exattr & 0x30) == 0x30) pad_y = ega->RPSSL; /* Set top padding of lower 2x character. */ + else if (exattr & 0x30) pad_y = ega->RPSSU; /* Set top padding of upper 2x character. */ + } + + if (ega->sc >= pad_y && ega->sc < 16 + pad_y) + { + /* Check the char code is in Wide charset of Shift-JIS. */ + if (is_kanji2(chr)) + { + fline = ega->sc - pad_y; + chr_left <<= 8; + /* Fix vertical position. */ + chr |= chr_left; + /* Horizontal wide font (Extended Attribute). */ + if (exattr & 0x20) + { + if (exattr & 0x10) fline = (fline >> 1) + 8; + else fline = fline >> 1; + } + /* Vertical wide font (Extended Attribute). */ + if (exattr & 0x40) + { + dat = jfont_dbcs_16[chr * 32 + fline * 2]; + if (!(exattr & 0x08)) + dat = jfont_dbcs_16[chr * 32 + fline * 2 + 1]; + /* Draw 8 dots. */ + ega_jega_render_blit_text(ega, x, dl, 0, 8, dat, 2, fg, bg); + } + else + { + /* Get the font pattern. */ + dat = jfont_dbcs_16[chr * 32 + fline * 2]; + dat <<= 8; + dat |= jfont_dbcs_16[chr * 32 + fline * 2 + 1]; + /* Bold (Extended Attribute). */ + if (exattr &= 0x80) + { + dat2 = dat; + dat2 >>= 1; + dat |= dat2; + /* Original JEGA colours the last row with the next column's attribute. */ + } + /* Draw 16 dots */ + ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); + } + } + else + { + /* Ignore wide char mode, put blank. */ + dat = 0; + ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); + } + } + else if (ega->sc == (17 + pad_y) && (bsattr & 0x10)) + { + /* Underline. */ + dat = 0xffff; + ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); + } + else + { + /* Draw blank */ + dat = 0; + ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); + } + + if (bsattr & 0x20) + { + /* Vertical line draw at last. */ + dat = 0x0180; + ega_jega_render_blit_text(ega, x, dl, 0, 16, dat, 1, fg, bg); + } + + chr_wide = 0; + blocks -= 2; /* Move by 2 columns. */ + } + + ega->ma += 4; + ega->ma &= ega->vrammask; + } + } +} + void ega_render_2bpp_lowres(ega_t *ega) { int x_add = (enable_overscan) ? 8 : 0; diff --git a/src/VIDEO/vid_ega_render.h b/src/VIDEO/vid_ega_render.h index 0f7805751..b833128a9 100644 --- a/src/VIDEO/vid_ega_render.h +++ b/src/VIDEO/vid_ega_render.h @@ -8,7 +8,7 @@ * * EGA renderers. * - * Version: @(#)vid_ega_render.h 1.0.0 2017/05/30 + * Version: @(#)vid_ega_render.h 1.0.1 2017/06/05 * * Author: Sarah Walker, * Miran Grca, @@ -29,7 +29,7 @@ extern uint8_t edatlookup[4][4]; void ega_render_blank(ega_t *ega); void ega_render_text_standard(ega_t *ega, int drawcursor); -void ega_render_text_jega(ega_t *ega); +void ega_render_text_jega(ega_t *ega, int drawcursor); void ega_render_2bpp_lowres(ega_t *ega); void ega_render_2bpp_highres(ega_t *ega); diff --git a/src/WIN/win.c b/src/WIN/win.c index 5a76bcc94..df1fe3e0f 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -486,7 +486,7 @@ void create_cdrom_submenu(HMENU m, int id) for (i = 0; i < 26; i++) { - wsprintf(s, L"Host CD/DVD Drive (%c:)", i + 0x41); + _swprintf(s, L"Host CD/DVD Drive (%c:)", i + 0x41); if (host_cdrom_drive_available[i]) { AppendMenu(m, MF_STRING, IDM_CDROM_HOST_DRIVE | (i << 3) | id, s); @@ -2026,6 +2026,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM /* pclog_w(L"NVR path: %s\n", nvr_path); */ mem_resize(); loadbios(); + update_status_bar_panes(hwndStatus); resetpchard(); } } diff --git a/src/intel_flash.c b/src/intel_flash.c index cbab0384f..d03e1de94 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -18,8 +18,10 @@ #include #include "ibm.h" +#include "CPU/cpu.h" #include "device.h" #include "mem.h" +#include "model.h" #include "rom.h" #define FLASH_IS_BXB 2 @@ -171,75 +173,23 @@ void *intel_flash_init(uint8_t type) FILE *f; int i; flash_t *flash; + wchar_t *model_name; + wchar_t *flash_name; + flash = malloc(sizeof(flash_t)); memset(flash, 0, sizeof(flash_t)); - switch(romset) - { - case ROM_REVENGE: - wcscpy(flash_path, L"revenge.bin"); - break; -#if 0 - case ROM_586MC1: - wcscpy(flash_path, L"586mc1.bin"); - break; -#endif - case ROM_PLATO: - wcscpy(flash_path, L"plato.bin"); - break; - case ROM_ENDEAVOR: - wcscpy(flash_path, L"endeavor.bin"); - break; - case ROM_MB500N: - wcscpy(flash_path, L"mb500n.bin"); - break; - case ROM_P54TP4XE: - wcscpy(flash_path, L"p54tp4xe.bin"); - break; - case ROM_AP53: - wcscpy(flash_path, L"ap53.bin"); - break; - case ROM_P55T2S: - wcscpy(flash_path, L"p55t2s.bin"); - break; - case ROM_ACERM3A: - wcscpy(flash_path, L"acerm3a.bin"); - break; -#if 0 - case ROM_ACERV35N: - wcscpy(flash_path, L"acerv35n.bin"); - break; - case ROM_430VX: - wcscpy(flash_path, L"430vx.bin"); - break; -#endif - case ROM_P55VA: - wcscpy(flash_path, L"p55va.bin"); - break; - case ROM_P55T2P4: - wcscpy(flash_path, L"p55t2p4.bin"); - break; - case ROM_P55TVP4: - wcscpy(flash_path, L"p55tvp4.bin"); - break; - case ROM_440FX: - wcscpy(flash_path, L"440fx.bin"); - break; - case ROM_THOR: - wcscpy(flash_path, L"thor.bin"); - break; - case ROM_MRTHOR: - wcscpy(flash_path, L"mrthor.bin"); - break; - case ROM_ZAPPA: - wcscpy(flash_path, L"zappa.bin"); - break; - case ROM_S1668: - wcscpy(flash_path, L"tpatx.bin"); - break; - default: - fatal("intel_flash_init on unsupported ROM set %i\n", romset); - } + model_name = (wchar_t *) malloc((strlen(model_get_internal_name_ex(model)) << 1) + 2); + mbstowcs(model_name, model_get_internal_name_ex(model), strlen(model_get_internal_name_ex(model)) + 1); + flash_name = (wchar_t *) malloc((wcslen(model_name) << 1) + 2 + 8); + _swprintf(flash_name, L"%s.bin", model_name); + + wcscpy(flash_path, flash_name); + + free(flash_name); + free(model_name); + + pclog_w(L"Flash path: %s\n", flash_name); flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; flash->invert_high_pin = (type & FLASH_INVERT); diff --git a/src/model.c b/src/model.c index 9abbe7e14..e7bdaef9a 100644 --- a/src/model.c +++ b/src/model.c @@ -119,27 +119,17 @@ extern void at_wd76c10_init(void); extern void at_ali1429_init(void); extern void at_headland_init(void); extern void at_opti495_init(void); -extern void at_sis496_init(void); -#if 0 -extern void at_i430vx_init(void); -#endif extern void at_batman_init(void); extern void at_endeavor_init(void); extern void at_dtk486_init(void); extern void at_r418_init(void); -#if 0 -extern void at_586mc1_init(void); -#endif extern void at_plato_init(void); extern void at_mb500n_init(void); extern void at_p54tp4xe_init(void); extern void at_ap53_init(void); extern void at_p55t2s_init(void); extern void at_acerm3a_init(void); -#if 0 -extern void at_acerv35n_init(void); -#endif extern void at_p55t2p4_init(void); extern void at_p55tvp4_init(void); extern void at_p55va_init(void); @@ -161,83 +151,73 @@ int romset; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_laserxt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, - {"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, ibm_at_init, NULL}, - {"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, - {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_ide_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_scat_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, ps2_m30_286_init, NULL}, - {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, ps2_model_50_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, ps1_m2121_init, NULL}, - {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, ps2_model_55sx_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, deskpro386_init, NULL}, - {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, at_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, at_neat_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_headland_init, NULL}, - {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, ps2_model_80_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, 0, xt_init, NULL}, + {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device}, + {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_laserxt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_laserxt_init, NULL}, + {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device}, + {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device}, + {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL}, + {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, + {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, + {"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, 0, europc_init, NULL}, + {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL}, + {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, + {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, + {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 63, ibm_at_init, NULL}, + {"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, + {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_scat_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, + {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, + {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL}, + {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_headland_init, NULL}, + {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL}, /* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, at_wd76c10_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_opti495_init, NULL}, - {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, ps1_m2133_init, NULL}, - {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_ali1429_init, NULL}, - {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, at_dtk486_init, NULL}, - {"Award SiS 496/497", ROM_SIS496, "sis496", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_sis496_init, NULL}, - {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, at_r418_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_batman_init, NULL}, -#if 0 - {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_586mc1_init, NULL}, -#endif - {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, at_mb500n_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p54tp4xe_init, NULL}, - {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_ap53_init, NULL}, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2s_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerm3a_init, NULL}, -#if 0 - {"Acer V35N", ROM_ACERV35N, "acerv3n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_acerv35n_init, NULL}, -#endif - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55t2p4_init, NULL}, -#if 0 - {"Award 430VX PCI", ROM_430VX, "430vx", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i430vx_init, NULL}, -#endif - {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_p55tvp4_init, NULL}, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_i440fx_init, NULL}, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, at_s1668_init, NULL}, - {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0, 0} + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, + {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, + {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, + {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL}, + {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL}, + {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, + {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, + {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, + {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL}, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL}, + {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0,0, 0} }; @@ -286,6 +266,16 @@ char *model_get_internal_name(void) return models[model].internal_name; } +char *model_get_internal_name_ex(int m) +{ + return models[m].internal_name; +} + +int model_get_nvrmask(int m) +{ + return models[m].nvrmask; +} + int model_get_model_from_internal_name(char *s) { int c = 0; diff --git a/src/model.h b/src/model.h index f483cd1aa..0fc8b6227 100644 --- a/src/model.h +++ b/src/model.h @@ -44,6 +44,7 @@ typedef struct { int flags; int min_ram, max_ram; int ram_granularity; + int nvrmask; void (*init)(void); device_t *device; } MODEL; @@ -62,6 +63,7 @@ extern int model_get_model_from_internal_name(char *s); extern void model_init(void); extern device_t *model_getdevice(int model); extern int model_getromset_ex(int m); - +extern char *model_get_internal_name_ex(int m); +extern int model_get_nvrmask(int m); #endif /*EMU_MODEL_H*/ diff --git a/src/nvr.c b/src/nvr.c index 44a909627..7e9c171b7 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -18,16 +18,22 @@ * Copyright 2016-2017 Mahod. */ #include +#include +#include +#include #include "ibm.h" +#include "CPU/cpu.h" +#include "device.h" #include "io.h" #include "mem.h" +#include "model.h" #include "nvr.h" #include "pic.h" #include "rom.h" #include "timer.h" #include "rtc.h" -int oldromset; +int oldmodel; int nvrmask=63; char nvrram[128]; int nvraddr; @@ -208,71 +214,27 @@ void loadnvr(void) FILE *f; int c; nvrmask=63; - oldromset=romset; - switch (romset) - { - case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"rb"); break; - case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"rb"); break; - case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"rb"); break; - case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"rb"); break; - case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"rb"); break; - case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"rb"); break; - case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"rb"); nvrmask = 127; break; - case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"rb"); nvrmask = 127; break; - case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"rb"); nvrmask = 127; break; - case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"rb"); break; - case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"rb"); break; - case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"rb"); break; - case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"rb"); nvrmask = 127; break; - case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"rb"); break; - case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"rb"); break; - case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"rb"); nvrmask = 127; break; - case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"rb"); nvrmask = 127; break; - case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"rb"); nvrmask = 127; break; - case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"rb"); nvrmask = 127; break; - case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"rb"); nvrmask = 127; break; - case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"rb"); break; - case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"rb"); break; - case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"rb"); nvrmask = 127; break; - case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"rb"); nvrmask = 127; break; - case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"rb"); nvrmask = 127; break; - case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"rb"); nvrmask = 127; break; - case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"rb"); nvrmask = 127; break; - case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"rb"); nvrmask = 127; break; -#if 0 - case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"rb"); nvrmask = 127; break; -#endif - case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"rb"); nvrmask = 127; break; - case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"rb"); nvrmask = 127; break; - case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"rb"); nvrmask = 127; break; - case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"rb"); nvrmask = 127; break; - case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"rb"); nvrmask = 127; break; - case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"rb"); nvrmask = 127; break; - case ROM_R418: f = nvrfopen(L"r418.nvr", L"rb"); nvrmask = 127; break; -#if 0 - case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"rb"); nvrmask = 127; break; -#endif - case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"rb"); nvrmask = 127; break; - case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"rb"); nvrmask = 127; break; - case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"rb"); nvrmask = 127; break; - case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"rb"); nvrmask = 127; break; - case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"rb"); nvrmask = 127; break; - case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"rb"); nvrmask = 127; break; -#if 0 - case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"rb"); nvrmask = 127; break; -#endif - case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"rb"); nvrmask = 127; break; - case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"rb"); nvrmask = 127; break; - case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"rb"); nvrmask = 127; break; - case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"rb"); nvrmask = 127; break; - case ROM_THOR: f = nvrfopen(L"thor.nvr", L"rb"); nvrmask = 127; break; - case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"rb"); nvrmask = 127; break; - case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"rb"); nvrmask = 127; break; - case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"rb"); nvrmask = 127; break; - case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"rb"); nvrmask = 127; break; - default: return; - } + oldmodel = model; + + wchar_t *model_name; + wchar_t *nvr_name; + + model_name = (wchar_t *) malloc((strlen(model_get_internal_name_ex(model)) << 1) + 2); + mbstowcs(model_name, model_get_internal_name_ex(model), strlen(model_get_internal_name_ex(model)) + 1); + nvr_name = (wchar_t *) malloc((wcslen(model_name) << 1) + 2 + 8); + _swprintf(nvr_name, L"%s.nvr", model_name); + + pclog_w(L"Opening NVR file: %s...\n", nvr_name); + + if (model_get_nvrmask(model) != 0) + { + f = nvrfopen(nvr_name, L"rb"); + nvrmask = model_get_nvrmask(model); + } + + free(nvr_name); + free(model_name); + if (!f) { memset(nvrram,0xFF,128); @@ -297,73 +259,34 @@ void loadnvr(void) c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); } + void savenvr(void) { FILE *f; - switch (oldromset) - { - case ROM_PC1512: f = nvrfopen(L"pc1512.nvr", L"wb"); break; - case ROM_PC1640: f = nvrfopen(L"pc1640.nvr", L"wb"); break; - case ROM_PC200: f = nvrfopen(L"pc200.nvr", L"wb"); break; - case ROM_PC2086: f = nvrfopen(L"pc2086.nvr", L"wb"); break; - case ROM_PC3086: f = nvrfopen(L"pc3086.nvr", L"wb"); break; - case ROM_IBMAT: f = nvrfopen(L"at.nvr", L"wb"); break; - case ROM_IBMPS1_2011: f = nvrfopen(L"ibmps1_2011.nvr", L"wb"); break; - case ROM_IBMPS1_2121: f = nvrfopen(L"ibmps1_2121.nvr", L"wb"); break; - case ROM_IBMPS1_2121_ISA: f = nvrfopen(L"ibmps1_2121_isa.nvr", L"wb"); break; - case ROM_IBMPS2_M30_286: f = nvrfopen(L"ibmps2_m30_286.nvr", L"wb"); break; - case ROM_IBMPS2_M50: f = nvrfopen(L"ibmps2_m50.nvr", L"wb"); break; - case ROM_IBMPS2_M55SX: f = nvrfopen(L"ibmps2_m55sx.nvr", L"wb"); break; - case ROM_IBMPS2_M80: f = nvrfopen(L"ibmps2_m80.nvr", L"wb"); break; - case ROM_CMDPC30: f = nvrfopen(L"cmdpc30.nvr", L"wb"); break; - case ROM_PORTABLEII: f = nvrfopen(L"portableii.nvr", L"wb"); break; - case ROM_PORTABLEIII: f = nvrfopen(L"portableiii.nvr", L"wb"); break; - case ROM_AMI286: f = nvrfopen(L"ami286.nvr", L"wb"); break; - case ROM_AWARD286: f = nvrfopen(L"award286.nvr", L"wb"); break; - case ROM_SUPER286TR: f = nvrfopen(L"super286tr.nvr", L"wb"); break; - case ROM_SPC4200P: f = nvrfopen(L"spc4200p.nvr", L"wb"); break; - case ROM_IBMAT386: f = nvrfopen(L"at386.nvr", L"wb"); break; - case ROM_DESKPRO_386: f = nvrfopen(L"deskpro386.nvr", L"wb"); break; - case ROM_PORTABLEIII386: f = nvrfopen(L"portableiii386.nvr", L"wb"); break; - case ROM_MEGAPC: f = nvrfopen(L"megapc.nvr", L"wb"); break; - case ROM_MEGAPCDX: f = nvrfopen(L"megapcdx.nvr", L"wb"); break; - case ROM_AMI386SX: f = nvrfopen(L"ami386.nvr", L"wb"); break; - case ROM_AMI486: f = nvrfopen(L"ami486.nvr", L"wb"); break; - case ROM_WIN486: f = nvrfopen(L"win486.nvr", L"wb"); break; - case ROM_SIS496: f = nvrfopen(L"sis496.nvr", L"wb"); break; -#if 0 - case ROM_430VX: f = nvrfopen(L"430vx.nvr", L"wb"); break; -#endif - case ROM_REVENGE: f = nvrfopen(L"revenge.nvr", L"wb"); break; - case ROM_ENDEAVOR: f = nvrfopen(L"endeavor.nvr", L"wb"); break; - case ROM_DTK386: f = nvrfopen(L"dtk386.nvr", L"wb"); break; - case ROM_MR386DX_OPTI495: f = nvrfopen(L"mr386dx_opti495.nvr", L"wb"); break; - case ROM_AMI386DX_OPTI495: f = nvrfopen(L"ami386dx_opti495.nvr", L"wb"); break; - case ROM_DTK486: f = nvrfopen(L"dtk486.nvr", L"wb"); break; - case ROM_R418: f = nvrfopen(L"r418.nvr", L"wb"); break; -#if 0 - case ROM_586MC1: f = nvrfopen(L"586mc1.nvr", L"wb"); break; -#endif - case ROM_PLATO: f = nvrfopen(L"plato.nvr", L"wb"); break; - case ROM_MB500N: f = nvrfopen(L"mb500n.nvr", L"wb"); break; - case ROM_P54TP4XE: f = nvrfopen(L"p54tp4xe.nvr", L"wb"); break; - case ROM_AP53: f = nvrfopen(L"ap53.nvr", L"wb"); break; - case ROM_P55T2S: f = nvrfopen(L"p55t2s.nvr", L"wb"); break; - case ROM_ACERM3A: f = nvrfopen(L"acerm3a.nvr", L"wb"); break; -#if 0 - case ROM_ACERV35N: f = nvrfopen(L"acerv35n.nvr", L"wb"); break; -#endif - case ROM_P55VA: f = nvrfopen(L"p55va.nvr", L"wb"); break; - case ROM_P55T2P4: f = nvrfopen(L"p55t2p4.nvr", L"wb"); break; - case ROM_P55TVP4: f = nvrfopen(L"p55tvp4.nvr", L"wb"); break; - case ROM_440FX: f = nvrfopen(L"440fx.nvr", L"wb"); break; - case ROM_THOR: f = nvrfopen(L"thor.nvr", L"wb"); break; - case ROM_MRTHOR: f = nvrfopen(L"mrthor.nvr", L"wb"); break; - case ROM_ZAPPA: f = nvrfopen(L"zappa.nvr", L"wb"); break; - case ROM_S1668: f = nvrfopen(L"tpatx.nvr", L"wb"); break; - case ROM_IBMPS1_2133: f = nvrfopen(L"ibmps1_2133.nvr", L"wb"); break; - default: return; - } + + wchar_t *model_name; + wchar_t *nvr_name; + + model_name = (wchar_t *) malloc((strlen(model_get_internal_name_ex(oldmodel)) << 1) + 2); + mbstowcs(model_name, model_get_internal_name_ex(oldmodel), strlen(model_get_internal_name_ex(oldmodel)) + 1); + nvr_name = (wchar_t *) malloc((wcslen(model_name) << 1) + 2 + 8); + _swprintf(nvr_name, L"%s.nvr", model_name); + + pclog_w(L"Saving NVR file: %s...\n", nvr_name); + + if (model_get_nvrmask(oldmodel) != 0) + { + f = nvrfopen(nvr_name, L"wb"); + } + + free(nvr_name); + free(model_name); + + if (!f) + { + return; + } + fwrite(nvrram,128,1,f); fclose(f); } From 987f7d4619b218287be237acf73acfb448043246 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 8 Jun 2017 01:13:18 +0200 Subject: [PATCH 320/392] Fixed inverted left-right button clicks in the Mouse Systems Mouse emulation. --- src/mouse_serial.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 6a2c9ef34..bb855ecc0 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -150,11 +150,14 @@ mssystems_mouse_poll(int x, int y, int z, int b, void *priv) if (x<-128) x = -128; if (y<-128) y = -128; - data[0] = 0x80 | ((((b & 0x04) >> 1) + ((b & 0x02) << 1) + (b & 0x01)) ^ 0x07); + data[0] = 0x80; + data[0] |= (b & 0x01 ? 0x00 : 0x04); /*Left button*/ + data[0] |= (b & 0x02 ? 0x00 : 0x01); /*Middle button*/ + data[0] |= (b & 0x04 ? 0x00 : 0x02); /*Right button*/ data[1] = x; data[2] = y; - data[3] = 0; - data[4] = 0; + data[3] = x;/*Same as byte 1*/ + data[4] = y;/*Same as byte 2*/ pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); From de9d14ede05c0cb277f273aee0fb250daeafa485 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 8 Jun 2017 01:52:23 +0200 Subject: [PATCH 321/392] The NVR read and save functions now do more sanity checks and properly initialize the file pointer to NULL on start, fixes the crash on machines without a NVR file. --- src/config.c | 90 ++++++++++++++++++++++++++-------------------------- src/nvr.c | 16 +++++++--- 2 files changed, 57 insertions(+), 49 deletions(-) diff --git a/src/config.c b/src/config.c index 0b4dbce53..912c4aaac 100644 --- a/src/config.c +++ b/src/config.c @@ -773,7 +773,6 @@ static void loadconfig_general(void) { char *cat = "General"; char temps[512]; - wchar_t *wp; char *p; vid_resize = !!config_get_int(cat, "vid_resize", 0); @@ -824,6 +823,42 @@ static void loadconfig_general(void) window_w = window_h = window_x = window_y = 0; } +#ifndef __unix + /* Currently, 86Box is English (US) only, but in the future (version 1.30 at the earliest) other languages will be added, + therefore it is better to future-proof the code. */ + dwLanguage = config_get_hex16(cat, "language", 0x0409); +#endif +} + + +/* Machine */ +static void loadconfig_machine(void) +{ + char *cat = "Machine"; + wchar_t *wp; + char *p; + + p = config_get_string(cat, "model", NULL); + if (p != NULL) + model = model_get_model_from_internal_name(p); + else + model = 0; + if (model >= model_count()) + model = model_count() - 1; + + romset = model_getromset(); + cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); + cpu = config_get_int(cat, "cpu", 0); + cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); + + mem_size = config_get_int(cat, "mem_size", 4096); + if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + if (mem_size > 262144) + { + mem_size = 262144; + } + if (read_nvr_path != NULL) { free(read_nvr_path); @@ -857,41 +892,6 @@ static void loadconfig_general(void) path_len = wcslen(nvr_path); -#ifndef __unix - /* Currently, 86Box is English (US) only, but in the future (version 1.30 at the earliest) other languages will be added, - therefore it is better to future-proof the code. */ - dwLanguage = config_get_hex16(cat, "language", 0x0409); -#endif -} - - -/* Machine */ -static void loadconfig_machine(void) -{ - char *cat = "Machine"; - char *p; - - p = config_get_string(cat, "model", NULL); - if (p != NULL) - model = model_get_model_from_internal_name(p); - else - model = 0; - if (model >= model_count()) - model = model_count() - 1; - - romset = model_getromset(); - cpu_manufacturer = config_get_int(cat, "cpu_manufacturer", 0); - cpu = config_get_int(cat, "cpu", 0); - cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); - - mem_size = config_get_int(cat, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - if (mem_size > 262144) - { - mem_size = 262144; - } - cpu_use_dynarec = !!config_get_int(cat, "cpu_use_dynarec", 0); enable_external_fpu = !!config_get_int(cat, "cpu_enable_fpu", 0); @@ -1793,15 +1793,6 @@ static void saveconfig_general(void) config_delete_var(cat, "window_coordinates"); } - if (read_nvr_path == NULL) - { - config_delete_var(cat, "nvr_path"); - } - else - { - config_set_wstring(cat, "nvr_path", nvr_path); - } - #ifndef __unix if (dwLanguage == 0x0409) { @@ -1860,6 +1851,15 @@ static void saveconfig_machine(void) config_set_int(cat, "mem_size", mem_size); } + if (read_nvr_path == NULL) + { + config_delete_var(cat, "nvr_path"); + } + else + { + config_set_wstring(cat, "nvr_path", nvr_path); + } + config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); if (enable_external_fpu == 0) diff --git a/src/nvr.c b/src/nvr.c index 7e9c171b7..eacb4d664 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -211,7 +211,7 @@ uint8_t readnvr(uint16_t addr, void *priv) void loadnvr(void) { - FILE *f; + FILE *f = NULL; int c; nvrmask=63; oldmodel = model; @@ -235,8 +235,12 @@ void loadnvr(void) free(nvr_name); free(model_name); - if (!f) + if (!f || (model_get_nvrmask(model) == 0)) { + if (f) + { + fclose(f); + } memset(nvrram,0xFF,128); if (!enable_sync) { @@ -262,7 +266,7 @@ void loadnvr(void) void savenvr(void) { - FILE *f; + FILE *f = NULL; wchar_t *model_name; wchar_t *nvr_name; @@ -282,8 +286,12 @@ void savenvr(void) free(nvr_name); free(model_name); - if (!f) + if (!f || (model_get_nvrmask(oldmodel) == 0)) { + if (f) + { + fclose(f); + } return; } From cdd855d258fd287f9f659147f8c5d52a3a4748a5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 8 Jun 2017 20:58:32 +0200 Subject: [PATCH 322/392] Floppies and CD-ROM's are now reloaded on new config load. --- src/WIN/win.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/WIN/win.c b/src/WIN/win.c index df1fe3e0f..4da18a9cc 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1794,6 +1794,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { HMENU hmenu; RECT rect; + int i = 0; switch (message) { @@ -2022,7 +2023,53 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if (msgbox_reset_yn(ghwnd) == IDYES) { config_save(config_file_default); + for (i = 0; i < FDD_NUM; i++) + { + disc_close(i); + } + for (i = 0; i < CDROM_NUM; i++) + { + cdrom_drives[i].handler->exit(i); + if (cdrom_drives[i].host_drive == 200) + { + image_close(i); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_close(i); + } + else + { + null_close(i); + } + } loadconfig(wopenfilestring); + for (i = 0; i < CDROM_NUM; i++) + { + if (cdrom_drives[i].bus_type) + { + SCSIReset(cdrom_drives[i].scsi_device_id, cdrom_drives[i].scsi_device_lun); + } + + if (cdrom_drives[i].host_drive == 200) + { + image_open(i, cdrom_image[i].image_path); + } + else if ((cdrom_drives[i].host_drive >= 'A') && (cdrom_drives[i].host_drive <= 'Z')) + { + ioctl_open(i, cdrom_drives[i].host_drive); + } + else + { + cdrom_null_open(i, cdrom_drives[i].host_drive); + } + } + + disc_load(0, discfns[0]); + disc_load(1, discfns[1]); + disc_load(2, discfns[2]); + disc_load(3, discfns[3]); + /* pclog_w(L"NVR path: %s\n", nvr_path); */ mem_resize(); loadbios(); From eda2a004fdd0c9794af03266655f81ac187e8240 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 8 Jun 2017 23:49:08 -0400 Subject: [PATCH 323/392] meh --- src/WIN/win.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 4da18a9cc..79080427d 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -240,12 +240,12 @@ void updatewindowsize(int x, int y) } } -void uws_natural() +void uws_natural(void) { updatewindowsize(unscaled_size_x, efwinsizey); } -void releasemouse() +void releasemouse(void) { if (mousecapture) { @@ -255,17 +255,17 @@ void releasemouse() } } -void startblit() +void startblit(void) { WaitForSingleObject(ghMutex, INFINITE); } -void endblit() +void endblit(void) { ReleaseMutex(ghMutex); } -void leave_fullscreen() +void leave_fullscreen(void) { leave_fullscreen_flag = 1; } @@ -362,7 +362,7 @@ void thread_sleep(int t) Sleep(t); } -event_t *thread_create_event() +event_t *thread_create_event(void) { win_event_t *event = malloc(sizeof(win_event_t)); @@ -537,14 +537,14 @@ void set_window_title(WCHAR *s) SetWindowText(ghwnd, s); } -uint64_t timer_read() +uint64_t timer_read(void) { LARGE_INTEGER qpc_time; QueryPerformanceCounter(&qpc_time); return qpc_time.QuadPart; } -static void process_command_line() +static void process_command_line(void) { WCHAR *cmdline; int argc_max; @@ -957,7 +957,7 @@ void status_settext(char *str) status_settextw(cwstr); } -void destroy_menu_handles() +void destroy_menu_handles(void) { int i = 0; @@ -974,7 +974,7 @@ void destroy_menu_handles() free(sb_menu_handles); } -void destroy_tips() +void destroy_tips(void) { int i = 0; @@ -1344,7 +1344,7 @@ HWND EmulatorStatusBar(HWND hwndParent, int idStatus, HINSTANCE hinst) return hwndStatus; } -void win_menu_update() +void win_menu_update(void) { #if 0 menu = LoadMenu(hThisInstance, TEXT("MainMenu")); From 760b4f89ae1c72ccbf958438b92025b749f57f26 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 17:40:34 +0200 Subject: [PATCH 324/392] Fixed SVGA 15bpp and 16bpp low resolution renderers; IDE WIN_DRIVE_DIAGNOSTICS fix per patch by greatpsycho; The two Laser XT boards now allow using up to 1152 kB RAM per report from greatpsycho. --- src/VIDEO/vid_svga_render.c | 116 ++++++++++++++++++++++++++++++------ src/VIDEO/vid_svga_render.h | 2 + src/ide.c | 27 +++++---- src/model.c | 4 +- 4 files changed, 119 insertions(+), 30 deletions(-) diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index 0d09326e7..c942cf6ab 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -691,22 +691,36 @@ void svga_render_15bpp_lowres(svga_t *svga) int x; int offset = (8 - (svga->scrollcache & 6)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; - + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) + + for (x = 0; x <= svga->hdisp; x += 16) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1), svga)]); - + uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x, svga)]); p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 1] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 2] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 3] = svga_color_transform(video_15to32[dat >> 16]); + + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x + 4, svga)]); + p[x + 4] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 5] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 6] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 7] = svga_color_transform(video_15to32[dat >> 16]); - dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 4, svga)]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x + 8, svga)]); + p[x + 8] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 9] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 10] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 11] = svga_color_transform(video_15to32[dat >> 16]); - p[x] = svga_color_transform(video_15to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_15to32[dat >> 16]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x + 12, svga)]); + p[x + 12] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 13] = svga_color_transform(video_15to32[dat & 0xffff]); + p[x + 14] = svga_color_transform(video_15to32[dat >> 16]); + p[x + 15] = svga_color_transform(video_15to32[dat >> 16]); } svga->ma += x << 1; svga->ma = svga_mask_addr(svga->ma, svga); @@ -763,22 +777,36 @@ void svga_render_16bpp_lowres(svga_t *svga) int x; int offset = (8 - (svga->scrollcache & 6)) + 24; uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; - + if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - - for (x = 0; x <= svga->hdisp; x += 4) + + for (x = 0; x <= svga->hdisp; x += 16) { - uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1), svga)]); - + uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x, svga)]); p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 1] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 2] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 3] = svga_color_transform(video_16to32[dat >> 16]); + + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x + 4, svga)]); + p[x + 4] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 5] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 6] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 7] = svga_color_transform(video_16to32[dat >> 16]); - dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 1) + 4, svga)]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x + 8, svga)]); + p[x + 8] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 9] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 10] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 11] = svga_color_transform(video_16to32[dat >> 16]); - p[x] = svga_color_transform(video_16to32[dat & 0xffff]); - p[x + 1] = svga_color_transform(video_16to32[dat >> 16]); + dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + x + 12, svga)]); + p[x + 12] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 13] = svga_color_transform(video_16to32[dat & 0xffff]); + p[x + 14] = svga_color_transform(video_16to32[dat >> 16]); + p[x + 15] = svga_color_transform(video_16to32[dat >> 16]); } svga->ma += x << 1; svga->ma = svga_mask_addr(svga->ma, svga); @@ -940,6 +968,32 @@ void svga_render_32bpp_highres(svga_t *svga) } } +void svga_render_ABGR8888_lowres(svga_t *svga) +{ + int y_add = (enable_overscan) ? 16 : 0; + int x_add = y_add >> 1; + int dl = svga_display_line(svga); + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2, svga)] || svga->fullchange) + { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 2), svga)]); + p[x << 1] = p[(x << 1) + 1] = svga_color_transform(((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16)); + } + svga->ma += 4; + svga->ma = svga_mask_addr(svga->ma, svga); + } +} + void svga_render_ABGR8888_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; @@ -966,6 +1020,32 @@ void svga_render_ABGR8888_highres(svga_t *svga) } } +void svga_render_RGBA8888_lowres(svga_t *svga) +{ + int y_add = (enable_overscan) ? 16 : 0; + int x_add = y_add >> 1; + int dl = svga_display_line(svga); + + if (svga->changedvram[svga->ma >> 12] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 1, svga)] || svga->changedvram[svga_mask_changedaddr((svga->ma >> 12) + 2, svga)] || svga->fullchange) + { + int x; + int offset = (8 - ((svga->scrollcache & 6) >> 1)) + 24; + uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; + + if (svga->firstline_draw == 2000) + svga->firstline_draw = svga->displine; + svga->lastline_draw = svga->displine; + + for (x = 0; x <= svga->hdisp; x++) + { + uint32_t dat = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma + (x << 2), svga)]); + p[x << 1] = p[(x << 1) + 1] = svga_color_transform(dat >> 8); + } + svga->ma += 4; + svga->ma = svga_mask_addr(svga->ma, svga); + } +} + void svga_render_RGBA8888_highres(svga_t *svga) { int y_add = (enable_overscan) ? 16 : 0; diff --git a/src/VIDEO/vid_svga_render.h b/src/VIDEO/vid_svga_render.h index eb3715fdd..cfad3585d 100644 --- a/src/VIDEO/vid_svga_render.h +++ b/src/VIDEO/vid_svga_render.h @@ -47,7 +47,9 @@ void svga_render_24bpp_lowres(svga_t *svga); void svga_render_24bpp_highres(svga_t *svga); void svga_render_32bpp_lowres(svga_t *svga); void svga_render_32bpp_highres(svga_t *svga); +void svga_render_ABGR8888_lowres(svga_t *svga); void svga_render_ABGR8888_highres(svga_t *svga); +void svga_render_RGBA8888_lowres(svga_t *svga); void svga_render_RGBA8888_highres(svga_t *svga); extern void (*svga_render)(svga_t *svga); diff --git a/src/ide.c b/src/ide.c index 87822a628..d92ce13be 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1252,21 +1252,28 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SETIDLE1: /* Idle */ case WIN_CHECKPOWERMODE1: case WIN_SLEEP1: - if (ide_drive_is_cdrom(ide)) + if (val == WIN_DRIVE_DIAGNOSTICS) { - cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + callbackide(ide_board); } else { - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } + timer_process(); + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = ((val == WIN_DRIVE_DIAGNOSTICS) ? 200 : 30) * IDE_TIME; + } + idecallback[ide_board] = ((val == WIN_DRIVE_DIAGNOSTICS) ? 200 : 30) * IDE_TIME; + timer_update_outstanding(); } - timer_process(); - if (ide_drive_is_cdrom(ide)) - { - cdrom[atapi_cdrom_drives[ide->channel]].callback = 30*IDE_TIME; - } - idecallback[ide_board]=30*IDE_TIME; - timer_update_outstanding(); return; case WIN_IDENTIFY: /* Identify Device */ diff --git a/src/model.c b/src/model.c index e7bdaef9a..b45b89efc 100644 --- a/src/model.c +++ b/src/model.c @@ -158,8 +158,8 @@ MODEL models[] = {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_laserxt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_laserxt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device}, From d7917f91ecd54da7463d1a452c55deaa0745a3ee Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 18:07:03 +0200 Subject: [PATCH 325/392] Moved the endblit();'s around a bit in win.c, hopefully that will stabilize Direct3D 9 a bit. --- src/WIN/win.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 79080427d..0789ce82c 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1877,12 +1877,12 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_VID_D3D: startblit(); video_wait_for_blit(); + endblit(); CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); vid_apis[0][vid_api].close(); vid_api = LOWORD(wParam) - IDM_VID_DDRAW; CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); vid_apis[0][vid_api].init(hwndRender); - endblit(); saveconfig(); device_force_redraw(); break; @@ -1898,13 +1898,13 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM startblit(); video_wait_for_blit(); + endblit(); mouse_close(); vid_apis[0][vid_api].close(); video_fullscreen = 1; vid_apis[1][vid_api].init(ghwnd); mouse_init(); leave_fullscreen_flag = 0; - endblit(); saveconfig(); device_force_redraw(); } From c445d970be04a68faf2212eb1e5bc0738cadead2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 18:16:02 +0200 Subject: [PATCH 326/392] The emulation is now paused when the window is being resized or when the renderer is changed or when switching to/from full screen. --- src/WIN/win.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 0789ce82c..6283e2d6c 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1875,6 +1875,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_VID_DDRAW: case IDM_VID_D3D: + pause = 1; startblit(); video_wait_for_blit(); endblit(); @@ -1885,6 +1886,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM vid_apis[0][vid_api].init(hwndRender); saveconfig(); device_force_redraw(); + pause = 0; break; case IDM_VID_FULLSCREEN: @@ -1896,6 +1898,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM msgbox_info(ghwnd, IDS_2193); } + pause = 1; startblit(); video_wait_for_blit(); endblit(); @@ -1907,6 +1910,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM leave_fullscreen_flag = 0; saveconfig(); device_force_redraw(); + pause = 0; } break; @@ -2156,17 +2160,19 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM winsizex = (lParam & 0xFFFF); winsizey = (lParam >> 16) - (17 + 6); + pause = 1; MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); if (vid_apis[video_fullscreen][vid_api].resize) { startblit(); video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); endblit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); } MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); + pause = 0; if (mousecapture) { From 7b1a96302ee74afda998acc9c391464851c66558 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 18:58:36 +0200 Subject: [PATCH 327/392] If win_doresize is set to 1, the WM_SIZE message handler only handles the status bar's size and does not resize the window again, reduces excess window resizes. --- src/WIN/win.c | 6 ++++++ src/WIN/win_ddraw.cc | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 6283e2d6c..8e3c2da57 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -2157,6 +2157,12 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_SIZE: + if (win_doresize) + { + MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); + break; + } + winsizex = (lParam & 0xFFFF); winsizey = (lParam >> 16) - (17 + 6); diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc index dc111bab1..39eeaca9a 100644 --- a/src/WIN/win_ddraw.cc +++ b/src/WIN/win_ddraw.cc @@ -125,9 +125,8 @@ static void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { RECT r_src; RECT r_dest; - int xx, yy; + int yy; POINT po; - uint32_t *p; HRESULT hr; // pclog("Blit memtoscreen %i,%i %i %i %i,%i\n", x, y, y1, y2, w, h); From c4a6f8dbf45f9f38a32c78961c81185a04b4f481 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 19:21:41 +0200 Subject: [PATCH 328/392] DirectDraw now attempts fall back to system buffers if initialization has failed, patch from mainline PCem; The WM_SIZE handler no longer resizes the window if the window is not set to resizable. --- src/WIN/win.c | 26 +++++++++++++++----------- src/WIN/win_ddraw.cc | 18 ++++++++++++++++-- src/WIN/win_ddraw_fs.cc | 9 ++++++++- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 8e3c2da57..5064828fd 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -2163,18 +2163,22 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; } - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - - pause = 1; - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) + if (vid_resize) { - startblit(); - video_wait_for_blit(); - endblit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + pause = 1; + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) + { + startblit(); + video_wait_for_blit(); + endblit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + } + } MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); diff --git a/src/WIN/win_ddraw.cc b/src/WIN/win_ddraw.cc index 39eeaca9a..e87265f87 100644 --- a/src/WIN/win_ddraw.cc +++ b/src/WIN/win_ddraw.cc @@ -65,7 +65,14 @@ int ddraw_init(HWND h) ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) - return 0; + { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) + fatal("CreateSurface back failed\n"); + } memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); @@ -75,7 +82,14 @@ int ddraw_init(HWND h) ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) - return 0; + { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back2, NULL))) + fatal("CreateSurface back failed\n"); + } if (FAILED(lpdd7->CreateClipper(0, &lpdd_clipper, NULL))) return 0; diff --git a/src/WIN/win_ddraw_fs.cc b/src/WIN/win_ddraw_fs.cc index f29524d64..abb390093 100644 --- a/src/WIN/win_ddraw_fs.cc +++ b/src/WIN/win_ddraw_fs.cc @@ -78,7 +78,14 @@ int ddraw_fs_init(HWND h) ddsd.dwHeight = 2048; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) - return 0; + { + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.dwWidth = 2048; + ddsd.dwHeight = 2048; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; + if (FAILED(lpdd7->CreateSurface(&ddsd, &lpdds_back, NULL))) + return 0; + } pclog("DDRAW_INIT complete\n"); ddraw_hwnd = h; From 9caaa19daf863776b1ecac52ae287d3db7bf21fd Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 20:02:40 +0200 Subject: [PATCH 329/392] More tweaks to window resize handling. --- src/WIN/win.c | 89 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 5064828fd..187374fb5 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -155,6 +155,8 @@ static int sb_parts = 0; static int sb_ready = 0; +void win_resize(void); + void updatewindowsize(int x, int y) { int owsx = winsizex; @@ -232,11 +234,8 @@ void updatewindowsize(int x, int y) if ((owsx != winsizex) || (owsy != winsizey)) { - win_doresize = 1; - } - else - { - win_doresize = 0; + win_doresize = 1; + win_resize(); } } @@ -270,6 +269,46 @@ void leave_fullscreen(void) leave_fullscreen_flag = 1; } +void win_resize(void) +{ + RECT r; + int sb_borders[3]; + + if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) + { + startblit(); + video_wait_for_blit(); + SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); + GetWindowRect(ghwnd, &r); + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + GetWindowRect(hwndRender, &r); + MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), winsizex, 17, TRUE); + GetWindowRect(ghwnd, &r); + + MoveWindow(ghwnd, r.left, r.top, + winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), + winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, + TRUE); + + GetWindowRect(ghwnd, &r); + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) + { + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + } + + if (mousecapture) + { + GetWindowRect(hwndRender, &r); + ClipCursor(&r); + } + + endblit(); + win_doresize = 0; + } +} + void mainthread(LPVOID param) { int frames = 0; @@ -311,6 +350,7 @@ void mainthread(LPVOID param) else Sleep(1); +#if 0 if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) { video_wait_for_blit(); @@ -326,6 +366,14 @@ void mainthread(LPVOID param) winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, TRUE); + if (vid_apis[video_fullscreen][vid_api].resize) + { + startblit(); + video_wait_for_blit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + endblit(); + } + if (mousecapture) { GetWindowRect(hwndRender, &r); @@ -334,6 +382,7 @@ void mainthread(LPVOID param) win_doresize = 0; } +#endif if (leave_fullscreen_flag) { @@ -1878,12 +1927,12 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM pause = 1; startblit(); video_wait_for_blit(); - endblit(); CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); vid_apis[0][vid_api].close(); vid_api = LOWORD(wParam) - IDM_VID_DDRAW; CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED); vid_apis[0][vid_api].init(hwndRender); + endblit(); saveconfig(); device_force_redraw(); pause = 0; @@ -1901,11 +1950,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM pause = 1; startblit(); video_wait_for_blit(); - endblit(); mouse_close(); vid_apis[0][vid_api].close(); video_fullscreen = 1; vid_apis[1][vid_api].init(ghwnd); + endblit(); mouse_init(); leave_fullscreen_flag = 0; saveconfig(); @@ -2163,26 +2212,20 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; } - if (vid_resize) + winsizex = (lParam & 0xFFFF); + winsizey = (lParam >> 16) - (17 + 6); + + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); + + if (vid_apis[video_fullscreen][vid_api].resize) { - winsizex = (lParam & 0xFFFF); - winsizey = (lParam >> 16) - (17 + 6); - - pause = 1; - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) - { - startblit(); - video_wait_for_blit(); - endblit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - } - + startblit(); + video_wait_for_blit(); + vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); + endblit(); } MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); - pause = 0; if (mousecapture) { From 6588797139526def51155d09fad0971d274b6f7b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 20:49:53 +0200 Subject: [PATCH 330/392] The Direct3D 9 render is now actually identical to mainline PCem's; Reverted the win.c changes of earlier today. --- src/WIN/win.c | 56 +++++-------------------------------------- src/WIN/win_d3d.cc | 50 ++++++++++++++++++++++++++++---------- src/WIN/win_d3d_fs.cc | 51 +++++++++++++++++++++++++++------------ 3 files changed, 80 insertions(+), 77 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 187374fb5..cf674db48 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -155,8 +155,6 @@ static int sb_parts = 0; static int sb_ready = 0; -void win_resize(void); - void updatewindowsize(int x, int y) { int owsx = winsizex; @@ -235,7 +233,10 @@ void updatewindowsize(int x, int y) if ((owsx != winsizex) || (owsy != winsizey)) { win_doresize = 1; - win_resize(); + } + else + { + win_doresize = 0; } } @@ -269,46 +270,6 @@ void leave_fullscreen(void) leave_fullscreen_flag = 1; } -void win_resize(void) -{ - RECT r; - int sb_borders[3]; - - if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) - { - startblit(); - video_wait_for_blit(); - SendMessage(hwndStatus, SB_GETBORDERS, 0, (LPARAM) sb_borders); - GetWindowRect(ghwnd, &r); - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); - GetWindowRect(hwndRender, &r); - MoveWindow(hwndStatus, 0, r.bottom + GetSystemMetrics(SM_CYEDGE), winsizex, 17, TRUE); - GetWindowRect(ghwnd, &r); - - MoveWindow(ghwnd, r.left, r.top, - winsizex + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, - TRUE); - - GetWindowRect(ghwnd, &r); - MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); - - if (vid_apis[video_fullscreen][vid_api].resize) - { - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - } - - if (mousecapture) - { - GetWindowRect(hwndRender, &r); - ClipCursor(&r); - } - - endblit(); - win_doresize = 0; - } -} - void mainthread(LPVOID param) { int frames = 0; @@ -350,7 +311,6 @@ void mainthread(LPVOID param) else Sleep(1); -#if 0 if (!video_fullscreen && win_doresize && (winsizex > 0) && (winsizey > 0)) { video_wait_for_blit(); @@ -382,7 +342,6 @@ void mainthread(LPVOID param) win_doresize = 0; } -#endif if (leave_fullscreen_flag) { @@ -2206,11 +2165,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_SIZE: - if (win_doresize) - { - MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); - break; - } + MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); + break; winsizex = (lParam & 0xFFFF); winsizey = (lParam >> 16) - (17 + 6); diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index f090465b3..1f4904405 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -45,18 +45,27 @@ static HWND d3d_hwnd; struct CUSTOMVERTEX { FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag + DWORD color; FLOAT tu, tv; }; static CUSTOMVERTEX d3d_verts[] = { - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f} }; int d3d_init(HWND h) @@ -120,6 +129,7 @@ void d3d_close_objects(void) void d3d_init_objects(void) { D3DLOCKED_RECT dr; + int y; RECT r; d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), @@ -131,17 +141,17 @@ void d3d_init_objects(void) d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - // r.top = r.left = 0; + r.top = r.left = 0; r.bottom = r.right = 2047; if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - /* for (y = 0; y < 2048; y++) + for (y = 0; y < 2048; y++) { - uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); + uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (y * dr.Pitch)); memset(p, 0, 2048 * 4); - } */ + } d3dTexture->UnlockRect(0); @@ -245,7 +255,7 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) fatal("LockRect failed\n"); for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); video_blit_complete(); d3dTexture->UnlockRect(0); @@ -257,12 +267,20 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; GetClientRect(d3d_hwnd, &r); d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right - r.left) - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right - r.left) - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; if (hr == D3D_OK) hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer @@ -329,7 +347,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) for (yy = 0; yy < h; yy++) { - p = (uint32_t *) &((((uint8_t *) dr.pBits)[yy * dr.Pitch])); + uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch)); if ((y + yy) >= 0 && (y + yy) < buffer->h) { for (xx = 0; xx < w; xx++) @@ -347,12 +365,20 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; GetClientRect(d3d_hwnd, &r); d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5; d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right - r.left) - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right - r.left) - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; if (hr == D3D_OK) hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 0f894dc34..5af1b1739 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -51,6 +51,7 @@ static int d3d_fs_w, d3d_fs_h; struct CUSTOMVERTEX { FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag + DWORD color; FLOAT tu, tv; }; @@ -109,13 +110,21 @@ uint32_t pal_lookup[256]; static CUSTOMVERTEX d3d_verts[] = { - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f}, + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, - { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f}, + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f} }; @@ -240,6 +249,7 @@ static void d3d_fs_close_objects(void) static void d3d_fs_init_objects(void) { D3DLOCKED_RECT dr; + int y; RECT r; d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), @@ -251,18 +261,17 @@ static void d3d_fs_init_objects(void) d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL); - // r.top = r.left = 0; - r.bottom = 2047; - r.right = 2047; + r.top = r.left = 0; + r.bottom = r.right = 2047; if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - /* for (y = 0; y < 2048; y++) + for (y = 0; y < 2048; y++) { - uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch)); + uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (y * dr.Pitch)); memset(p, 0, 2048 * 4); - } */ + } d3dTexture->UnlockRect(0); @@ -427,7 +436,7 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) fatal("LockRect failed\n"); for (yy = y1; yy < y2; yy++) - memcpy((uint32_t *) &(((uint8_t *) dr.pBits)[(yy - y1) * dr.Pitch]), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); video_blit_complete(); d3dTexture->UnlockRect(0); @@ -439,6 +448,10 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; GetClientRect(d3d_device_window, &window_rect); d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); @@ -525,10 +538,10 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) fatal("LockRect failed\n"); - + for (yy = 0; yy < h; yy++) { - p = (uint32_t *) &(((uint8_t *) dr.pBits)[yy * dr.Pitch]); + uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch)); if ((y + yy) >= 0 && (y + yy) < buffer->h) { for (xx = 0; xx < w; xx++) @@ -547,6 +560,10 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; GetClientRect(d3d_device_window, &window_rect); d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); @@ -563,6 +580,10 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) d3d_verts[4].y = t; d3d_verts[5].x = r; d3d_verts[5].y = b; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; if (hr == D3D_OK) hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); From cd4eb393f1db138c026d68f0e99f6d9f8dd13b93 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 20:57:34 +0200 Subject: [PATCH 331/392] Properly reverted all the win.c changes now. --- src/WIN/win.c | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index cf674db48..79080427d 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -232,7 +232,7 @@ void updatewindowsize(int x, int y) if ((owsx != winsizex) || (owsy != winsizey)) { - win_doresize = 1; + win_doresize = 1; } else { @@ -326,14 +326,6 @@ void mainthread(LPVOID param) winsizey + (GetSystemMetrics(SM_CYEDGE) * 2) + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 17 + sb_borders[1] + 1, TRUE); - if (vid_apis[video_fullscreen][vid_api].resize) - { - startblit(); - video_wait_for_blit(); - vid_apis[video_fullscreen][vid_api].resize(winsizex, winsizey); - endblit(); - } - if (mousecapture) { GetWindowRect(hwndRender, &r); @@ -1883,7 +1875,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM case IDM_VID_DDRAW: case IDM_VID_D3D: - pause = 1; startblit(); video_wait_for_blit(); CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED); @@ -1894,7 +1885,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM endblit(); saveconfig(); device_force_redraw(); - pause = 0; break; case IDM_VID_FULLSCREEN: @@ -1906,19 +1896,17 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM msgbox_info(ghwnd, IDS_2193); } - pause = 1; startblit(); video_wait_for_blit(); mouse_close(); vid_apis[0][vid_api].close(); video_fullscreen = 1; vid_apis[1][vid_api].init(ghwnd); - endblit(); mouse_init(); leave_fullscreen_flag = 0; + endblit(); saveconfig(); device_force_redraw(); - pause = 0; } break; @@ -2165,9 +2153,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; case WM_SIZE: - MoveWindow(hwndStatus, 0, winsizey + 6, winsizex, 17, TRUE); - break; - winsizex = (lParam & 0xFFFF); winsizey = (lParam >> 16) - (17 + 6); From 5088f5f123bcf3c3467d2ae3856fe15f724bdadf Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 21:10:11 +0200 Subject: [PATCH 332/392] Fixed Direct3D renderer. --- src/WIN/win_d3d.cc | 47 ++++--- src/WIN/win_d3d_fs.cc | 277 +++++++++++++++++++----------------------- 2 files changed, 149 insertions(+), 175 deletions(-) diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index 1f4904405..97953515f 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -70,17 +70,15 @@ static CUSTOMVERTEX d3d_verts[] = int d3d_init(HWND h) { - HRESULT hr; + int c; + int ret; - cgapal_rebuild(); + for (c = 0; c < 256; c++) + pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); d3d_hwnd = h; d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (d3d == NULL) - { - return 0; - } memset(&d3dpp, 0, sizeof(d3dpp)); @@ -98,11 +96,7 @@ int d3d_init(HWND h) d3dpp.BackBufferWidth = 0; d3dpp.BackBufferHeight = 0; - hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); - if (FAILED(hr)) - { - return 0; - } + d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); d3d_init_objects(); @@ -112,7 +106,7 @@ int d3d_init(HWND h) return 1; } -void d3d_close_objects(void) +void d3d_close_objects() { if (d3dTexture) { @@ -126,15 +120,15 @@ void d3d_close_objects(void) } } -void d3d_init_objects(void) +void d3d_init_objects() { D3DLOCKED_RECT dr; int y; RECT r; - d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), 0, - D3DFVF_XYZRHW | D3DFVF_TEX1, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_MANAGED, &v_buffer, NULL); @@ -171,10 +165,12 @@ void d3d_resize(int x, int y) d3d_reset(); } -void d3d_reset(void) +void d3d_reset() { HRESULT hr; - + + if (!d3ddev) + return; memset(&d3dpp, 0, sizeof(d3dpp)); d3dpp.Flags = 0; @@ -206,7 +202,7 @@ void d3d_reset(void) device_force_redraw(); } -void d3d_close(void) +void d3d_close() { if (d3dTexture) { @@ -238,10 +234,10 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) RECT r; int yy; - if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (y1 == y2) || (y1 < 0) || (y1 > 2048) || (y2 < 0) || (y2 > 2048) || (d3dTexture == NULL)) - { + if (y1 == y2) + { video_blit_complete(); - return; /*Nothing to do*/ + return; /*Nothing to do*/ } r.top = y1; @@ -298,7 +294,7 @@ void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) hr = d3ddev->SetTexture(0, d3dTexture); if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); if (hr == D3D_OK) hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); @@ -325,11 +321,10 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) VOID* pVoid; D3DLOCKED_RECT dr; RECT r; - uint32_t *p; int yy, xx; HRESULT hr = D3D_OK; - if ((w <= 0) || (w > 2048) || (h <= 0) || (h > 2048) || (d3dTexture == NULL)) + if (h == 0) { video_blit_complete(); return; /*Nothing to do*/ @@ -344,7 +339,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) { if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) fatal("LockRect failed\n"); - + for (yy = 0; yy < h; yy++) { uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch)); @@ -396,7 +391,7 @@ void d3d_blit_memtoscreen_8(int x, int y, int w, int h) hr = d3ddev->SetTexture(0, d3dTexture); if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); if (hr == D3D_OK) hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); diff --git a/src/WIN/win_d3d_fs.cc b/src/WIN/win_d3d_fs.cc index 5af1b1739..7a84bc77b 100644 --- a/src/WIN/win_d3d_fs.cc +++ b/src/WIN/win_d3d_fs.cc @@ -167,13 +167,14 @@ void cgapal_rebuild(void) int d3d_fs_init(HWND h) { - HRESULT hr; + int c; WCHAR emulator_title[200]; d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); - cgapal_rebuild(); + for (c = 0; c < 256; c++) + pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); d3d_hwnd = h; @@ -195,10 +196,6 @@ int d3d_fs_init(HWND h) ); d3d = Direct3DCreate9(D3D_SDK_VERSION); - if (d3d == NULL) - { - return 0; - } memset(&d3dpp, 0, sizeof(d3dpp)); @@ -216,11 +213,7 @@ int d3d_fs_init(HWND h) d3dpp.BackBufferWidth = d3d_fs_w; d3dpp.BackBufferHeight = d3d_fs_h; - hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); - if (FAILED(hr)) - { - return 0; - } + d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); d3d_fs_init_objects(); @@ -230,8 +223,7 @@ int d3d_fs_init(HWND h) return 1; } - -static void d3d_fs_close_objects(void) +static void d3d_fs_close_objects() { if (d3dTexture) { @@ -245,16 +237,15 @@ static void d3d_fs_close_objects(void) } } - -static void d3d_fs_init_objects(void) +static void d3d_fs_init_objects() { D3DLOCKED_RECT dr; int y; RECT r; - d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX), + d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), 0, - D3DFVF_XYZRHW | D3DFVF_TEX1, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_MANAGED, &v_buffer, NULL); @@ -283,7 +274,6 @@ static void d3d_fs_init_objects(void) d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } - /*void d3d_resize(int x, int y) { HRESULT hr; @@ -294,8 +284,7 @@ static void d3d_fs_init_objects(void) d3d_reset(); }*/ - -void d3d_fs_reset(void) +void d3d_fs_reset() { HRESULT hr; @@ -330,19 +319,9 @@ void d3d_fs_reset(void) device_force_redraw(); } - -void d3d_fs_close(void) +void d3d_fs_close() { - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } + d3d_fs_close_objects(); if (d3ddev) { d3ddev->Release(); @@ -356,7 +335,6 @@ void d3d_fs_close(void) DestroyWindow(d3d_device_window); } - static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h) { int ratio_w, ratio_h; @@ -407,7 +385,6 @@ static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, doubl } } - static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) { HRESULT hr = D3D_OK; @@ -417,10 +394,10 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) int yy; double l, t, r, b; - if ((y1 == y2) || (d3dTexture == NULL)) + if (y1 == y2) { video_blit_complete(); - return; /*Nothing to do*/ + return; /*Nothing to do*/ } if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) @@ -456,118 +433,6 @@ static void d3d_fs_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) GetClientRect(d3d_device_window, &window_rect); d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = r; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = r; - d3d_verts[4].y = t; - d3d_verts[5].x = r; - d3d_verts[5].y = b; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); - if (hr == D3D_OK) - hr = v_buffer->Unlock(); - - if (hr == D3D_OK) - hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) - { - if (hr == D3D_OK) - d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - - if (hr == D3D_OK) - hr = d3ddev->EndScene(); - } - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(ghwnd, WM_RESETD3D, 0, 0); -} - - -static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) -{ - HRESULT hr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT window_rect; - uint32_t *p; - int xx, yy; - double l, t, r, b; - - if (!h || (d3dTexture == NULL)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - if (hr == D3D_OK) - { - RECT lock_rect; - - lock_rect.top = 0; - lock_rect.left = 0; - lock_rect.bottom = 2047; - lock_rect.right = 2047; - - if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) - fatal("LockRect failed\n"); - - for (yy = 0; yy < h; yy++) - { - uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch)); - if ((y + yy) >= 0 && (y + yy) < buffer->h) - { - for (xx = 0; xx < w; xx++) - p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; - } - } - - video_blit_complete(); - - d3dTexture->UnlockRect(0); - } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - GetClientRect(d3d_device_window, &window_rect); - d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); - d3d_verts[0].x = l; d3d_verts[0].y = t; d3d_verts[1].x = r; @@ -604,7 +469,121 @@ static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) hr = d3ddev->SetTexture(0, d3dTexture); if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); + + if (hr == D3D_OK) + hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); + + if (hr == D3D_OK) + hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, NULL); + + if (hr == D3D_OK) + hr = d3ddev->EndScene(); + } + + if (hr == D3D_OK) + hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) + PostMessage(ghwnd, WM_RESETD3D, 0, 0); +} + +static void d3d_fs_blit_memtoscreen_8(int x, int y, int w, int h) +{ + HRESULT hr = D3D_OK; + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT window_rect; + int xx, yy; + double l, t, r, b; + + if (!h) + { + video_blit_complete(); + return; /*Nothing to do*/ + } + + if (hr == D3D_OK) + { + RECT lock_rect; + + lock_rect.top = 0; + lock_rect.left = 0; + lock_rect.bottom = 2047; + lock_rect.right = 2047; + + if (FAILED(d3dTexture->LockRect(0, &dr, &lock_rect, 0))) + fatal("LockRect failed\n"); + + for (yy = 0; yy < h; yy++) + { + uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (yy * dr.Pitch)); + if ((y + yy) >= 0 && (y + yy) < buffer->h) + { + for (xx = 0; xx < w; xx++) + p[xx] = pal_lookup[buffer->line[y + yy][x + xx]]; + } + } + + video_blit_complete(); + + d3dTexture->UnlockRect(0); + } + else + video_blit_complete(); + + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; + d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; + d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; + + GetClientRect(d3d_device_window, &window_rect); + d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); + + d3d_verts[0].x = l; + d3d_verts[0].y = t; + d3d_verts[1].x = r; + d3d_verts[1].y = b; + d3d_verts[2].x = l; + d3d_verts[2].y = b; + d3d_verts[3].x = l; + d3d_verts[3].y = t; + d3d_verts[4].x = r; + d3d_verts[4].y = t; + d3d_verts[5].x = r; + d3d_verts[5].y = b; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); + if (hr == D3D_OK) + hr = v_buffer->Unlock(); + + if (hr == D3D_OK) + hr = d3ddev->BeginScene(); + + if (hr == D3D_OK) + { + if (hr == D3D_OK) + d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, d3dTexture); + + if (hr == D3D_OK) + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); if (hr == D3D_OK) hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); From f56bfa5e62c528e623819d94872c921ffed0b0c9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 11 Jun 2017 23:53:01 +0200 Subject: [PATCH 333/392] The WM_SIZE handler now forces winsizey to a minimum value of 0. --- src/WIN/win.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/WIN/win.c b/src/WIN/win.c index 79080427d..6203d3dfa 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -2156,6 +2156,11 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM winsizex = (lParam & 0xFFFF); winsizey = (lParam >> 16) - (17 + 6); + if (winsizey < 0) + { + winsizey = 0; + } + MoveWindow(hwndRender, 0, 0, winsizex, winsizey, TRUE); if (vid_apis[video_fullscreen][vid_api].resize) From fdb24c330f2efc1db974397debdd1b58afd14cf8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 13 Jun 2017 16:16:36 +0200 Subject: [PATCH 334/392] find_status_bar_part() now uses the sb_parts variable rather than the hardcoded number 12 for the number of array elements to search. --- src/WIN/win.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WIN/win.c b/src/WIN/win.c index 6203d3dfa..06ffc57c3 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -693,7 +693,7 @@ int find_status_bar_part(int tag) return -1; } - for (i = 0; i < 12; i++) + for (i = 0; i < sb_parts; i++) { if (sb_part_meanings[i] == tag) { From 7db0c897a52627e0ff3cc58a94c0963e4a67e749 Mon Sep 17 00:00:00 2001 From: waltje Date: Tue, 13 Jun 2017 13:44:51 -0400 Subject: [PATCH 335/392] Fix for CUE/BIN crash on bad filename, fix for crash-on-exit because of the bad sb_parts count (12 i/o sb_parts.) --- src/WIN/win.c | 4 +- src/cdrom_dosbox.cpp | 2 + src/mouse_prot.txt | 207 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 src/mouse_prot.txt diff --git a/src/WIN/win.c b/src/WIN/win.c index 79080427d..f46b54897 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -8,7 +8,7 @@ * * The Emulator's Windows core. * - * Version: @(#)win.c 1.0.2 2017/06/04 + * Version: @(#)win.c 1.0.3 2017/06/12 * * Authors: Sarah Walker, * Miran Grca, @@ -693,7 +693,7 @@ int find_status_bar_part(int tag) return -1; } - for (i = 0; i < 12; i++) + for (i = 0; i < sb_parts; i++) { if (sb_part_meanings[i] == tag) { diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index be632fd38..7b621a710 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -68,6 +68,7 @@ bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint6 { uint64_t offs = 0; file = fopen64(fn, "rb"); + if (file == NULL) return 0; fseeko64(file, seek, SEEK_SET); offs = fread(buffer, 1, count, file); fclose(file); @@ -79,6 +80,7 @@ uint64_t CDROM_Interface_Image::BinaryFile::getLength() { uint64_t ret = 0; file = fopen64(fn, "rb"); + if (file == NULL) return 0; fseeko64(file, 0, SEEK_END); ret = ftello64(file); fclose(file); diff --git a/src/mouse_prot.txt b/src/mouse_prot.txt new file mode 100644 index 000000000..e810e969a --- /dev/null +++ b/src/mouse_prot.txt @@ -0,0 +1,207 @@ +Serial mouse reset +------------------ + +1: Set UART to 'break line' state (set bit 6 in the LCR). +2: Clear the RTS and DTR (bits 0-1) in the MCR, wait a while. +3: Set the RTS and DTR bits again. + + +Serial mouse detection (identification bytes before optional PnP data) +---------------------------------------------------------------------- + +In Mouse Systems mode, mouse sends nothing. +In Microsoft mode, mouse sends 'M' after dropping and raising RTS. +In Logitech mode, mouse sends 'M3' after dropping and raising RTS. +In wheel mode, mouse sends 'MZ@',0,0,0 after dropping and raising RTS. + + +PS/2 pointing device ID (reported after 0F2h command) +----------------------------------------------------- + +In standard mode, the device reports 0. +In wheel mode, the device reports 3. This mode is enabled by sending a + Select Report Rate 200, a Rate 100 and finally a Rate 80 command sequence. +In extended mode, the device reports 4. This mode is enabled by sending a + Select Report Rate 200, a Rate 200 and finally a Rate 80 command sequence. + + +=========================================================================== +Serial Mouse Systems mode: 1200 bps, 8 data bits, 1 stop bit, no parity + + 1st byte 2nd byte 3rd byte + +---------------+ +---------------+ +---------------+ + |1|0|0|0|0|L|M|R| |X|X|X|X|X|X|X|X| |Y|Y|Y|Y|Y|Y|Y|Y| + +---------------+ +---------------+ +---------------+ + | | | Xa movement Ya movement + | | | + | | | 4th byte 5th byte + Left Button ------+ | | +---------------+ +---------------+ +Middle Button --------+ | |X|X|X|X|X|X|X|X| |Y|Y|Y|Y|Y|Y|Y|Y| + Right Button ----------+ +---------------+ +---------------+ +(0 if pressed) Xb movement Yb movement + + +Xa/Ya - movement of the mouse since last packet. +Xb/Yb - movement of the mouse since Xa/Ya. +Movement values are 8-bit signed twos complement integers. +Positive movement value indicates motion to the right/upward. + + +=========================================================================== +Serial Microsoft mode: 1200 bps, 7 data bits, 1 stop bit, no parity + + 1st byte 2nd byte 3rd byte + +---------------+ +---------------+ +---------------+ + |0|1|L|R|Y|Y|X|X| |0|0|X|X|X|X|X|X| |0|0|Y|Y|Y|Y|Y|Y| + +---------------+ +---------------+ +---------------+ + | | \ / \ / \----+----/ \----+----/ + | | | | | | + | | +---|-------------|---------+ | + | | +-----+ | | | + | | / \ /----+----\ / \ /----+----\ + | | +---------------+ +---------------+ + Left Button -+ | | | | | | | | | | | | | | | | | | | +Right Button ---+ +---------------+ +---------------+ +(1 if pressed) X movement Y movement + + +Movement values are 8-bit signed twos complement integers. +Positive movement value indicates motion to the right/downward. + + +=========================================================================== +Serial Logitech mode: 1200 bps, 7 data bits, 1 stop bit, no parity + + 1st byte 2nd byte 3rd byte + +---------------+ +---------------+ +---------------+ + |0|1|L|R|Y|Y|X|X| |0|0|X|X|X|X|X|X| |0|0|Y|Y|Y|Y|Y|Y| + +---------------+ +---------------+ +---------------+ + | | \ / \ / \----+----/ \----+----/ + | | | | | | + | | +---|-------------|---------+ | + | | +-----+ | | | + | | / \ /----+----\ / \ /----+----\ + | | +---------------+ +---------------+ + Left Button -+ | | | | | | | | | | | | | | | | | | | +Right Button ---+ +---------------+ +---------------+ +(1 if pressed) X movement Y movement + + +The extra byte (only when middle button is pressed) +--------------------------------------------------- + + 4th byte + +---------------+ + |0|0|M|0|0|0|0|0| + +---------------+ + | + Middle Button (1 if pressed) + + +First three bytes are equal to Mouse mode packet. +Movement values are 8-bit signed twos complement integers. +Positive movement value indicates motion to the right/downward. + + +=========================================================================== +Serial Microsoft wheel mode: 1200 bps, 7 data bits, 1 stop bit, no parity + + 1st byte 2nd byte 3rd byte 4th byte + +---------------+ +---------------+ +---------------+ +---------------+ + |0|1|L|R|Y|Y|X|X| |0|0|X|X|X|X|X|X| |0|0|Y|Y|Y|Y|Y|Y| |0|0|0|M|w|w|w|w| + +---------------+ +---------------+ +---------------+ +---------------+ + | | \ / \ / \----+----/ \----+----/ | \--+--/ + | | | | | | | | + | | +---|-------------|---------+ | | | + | | +-----+ | | | | Wheel + | | / \ /----+----\ / \ /----+----\ | Movement + | | +---------------+ +---------------+ | + Left Button -+ | | | | | | | | | | | | | | | | | | | | +Right Button ---+ +---------------+ +---------------+ Middle Button +(1 if pressed) X movement Y movement (1 if pressed) + + +First three bytes are equal to Mouse mode packet. +Movement values are 8-bit signed twos complement integers. +Positive movement value indicates motion to the right/downward. +Wheel movement is a 4-bit signed twos complement integer. +Positive wheel movement value indicates rotation downward. + + +=========================================================================== +PS/2 standard mode protocol: + + 1st byte 2nd byte 3rd byte + +---------------+ +---------------+ +---------------+ + |?|?|Y|X|1|M|R|L| |X|X|X|X|X|X|X|X| |Y|Y|Y|Y|Y|Y|Y|Y| + +---------------+ +---------------+ +---------------+ + | | | | | \------+------/ \------+------/ + | | | | | | | + +-|---|-|-|----------|-----------+ | + +---|-|-|--+ | | | + | | | | /-----+-------\ | /---+---------\ +Middle Button ------+ | | +-----------------+ +-----------------+ + Right Button --------+ | | | | | | | | | | | | | | | | | | | | | + Left Button ----------+ +-----------------+ +-----------------+ +(1 if pressed) X movement Y movement + + +Two most significant bits in first byte indicate overflow (more than 9 bits + of movement) in each direction. Usually ignored. +Movement values are 9-bit signed twos complement integers. +Positive movement value indicates motion to the right/upward. + + +=========================================================================== +PS/2 wheel mode protocol: + + 1st byte 2nd byte 3rd byte 4th byte + +---------------+ +---------------+ +---------------+ +---------------+ + |?|?|Y|X|1|M|R|L| |X|X|X|X|X|X|X|X| |Y|Y|Y|Y|Y|Y|Y|Y| |w|w|w|w|W|W|W|W| + +---------------+ +---------------+ +---------------+ +---------------+ + | | | | | \------+------/ \------+------/ \-------+-----/ + | | | | | | | | + +-|---|-|-|----------|-----------+ | | + +---|-|-|--+ | | | | + | | | | /-----+-------\ | /---+---------\ | +Middle Button ------+ | | +-----------------+ +-----------------+ | + Right Button --------+ | | | | | | | | | | | | | | | | | | | | | | + Left Button ----------+ +-----------------+ +-----------------+ Wheel +(1 if pressed) X movement Y movement Movement + + +First three bytes are equal to PS/2 standard mode packet. +Two most significant bits in first byte indicate overflow (more than 9 bits + of movement) in each direction. Usually ignored. +Movement values are 9-bit signed twos complement integers. +Positive movement value indicates motion to the right/upward. +Wheel movement is a 8-bit signed twos complement integer and usually + limited by -8..+7 range (4-bit value). +Positive wheel movement value indicates rotation downward. + + +=========================================================================== +PS/2 extended mode protocol: + + 1st byte 2nd byte 3rd byte 4th byte + +---------------+ +---------------+ +---------------+ +---------------+ + |?|?|Y|X|1|M|R|L| |X|X|X|X|X|X|X|X| |Y|Y|Y|Y|Y|Y|Y|Y| |0|0|B|F|W|W|W|W| + +---------------+ +---------------+ +---------------+ +---------------+ + | | | | | \------+------/ \------+------/ | | \--+--/ + | | | | | | | | | | + +-|---|-|-|----------|-----------+ | | | | + +---|-|-|--+ | | | | | Wheel + | | | | /-----+-------\ | /---+---------\ | | Movement +Middle Button ------+ | | +-----------------+ +-----------------+ | | + Right Button --------+ | | | | | | | | | | | | | | | | | | | | | | +- Forward Button + Left Button ----------+ +-----------------+ +-----------------+ +--- Back Button +(1 if pressed) X movement Y movement (1 if pressed) + + +First three bytes are equal to PS/2 standard mode packet. +Two most significant bits in first byte indicate overflow (more than 9 bits + of movement) in each direction. Usually ignored. +Movement values are 9-bit signed twos complement integers. +Positive movement value indicates motion to the right/upward. +Wheel movement is a 4-bit signed twos complement integer. +Positive wheel movement value indicates rotation downward. From eb8b8e3766fc7bbb1747af54359af2184c73decd Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 14 Jun 2017 03:03:29 +0200 Subject: [PATCH 336/392] SCSI controller is now once again reset on soft reset, but this time this is handled in a more appropriate way; Fixed some copyright headers. --- src/CPU/808x.c | 3 +++ src/SOUND/snd_dbopl.cc | 2 +- src/SOUND/snd_dbopl.h | 2 +- src/device.c | 16 +++++++++++ src/device.h | 1 + src/scsi.c | 55 +++++++++++++++++++++++++++++-------- src/scsi.h | 1 + src/scsi_aha154x.c | 61 ++++++++++++++++++++++++------------------ src/scsi_aha154x.h | 2 ++ src/scsi_buslogic.c | 10 ++++++- src/scsi_buslogic.h | 2 ++ 11 files changed, 115 insertions(+), 40 deletions(-) diff --git a/src/CPU/808x.c b/src/CPU/808x.c index 32a52e955..faa951409 100644 --- a/src/CPU/808x.c +++ b/src/CPU/808x.c @@ -34,6 +34,7 @@ #include "../mem.h" #include "../nmi.h" #include "../pic.h" +#include "../scsi.h" #include "../timer.h" int xt_cpu_multi; @@ -599,6 +600,7 @@ void resetx86() codegen_reset(); x86_was_reset = 1; port_92_clear_reset(); + scsi_card_reset(); } void softresetx86() @@ -618,6 +620,7 @@ void softresetx86() x86seg_reset(); x86_was_reset = 1; port_92_clear_reset(); + scsi_card_reset(); } static void setznp8(uint8_t val) diff --git a/src/SOUND/snd_dbopl.cc b/src/SOUND/snd_dbopl.cc index cf4bc1ebe..94480ad4f 100644 --- a/src/SOUND/snd_dbopl.cc +++ b/src/SOUND/snd_dbopl.cc @@ -1,4 +1,4 @@ -/* Copyright holders: The DOSBox Team, SA1988 +/* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ #include "dbopl.h" diff --git a/src/SOUND/snd_dbopl.h b/src/SOUND/snd_dbopl.h index 49b2aa095..6fd536f39 100644 --- a/src/SOUND/snd_dbopl.h +++ b/src/SOUND/snd_dbopl.h @@ -1,4 +1,4 @@ -/* Copyright holders: The DOSBox Team, SA1988 +/* Copyright holders: Sarah Walker, SA1988 see COPYING for more details */ #ifdef __cplusplus diff --git a/src/device.c b/src/device.c index 9b90c9ea1..9d8968f82 100644 --- a/src/device.c +++ b/src/device.c @@ -73,6 +73,22 @@ void device_close_all() } } +void *device_get_priv(device_t *d) +{ + int c; + + for (c = 0; c < 256; c++) + { + if (devices[c] != NULL) + { + if (devices[c] == d) + return device_priv[c]; + } + } + + return NULL; +} + int device_available(device_t *d) { #ifdef RELEASE_BUILD diff --git a/src/device.h b/src/device.h index 5a2f9b17e..e5613f836 100644 --- a/src/device.h +++ b/src/device.h @@ -72,6 +72,7 @@ typedef struct device_t extern void device_init(void); extern void device_add(device_t *d); extern void device_close_all(void); +extern void *device_get_priv(device_t *d); extern int device_available(device_t *d); extern void device_speed_changed(void); extern void device_force_redraw(void); diff --git a/src/scsi.c b/src/scsi.c index 4a2ce29fb..186a2495a 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -1,7 +1,21 @@ -/* Copyright holders: SA1988, Tenshi - see COPYING for more details -*/ -/*SCSI layer emulation*/ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the SCSI controllers. + * + * NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go. + * + * Version: @(#)scsi.c 1.0.0 2017/06/14 + * + * Authors: Fred N. van Kempen, + * Original Buslogic version by SA1988 and Miran Grca. + * Copyright 2017 Fred N. van Kempen. + */ #include #include #include "86box.h" @@ -28,17 +42,18 @@ typedef struct { char name[64]; char internal_name[32]; device_t *device; + void (*reset)(void *p); } SCSI_CARD; static SCSI_CARD scsi_cards[] = { - { "None", "none", NULL }, - { "Adaptec AHA-1540B", "aha1540b", &aha1540b_device }, - { "Adaptec AHA-1542CF", "aha1542cf", &aha1542cf_device }, - { "Adaptec AHA-1640", "aha1640", &aha1640_device }, - { "BusLogic BT-542B", "bt542b", &buslogic_device }, - { "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device }, - { "", "", NULL } + { "None", "none", NULL, NULL }, + { "Adaptec AHA-1540B", "aha1540b", &aha1540b_device, aha_device_reset }, + { "Adaptec AHA-1542CF", "aha1542cf", &aha1542cf_device, aha_device_reset }, + { "Adaptec AHA-1640", "aha1640", &aha1640_device, aha_device_reset }, + { "BusLogic BT-542B", "bt542b", &buslogic_device, BuslogicDeviceReset }, + { "BusLogic BT-958D PCI", "bt958d", &buslogic_pci_device, BuslogicDeviceReset }, + { "", "", NULL, NULL }, }; @@ -100,6 +115,24 @@ void scsi_card_init() } +void scsi_card_reset(void) +{ + void *p = NULL; + + if (scsi_cards[scsi_card_current].device) + { + p = device_get_priv(scsi_cards[scsi_card_current].device); + if (p) + { + if (scsi_cards[scsi_card_current].reset) + { + scsi_cards[scsi_card_current].reset(p); + } + } + } +} + + /* Initialization function for the SCSI layer */ void SCSIReset(uint8_t id, uint8_t lun) { diff --git a/src/scsi.h b/src/scsi.h index 8c3efc3b5..d0e4bfb91 100644 --- a/src/scsi.h +++ b/src/scsi.h @@ -260,6 +260,7 @@ int scsi_card_has_config(int card); char *scsi_card_get_internal_name(int card); int scsi_card_get_from_internal_name(char *s); void scsi_card_init(); +void scsi_card_reset(void); extern uint8_t scsi_hard_disks[16][8]; diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index 72f615843..f37838cf1 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -12,7 +12,7 @@ * * NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go. * - * Version: @(#)scsi_aha154x.c 1.0.6 2017/05/06 + * Version: @(#)scsi_aha154x.c 1.0.7 2017/06/14 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -179,6 +179,32 @@ static uint16_t aha_ports[] = { 0x0130, 0x0134, 0x0000, 0x0000 }; + +#ifdef WALTJE +int aha_do_log = 1; +# define ENABLE_AHA154X_LOG +#else +int aha_do_log = 0; +#endif + + +static void +aha_log(const char *format, ...) +{ +#ifdef ENABLE_AHA154X_LOG + va_list ap; + + if (aha_do_log) { + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#define pclog aha_log + + /* * Write data to the BIOS space. * @@ -839,31 +865,6 @@ enum { }; -#ifdef WALTJE -int aha_do_log = 1; -# define ENABLE_AHA154X_LOG -#else -int aha_do_log = 0; -#endif - - -static void -aha_log(const char *format, ...) -{ -#ifdef ENABLE_AHA154X_LOG - va_list ap; - - if (aha_do_log) { - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} -#define pclog aha_log - - static void ClearIntr(aha_t *dev) { @@ -2168,6 +2169,14 @@ void aha_mca_write(int port, uint8_t val, void *p) } +void +aha_device_reset(void *p) +{ + aha_t *dev = (aha_t *) p; + aha_reset_ctrl(dev, 1); +} + + static void * aha_init(int chip, int has_bios) { diff --git a/src/scsi_aha154x.h b/src/scsi_aha154x.h index 0e7db0d0d..d15de7c2d 100644 --- a/src/scsi_aha154x.h +++ b/src/scsi_aha154x.h @@ -13,6 +13,8 @@ typedef struct { extern device_t aha1540b_device; extern device_t aha1542cf_device; extern device_t aha1640_device; + +extern void aha_device_reset(void *p); #endif /*SCSI_AHA154X_H*/ diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index d5113e000..1b4c8794d 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -10,7 +10,7 @@ * 0 - BT-542B ISA; * 1 - BT-958 PCI (but BT-542B ISA on non-PCI machines) * - * Version: @(#)scsi_buslogic.c 1.0.3 2017/06/03 + * Version: @(#)scsi_buslogic.c 1.0.4 2017/06/14 * * Authors: TheCollector1995, * Miran Grca, @@ -2226,6 +2226,14 @@ BuslogicPCIWrite(int func, int addr, uint8_t val, void *p) } +void +BuslogicDeviceReset(void *p) +{ + Buslogic_t *dev = (Buslogic_t *) p; + BuslogicResetControl(dev, 1); +} + + static void * BuslogicInit(int chip) { diff --git a/src/scsi_buslogic.h b/src/scsi_buslogic.h index c952e06d1..e835ea989 100644 --- a/src/scsi_buslogic.h +++ b/src/scsi_buslogic.h @@ -23,6 +23,8 @@ extern device_t buslogic_device; extern device_t buslogic_pci_device; + +extern void BuslogicDeviceReset(void *p); #endif /*SCSI_BUSLOGIC_H*/ From 9f922ecc2ed8d64e687bcac99e0143095c13c967 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 14 Jun 2017 05:17:13 +0200 Subject: [PATCH 337/392] Fixed reading of Mode 2 data from images. --- src/cdrom.c | 2 +- src/cdrom_image.cc | 49 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/cdrom.c b/src/cdrom.c index 2bcfc20cc..4f81e253c 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -1856,7 +1856,7 @@ int cdrom_read_blocks(uint8_t id, uint32_t *len, int first_batch) } else { - type = 2; + type = 8; flags = 0x10; } diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 07380e79a..810601b24 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -447,7 +447,7 @@ static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ism if (cdrom_image[id].image_is_iso) { audio = 0; - mode2 = 0; + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; } else { @@ -464,7 +464,7 @@ static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ism return 0; } - if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + if ((cdrom_sector_type == 3) || ((cdrom_sector_type > 4) && (cdrom_sector_type != 8))) { if (cdrom_sector_type == 3) { @@ -589,7 +589,7 @@ read_mode1: } else if (cdrom_sector_type == 4) { - if (audio || !mode2 || cdrom_image[id].image_is_iso) + if (audio || !mode2) { cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); return 0; @@ -626,7 +626,31 @@ read_mode2: return 0; } - cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 24, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 12; + bb += 2048; + memset(bb, 0, 280); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } cdrom_sector_size = 0; @@ -671,6 +695,23 @@ read_mode2: temp_b += 280; } } + else if (cdrom_sector_type == 8) + { + if (audio) + { + cdrom_image_log("CD-ROM %i: [Any Data] Attempting to read a data sector from an audio track\n", id); + return 0; + } + + if (mode2) + { + goto read_mode2; + } + else + { + goto read_mode1; + } + } else { if (mode2) From 8c4360da510094d947cf550f2e1358036d8a8c75 Mon Sep 17 00:00:00 2001 From: waltje Date: Wed, 14 Jun 2017 00:55:11 -0400 Subject: [PATCH 338/392] Cleanups for Makefile. Now using += to make things easier, and added explicit -m32 and -m64 switches. --- src/CPU/codegen.h | 2 +- src/Makefile.mingw | 81 ++++++++++++++++++++++------------------------ 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index 5a076db8f..d4c25ae7a 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -1,4 +1,4 @@ -#include "mem.h" +#include "../mem.h" #ifdef __amd64__ #include "codegen_x86-64.h" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 1289db48f..d5a1e30ea 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.25 2017/06/04 +# Version: @(#)Makefile.mingw 1.0.26 2017/06/13 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -43,7 +43,7 @@ ifndef EXTRAS EXTRAS = endif -# Do we want a debugging build? +# Defaults for several build options (possibly defined in a chained file.) ifndef DEBUG DEBUG = n endif @@ -66,56 +66,51 @@ endif ######################################################################### VPATH = . cpu sound sound/resid-fp video lzf slirp win PLAT = win/ -CPP = g++.exe -CC = gcc.exe +ifeq ($(X64), y) +CPP = g++.exe -m64 -U__unix +CC = gcc.exe -m64 -U__unix +else +CPP = g++.exe -m32 +CC = gcc.exe -m32 +endif WINDRES = windres.exe OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) -ifeq ($(DEBUG), y) -ifeq ($(VRAMDUMP), y) -DFLAGS = -march=i686 -ggdb -DDEBUG -DENABLE_VRAM_DUMP -else -DFLAGS = -march=i686 -ggdb -DDEBUG -endif -ifndef COPTIM -COPTIM = -Og -endif -else -ifeq ($(OPTIM), y) -DFLAGS = -march=native -ifndef COPTIM -COPTIM = -O6 -endif -else + ifeq ($(X64), y) -DFLAGS = + DFLAGS = else -DFLAGS = -march=i686 + DFLAGS = -march=i686 endif -ifndef COPTIM -COPTIM = -O3 -endif -endif -endif -ifeq ($(OPTIM), y) -AOPTIM = -mtune=native +ifeq ($(DEBUG), y) + DFLAGS += -ggdb -DDEBUG + AOPTIM = + ifndef COPTIM + COPTIM = -Og + endif else -AOPTIM = + ifeq ($(OPTIM), y) + AOPTIM = -mtune=native + ifndef COPTIM + COPTIM = -O6 + endif + else + ifndef COPTIM + COPTIM = -O3 + endif + endif endif -AFLAGS = -msse -msse2 \ - -mfpmath=sse +AFLAGS = -msse -msse2 -mfpmath=sse +CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ + -fomit-frame-pointer -mstackrealign +RFLAGS = --input-format=rc -O coff ifeq ($(RELEASE), y) -CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ - -fomit-frame-pointer -mstackrealign -DRELEASE_BUILD -RFLAGS = --input-format=rc -O coff -DRELEASE_BUILD -else -CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ - -fomit-frame-pointer -mstackrealign -ifeq ($(VRAMDUMP), y) -RFLAGS = --input-format=rc -O coff -DENABLE_VRAM_DUMP -else -RFLAGS = --input-format=rc -O coff +CFLAGS += -DRELEASE_BUILD +RFLAGS += -DRELEASE_BUILD endif +ifeq ($(VRAMDUMP), y) +CFLAGS += -DENABLE_VRAM_DUMP +RFLAGS += -DENABLE_VRAM_DUMP endif ifeq ($(X64), y) @@ -234,7 +229,7 @@ LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ # Build rules. %.o: %.c @echo $< - @$(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< From 62dea57270a25b40b7d32c37f4574e86914d26cc Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 14 Jun 2017 07:21:01 +0200 Subject: [PATCH 339/392] Added the ability to set sound to use STEREO16 format instead of STEREO_FLOAT32 (defaults to STEREO_FLOAT32); Moved network-related files to their own subdirectory. --- src/Makefile.mingw | 6 +- src/{ => NETWORK}/bswap.h | 2 +- src/{ => NETWORK}/net_ne2000.c | 20 ++--- src/{ => NETWORK}/net_ne2000.h | 0 src/{ => NETWORK}/net_pcap.c | 10 +-- src/{ => NETWORK}/net_slirp.c | 10 +-- src/{ => NETWORK}/network.c | 10 +-- src/{ => NETWORK}/network.h | 0 src/{ => NETWORK}/pcap_if.c | 0 src/{ => NETWORK}/slirp/COPYRIGHT.txt | 0 src/{ => NETWORK}/slirp/VERSION.txt | 0 src/{ => NETWORK}/slirp/bootp.c | 0 src/{ => NETWORK}/slirp/bootp.h | 0 src/{ => NETWORK}/slirp/cksum.c | 0 src/{ => NETWORK}/slirp/config-host.h | 0 src/{ => NETWORK}/slirp/config.h | 0 src/{ => NETWORK}/slirp/ctl.h | 0 src/{ => NETWORK}/slirp/debug.c | 0 src/{ => NETWORK}/slirp/debug.h | 0 src/{ => NETWORK}/slirp/icmp_var.h | 0 src/{ => NETWORK}/slirp/if.c | 0 src/{ => NETWORK}/slirp/if.h | 0 src/{ => NETWORK}/slirp/ip.h | 0 src/{ => NETWORK}/slirp/ip_icmp.c | 0 src/{ => NETWORK}/slirp/ip_icmp.h | 0 src/{ => NETWORK}/slirp/ip_input.c | 0 src/{ => NETWORK}/slirp/ip_output.c | 0 src/{ => NETWORK}/slirp/libslirp.h | 0 src/{ => NETWORK}/slirp/main.h | 0 src/{ => NETWORK}/slirp/mbuf.c | 0 src/{ => NETWORK}/slirp/mbuf.h | 0 src/{ => NETWORK}/slirp/misc.c | 0 src/{ => NETWORK}/slirp/misc.h | 0 src/{ => NETWORK}/slirp/queue.c | 0 src/{ => NETWORK}/slirp/queue.h | 0 src/{ => NETWORK}/slirp/sbuf.c | 0 src/{ => NETWORK}/slirp/sbuf.h | 0 src/{ => NETWORK}/slirp/slirp.c | 2 + src/{ => NETWORK}/slirp/slirp.h | 0 src/{ => NETWORK}/slirp/slirp_config.h | 0 src/{ => NETWORK}/slirp/socket.c | 0 src/{ => NETWORK}/slirp/socket.h | 0 src/{ => NETWORK}/slirp/tcp.h | 0 src/{ => NETWORK}/slirp/tcp_input.c | 0 src/{ => NETWORK}/slirp/tcp_output.c | 0 src/{ => NETWORK}/slirp/tcp_subr.c | 0 src/{ => NETWORK}/slirp/tcp_timer.c | 0 src/{ => NETWORK}/slirp/tcp_timer.h | 0 src/{ => NETWORK}/slirp/tcp_var.h | 0 src/{ => NETWORK}/slirp/tcpip.h | 0 src/{ => NETWORK}/slirp/tftp.c | 0 src/{ => NETWORK}/slirp/tftp.h | 0 src/{ => NETWORK}/slirp/udp.c | 0 src/SOUND/openal.c | 70 ++++++++++++++- src/SOUND/sound.c | 116 ++++++++++++++++++++++--- src/SOUND/sound.h | 8 +- src/WIN/86Box.rc | 7 +- src/WIN/resource.h | 1 + src/WIN/win.c | 2 +- src/WIN/win_settings.c | 16 +++- src/config.c | 26 +++++- src/pc.c | 2 +- src/slirp/Makefile | 26 ------ src/slirp/udp.h | 114 ------------------------ 64 files changed, 255 insertions(+), 193 deletions(-) rename src/{ => NETWORK}/bswap.h (99%) rename src/{ => NETWORK}/net_ne2000.c (99%) rename src/{ => NETWORK}/net_ne2000.h (100%) rename src/{ => NETWORK}/net_pcap.c (98%) rename src/{ => NETWORK}/net_slirp.c (96%) rename src/{ => NETWORK}/network.c (97%) rename src/{ => NETWORK}/network.h (100%) rename src/{ => NETWORK}/pcap_if.c (100%) rename src/{ => NETWORK}/slirp/COPYRIGHT.txt (100%) rename src/{ => NETWORK}/slirp/VERSION.txt (100%) rename src/{ => NETWORK}/slirp/bootp.c (100%) rename src/{ => NETWORK}/slirp/bootp.h (100%) rename src/{ => NETWORK}/slirp/cksum.c (100%) rename src/{ => NETWORK}/slirp/config-host.h (100%) rename src/{ => NETWORK}/slirp/config.h (100%) rename src/{ => NETWORK}/slirp/ctl.h (100%) rename src/{ => NETWORK}/slirp/debug.c (100%) rename src/{ => NETWORK}/slirp/debug.h (100%) rename src/{ => NETWORK}/slirp/icmp_var.h (100%) rename src/{ => NETWORK}/slirp/if.c (100%) rename src/{ => NETWORK}/slirp/if.h (100%) rename src/{ => NETWORK}/slirp/ip.h (100%) rename src/{ => NETWORK}/slirp/ip_icmp.c (100%) rename src/{ => NETWORK}/slirp/ip_icmp.h (100%) rename src/{ => NETWORK}/slirp/ip_input.c (100%) rename src/{ => NETWORK}/slirp/ip_output.c (100%) rename src/{ => NETWORK}/slirp/libslirp.h (100%) rename src/{ => NETWORK}/slirp/main.h (100%) rename src/{ => NETWORK}/slirp/mbuf.c (100%) rename src/{ => NETWORK}/slirp/mbuf.h (100%) rename src/{ => NETWORK}/slirp/misc.c (100%) rename src/{ => NETWORK}/slirp/misc.h (100%) rename src/{ => NETWORK}/slirp/queue.c (100%) rename src/{ => NETWORK}/slirp/queue.h (100%) rename src/{ => NETWORK}/slirp/sbuf.c (100%) rename src/{ => NETWORK}/slirp/sbuf.h (100%) rename src/{ => NETWORK}/slirp/slirp.c (99%) rename src/{ => NETWORK}/slirp/slirp.h (100%) rename src/{ => NETWORK}/slirp/slirp_config.h (100%) rename src/{ => NETWORK}/slirp/socket.c (100%) rename src/{ => NETWORK}/slirp/socket.h (100%) rename src/{ => NETWORK}/slirp/tcp.h (100%) rename src/{ => NETWORK}/slirp/tcp_input.c (100%) rename src/{ => NETWORK}/slirp/tcp_output.c (100%) rename src/{ => NETWORK}/slirp/tcp_subr.c (100%) rename src/{ => NETWORK}/slirp/tcp_timer.c (100%) rename src/{ => NETWORK}/slirp/tcp_timer.h (100%) rename src/{ => NETWORK}/slirp/tcp_var.h (100%) rename src/{ => NETWORK}/slirp/tcpip.h (100%) rename src/{ => NETWORK}/slirp/tftp.c (100%) rename src/{ => NETWORK}/slirp/tftp.h (100%) rename src/{ => NETWORK}/slirp/udp.c (100%) delete mode 100644 src/slirp/Makefile delete mode 100644 src/slirp/udp.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d5a1e30ea..7baeaf1c8 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.26 2017/06/13 +# Version: @(#)Makefile.mingw 1.0.27 2017/06/14 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -64,7 +64,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/resid-fp video lzf slirp win +VPATH = . cpu sound sound/resid-fp video lzf network network/slirp win PLAT = win/ ifeq ($(X64), y) CPP = g++.exe -m64 -U__unix @@ -229,7 +229,7 @@ LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ # Build rules. %.o: %.c @echo $< - $(CC) $(CFLAGS) -c $< + @$(CC) $(CFLAGS) -c $< %.o: %.cc @echo $< diff --git a/src/bswap.h b/src/NETWORK/bswap.h similarity index 99% rename from src/bswap.h rename to src/NETWORK/bswap.h index a1f2f8052..81275a6e6 100644 --- a/src/bswap.h +++ b/src/NETWORK/bswap.h @@ -1,4 +1,4 @@ -/* Copyright holders: Sarah Walker +/* Copyright holders: neozeed see COPYING for more details */ #ifndef BSWAP_H diff --git a/src/net_ne2000.c b/src/NETWORK/net_ne2000.c similarity index 99% rename from src/net_ne2000.c rename to src/NETWORK/net_ne2000.c index 7194adf68..b9fb05a34 100644 --- a/src/net_ne2000.c +++ b/src/NETWORK/net_ne2000.c @@ -10,7 +10,7 @@ * * NOTE: The file will also implement an NE1000 for 8-bit ISA systems. * - * Version: @(#)net_ne2000.c 1.0.10 2017/06/03 + * Version: @(#)net_ne2000.c 1.0.11 2017/06/14 * * Authors: Fred N. van Kempen, * Peter Grehan, grehan@iprg.nokia.com> @@ -24,15 +24,15 @@ #include #include #include -#include "ibm.h" -#include "io.h" -#include "mem.h" -#include "rom.h" -#include "pci.h" -#include "pic.h" -#include "device.h" -#include "config.h" -#include "disc_random.h" +#include "../ibm.h" +#include "../io.h" +#include "../mem.h" +#include "../rom.h" +#include "../pci.h" +#include "../pic.h" +#include "../device.h" +#include "../config.h" +#include "../disc_random.h" #include "network.h" #include "net_ne2000.h" #include "bswap.h" diff --git a/src/net_ne2000.h b/src/NETWORK/net_ne2000.h similarity index 100% rename from src/net_ne2000.h rename to src/NETWORK/net_ne2000.h diff --git a/src/net_pcap.c b/src/NETWORK/net_pcap.c similarity index 98% rename from src/net_pcap.c rename to src/NETWORK/net_pcap.c index 8e2860be2..324b368b3 100644 --- a/src/net_pcap.c +++ b/src/NETWORK/net_pcap.c @@ -17,12 +17,12 @@ #include #include #include -#include "ibm.h" -#include "config.h" -#include "device.h" +#include "../ibm.h" +#include "../config.h" +#include "../device.h" #include "network.h" -#include "plat_dynld.h" -#include "plat_thread.h" +#include "../WIN/plat_dynld.h" +#include "../WIN/plat_thread.h" static void *pcap_handle; /* handle to WinPcap DLL */ diff --git a/src/net_slirp.c b/src/NETWORK/net_slirp.c similarity index 96% rename from src/net_slirp.c rename to src/NETWORK/net_slirp.c index f49167cbd..89c8eb1ac 100644 --- a/src/net_slirp.c +++ b/src/NETWORK/net_slirp.c @@ -8,7 +8,7 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.3 2017/05/21 + * Version: @(#)net_slirp.c 1.0.4 2017/06/14 * * Author: Fred N. van Kempen, */ @@ -18,11 +18,11 @@ #include #include "slirp/slirp.h" #include "slirp/queue.h" -#include "ibm.h" -#include "config.h" -#include "device.h" +#include "../ibm.h" +#include "../config.h" +#include "../device.h" #include "network.h" -#include "plat_thread.h" +#include "../WIN/plat_thread.h" static queueADT slirpq; /* SLiRP library handle */ diff --git a/src/network.c b/src/NETWORK/network.c similarity index 97% rename from src/network.c rename to src/NETWORK/network.c index cd6cc3ea5..abac44263 100644 --- a/src/network.c +++ b/src/NETWORK/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.9 2017/06/03 + * Version: @(#)network.c 1.0.10 2017/06/14 * * Author: Fred N. van Kempen, */ @@ -20,12 +20,12 @@ #include #include #include -#include "ibm.h" -#include "device.h" +#include "../ibm.h" +#include "../device.h" #include "network.h" #include "net_ne2000.h" -#include "win.h" -#include "win_language.h" +#include "../WIN/win.h" +#include "../WIN/win_language.h" static netcard_t net_cards[] = { diff --git a/src/network.h b/src/NETWORK/network.h similarity index 100% rename from src/network.h rename to src/NETWORK/network.h diff --git a/src/pcap_if.c b/src/NETWORK/pcap_if.c similarity index 100% rename from src/pcap_if.c rename to src/NETWORK/pcap_if.c diff --git a/src/slirp/COPYRIGHT.txt b/src/NETWORK/slirp/COPYRIGHT.txt similarity index 100% rename from src/slirp/COPYRIGHT.txt rename to src/NETWORK/slirp/COPYRIGHT.txt diff --git a/src/slirp/VERSION.txt b/src/NETWORK/slirp/VERSION.txt similarity index 100% rename from src/slirp/VERSION.txt rename to src/NETWORK/slirp/VERSION.txt diff --git a/src/slirp/bootp.c b/src/NETWORK/slirp/bootp.c similarity index 100% rename from src/slirp/bootp.c rename to src/NETWORK/slirp/bootp.c diff --git a/src/slirp/bootp.h b/src/NETWORK/slirp/bootp.h similarity index 100% rename from src/slirp/bootp.h rename to src/NETWORK/slirp/bootp.h diff --git a/src/slirp/cksum.c b/src/NETWORK/slirp/cksum.c similarity index 100% rename from src/slirp/cksum.c rename to src/NETWORK/slirp/cksum.c diff --git a/src/slirp/config-host.h b/src/NETWORK/slirp/config-host.h similarity index 100% rename from src/slirp/config-host.h rename to src/NETWORK/slirp/config-host.h diff --git a/src/slirp/config.h b/src/NETWORK/slirp/config.h similarity index 100% rename from src/slirp/config.h rename to src/NETWORK/slirp/config.h diff --git a/src/slirp/ctl.h b/src/NETWORK/slirp/ctl.h similarity index 100% rename from src/slirp/ctl.h rename to src/NETWORK/slirp/ctl.h diff --git a/src/slirp/debug.c b/src/NETWORK/slirp/debug.c similarity index 100% rename from src/slirp/debug.c rename to src/NETWORK/slirp/debug.c diff --git a/src/slirp/debug.h b/src/NETWORK/slirp/debug.h similarity index 100% rename from src/slirp/debug.h rename to src/NETWORK/slirp/debug.h diff --git a/src/slirp/icmp_var.h b/src/NETWORK/slirp/icmp_var.h similarity index 100% rename from src/slirp/icmp_var.h rename to src/NETWORK/slirp/icmp_var.h diff --git a/src/slirp/if.c b/src/NETWORK/slirp/if.c similarity index 100% rename from src/slirp/if.c rename to src/NETWORK/slirp/if.c diff --git a/src/slirp/if.h b/src/NETWORK/slirp/if.h similarity index 100% rename from src/slirp/if.h rename to src/NETWORK/slirp/if.h diff --git a/src/slirp/ip.h b/src/NETWORK/slirp/ip.h similarity index 100% rename from src/slirp/ip.h rename to src/NETWORK/slirp/ip.h diff --git a/src/slirp/ip_icmp.c b/src/NETWORK/slirp/ip_icmp.c similarity index 100% rename from src/slirp/ip_icmp.c rename to src/NETWORK/slirp/ip_icmp.c diff --git a/src/slirp/ip_icmp.h b/src/NETWORK/slirp/ip_icmp.h similarity index 100% rename from src/slirp/ip_icmp.h rename to src/NETWORK/slirp/ip_icmp.h diff --git a/src/slirp/ip_input.c b/src/NETWORK/slirp/ip_input.c similarity index 100% rename from src/slirp/ip_input.c rename to src/NETWORK/slirp/ip_input.c diff --git a/src/slirp/ip_output.c b/src/NETWORK/slirp/ip_output.c similarity index 100% rename from src/slirp/ip_output.c rename to src/NETWORK/slirp/ip_output.c diff --git a/src/slirp/libslirp.h b/src/NETWORK/slirp/libslirp.h similarity index 100% rename from src/slirp/libslirp.h rename to src/NETWORK/slirp/libslirp.h diff --git a/src/slirp/main.h b/src/NETWORK/slirp/main.h similarity index 100% rename from src/slirp/main.h rename to src/NETWORK/slirp/main.h diff --git a/src/slirp/mbuf.c b/src/NETWORK/slirp/mbuf.c similarity index 100% rename from src/slirp/mbuf.c rename to src/NETWORK/slirp/mbuf.c diff --git a/src/slirp/mbuf.h b/src/NETWORK/slirp/mbuf.h similarity index 100% rename from src/slirp/mbuf.h rename to src/NETWORK/slirp/mbuf.h diff --git a/src/slirp/misc.c b/src/NETWORK/slirp/misc.c similarity index 100% rename from src/slirp/misc.c rename to src/NETWORK/slirp/misc.c diff --git a/src/slirp/misc.h b/src/NETWORK/slirp/misc.h similarity index 100% rename from src/slirp/misc.h rename to src/NETWORK/slirp/misc.h diff --git a/src/slirp/queue.c b/src/NETWORK/slirp/queue.c similarity index 100% rename from src/slirp/queue.c rename to src/NETWORK/slirp/queue.c diff --git a/src/slirp/queue.h b/src/NETWORK/slirp/queue.h similarity index 100% rename from src/slirp/queue.h rename to src/NETWORK/slirp/queue.h diff --git a/src/slirp/sbuf.c b/src/NETWORK/slirp/sbuf.c similarity index 100% rename from src/slirp/sbuf.c rename to src/NETWORK/slirp/sbuf.c diff --git a/src/slirp/sbuf.h b/src/NETWORK/slirp/sbuf.h similarity index 100% rename from src/slirp/sbuf.h rename to src/NETWORK/slirp/sbuf.h diff --git a/src/slirp/slirp.c b/src/NETWORK/slirp/slirp.c similarity index 99% rename from src/slirp/slirp.c rename to src/NETWORK/slirp/slirp.c index 6a9670f12..3068dc72c 100644 --- a/src/slirp/slirp.c +++ b/src/NETWORK/slirp/slirp.c @@ -29,6 +29,8 @@ fd_set *global_readfds, *global_writefds, *global_xfds; extern void pclog(const char *, ...); extern int config_get_int(char *, char *, int); +#define printf pclog + #ifdef _WIN32 static int get_dns_addr(struct in_addr *pdns_addr) diff --git a/src/slirp/slirp.h b/src/NETWORK/slirp/slirp.h similarity index 100% rename from src/slirp/slirp.h rename to src/NETWORK/slirp/slirp.h diff --git a/src/slirp/slirp_config.h b/src/NETWORK/slirp/slirp_config.h similarity index 100% rename from src/slirp/slirp_config.h rename to src/NETWORK/slirp/slirp_config.h diff --git a/src/slirp/socket.c b/src/NETWORK/slirp/socket.c similarity index 100% rename from src/slirp/socket.c rename to src/NETWORK/slirp/socket.c diff --git a/src/slirp/socket.h b/src/NETWORK/slirp/socket.h similarity index 100% rename from src/slirp/socket.h rename to src/NETWORK/slirp/socket.h diff --git a/src/slirp/tcp.h b/src/NETWORK/slirp/tcp.h similarity index 100% rename from src/slirp/tcp.h rename to src/NETWORK/slirp/tcp.h diff --git a/src/slirp/tcp_input.c b/src/NETWORK/slirp/tcp_input.c similarity index 100% rename from src/slirp/tcp_input.c rename to src/NETWORK/slirp/tcp_input.c diff --git a/src/slirp/tcp_output.c b/src/NETWORK/slirp/tcp_output.c similarity index 100% rename from src/slirp/tcp_output.c rename to src/NETWORK/slirp/tcp_output.c diff --git a/src/slirp/tcp_subr.c b/src/NETWORK/slirp/tcp_subr.c similarity index 100% rename from src/slirp/tcp_subr.c rename to src/NETWORK/slirp/tcp_subr.c diff --git a/src/slirp/tcp_timer.c b/src/NETWORK/slirp/tcp_timer.c similarity index 100% rename from src/slirp/tcp_timer.c rename to src/NETWORK/slirp/tcp_timer.c diff --git a/src/slirp/tcp_timer.h b/src/NETWORK/slirp/tcp_timer.h similarity index 100% rename from src/slirp/tcp_timer.h rename to src/NETWORK/slirp/tcp_timer.h diff --git a/src/slirp/tcp_var.h b/src/NETWORK/slirp/tcp_var.h similarity index 100% rename from src/slirp/tcp_var.h rename to src/NETWORK/slirp/tcp_var.h diff --git a/src/slirp/tcpip.h b/src/NETWORK/slirp/tcpip.h similarity index 100% rename from src/slirp/tcpip.h rename to src/NETWORK/slirp/tcpip.h diff --git a/src/slirp/tftp.c b/src/NETWORK/slirp/tftp.c similarity index 100% rename from src/slirp/tftp.c rename to src/NETWORK/slirp/tftp.c diff --git a/src/slirp/tftp.h b/src/NETWORK/slirp/tftp.h similarity index 100% rename from src/slirp/tftp.h rename to src/NETWORK/slirp/tftp.h diff --git a/src/slirp/udp.c b/src/NETWORK/slirp/udp.c similarity index 100% rename from src/slirp/udp.c rename to src/NETWORK/slirp/udp.c diff --git a/src/SOUND/openal.c b/src/SOUND/openal.c index 9f20b57de..e6dd1add2 100644 --- a/src/SOUND/openal.c +++ b/src/SOUND/openal.c @@ -73,10 +73,15 @@ void inital(ALvoid) { #ifdef USE_OPENAL int c; + float buf[BUFLEN*2]; float cd_buf[CD_BUFLEN*2]; + int16_t buf_int16[BUFLEN*2]; + + int16_t cd_buf_int16[CD_BUFLEN*2]; + alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); @@ -98,8 +103,16 @@ void inital(ALvoid) for (c = 0; c < 4; c++) { - alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + if (sound_is_float) + { + alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + } + else + { + alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + } } alSourceQueueBuffers(source[0], 4, buffers); @@ -135,6 +148,32 @@ void givealbuffer(float *buf) #endif } +void givealbuffer_int16(int16_t *buf) +{ +#ifdef USE_OPENAL + int processed; + int state; + ALuint buffer; + + alGetSourcei(source[0], AL_SOURCE_STATE, &state); + + if (state==0x1014) + { + alSourcePlay(source[0]); + } + alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + + if (processed>=1) + { + alSourceUnqueueBuffers(source[0], 1, &buffer); + + alBufferData(buffer, AL_FORMAT_STEREO16, buf, BUFLEN*2*sizeof(int16_t), FREQ); + + alSourceQueueBuffers(source[0], 1, &buffer); + } +#endif +} + void givealbuffer_cd(float *buf) { #ifdef USE_OPENAL @@ -161,3 +200,30 @@ void givealbuffer_cd(float *buf) } #endif } + +void givealbuffer_cd_int16(int16_t *buf) +{ +#ifdef USE_OPENAL + int processed; + int state; + + alGetSourcei(source[1], AL_SOURCE_STATE, &state); + + if (state==0x1014) + { + alSourcePlay(source[1]); + } + alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); + + if (processed>=1) + { + ALuint buffer; + + alSourceUnqueueBuffers(source[1], 1, &buffer); + + alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + + alSourceQueueBuffers(source[1], 1, &buffer); + } +#endif +} diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index c233c0966..369065411 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -8,7 +8,7 @@ * * Sound emulation core. * - * Version: @(#)sound.c 1.0.1 2017/06/04 + * Version: @(#)sound.c 1.0.2 2017/06/14 * * Authors: Sarah Walker, * Miran Grca, @@ -136,11 +136,14 @@ int soundon = 1; static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2]; static float cd_out_buffer[CD_BUFLEN * 2]; +static int16_t cd_out_buffer_int16[CD_BUFLEN * 2]; static thread_t *sound_cd_thread_h; static event_t *sound_cd_event; static unsigned int cd_vol_l, cd_vol_r; static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN; +int sound_is_float = 1; + void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r) { cd_vol_l = vol_l; @@ -151,10 +154,13 @@ static void sound_cd_thread(void *param) { int i = 0; + float cd_buffer_temp[2] = {0.0, 0.0}; + float cd_buffer_temp2[2] = {0.0, 0.0}; + + int c, has_audio; + while (1) { - int c, has_audio; - thread_wait_event(sound_cd_event, -1); if (!soundon) { @@ -162,8 +168,16 @@ static void sound_cd_thread(void *param) } for (c = 0; c < CD_BUFLEN*2; c += 2) { - cd_out_buffer[c] = 0.0; - cd_out_buffer[c+1] = 0.0; + if (sound_is_float) + { + cd_out_buffer[c] = 0.0; + cd_out_buffer[c+1] = 0.0; + } + else + { + cd_out_buffer_int16[c] = 0; + cd_out_buffer_int16[c+1] = 0; + } } for (i = 0; i < CDROM_NUM; i++) { @@ -184,9 +198,6 @@ static void sound_cd_thread(void *param) for (c = 0; c < CD_BUFLEN*2; c += 2) { - float cd_buffer_temp[2] = {0.0, 0.0}; - float cd_buffer_temp2[2] = {0.0, 0.0}; - /* First, transfer the CD audio data to the temporary buffer. */ cd_buffer_temp[0] = (float) cd_buffer[i][c]; cd_buffer_temp[1] = (float) cd_buffer[i][c+1]; @@ -223,20 +234,71 @@ static void sound_cd_thread(void *param) cd_buffer_temp2[1] *= (float) cd_vol_r; cd_buffer_temp2[1] /= 65535.0; - cd_out_buffer[c] += (cd_buffer_temp2[0] / 32768.0); - cd_out_buffer[c+1] += (cd_buffer_temp2[1] / 32768.0); + if (sound_is_float) + { + cd_out_buffer[c] += (cd_buffer_temp2[0] / 32768.0); + cd_out_buffer[c+1] += (cd_buffer_temp2[1] / 32768.0); + } + else + { + if (cd_buffer_temp2[0] > 32767) + cd_buffer_temp2[0] = 32767; + if (cd_buffer_temp2[0] < -32768) + cd_buffer_temp2[0] = -32768; + if (cd_buffer_temp2[1] > 32767) + cd_buffer_temp2[1] = 32767; + if (cd_buffer_temp2[1] < -32768) + cd_buffer_temp2[1] = -32768; + + cd_out_buffer_int16[c] += cd_buffer_temp2[0]; + cd_out_buffer_int16[c+1] += cd_buffer_temp2[1]; + } } } } - givealbuffer_cd(cd_out_buffer); + if (sound_is_float) + { + givealbuffer_cd(cd_out_buffer); + } + else + { + givealbuffer_cd_int16(cd_out_buffer_int16); + } } } static int32_t *outbuffer; static float *outbuffer_ex; +static int16_t *outbuffer_ex_int16; static int cd_thread_enable = 0; +void sound_realloc_buffers(void) +{ + closeal(); + initalmain(0,NULL); + inital(); + + if (outbuffer_ex != NULL) + { + free(outbuffer_ex); + } + + if (outbuffer_ex_int16 != NULL) + { + free(outbuffer_ex_int16); + } + + if (sound_is_float) + { + outbuffer_ex = malloc(SOUNDBUFLEN * 2 * sizeof(float)); + } + else + { + outbuffer_ex_int16 = malloc(SOUNDBUFLEN * 2 * sizeof(int16_t)); + } +} + void sound_init(void) { int i = 0; @@ -245,8 +307,12 @@ void sound_init(void) initalmain(0,NULL); inital(); + outbuffer_ex = NULL; + outbuffer_ex_int16 = NULL; + outbuffer = malloc(SOUNDBUFLEN * 2 * sizeof(int32_t)); - outbuffer_ex = malloc(SOUNDBUFLEN * 2 * sizeof(float)); + + sound_realloc_buffers(); for (i = 0; i < CDROM_NUM; i++) { @@ -289,10 +355,32 @@ void sound_poll(void *priv) for (c = 0; c < SOUNDBUFLEN * 2; c++) { - outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; + if (sound_is_float) + { + outbuffer_ex[c] = ((float) outbuffer[c]) / 32768.0; + } + else + { + if (outbuffer[c] > 32767) + outbuffer[c] = 32767; + if (outbuffer[c] < -32768) + outbuffer[c] = -32768; + + outbuffer_ex_int16[c] = outbuffer[c]; + } } - if (soundon) givealbuffer(outbuffer_ex); + if (soundon) + { + if (sound_is_float) + { + givealbuffer(outbuffer_ex); + } + else + { + givealbuffer_int16(outbuffer_ex_int16); + } + } if (cd_thread_enable) { diff --git a/src/SOUND/sound.h b/src/SOUND/sound.h index 22d2d2afa..d6c82fb6a 100644 --- a/src/SOUND/sound.h +++ b/src/SOUND/sound.h @@ -8,7 +8,7 @@ * * Sound emulation core. * - * Version: @(#)sound.h 1.0.0 2017/05/30 + * Version: @(#)sound.h 1.0.1 2017/06/14 * * Author: Sarah Walker, * Miran Grca, @@ -35,12 +35,18 @@ void sound_set_cd_volume(unsigned int vol_l, unsigned int vol_r); extern int sound_pos_global; void sound_speed_changed(); +extern int sound_is_float; +void sound_realloc_buffers(void); + void sound_init(); void sound_reset(); void sound_cd_thread_reset(); +void closeal(ALvoid); void initalmain(int argc, char *argv[]); void inital(); void givealbuffer(float *buf); +void givealbuffer_int16(int16_t *buf); void givealbuffer_cd(float *buf); +void givealbuffer_cd_int16(int16_t *buf); diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index e5b19e765..0a64e8b42 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -279,7 +279,7 @@ BEGIN PUSHBUTTON "Joystick 4...",IDC_JOY4,209,44,50,14 END -DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 98 +DLG_CFG_SOUND DIALOG DISCARDABLE 97, 0, 267, 116 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN @@ -304,6 +304,9 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,7,81,94,10 CONTROL "Use Nuked OPL",IDC_CHECK_NUKEDOPL,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,147,81,94,10 + + CONTROL "Use FLOAT32 sound",IDC_CHECK_FLOAT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,99,94,10 END DLG_CFG_NETWORK DIALOG DISCARDABLE 97, 0, 267, 63 @@ -668,7 +671,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 260 TOPMARGIN, 7 - BOTTOMMARGIN, 71 + BOTTOMMARGIN, 109 END CONFIGUREDLG_NETWORK, DIALOG diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 47c92c31c..39feb0a5d 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -126,6 +126,7 @@ #define IDC_COMBO_MIDI 1076 #define IDC_CHECK_MPU401 1077 #define IDC_CONFIGURE_MPU401 1078 +#define IDC_CHECK_FLOAT 1079 #define IDC_COMBO_NET_TYPE 1090 /* network config */ #define IDC_COMBO_PCAP 1091 diff --git a/src/WIN/win.c b/src/WIN/win.c index e6e8077e7..394a05e3b 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -1240,7 +1240,7 @@ void update_status_bar_panes(HWND hwnds) break; case SB_TEXT: /* Status text */ - SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L"Welcome to Unicode 86Box! :p"); + SendMessage(hwnds, SB_SETTEXT, i | SBT_NOBORDERS, (LPARAM) L""); sb_part_icons[i] = -1; break; } diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 702b8b5d5..865bc39dd 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.2 2017/06/04 + * Version: @(#)win_settings.c 1.0.3 2017/06/14 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -34,7 +34,7 @@ #include "../ide.h" #include "../scsi.h" #include "../scsi_buslogic.h" -#include "../network.h" +#include "../network/network.h" #include "../sound/sound.h" #include "../sound/snd_dbopl.h" #include "../sound/snd_mpu401.h" @@ -58,6 +58,7 @@ static int temp_mouse, temp_joystick; /* Sound category */ static int temp_sound_card, temp_midi_id, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; +static int temp_float; /* Network category */ static int temp_net_type, temp_net_card; @@ -124,6 +125,7 @@ static void win_settings_init(void) temp_GAMEBLASTER = GAMEBLASTER; temp_GUS = GUS; temp_opl3_type = opl3_type; + temp_float = sound_is_float; /* Network category */ temp_net_type = network_type; @@ -189,6 +191,7 @@ static int win_settings_changed(void) i = i || (GAMEBLASTER != temp_GAMEBLASTER); i = i || (GUS != temp_GUS); i = i || (opl3_type != temp_opl3_type); + i = i || (sound_is_float != temp_float); /* Network category */ i = i || (network_type != temp_net_type); @@ -286,6 +289,7 @@ static void win_settings_save(void) GAMEBLASTER = temp_GAMEBLASTER; GUS = temp_GUS; opl3_type = temp_opl3_type; + sound_is_float = temp_float; /* Network category */ network_type = temp_net_type; @@ -321,6 +325,8 @@ static void win_settings_save(void) update_status_bar_panes(hwndStatus); + sound_realloc_buffers(); + resetpchard(); cpu_set(); @@ -1235,6 +1241,9 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h=GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); SendMessage(h, BM_SETCHECK, temp_opl3_type, 0); + h=GetDlgItem(hdlg, IDC_CHECK_FLOAT); + SendMessage(h, BM_SETCHECK, temp_float, 0); + free(lptsTemp); return TRUE; @@ -1306,6 +1315,9 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CHECK_NUKEDOPL); temp_opl3_type = SendMessage(h, BM_GETCHECK, 0, 0); + h = GetDlgItem(hdlg, IDC_CHECK_FLOAT); + temp_float = SendMessage(h, BM_GETCHECK, 0, 0); + default: return FALSE; } diff --git a/src/config.c b/src/config.c index 912c4aaac..7a044a6c0 100644 --- a/src/config.c +++ b/src/config.c @@ -24,7 +24,7 @@ #include "hdd.h" #include "model.h" #include "mouse.h" -#include "network.h" +#include "network/network.h" #include "nvr.h" #include "scsi.h" #include "win/plat_joystick.h" @@ -997,6 +997,21 @@ static void loadconfig_sound(void) { opl3_type = 0; } + + memset(temps, '\0', sizeof(temps)); + p = config_get_string(cat, "sound_type", "float"); + if (p != NULL) + { + strcpy(temps, p); + } + if (!strcmp(temps, "float") || !strcmp(temps, "1")) + { + sound_is_float = 1; + } + else + { + sound_is_float = 0; + } } @@ -2059,6 +2074,15 @@ static void saveconfig_sound(void) config_set_string(cat, "opl3_type", (opl3_type == 1) ? "nukedopl" : "dbopl"); } + if (sound_is_float == 1) + { + config_delete_var(cat, "sound_type"); + } + else + { + config_set_string(cat, "sound_type", (sound_is_float == 1) ? "float" : "int16"); + } + config_delete_section_if_empty(cat); } diff --git a/src/pc.c b/src/pc.c index f60a03a3e..8ced5b20b 100644 --- a/src/pc.c +++ b/src/pc.c @@ -59,7 +59,7 @@ #include "model.h" #include "mouse.h" #include "plat_mouse.h" -#include "network.h" +#include "network/network.h" #include "serial.h" #include "sound/sound.h" #include "sound/snd_cms.h" diff --git a/src/slirp/Makefile b/src/slirp/Makefile deleted file mode 100644 index 275c054d2..000000000 --- a/src/slirp/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -CC=gcc -CFLAGS=-I. -O2 -Wall -DEPS = bootp.h config-host.h config.h ctl.h \ - debug.h icmp_var.h if.h ip.h \ - ip_icmp.h libslirp.h main.h mbuf.h \ - misc.h queue.h sbuf.h slirp.h \ - slirp_config.h socket.h tcp.h tcpip.h \ - tcp_timer.h tcp_var.h tftp.h udp.h - -OBJ = bootp.o cksum.o debug.o if.o ip_icmp.o \ - ip_input.o ip_output.o mbuf.o misc.o queue.o \ - sbuf.o slirp.o socket.o tcp_input.o tcp_output.o \ - tcp_subr.o tcp_timer.o tftp.o udp.o - -%.o: %.c $(DEPS) - $(CC) $(CFLAGS) -c $< -o $@ - -default: libslirp.a - -clean: - rm -f $(OBJ) - rm -f libslirp.a - -libslirp.a: $(OBJ) - ar rcs $@ $^ - ranlib $@ \ No newline at end of file diff --git a/src/slirp/udp.h b/src/slirp/udp.h deleted file mode 100644 index 2f6b1e483..000000000 --- a/src/slirp/udp.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)udp.h 8.1 (Berkeley) 6/10/93 - * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp - */ - -#ifndef _UDP_H_ -#define _UDP_H_ - -#define UDP_TTL 0x60 -#define UDP_UDPDATALEN 16192 - -extern struct SLIRPsocket *udp_last_so; - -/* - * Udp protocol header. - * Per RFC 768, September, 1981. - */ -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(1) -#endif - -struct udphdr { - u_int16_t uh_sport; /* source port */ - u_int16_t uh_dport; /* destination port */ - int16_t uh_ulen; /* udp length */ - u_int16_t uh_sum; /* udp checksum */ -} PACKED__; - -#ifdef PRAGMA_PACK_SUPPORTED -#pragma pack(PACK_END) -#endif - -/* - * UDP kernel structures and variables. - */ -struct udpiphdr { - struct ipovly ui_i; /* overlaid ip structure */ - struct udphdr ui_u; /* udp header */ -}; -#define ui_next ui_i.ih_next -#define ui_prev ui_i.ih_prev -#define ui_x1 ui_i.ih_x1 -#define ui_pr ui_i.ih_pr -#define ui_len ui_i.ih_len -#define ui_src ui_i.ih_src -#define ui_dst ui_i.ih_dst -#define ui_sport ui_u.uh_sport -#define ui_dport ui_u.uh_dport -#define ui_ulen ui_u.uh_ulen -#define ui_sum ui_u.uh_sum - -struct udpstat { - /* input statistics: */ - u_long udps_ipackets; /* total input packets */ - u_long udps_hdrops; /* packet shorter than header */ - u_long udps_badsum; /* checksum error */ - u_long udps_badlen; /* data length larger than packet */ - u_long udps_noport; /* no socket on port */ - u_long udps_noportbcast; /* of above, arrived as broadcast */ - u_long udps_fullsock; /* not delivered, input socket full */ - u_long udpps_pcbcachemiss; /* input packets missing pcb cache */ - /* output statistics: */ - u_long udps_opackets; /* total output packets */ -}; - -/* - * Names for UDP sysctl objects - */ -#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ -#define UDPCTL_MAXID 2 - -extern struct udpstat udpstat; -extern struct SLIRPsocket udb; -struct SLIRPmbuf; - -void udp_init _P((void)); -void udp_input _P((register struct SLIRPmbuf *, int)); -int udp_output _P((struct SLIRPsocket *, struct SLIRPmbuf *, struct sockaddr_in *)); -int udp_attach _P((struct SLIRPsocket *)); -void udp_detach _P((struct SLIRPsocket *)); -u_int8_t udp_tos _P((struct SLIRPsocket *)); -void udp_emu _P((struct SLIRPsocket *, struct SLIRPmbuf *)); -struct SLIRPsocket * udp_listen _P((u_int, u_int32_t, u_int, int)); -int udp_output2(struct SLIRPsocket *so, struct SLIRPmbuf *m, - struct sockaddr_in *saddr, struct sockaddr_in *daddr, - int iptos); -#endif From 62bfb60a7bba069cb696dd0cb7842a30a3884507 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 14 Jun 2017 07:35:39 +0200 Subject: [PATCH 340/392] Committed network/slirp/udp.h that I forgot to commit before. --- src/NETWORK/slirp/udp.h | 114 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 src/NETWORK/slirp/udp.h diff --git a/src/NETWORK/slirp/udp.h b/src/NETWORK/slirp/udp.h new file mode 100644 index 000000000..2f6b1e483 --- /dev/null +++ b/src/NETWORK/slirp/udp.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 1982, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)udp.h 8.1 (Berkeley) 6/10/93 + * udp.h,v 1.3 1994/08/21 05:27:41 paul Exp + */ + +#ifndef _UDP_H_ +#define _UDP_H_ + +#define UDP_TTL 0x60 +#define UDP_UDPDATALEN 16192 + +extern struct SLIRPsocket *udp_last_so; + +/* + * Udp protocol header. + * Per RFC 768, September, 1981. + */ +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(1) +#endif + +struct udphdr { + u_int16_t uh_sport; /* source port */ + u_int16_t uh_dport; /* destination port */ + int16_t uh_ulen; /* udp length */ + u_int16_t uh_sum; /* udp checksum */ +} PACKED__; + +#ifdef PRAGMA_PACK_SUPPORTED +#pragma pack(PACK_END) +#endif + +/* + * UDP kernel structures and variables. + */ +struct udpiphdr { + struct ipovly ui_i; /* overlaid ip structure */ + struct udphdr ui_u; /* udp header */ +}; +#define ui_next ui_i.ih_next +#define ui_prev ui_i.ih_prev +#define ui_x1 ui_i.ih_x1 +#define ui_pr ui_i.ih_pr +#define ui_len ui_i.ih_len +#define ui_src ui_i.ih_src +#define ui_dst ui_i.ih_dst +#define ui_sport ui_u.uh_sport +#define ui_dport ui_u.uh_dport +#define ui_ulen ui_u.uh_ulen +#define ui_sum ui_u.uh_sum + +struct udpstat { + /* input statistics: */ + u_long udps_ipackets; /* total input packets */ + u_long udps_hdrops; /* packet shorter than header */ + u_long udps_badsum; /* checksum error */ + u_long udps_badlen; /* data length larger than packet */ + u_long udps_noport; /* no socket on port */ + u_long udps_noportbcast; /* of above, arrived as broadcast */ + u_long udps_fullsock; /* not delivered, input socket full */ + u_long udpps_pcbcachemiss; /* input packets missing pcb cache */ + /* output statistics: */ + u_long udps_opackets; /* total output packets */ +}; + +/* + * Names for UDP sysctl objects + */ +#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ +#define UDPCTL_MAXID 2 + +extern struct udpstat udpstat; +extern struct SLIRPsocket udb; +struct SLIRPmbuf; + +void udp_init _P((void)); +void udp_input _P((register struct SLIRPmbuf *, int)); +int udp_output _P((struct SLIRPsocket *, struct SLIRPmbuf *, struct sockaddr_in *)); +int udp_attach _P((struct SLIRPsocket *)); +void udp_detach _P((struct SLIRPsocket *)); +u_int8_t udp_tos _P((struct SLIRPsocket *)); +void udp_emu _P((struct SLIRPsocket *, struct SLIRPmbuf *)); +struct SLIRPsocket * udp_listen _P((u_int, u_int32_t, u_int, int)); +int udp_output2(struct SLIRPsocket *so, struct SLIRPmbuf *m, + struct sockaddr_in *saddr, struct sockaddr_in *daddr, + int iptos); +#endif From c0a8830d5ef6878624f00dda92ab1a324c2f095d Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 14 Jun 2017 20:35:58 +0200 Subject: [PATCH 341/392] Brought the Voodoo files in line with the mainline PCem code - fixes all warnings; Applied all the mainline PCem commits; Fixed some sound-related warnings. --- src/CPU/386_dynarec.c | 21 +- src/CPU/codegen.h | 5 +- src/CPU/codegen_ops_x86-64.h | 4 +- src/CPU/codegen_x86-64.c | 119 +++----- src/CPU/codegen_x86.c | 73 +++-- src/SOUND/openal.c | 4 +- src/SOUND/sound.h | 2 +- src/VIDEO/vid_voodoo.c | 381 ++++++++++++++++++-------- src/VIDEO/vid_voodoo_codegen_x86-64.h | 101 ++++--- src/VIDEO/vid_voodoo_codegen_x86.h | 142 +++++++--- src/hdd_esdi.c | 6 +- src/mem.c | 28 +- src/mem.h | 4 +- 13 files changed, 517 insertions(+), 373 deletions(-) diff --git a/src/CPU/386_dynarec.c b/src/CPU/386_dynarec.c index a362f50da..c59110cd6 100644 --- a/src/CPU/386_dynarec.c +++ b/src/CPU/386_dynarec.c @@ -1426,7 +1426,7 @@ void exec386_dynarec(int cycs) { uint64_t mask = (uint64_t)1 << ((phys_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if (page->code_present_mask & mask) + if (page->code_present_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] & mask) { /*Walk page tree to see if we find the correct block*/ codeblock_t *new_block = codeblock_tree_find(phys_addr, cs); @@ -1439,10 +1439,11 @@ void exec386_dynarec(int cycs) } } } - if (valid_block && (block->page_mask & page->dirty_mask)) + + if (valid_block && (block->page_mask & *block->dirty_mask)) { - codegen_check_flush(page, page->dirty_mask, phys_addr); - page->dirty_mask = 0; + codegen_check_flush(page, page->dirty_mask[(phys_addr >> 10) & 3], phys_addr); + page->dirty_mask[(phys_addr >> 10) & 3] = 0; if (!block->pc) valid_block = 0; } @@ -1455,15 +1456,15 @@ void exec386_dynarec(int cycs) allow the first page to be interpreted and for the page fault to occur when the page boundary is actually crossed.*/ - uint32_t phys_addr_2 = get_phys_noabrt(block->endpc) & ~0xfff; + uint32_t phys_addr_2 = get_phys_noabrt(block->endpc); page_t *page_2 = &pages[phys_addr_2 >> 12]; if ((block->phys_2 ^ phys_addr_2) & ~0xfff) valid_block = 0; - else if (block->page_mask2 & page_2->dirty_mask) + else if (block->page_mask2 & *block->dirty_mask2) { - codegen_check_flush(page_2, page_2->dirty_mask, phys_addr_2); - page_2->dirty_mask = 0; + codegen_check_flush(page_2, page_2->dirty_mask[(phys_addr_2 >> 10) & 3], phys_addr_2); + page_2->dirty_mask[(phys_addr_2 >> 10) & 3] = 0; if (!block->pc) valid_block = 0; } @@ -1537,7 +1538,7 @@ inrecomp=0; will prevent any block from spanning more than 2 pages. In practice this limit will never be hit, as host block size is only 2kB*/ - if ((cpu_state.pc - start_pc) > 4000) + if ((cpu_state.pc - start_pc) > 1000) CPU_BLOCK_END(); if (trap) @@ -1605,7 +1606,7 @@ inrecomp=0; will prevent any block from spanning more than 2 pages. In practice this limit will never be hit, as host block size is only 2kB*/ - if ((cpu_state.pc - start_pc) > 4000) + if ((cpu_state.pc - start_pc) > 1000) CPU_BLOCK_END(); if (trap) diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index d4c25ae7a..e86919c3a 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -36,6 +36,7 @@ typedef struct codeblock_t { uint64_t page_mask, page_mask2; + uint64_t *dirty_mask, *dirty_mask2; uint64_t cmp; /*Previous and next pointers, for the codeblock list associated with @@ -236,8 +237,10 @@ static __inline void codeblock_tree_delete(codeblock_t *block) } } +#define PAGE_MASK_INDEX_MASK 3 +#define PAGE_MASK_INDEX_SHIFT 10 #define PAGE_MASK_MASK 63 -#define PAGE_MASK_SHIFT 6 +#define PAGE_MASK_SHIFT 4 extern codeblock_t *codeblock; diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index e85f5315f..4805be498 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -5504,7 +5504,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) { addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ addbyte(0x3c); - addbyte(0xfd); + addbyte(0xf5); addlong((uint32_t)writelookup2); addbyte(-1); } @@ -5653,7 +5653,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) { addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ addbyte(0x3c); - addbyte(0xfd); + addbyte(0xf5); addlong((uint32_t)writelookup2); addbyte(-1); } diff --git a/src/CPU/codegen_x86-64.c b/src/CPU/codegen_x86-64.c index c5214bd4b..3ce22d95e 100644 --- a/src/CPU/codegen_x86-64.c +++ b/src/CPU/codegen_x86-64.c @@ -87,7 +87,6 @@ void codegen_init() exit(-1); } #endif -// pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); } void codegen_reset() @@ -99,25 +98,11 @@ void codegen_reset() void dump_block() { - codeblock_t *block = pages[0x119000 >> 12].block; - - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); - - block = block->next; - } - pclog("dump_block done\n"); } static void add_to_block_list(codeblock_t *block) { - codeblock_t *block_prev = pages[block->phys >> 12].block; + codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; if (!block->page_mask) fatal("add_to_block_list - mask = 0\n"); @@ -126,12 +111,12 @@ static void add_to_block_list(codeblock_t *block) { block->next = block_prev; block_prev->prev = block; - pages[block->phys >> 12].block = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; } else { block->next = NULL; - pages[block->phys >> 12].block = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; } if (block->next) @@ -142,18 +127,18 @@ static void add_to_block_list(codeblock_t *block) if (block->page_mask2) { - block_prev = pages[block->phys_2 >> 12].block_2; + block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; if (block_prev) { block->next_2 = block_prev; block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } else { block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } } } @@ -171,7 +156,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } else { - pages[block->phys >> 12].block = block->next; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; if (block->next) block->next->prev = NULL; else @@ -192,8 +177,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } else { -// pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); - pages[block->phys_2 >> 12].block_2 = block->next_2; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; if (block->next_2) block->next_2->prev_2 = NULL; else @@ -218,7 +202,7 @@ static void delete_block(codeblock_t *block) void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) { - struct codeblock_t *block = page->block; + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; while (block) { @@ -232,7 +216,7 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) block = block->next; } - block = page->block_2; + block = page->block_2[(phys_addr >> 10) & 3]; while (block) { @@ -253,17 +237,14 @@ void codegen_block_init(uint32_t phys_addr) int has_evicted = 0; page_t *page = &pages[phys_addr >> 12]; - if (!page->block) + if (!page->block[(phys_addr >> 10) & 3]) mem_flush_write_page(phys_addr, cs+cpu_state.pc); block_current = (block_current + 1) & BLOCK_MASK; block = &codeblock[block_current]; -// if (block->pc == 0xb00b4ff5) -// pclog("Init target block\n"); if (block->pc != 0) { -// pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); delete_block(block); cpu_recomp_reuse++; } @@ -275,6 +256,8 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = NULL; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; @@ -294,7 +277,7 @@ void codegen_block_start_recompile(codeblock_t *block) int has_evicted = 0; page_t *page = &pages[block->phys >> 12]; - if (!page->block) + if (!page->block[(block->phys >> 10) & 3]) mem_flush_write_page(block->phys, cs+cpu_state.pc); block_num = HASH(block->phys); @@ -360,8 +343,6 @@ void codegen_block_start_recompile(codeblock_t *block) addbyte(0xBD); addquad(((uintptr_t)&cpu_state) + 128); -// pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); - last_op32 = -1; last_ea_seg = NULL; last_ssegs = -1; @@ -405,59 +386,60 @@ void codegen_block_remove() void codegen_block_generate_end_mask() { codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = ((codegen_endpc + 3) & 0xffc) | (block->phys & ~0xfff); + uint32_t start_pc; + uint32_t end_pc; block->endpc = codegen_endpc; block->page_mask = 0; - start_pc = block->pc & 0xffc; - start_pc &= ~PAGE_MASK_MASK; - end_pc = ((block->endpc & 0xffc) + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - if (end_pc > 0xfff || end_pc < start_pc) - end_pc = 0xfff; + start_pc = (block->pc & 0x3ff) & ~15; + if ((block->pc ^ block->endpc) & ~0x3ff) + end_pc = 0x3ff & ~15; + else + end_pc = (block->endpc & 0x3ff) & ~15; + if (end_pc < start_pc) + end_pc = 0x3ff; start_pc >>= PAGE_MASK_SHIFT; end_pc >>= PAGE_MASK_SHIFT; -// pclog("block_end: %08x %08x\n", start_pc, end_pc); for (; start_pc <= end_pc; start_pc++) { block->page_mask |= ((uint64_t)1 << start_pc); -// pclog(" %08x %llx\n", start_pc, block->page_mask); } - pages[block->phys >> 12].code_present_mask |= block->page_mask; + pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; block->phys_2 = -1; block->page_mask2 = 0; block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0xfff) + if ((block->pc ^ block->endpc) & ~0x3ff) { block->phys_2 = get_phys_noabrt(block->endpc); if (block->phys_2 != -1) { -// pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2); + page_t *page_2 = &pages[block->phys_2 >> 12]; start_pc = 0; - end_pc = (block->endpc & 0xfff) >> PAGE_MASK_SHIFT; + end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; for (; start_pc <= end_pc; start_pc++) block->page_mask2 |= ((uint64_t)1 << start_pc); - - if (!pages[block->phys_2 >> 12].block_2) + page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; + + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) mem_flush_write_page(block->phys_2, block->endpc); -// pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2); + if (!block->page_mask2) fatal("!page_mask2\n"); if (block->next_2) { -// pclog(" next_2->pc=%08x\n", block->next_2->pc); if (!block->next_2->pc) fatal("block->next_2->pc=0 %p\n", (void *)block->next_2); } + + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; } } -// pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask); recomp_page = -1; } @@ -487,16 +469,6 @@ void codegen_block_end_recompile(codeblock_t *block) addbyte(cpu_state_offset(cpu_recomp_ins)); addlong(codegen_block_ins); } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - } -#endif addbyte(0x48); /*ADDL $40,%rsp*/ addbyte(0x83); addbyte(0xC4); @@ -523,7 +495,6 @@ void codegen_block_end_recompile(codeblock_t *block) block->next_2 = block->prev_2 = NULL; codegen_block_generate_end_mask(); add_to_block_list(block); -// pclog("End block %i\n", block_num); } void codegen_flush() @@ -730,7 +701,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, } return op_ea_seg; } -//#if 0 + static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { uint32_t new_eaaddr; @@ -932,7 +903,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, } return op_ea_seg; } -//#endif + void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_pc, uint32_t old_pc) { codeblock_t *block = &codeblock[block_current]; @@ -1117,17 +1088,6 @@ generate_call: addlong(codegen_block_ins); codegen_block_ins = 0; } -#if 0 - if (codegen_block_full_ins) - { - addbyte(0x81); /*ADD $codegen_block_ins,ins*/ - addbyte(0x04); - addbyte(0x25); - addlong((uint32_t)&cpu_recomp_full_ins); - addlong(codegen_block_full_ins); - codegen_block_full_ins = 0; - } -#endif } if (recomp_op_table && recomp_op_table[(opcode | op_32) & 0x1ff]) { @@ -1147,8 +1107,6 @@ generate_call: } op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; -// if (output) -// pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); if (op_ssegs != last_ssegs) { last_ssegs = op_ssegs; @@ -1157,7 +1115,7 @@ generate_call: addbyte(cpu_state_offset(ssegs)); addbyte(op_ssegs); } -//#if 0 + if ((!test_modrm || (op_table == x86_dynarec_opcodes && opcode_modrm[opcode]) || (op_table == x86_dynarec_opcodes_0f && opcode_0f_modrm[opcode]))/* && !(op_32 & 0x200)*/) @@ -1183,10 +1141,9 @@ generate_call: op_ea_seg = codegen_generate_ea_32_long(op_ea_seg, fetchdat, op_ssegs, &op_pc, stack_offset); op_pc -= pc_off; } -//#endif + if (op_ea_seg != last_ea_seg) { -// last_ea_seg = op_ea_seg; addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ addbyte(0x45); addbyte(cpu_state_offset(ea_seg)); @@ -1223,8 +1180,6 @@ generate_call: addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); -// call(block, codegen_debug); - codegen_endpc = (cs + cpu_state.pc) + 8; } diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index a4f0ffe59..50fa7bc35 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1218,25 +1218,11 @@ void codegen_reset() void dump_block() { - codeblock_t *block = pages[0x119000 >> 12].block; - - pclog("dump_block:\n"); - while (block) - { - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); - pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); - if (!block->pc) - fatal("Dead PC=0\n"); - - block = block->next; - } - pclog("dump_block done\n"); } static void add_to_block_list(codeblock_t *block) { - codeblock_t *block_prev = pages[block->phys >> 12].block; + codeblock_t *block_prev = pages[block->phys >> 12].block[(block->phys >> 10) & 3]; if (!block->page_mask) fatal("add_to_block_list - mask = 0\n"); @@ -1245,12 +1231,12 @@ static void add_to_block_list(codeblock_t *block) { block->next = block_prev; block_prev->prev = block; - pages[block->phys >> 12].block = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; } else { block->next = NULL; - pages[block->phys >> 12].block = block; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block; } if (block->next) @@ -1261,18 +1247,18 @@ static void add_to_block_list(codeblock_t *block) if (block->page_mask2) { - block_prev = pages[block->phys_2 >> 12].block_2; + block_prev = pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]; if (block_prev) { block->next_2 = block_prev; block_prev->prev_2 = block; - pages[block->phys_2 >> 12].block_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } else { block->next_2 = NULL; - pages[block->phys_2 >> 12].block_2 = block; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block; } } } @@ -1290,7 +1276,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } else { - pages[block->phys >> 12].block = block->next; + pages[block->phys >> 12].block[(block->phys >> 10) & 3] = block->next; if (block->next) block->next->prev = NULL; else @@ -1312,7 +1298,7 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) else { /* pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); */ - pages[block->phys_2 >> 12].block_2 = block->next_2; + pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; if (block->next_2) block->next_2->prev_2 = NULL; else @@ -1337,7 +1323,7 @@ static void delete_block(codeblock_t *block) void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) { - struct codeblock_t *block = page->block; + struct codeblock_t *block = page->block[(phys_addr >> 10) & 3]; while (block) { @@ -1351,7 +1337,7 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) block = block->next; } - block = page->block_2; + block = page->block_2[(phys_addr >> 10) & 3]; while (block) { @@ -1372,14 +1358,12 @@ void codegen_block_init(uint32_t phys_addr) int has_evicted = 0; page_t *page = &pages[phys_addr >> 12]; - if (!page->block) + if (!page->block[(phys_addr >> 10) & 3]) mem_flush_write_page(phys_addr, cs+cpu_state.pc); block_current = (block_current + 1) & BLOCK_MASK; block = &codeblock[block_current]; - /* if (block->pc == 0xb00b4ff5) - pclog("Init target block\n"); */ if (block->pc != 0) { /* pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); */ @@ -1394,6 +1378,8 @@ void codegen_block_init(uint32_t phys_addr) block->_cs = cs; block->pnt = block_current; block->phys = phys_addr; + block->dirty_mask = &page->dirty_mask[(phys_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; + block->dirty_mask2 = NULL; block->next = block->prev = NULL; block->next_2 = block->prev_2 = NULL; block->page_mask = 0; @@ -1412,7 +1398,7 @@ void codegen_block_start_recompile(codeblock_t *block) int has_evicted = 0; page_t *page = &pages[block->phys >> 12]; - if (!page->block) + if (!page->block[(block->phys >> 10) & 3]) mem_flush_write_page(block->phys, cs+cpu_state.pc); block_num = HASH(block->phys); @@ -1497,17 +1483,19 @@ void codegen_block_remove() void codegen_block_generate_end_mask() { codeblock_t *block = &codeblock[block_current]; - uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); - uint32_t end_pc = ((codegen_endpc + 3) & 0xffc) | (block->phys & ~0xfff); + uint32_t start_pc; + uint32_t end_pc; block->endpc = codegen_endpc; block->page_mask = 0; - start_pc = block->pc & 0xffc; - start_pc &= ~PAGE_MASK_MASK; - end_pc = ((block->endpc & 0xffc) + PAGE_MASK_MASK) & ~PAGE_MASK_MASK; - if (end_pc > 0xfff || end_pc < start_pc) - end_pc = 0xfff; + start_pc = (block->pc & 0x3ff) & ~15; + if ((block->pc ^ block->endpc) & ~0x3ff) + end_pc = 0x3ff & ~15; + else + end_pc = (block->endpc & 0x3ff) & ~15; + if (end_pc < start_pc) + end_pc = 0x3ff; start_pc >>= PAGE_MASK_SHIFT; end_pc >>= PAGE_MASK_SHIFT; @@ -1518,26 +1506,27 @@ void codegen_block_generate_end_mask() /* pclog(" %08x %llx\n", start_pc, block->page_mask); */ } - pages[block->phys >> 12].code_present_mask |= block->page_mask; + pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; block->phys_2 = -1; block->page_mask2 = 0; block->next_2 = block->prev_2 = NULL; - if ((block->pc ^ block->endpc) & ~0xfff) + if ((block->pc ^ block->endpc) & ~0x3ff) { block->phys_2 = get_phys_noabrt(block->endpc); if (block->phys_2 != -1) { - /* pclog("start block - %08x %08x %p %p %p %08x\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, (void *)pages[block->phys_2 >> 12].block_2, block->phys_2); */ + page_t *page_2 = &pages[block->phys_2 >> 12]; start_pc = 0; - end_pc = (block->endpc & 0xfff) >> PAGE_MASK_SHIFT; + end_pc = (block->endpc & 0x3ff) >> PAGE_MASK_SHIFT; for (; start_pc <= end_pc; start_pc++) block->page_mask2 |= ((uint64_t)1 << start_pc); + page_2->code_present_mask[(block->phys_2 >> 10) & 3] |= block->page_mask2; - if (!pages[block->phys_2 >> 12].block_2) + if (!pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3]) mem_flush_write_page(block->phys_2, block->endpc); - /* pclog("New block - %08x %08x %p %p phys %08x %08x %016llx\n", block->pc, block->endpc, (void *)block, (void *)block->next_2, block->phys, block->phys_2, block->page_mask2); */ + if (!block->page_mask2) fatal("!page_mask2\n"); if (block->next_2) @@ -1546,6 +1535,8 @@ void codegen_block_generate_end_mask() if (!block->next_2->pc) fatal("block->next_2->pc=0 %p\n", (void *)block->next_2); } + + block->dirty_mask2 = &page_2->dirty_mask[(block->phys_2 >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK]; } } diff --git a/src/SOUND/openal.c b/src/SOUND/openal.c index e6dd1add2..b044c0e5a 100644 --- a/src/SOUND/openal.c +++ b/src/SOUND/openal.c @@ -21,7 +21,7 @@ static ALuint source[2]; /* audio source */ #define BUFLEN SOUNDBUFLEN -void closeal(ALvoid); +void closeal(void); ALvoid alutInit(ALint *argc,ALbyte **argv) { ALCcontext *Context; @@ -62,7 +62,7 @@ void initalmain(int argc, char *argv[]) #endif } -void closeal(ALvoid) +void closeal(void) { #ifdef USE_OPENAL alutExit(); diff --git a/src/SOUND/sound.h b/src/SOUND/sound.h index d6c82fb6a..05540b403 100644 --- a/src/SOUND/sound.h +++ b/src/SOUND/sound.h @@ -43,7 +43,7 @@ void sound_reset(); void sound_cd_thread_reset(); -void closeal(ALvoid); +void closeal(void); void initalmain(int argc, char *argv[]); void inital(); void givealbuffer(float *buf); diff --git a/src/VIDEO/vid_voodoo.c b/src/VIDEO/vid_voodoo.c index 9b823e1a2..f033acdbb 100644 --- a/src/VIDEO/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -14,6 +14,15 @@ #include "vid_voodoo.h" #include "vid_voodoo_dither.h" +#ifdef MIN +#undef MIN +#endif +#ifdef ABS +#undef ABS +#endif +#ifdef CLAMP +#undef CLAMP +#endif #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -53,7 +62,6 @@ static int tris = 0; static uint64_t status_time = 0; static uint64_t voodoo_time = 0; static int voodoo_render_time[2] = {0, 0}; -static int voodoo_render_time_old[2] = {0, 0}; typedef union int_float { @@ -384,9 +392,9 @@ typedef struct voodoo_t int wake_timer; - uint8_t thefilter[256][256]; /* pixel filter, feeding from one or two */ - uint8_t thefilterg[256][256]; /* for green */ - uint8_t thefilterb[256][256]; /* for blue */ + uint8_t thefilter[256][256]; // pixel filter, feeding from one or two + uint8_t thefilterg[256][256]; // for green + uint8_t thefilterb[256][256]; // for blue /* the voodoo adds purple lines for some reason */ uint16_t purpleline[256][3]; @@ -402,7 +410,7 @@ typedef struct voodoo_t void *codegen_data; } voodoo_t; -static __inline void wait_for_render_thread_idle(voodoo_t *voodoo); +static inline void wait_for_render_thread_idle(voodoo_t *voodoo); enum { @@ -552,7 +560,6 @@ enum SST_cmdFifoHoles = 0x1f8, SST_fbiInit4 = 0x200, - SST_vRetrace = 0x204, SST_backPorch = 0x208, SST_videoDimensions = 0x20c, @@ -715,7 +722,7 @@ enum SST_remap_fdAdY = 0x00d8 | 0x400, SST_remap_fdSdY = 0x00e4 | 0x400, SST_remap_fdTdY = 0x00f0 | 0x400, - SST_remap_fdWdY = 0x00fc | 0x400 + SST_remap_fdWdY = 0x00fc | 0x400, }; enum @@ -994,10 +1001,8 @@ static void voodoo_update_ncc(voodoo_t *voodoo, int tmu) for (col = 0; col < 256; col++) { int y = (col >> 4), i = (col >> 2) & 3, q = col & 3; - int _y = (col >> 4), _i = (col >> 2) & 3, _q = col & 3; int i_r, i_g, i_b; int q_r, q_g, q_b; - int r, g, b; y = (voodoo->nccTable[tmu][tbl].y[y >> 2] >> ((y & 3) * 8)) & 0xff; @@ -1108,8 +1113,6 @@ static void voodoo_recalc_tex(voodoo_t *voodoo, int tmu) int width = 256, height = 256; int shift = 8; int lod; - int lod_min = (voodoo->params.tLOD[tmu] >> 2) & 15; - int lod_max = (voodoo->params.tLOD[tmu] >> 8) & 15; uint32_t base = voodoo->params.texBaseAddr[tmu]; int tex_lod = 0; @@ -1243,6 +1246,7 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) lod_min = (params->tLOD[tmu] >> 2) & 15; lod_max = (params->tLOD[tmu] >> 8) & 15; +// pclog(" add new texture to %i tformat=%i %08x LOD=%i-%i\n", c, voodoo->params.tformat[tmu], params->texBaseAddr[tmu], lod_min, lod_max); for (lod = lod_min; lod <= lod_max; lod++) { @@ -1251,7 +1255,10 @@ static void use_texture(voodoo_t *voodoo, voodoo_params_t *params, int tmu) int x, y; int shift = 8 - params->tex_lod[tmu][lod]; rgba_u *pal; + + //pclog(" LOD %i : %08x - %08x %i %i,%i\n", lod, params->tex_base[tmu][lod] & voodoo->texture_mask, addr, voodoo->params.tformat[tmu], voodoo->params.tex_w_mask[tmu][lod],voodoo->params.tex_h_mask[tmu][lod]); + switch (params->tformat[tmu]) { case TEX_RGB332: @@ -1489,17 +1496,17 @@ static void flush_texture_cache(voodoo_t *voodoo, uint32_t dirty_addr, int tmu) int c; memset(voodoo->texture_present[tmu], 0, sizeof(voodoo->texture_present[0])); +// pclog("Evict %08x %i\n", dirty_addr, sizeof(voodoo->texture_present)); for (c = 0; c < TEX_CACHE_MAX; c++) { if (voodoo->texture_cache[tmu][c].base != -1) { - int lod_min = (voodoo->texture_cache[tmu][c].tLOD >> 2) & 15; - int lod_max = (voodoo->texture_cache[tmu][c].tLOD >> 8) & 15; int addr_start = voodoo->texture_cache[tmu][c].addr_start; int addr_end = voodoo->texture_cache[tmu][c].addr_end; if (dirty_addr >= (addr_start & voodoo->texture_mask & ~0x3ff) && dirty_addr < (((addr_end & voodoo->texture_mask) + 0x3ff) & ~0x3ff)) { +// pclog(" Evict texture %i %08x\n", c, voodoo->texture_cache[tmu][c].base); if (voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[0] || (voodoo->render_threads == 2 && voodoo->texture_cache[tmu][c].refcount != voodoo->texture_cache[tmu][c].refcount_r[1])) @@ -1552,7 +1559,7 @@ typedef struct voodoo_state_t int32_t ib, ig, ir, ia; int32_t z; - int64_t new_depth; + int32_t new_depth; int64_t tmu0_s, tmu0_t; int64_t tmu0_w; @@ -1563,7 +1570,7 @@ typedef struct voodoo_state_t int pixel_count, texel_count; int x, x2; - uint64_t w_depth; + uint32_t w_depth; float log_temp; uint32_t ebp_store; @@ -1594,7 +1601,7 @@ static uint8_t logtable[256] = 0xf4,0xf5,0xf5,0xf6,0xf7,0xf7,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff }; -static __inline int fastlog(uint64_t val) +static inline int fastlog(uint64_t val) { uint64_t oldval = val; int exp = 63; @@ -1603,32 +1610,32 @@ static __inline int fastlog(uint64_t val) if (!val || val & (1ULL << 63)) return 0x80000000; - if (!(val & 0xffffffff00000000ll)) + if (!(val & 0xffffffff00000000)) { exp -= 32; val <<= 32; } - if (!(val & 0xffff000000000000ll)) + if (!(val & 0xffff000000000000)) { exp -= 16; val <<= 16; } - if (!(val & 0xff00000000000000ll)) + if (!(val & 0xff00000000000000)) { exp -= 8; val <<= 8; } - if (!(val & 0xf000000000000000ll)) + if (!(val & 0xf000000000000000)) { exp -= 4; val <<= 4; } - if (!(val & 0xc000000000000000ll)) + if (!(val & 0xc000000000000000)) { exp -= 2; val <<= 2; } - if (!(val & 0x8000000000000000ll)) + if (!(val & 0x8000000000000000)) { exp -= 1; val <<= 1; @@ -1642,10 +1649,11 @@ static __inline int fastlog(uint64_t val) return (exp << 8) | logtable[frac]; } -static __inline int fls(uint16_t val) +static inline int voodoo_fls(uint16_t val) { int num = 0; +//pclog("fls(%04x) = ", val); if (!(val & 0xff00)) { num += 8; @@ -1666,6 +1674,7 @@ static __inline int fls(uint16_t val) num += 1; val <<= 1; } +//pclog("%i %04x\n", num, val); return num; } @@ -1676,7 +1685,7 @@ typedef struct voodoo_texture_state_t int tex_shift; } voodoo_texture_state_t; -static __inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) +static inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int tmu) { uint32_t dat; @@ -1716,7 +1725,7 @@ static __inline void tex_read(voodoo_state_t *state, voodoo_texture_state_t *tex #define LOW4(x) ((x & 0x0f) | ((x & 0x0f) << 4)) #define HIGH4(x) ((x & 0xf0) | ((x & 0xf0) >> 4)) -static __inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) +static inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *texture_state, int s, int t, int *d, int tmu, int x) { rgba_u dat[4]; @@ -1769,9 +1778,8 @@ static __inline void tex_read_4(voodoo_state_t *state, voodoo_texture_state_t *t state->tex_a[tmu] = (dat[0].rgba.a * d[0] + dat[1].rgba.a * d[1] + dat[2].rgba.a * d[2] + dat[3].rgba.a * d[3]) >> 8; } -static __inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +static inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { - rgba_u tex_samples[4]; voodoo_texture_state_t texture_state; int d[4]; int s, t; @@ -1807,26 +1815,54 @@ static __inline void voodoo_get_texture(voodoo_t *voodoo, voodoo_params_t *param s >>= 4; t >>= 4; - +//if (x == 80) +//if (voodoo_output) +// pclog("s=%08x t=%08x _ds=%02x _dt=%02x\n", s, t, _ds, dt); d[0] = (16 - _ds) * (16 - dt); d[1] = _ds * (16 - dt); d[2] = (16 - _ds) * dt; d[3] = _ds * dt; +// texture_state.s = s; +// texture_state.t = t; tex_read_4(state, &texture_state, s, t, d, tmu, x); + + +/* state->tex_r = (tex_samples[0].rgba.r * d[0] + tex_samples[1].rgba.r * d[1] + tex_samples[2].rgba.r * d[2] + tex_samples[3].rgba.r * d[3]) >> 8; + state->tex_g = (tex_samples[0].rgba.g * d[0] + tex_samples[1].rgba.g * d[1] + tex_samples[2].rgba.g * d[2] + tex_samples[3].rgba.g * d[3]) >> 8; + state->tex_b = (tex_samples[0].rgba.b * d[0] + tex_samples[1].rgba.b * d[1] + tex_samples[2].rgba.b * d[2] + tex_samples[3].rgba.b * d[3]) >> 8; + state->tex_a = (tex_samples[0].rgba.a * d[0] + tex_samples[1].rgba.a * d[1] + tex_samples[2].rgba.a * d[2] + tex_samples[3].rgba.a * d[3]) >> 8;*/ +/* state->tex_r = tex_samples[0].r; + state->tex_g = tex_samples[0].g; + state->tex_b = tex_samples[0].b; + state->tex_a = tex_samples[0].a;*/ } else { + // rgba_t tex_samples; + // voodoo_texture_state_t texture_state; +// int s = state->tex_s >> (18+state->lod); +// int t = state->tex_t >> (18+state->lod); + // int s, t; + +// state->tex_s -= 1 << (17+state->lod); +// state->tex_t -= 1 << (17+state->lod); + s = state->tex_s >> (4+tex_lod); t = state->tex_t >> (4+tex_lod); texture_state.s = s; texture_state.t = t; tex_read(state, &texture_state, tmu); + +/* state->tex_r = tex_samples[0].rgba.r; + state->tex_g = tex_samples[0].rgba.g; + state->tex_b = tex_samples[0].rgba.b; + state->tex_a = tex_samples[0].rgba.a;*/ } } -static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) +static inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int tmu, int x) { if (params->textureMode[tmu] & 1) { @@ -1940,7 +1976,7 @@ static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, } \ else \ { \ - int fog_r, fog_g, fog_b, fog_a; \ + int fog_r, fog_g, fog_b, fog_a = 0; \ int fog_idx; \ \ if (!(params->fogMode & FOG_ADD)) \ @@ -2061,7 +2097,7 @@ static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, do \ { \ int _a; \ - int newdest_r, newdest_g, newdest_b; \ + int newdest_r = 0, newdest_g = 0, newdest_b = 0; \ \ switch (dest_afunc) \ { \ @@ -2216,12 +2252,12 @@ static __inline void voodoo_tmu_fetch(voodoo_t *voodoo, voodoo_params_t *params, #define dither2x2 (params->fbzMode & FBZ_DITHER_2x2) /*Perform texture fetch and blending for both TMUs*/ -static __inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) +static inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int x) { int r,g,b,a; int c_reverse, a_reverse; - int c_reverse1, a_reverse1; - int factor_r, factor_g, factor_b, factor_a; +// int c_reverse1, a_reverse1; + int factor_r = 0, factor_g = 0, factor_b = 0, factor_a = 0; voodoo_tmu_fetch(voodoo, params, state, 1, x); @@ -2235,8 +2271,8 @@ static __inline void voodoo_tmu_fetch_and_blend(voodoo_t *voodoo, voodoo_params_ c_reverse = !tc_reverse_blend; a_reverse = !tca_reverse_blend; } - c_reverse1 = c_reverse; - a_reverse1 = a_reverse; +/* c_reverse1 = c_reverse; + a_reverse1 = a_reverse;*/ if (tc_sub_clocal_1) { switch (tc_mselect_1) @@ -2507,6 +2543,8 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->clamp_t[0] = params->textureMode[0] & TEXTUREMODE_TCLAMPT; state->clamp_s[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPS; state->clamp_t[1] = params->textureMode[1] & TEXTUREMODE_TCLAMPT; +// int last_x; +// pclog("voodoo_triangle : bottom-half %X %X %X %X %X %i %i %i %i\n", xstart, xend, dx1, dx2, dx2 * 36, xdir, y, yend, ydir); for (c = 0; c <= LOD_MAX; c++) { @@ -2551,14 +2589,18 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood yend = params->clipHighY; state->y = ystart; +// yend--; #ifndef NO_CODEGEN if (voodoo->use_recompiler) voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even); + else + voodoo_draw = NULL; #endif if (voodoo_output) pclog("dxAB=%08x dxBC=%08x dxAC=%08x\n", state->dxAB, state->dxBC, state->dxAC); +// pclog("Start %i %i\n", ystart, voodoo->fbzMode & (1 << 17)); for (; state->y < yend; state->y++) { int x, x2; @@ -2623,7 +2665,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood state->w += (params->dWdX * dx); if (voodoo_output) - pclog("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18+state->lod), (state->tmu0_t + (1 << 17+state->lod)) >> (18+state->lod)); + pclog("%08llx %lli %lli\n", state->tmu0_t, state->tmu0_t >> (18+state->lod), (state->tmu0_t + (1 << (17+state->lod))) >> (18+state->lod)); if (params->fbzMode & 1) { @@ -2682,8 +2724,8 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (x2 > x && state->xdir < 0) goto next_line; - state->fb_mem = fb_mem = &voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; - state->aux_mem = aux_mem = &voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; + state->fb_mem = fb_mem = (uint16_t *)&voodoo->fb_mem[params->draw_offset + (real_y * voodoo->row_width)]; + state->aux_mem = aux_mem = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (real_y * voodoo->row_width)) & voodoo->fb_mask]; if (voodoo_output) pclog("%03i: x=%08x x2=%08x xstart=%08x xend=%08x dx=%08x start_x2=%08x\n", state->y, x, x2, state->xstart, state->xend, dx, start_x2); @@ -2710,17 +2752,17 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood if (voodoo_output) pclog(" X=%03i T=%08x\n", x, state->tmu0_t); +// if (voodoo->fbzMode & FBZ_RGB_WMASK) { int update = 1; uint8_t cother_r, cother_g, cother_b, aother; uint8_t clocal_r, clocal_g, clocal_b, alocal; - int src_r, src_g, src_b, src_a; + int src_r = 0, src_g = 0, src_b = 0, src_a = 0; int msel_r, msel_g, msel_b, msel_a; uint8_t dest_r, dest_g, dest_b, dest_a; uint16_t dat; - uint16_t aux_dat; int sel; - int64_t new_depth, w_depth; + int32_t new_depth, w_depth; if (state->w & 0xffff00000000) w_depth = 0; @@ -2728,13 +2770,15 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood w_depth = 0xf001; else { - int exp = fls((uint16_t)((uint32_t)state->w >> 16)); + int exp = voodoo_fls((uint16_t)((uint32_t)state->w >> 16)); int mant = ((~(uint32_t)state->w >> (19 - exp))) & 0xfff; w_depth = (exp << 12) + mant + 1; if (w_depth > 0xffff) w_depth = 0xffff; } +// w_depth = CLAMP16(w_depth); + if (params->fbzMode & FBZ_W_BUFFER) new_depth = w_depth; else @@ -3138,7 +3182,6 @@ static void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_e { voodoo_state_t state; int vertexAy_adjusted; - int vertexBy_adjusted; int vertexCy_adjusted; int dx, dy; @@ -3214,7 +3257,6 @@ static void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_e state.vertexCx |= 0xffff0000; vertexAy_adjusted = (state.vertexAy+7) >> 4; - vertexBy_adjusted = (state.vertexBy+7) >> 4; vertexCy_adjusted = (state.vertexCy+7) >> 4; if (state.vertexBy - state.vertexAy) @@ -3283,14 +3325,14 @@ static void voodoo_triangle(voodoo_t *voodoo, voodoo_params_t *params, int odd_e voodoo_half_triangle(voodoo, params, &state, vertexAy_adjusted, vertexCy_adjusted, odd_even); } -static __inline void wake_render_thread(voodoo_t *voodoo) +static inline void wake_render_thread(voodoo_t *voodoo) { thread_set_event(voodoo->wake_render_thread[0]); /*Wake up render thread if moving from idle*/ if (voodoo->render_threads == 2) thread_set_event(voodoo->wake_render_thread[1]); /*Wake up render thread if moving from idle*/ } -static __inline void wait_for_render_thread_idle(voodoo_t *voodoo) +static inline void wait_for_render_thread_idle(voodoo_t *voodoo) { while (!PARAM_EMPTY_1 || (voodoo->render_threads == 2 && !PARAM_EMPTY_2) || voodoo->render_voodoo_busy[0] || (voodoo->render_threads == 2 && voodoo->render_voodoo_busy[1])) { @@ -3343,7 +3385,7 @@ static void render_thread_2(void *param) render_thread(param, 1); } -static __inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) +static inline void queue_triangle(voodoo_t *voodoo, voodoo_params_t *params) { voodoo_params_t *params_new = &voodoo->params_buffer[voodoo->params_write_idx & PARAM_MASK]; @@ -3709,7 +3751,7 @@ static void blit_start(voodoo_t *voodoo) int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY); int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1; int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1; - int src_x, dst_x; + int dst_x; int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff; int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8); int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8); @@ -3818,7 +3860,7 @@ skip_pixel_fill: case BLIT_COMMAND_SGRAM_FILL: /*32x32 tiles - 2kb*/ dst_y = voodoo->bltDstY & 0x3ff; - size_x = voodoo->bltSizeX & 0x1ff; + size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb size_y = voodoo->bltSizeY & 0x3ff; dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) | @@ -3861,7 +3903,6 @@ skip_pixel_fill: static void blit_data(voodoo_t *voodoo, uint32_t data) { - uint32_t data_orig = data; int src_bits = 32; uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8); uint16_t *dst = (uint16_t *)&voodoo->fb_mem[base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride]; @@ -3871,8 +3912,8 @@ static void blit_data(voodoo_t *voodoo, uint32_t data) while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) { - int r, g, b; - uint16_t src_dat, dst_dat; + int r = 0, g = 0, b = 0; + uint16_t src_dat = 0, dst_dat; int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x); int rop = 0; @@ -4033,6 +4074,7 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) chip = 0xf; tempif.i = val; +//pclog("voodoo_reg_write_l: addr=%08x val=%08x(%f) chip=%x\n", addr, val, tempif.f, chip); addr &= 0x3fc; if ((voodoo->fbiInit3 & FBIINIT3_REMAP) && addr < 0x100 && ad21) @@ -4040,6 +4082,7 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) switch (addr) { case SST_swapbufferCMD: +// pclog(" start swap buffer command\n"); if (TRIPLE_BUFFER) { @@ -4056,6 +4099,7 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->params.swapbufferCMD = val; pclog("Swap buffer %08x %d %p\n", val, voodoo->swap_count, &voodoo->swap_count); +// voodoo->front_offset = params->front_offset; wait_for_render_thread_idle(voodoo); if (!(val & 1)) { @@ -4513,10 +4557,12 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) case SST_sVx: tempif.i = val; voodoo->verts[3].sVx = tempif.f; +// pclog("sVx[%i]=%f\n", voodoo->vertex_num, tempif.f); break; case SST_sVy: tempif.i = val; voodoo->verts[3].sVy = tempif.f; +// pclog("sVy[%i]=%f\n", voodoo->vertex_num, tempif.f); break; case SST_sARGB: voodoo->verts[3].sBlue = (float)(val & 0xff); @@ -4574,11 +4620,13 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) break; case SST_sBeginTriCMD: +// pclog("sBeginTriCMD %i %f\n", voodoo->vertex_num, voodoo->verts[4].sVx); voodoo->verts[0] = voodoo->verts[3]; voodoo->vertex_num = 1; voodoo->num_verticies = 1; break; case SST_sDrawTriCMD: +// pclog("sDrawTriCMD %i %i %i\n", voodoo->num_verticies, voodoo->vertex_num, voodoo->sSetupMode & SETUPMODE_STRIP_MODE); if (voodoo->vertex_num == 3) voodoo->vertex_num = (voodoo->sSetupMode & SETUPMODE_STRIP_MODE) ? 1 : 0; voodoo->verts[voodoo->vertex_num] = voodoo->verts[3]; @@ -4587,6 +4635,7 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->vertex_num++; if (voodoo->num_verticies == 3) { +// pclog("triangle_setup\n"); triangle_setup(voodoo); voodoo->num_verticies = 2; @@ -4599,11 +4648,13 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltSrcBaseAddr = val & 0x3fffff; break; case SST_bltDstBaseAddr: +// pclog("Write bltDstBaseAddr %08x\n", val); voodoo->bltDstBaseAddr = val & 0x3fffff; break; case SST_bltXYStrides: voodoo->bltSrcXYStride = val & 0xfff; voodoo->bltDstXYStride = (val >> 16) & 0xfff; +// pclog("Write bltXYStrides %08x\n", val); break; case SST_bltSrcChromaRange: voodoo->bltSrcChromaRange = val; @@ -4637,12 +4688,14 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltSrcY = (val >> 16) & 0x7ff; break; case SST_bltDstXY: +// pclog("Write bltDstXY %08x\n", val); voodoo->bltDstX = val & 0x7ff; voodoo->bltDstY = (val >> 16) & 0x7ff; if (val & (1 << 31)) blit_start(voodoo); break; case SST_bltSize: +// pclog("Write bltSize %08x\n", val); voodoo->bltSizeX = val & 0xfff; if (voodoo->bltSizeX & 0x800) voodoo->bltSizeX |= 0xfffff000; @@ -4659,12 +4712,14 @@ static void voodoo_reg_writel(uint32_t addr, uint32_t val, void *p) voodoo->bltRop[3] = (val >> 12) & 0xf; break; case SST_bltColor: +// pclog("Write bltColor %08x\n", val); voodoo->bltColorFg = val & 0xffff; voodoo->bltColorBg = (val >> 16) & 0xffff; break; case SST_bltCommand: voodoo->bltCommand = val; +// pclog("Write bltCommand %08x\n", val); if (val & (1 << 31)) blit_start(voodoo); break; @@ -5135,6 +5190,7 @@ static uint16_t voodoo_fb_readw(uint32_t addr, void *p) temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); +// pclog("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++); return temp; } static uint32_t voodoo_fb_readl(uint32_t addr, void *p) @@ -5153,10 +5209,11 @@ static uint32_t voodoo_fb_readl(uint32_t addr, void *p) temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]); +// pclog("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width); return temp; } -static __inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) +static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y) { int r, g, b; @@ -5194,11 +5251,19 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) rgba8_t colour_data; uint16_t depth_data; uint8_t alpha_data; - int write_mask; + int write_mask = 0; + + colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0; depth_data = voodoo->params.zaColor & 0xffff; alpha_data = voodoo->params.zaColor >> 24; - + +// while (!RB_EMPTY) +// thread_reset_event(voodoo->not_full_event); + +// pclog("voodoo_fb_writew : %08X %04X\n", addr, val); + + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { case LFB_FORMAT_RGB565: @@ -5233,6 +5298,8 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + +// pclog("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr); if (voodoo->lfbMode & 0x100) { @@ -5256,7 +5323,7 @@ static void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p) if (params->fogMode & FOG_ENABLE) { int32_t z = new_depth << 12; - int64_t w_depth = new_depth; + int64_t w_depth = (int64_t)(int32_t)new_depth; int32_t ia = alpha_data << 12; APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth); @@ -5309,11 +5376,15 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) rgba8_t colour_data[2]; uint16_t depth_data[2]; uint8_t alpha_data[2]; - int write_mask, count = 1; + int write_mask = 0, count = 1; depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff; alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24; - +// while (!RB_EMPTY) +// thread_reset_event(voodoo->not_full_event); + +// pclog("voodoo_fb_writel : %08X %08X\n", addr, val); + switch (voodoo->lfbMode & LFB_FORMAT_MASK) { case LFB_FORMAT_RGB565: @@ -5365,6 +5436,8 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width); write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width); + +// pclog("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset); if (voodoo->lfbMode & 0x100) { @@ -5457,6 +5530,8 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) if (tmu && !voodoo->dual_tmus) return; +// pclog("voodoo_tex_writel : %08X %08X %i\n", addr, val, voodoo->params.tformat); + lod = (addr >> 17) & 0xf; t = (addr >> 9) & 0xff; if (voodoo->params.tformat[tmu] & 8) @@ -5471,20 +5546,24 @@ static void voodoo_tex_writel(uint32_t addr, uint32_t val, void *p) if (lod > LOD_MAX) return; - + +// if (addr >= 0x200000) +// return; + if (voodoo->params.tformat[tmu] & 8) addr = voodoo->params.tex_base[tmu][lod] + s*2 + (t << voodoo->params.tex_shift[tmu][lod])*2; else addr = voodoo->params.tex_base[tmu][lod] + s + (t << voodoo->params.tex_shift[tmu][lod]); if (voodoo->texture_present[tmu][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) { +// pclog("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT); flush_texture_cache(voodoo, addr & voodoo->texture_mask, tmu); } *(uint32_t *)(&voodoo->tex_mem[tmu][addr & voodoo->texture_mask]) = val; } #define WAKE_DELAY (TIMER_USEC * 100) -static __inline void wake_fifo_thread(voodoo_t *voodoo) +static inline void wake_fifo_thread(voodoo_t *voodoo) { if (!voodoo->wake_timer) { @@ -5498,7 +5577,7 @@ static __inline void wake_fifo_thread(voodoo_t *voodoo) } } -static __inline void wake_fifo_thread_now(voodoo_t *voodoo) +static inline void wake_fifo_thread_now(voodoo_t *voodoo) { thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -5512,10 +5591,9 @@ static void voodoo_wake_timer(void *p) thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } -static __inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) +static inline void queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val) { fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK]; - int c; if (FIFO_FULL) { @@ -5772,7 +5850,9 @@ static void voodoo_pixelclock_update(voodoo_t *voodoo) t /= 2.0f; line_length = (voodoo->hSync & 0xff) + ((voodoo->hSync >> 16) & 0x3ff); - + +// pclog("Pixel clock %f MHz hsync %08x line_length %d\n", t, voodoo->hSync, line_length); + voodoo->pixel_clock = t; clock_const = cpuclock / t; @@ -5782,13 +5862,7 @@ static void voodoo_pixelclock_update(voodoo_t *voodoo) static void voodoo_writel(uint32_t addr, uint32_t val, void *p) { voodoo_t *voodoo = (voodoo_t *)p; - union - { - uint32_t i; - float f; - } tempif; - tempif.i = val; voodoo->wr_count++; addr &= 0xffffff; @@ -5810,6 +5884,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) } else if ((addr & 0x200000) && (voodoo->fbiInit7 & FBIINIT7_CMDFIFO_ENABLE)) { +// pclog("Write CMDFIFO %08x(%08x) %08x %08x\n", addr, voodoo->cmdfifo_base + (addr & 0x3fffc), val, (voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask); *(uint32_t *)&voodoo->fb_mem[(voodoo->cmdfifo_base + (addr & 0x3fffc)) & voodoo->fb_mask] = val; voodoo->cmdfifo_depth_wr++; if ((voodoo->cmdfifo_depth_wr - voodoo->cmdfifo_depth_rd) < 20) @@ -5872,6 +5947,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) { voodoo->fbiInit4 = val; voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); +// pclog("fbiInit4 write %08x - read_time=%i\n", val, voodoo->read_time); } break; case SST_backPorch: @@ -5904,6 +5980,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->fbiInit1 = val; voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); +// pclog("fbiInit1 write %08x - write_time=%i burst_time=%i\n", val, voodoo->write_time, voodoo->burst_time); } break; case SST_fbiInit2: @@ -5946,6 +6023,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->dac_readdata = 0xff; if (val & 0x800) { +// pclog(" dacData read %i %02X\n", voodoo->dac_reg, voodoo->dac_data[7]); if (voodoo->dac_reg == 5) { switch (voodoo->dac_data[7]) @@ -5956,7 +6034,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) } } else - voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata]; + voodoo->dac_readdata = voodoo->dac_data[voodoo->dac_readdata & 7]; } else { @@ -5966,6 +6044,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff00) | val; else voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] = (voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf] & 0xff) | (val << 8); +// pclog("Write PLL reg %x %04x\n", voodoo->dac_data[4] & 0xf, voodoo->dac_pll_regs[voodoo->dac_data[4] & 0xf]); voodoo->dac_reg_ff = !voodoo->dac_reg_ff; if (!voodoo->dac_reg_ff) voodoo->dac_data[4]++; @@ -6009,6 +6088,7 @@ static void voodoo_writel(uint32_t addr, uint32_t val, void *p) case SST_cmdFifoBaseAddr: voodoo->cmdfifo_base = (val & 0x3ff) << 12; voodoo->cmdfifo_end = ((val >> 16) & 0x3ff) << 12; +// pclog("CMDFIFO base=%08x end=%08x\n", voodoo->cmdfifo_base, voodoo->cmdfifo_end); break; case SST_cmdFifoRdPtr: @@ -6053,10 +6133,11 @@ static uint32_t cmdfifo_get(voodoo_t *voodoo) voodoo->cmdfifo_depth_rd++; voodoo->cmdfifo_rp += 4; +// pclog(" CMDFIFO get %08x\n", val); return val; } -static __inline float cmdfifo_get_f(voodoo_t *voodoo) +static inline float cmdfifo_get_f(voodoo_t *voodoo) { union { @@ -6137,10 +6218,13 @@ static void fifo_thread(void *param) int num; int num_verticies; int v_num; - + +// pclog(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp); + switch (header & 7) { case 0: +// pclog("CMDFIFO0\n"); switch ((header >> 3) & 7) { case 0: /*NOP*/ @@ -6148,6 +6232,7 @@ static void fifo_thread(void *param) case 3: /*JMP local frame buffer*/ voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc; +// pclog("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header); break; default: @@ -6158,6 +6243,7 @@ static void fifo_thread(void *param) case 1: num = header >> 16; addr = (header & 0x7ff8) >> 1; +// pclog("CMDFIFO1 addr=%08x\n",addr); while (num--) { uint32_t val = cmdfifo_get(voodoo); @@ -6174,13 +6260,15 @@ static void fifo_thread(void *param) case 3: num = (header >> 29) & 7; - mask = header; + mask = header;//(header >> 10) & 0xff; smode = (header >> 22) & 0xf; voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo); num_verticies = (header >> 6) & 0xf; v_num = 0; if (((header >> 3) & 7) == 2) v_num = 1; +// pclog("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff); +// pclog("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7); while (num_verticies--) { @@ -6237,6 +6325,7 @@ static void fifo_thread(void *param) num = (header >> 29) & 7; mask = (header >> 15) & 0x3fff; addr = (header & 0x7ff8) >> 1; +// pclog("CMDFIFO4 addr=%08x\n",addr); while (mask) { if (mask & 1) @@ -6261,6 +6350,7 @@ static void fifo_thread(void *param) fatal("CMDFIFO packet 5 has byte disables set %08x\n", header); num = (header >> 3) & 0x7ffff; addr = cmdfifo_get(voodoo) & 0xffffff; +// pclog("CMDFIFO5 addr=%08x num=%i\n", addr, num); switch (header >> 30) { case 2: /*Framebuffer*/ @@ -6318,6 +6408,8 @@ uint8_t voodoo_pci_read(int func, int addr, void *p) if (func) return 0; +// pclog("Voodoo PCI read %08X PC=%08x\n", addr, cpu_state.pc); + switch (addr) { case 0x00: return 0x1a; /*3dfx*/ @@ -6363,6 +6455,8 @@ void voodoo_pci_write(int func, int addr, uint8_t val, void *p) if (func) return; +// pclog("Voodoo PCI write %04X %02X PC=%08x\n", addr, val, cpu_state.pc); + switch (addr) { case 0x04: @@ -6409,7 +6503,10 @@ static void voodoo_calc_clutData(voodoo_t *voodoo) int r = (c >> 8) & 0xf8; int g = (c >> 3) & 0xfc; int b = (c << 3) & 0xf8; - +// r |= (r >> 5); +// g |= (g >> 6); +// b |= (b >> 5); + voodoo->video_16to32[c] = (voodoo->clutData256[r].r << 16) | (voodoo->clutData256[g].g << 8) | voodoo->clutData256[b].b; } } @@ -6431,9 +6528,9 @@ static void voodoo_generate_filter_v1(voodoo_t *voodoo) fcg = FILTCAPG * 6; fcb = FILTCAPB * 5; - for (g=0;g -fcr)) thiscol = g + (difference / 2); if ((diffg < fcg) || (-diffg > -fcg)) @@ -6504,7 +6606,7 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) float clr, clg, clb = 0; float fcr, fcg, fcb = 0; - /* pre-clamping */ + // pre-clamping fcr = FILTCAP; fcg = FILTCAPG; @@ -6514,9 +6616,9 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) if (fcg > 32) fcg = 32; if (fcb > 32) fcb = 32; - for (g=0;g<256;g++) /* pixel 1 - our target pixel we want to bleed into */ + for (g=0;g<256;g++) // pixel 1 - our target pixel we want to bleed into { - for (h=0;h<256;h++) /* pixel 2 - our main pixel */ + for (h=0;h<256;h++) // pixel 2 - our main pixel { float avg; float avgdiff; @@ -6529,7 +6631,7 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) thiscol = thiscolg = thiscolb = g; - /* try lighten */ + // try lighten if (h > g) { clr = clg = clb = avgdiff; @@ -6567,7 +6669,7 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) if (difference > FILTCAPB) thiscolb = g; - /* clamp */ + // clamp if (thiscol < 0) thiscol = 0; if (thiscolg < 0) thiscolg = 0; if (thiscolb < 0) thiscolb = 0; @@ -6576,10 +6678,14 @@ static void voodoo_generate_filter_v2(voodoo_t *voodoo) if (thiscolg > 255) thiscolg = 255; if (thiscolb > 255) thiscolb = 255; - /* add to the table */ + // add to the table voodoo->thefilter[g][h] = (thiscol); voodoo->thefilterg[g][h] = (thiscolg); voodoo->thefilterb[g][h] = (thiscolb); + + // debug the ones that don't give us much of a difference + //if (difference < FILTCAP) + //pclog("Voodoofilter: %ix%i - %f difference, %f average difference, R=%f, G=%f, B=%f\n", g, h, difference, avgdiff, thiscol, thiscolg, thiscolb); } lined = g + 3; @@ -6624,7 +6730,7 @@ static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uin { int x; - /* Scratchpad for avoiding feedback streaks */ + // Scratchpad for avoiding feedback streaks uint8_t fil3[(voodoo->h_disp) * 3]; /* 16 to 32-bit */ @@ -6634,7 +6740,7 @@ static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uin fil[x*3+1] = (((src[x] >> 5) & 63) << 2); fil[x*3+2] = (((src[x] >> 11) & 31) << 3); - /* Copy to our scratchpads */ + // Copy to our scratchpads fil3[x*3+0] = fil[x*3+0]; fil3[x*3+1] = fil[x*3+1]; fil3[x*3+2] = fil[x*3+2]; @@ -6690,13 +6796,13 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin { int x; - /* Scratchpad for blending filter */ + // Scratchpad for blending filter uint8_t fil3[(voodoo->h_disp) * 3]; /* 16 to 32-bit */ for (x=0; x> 5) & 63) << 2); fil3[x*3+2] = fil[x*3+2] = (((src[x] >> 11) & 31) << 3); @@ -6723,7 +6829,7 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin fil[(x-1)*3+2] = voodoo->thefilter [fil3[(x-1)*3+2]][(((src[x] >> 11) & 31) << 3)]; } - /* unroll for edge cases */ + // unroll for edge cases fil3[(column-3)*3] = voodoo->thefilterb [((src[column-3] & 31) << 3)] [((src[column] & 31) << 3)]; fil3[(column-3)*3+1] = voodoo->thefilterg [(((src[column-3] >> 5) & 63) << 2)] [(((src[column] >> 5) & 63) << 2)]; @@ -6779,7 +6885,6 @@ void voodoo_callback(void *p) if (voodoo->scrfilter && voodoo->scrfilterEnabled) { - int j, offset; uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */ if (voodoo->type == VOODOO_2) @@ -6804,6 +6909,7 @@ void voodoo_callback(void *p) } if (voodoo->line == voodoo->v_disp) { +// pclog("retrace %i %i %08x %i\n", voodoo->retrace_count, voodoo->swap_interval, voodoo->swap_offset, voodoo->swap_pending); voodoo->retrace_count++; if (voodoo->swap_pending && (voodoo->retrace_count > voodoo->swap_interval)) { @@ -6898,6 +7004,7 @@ static void voodoo_speed_changed(void *p) voodoo->read_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit4 & 1) ? 2 : 1); voodoo->write_time = pci_nonburst_time + pci_burst_time * ((voodoo->fbiInit1 & 2) ? 1 : 0); voodoo->burst_time = pci_burst_time * ((voodoo->fbiInit1 & 2) ? 2 : 1); +// pclog("Voodoo read_time=%i write_time=%i burst_time=%i %08x %08x\n", voodoo->read_time, voodoo->write_time, voodoo->burst_time, voodoo->fbiInit1, voodoo->fbiInit4); } void *voodoo_init() @@ -7039,7 +7146,9 @@ void *voodoo_init() void voodoo_close(void *p) { +#ifndef RELEASE_BUILD FILE *f; +#endif voodoo_t *voodoo = (voodoo_t *)p; int c; @@ -7086,77 +7195,111 @@ void voodoo_close(void *p) static device_config_t voodoo_config[] = { { - "type", "Voodoo type", CONFIG_SELECTION, "", 0, + .name = "type", + .description = "Voodoo type", + .type = CONFIG_SELECTION, + .selection = { { - "Voodoo Graphics", VOODOO_1 + .description = "Voodoo Graphics", + .value = VOODOO_1 }, { - "Obsidian SB50 + Amethyst (2 TMUs)", VOODOO_SB50 + .description = "Obsidian SB50 + Amethyst (2 TMUs)", + .value = VOODOO_SB50 }, { - "Voodoo 2", VOODOO_2 + .description = "Voodoo 2", + .value = VOODOO_2 }, { - "" + .description = "" } - } + }, + .default_int = 0 }, { - "framebuffer_memory", "Framebuffer memory size", CONFIG_SELECTION, "", 2, + .name = "framebuffer_memory", + .description = "Framebuffer memory size", + .type = CONFIG_SELECTION, + .selection = { { - "2 MB", 2 + .description = "2 MB", + .value = 2 }, { - "4 MB", 4 + .description = "4 MB", + .value = 4 }, { - "" + .description = "" } - } + }, + .default_int = 2 }, { - "texture_memory", "Texture memory size", CONFIG_SELECTION, "", 2, + .name = "texture_memory", + .description = "Texture memory size", + .type = CONFIG_SELECTION, + .selection = { { - "2 MB", 2 + .description = "2 MB", + .value = 2 }, { - "4 MB",4 + .description = "4 MB", + .value = 4 }, { - "" + .description = "" } - } + }, + .default_int = 2 }, { - "render_threads", "Render threads", CONFIG_SELECTION, "", 2, + .name = "bilinear", + .description = "Bilinear filtering", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "dacfilter", + .description = "Screen Filter", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "render_threads", + .description = "Render threads", + .type = CONFIG_SELECTION, + .selection = { { - "1", 1 + .description = "1", + .value = 1 }, { - "2", 2 + .description = "2", + .value = 2 }, { - "" + .description = "" } - } - }, - { - "bilinear", "Bilinear filtering", CONFIG_BINARY, "", 1 - }, - { - "dacfilter", "Screen Filter", CONFIG_BINARY, "", 0 + }, + .default_int = 2 }, #ifndef NO_CODEGEN { - "recompiler", "Recompiler", CONFIG_BINARY, "", 1 + .name = "recompiler", + .description = "Recompiler", + .type = CONFIG_BINARY, + .default_int = 1 }, #endif { - "", "", -1 + .type = -1 } }; diff --git a/src/VIDEO/vid_voodoo_codegen_x86-64.h b/src/VIDEO/vid_voodoo_codegen_x86-64.h index 1caa67311..160708b93 100644 --- a/src/VIDEO/vid_voodoo_codegen_x86-64.h +++ b/src/VIDEO/vid_voodoo_codegen_x86-64.h @@ -42,26 +42,26 @@ static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; #define addbyte(val) \ - code_block[block_pos++] = (uint8_t)val; \ + code_block[block_pos++] = val; \ if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = (uint16_t)val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ +#define addword(val) \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = (uint32_t)val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ +#define addlong(val) \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = (uint64_t)val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ +#define addquad(val) \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") @@ -70,7 +70,6 @@ static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; static __m128i xmm_ff_b;// = 0x00000000ffffffffull; static uint32_t zero = 0; -static double const_1_48 = (double)(1ull << 4); static __m128i alookup[257], aminuslookup[256]; static __m128i minus_254;// = 0xff02ff02ff02ff02ull; @@ -161,7 +160,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x0f); /*MOVZX EAX, logtable[RAX]*/ addbyte(0xb6); addbyte(0x80); - addlong((uint32_t)logtable); + addlong((uint32_t)(uintptr_t)logtable); addbyte(0x09); /*OR EAX, EDX*/ addbyte(0xd0); addbyte(0x03); /*ADD EAX, state->lod*/ @@ -339,7 +338,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x48); addbyte(0x14); addbyte(0x25); - addlong(&zero); + addlong((uint32_t)(uintptr_t)&zero); addbyte(0x3b); /*CMP EDX, params->tex_h_mask[ESI]*/ addbyte(0x96); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -353,7 +352,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x48); addbyte(0x1c); addbyte(0x25); - addlong(&zero); + addlong((uint32_t)(uintptr_t)&zero); addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -400,7 +399,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x48); addbyte(0x04); addbyte(0x25); - addlong(&zero); + addlong((uint32_t)(uintptr_t)&zero); addbyte(0x78); /*JS + - clamp on 0*/ addbyte(2+3+2+ 5+5+2); addbyte(0x3b); /*CMP EAX, EBP*/ @@ -501,7 +500,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x49); /*MOV R8, bilinear_lookup*/ addbyte(0xb8); - addquad(bilinear_lookup); + addquad((uintptr_t)bilinear_lookup); addbyte(0x66); /*PUNPCKLBW XMM0, XMM2*/ addbyte(0x0f); @@ -615,7 +614,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x48); addbyte(0x04); addbyte(0x25); - addlong(&zero); + addlong((uint32_t)(uintptr_t)&zero); addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI+ECX*4]*/ addbyte(0x84); addbyte(0x8e); @@ -642,7 +641,7 @@ static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, v addbyte(0x48); addbyte(0x1c); addbyte(0x25); - addlong(&zero); + addlong((uint32_t)(uintptr_t)&zero); addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI+ECX*4]*/ addbyte(0x9c); addbyte(0x8e); @@ -1080,7 +1079,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xef); addbyte(0x83); - addlong((uint32_t)&xmm_00_ff_w[0]); + addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]); } else if (!tc_reverse_blend_1) { @@ -1089,14 +1088,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xef); addbyte(0x04); addbyte(0x25); - addlong((uint32_t)&xmm_ff_w); + addlong((uint32_t)(uintptr_t)&xmm_ff_w); } addbyte(0x66); /*PADDW XMM0, xmm_01_w*/ addbyte(0x0f); addbyte(0xfd); addbyte(0x04); addbyte(0x25); - addlong((uint32_t)&xmm_01_w); + addlong((uint32_t)(uintptr_t)&xmm_01_w); addbyte(0xf3); /*MOVQ XMM1, XMM2*/ addbyte(0x0f); addbyte(0x7e); @@ -1217,7 +1216,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x33); /*XOR EAX, i_00_ff_w[ECX*4]*/ addbyte(0x04); addbyte(0x8d); - addlong((uint32_t)i_00_ff_w); + addlong((uint32_t)(uintptr_t)i_00_ff_w); } else if (!tc_reverse_blend_1) { @@ -1404,7 +1403,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xef); addbyte(0xa3); - addlong((uint32_t)&xmm_00_ff_w[0]); + addlong((uint32_t)(uintptr_t)&xmm_00_ff_w[0]); } else if (!tc_reverse_blend) { @@ -1413,14 +1412,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xef); addbyte(0x24); addbyte(0x25); - addlong(&xmm_ff_w); + addlong((uint32_t)(uintptr_t)&xmm_ff_w); } addbyte(0x66); /*PADDW XMM4, 1*/ addbyte(0x0f); addbyte(0xfd); addbyte(0x24); addbyte(0x25); - addlong(&xmm_01_w); + addlong((uint32_t)(uintptr_t)&xmm_01_w); addbyte(0xf3); /*MOVQ XMM5, XMM1*/ addbyte(0x0f); addbyte(0x7e); @@ -1488,7 +1487,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x0f); addbyte(0xef); addbyte(0x0d); - addlong(&xmm_ff_w); + addlong((uint32_t)(uintptr_t)&xmm_ff_w); } addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ @@ -1585,7 +1584,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x33); /*XOR EBX, i_00_ff_w[ECX*4]*/ addbyte(0x1c); addbyte(0x8d); - addlong((uint32_t)i_00_ff_w); + addlong((uint32_t)(uintptr_t)i_00_ff_w); } else if (!tca_reverse_blend) { @@ -2143,14 +2142,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xef); addbyte(0x1c); addbyte(0x25); - addlong(&xmm_ff_w); + addlong((uint32_t)(uintptr_t)&xmm_ff_w); } addbyte(0x66); /*PADDW XMM3, 1*/ addbyte(0x0f); addbyte(0xfd); addbyte(0x1c); addbyte(0x25); - addlong(&xmm_01_w); + addlong((uint32_t)(uintptr_t)&xmm_01_w); addbyte(0x66); /*PMULLW XMM0, XMM3*/ addbyte(0x0f); addbyte(0xd5); @@ -2194,7 +2193,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xef); addbyte(0x04); addbyte(0x25); - addlong(&xmm_ff_b); + addlong((uint32_t)(uintptr_t)&xmm_ff_b); } if (params->fogMode & FOG_ENABLE) @@ -2441,7 +2440,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x49); /*MOV R8, rgb565*/ addbyte(0xb8); - addquad(rgb565); + addquad((uintptr_t)rgb565); addbyte(0x8b); /*MOV EAX, state->x[EDI]*/ addbyte(0x87); addlong(offsetof(voodoo_state_t, x)); @@ -2489,7 +2488,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0x24); addbyte(0xd5); - addlong(alookup); + addlong((uint32_t)(uintptr_t)alookup); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); @@ -2499,7 +2498,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x24); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2529,7 +2528,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x24); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2555,7 +2554,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0x24); addbyte(0xd5); - addlong(aminuslookup); + addlong((uint32_t)(uintptr_t)aminuslookup); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); @@ -2565,7 +2564,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x24); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2587,7 +2586,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0x2c); addbyte(0x25); - addlong(&xmm_ff_w); + addlong((uint32_t)(uintptr_t)&xmm_ff_w); addbyte(0x66); /*PSUBW XMM5, XMM0*/ addbyte(0x0f); addbyte(0xf9); @@ -2605,7 +2604,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x24); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2633,7 +2632,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0x24); addbyte(0xd5); - addlong(&minus_254); + addlong((uint32_t)(uintptr_t)&minus_254); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); @@ -2643,7 +2642,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x24); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2674,7 +2673,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0x04); addbyte(0xd5); - addlong(alookup); + addlong((uint32_t)(uintptr_t)alookup); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2684,7 +2683,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x04); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2714,7 +2713,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x04); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2740,7 +2739,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xd5); addbyte(0x04); addbyte(0xd5); - addlong(aminuslookup); + addlong((uint32_t)(uintptr_t)aminuslookup); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2750,7 +2749,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x04); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2772,7 +2771,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x7e); addbyte(0x2c); addbyte(0x25); - addlong(&xmm_ff_w); + addlong((uint32_t)(uintptr_t)&xmm_ff_w); addbyte(0x66); /*PSUBW XMM5, XMM6*/ addbyte(0x0f); addbyte(0xf9); @@ -2790,7 +2789,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0xfd); addbyte(0x04); addbyte(0x25); - addlong((uint32_t)alookup + 16); + addlong((uint32_t)(uintptr_t)alookup + 16); addbyte(0x66); /*PSRLW XMM5, 8*/ addbyte(0x0f); addbyte(0x71); @@ -2842,7 +2841,7 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo { addbyte(0x49); /*MOV R8, dither_rb*/ addbyte(0xb8); - addquad(dither2x2 ? dither_rb2x2 : dither_rb); + addquad(dither2x2 ? (uintptr_t)dither_rb2x2 : (uintptr_t)dither_rb); addbyte(0x4c); /*MOV ESI, real_y (R14)*/ addbyte(0x89); addbyte(0xf6); diff --git a/src/VIDEO/vid_voodoo_codegen_x86.h b/src/VIDEO/vid_voodoo_codegen_x86.h index 54c09a1bc..5a9f65e46 100644 --- a/src/VIDEO/vid_voodoo_codegen_x86.h +++ b/src/VIDEO/vid_voodoo_codegen_x86.h @@ -40,43 +40,43 @@ static int last_block[2] = {0, 0}; static int next_block_to_write[2] = {0, 0}; #define addbyte(val) \ - code_block[block_pos++] = (uint8_t)val; \ + code_block[block_pos++] = val; \ if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addword(val) \ - *(uint16_t *)&code_block[block_pos] = (uint16_t)val; \ - block_pos += 2; \ - if (block_pos >= BLOCK_SIZE) \ +#define addword(val) \ + *(uint16_t *)&code_block[block_pos] = val; \ + block_pos += 2; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addlong(val) \ - *(uint32_t *)&code_block[block_pos] = (uint32_t)val; \ - block_pos += 4; \ - if (block_pos >= BLOCK_SIZE) \ +#define addlong(val) \ + *(uint32_t *)&code_block[block_pos] = val; \ + block_pos += 4; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -#define addquad(val) \ - *(uint64_t *)&code_block[block_pos] = (uint64_t)val; \ - block_pos += 8; \ - if (block_pos >= BLOCK_SIZE) \ +#define addquad(val) \ + *(uint64_t *)&code_block[block_pos] = val; \ + block_pos += 8; \ + if (block_pos >= BLOCK_SIZE) \ fatal("Over!\n") -static __m128i xmm_01_w; -static __m128i xmm_ff_w; -static __m128i xmm_ff_b; +static __m128i xmm_01_w;// = 0x0001000100010001ull; +static __m128i xmm_ff_w;// = 0x00ff00ff00ff00ffull; +static __m128i xmm_ff_b;// = 0x00000000ffffffffull; static uint32_t zero = 0; static double const_1_48 = (double)(1ull << 4); static __m128i alookup[257], aminuslookup[256]; -static __m128i minus_254; +static __m128i minus_254;// = 0xff02ff02ff02ff02ull; static __m128i bilinear_lookup[256*2]; static __m128i xmm_00_ff_w[2]; static uint32_t i_00_ff_w[2] = {0, 0xff}; -static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) +static inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int block_pos, int tmu) { if (params->textureMode[tmu] & 1) { @@ -85,7 +85,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addlong(tmu ? offsetof(voodoo_state_t, tmu1_w) : offsetof(voodoo_state_t, tmu0_w)); addbyte(0xdd); /*FLDq const_1_48*/ addbyte(0x05); - addlong(&const_1_48); + addlong((uint32_t)&const_1_48); addbyte(0xde); /*FDIV ST(1)*/ addbyte(0xf1); addbyte(0xdf); /*FILDq state->tmu0_s*/ @@ -129,7 +129,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x0f); /*MOVZX EBX, logtable[EBX]*/ addbyte(0xb6); addbyte(0x9b); - addlong(logtable); + addlong((uint32_t)logtable); addbyte(0x09); /*OR EAX, EBX*/ addbyte(0xd8); addbyte(0x03); /*ADD EAX, state->lod*/ @@ -322,7 +322,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x0f); /*CMOVS EDX, zero*/ addbyte(0x48); addbyte(0x15); - addlong(&zero); + addlong((uint32_t)&zero); addbyte(0x3b); /*CMP EDX, params->tex_h_mask[ESI]*/ addbyte(0x96); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -335,7 +335,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x0f); /*CMOVS EBX, zero*/ addbyte(0x48); addbyte(0x1d); - addlong(&zero); + addlong((uint32_t)&zero); addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI]*/ addbyte(0x9e); addlong(offsetof(voodoo_params_t, tex_h_mask[tmu])); @@ -379,7 +379,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x0f); /*CMOVS EAX, zero*/ addbyte(0x48); addbyte(0x05); - addlong(&zero); + addlong((uint32_t)&zero); addbyte(0x78); /*JS + - clamp on 0*/ addbyte(2+3+2+ 5+5+2); addbyte(0x3b); /*CMP EAX, EBP*/ @@ -489,7 +489,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x81); /*ADD ESI, bilinear_lookup*/ addbyte(0xc6); - addlong(bilinear_lookup); + addlong((uint32_t)bilinear_lookup); addbyte(0x66); /*PMULLW XMM0, bilinear_lookup[ESI]*/ addbyte(0x0f); @@ -592,7 +592,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x0f); /*CMOVS EAX, zero*/ addbyte(0x48); addbyte(0x05); - addlong(&zero); + addlong((uint32_t)&zero); addbyte(0x3b); /*CMP EAX, params->tex_w_mask[ESI+ECX*4]*/ addbyte(0x84); addbyte(0x8e); @@ -618,7 +618,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, addbyte(0x0f); /*CMOVS EBX, zero*/ addbyte(0x48); addbyte(0x1d); - addlong(&zero); + addlong((uint32_t)&zero); addbyte(0x3b); /*CMP EBX, params->tex_h_mask[ESI+ECX*4]*/ addbyte(0x9c); addbyte(0x8e); @@ -653,7 +653,7 @@ static __inline int codegen_texture_fetch(uint8_t *code_block, voodoo_t *voodoo, return block_pos; } -static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) +static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int depthop) { int block_pos = 0; int z_skip_pos = 0; @@ -662,10 +662,24 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood int depth_jump_pos = 0; int depth_jump_pos2 = 0; int loop_jump_pos = 0; +// xmm_01_w = (__m128i)0x0001000100010001ull; +// xmm_ff_w = (__m128i)0x00ff00ff00ff00ffull; +// xmm_ff_b = (__m128i)0x00000000ffffffffull; xmm_01_w = _mm_set_epi32(0, 0, 0x00010001, 0x00010001); xmm_ff_w = _mm_set_epi32(0, 0, 0x00ff00ff, 0x00ff00ff); xmm_ff_b = _mm_set_epi32(0, 0, 0, 0x00ffffff); minus_254 = _mm_set_epi32(0, 0, 0xff02ff02, 0xff02ff02); +// *(uint64_t *)&const_1_48 = 0x45b0000000000000ull; +// block_pos = 0; +// voodoo_get_depth = &code_block[block_pos]; + /*W at (%esp+4) + Z at (%esp+12) + new_depth at (%esp+16)*/ +// if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depth_op == DEPTHOP_NEVER)) +// { +// addbyte(0xC3); /*RET*/ +// return; +// } addbyte(0x55); /*PUSH EBP*/ addbyte(0x57); /*PUSH EDI*/ addbyte(0x56); /*PUSH ESI*/ @@ -697,6 +711,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x75); /*JNZ got_depth*/ depth_jump_pos = block_pos; addbyte(0); +// addbyte(4+5+2+3+2+5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0x8b); /*MOV EDX, w*/ addbyte(0x97); addlong(offsetof(voodoo_state_t, w)); @@ -710,6 +725,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x74); /*JZ got_depth*/ depth_jump_pos2 = block_pos; addbyte(0); +// addbyte(5+5+3+2+2+2+/*3+*/3+2+6+4+5+2+3); addbyte(0xb9); /*MOV ECX, 19*/ addlong(19); addbyte(0x0f); /*BSR EAX, EDX*/ @@ -875,8 +891,17 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood else if ((params->fbzMode & FBZ_DEPTH_ENABLE) && (depthop == DEPTHOP_NEVER)) { addbyte(0xC3); /*RET*/ +// addbyte(0x30); /*XOR EAX, EAX*/ +// addbyte(0xc0); } +// else +// { +// addbyte(0xb0); /*MOV AL, 1*/ +// addbyte(1); +// } + +// voodoo_combine = &code_block[block_pos]; /*XMM0 = colour*/ /*XMM2 = 0 (for unpacking*/ @@ -1367,13 +1392,13 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0xef); addbyte(0x25); - addlong(&xmm_ff_w); + addlong((uint32_t)&xmm_ff_w); } addbyte(0x66); /*PADDW XMM4, 1*/ addbyte(0x0f); addbyte(0xfd); addbyte(0x25); - addlong(&xmm_01_w); + addlong((uint32_t)&xmm_01_w); addbyte(0xf3); /*MOVQ XMM5, XMM1*/ addbyte(0x0f); addbyte(0x7e); @@ -1441,7 +1466,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0xef); addbyte(0x0d); - addlong(&xmm_ff_w); + addlong((uint32_t)&xmm_ff_w); } addbyte(0x66); /*PACKUSWB XMM0, XMM0*/ @@ -2096,13 +2121,13 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0xef); addbyte(0x1d); - addlong(&xmm_ff_w); + addlong((uint32_t)&xmm_ff_w); } addbyte(0x66); /*PADDW XMM3, 1*/ addbyte(0x0f); addbyte(0xfd); addbyte(0x1d); - addlong(&xmm_01_w); + addlong((uint32_t)&xmm_01_w); addbyte(0x66); /*PMULLW XMM0, XMM3*/ addbyte(0x0f); addbyte(0xd5); @@ -2145,8 +2170,14 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0xef); addbyte(0x05); - addlong(&xmm_ff_b); + addlong((uint32_t)&xmm_ff_b); } +//#if 0 +// addbyte(0x66); /*MOVD state->out[EDI], XMM0*/ +// addbyte(0x0f); +// addbyte(0x7e); +// addbyte(0x87); +// addlong(offsetof(voodoo_state_t, out)); if (params->fogMode & FOG_ENABLE) { if (params->fogMode & FOG_CONSTANT) @@ -2241,6 +2272,11 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(10); addbyte(0x01); /*ADD EAX, EBX*/ addbyte(0xd8); + +/* int fog_idx = (w_depth >> 10) & 0x3f; + + fog_a = params->fogTable[fog_idx].fog; + fog_a += (params->fogTable[fog_idx].dfog * ((w_depth >> 2) & 0xff)) >> 10;*/ break; case FOG_Z: @@ -2252,6 +2288,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(12); addbyte(0x25); /*AND EAX, 0xff*/ addlong(0xff); +// fog_a = (z >> 20) & 0xff; break; case FOG_ALPHA: @@ -2273,6 +2310,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); +// fog_a = CLAMP(ia >> 12); break; case FOG_W: @@ -2293,10 +2331,12 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); /*CMOVAE EAX, EBX*/ addbyte(0x43); addbyte(0xc3); +// fog_a = CLAMP(w >> 32); break; } addbyte(0x01); /*ADD EAX, EAX*/ addbyte(0xc0); +// fog_a++; addbyte(0x66); /*PMULLW XMM3, alookup+4[EAX*8]*/ addbyte(0x0f); @@ -2419,7 +2459,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x6e); addbyte(0x24); addbyte(0x85); - addlong(rgb565); + addlong((uint32_t)rgb565); addbyte(0x66); /*PUNPCKLBW XMM4, XMM2*/ addbyte(0x0f); addbyte(0x60); @@ -2443,7 +2483,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0xd5); addbyte(0x24); addbyte(0xd5); - addlong(alookup); + addlong((uint32_t)alookup); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); @@ -2507,7 +2547,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0xd5); addbyte(0x24); addbyte(0xd5); - addlong(aminuslookup); + addlong((uint32_t)aminuslookup); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); @@ -2537,7 +2577,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0x7e); addbyte(0x2d); - addlong(&xmm_ff_w); + addlong((uint32_t)&xmm_ff_w); addbyte(0x66); /*PSUBW XMM5, XMM0*/ addbyte(0x0f); addbyte(0xf9); @@ -2581,7 +2621,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0xd5); addbyte(0x25); - addlong(&minus_254); + addlong((uint32_t)&minus_254); addbyte(0xf3); /*MOVQ XMM5, XMM4*/ addbyte(0x0f); addbyte(0x7e); @@ -2621,7 +2661,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0xd5); addbyte(0x04); addbyte(0xd5); - addlong(alookup); + addlong((uint32_t)alookup); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2685,7 +2725,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0xd5); addbyte(0x04); addbyte(0xd5); - addlong(aminuslookup); + addlong((uint32_t)aminuslookup); addbyte(0xf3); /*MOVQ XMM5, XMM0*/ addbyte(0x0f); addbyte(0x7e); @@ -2715,7 +2755,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x0f); addbyte(0x7e); addbyte(0x2d); - addlong(&xmm_ff_w); + addlong((uint32_t)&xmm_ff_w); addbyte(0x66); /*PSUBW XMM5, XMM6*/ addbyte(0x0f); addbyte(0xf9); @@ -2768,6 +2808,13 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0x67); addbyte(0xc0); } +//#endif + +// addbyte(0x8b); /*MOV EDX, x (ESP+12)*/ +// addbyte(0x54); +// addbyte(0x24); +// addbyte(12); + addbyte(0x8b); /*MOV EDX, state->x[EDI]*/ addbyte(0x97); @@ -2780,6 +2827,10 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood if (params->fbzMode & FBZ_RGB_WMASK) { +// addbyte(0x89); /*MOV state->rgb_out[EDI], EAX*/ +// addbyte(0x87); +// addlong(offsetof(voodoo_state_t, rgb_out)); + if (dither) { addbyte(0x8b); /*MOV ESI, real_y (ESP+16)*/ @@ -2857,17 +2908,17 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood addbyte(0xb6); addbyte(0x9c); addbyte(0x33); - addlong(dither2x2 ? dither_g2x2 : dither_g); + addlong(dither2x2 ? (uint32_t)dither_g2x2 : (uint32_t)dither_g); addbyte(0x0f); /*MOVZX ECX, dither_rb[ECX+ESI]*/ addbyte(0xb6); addbyte(0x8c); addbyte(0x31); - addlong(dither2x2 ? dither_rb2x2 : dither_rb); + addlong(dither2x2 ? (uint32_t)dither_rb2x2 : (uint32_t)dither_rb); addbyte(0x0f); /*MOVZX EAX, dither_rb[EAX+ESI]*/ addbyte(0xb6); addbyte(0x84); addbyte(0x30); - addlong(dither2x2 ? dither_rb2x2 : dither_rb); + addlong(dither2x2 ? (uint32_t)dither_rb2x2 : (uint32_t)dither_rb); addbyte(0xc1); /*SHL EBX, 5*/ addbyte(0xe3); addbyte(5); @@ -3181,7 +3232,7 @@ static __inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, vood } static int voodoo_recomp = 0; -static __inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) +static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even) { int c; int b = last_block[odd_even]; @@ -3211,6 +3262,7 @@ static __inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params } voodoo_recomp++; data = &codegen_data[odd_even + next_block_to_write[odd_even]*2]; +// code_block = data->code_block; voodoo_generate(data->code_block, voodoo, params, state, depth_op); diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 4772b2c48..4c3cc152d 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -54,7 +54,7 @@ typedef struct esdi_t int data_pos; uint16_t data[256]; - uint16_t sector_buffer[16][256]; + uint16_t sector_buffer[256][256]; int sector_pos; int sector_count; @@ -632,7 +632,7 @@ static void esdi_callback(void *p) case 0: esdi->sector_pos = 0; esdi->sector_count = esdi->cmd_data[1]; - if (esdi->sector_count > 16) + if (esdi->sector_count > 256) fatal("Read sector buffer count %04x\n", esdi->cmd_data[1]); esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; @@ -692,7 +692,7 @@ static void esdi_callback(void *p) case 0: esdi->sector_pos = 0; esdi->sector_count = esdi->cmd_data[1]; - if (esdi->sector_count > 16) + if (esdi->sector_count > 256) fatal("Write sector buffer count %04x\n", esdi->cmd_data[1]); esdi->status = STATUS_IRQ | STATUS_CMD_IN_PROGRESS | STATUS_TRANSFER_REQ; diff --git a/src/mem.c b/src/mem.c index 5fd0cf5a2..fd393e446 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1131,7 +1131,7 @@ void addwritelookup(uint32_t virt, uint32_t phys) writelookup2[writelookup[writelnext]] = -1; } - if (pages[phys >> 12].block || (phys & ~0xfff) == recomp_page) + if (pages[phys >> 12].block[0] || pages[phys >> 12].block[1] || pages[phys >> 12].block[2] || pages[phys >> 12].block[3] || (phys & ~0xfff) == recomp_page) page_lookup[virt >> 12] = &pages[phys >> 12]; else writelookup2[virt>>12] = (uintptr_t)&ram[(uintptr_t)(phys & ~0xFFF) - (uintptr_t)(virt & ~0xfff)]; @@ -1713,7 +1713,7 @@ void mem_write_ramb_page(uint32_t addr, uint8_t val, page_t *p) if (val != p->mem[addr & 0xfff] || codegen_in_recompile) { uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - p->dirty_mask |= mask; + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; p->mem[addr & 0xfff] = val; } } @@ -1722,9 +1722,9 @@ void mem_write_ramw_page(uint32_t addr, uint16_t val, page_t *p) if (val != *(uint16_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if ((addr & 0x3f) == 0x3f) + if ((addr & 0xf) == 0xf) mask |= (mask << 1); - p->dirty_mask |= mask; + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; *(uint16_t *)&p->mem[addr & 0xfff] = val; } } @@ -1733,9 +1733,9 @@ void mem_write_raml_page(uint32_t addr, uint32_t val, page_t *p) if (val != *(uint32_t *)&p->mem[addr & 0xfff] || codegen_in_recompile) { uint64_t mask = (uint64_t)1 << ((addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - if ((addr & 0x3f) >= 0x3d) + if ((addr & 0xf) >= 0xd) mask |= (mask << 1); - p->dirty_mask |= mask; + p->dirty_mask[(addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; *(uint32_t *)&p->mem[addr & 0xfff] = val; } } @@ -1758,10 +1758,10 @@ void mem_write_raml(uint32_t addr, uint32_t val, void *priv) uint8_t mem_read_bios(uint32_t addr, void *priv) { - if (AMIBIOS && (addr&0xFFFFF)==0xF8281) /*This is read constantly during AMIBIOS POST, but is never written to. It's clearly a status register of some kind, but for what?*/ - { - return 0x40; - } + if (AMIBIOS && (addr&0xFFFFF)==0xF8281) /*This is read constantly during AMIBIOS POST, but is never written to. It's clearly a status register of some kind, but for what?*/ + { + return 0x40; + } return rom[addr & biosmask]; } uint16_t mem_read_biosw(uint32_t addr, void *priv) @@ -1804,8 +1804,8 @@ void mem_invalidate_range(uint32_t start_addr, uint32_t end_addr) for (; start_addr <= end_addr; start_addr += (1 << PAGE_MASK_SHIFT)) { uint64_t mask = (uint64_t)1 << ((start_addr >> PAGE_MASK_SHIFT) & PAGE_MASK_MASK); - - pages[start_addr >> 12].dirty_mask |= mask; + + pages[start_addr >> 12].dirty_mask[(start_addr >> PAGE_MASK_INDEX_SHIFT) & PAGE_MASK_INDEX_MASK] |= mask; } } @@ -2220,8 +2220,8 @@ void mem_reset_page_blocks() pages[c].write_b = mem_write_ramb_page; pages[c].write_w = mem_write_ramw_page; pages[c].write_l = mem_write_raml_page; - pages[c].block = NULL; - pages[c].block_2 = NULL; + pages[c].block[0] = pages[c].block[1] = pages[c].block[2] = pages[c].block[3] = NULL; + pages[c].block_2[0] = pages[c].block_2[1] = pages[c].block_2[2] = pages[c].block_2[3] = NULL; } } diff --git a/src/mem.h b/src/mem.h index 6bf127ecf..916e89995 100644 --- a/src/mem.h +++ b/src/mem.h @@ -122,12 +122,12 @@ typedef struct page_t uint8_t *mem; - struct codeblock_t *block, *block_2; + struct codeblock_t *block[4], *block_2[4]; /*Head of codeblock tree associated with this page*/ struct codeblock_t *head; - uint64_t code_present_mask, dirty_mask; + uint64_t code_present_mask[4], dirty_mask[4]; } page_t; extern page_t *pages; From 9ed5b93f8157891931e95db541fe63052e322f7c Mon Sep 17 00:00:00 2001 From: Melissa Goad Date: Wed, 14 Jun 2017 21:33:58 -0500 Subject: [PATCH 342/392] Add XRGB8888 LFB format to Voodoo 1. --- src/VIDEO/vid_voodoo.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/VIDEO/vid_voodoo.c b/src/VIDEO/vid_voodoo.c index f033acdbb..042e88a42 100644 --- a/src/VIDEO/vid_voodoo.c +++ b/src/VIDEO/vid_voodoo.c @@ -745,6 +745,7 @@ enum LFB_FORMAT_RGB565 = 0, LFB_FORMAT_RGB555 = 1, LFB_FORMAT_ARGB1555 = 2, + LFB_FORMAT_XRGB8888 = 4, LFB_FORMAT_ARGB8888 = 5, LFB_FORMAT_DEPTH = 15, LFB_FORMAT_MASK = 15 @@ -5408,6 +5409,13 @@ static void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p) count = 2; break; + case LFB_FORMAT_XRGB8888: + colour_data[0].b = val & 0xff; + colour_data[0].g = (val >> 8) & 0xff; + colour_data[0].r = (val >> 16) & 0xff; + write_mask = LFB_WRITE_COLOUR; + addr >>= 1; + break; case LFB_FORMAT_ARGB8888: colour_data[0].b = val & 0xff; colour_data[0].g = (val >> 8) & 0xff; From 12e1e8dfa7cba2ecc0c7b7e97495392c9d523460 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 15 Jun 2017 05:17:34 +0200 Subject: [PATCH 343/392] Properly fixed Adaptec AHA-1640 MCA adapter, setup is handled directly by the ADF file in the reference disks. Re-introduced the Acer V35n machine, but with a proper bios (r01-c0.bin instead of the service one). MCA serial and parallel initialization fixes alongside the ISA PS/1 and PS/2 Model 30 ones. --- src/mem.c | 6 +- src/model.c | 1 + src/ps1.c | 14 +--- src/ps2.c | 7 +- src/ps2_mca.c | 9 +-- src/scsi_aha154x.c | 172 +++++++++++++++++++++------------------------ 6 files changed, 90 insertions(+), 119 deletions(-) diff --git a/src/mem.c b/src/mem.c index fd393e446..d1cf95fd4 100644 --- a/src/mem.c +++ b/src/mem.c @@ -716,15 +716,13 @@ int loadbios() biosmask = 0x1ffff; return 1; -#if 0 - case ROM_ACERV35N: - f = romfopen(L"roms/acerv35n/V35ND1S1.BIN", L"rb"); + case ROM_ACERV35N: + f = romfopen(L"roms/acerv35n/R01-C0.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); biosmask = 0x1ffff; return 1; -#endif case ROM_P55VA: f = romfopen(L"roms/p55va/VA021297.BIN", L"rb"); diff --git a/src/model.c b/src/model.c index b45b89efc..ff24d4255 100644 --- a/src/model.c +++ b/src/model.c @@ -212,6 +212,7 @@ MODEL models[] = {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, + {"Acer V35n", ROM_ACERV35N, "acerv35n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, diff --git a/src/ps1.c b/src/ps1.c index 97b319e75..0e7d5148c 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -295,13 +295,8 @@ void ps1mb_m2121_init() MEM_MAPPING_EXTERNAL); ps1_190 = 0; - lpt1_remove(); - lpt2_remove(); lpt1_init(0x3bc); - - serial_remove(1); - serial_remove(2); - + mem_remap_top_384k(); } @@ -315,12 +310,7 @@ void ps1mb_m2133_init() ps1_190 = 0; - lpt1_remove(); - lpt2_remove(); lpt1_init(0x3bc); - - serial_remove(1); - serial_remove(2); - + mem_remap_top_384k(); } diff --git a/src/ps2.c b/src/ps2.c index 0f1e1a964..1f91591d1 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -126,13 +126,8 @@ void ps2board_init() io_sethandler(0x0324, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); ps2_190 = 0; - - lpt1_remove(); - lpt2_remove(); + lpt1_init(0x3bc); - serial_remove(1); - serial_remove(2); - memset(&ps2_hd, 0, sizeof(ps2_hd)); } diff --git a/src/ps2_mca.c b/src/ps2_mca.c index 5af537b6e..1a31e07d5 100644 --- a/src/ps2_mca.c +++ b/src/ps2_mca.c @@ -552,12 +552,7 @@ static void ps2_mca_board_common_init() ps2.setup = 0xff; - lpt1_remove(); - lpt2_remove(); lpt1_init(0x3bc); - - serial_remove(1); - serial_remove(2); } void ps2_mca_board_model_50_init() @@ -701,7 +696,7 @@ void ps2_mca_board_model_80_type2_init() mem_remap_top_256k(); ps2.split_addr = mem_size * 1024; - mca_init(8); + mca_init(24); ps2.planar_read = model_80_read; ps2.planar_write = model_80_write; @@ -746,7 +741,7 @@ void ps2_mca_board_model_80_type2_init() if (mem_size > 4096) { /* Only 4 MB supported on planar, create a memory expansion card for the rest */ - mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x300000); + mem_mapping_set_addr(&ram_high_mapping, 0x100000, 0x800000); ps2.mem_pos_regs[0] = 0xff; ps2.mem_pos_regs[1] = 0xfc; diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index f37838cf1..dfb851d7f 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -1483,8 +1483,8 @@ aha_0x01: break; case 0x04: - dev->DataBuf[0] = dev->aha.bid; - dev->DataBuf[1] = 0x30; + dev->DataBuf[0] = (dev->chip != CHIP_AHA1640) ? dev->aha.bid : 0x42; + dev->DataBuf[1] = (dev->chip != CHIP_AHA1640) ? 0x30 : 0x42; dev->DataBuf[2] = dev->aha.fwh; dev->DataBuf[3] = dev->aha.fwl; dev->DataReplyLeft = 4; @@ -2147,7 +2147,38 @@ uint8_t aha_mca_read(int port, void *p) return dev->pos_regs[port & 7]; } -static uint16_t aha_mca_addr[6] = {0x130, 0x134, 0x230, 0x234, 0x330, 0x334}; +uint16_t aha_mca_get_port(uint8_t pos_port) +{ + uint16_t addr; + switch (pos_port & 0xC7) + { + case 0x01: + addr = 0x130; + break; + + case 0x02: + addr = 0x230; + break; + + case 0x03: + addr = 0x330; + break; + + case 0x41: + addr = 0x134; + break; + + case 0x42: + addr = 0x234; + break; + + case 0x43: + addr = 0x334; + break; + } + + return addr; +} void aha_mca_write(int port, uint8_t val, void *p) { @@ -2157,18 +2188,21 @@ void aha_mca_write(int port, uint8_t val, void *p) if (port < 0x102) return; - addr = aha_mca_addr[dev->pos_regs[4] & 6]; - io_removehandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); - + addr = aha_mca_get_port(dev->pos_regs[3]); + io_removehandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); + dev->pos_regs[port & 7] = val; if (dev->pos_regs[2] & 1) { + addr = aha_mca_get_port(dev->pos_regs[3]); io_sethandler(addr, 0x0004, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); } + + dev->Irq = (dev->pos_regs[4] & 0x7) + 8; + dev->DmaChannel = dev->pos_regs[5] & 0xf; } - void aha_device_reset(void *p) { @@ -2222,14 +2256,6 @@ aha_init(int chip, int has_bios) } } - if (dev->chip == CHIP_AHA1640) - { - pclog("Aha1640 initialized\n"); - mca_add(aha_mca_read, aha_mca_write, dev); - dev->pos_regs[0] = 0x1F; - dev->pos_regs[1] = 0x0F; - } - timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev); timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev); @@ -2262,7 +2288,46 @@ aha_154xCF_init(void) static void * aha_1640_init(void) { - return(aha_init(CHIP_AHA1640, 1)); + aha_t *dev; + int i = 0; + int j = 0; + + dev = malloc(sizeof(aha_t)); + memset(dev, 0x00, sizeof(aha_t)); + + ResetDev = dev; + dev->chip = CHIP_AHA1640; + + pclog("Aha1640 initialized\n"); + mca_add(aha_mca_read, aha_mca_write, dev); + dev->pos_regs[0] = 0x1F; + dev->pos_regs[1] = 0x0F; + + pclog("Building SCSI hard disk map...\n"); + build_scsi_hd_map(); + pclog("Building SCSI CD-ROM map...\n"); + build_scsi_cdrom_map(); + + for (i=0; i<16; i++) { + for (j=0; j<8; j++) { + if (scsi_hard_disks[i][j] != 0xff) { + SCSIDevices[i][j].LunType = SCSI_DISK; + } + else if (find_cdrom_for_scsi_id(i, j) != 0xff) { + SCSIDevices[i][j].LunType = SCSI_CDROM; + } + else { + SCSIDevices[i][j].LunType = SCSI_NONE; + } + } + } + + timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev); + timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, dev); + + aha_reset_ctrl(dev, CTRL_HRST); + + return(dev); } @@ -2373,78 +2438,6 @@ static device_config_t aha_154XCF_config[] = { } }; -static device_config_t aha_1640_config[] = { - { - "base", "Address", CONFIG_HEX16, "", 0x330, - { - { - "0x330", 0x330 - }, - { - "0x334", 0x334 - }, - { - "0x230", 0x230 - }, - { - "0x234", 0x234 - }, - { - "0x130", 0x130 - }, - { - "0x134", 0x134 - }, - { - "" - } - }, - }, - { - "irq", "IRQ", CONFIG_SELECTION, "", 10, - { - { - "IRQ 10", 10 - }, - { - "IRQ 11", 11 - }, - { - "IRQ 12", 12 - }, - { - "IRQ 14", 14 - }, - { - "IRQ 15", 15 - }, - { - "" - } - }, - }, - { - "dma", "DMA channel", CONFIG_SELECTION, "", 6, - { - { - "DMA 5", 5 - }, - { - "DMA 6", 6 - }, - { - "DMA 7", 7 - }, - { - "" - } - }, - }, - { - "", "", -1 - } -}; - device_t aha1540b_device = { "Adaptec AHA-1540B", 0, @@ -2477,6 +2470,5 @@ device_t aha1640_device = { NULL, NULL, NULL, - NULL, - aha_1640_config + NULL }; \ No newline at end of file From e4c08cf59494c04faace8f620c83d4a40a183391 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 15 Jun 2017 06:34:08 +0200 Subject: [PATCH 344/392] Network code and pc.c are more platform-independent now. --- src/NETWORK/network.c | 5 ++-- src/WIN/plat_ui.h | 26 ++++++++++++++++++ src/WIN/win.c | 5 ++-- src/WIN/win.h | 4 +-- src/WIN/win_language.c | 61 ++++++++++++++++++++++++++++++++++++++++++ src/pc.c | 11 ++++---- 6 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 src/WIN/plat_ui.h diff --git a/src/NETWORK/network.c b/src/NETWORK/network.c index abac44263..679eaf721 100644 --- a/src/NETWORK/network.c +++ b/src/NETWORK/network.c @@ -24,8 +24,7 @@ #include "../device.h" #include "network.h" #include "net_ne2000.h" -#include "../WIN/win.h" -#include "../WIN/win_language.h" +#include "../WIN/plat_ui.h" static netcard_t net_cards[] = { @@ -112,7 +111,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) case NET_TYPE_PCAP: ret = network_pcap_setup(mac, rx, dev); if (ret < 0) { - msgbox_error(ghwnd, IDS_2219); + plat_msgbox_error(IDS_2219); network_type = NET_TYPE_NONE; } break; diff --git a/src/WIN/plat_ui.h b/src/WIN/plat_ui.h new file mode 100644 index 000000000..7bc6d35d9 --- /dev/null +++ b/src/WIN/plat_ui.h @@ -0,0 +1,26 @@ +#ifndef __unix +extern void plat_msgbox_error(int i); +extern wchar_t *plat_get_string_from_id(int i); + +#ifndef IDS_2219 +#define IDS_2219 2219 +#endif + +#ifndef IDS_2077 +#define IDS_2077 2077 +#endif + +#ifndef IDS_2078 +#define IDS_2078 2078 +#endif + +#ifndef IDS_2079 +#define IDS_2079 2079 +#endif +#endif + +extern void plat_msgbox_fatal(char *string); +extern void get_executable_name(wchar_t *s, int size); +extern void set_window_title(wchar_t *s); +extern void startblit(void); +extern void endblit(void); diff --git a/src/WIN/win.c b/src/WIN/win.c index 394a05e3b..41eb621dc 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -49,6 +49,7 @@ #include "plat_mouse.h" #include "plat_midi.h" #include "plat_thread.h" +#include "plat_ui.h" #include "win.h" #include "win_cgapal.h" @@ -525,12 +526,12 @@ void create_removable_disk_submenu(HMENU m, int id) AppendMenu(m, MF_STRING, IDM_RDISK_IMAGE_WP | id, win_language_get_string_from_id(2220)); } -void get_executable_name(WCHAR *s, int size) +void get_executable_name(wchar_t *s, int size) { GetModuleFileName(hinstance, s, size); } -void set_window_title(WCHAR *s) +void set_window_title(wchar_t *s) { if (video_fullscreen) return; diff --git a/src/WIN/win.h b/src/WIN/win.h index 72bad6dcf..d2006df00 100644 --- a/src/WIN/win.h +++ b/src/WIN/win.h @@ -83,8 +83,8 @@ extern void joystickconfig_open(HWND hwnd, int joy_nr, int type); extern int getfile(HWND hwnd, char *f, char *fn); extern int getsfile(HWND hwnd, char *f, char *fn); -extern void get_executable_name(WCHAR *s, int size); -extern void set_window_title(WCHAR *s); +extern void get_executable_name(wchar_t *s, int size); +extern void set_window_title(wchar_t *s); extern void startblit(void); extern void endblit(void); diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index 6279e2da6..61dae5f2c 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -20,6 +20,7 @@ #define BITMAP WINDOWS_BITMAP #include #include +#include #undef BITMAP #include @@ -27,6 +28,7 @@ #include "../ibm.h" #include "../device.h" #include "../ide.h" +#include "plat_ui.h" #include "win.h" #include "win_language.h" @@ -82,6 +84,11 @@ LPTSTR win_language_get_string_from_id(int i) return lpResourceString[i - 2048]; } +wchar_t *plat_get_string_from_id(int i) +{ + return (wchar_t *) win_language_get_string_from_id(i); +} + LPTSTR win_language_get_string_from_string(char *str) { return lpResourceString[atoi(str) - 2048]; @@ -117,6 +124,11 @@ void msgbox_error(HWND hwndParent, int i) MessageBox(hwndParent, win_language_get_string_from_id(i), lpResourceString[1], MB_OK | MB_ICONWARNING); } +void plat_msgbox_error(int i) +{ + msgbox_error(ghwnd, i); +} + void msgbox_error_wstr(HWND hwndParent, WCHAR *wstr) { MessageBox(hwndParent, wstr, lpResourceString[1], MB_OK | MB_ICONWARNING); @@ -139,6 +151,11 @@ void msgbox_fatal(HWND hwndParent, char *string) free(lptsTemp); } +void plat_msgbox_fatal(char *string) +{ + msgbox_fatal(ghwnd, string); +} + int file_dlg_w(HWND hwnd, WCHAR *f, WCHAR *fn, int save) { OPENFILENAME ofn; /* common dialog box structure */ @@ -207,3 +224,47 @@ int file_dlg_st(HWND hwnd, int i, char *fn, int save) { return file_dlg(hwnd, win_language_get_string_from_id(i), fn, save); } + +static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + if(uMsg == BFFM_INITIALIZED) + { + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData); + } + + return 0; +} + +WCHAR path[MAX_PATH]; + +wchar_t *BrowseFolder(wchar_t *saved_path) +{ + BROWSEINFO bi = { 0 }; + bi.lpszTitle = L"Browse for folder..."; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; + bi.lpfn = BrowseCallbackProc; + bi.lParam = (LPARAM) saved_path; + + LPITEMIDLIST pidl = SHBrowseForFolder(&bi); + + if (pidl != 0) + { + /* Get the name of the folder and put it in path. */ + SHGetPathFromIDList(pidl, path); + + /* Free memory used. */ +#if 0 + IMalloc *imalloc = 0; + if (SUCCEEDED(SHGetMalloc(&imalloc))) + { + imalloc->Free(pidl); + imalloc->Release(); + } +#endif + free(pidl); + + return path; + } + + return L""; +} diff --git a/src/pc.c b/src/pc.c index 8ced5b20b..a37b3f2f6 100644 --- a/src/pc.c +++ b/src/pc.c @@ -73,8 +73,7 @@ #include "video/video.h" #include "video/vid_voodoo.h" #include "amstrad.h" -#include "win.h" -#include "win_language.h" +#include "../WIN/plat_ui.h" #ifdef WALTJE # include "plat_dir.h" #endif @@ -187,7 +186,7 @@ void fatal(const char *format, ...) { *newline = 0; } - msgbox_fatal(ghwnd, msg); + plat_msgbox_fatal(msg); #endif dumppic(); dumpregs(1); @@ -577,8 +576,8 @@ int serial_fifo_read, serial_fifo_write; int emu_fps = 0; -static WCHAR wmodel[2048]; -static WCHAR wcpu[2048]; +static wchar_t wmodel[2048]; +static wchar_t wcpu[2048]; void runpc(void) { @@ -659,7 +658,7 @@ void runpc(void) win_title_update=0; mbstowcs(wmodel, model_getname(), strlen(model_getname()) + 1); mbstowcs(wcpu, models[model].cpu[cpu_manufacturer].cpus[cpu].name, strlen(models[model].cpu[cpu_manufacturer].cpus[cpu].name) + 1); - _swprintf(s, L"%s v%s - %i%% - %s - %s - %s", EMU_NAME_W, EMU_VERSION_W, fps, wmodel, wcpu, (!mousecapture) ? win_language_get_string_from_id(2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? win_language_get_string_from_id(2078) : win_language_get_string_from_id(2079))); + _swprintf(s, L"%s v%s - %i%% - %s - %s - %s", EMU_NAME_W, EMU_VERSION_W, fps, wmodel, wcpu, (!mousecapture) ? plat_get_string_from_id(IDS_2077) : ((mouse_get_type(mouse_type) & MOUSE_TYPE_3BUTTON) ? plat_get_string_from_id(IDS_2078) : plat_get_string_from_id(IDS_2079))); set_window_title(s); } done++; From fd923ef050bee7693f26fe6af3b30e8c4a33e347 Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 15 Jun 2017 03:10:31 -0400 Subject: [PATCH 345/392] Added module dependencies to Makefile, small fixes. --- src/Makefile.mingw | 272 +++++++++++++++++++++++++++++++++++++++++++-- src/pc.c | 6 +- 2 files changed, 267 insertions(+), 11 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 7baeaf1c8..a2b5e746d 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.27 2017/06/14 +# Version: @(#)Makefile.mingw 1.0.28 2017/06/14 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -67,8 +67,8 @@ endif VPATH = . cpu sound sound/resid-fp video lzf network network/slirp win PLAT = win/ ifeq ($(X64), y) -CPP = g++.exe -m64 -U__unix -CC = gcc.exe -m64 -U__unix +CPP = g++.exe -m64 +CC = gcc.exe -m64 else CPP = g++.exe -m32 CC = gcc.exe -m32 @@ -164,7 +164,11 @@ ifdef USB USBOBJ = usb.o endif NETOBJ = network.o \ - net_pcap.o net_slirp.o \ + net_pcap.o \ + net_slirp.o \ + bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ + ip_input.o queue.o tcp_input.o debug.o ip_output.o \ + sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \ net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ @@ -217,9 +221,6 @@ OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) LZFOBJ = lzf_c.o lzf_d.o -SLIRPOBJ= bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ - ip_input.o queue.o tcp_input.o debug.o ip_output.o \ - sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ -mwindows -lcomctl32 -lwinmm -lwsock32 -liphlpapi -lpsapi \ @@ -242,9 +243,9 @@ LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ all: $(PROG).exe pcap_if.exe -$(PROG).exe: $(OBJ) $(LZFOBJ) $(SLIRPOBJ) +$(PROG).exe: $(OBJ) $(LZFOBJ) @echo Linking $(PROG).exe .. - @$(CC) -o $(PROG).exe $(OBJ) $(LZFOBJ) $(SLIRPOBJ) $(LIBS) + @$(CC) -o $(PROG).exe $(OBJ) $(LZFOBJ) $(LIBS) ifneq ($(DEBUG), y) @strip $(PROG).exe endif @@ -272,4 +273,257 @@ pcap_if.res: pcap_if.rc @$(WINDRES) $(RFLAGS) -i win/pcap_if.rc -o pcap_if.res +# Module dependencies. +acer386sx.o: ibm.h cpu/cpu.h io.h acer386sx.h + +acerm3a.o: ibm.h io.h acerm3a.h + +ali1429.o: ibm.h cpu/cpu.h io.h mem.h ali1429.h + +amstrad.o: ibm.h io.h keyboard.h lpt.h mouse.h amstrad.h + +bugger.o: ibm.h io.h bugger.h + +cdrom.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h timer.h \ + win/plat_iodev.h + +cdrom_ioctl.o: ibm.h cdrom.h cdrom_ioctl.h scsi.h + +cdrom_null.o: ibm.h cdrom.h cdrom_ioctl.h + +compaq.o: ibm.h mem.h + +config.o: cdrom.h config.h device.h disc.h fdc.h fdd.h ibm.h \ + cpu/cpu.h gameport.h ide.h hdd.h model.h mouse.h \ + network/network.h nvr.h scsi.h win/plat_joystick.h \ + win/plat_midi.h sound/snd_dbopl.h sound/snd_mpu401.h \ + sound/snd_opl.h sound/sound.h video/video.h win/win.h \ + win/win_language.h + +device.o: ibm.h cpu/cpu.h config.h device.h model.h sound/sound.h + +disc.o: ibm.h config.h disc.h disc_fdi.h disc_img.h disc_86f.h \ + disc_td0.h disc_imd.h fdc.h fdd.h timer.h + +disc_86f.o: lzf/lzf.h config.h dma.h disc.h disc_86f.h disc_random.h \ + fdc.h fdd.h ibm.h + +disc_fdi.o: ibm.h disc.h disc_img.h disc_fdi.h fdc.h fdd.h fdi2raw.h \ + ibm.h disc.h disc_imd.h fdc.h fdd.h ibm.h config.h disc.h \ + disc_img.h fdc.h fdd.h + +disc_random.o: disc_random.h + +disc_td0.o: ibm.h disc.h disc_td0.h fdc.h fdd.h + +dma.o: ibm.h cpu/x86.h mem.h io.h dma.h + +fdc.o: ibm.h disc.h dma.h fdc.h fdd.h io.h pic.h timer.h + +fdc37c665.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \ + fdc37c665.h ibm.h disc.h fdc.h fdd.h io.h ide.h \ + lpt.h serial.h fdc37c669.h + +fdc37c932fr.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \ + fdc37c932fr.h + +fdd.o: ibm.h disc.h fdc.h fdd.h + +fdi2raw.o: fdi2raw.h ibm.h + +gameport.o: ibm.h cpu/cpu.h device.h io.h timer.h gameport.h \ + joystick_ch_flightstick_pro.h joystick_standard.h \ + joystick_sw_pad.h joystick_tm_fcs.h plat_joystick.h + +hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h hdd_esdi.h \ + mfm_at.h mfm_xebec.h xtide.h + +hdd_esdi.o: ibm.h device.h dma.h io.h mca.h mem.h pic.h rom.h \ + timer.h hdd_esdi.h + +headland.o: ibm.h cpu/cpu.h io.h mem.h headland.h + +i430fx.o: ibm.h mem.h pci.h i430fx.h + +i430hx.o: ibm.h io.h mem.h pci.h i430hx.h + +i430lx.o: ibm.h mem.h pci.h i430lx.h + +i430nx.o: ibm.h mem.h pci.h i430nx.h + +i430vx.o: ibm.h io.h mem.h pci.h i430vx.h + +i440fx.o: ibm.h io.h mem.h pci.h i440fx.h + +i82335.o: ibm.h io.h mem.h + +ide.o: 86box.h cdrom.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h + +intel.o: ibm.h cpu/cpu.h io.h mem.h pit.h timer.h intel.h + +intel_flash.o: ibm.h cpu/cpu.h device.h mem.h model.h rom.h + +io.o: ibm.h io.h + +jim.o: ibm.h io.h + +joystick_ch_flightstick_pro.o: ibm.h device.h timer.h gameport.h \ + joystick_standard.h plat_joystick.h + +joystick_standard.o: ibm.h device.h timer.h gameport.h \ + joystick_standard.h plat_joystick.h + +joystick_sw_pad.o: ibm.h device.h timer.h gameport.h \ + joystick_sw_pad.h plat_joystick.h + +joystick_tm_fcs.o: ibm.h device.h timer.h gameport.h \ + joystick_standard.h plat_joystick.h + +keyboard.o: ibm.h plat_keyboard.h keyboard.h + +keyboard_amstrad.o: ibm.h io.h mem.h pic.h pit.h timer.h sound/sound.h \ + sound/snd_speaker.h keyboard.h keyboard_amstrad.h + +keyboard_at.o: ibm.h io.h mem.h pic.h pit.h timer.h disc.h fdc.h \ + sound/sound.h sound/snd_speaker.h keyboard.h keyboard_at.h + +keyboard_olim24.o: ibm.h io.h mem.h pic.h pit.h timer.h mouse.h \ + sound/sound.h sound/snd_speaker.h keyboard.h keyboard_olim24.h + +keyboard_pcjr.o: ibm.h io.h mem.h nmi.h pic.h pit.h timer.h \ + device.h sound/sound.h sound/snd_speaker.h \ + sound/snd_sn76489.h keyboard.h keyboard_pcjr.h + +keyboard_xt.o: ibm.h io.h mem.h pic.h pit.h timer.h device.h tandy_eeprom.h \ + sound/sound.h sound/snd_speaker.h keyboard.h keyboard_xt.h + +laserxt.o: ibm.h io.h mem.h + +lpt.o: ibm.h io.h lpt.h + +mca.o: ibm.h io.h mem.h mca.h + +mcr.o: ibm.h + +mem.o: ibm.h cpu/cpu.h cpu/x86_ops.h cpu/x86.h config.h \ + io.h mem.h rom.h cpu/codegen.h video/video.h + +memregs.o: ibm.h io.h memregs.h + +mfm_at.o: ibm.h device.h io.h pic.h timer.h mfm_at.h + +mfm_xebec.o: ibm.h device.h dma.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h + +model.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h mouse.h \ + mouse_ps2.h cdrom.h acerm3a.h ali1429.h amstrad.h compaq.h \ + disc.h dma.h fdc.h fdc37c665.h fdc37c669.h fdc37c932fr.h \ + gameport.h headland.h i430fx.h i430hx.h i430lx.h i430nx.h \ + i430vx.h i440fx.h i82335.h ide.h intel.h intel_flash.h jim.h \ + keyboard_amstrad.h keyboard_at.h keyboard_olim24.h \ + keyboard_pcjr.h keyboard_xt.h laserxt.h lpt.h mem.h memregs.h \ + neat.h nmi.h nvr.h olivetti_m24.h opti495.h pc87306.h pci.h \ + pic.h piix.h pit.h ps1.h ps2.h ps2_mca.h scat.h serial.h \ + sis496.h sis85c471.h sio.h sound/snd_ps1.h sound/snd_pssj.h \ + sound/snd_sn76489.h tandy_eeprom.h tandy_rom.h \ + video/vid_pcjr.h video/vid_tandy.h w83877f.h wd76c10.h \ + xtide.h bugger.h + +mouse.o: ibm.h mouse.h mouse_serial.h mouse_ps2.h mouse_bus.h \ + amstrad.h keyboard_olim24.h + +mouse_bus.o: ibm.h io.h pic.h mouse.h mouse_bus.h plat_mouse.h + +mouse_ps2.o: ibm.h keyboard_at.h mouse.h mouse_ps2.h plat_mouse.h + +mouse_serial.o: ibm.h timer.h serial.h mouse.h mouse_serial.h + +neat.o: ibm.h io.h neat.h + +nmi.o: ibm.h io.h nmi.h + +nvr.o: ibm.h cpu/cpu.h device.h io.h mem.h model.h nvr.h \ + pic.h rom.h timer.h rtc.h + +olivetti_m24.o: ibm.h io.h olivetti_m24.h + +opti495.o: ibm.h cpu/cpu.h io.h mem.h + +pc.o: 86box.h ibm.h mem.h cpu/cpu.h cpu/x86_ops.h cpu/codegen.h \ + dma.h nvr.h pic.h pit.h timer.h device.h ali1429.h disc.h \ + disc_86f.h disc_fdi.h disc_imd.h disc_img.h disc_td0.h \ + disc_random.h config.h fdc.h fdd.h gameport.h plat_joystick.h \ + plat_midi.h hdd.h ide.h cdrom.h cdrom_ioctl.h cdrom_image.h \ + cdrom_null.h scsi.h keyboard.h plat_keyboard.h keyboard_at.h \ + model.h mouse.h plat_mouse.h network/network.h serial.h \ + sound/sound.h sound/snd_cms.h sound/snd_dbopl.h \ + sound/snd_mpu401.h sound/snd_opl.h sound/snd_gus.h \ + sound/snd_sb.h sound/snd_speaker.h sound/snd_ssi2001.h \ + video/video.h video/vid_voodoo.h amstrad.h win/plat_ui.h + +pc87306.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h pc87306.h + +pci.o: ibm.h io.h mem.h pic.h pci.h + +pic.o: ibm.h io.h pic.h pit.h + +piix.o: ibm.h dma.h ide.h io.h mem.h pci.h piix.h + +pit.o: ibm.h cpu/cpu.h dma.h io.h pic.h pit.h device.h timer.h \ + model.h sound/snd_speaker.h video/video.h + +ppi.o: ibm.h pit.h plat_keyboard.h plat_mouse.h + +ps1.o: ibm.h io.h mem.h ps1.h rom.h lpt.h serial.h + +ps2.o: ibm.h io.h mem.h ps2.h rom.h lpt.h serial.h + +ps2_mca.o: ibm.h cpu/cpu.h cpu/x86.h io.h mca.h mem.h rom.h device.h \ + lpt.h ps2_mca.h ps2_nvr.h serial.h + +ps2_nvr.o: ibm.h device.h io.h mem.h rom.h ps2_nvr.h + +rom.o: config.h ibm.h mem.h rom.h + +rtc.o: nvr.h rtc.h + +scat.o: ibm.h io.h scat.h mem.h + +scsi.o: 86box.h ibm.h timer.h device.h cdrom.h scsi.h \ + scsi_aha154x.h scsi_buslogic.h + +scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \ + device.h cdrom.h scsi.h scsi_disk.h scsi_aha154x.h \ + +scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \ + device.h scsi.h scsi_disk.h cdrom.h scsi_buslogic.h + +scsi_disk.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h scsi_disk.h \ + timer.h win/plat_iodev.h + +serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h + +sio.o: ibm.h cdrom.h disc.h dma.h fdc.h keyboard_at.h ide.h \ + io.h mem.h pci.h sio.h + +sis496.o: ibm.h device.h io.h mem.h pci.h sis496.h + +sis50x.o: ibm.h device.h io.h mem.h pci.h sis50x.h + +sis85c471.o: ibm.h ide.h disc.h fdc.h fdd.h io.h lpt.h serial.h sis85c471.h + +tandy_eeprom.o: ibm.h device.h mem.h io.h rom.h tandy_eeprom.h + +tandy_rom.o: ibm.h device.h io.h mem.h rom.h tandy_rom.h + +timer.o: ibm.h timer.h + +usb.o: ibm.h io.h mem.h usb.h + +w83877f.o: ibm.h disc.h fdc.h fdd.h io.h lpt.h serial.h w83877f.h + +wd76c10.o: ibm.h disc.h fdc.h io.h mem.h serial.h wd76c10.h + +xtide.o: ibm.h io.h mem.h rom.h device.h ide.h xtide.h + + # End of Makefile.mingw. diff --git a/src/pc.c b/src/pc.c index a37b3f2f6..e72202820 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.3 2017/06/03 + * Version: @(#)pc.c 1.0.4 2017/06/15 * * Authors: Sarah Walker, * Miran Grca, @@ -73,9 +73,11 @@ #include "video/video.h" #include "video/vid_voodoo.h" #include "amstrad.h" -#include "../WIN/plat_ui.h" +#include "plat_ui.h" #ifdef WALTJE +# define UNICODE # include "plat_dir.h" +# undef UNICODE #endif From 15b25157eee1a4695c9373e4aa08ca91ae162c3f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 15 Jun 2017 19:35:48 +0200 Subject: [PATCH 346/392] Reverted the Acer V35N to the service BIOS and made it initialize PCI with the correct slot ID's, the board works correctly now. --- src/mem.c | 4 ++-- src/model.c | 17 ++++++++--------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/mem.c b/src/mem.c index d1cf95fd4..971d4ebb6 100644 --- a/src/mem.c +++ b/src/mem.c @@ -716,8 +716,8 @@ int loadbios() biosmask = 0x1ffff; return 1; - case ROM_ACERV35N: - f = romfopen(L"roms/acerv35n/R01-C0.BIN", L"rb"); + case ROM_ACERV35N: + f = romfopen(L"roms/acerv35n/V35ND1S1.BIN", L"rb"); if (!f) break; fread(rom, 0x20000, 1, f); fclose(f); diff --git a/src/model.c b/src/model.c index ff24d4255..a1cc25433 100644 --- a/src/model.c +++ b/src/model.c @@ -130,6 +130,7 @@ extern void at_p54tp4xe_init(void); extern void at_ap53_init(void); extern void at_p55t2s_init(void); extern void at_acerm3a_init(void); +extern void at_acerv35n_init(void); extern void at_p55t2p4_init(void); extern void at_p55tvp4_init(void); extern void at_p55va_init(void); @@ -212,7 +213,7 @@ MODEL models[] = {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, - {"Acer V35n", ROM_ACERV35N, "acerv35n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, + {"Acer V35n", ROM_ACERV35N, "acerv35n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL}, {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, @@ -775,30 +776,28 @@ void at_acerm3a_init(void) pci_slot(0xe); pci_slot(0xf); i430hx_init(); - piix_init(7, 0xc, 0xd, 0xe, 0xf); + piix3_init(7, 0xc, 0xd, 0xe, 0xf); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); } -#if 0 void at_acerv35n_init(void) { at_ide_init(); memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xc); - pci_slot(0xd); - pci_slot(0xe); - pci_slot(0xf); + pci_slot(0x11); + pci_slot(0x12); + pci_slot(0x13); + pci_slot(0x14); i430hx_init(); - piix_init(7, 0xc, 0xd, 0xe, 0xf); + piix3_init(7, 0x11, 0x12, 0x13, 0x14); fdc37c932fr_init(); acerm3a_io_init(); device_add(&intel_flash_bxb_device); } -#endif void at_p55t2p4_init(void) { From 8dcc7176a9fdf3fdbdbd81123d82b26ffe7596ef Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 03:18:59 +0200 Subject: [PATCH 347/392] Hard disk image handling is now unified in hdd_image.c/h; Fixed some bugs regarding the Winbond W83877F Super I/O Chip and serial ports; Added the President Award 430FX PCI machine, thank you ashenone for the BIOS. --- src/Makefile.mingw | 24 +- src/fdc37c665.c | 2 + src/hdd_esdi.c | 76 ++---- src/hdd_image.c | 441 ++++++++++++++++++++++++++++++++++ src/hdd_image.h | 10 + src/ibm.h | 2 + src/ide.c | 275 ++------------------- src/ide.h | 1 - src/mem.c | 8 + src/mfm_at.c | 81 ++----- src/mfm_xebec.c | 95 +++----- src/model.c | 35 ++- src/scsi_aha154x.c | 6 +- src/scsi_buslogic.c | 6 +- src/scsi_disk.c | 552 ++----------------------------------------- src/scsi_disk.h | 4 - src/superio_detect.c | 52 ++++ src/superio_detect.h | 1 + src/w83877f.c | 37 ++- 19 files changed, 717 insertions(+), 991 deletions(-) create mode 100644 src/hdd_image.c create mode 100644 src/hdd_image.h create mode 100644 src/superio_detect.c create mode 100644 src/superio_detect.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index a2b5e746d..900e874a9 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.28 2017/06/14 +# Version: @(#)Makefile.mingw 1.0.29 2017/06/16 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -143,6 +143,7 @@ SYSOBJ = model.o \ olivetti_m24.o ps1.o ps2.o ps2_mca.o \ tandy_eeprom.o tandy_rom.o DEVOBJ = bugger.o lpt.o serial.o \ + fdc37c665.o fdc37c669.o fdc37c932fr.o \ pc87306.o sis85c471.o w83877f.o \ keyboard.o \ keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ @@ -151,9 +152,8 @@ DEVOBJ = bugger.o lpt.o serial.o \ joystick_standard.o joystick_ch_flightstick_pro.o \ joystick_sw_pad.o joystick_tm_fcs.o \ mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ - fdd.o fdc.o \ - fdc37c665.o fdc37c669.o fdc37c932fr.o fdi2raw.o \ - hdd.o \ + fdd.o fdc.o fdi2raw.o \ + hdd.o hdd_image.o \ mfm_at.o mfm_xebec.o hdd_esdi.o ide.o xtide.o piix.o \ disc.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ @@ -338,8 +338,10 @@ gameport.o: ibm.h cpu/cpu.h device.h io.h timer.h gameport.h \ hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h hdd_esdi.h \ mfm_at.h mfm_xebec.h xtide.h -hdd_esdi.o: ibm.h device.h dma.h io.h mca.h mem.h pic.h rom.h \ - timer.h hdd_esdi.h +hdd_image.o: ibm.h ide.h hdd_image.h + +hdd_esdi.o: ibm.h device.h dma.h hdd_image.h io.h mca.h mem.h \ + pic.h rom.h timer.h hdd_esdi.h headland.o: ibm.h cpu/cpu.h io.h mem.h headland.h @@ -357,7 +359,7 @@ i440fx.o: ibm.h io.h mem.h pci.h i440fx.h i82335.o: ibm.h io.h mem.h -ide.o: 86box.h cdrom.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h +ide.o: 86box.h cdrom.h hdd_image.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h intel.o: ibm.h cpu/cpu.h io.h mem.h pit.h timer.h intel.h @@ -410,9 +412,9 @@ mem.o: ibm.h cpu/cpu.h cpu/x86_ops.h cpu/x86.h config.h \ memregs.o: ibm.h io.h memregs.h -mfm_at.o: ibm.h device.h io.h pic.h timer.h mfm_at.h +mfm_at.o: ibm.h device.h hdd_image.h io.h pic.h timer.h mfm_at.h -mfm_xebec.o: ibm.h device.h dma.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h +mfm_xebec.o: ibm.h device.h dma.h hdd_image.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h model.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h mouse.h \ mouse_ps2.h cdrom.h acerm3a.h ali1429.h amstrad.h compaq.h \ @@ -497,8 +499,8 @@ scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \ scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \ device.h scsi.h scsi_disk.h cdrom.h scsi_buslogic.h -scsi_disk.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h scsi_disk.h \ - timer.h win/plat_iodev.h +scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \ + scsi_disk.h timer.h win/plat_iodev.h serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h diff --git a/src/fdc37c665.c b/src/fdc37c665.c index 00a80c429..56623d054 100644 --- a/src/fdc37c665.c +++ b/src/fdc37c665.c @@ -45,6 +45,7 @@ static void write_lock(uint8_t val) static void ide_handler() { +#if 0 uint16_t or_value = 0; if ((romset == ROM_440FX) || (romset == ROM_R418) || (romset == ROM_MB500N)) { @@ -65,6 +66,7 @@ static void ide_handler() ide_set_side(0, 0x376 | or_value); ide_pri_enable_ex(); } +#endif } static void set_com34_addr() diff --git a/src/hdd_esdi.c b/src/hdd_esdi.c index 4c3cc152d..4f31c8836 100644 --- a/src/hdd_esdi.c +++ b/src/hdd_esdi.c @@ -1,17 +1,9 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include - -#include +#include #include "ibm.h" #include "device.h" #include "dma.h" +#include "hdd_image.h" #include "io.h" #include "mca.h" #include "mem.h" @@ -30,7 +22,8 @@ typedef struct esdi_drive_t int spt, hpc; int tracks; int sectors; - FILE *hdfile; + int present; + int hdc_num; } esdi_drive_t; typedef struct esdi_t @@ -395,7 +388,7 @@ static void esdi_callback(void *p) case CMD_READ: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!drive->present) { device_not_present(esdi); return; @@ -431,8 +424,7 @@ static void esdi_callback(void *p) { if (esdi->rba >= drive->sectors) fatal("Read past end of drive\n"); - fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); - fread(esdi->data, 512, 1, drive->hdfile); + hdd_image_read(drive->hdc_num, esdi->rba, 1, (uint8_t *) esdi->data); update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1); } while (esdi->data_pos < 256) @@ -471,7 +463,7 @@ static void esdi_callback(void *p) case CMD_WRITE_VERIFY: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!drive->present) { device_not_present(esdi); return; @@ -518,8 +510,7 @@ static void esdi_callback(void *p) if (esdi->rba >= drive->sectors) fatal("Write past end of drive\n"); - fseek(drive->hdfile, esdi->rba * 512, SEEK_SET); - fwrite(esdi->data, 512, 1, drive->hdfile); + hdd_image_write(drive->hdc_num, esdi->rba, 1, (uint8_t *) esdi->data); esdi->rba++; esdi->sector_pos++; update_status_bar_icon(SB_HDD | HDD_BUS_RLL, 1); @@ -545,7 +536,7 @@ static void esdi_callback(void *p) case CMD_READ_VERIFY: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!drive->present) { device_not_present(esdi); return; @@ -560,7 +551,7 @@ static void esdi_callback(void *p) case CMD_SEEK: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!drive->present) { device_not_present(esdi); return; @@ -575,7 +566,7 @@ static void esdi_callback(void *p) case CMD_GET_DEV_CONFIG: ESDI_DRIVE_ONLY(); - if (!drive->hdfile) + if (!drive->present) { device_not_present(esdi); return; @@ -799,40 +790,22 @@ static void esdi_mca_write(int port, uint8_t val, void *p) static void loadhd(esdi_t *esdi, int hdc_num, int d, const wchar_t *fn) { esdi_drive_t *drive = &esdi->drives[d]; - - if (drive->hdfile == NULL) - { - /* Try to open existing hard disk image */ - drive->hdfile = _wfopen(fn, L"rb+"); - if (drive->hdfile == NULL) - { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) - { - /* Failed because it does not exist, - so try to create new file */ - drive->hdfile = _wfopen(fn, L"wb+"); - if (drive->hdfile == NULL) - { - pclog("Cannot create file '%s': %s", - fn, strerror(errno)); - return; - } - } - else - { - /* Failed for another reason */ - pclog("Cannot open file '%s': %s", - fn, strerror(errno)); - return; - } - } - } + int ret = 0; + ret = hdd_image_load(hdc_num); + + if (!ret) + { + drive->present = 0; + return; + } + drive->spt = hdc[hdc_num].spt; drive->hpc = hdc[hdc_num].hpc; drive->tracks = hdc[hdc_num].tracks; drive->sectors = hdc[hdc_num].spt * hdc[hdc_num].hpc * hdc[hdc_num].tracks; + drive->hdc_num = hdc_num; + drive->present = 1; } static void *esdi_init() @@ -878,9 +851,8 @@ static void esdi_close(void *p) for (d = 0; d < 2; d++) { esdi_drive_t *drive = &esdi->drives[d]; - - if (drive->hdfile != NULL) - fclose(drive->hdfile); + + hdd_image_close(drive->hdc_num); } free(esdi); diff --git a/src/hdd_image.c b/src/hdd_image.c new file mode 100644 index 000000000..ecfcbeb3a --- /dev/null +++ b/src/hdd_image.c @@ -0,0 +1,441 @@ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include "ibm.h" +#include "ide.h" +#include "hdd_image.h" + +typedef struct +{ + FILE *file; + uint32_t base; + uint32_t last_sector; + uint8_t type; + uint8_t loaded; +} hdd_image_t; + +hdd_image_t hdd_images[HDC_NUM]; + +static char empty_sector[512]; +static char *empty_sector_1mb; + +int hdd_image_do_log = 0; + +void hdd_image_log(const char *format, ...) +{ +#ifdef ENABLE_HDD_IMAGE_LOG + if (hdd_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + +int image_is_hdi(const wchar_t *s) +{ + int len; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + char *ws = (char *) s; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) + { + return 0; + } + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcsicmp(ext, L".HDI") == 0) + { + return 1; + } + else + { + return 0; + } +} + +int image_is_hdx(const wchar_t *s, int check_signature) +{ + int len; + FILE *f; + uint64_t filelen; + uint64_t signature; + char *ws = (char *) s; + wchar_t ext[5] = { 0, 0, 0, 0, 0 }; + len = wcslen(s); + if ((len < 4) || (s[0] == L'.')) + { + return 0; + } + memcpy(ext, ws + ((len - 4) << 1), 8); + if (wcsicmp(ext, L".HDX") == 0) + { + if (check_signature) + { + f = _wfopen(s, L"rb"); + if (!f) + { + return 0; + } + fseeko64(f, 0, SEEK_END); + filelen = ftello64(f); + fseeko64(f, 0, SEEK_SET); + if (filelen < 44) + { + return 0; + } + fread(&signature, 1, 8, f); + fclose(f); + if (signature == 0xD778A82044445459ll) + { + return 1; + } + else + { + return 0; + } + } + else + { + return 1; + } + } + else + { + return 0; + } +} + +int hdd_image_load(int id) +{ + uint32_t sector_size = 512; + uint32_t zero = 0; + uint64_t signature = 0xD778A82044445459ll; + uint64_t full_size = 0; + uint64_t spt = 0, hpc = 0, tracks = 0; + int c; + uint64_t i = 0, s = 0, t = 0; + wchar_t *fn = hdc[id].fn; + + memset(empty_sector, 0, sizeof(empty_sector)); + + hdd_images[id].base = 0; + hdd_images[id].loaded = 0; + + if (hdd_images[id].file != NULL) + { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + } + + /* Try to open existing hard disk image */ + if (fn[0] == '.') + { + hdd_image_log("File name starts with .\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + hdd_images[id].file = _wfopen(fn, L"rb+"); + if (hdd_images[id].file == NULL) + { + /* Failed to open existing hard disk image */ + if (errno == ENOENT) + { + /* Failed because it does not exist, + so try to create new file */ + if (hdc[id].wp) + { + hdd_image_log("A write-protected image must exist\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + + hdd_images[id].file = _wfopen(fn, L"wb+"); + if (hdd_images[id].file == NULL) + { + hdd_image_log("Unable to open image\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + else + { + if (image_is_hdi(fn)) + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + hdd_images[id].base = 0x1000; + fwrite(&zero, 1, 4, hdd_images[id].file); + fwrite(&zero, 1, 4, hdd_images[id].file); + fwrite(&(hdd_images[id].base), 1, 4, hdd_images[id].file); + fwrite(&full_size, 1, 4, hdd_images[id].file); + fwrite(§or_size, 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].spt), 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].tracks), 1, 4, hdd_images[id].file); + for (c = 0; c < 0x3f8; c++) + { + fwrite(&zero, 1, 4, hdd_images[id].file); + } + hdd_images[id].type = 1; + } + else if (image_is_hdx(fn, 0)) + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + hdd_images[id].base = 0x28; + fwrite(&signature, 1, 8, hdd_images[id].file); + fwrite(&full_size, 1, 8, hdd_images[id].file); + fwrite(§or_size, 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].spt), 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].hpc), 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].tracks), 1, 4, hdd_images[id].file); + fwrite(&zero, 1, 4, hdd_images[id].file); + fwrite(&zero, 1, 4, hdd_images[id].file); + hdd_images[id].type = 2; + } + else + { + hdd_images[id].type = 0; + } + hdd_images[id].last_sector = 0; + } + + s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + + goto prepare_new_hard_disk; + } + else + { + /* Failed for another reason */ + hdd_image_log("Failed for another reason\n"); + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + } + else + { + if (image_is_hdi(fn)) + { + fseeko64(hdd_images[id].file, 0x8, SEEK_SET); + fread(&(hdd_images[id].base), 1, 4, hdd_images[id].file); + fseeko64(hdd_images[id].file, 0xC, SEEK_SET); + full_size = 0; + fread(&full_size, 1, 4, hdd_images[id].file); + fseeko64(hdd_images[id].file, 0x10, SEEK_SET); + fread(§or_size, 1, 4, hdd_images[id].file); + if (sector_size != 512) + { + /* Sector size is not 512 */ + hdd_image_log("HDI: Sector size is not 512\n"); + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + fread(&spt, 1, 4, hdd_images[id].file); + fread(&hpc, 1, 4, hdd_images[id].file); + fread(&tracks, 1, 4, hdd_images[id].file); + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + hdd_image_log("HDI: Geometry mismatch\n"); + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; + hdd_images[id].type = 1; + } + else if (image_is_hdx(fn, 1)) + { + hdd_images[id].base = 0x28; + fseeko64(hdd_images[id].file, 8, SEEK_SET); + fread(&full_size, 1, 8, hdd_images[id].file); + fseeko64(hdd_images[id].file, 0x10, SEEK_SET); + fread(§or_size, 1, 4, hdd_images[id].file); + if (sector_size != 512) + { + /* Sector size is not 512 */ + hdd_image_log("HDX: Sector size is not 512\n"); + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + fread(&spt, 1, 4, hdd_images[id].file); + fread(&hpc, 1, 4, hdd_images[id].file); + fread(&tracks, 1, 4, hdd_images[id].file); + if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) + { + if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) + { + hdd_image_log("HDX: Geometry mismatch\n"); + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); + return 0; + } + } + hdc[id].spt = spt; + hdc[id].hpc = hpc; + hdc[id].tracks = tracks; + fread(&(hdc[id].at_spt), 1, 4, hdd_images[id].file); + fread(&(hdc[id].at_hpc), 1, 4, hdd_images[id].file); + hdd_images[id].type = 2; + } + else + { + full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; + hdd_images[id].type = 0; + } + } + + fseeko64(hdd_images[id].file, 0, SEEK_END); + if (ftello64(hdd_images[id].file) < (full_size + hdd_images[id].base)) + { + s = (full_size + hdd_images[id].base) - ftello64(hdd_images[id].file); +prepare_new_hard_disk: + s >>= 9; + t = (s >> 11) << 11; + s -= t; + t >>= 11; + + empty_sector_1mb = (char *) malloc(1048576); + memset(empty_sector_1mb, 0, 1048576); + + if (s > 0) + { + for (i = 0; i < s; i++) + { + fwrite(empty_sector, 1, 512, hdd_images[id].file); + } + } + + if (t > 0) + { + for (i = 0; i < t; i++) + { + fwrite(empty_sector_1mb, 1, 1045876, hdd_images[id].file); + } + } + + free(empty_sector_1mb); + } + + hdd_images[id].last_sector = (uint32_t) (full_size >> 9) - 1; + + return 1; + hdd_images[id].loaded = 1; +} + +void hdd_image_seek(uint8_t id, uint32_t sector) +{ + uint64_t addr = sector; + addr <<= 9; + addr += hdd_images[id].base; + + fseeko64(hdd_images[id].file, addr, SEEK_SET); +} + +void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) +{ + count <<= 9; + + hdd_image_seek(id, sector); + memset(buffer, 0, count); + fread(buffer, 1, count, hdd_images[id].file); +} + +void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer) +{ + count <<= 9; + + hdd_image_seek(id, sector); + fwrite(buffer, 1, count, hdd_images[id].file); +} + +void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count) +{ + int i = 0; + uint8_t *b; + + b = (uint8_t *) malloc(512); + memset(b, 0, 512); + + hdd_image_seek(id, sector); + for (i = 0; i < count; i++) + { + fwrite(b, 1, 512, hdd_images[id].file); + } + + free(b); +} + +uint32_t hdd_image_get_last_sector(uint8_t id) +{ + return hdd_images[id].last_sector; +} + +uint8_t hdd_image_get_type(uint8_t id) +{ + return hdd_images[id].type; +} + +void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt) +{ + if (hdd_images[id].type == 2) + { + hdc[id].at_hpc = hpc; + hdc[id].at_spt = spt; + fseeko64(hdd_images[id].file, 0x20, SEEK_SET); + fwrite(&(hdc[id].at_spt), 1, 4, hdd_images[id].file); + fwrite(&(hdc[id].at_hpc), 1, 4, hdd_images[id].file); + } +} + +void hdd_image_unload(uint8_t id, int fn_preserve) +{ + if (wcslen(hdc[id].fn) == 0) + { + return; + } + + if (hdd_images[id].loaded) + { + if (hdd_images[id].file != NULL) + { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + } + } + + hdd_images[id].last_sector = -1; + + memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); + if (fn_preserve) + { + wcscpy(hdc[id].prev_fn, hdc[id].fn); + } + + memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); +} + +void hdd_image_close(uint8_t id) +{ + if (hdd_images[id].file != NULL) + { + fclose(hdd_images[id].file); + hdd_images[id].file = NULL; + } +} diff --git a/src/hdd_image.h b/src/hdd_image.h new file mode 100644 index 000000000..e972894fe --- /dev/null +++ b/src/hdd_image.h @@ -0,0 +1,10 @@ +extern int hdd_image_load(int id); +extern void hdd_image_seek(uint8_t id, uint32_t sector); +extern void hdd_image_read(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); +extern void hdd_image_write(uint8_t id, uint32_t sector, uint32_t count, uint8_t *buffer); +extern void hdd_image_zero(uint8_t id, uint32_t sector, uint32_t count); +extern uint32_t hdd_image_get_last_sector(uint8_t id); +extern uint8_t hdd_image_get_type(uint8_t id); +extern void hdd_image_specify(uint8_t id, uint64_t hpc, uint64_t spt); +extern void hdd_image_unload(uint8_t id, int fn_preserve); +extern void hdd_image_close(uint8_t id); diff --git a/src/ibm.h b/src/ibm.h index a95d3635e..f75e5924f 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -471,6 +471,8 @@ enum ROM_S1668, /*Tyan Titan-Pro ATX / 440FX / AMI BIOS / SMC FDC37C669*/ ROM_IBMPS1_2133, + ROM_PRESIDENT, /*President Award 430FX PCI / 430FX / Award BIOS / Unknown Super I/O chip*/ + ROM_MAX }; diff --git a/src/ide.c b/src/ide.c index d92ce13be..4a11ed3a7 100644 --- a/src/ide.c +++ b/src/ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)ide.c 1.0.1 2017/06/03 + * Version: @(#)ide.c 1.0.2 2017/06/16 * * Authors: Sarah Walker, * Miran Grca, @@ -18,23 +18,14 @@ * Copyright 2016-2017 Miran Grca. * Copyright 2016-2017 TheCollector1995. */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include #include -#include -#include -#include - #include #include #include "86box.h" #include "cdrom.h" #include "ibm.h" +#include "hdd_image.h" #include "io.h" #include "pic.h" #include "timer.h" @@ -163,79 +154,6 @@ int ide_drive_is_cdrom(IDE *ide) } } -int image_is_hdi(const wchar_t *s) -{ - int len; - wchar_t ext[5] = { 0, 0, 0, 0, 0 }; - char *ws = (char *) s; - len = wcslen(s); - if ((len < 4) || (s[0] == L'.')) - { - return 0; - } - memcpy(ext, ws + ((len - 4) << 1), 8); - if (wcsicmp(ext, L".HDI") == 0) - { - return 1; - } - else - { - return 0; - } -} - -int image_is_hdx(const wchar_t *s, int check_signature) -{ - int len; - FILE *f; - uint64_t filelen; - uint64_t signature; - char *ws = (char *) s; - wchar_t ext[5] = { 0, 0, 0, 0, 0 }; - len = wcslen(s); - if ((len < 4) || (s[0] == L'.')) - { - return 0; - } - memcpy(ext, ws + ((len - 4) << 1), 8); - if (wcsicmp(ext, L".HDX") == 0) - { - if (check_signature) - { - f = _wfopen(s, L"rb"); - if (!f) - { - return 0; - } - fseeko64(f, 0, SEEK_END); - filelen = ftello64(f); - fseeko64(f, 0, SEEK_SET); - if (filelen < 44) - { - return 0; - } - fread(&signature, 1, 8, f); - fclose(f); - if (signature == 0xD778A82044445459ll) - { - return 1; - } - else - { - return 0; - } - } - else - { - return 1; - } - } - else - { - return 0; - } -} - int ide_enable[5] = { 1, 1, 0, 0, 1 }; int ide_irq[5] = { 14, 15, 10, 11, 0 }; @@ -371,7 +289,7 @@ static void ide_identify(IDE *ide) #if 0 uint64_t full_size = (hdc[ide->hdc_num].tracks * hdc[ide->hdc_num].hpc * hdc[ide->hdc_num].spt); #endif - + device_identify[6] = (ide->hdc_num / 10) + 0x30; device_identify[7] = (ide->hdc_num % 10) + 0x30; ide_log("IDE Identify: %s\n", device_identify); @@ -525,126 +443,22 @@ static void ide_next_sector(IDE *ide) static void loadhd(IDE *ide, int d, const wchar_t *fn) { - uint32_t sector_size = 512; - uint32_t zero = 0; - uint64_t signature = 0xD778A82044445459ll; - uint64_t full_size = 0; - int c; - ide->base = 0; - ide->hdi = 0; - if (ide->hdfile == NULL) + int ret = 0; + + ret = hdd_image_load(d); + + if (!ret) { - /* Try to open existing hard disk image */ - if (fn[0] == L'.') - { - ide->type = IDE_NONE; - return; - } - ide->hdfile = _wfopen(fn, L"rb+"); - if (ide->hdfile == NULL) - { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) - { - /* Failed because it does not exist, - so try to create new file */ - ide->hdfile = _wfopen(fn, L"wb+"); - if (ide->hdfile == NULL) - { - ide->type = IDE_NONE; - return; - } - else - { - if (image_is_hdi(fn)) - { - full_size = hdc[d].spt * hdc[d].hpc * hdc[d].tracks * 512; - ide->base = 0x1000; - ide->hdi = 1; - fwrite(&zero, 1, 4, ide->hdfile); - fwrite(&zero, 1, 4, ide->hdfile); - fwrite(&(ide->base), 1, 4, ide->hdfile); - fwrite(&full_size, 1, 4, ide->hdfile); - fwrite(§or_size, 1, 4, ide->hdfile); - fwrite(&(hdc[d].spt), 1, 4, ide->hdfile); - fwrite(&(hdc[d].hpc), 1, 4, ide->hdfile); - fwrite(&(hdc[d].tracks), 1, 4, ide->hdfile); - for (c = 0; c < 0x3f8; c++) - { - fwrite(&zero, 1, 4, ide->hdfile); - } - } - else if (image_is_hdx(fn, 0)) - { - full_size = hdc[d].spt * hdc[d].hpc * hdc[d].tracks * 512; - ide->base = 0x28; - ide->hdi = 2; - fwrite(&signature, 1, 8, ide->hdfile); - fwrite(&full_size, 1, 8, ide->hdfile); - fwrite(§or_size, 1, 4, ide->hdfile); - fwrite(&(hdc[d].spt), 1, 4, ide->hdfile); - fwrite(&(hdc[d].hpc), 1, 4, ide->hdfile); - fwrite(&(hdc[d].tracks), 1, 4, ide->hdfile); - fwrite(&zero, 1, 4, ide->hdfile); - fwrite(&zero, 1, 4, ide->hdfile); - } - ide->hdc_num = d; - } - } - else - { - /* Failed for another reason */ - ide->type = IDE_NONE; - return; - } - } - else - { - if (image_is_hdi(fn)) - { - fseeko64(ide->hdfile, 0x8, SEEK_SET); - fread(&(ide->base), 1, 4, ide->hdfile); - fseeko64(ide->hdfile, 0x10, SEEK_SET); - fread(§or_size, 1, 4, ide->hdfile); - if (sector_size != 512) - { - /* Sector size is not 512 */ - fclose(ide->hdfile); - ide->type = IDE_NONE; - return; - } - fread(&(hdc[d].spt), 1, 4, ide->hdfile); - fread(&(hdc[d].hpc), 1, 4, ide->hdfile); - fread(&(hdc[d].tracks), 1, 4, ide->hdfile); - ide->hdi = 1; - } - else if (image_is_hdx(fn, 1)) - { - ide->base = 0x28; - fseeko64(ide->hdfile, 0x10, SEEK_SET); - fread(§or_size, 1, 4, ide->hdfile); - if (sector_size != 512) - { - /* Sector size is not 512 */ - fclose(ide->hdfile); - ide->type = IDE_NONE; - return; - } - fread(&(hdc[d].spt), 1, 4, ide->hdfile); - fread(&(hdc[d].hpc), 1, 4, ide->hdfile); - fread(&(hdc[d].tracks), 1, 4, ide->hdfile); - fread(&(hdc[d].at_spt), 1, 4, ide->hdfile); - fread(&(hdc[d].at_hpc), 1, 4, ide->hdfile); - ide->hdi = 2; - } - } + ide->type = IDE_NONE; + return; } - - ide->spt = hdc[d].spt; - ide->hpc = hdc[d].hpc; - ide->tracks = hdc[d].tracks; - ide->type = IDE_HDD; + + ide->spt = hdc[d].spt; + ide->hpc = hdc[d].hpc; + ide->tracks = hdc[d].tracks; + ide->type = IDE_HDD; ide->hdc_num = d; + ide->hdi = hdd_image_get_type(d); } void ide_set_signature(IDE *ide) @@ -771,11 +585,7 @@ void resetide(void) { ide_drives[d].channel = d; ide_drives[d].type = IDE_NONE; - if (ide_drives[d].hdfile != NULL) - { - fclose(ide_drives[d].hdfile); - ide_drives[d].hdfile = NULL; - } + hdd_image_close(ide_drives[d].hdc_num); if (ide_drive_is_cdrom(&ide_drives[d])) { cdrom[atapi_cdrom_drives[d]].status = READY_STAT | DSC_STAT; @@ -856,13 +666,6 @@ void ide_write_data(int ide_board, uint32_t val, int length) uint16_t *idebufferw = ide->buffer; uint32_t *idebufferl = (uint32_t *) ide->buffer; -#if 0 - if (ide_drive_is_cdrom(ide)) - { - ide_log("CD-ROM write data: %04X\n", val); - } -#endif - if (ide->command == WIN_PACKETCMD) { ide->pos = 0; @@ -1621,8 +1424,6 @@ int times30=0; void callbackide(int ide_board) { IDE *ide, *ide_other; - off64_t addr; - int c; int64_t snum; int cdrom_id; uint64_t full_size = 0; @@ -1760,10 +1561,8 @@ void callbackide(int ide_board) { goto id_not_found; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); - fread(ide->buffer, 512, 1, ide->hdfile); + hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->pos=0; ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1781,9 +1580,7 @@ void callbackide(int ide_board) { goto id_not_found; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, addr, SEEK_SET); - fread(ide->buffer, 512, 1, ide->hdfile); + hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->pos=0; if (ide_bus_master_read) @@ -1831,9 +1628,7 @@ void callbackide(int ide_board) goto id_not_found; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); - fread(ide->buffer, 512, 1, ide->hdfile); + hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->pos=0; ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; if (!ide->blockcount) @@ -1859,9 +1654,7 @@ void callbackide(int ide_board) { goto id_not_found; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); - fwrite(ide->buffer, 512, 1, ide->hdfile); + hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide_irq_raise(ide); ide->secount = (ide->secount - 1) & 0xff; if (ide->secount) @@ -1898,9 +1691,7 @@ void callbackide(int ide_board) else { /*DMA successful*/ - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); - fwrite(ide->buffer, 512, 1, ide->hdfile); + hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; @@ -1931,9 +1722,7 @@ void callbackide(int ide_board) { goto id_not_found; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); - fwrite(ide->buffer, 512, 1, ide->hdfile); + hdd_image_write(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); ide->blockcount++; if (ide->blockcount >= ide->blocksize || ide->secount == 1) { @@ -1980,13 +1769,8 @@ void callbackide(int ide_board) { goto id_not_found; } - addr = ide_get_sector(ide) * 512; - fseeko64(ide->hdfile, ide->base + addr, SEEK_SET); - memset(ide->buffer, 0, 512); - for (c=0;csecount;c++) - { - fwrite(ide->buffer, 512, 1, ide->hdfile); - } + hdd_image_zero(ide->hdc_num, ide_get_sector(ide), ide->secount); + ide->atastat = READY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -2019,14 +1803,7 @@ void callbackide(int ide_board) full_size /= (ide->head+1); full_size /= ide->secount; ide->specify_success = 1; - if (ide->hdi == 2) - { - hdc[ide->hdc_num].at_hpc = ide->head+1; - hdc[ide->hdc_num].at_spt = ide->secount; - fseeko64(ide->hdfile, 0x20, SEEK_SET); - fwrite(&(hdc[ide->hdc_num].at_spt), 1, 4, ide->hdfile); - fwrite(&(hdc[ide->hdc_num].at_hpc), 1, 4, ide->hdfile); - } + hdd_image_specify(ide->hdc_num, ide->head + 1, ide->secount); ide->spt=ide->secount; ide->hpc=ide->head+1; ide->atastat = READY_STAT | DSC_STAT; diff --git a/src/ide.h b/src/ide.h index 003cbbb07..57057af13 100644 --- a/src/ide.h +++ b/src/ide.h @@ -38,7 +38,6 @@ typedef struct { int packetstatus; uint8_t asc; int reset; - FILE *hdfile; uint16_t buffer[65536]; int irqstat; int service; diff --git a/src/mem.c b/src/mem.c index 971d4ebb6..c401f0841 100644 --- a/src/mem.c +++ b/src/mem.c @@ -700,6 +700,14 @@ int loadbios() biosmask = 0x1ffff; return 1; + case ROM_PRESIDENT: + f = romfopen(L"roms/president/BIOS.BIN", L"rb"); + if (!f) break; + fread(rom, 0x20000, 1, f); + fclose(f); + biosmask = 0x1ffff; + return 1; + case ROM_P54TP4XE: f = romfopen(L"roms/p54tp4xe/T15I0302.AWD", L"rb"); if (!f) break; diff --git a/src/mfm_at.c b/src/mfm_at.c index b62fbbef0..eca973a85 100644 --- a/src/mfm_at.c +++ b/src/mfm_at.c @@ -1,16 +1,7 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include #include -#include -#include -#include - -#include -#include #include "ibm.h" +#include "hdd_image.h" #include "device.h" #include "io.h" #include "pic.h" @@ -53,7 +44,8 @@ typedef struct mfm_drive_t int cfg_spt; int cfg_hpc; int current_cylinder; - FILE *hdfile; + int present; + int hdc_num; } mfm_drive_t; typedef struct mfm_t @@ -163,39 +155,21 @@ static void mfm_next_sector(mfm_t *mfm) static void loadhd(mfm_t *mfm, int c, int d, const wchar_t *fn) { mfm_drive_t *drive = &mfm->drives[c]; - - if (drive->hdfile == NULL) - { - /* Try to open existing hard disk image */ - drive->hdfile = _wfopen(fn, L"rb+"); - if (drive->hdfile == NULL) - { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) - { - /* Failed because it does not exist, - so try to create new file */ - drive->hdfile = _wfopen(fn, L"wb+"); - if (drive->hdfile == NULL) - { - pclog("Cannot create file '%s': %s", - fn, strerror(errno)); - return; - } - } - else - { - /* Failed for another reason */ - pclog("Cannot open file '%s': %s", - fn, strerror(errno)); - return; - } - } - } + int ret = 0; + ret = hdd_image_load(d); + + if (!ret) + { + drive->present = 0; + return; + } + drive->spt = hdc[d].spt; drive->hpc = hdc[d].hpc; drive->tracks = hdc[d].tracks; + drive->hdc_num = d; + drive->present = 1; } @@ -233,14 +207,14 @@ void mfm_write(uint16_t port, uint8_t val, void *p) case 0x1F6: /* Drive/Head */ mfm->head = val & 0xF; mfm->drive_sel = (val & 0x10) ? 1 : 0; - if (mfm->drives[mfm->drive_sel].hdfile == NULL) - mfm->status = 0; - else + if (mfm->drives[mfm->drive_sel].present) mfm->status = STAT_READY | STAT_DSC; + else + mfm->status = 0; return; case 0x1F7: /* Command register */ - if (mfm->drives[mfm->drive_sel].hdfile == NULL) + if (!mfm->drives[mfm->drive_sel].present) fatal("Command on non-present drive\n"); mfm_irq_lower(mfm); @@ -462,7 +436,6 @@ void mfm_callback(void *p) mfm_t *mfm = (mfm_t *)p; mfm_drive_t *drive = &mfm->drives[mfm->drive_sel]; off64_t addr; - int c; mfm->callback = 0; if (mfm->reset) @@ -500,8 +473,7 @@ void mfm_callback(void *p) break; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(mfm->buffer, 512, 1, drive->hdfile); + hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) mfm->buffer); mfm->pos = 0; mfm->status = STAT_DRQ | STAT_READY | STAT_DSC; mfm_irq_raise(mfm); @@ -517,8 +489,7 @@ void mfm_callback(void *p) mfm_irq_raise(mfm); break; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fwrite(mfm->buffer, 512, 1, drive->hdfile); + hdd_image_write(drive->hdc_num, addr, 1, (uint8_t *) mfm->buffer); mfm_irq_raise(mfm); mfm->secount = (mfm->secount - 1) & 0xff; if (mfm->secount) @@ -552,12 +523,7 @@ void mfm_callback(void *p) mfm_irq_raise(mfm); break; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - memset(mfm->buffer, 0, 512); - for (c = 0; c < mfm->secount; c++) - { - fwrite(mfm->buffer, 512, 1, drive->hdfile); - } + hdd_image_zero(drive->hdc_num, addr, mfm->secount); mfm->status = STAT_READY | STAT_DSC; mfm_irq_raise(mfm); update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); @@ -624,9 +590,8 @@ void mfm_close(void *p) for (d = 0; d < 2; d++) { mfm_drive_t *drive = &mfm->drives[d]; - - if (drive->hdfile != NULL) - fclose(drive->hdfile); + + hdd_image_close(drive->hdc_num); } free(mfm); diff --git a/src/mfm_xebec.c b/src/mfm_xebec.c index b318c4de3..eb56d2ec0 100644 --- a/src/mfm_xebec.c +++ b/src/mfm_xebec.c @@ -1,17 +1,10 @@ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include - +#include #include #include "ibm.h" #include "device.h" #include "dma.h" +#include "hdd_image.h" #include "io.h" #include "mem.h" #include "pic.h" @@ -43,7 +36,8 @@ typedef struct mfm_drive_t int cfg_hpc; int cfg_cyl; int current_cylinder; - FILE *hdfile; + int present; + int hdc_num; } mfm_drive_t; typedef struct xebec_t @@ -297,6 +291,8 @@ static void xebec_next_sector(xebec_t *xebec) static void xebec_callback(void *p) { + off64_t addr; + xebec_t *xebec = (xebec_t *)p; mfm_drive_t *drive; @@ -310,13 +306,13 @@ static void xebec_callback(void *p) switch (xebec->command[0]) { case CMD_TEST_DRIVE_READY: - if (!drive->hdfile) + if (!drive->present) xebec_error(xebec, ERR_NOT_READY); xebec_complete(xebec); break; case CMD_RECALIBRATE: - if (!drive->hdfile) + if (!drive->present) xebec_error(xebec, ERR_NOT_READY); else { @@ -357,8 +353,6 @@ static void xebec_callback(void *p) xebec->sector_count = xebec->command[4]; do { - off64_t addr; - if (xebec_get_sector(xebec, &addr)) { pclog("xebec_get_sector failed\n"); @@ -384,9 +378,6 @@ static void xebec_callback(void *p) case CMD_FORMAT_TRACK: { - off64_t addr; - int c; - xebec->cylinder = xebec->command[3] | ((xebec->command[2] & 0xc0) << 2); drive->current_cylinder = (xebec->cylinder >= drive->cfg_cyl) ? drive->cfg_cyl-1 : xebec->cylinder; xebec->head = xebec->command[1] & 0x1f; @@ -398,10 +389,8 @@ static void xebec_callback(void *p) xebec_complete(xebec); return; } - - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - for (c = 0; c < 17; c++) - fwrite(xebec->sector_buf, 512, 1, drive->hdfile); + + hdd_image_zero(drive->hdc_num, addr, 17); xebec_complete(xebec); } @@ -420,8 +409,6 @@ static void xebec_callback(void *p) xebec->data_pos = 0; xebec->data_len = 512; { - off64_t addr; - if (xebec_get_sector(xebec, &addr)) { xebec_error(xebec, xebec->error); @@ -429,8 +416,7 @@ static void xebec_callback(void *p) return; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(xebec->sector_buf, 512, 1, drive->hdfile); + hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf); update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); } if (xebec->irq_dma_mask & DMA_ENA) @@ -474,8 +460,6 @@ static void xebec_callback(void *p) if (xebec->sector_count) { - off64_t addr; - if (xebec_get_sector(xebec, &addr)) { xebec_error(xebec, xebec->error); @@ -483,8 +467,7 @@ static void xebec_callback(void *p) return; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fread(xebec->sector_buf, 512, 1, drive->hdfile); + hdd_image_read(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf); update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); xebec->state = STATE_SEND_DATA; @@ -559,8 +542,6 @@ static void xebec_callback(void *p) memcpy(xebec->sector_buf, xebec->data, 512); { - off64_t addr; - if (xebec_get_sector(xebec, &addr)) { xebec_error(xebec, xebec->error); @@ -568,8 +549,7 @@ static void xebec_callback(void *p) return; } - fseeko64(drive->hdfile, addr * 512, SEEK_SET); - fwrite(xebec->sector_buf, 512, 1, drive->hdfile); + hdd_image_write(drive->hdc_num, addr, 1, (uint8_t *) xebec->sector_buf); } update_status_bar_icon(SB_HDD | HDD_BUS_MFM, 1); @@ -596,7 +576,7 @@ static void xebec_callback(void *p) break; case CMD_SEEK: - if (!drive->hdfile) + if (!drive->present) xebec_error(xebec, ERR_NOT_READY); else { @@ -766,39 +746,21 @@ static void xebec_callback(void *p) static void loadhd(xebec_t *xebec, int c, int d, const wchar_t *fn) { mfm_drive_t *drive = &xebec->drives[d]; - - if (drive->hdfile == NULL) - { - /* Try to open existing hard disk image */ - drive->hdfile = _wfopen(fn, L"rb+"); - if (drive->hdfile == NULL) - { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) - { - /* Failed because it does not exist, - so try to create new file */ - drive->hdfile = _wfopen(fn, L"wb+"); - if (drive->hdfile == NULL) - { - pclog("Cannot create file '%s': %s", - fn, strerror(errno)); - return; - } - } - else - { - /* Failed for another reason */ - pclog("Cannot open file '%s': %s", - fn, strerror(errno)); - return; - } - } - } + int ret = 0; + ret = hdd_image_load(d); + + if (!ret) + { + drive->present = 0; + return; + } + drive->spt = hdc[c].spt; drive->hpc = hdc[c].hpc; drive->tracks = hdc[c].tracks; + drive->hdc_num = c; + drive->present = 1; } static struct @@ -822,7 +784,7 @@ static void xebec_set_switches(xebec_t *xebec) { mfm_drive_t *drive = &xebec->drives[d]; - if (!drive->hdfile) + if (!drive->present) continue; for (c = 0; c < 4; c++) @@ -878,9 +840,8 @@ static void xebec_close(void *p) for (d = 0; d < 2; d++) { mfm_drive_t *drive = &xebec->drives[d]; - - if (drive->hdfile != NULL) - fclose(drive->hdfile); + + hdd_image_close(drive->hdc_num); } free(xebec); diff --git a/src/model.c b/src/model.c index a1cc25433..fdae935df 100644 --- a/src/model.c +++ b/src/model.c @@ -82,6 +82,9 @@ #include "sound/snd_ps1.h" #include "sound/snd_pssj.h" #include "sound/snd_sn76489.h" +#if 0 +#include "superio_detect.h" +#endif #include "tandy_eeprom.h" #include "tandy_rom.h" #if 0 @@ -120,12 +123,16 @@ extern void at_ali1429_init(void); extern void at_headland_init(void); extern void at_opti495_init(void); extern void at_batman_init(void); +#if 0 +extern void at_586mc1_init(void); +#endif extern void at_endeavor_init(void); extern void at_dtk486_init(void); extern void at_r418_init(void); extern void at_plato_init(void); extern void at_mb500n_init(void); +extern void at_president_init(void); extern void at_p54tp4xe_init(void); extern void at_ap53_init(void); extern void at_p55t2s_init(void); @@ -203,13 +210,17 @@ MODEL models[] = {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL}, {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL}, +#if 0 + {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL}, +#endif {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, + {"President Award 430FX PCI", ROM_PRESIDENT, "president", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, @@ -648,7 +659,7 @@ void at_premiere_common_init(void) pci_slot(0xc); pci_slot(0xe); pci_slot(0x6); - sio_init(2, 0xc, 0xe, 0x6, 0); + sio_init(1, 0xc, 0xe, 0x6, 0); fdc37c665_init(); intel_batman_init(); device_add(&intel_flash_bxt_ami_device); @@ -670,7 +681,7 @@ void at_586mc1_init(void) pci_slot(0xc); pci_slot(0xe); pci_slot(0x6); - sio_init(2, 0xc, 0xe, 0x6, 0); + sio_init(1, 0xc, 0xe, 0x6, 0); device_add(&intel_flash_bxt_device); secondary_ide_check(); } @@ -716,6 +727,24 @@ void at_mb500n_init(void) device_add(&intel_flash_bxt_device); } +void at_president_init(void) +{ + at_ide_init(); + memregs_init(); + pci_init(PCI_CONFIG_TYPE_1); + pci_slot(8); + pci_slot(9); + pci_slot(10); + pci_slot(11); + i430fx_init(); + piix_init(7, 8, 9, 10, 11); +#if 0 + superio_detect_init(); +#endif + w83877f_init(); + device_add(&intel_flash_bxt_device); +} + void at_p54tp4xe_init(void) { at_ide_init(); diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index dfb851d7f..a91abdf87 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -1796,12 +1796,12 @@ aha_disk_cmd(aha_t *dev) pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); } - memset(temp_cdb, 0, shdc[hdc_id].cdb_len); - if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) { + memset(temp_cdb, 0, 12); + if (req->CmdBlock.common.CdbLength <= 12) { memcpy(temp_cdb, req->CmdBlock.common.Cdb, req->CmdBlock.common.CdbLength); } else { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len); + memcpy(temp_cdb, req->CmdBlock.common.Cdb, 12); } /* diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 1b4c8794d..f9a215bee 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -1685,12 +1685,12 @@ BuslogicHDCommand(Buslogic_t *bl) pclog("SCSI Cdb[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); } - memset(temp_cdb, 0, shdc[hdc_id].cdb_len); - if (req->CmdBlock.common.CdbLength <= shdc[hdc_id].cdb_len) { + memset(temp_cdb, 0, 12); + if (req->CmdBlock.common.CdbLength <= 12) { memcpy(temp_cdb, req->CmdBlock.common.Cdb, req->CmdBlock.common.CdbLength); } else { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, shdc[hdc_id].cdb_len); + memcpy(temp_cdb, req->CmdBlock.common.Cdb, 12); } /* diff --git a/src/scsi_disk.c b/src/scsi_disk.c index 69726cf0b..340ffd6b3 100644 --- a/src/scsi_disk.c +++ b/src/scsi_disk.c @@ -6,26 +6,19 @@ * * Emulation of SCSI fixed and removable disks. * - * Version: @(#)scsi_disk.c 1.0.1 2017/06/03 + * Version: @(#)scsi_disk.c 1.0.2 2017/06/16 * * Author: Miran Grca, * Copyright 2017-2017 Miran Grca. */ -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include +#include #include -#include +#include #include "86box.h" #include "cdrom.h" #include "ibm.h" +#include "hdd_image.h" #include "ide.h" #include "piix.h" #include "scsi.h" @@ -213,278 +206,28 @@ void scsi_disk_insert(uint8_t id) shdc[id].unit_attention = (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) ? 1 : 0; } -static char empty_sector[512]; -static char *empty_sector_1mb; - void scsi_loadhd(int scsi_id, int scsi_lun, int id) { - uint32_t sector_size = 512; - uint32_t zero = 0; - uint64_t signature = 0xD778A82044445459ll; - uint64_t full_size = 0; - uint64_t spt = 0, hpc = 0, tracks = 0; - int c; - uint64_t i = 0, s = 0, t = 0; - wchar_t *fn = hdc[id].fn; + int ret = 0; - memset(empty_sector, 0, sizeof(empty_sector)); + ret = hdd_image_load(id); - shdc[id].base = 0; - - if (shdf[id] != NULL) + if (!ret) { - fclose(shdf[id]); - shdf[id] = NULL; - } - - /* Try to open existing hard disk image */ - if (fn[0] == '.') - { - scsi_hd_log("File name starts with .\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) { scsi_hard_disks[scsi_id][scsi_lun] = 0xff; } - else - { - shdc[id].cdb_len = 12; - } - return; - } - shdf[id] = _wfopen(fn, L"rb+"); - if (shdf[id] == NULL) - { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) - { - /* Failed because it does not exist, - so try to create new file */ - if (hdc[id].wp) - { - scsi_hd_log("A write-protected image must exist\n"); - goto scsi_hd_load_error; - } - - shdf[id] = _wfopen(fn, L"wb+"); - if (shdf[id] == NULL) - { -scsi_hd_load_error: - scsi_hd_log("Unable to open image\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) - { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; - } - else - { - shdc[id].cdb_len = 12; - } - return; - } - else - { - memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); - if (image_is_hdi(fn)) - { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - shdc[id].base = 0x1000; - fwrite(&zero, 1, 4, shdf[id]); - fwrite(&zero, 1, 4, shdf[id]); - fwrite(&(shdc[id].base), 1, 4, shdf[id]); - fwrite(&full_size, 1, 4, shdf[id]); - fwrite(§or_size, 1, 4, shdf[id]); - fwrite(&(hdc[id].spt), 1, 4, shdf[id]); - fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); - fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); - for (c = 0; c < 0x3f8; c++) - { - fwrite(&zero, 1, 4, shdf[id]); - } - } - else if (image_is_hdx(fn, 0)) - { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - shdc[id].base = 0x28; - fwrite(&signature, 1, 8, shdf[id]); - fwrite(&full_size, 1, 8, shdf[id]); - fwrite(§or_size, 1, 4, shdf[id]); - fwrite(&(hdc[id].spt), 1, 4, shdf[id]); - fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); - fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); - fwrite(&zero, 1, 4, shdf[id]); - fwrite(&zero, 1, 4, shdf[id]); - } - shdc[id].last_sector = 0; - shdc[id].cdb_len = 12; - } - - scsi_disk_insert(id); - - s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - - goto prepare_new_hard_disk; - } - else - { - /* Failed for another reason */ - scsi_hd_log("Failed for another reason\n"); - if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) - { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; - } - else - { - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - } - return; - } } else { - memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); - if (image_is_hdi(fn)) - { - fseeko64(shdf[id], 0x8, SEEK_SET); - fread(&(shdc[id].base), 1, 4, shdf[id]); - fseeko64(shdf[id], 0xC, SEEK_SET); - full_size = 0; - fread(&full_size, 1, 4, shdf[id]); - fseeko64(shdf[id], 0x10, SEEK_SET); - fread(§or_size, 1, 4, shdf[id]); - if (sector_size != 512) - { - /* Sector size is not 512 */ - scsi_hd_log("HDI: Sector size is not 512\n"); - fclose(shdf[id]); - if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) - { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; - } - else - { - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - } - return; - } - fread(&spt, 1, 4, shdf[id]); - fread(&hpc, 1, 4, shdf[id]); - fread(&tracks, 1, 4, shdf[id]); - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) - { - if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) - { - fclose(shdf[id]); - shdf[id] = NULL; - goto scsi_hd_load_error; - } - } - hdc[id].spt = spt; - hdc[id].hpc = hpc; - hdc[id].tracks = tracks; - } - else if (image_is_hdx(fn, 1)) - { - shdc[id].base = 0x28; - fseeko64(shdf[id], 8, SEEK_SET); - fread(&full_size, 1, 8, shdf[id]); - fseeko64(shdf[id], 0x10, SEEK_SET); - fread(§or_size, 1, 4, shdf[id]); - if (sector_size != 512) - { - /* Sector size is not 512 */ - scsi_hd_log("HDX: Sector size is not 512\n"); - fclose(shdf[id]); - if (hdc[id].bus != HDD_BUS_SCSI_REMOVABLE) - { - scsi_hard_disks[scsi_id][scsi_lun] = 0xff; - } - else - { - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - } - return; - } - fread(&spt, 1, 4, shdf[id]); - fread(&hpc, 1, 4, shdf[id]); - fread(&tracks, 1, 4, shdf[id]); - if (hdc[id].bus == HDD_BUS_SCSI_REMOVABLE) - { - if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) - { - fclose(shdf[id]); - shdf[id] = NULL; - goto scsi_hd_load_error; - } - } - hdc[id].spt = spt; - hdc[id].hpc = hpc; - hdc[id].tracks = tracks; - fread(&(hdc[id].at_spt), 1, 4, shdf[id]); - fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); - } - else - { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - } - shdc[id].cdb_len = 12; scsi_disk_insert(id); } - - fseeko64(shdf[id], 0, SEEK_END); - if (ftello64(shdf[id]) < (full_size + shdc[id].base)) - { - s = (full_size + shdc[id].base) - ftello64(shdf[id]); -prepare_new_hard_disk: - s >>= 9; - t = (s >> 11) << 11; - s -= t; - t >>= 11; - - empty_sector_1mb = (char *) malloc(1048576); - memset(empty_sector_1mb, 0, 1048576); - - if (s > 0) - { - for (i = 0; i < s; i++) - { - fwrite(empty_sector, 1, 512, shdf[id]); - } - } - - if (t > 0) - { - for (i = 0; i < t; i++) - { - fwrite(empty_sector_1mb, 1, 1045876, shdf[id]); - } - } - - free(empty_sector_1mb); - } - - shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; - -#if 0 - fclose(shdf[id]); -#endif } void scsi_reloadhd(int id) { - uint32_t sector_size = 512; - uint32_t zero = 0; - uint64_t signature = 0xD778A82044445459ll; - uint64_t full_size = 0; - uint64_t spt = 0, hpc = 0, tracks = 0; - int c; - uint64_t i = 0, s = 0, t = 0; - wchar_t *fn = hdc[id].fn; - - memset(empty_sector, 0, sizeof(empty_sector)); + int ret = 0; if(hdc[id].prev_fn == NULL) { @@ -496,232 +239,17 @@ void scsi_reloadhd(int id) memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); } - shdc[id].base = 0; + ret = hdd_image_load(id); - if (shdf[id] != NULL) + if (ret) { - fclose(shdf[id]); - shdf[id] = NULL; - } - - /* Try to open existing hard disk image */ - if (fn[0] == '.') - { - scsi_hd_log("File name starts with .\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - return; - } - shdf[id] = _wfopen(fn, L"rb+"); - if (shdf[id] == NULL) - { - /* Failed to open existing hard disk image */ - if (errno == ENOENT) - { - /* Failed because it does not exist, - so try to create new file */ - if (hdc[id].wp) - { - scsi_hd_log("A write-protected image must exist\n"); - goto scsi_hd_reload_error; - } - - shdf[id] = _wfopen(fn, L"wb+"); - if (shdf[id] == NULL) - { -scsi_hd_reload_error: - scsi_hd_log("Unable to open image\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - return; - } - else - { - memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); - if (image_is_hdi(fn)) - { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - shdc[id].base = 0x1000; - fwrite(&zero, 1, 4, shdf[id]); - fwrite(&zero, 1, 4, shdf[id]); - fwrite(&(shdc[id].base), 1, 4, shdf[id]); - fwrite(&full_size, 1, 4, shdf[id]); - fwrite(§or_size, 1, 4, shdf[id]); - fwrite(&(hdc[id].spt), 1, 4, shdf[id]); - fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); - fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); - for (c = 0; c < 0x3f8; c++) - { - fwrite(&zero, 1, 4, shdf[id]); - } - } - else if (image_is_hdx(fn, 0)) - { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - shdc[id].base = 0x28; - fwrite(&signature, 1, 8, shdf[id]); - fwrite(&full_size, 1, 8, shdf[id]); - fwrite(§or_size, 1, 4, shdf[id]); - fwrite(&(hdc[id].spt), 1, 4, shdf[id]); - fwrite(&(hdc[id].hpc), 1, 4, shdf[id]); - fwrite(&(hdc[id].tracks), 1, 4, shdf[id]); - fwrite(&zero, 1, 4, shdf[id]); - fwrite(&zero, 1, 4, shdf[id]); - } - shdc[id].last_sector = 0; - shdc[id].cdb_len = 12; - } - - scsi_disk_insert(id); - - s = full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - - goto reload_prepare_new_hard_disk; - } - else - { - /* Failed for another reason */ - scsi_hd_log("Failed for another reason\n"); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - return; - } - } - else - { - memset(&(shdc[id]), 0, sizeof(scsi_hard_disk_t)); - if (image_is_hdi(fn)) - { - fseeko64(shdf[id], 0x8, SEEK_SET); - fread(&(shdc[id].base), 1, 4, shdf[id]); - fseeko64(shdf[id], 0xC, SEEK_SET); - full_size = 0; - fread(&full_size, 1, 4, shdf[id]); - fseeko64(shdf[id], 0x10, SEEK_SET); - fread(§or_size, 1, 4, shdf[id]); - if (sector_size != 512) - { - /* Sector size is not 512 */ - scsi_hd_log("HDI: Sector size is not 512\n"); - fclose(shdf[id]); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - return; - } - fread(&spt, 1, 4, shdf[id]); - fread(&hpc, 1, 4, shdf[id]); - fread(&tracks, 1, 4, shdf[id]); - if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) - { - fclose(shdf[id]); - shdf[id] = NULL; - goto scsi_hd_reload_error; - } - hdc[id].spt = spt; - hdc[id].hpc = hpc; - hdc[id].tracks = tracks; - } - else if (image_is_hdx(fn, 1)) - { - shdc[id].base = 0x28; - fseeko64(shdf[id], 8, SEEK_SET); - fread(&full_size, 1, 8, shdf[id]); - fseeko64(shdf[id], 0x10, SEEK_SET); - fread(§or_size, 1, 4, shdf[id]); - if (sector_size != 512) - { - /* Sector size is not 512 */ - scsi_hd_log("HDX: Sector size is not 512\n"); - fclose(shdf[id]); - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - shdc[id].cdb_len = 12; - return; - } - fread(&spt, 1, 4, shdf[id]); - fread(&hpc, 1, 4, shdf[id]); - fread(&tracks, 1, 4, shdf[id]); - if ((spt != hdc[id].spt) || (hpc != hdc[id].hpc) || (tracks != hdc[id].tracks)) - { - fclose(shdf[id]); - shdf[id] = NULL; - goto scsi_hd_reload_error; - } - hdc[id].spt = spt; - hdc[id].hpc = hpc; - hdc[id].tracks = tracks; - fread(&(hdc[id].at_spt), 1, 4, shdf[id]); - fread(&(hdc[id].at_hpc), 1, 4, shdf[id]); - } - else - { - full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; - } - shdc[id].cdb_len = 12; scsi_disk_insert(id); } - - fseeko64(shdf[id], 0, SEEK_END); - if (ftello64(shdf[id]) < (full_size + shdc[id].base)) - { - s = (full_size + shdc[id].base) - ftello64(shdf[id]); -reload_prepare_new_hard_disk: - s >>= 9; - t = (s >> 11) << 11; - s -= t; - t >>= 11; - - empty_sector_1mb = (char *) malloc(1048576); - memset(empty_sector_1mb, 0, 1048576); - - if (s > 0) - { - for (i = 0; i < s; i++) - { - fwrite(empty_sector, 1, 512, shdf[id]); - } - } - - if (t > 0) - { - for (i = 0; i < t; i++) - { - fwrite(empty_sector_1mb, 1, 1045876, shdf[id]); - } - } - - free(empty_sector_1mb); - } - - shdc[id].last_sector = (uint32_t) (full_size >> 9) - 1; - -#if 0 - fclose(shdf[id]); -#endif } void scsi_unloadhd(int scsi_id, int scsi_lun, int id) { - if (wcslen(hdc[id].fn) == 0) - { - return; - } - - if (shdf[id] != NULL) - { - fclose(shdf[id]); - shdf[id] = NULL; - } - - shdc[id].last_sector = -1; - - memset(hdc[id].prev_fn, 0, sizeof(hdc[id].prev_fn)); - wcscpy(hdc[id].prev_fn, hdc[id].fn); - - memset(hdc[id].fn, 0, sizeof(hdc[id].fn)); - - shdc[id].cdb_len = 12; - - fclose(shdf[id]); + hdd_image_unload(id, 1); } void build_scsi_hd_map() @@ -746,10 +274,6 @@ void build_scsi_hd_map() { scsi_loadhd(i, j, scsi_hard_disks[i][j]); } - else - { - shdc[scsi_hard_disks[i][j]].cdb_len = 12; - } } } } @@ -759,7 +283,7 @@ int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *l { int size = 0; - size = shdc[id].last_sector; + size = hdd_image_get_last_sector(id); memset(buffer, 0, 8); buffer[0] = (size >> 24) & 0xff; buffer[1] = (size >> 16) & 0xff; @@ -771,16 +295,6 @@ int scsi_hd_read_capacity(uint8_t id, uint8_t *cdb, uint8_t *buffer, uint32_t *l return 1; } -void scsi_hd_set_cdb_len(int id, int cdb_len) -{ - shdc[id].cdb_len = cdb_len; -} - -void scsi_hd_reset_cdb_len(int id) -{ - shdc[id].cdb_len = 12; -} - void scsi_hd_update_request_length(uint8_t id, int len, int block_len) { /* For media access commands, make sure the requested DRQ length matches the block length. */ @@ -1080,7 +594,7 @@ int scsi_hd_pre_execution_check(uint8_t id, uint8_t *cdb) static void scsi_hd_seek(uint8_t id, uint32_t pos) { /* scsi_hd_log("SCSI HD %i: Seek %08X\n", id, pos); */ - shdc[id].seek_pos = pos; + hdd_image_seek(id, pos); } static void scsi_hd_rezero(uint8_t id) @@ -1179,14 +693,16 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) unsigned size_idx; unsigned preamble_len; uint32_t alloc_length; - uint64_t pos64; char device_identify[9] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', 0 }; char device_identify_ex[15] = { '8', '6', 'B', '_', 'H', 'D', '0', '0', ' ', 'v', '1', '.', '0', '0', 0 }; - char *tempbuffer; + uint8_t *tempbuffer; + uint32_t last_sector = 0; #if 0 int CdbLength; #endif + last_sector = hdd_image_get_last_sector(id); + shdc[id].status &= ~ERR_STAT; shdc[id].packet_len = 0; @@ -1210,7 +726,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) shdc[id].data_pos = 0; - memcpy(shdc[id].current_cdb, cdb, shdc[id].cdb_len); + memcpy(shdc[id].current_cdb, cdb, 12); if (cdb[0] != 0) { @@ -1218,7 +734,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) scsi_hd_log("SCSI HD %i: Request length: %04X\n", id, shdc[id].request_length); #if 0 - for (CdbLength = 1; CdbLength < shdc[id].cdb_len; CdbLength++) + for (CdbLength = 1; CdbLength < 12; CdbLength++) { scsi_hd_log("SCSI HD %i: CDB[%d] = 0x%02X\n", id, CdbLength, cdb[CdbLength]); } @@ -1284,7 +800,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector)) + if ((shdc[id].sector_pos > last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { scsi_hd_lba_out_of_range(id); return; @@ -1301,27 +817,18 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len = shdc[id].sector_len; shdc[id].requested_blocks = max_len; - pos64 = (uint64_t) shdc[id].sector_pos; - alloc_length = shdc[id].packet_len = max_len << 9; if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { -#if 0 - shdf[id] = _wfopen(hdc[id].fn, L"rb+"); -#endif - fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) { - fread(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]); + hdd_image_read(id, shdc[id].sector_pos, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength >> 9, hdbufferb); } else { - fread(hdbufferb, 1, alloc_length, shdf[id]); + hdd_image_read(id, shdc[id].sector_pos, max_len, hdbufferb); } -#if 0 - fclose(shdf[id]); -#endif } if (shdc[id].requested_blocks > 1) @@ -1369,7 +876,7 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) break; } - if ((shdc[id].sector_pos > shdc[id].last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > shdc[id].last_sector)) + if ((shdc[id].sector_pos > last_sector) || ((shdc[id].sector_pos + shdc[id].sector_len - 1) > last_sector)) { scsi_hd_lba_out_of_range(id); return; @@ -1386,27 +893,18 @@ void scsi_hd_command(uint8_t id, uint8_t *cdb) max_len = shdc[id].sector_len; shdc[id].requested_blocks = max_len; - pos64 = (uint64_t) shdc[id].sector_pos; - alloc_length = shdc[id].packet_len = max_len << 9; if ((shdc[id].requested_blocks > 0) && (SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength > 0)) { -#if 0 - shdf[id] = _wfopen(hdc[id].fn, L"rb+"); -#endif - fseeko64(shdf[id], shdc[id].base + (pos64 << 9), SEEK_SET); if (alloc_length > SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength) { - fwrite(hdbufferb, 1, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength, shdf[id]); + hdd_image_write(id, shdc[id].sector_pos, SCSIDevices[hdc[id].scsi_id][hdc[id].scsi_lun].InitLength >> 9, hdbufferb); } else { - fwrite(hdbufferb, 1, alloc_length, shdf[id]); + hdd_image_write(id, shdc[id].sector_pos, max_len, hdbufferb); } -#if 0 - fclose(shdf[id]); -#endif } if (shdc[id].requested_blocks > 1) diff --git a/src/scsi_disk.h b/src/scsi_disk.h index 95fdd9316..db3ea9848 100644 --- a/src/scsi_disk.h +++ b/src/scsi_disk.h @@ -36,14 +36,10 @@ typedef struct { uint8_t error; uint32_t sector_pos; uint32_t sector_len; - uint32_t last_sector; uint32_t seek_pos; int data_pos; int old_len; - int cdb_len_setting; - int cdb_len; int request_pos; - uint64_t base; uint8_t hd_cdb[16]; } scsi_hard_disk_t; #pragma pack(pop) diff --git a/src/superio_detect.c b/src/superio_detect.c new file mode 100644 index 000000000..dbedca3cd --- /dev/null +++ b/src/superio_detect.c @@ -0,0 +1,52 @@ +/* + SMSC SMC FDC37C665 Super I/O Chip + Used by Batman's Revenge +*/ + +#include "ibm.h" + +#include "io.h" +#include "disc.h" +#include "fdd.h" +#include "fdc.h" +#include "superio_detect.h" + +static int fdc37c665_locked; +static int fdc37c665_curreg = 0; +static uint8_t detect_regs[2]; +static uint8_t tries; + +void superio_detect_write(uint16_t port, uint8_t val, void *priv) +{ + uint8_t index = (port & 1) ? 0 : 1; + uint8_t valxor = 0; + int temp; + pclog("superio_detect_write : port=%04x = %02X\n", port, val); + + detect_regs[port & 1] = val; + return; +} + +uint8_t superio_detect_read(uint16_t port, void *priv) +{ + pclog("superio_detect_read : port=%04x = %02X\n", port, detect_regs[port & 1]); + + return detect_regs[port & 1]; +} + +void superio_detect_init() +{ + fdc_remove(); + fdc_add_for_superio(); + + io_sethandler(0x24, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x26, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x2e, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x44, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x46, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x4e, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x108, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x250, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x370, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); + io_sethandler(0x3f0, 0x0002, superio_detect_read, NULL, NULL, superio_detect_write, NULL, NULL, NULL); +} diff --git a/src/superio_detect.h b/src/superio_detect.h new file mode 100644 index 000000000..542fafac5 --- /dev/null +++ b/src/superio_detect.h @@ -0,0 +1 @@ +extern void superio_detect_init(); diff --git a/src/w83877f.c b/src/w83877f.c index 6a6dd0552..f9fc3c6ec 100644 --- a/src/w83877f.c +++ b/src/w83877f.c @@ -216,6 +216,7 @@ static void w83877f_remap() winbond_port = (HEFRAS ? 0x3f0 : 0x250); winbond_key_times = HEFRAS + 1; winbond_key = (HEFRAS ? 0x86 : 0x88) | HEFERE; + pclog("W83877F: Remapped to port %04X, key %02X\n", winbond_port, winbond_key); } static uint8_t is_in_array(uint16_t *port_array, uint8_t max, uint16_t port) @@ -282,6 +283,24 @@ static uint16_t make_port(uint8_t reg) return p; } +void w83877f_serial_handler(int id) +{ + int reg_mask = (id - 1) ? 0x10 : 0x20; + int reg_id = (id - 1) ? 0x24 : 0x25; + int irq_mask = (id - 1) ? 0xF : 0xF0; + + /* pclog("Registers (%i): %02X %02X %02X\n", id, w83877f_regs[4], w83877f_regs[reg_id], w83877f_regs[0x28]); */ + + if ((w83877f_regs[4] & reg_mask) || !(w83877f_regs[reg_id] & 0xc0)) + { + serial_remove(id); + } + else + { + serial_setup(id, make_port(reg_id), w83877f_regs[0x28] & irq_mask); + } +} + void w83877f_write(uint16_t port, uint8_t val, void *priv) { uint8_t index = (port & 1) ? 0 : 1; @@ -353,16 +372,11 @@ process_value: case 4: if (valxor & 0x10) { - serial_remove(2); - if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); + w83877f_serial_handler(2); } if (valxor & 0x20) { - serial_remove(1); - if (!(w83877f_regs[4] & 0x20)) - { - serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); - } + w83877f_serial_handler(1); } if (valxor & 0x80) { @@ -418,16 +432,13 @@ process_value: case 0x24: if (valxor & 0xfe) { - if (!(w83877f_regs[4] & 0x20)) - { - serial_setup(1, make_port(0x24), (w83877f_regs[0x28] & 0xF0) >> 8); - } + w83877f_serial_handler(1); } break; case 0x25: if (valxor & 0xfe) { - if (!(w83877f_regs[2] & 0x10)) serial_setup(2, make_port(0x25), w83877f_regs[0x28] & 0xF); + w83877f_serial_handler(2); } break; case 0x28: @@ -486,7 +497,7 @@ void w83877f_reset(void) w83877f_regs[0xA] = 0x1F; w83877f_regs[0xC] = 0x28; w83877f_regs[0xD] = 0xA3; - w83877f_regs[0x16] = 5; + w83877f_regs[0x16] = (romset == ROM_PRESIDENT) ? 4 : 5; w83877f_regs[0x1E] = 0x81; w83877f_regs[0x20] = (0x3f0 >> 2) & 0xfc; w83877f_regs[0x21] = (0x1f0 >> 2) & 0xfc; From 657f633edb182efd81d0d0f4caad7d1b58d4a86b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 03:40:18 +0200 Subject: [PATCH 348/392] Fixed the bus location controls in the Settings and Add Hard Disk dialogs. --- src/WIN/86Box.rc | 10 ++++------ src/WIN/win_settings.c | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 0a64e8b42..156839915 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -384,7 +384,6 @@ BEGIN LTEXT "LUN:",IDT_1724,200,118,38,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,170,117,90,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1725,131,118,38,8 END DLG_CFG_HARD_DISKS_ADD DIALOG DISCARDABLE 0, 0, 219, 111 @@ -410,19 +409,18 @@ BEGIN LTEXT "File name:",IDT_1731,7,7,204,9 COMBOBOX IDC_COMBO_HD_BUS,33,71,58,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Bus:",IDT_1732,7,72,24,8 + LTEXT "Bus:",IDT_1721,7,72,24,8 COMBOBOX IDC_COMBO_HD_CHANNEL,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1733,99,72,34,8 + LTEXT "Channel:",IDT_1722,99,72,34,8 COMBOBOX IDC_COMBO_HD_ID,133,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "ID:",IDT_1734,117,72,15,8 + LTEXT "ID:",IDT_1723,117,72,15,8 COMBOBOX IDC_COMBO_HD_LUN,185,71,26,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "LUN:",IDT_1735,168,72,15,8 + LTEXT "LUN:",IDT_1724,168,72,15,8 COMBOBOX IDC_COMBO_HD_CHANNEL_IDE,134,71,77,12,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel:",IDT_1736,99,72,34,8 END /* Static text label IDs. */ diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 865bc39dd..fffbbbf34 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1860,7 +1860,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) int bus = 0; - for (i = 1799; i < 1803; i++) + for (i = IDT_1722; i < IDT_1725; i++) { h = GetDlgItem(hdlg, i); EnableWindow(h, FALSE); @@ -1892,7 +1892,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) switch(bus) { case HDD_BUS_MFM: /* MFM */ - h = GetDlgItem(hdlg, 1799); + h = GetDlgItem(hdlg, IDT_1722); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1902,7 +1902,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.mfm_channel : temp_hdc[hdlv_current_sel].mfm_channel, 0); break; case HDD_BUS_RLL: /* RLL */ - h = GetDlgItem(hdlg, 1799); + h = GetDlgItem(hdlg, IDT_1722); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1912,7 +1912,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) SendMessage(h, CB_SETCURSEL, is_add_dlg ? new_hdc.rll_channel : temp_hdc[hdlv_current_sel].rll_channel, 0); break; case HDD_BUS_XTIDE: /* XT IDE */ - h = GetDlgItem(hdlg, 1799); + h = GetDlgItem(hdlg, IDT_1722); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1923,7 +1923,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) break; case HDD_BUS_IDE_PIO_ONLY: /* IDE (PIO-only) */ case HDD_BUS_IDE_PIO_AND_DMA: /* IDE (PIO and DMA) */ - h = GetDlgItem(hdlg, 1802); + h = GetDlgItem(hdlg, IDT_1722); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1934,10 +1934,10 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) break; case HDD_BUS_SCSI: /* SCSI */ case HDD_BUS_SCSI_REMOVABLE: /* SCSI (removable) */ - h = GetDlgItem(hdlg, 1800); + h = GetDlgItem(hdlg, IDT_1723); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, 1801); + h = GetDlgItem(hdlg, IDT_1724); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -1956,7 +1956,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) if ((hd_listview_items == 0) && !is_add_dlg) { - h = GetDlgItem(hdlg, 1798); + h = GetDlgItem(hdlg, IDT_1721); EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); @@ -1965,7 +1965,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) } else { - h = GetDlgItem(hdlg, 1798); + h = GetDlgItem(hdlg, IDT_1721); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3758,7 +3758,7 @@ static void cdrom_recalc_location_controls(HWND hdlg) int bus = temp_cdrom_drives[cdlv_current_sel].bus_type; - for (i = 1800; i < 1803; i++) + for (i = IDT_1741; i < (IDT_1743 + 1); i++) { h = GetDlgItem(hdlg, i); EnableWindow(h, FALSE); @@ -3779,9 +3779,9 @@ static void cdrom_recalc_location_controls(HWND hdlg) switch(bus) { - case CDROM_BUS_ATAPI_PIO_ONLY: /* ATAPI (PIO-only) */ + case CDROM_BUS_ATAPI_PIO_ONLY: /* ATAPI (PIO-only) */ case CDROM_BUS_ATAPI_PIO_AND_DMA: /* ATAPI (PIO and DMA) */ - h = GetDlgItem(hdlg, 1802); + h = GetDlgItem(hdlg, IDT_1743); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); @@ -3791,14 +3791,14 @@ static void cdrom_recalc_location_controls(HWND hdlg) SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].ide_channel, 0); break; case CDROM_BUS_SCSI: /* SCSI */ - h = GetDlgItem(hdlg, 1800); + h = GetDlgItem(hdlg, IDT_1741); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); h = GetDlgItem(hdlg, 1801); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); + h = GetDlgItem(hdlg, IDT_1742); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); From 464b1a624fe5afbeceeba3adcec11f1aea146beb Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 04:14:50 +0200 Subject: [PATCH 349/392] Fixed the hard disk controls in the Settings dialog. --- src/WIN/win_settings.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index fffbbbf34..a5749f1d1 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -3794,11 +3794,11 @@ static void cdrom_recalc_location_controls(HWND hdlg) h = GetDlgItem(hdlg, IDT_1741); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, 1801); + h = GetDlgItem(hdlg, IDT_1742); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); - h = GetDlgItem(hdlg, IDT_1742); + h = GetDlgItem(hdlg, IDC_COMBO_CD_ID); ShowWindow(h, SW_SHOW); EnableWindow(h, TRUE); SendMessage(h, CB_SETCURSEL, temp_cdrom_drives[cdlv_current_sel].scsi_device_id, 0); From 477491ca003e28d677641c17cb125f373d8d0f3d Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 15 Jun 2017 22:40:43 -0400 Subject: [PATCH 350/392] Resources postfix. --- src/WIN/86Box.rc | 48 +---------------------- src/WIN/resource.h | 88 ++++++++++++++++++++---------------------- src/WIN/win_settings.c | 2 +- 3 files changed, 43 insertions(+), 95 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 156839915..73f326984 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -8,7 +8,7 @@ * * Windows resource script. * - * Version: @(#)86Box.rc 1.0.2 2017/06/04 + * Version: @(#)86Box.rc 1.0.3 2017/06/16 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -423,52 +423,6 @@ BEGIN WS_VSCROLL | WS_TABSTOP END -/* Static text label IDs. */ -#define IDT_1700 1700 // Language: -#define IDT_1701 1701 // Machine: -#define IDT_1702 1702 // CPU type: -#define IDT_1703 1703 // Wait states: -#define IDT_1704 1704 // CPU: -#define IDT_1705 1705 // MB == IDC_TEXT_MB -#define IDT_1706 1706 // Memory: -#define IDT_1707 1707 // Video: -#define IDT_1708 1708 // Video speed: -#define IDT_1709 1709 // Mouse: -#define IDT_1710 1710 // Joystick: -#define IDT_1711 1711 // Sound card: -#define IDT_1712 1712 // MIDI Out Device: -#define IDT_1713 1713 // Network type: -#define IDT_1714 1714 // PCap device: -#define IDT_1715 1715 // Network adapter: -#define IDT_1716 1716 // SCSI Controller: -#define IDT_1717 1717 // HD Controller: -#define IDT_1718 1718 // Tertiary IDE: -#define IDT_1719 1719 // Quaternary IDE: -#define IDT_1720 1720 // Hard disks: -#define IDT_1721 1721 // Bus: -#define IDT_1722 1722 // Channel: -#define IDT_1723 1723 // ID: -#define IDT_1724 1724 // LUN: -#define IDT_1725 1725 // Channel: -#define IDT_1726 1726 // Sectors: -#define IDT_1727 1727 // Heads: -#define IDT_1728 1728 // Cylinders: -#define IDT_1729 1729 // Size (MB): -#define IDT_1730 1730 // Type: -#define IDT_1731 1731 // File name: -#define IDT_1732 1732 // Bus: -#define IDT_1733 1733 // Channel: -#define IDT_1734 1734 // ID: -#define IDT_1735 1735 // LUN: -#define IDT_1736 1736 // Channel: -#define IDT_1737 1737 // Floppy drives: -#define IDT_1738 1738 // Type: -#define IDT_1739 1739 // CD-ROM drives: -#define IDT_1740 1740 // Bus: -#define IDT_1741 1741 // ID: -#define IDT_1742 1742 // LUN: -#define IDT_1743 1743 // Channel: - DLG_CFG_REMOVABLE_DEVICES DIALOG DISCARDABLE 97, 0, 267, 202 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" diff --git a/src/WIN/resource.h b/src/WIN/resource.h index 39feb0a5d..d73057c21 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -10,7 +10,7 @@ * * NOTE: FIXME: Strings 2176 and 2193 are same. * - * Version: @(#)resource.h 1.0.3 2017/06/04 + * Version: @(#)resource.h 1.0.4 2017/06/16 * * Authors: Sarah Walker, * Miran Grca, @@ -37,52 +37,46 @@ #define DLG_CFG_REMOVABLE_DEVICES 119 /* sub-dialog of config */ /* Static text label IDs. */ -#define IDT_1700 1700 // Language: -#define IDT_1701 1701 // Machine: -#define IDT_1702 1702 // CPU type: -#define IDT_1703 1703 // Wait states: -#define IDT_1704 1704 // CPU: -#define IDT_1705 1705 // MB == IDC_TEXT_MB -#define IDT_1706 1706 // Memory: -#define IDT_1707 1707 // Video: -#define IDT_1708 1708 // Video speed: -#define IDT_1709 1709 // Mouse: -#define IDT_1710 1710 // Joystick: -#define IDT_1711 1711 // Sound card: -#define IDT_1712 1712 // MIDI Out Device: -#define IDT_1713 1713 // Network type: -#define IDT_1714 1714 // PCap device: -#define IDT_1715 1715 // Network adapter: -#define IDT_1716 1716 // SCSI Controller: -#define IDT_1717 1717 // HD Controller: -#define IDT_1718 1718 // Tertiary IDE: -#define IDT_1719 1719 // Quaternary IDE: -#define IDT_1720 1720 // Hard disks: -#define IDT_1721 1721 // Bus: -#define IDT_1722 1722 // Channel: -#define IDT_1723 1723 // ID: -#define IDT_1724 1724 // LUN: -#define IDT_1725 1725 // Channel: -#define IDT_1726 1726 // Sectors: -#define IDT_1727 1727 // Heads: -#define IDT_1728 1728 // Cylinders: -#define IDT_1729 1729 // Size (MB): -#define IDT_1730 1730 // Type: -#define IDT_1731 1731 // File name: -#define IDT_1732 1732 // Bus: -#define IDT_1733 1733 // Channel: -#define IDT_1734 1734 // ID: -#define IDT_1735 1735 // LUN: -#define IDT_1736 1736 // Channel: -#define IDT_1737 1737 // Floppy drives: -#define IDT_1738 1738 // Type: -#define IDT_1739 1739 // CD-ROM drives: -#define IDT_1740 1740 // Bus: -#define IDT_1741 1741 // ID: -#define IDT_1742 1742 // LUN: -#define IDT_1743 1743 // Channel: -#define IDT_STEXT 1744 // text in status window -#define IDT_SDEVICE 1745 // text in status window +#define IDT_1700 1700 /* Language: */ +#define IDT_1701 1701 /* Machine: */ +#define IDT_1702 1702 /* CPU type: */ +#define IDT_1703 1703 /* Wait states: */ +#define IDT_1704 1704 /* CPU: */ +#define IDT_1705 1705 /* MB == IDC_TEXT_MB */ +#define IDT_1706 1706 /* Memory: */ +#define IDT_1707 1707 /* Video: */ +#define IDT_1708 1708 /* Video speed: */ +#define IDT_1709 1709 /* Mouse: */ +#define IDT_1710 1710 /* Joystick: */ +#define IDT_1711 1711 /* Sound card: */ +#define IDT_1712 1712 /* MIDI Out Device: */ +#define IDT_1713 1713 /* Network type: */ +#define IDT_1714 1714 /* PCap device: */ +#define IDT_1715 1715 /* Network adapter: */ +#define IDT_1716 1716 /* SCSI Controller: */ +#define IDT_1717 1717 /* HD Controller: */ +#define IDT_1718 1718 /* Tertiary IDE: */ +#define IDT_1719 1719 /* Quaternary IDE: */ +#define IDT_1720 1720 /* Hard disks: */ +#define IDT_1721 1721 /* Bus: */ +#define IDT_1722 1722 /* Channel: */ +#define IDT_1723 1723 /* ID: */ +#define IDT_1724 1724 /* LUN: */ +#define IDT_1726 1726 /* Sectors: */ +#define IDT_1727 1727 /* Heads: */ +#define IDT_1728 1728 /* Cylinders: */ +#define IDT_1729 1729 /* Size (MB): */ +#define IDT_1730 1730 /* Type: */ +#define IDT_1731 1731 /* File name: */ +#define IDT_1737 1737 /* Floppy drives: */ +#define IDT_1738 1738 /* Type: */ +#define IDT_1739 1739 /* CD-ROM drives: */ +#define IDT_1740 1740 /* Bus: */ +#define IDT_1741 1741 /* ID: */ +#define IDT_1742 1742 /* LUN: */ +#define IDT_1743 1743 /* Channel: */ +#define IDT_STEXT 1744 /* text in status window */ +#define IDT_SDEVICE 1745 /* text in status window */ /* diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index a5749f1d1..4b7446bff 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1860,7 +1860,7 @@ static void recalc_location_controls(HWND hdlg, int is_add_dlg) int bus = 0; - for (i = IDT_1722; i < IDT_1725; i++) + for (i = IDT_1722; i <= IDT_1724; i++) { h = GetDlgItem(hdlg, i); EnableWindow(h, FALSE); From 8061db66fe3283b31fa618951ddd8547e0491ba1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 06:44:11 +0200 Subject: [PATCH 351/392] A lot of cleanaps, got rid of all warnings with -Wall; The makefile now uses -Wall. --- src/CPU/codegen.h | 9 +- src/CPU/codegen_ops_arith.h | 348 +++++----- src/CPU/codegen_ops_fpu.h | 70 +- src/CPU/codegen_ops_jump.h | 10 +- src/CPU/codegen_ops_misc.h | 68 +- src/CPU/codegen_ops_mmx.h | 36 +- src/CPU/codegen_ops_mov.h | 12 +- src/CPU/codegen_ops_shift.h | 24 +- src/CPU/codegen_ops_stack.h | 10 - src/CPU/codegen_ops_x86-64.h | 894 ++++++++++++------------ src/CPU/codegen_ops_x86.h | 1040 ++++++++++++++-------------- src/CPU/codegen_timing_686.c | 7 +- src/CPU/codegen_timing_pentium.c | 7 +- src/CPU/codegen_x86.c | 206 +++--- src/CPU/x86_ops_call.h | 16 +- src/CPU/x86_ops_i686.h | 14 +- src/CPU/x86_ops_int.h | 40 +- src/CPU/x86_ops_ret.h | 14 +- src/CPU/x87_ops.h | 8 +- src/CPU/x87_ops_arith.h | 5 +- src/CPU/x87_ops_misc.h | 13 +- src/Makefile.mingw | 2 +- src/NETWORK/net_ne2000.c | 10 +- src/NETWORK/net_slirp.c | 3 - src/NETWORK/network.c | 2 - src/NETWORK/pcap_if.c | 5 +- src/SOUND/dbopl.cpp | 6 + src/VIDEO/vid_ega_render.c | 14 +- src/VIDEO/vid_et4000w32.c | 1 - src/VIDEO/vid_s3.c | 2 +- src/VIDEO/vid_s3_virge.c | 8 +- src/VIDEO/vid_svga_render.c | 40 +- src/VIDEO/vid_voodoo_codegen_x86.h | 12 +- src/WIN/win_d3d.cc | 1 - src/WIN/win_deviceconfig.c | 2 - src/WIN/win_dynld.c | 2 +- src/WIN/win_midi.c | 23 +- src/WIN/win_serial.c | 7 - src/WIN/win_settings.c | 5 +- src/cdrom_dosbox.cpp | 12 +- src/cdrom_dosbox.h | 2 +- src/cdrom_image.cc | 17 - src/cdrom_ioctl.c | 4 +- src/config.c | 3 +- src/disc_imd.c | 6 +- src/disc_img.c | 52 +- src/ibm.h | 2 + src/intel_flash.c | 8 +- src/keyboard_amstrad.c | 2 +- src/keyboard_olim24.c | 14 +- src/mem.c | 6 +- src/model.c | 139 ++-- src/mouse_bus.c | 2 +- src/pc.c | 8 +- src/pit.c | 2 +- src/scsi_aha154x.c | 11 +- src/scsi_buslogic.c | 9 - src/serial.c | 4 +- src/sio.c | 4 +- src/tandy_eeprom.c | 4 +- 60 files changed, 1614 insertions(+), 1693 deletions(-) diff --git a/src/CPU/codegen.h b/src/CPU/codegen.h index e86919c3a..d9175d3a5 100644 --- a/src/CPU/codegen.h +++ b/src/CPU/codegen.h @@ -311,7 +311,8 @@ static __inline void addbyte(uint8_t val) static __inline void addword(uint16_t val) { - *(uint16_t *)&codeblock[block_current].data[block_pos] = val; + uint16_t *p = (uint16_t *)&codeblock[block_current].data[block_pos]; + *p = val; block_pos += 2; if (block_pos >= BLOCK_MAX) { @@ -321,7 +322,8 @@ static __inline void addword(uint16_t val) static __inline void addlong(uint32_t val) { - *(uint32_t *)&codeblock[block_current].data[block_pos] = val; + uint32_t *p = (uint32_t *)&codeblock[block_current].data[block_pos]; + *p = val; block_pos += 4; if (block_pos >= BLOCK_MAX) { @@ -331,7 +333,8 @@ static __inline void addlong(uint32_t val) static __inline void addquad(uint64_t val) { - *(uint64_t *)&codeblock[block_current].data[block_pos] = val; + uint64_t *p = (uint64_t *)&codeblock[block_current].data[block_pos]; + *p = val; block_pos += 8; if (block_pos >= BLOCK_MAX) { diff --git a/src/CPU/codegen_ops_arith.h b/src/CPU/codegen_ops_arith.h index fc67be9f1..ed2ce1ece 100644 --- a/src/CPU/codegen_ops_arith.h +++ b/src/CPU/codegen_ops_arith.h @@ -2,15 +2,15 @@ static uint32_t ropINC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); host_reg = LOAD_REG_W(opcode & 7); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); codegen_flags_changed = 1; @@ -21,15 +21,15 @@ static uint32_t ropINC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); host_reg = LOAD_REG_L(opcode & 7); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); codegen_flags_changed = 1; @@ -40,15 +40,15 @@ static uint32_t ropDEC_rw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); host_reg = LOAD_REG_W(opcode & 7); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); codegen_flags_changed = 1; @@ -59,15 +59,15 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin { int host_reg; - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); host_reg = LOAD_REG_L(opcode & 7); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); codegen_flags_changed = 1; @@ -93,12 +93,12 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin MEM_CHECK_WRITE(target_seg); \ dst_reg = MEM_LOAD_ADDR_EA_B_NO_ABRT(target_seg); \ } \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ src_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ if (writeback) \ { \ if ((fetchdat & 0xc0) == 0xc0) \ @@ -133,12 +133,12 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin MEM_CHECK_WRITE_W(target_seg); \ dst_reg = MEM_LOAD_ADDR_EA_W_NO_ABRT(target_seg); \ } \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ src_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ if (writeback) \ { \ if ((fetchdat & 0xc0) == 0xc0) \ @@ -173,12 +173,12 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin MEM_CHECK_WRITE_L(target_seg); \ dst_reg = MEM_LOAD_ADDR_EA_L_NO_ABRT(target_seg); \ } \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ src_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg); \ + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ if (writeback) \ { \ if ((fetchdat & 0xc0) == 0xc0) \ @@ -215,11 +215,11 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } \ \ dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 8); \ + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); \ op ## _HOST_REG_B(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg); \ + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); \ if (writeback) STORE_REG_B_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ RELEASE_REG(src_reg); \ @@ -244,11 +244,11 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } \ \ dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 16); \ + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); \ op ## _HOST_REG_W(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg); \ + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); \ if (writeback) STORE_REG_W_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ RELEASE_REG(src_reg); \ @@ -273,11 +273,11 @@ static uint32_t ropDEC_rl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } \ \ dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg); \ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ ## op ## 32); \ + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); \ op ## _HOST_REG_L(dst_reg, src_reg); \ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg); \ + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); \ if (writeback) STORE_REG_L_RELEASE(dst_reg); \ else RELEASE_REG(dst_reg); \ RELEASE_REG(src_reg); \ @@ -308,11 +308,11 @@ static uint32_t ropCMP_b_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u } dst_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); RELEASE_REG(dst_reg); RELEASE_REG(src_reg); @@ -336,11 +336,11 @@ static uint32_t ropCMP_w_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u } dst_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); RELEASE_REG(dst_reg); RELEASE_REG(src_reg); @@ -364,11 +364,11 @@ static uint32_t ropCMP_l_rm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u } dst_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); RELEASE_REG(dst_reg); RELEASE_REG(src_reg); @@ -392,12 +392,12 @@ static uint32_t ropCMP_b_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, dst_reg = 0; } - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); src_reg = LOAD_REG_B((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, dst_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, dst_reg); dst_reg = CMP_HOST_REG_B(dst_reg, src_reg); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, dst_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, dst_reg); RELEASE_REG(dst_reg); RELEASE_REG(src_reg); @@ -420,12 +420,12 @@ static uint32_t ropCMP_w_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, dst_reg = 0; } \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); src_reg = LOAD_REG_W((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, dst_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, dst_reg); dst_reg = CMP_HOST_REG_W(dst_reg, src_reg); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, dst_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, dst_reg); RELEASE_REG(dst_reg); RELEASE_REG(src_reg); @@ -448,12 +448,12 @@ static uint32_t ropCMP_l_rmw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, dst_reg = 0; } - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); src_reg = LOAD_REG_L((fetchdat >> 3) & 7); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, dst_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, dst_reg); dst_reg = CMP_HOST_REG_L(dst_reg, src_reg); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op2, src_reg); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, dst_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op2, src_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, dst_reg); RELEASE_REG(dst_reg); RELEASE_REG(src_reg); @@ -466,11 +466,11 @@ static uint32_t ropADD_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, { int host_reg = LOAD_REG_B(REG_AL); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD8); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); codegen_flags_changed = 1; @@ -480,11 +480,11 @@ static uint32_t ropADD_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, { int host_reg = LOAD_REG_W(REG_AX); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); codegen_flags_changed = 1; @@ -494,12 +494,12 @@ static uint32_t ropADD_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 { int host_reg = LOAD_REG_L(REG_EAX); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); fetchdat = fastreadl(cs + op_pc); ADD_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); codegen_flags_changed = 1; @@ -510,11 +510,11 @@ static uint32_t ropCMP_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, { int host_reg = LOAD_REG_B(REG_AL); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); RELEASE_REG(host_reg); codegen_flags_changed = 1; @@ -524,11 +524,11 @@ static uint32_t ropCMP_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, { int host_reg = LOAD_REG_W(REG_AX); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); RELEASE_REG(host_reg); codegen_flags_changed = 1; @@ -538,12 +538,12 @@ static uint32_t ropCMP_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 { int host_reg = LOAD_REG_L(REG_EAX); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); fetchdat = fastreadl(cs + op_pc); host_reg = CMP_HOST_REG_IMM_L(host_reg, fetchdat); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); RELEASE_REG(host_reg); codegen_flags_changed = 1; @@ -554,11 +554,11 @@ static uint32_t ropSUB_AL_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, { int host_reg = LOAD_REG_B(REG_AL); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_B(host_reg, fetchdat & 0xff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xff); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_B_RELEASE(host_reg); codegen_flags_changed = 1; @@ -568,11 +568,11 @@ static uint32_t ropSUB_AX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, { int host_reg = LOAD_REG_W(REG_AX); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat & 0xffff); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat & 0xffff); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_W_RELEASE(host_reg); codegen_flags_changed = 1; @@ -582,12 +582,12 @@ static uint32_t ropSUB_EAX_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 { int host_reg = LOAD_REG_L(REG_EAX); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); fetchdat = fastreadl(cs + op_pc); SUB_HOST_REG_IMM(host_reg, fetchdat); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, fetchdat); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, fetchdat); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); STORE_REG_L_RELEASE(host_reg); codegen_flags_changed = 1; @@ -598,7 +598,7 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ { int host_reg; uint32_t imm; - x86seg *target_seg; + x86seg *target_seg = NULL; if ((fetchdat & 0x30) == 0x10) return 0; @@ -629,38 +629,38 @@ static uint32_t rop80(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD8); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm | 0xffffff00); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); break; case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN8); break; case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_B(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB8); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB8); break; } - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0x38) != 0x38) { if ((fetchdat & 0xc0) != 0xc0) @@ -684,7 +684,7 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 { int host_reg; uint32_t imm; - x86seg *target_seg; + x86seg *target_seg = NULL; if ((fetchdat & 0x30) == 0x10) return 0; @@ -715,38 +715,38 @@ static uint32_t rop81_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); break; case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); break; case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); break; } - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0x38) != 0x38) { if ((fetchdat & 0xc0) != 0xc0) @@ -769,7 +769,7 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 { int host_reg; uint32_t imm; - x86seg *target_seg; + x86seg *target_seg = NULL; if ((fetchdat & 0x30) == 0x10) return 0; @@ -799,38 +799,38 @@ static uint32_t rop81_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); break; case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); break; case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); break; } - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0x38) != 0x38) { if ((fetchdat & 0xc0) != 0xc0) @@ -854,7 +854,7 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 { int host_reg; uint32_t imm; - x86seg *target_seg; + x86seg *target_seg = NULL; if ((fetchdat & 0x30) == 0x10) return 0; @@ -888,38 +888,38 @@ static uint32_t rop83_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD16); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm | 0xffff0000); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); break; case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN16); break; case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_W(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB16); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB16); break; } - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0x38) != 0x38) { if ((fetchdat & 0xc0) != 0xc0) @@ -942,7 +942,7 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 { int host_reg; uint32_t imm; - x86seg *target_seg; + x86seg *target_seg = NULL; if ((fetchdat & 0x30) == 0x10) return 0; @@ -976,38 +976,38 @@ static uint32_t rop83_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 switch (fetchdat & 0x38) { case 0x00: /*ADD*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ADD32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ADD32); break; case 0x08: /*OR*/ OR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); break; case 0x20: /*AND*/ AND_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); break; case 0x28: /*SUB*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); break; case 0x30: /*XOR*/ XOR_HOST_REG_IMM(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_ZN32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_ZN32); break; case 0x38: /*CMP*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); host_reg = CMP_HOST_REG_IMM_L(host_reg, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, imm); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SUB32); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, imm); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SUB32); break; } - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0x38) != 0x38) { if ((fetchdat & 0xc0) != 0xc0) diff --git a/src/CPU/codegen_ops_fpu.h b/src/CPU/codegen_ops_fpu.h index 7c414c3b5..7cc9499e5 100644 --- a/src/CPU/codegen_ops_fpu.h +++ b/src/CPU/codegen_ops_fpu.h @@ -200,30 +200,30 @@ static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t return op_pc + 1; \ } -ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) -ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) -ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) -ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) -ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) -ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S) -ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) -ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) -ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) -ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) -ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) -ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D) -ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) -ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) -ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) -ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) -ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) -ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW) -ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) -ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) -ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) -ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) -ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) -ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL) +ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); #define ropFcompare(name, size, load, op) \ static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ @@ -252,10 +252,10 @@ static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uin return new_pc; \ } -ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S) -ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D) -ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW) -ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL) +ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); +ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); +ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW); +ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL); /*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { @@ -491,7 +491,7 @@ static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u int host_reg; FP_ENTER(); - host_reg = LOAD_VAR_W((uintptr_t) &cpu_state.npxs); + host_reg = LOAD_VAR_W((uintptr_t)&cpu_state.npxs); STORE_REG_TARGET_W_RELEASE(host_reg, REG_AX); return op_pc; @@ -622,17 +622,19 @@ static uint32_t ropFCHS(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 static uint32_t ropFLD ## name(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ { \ static double fp_imm = v; \ + static uint64_t *fpp; \ \ FP_ENTER(); \ - FP_LOAD_IMM_Q(*(uint64_t *)&fp_imm); \ + fpp = (uint64_t *)&fp_imm; \ + FP_LOAD_IMM_Q(*fpp); \ \ return op_pc; \ } opFLDimm(1, 1.0) opFLDimm(L2T, 3.3219280948873623) -opFLDimm(L2E, 1.4426950408889634) -opFLDimm(PI, 3.141592653589793) -opFLDimm(EG2, 0.3010299956639812) -opFLDimm(LN2, 0.693147180559945) +opFLDimm(L2E, 1.4426950408889634); +opFLDimm(PI, 3.141592653589793); +opFLDimm(EG2, 0.3010299956639812); +opFLDimm(LN2, 0.693147180559945); opFLDimm(Z, 0.0) diff --git a/src/CPU/codegen_ops_jump.h b/src/CPU/codegen_ops_jump.h index 440f867ef..0ad293744 100644 --- a/src/CPU/codegen_ops_jump.h +++ b/src/CPU/codegen_ops_jump.h @@ -77,7 +77,7 @@ static uint32_t ropLOOP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 static void BRANCH_COND_B(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC((void *) CF_SET); + CALL_FUNC((uintptr_t)CF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else @@ -122,7 +122,7 @@ static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int no break; case FLAGS_UNKNOWN: - CALL_FUNC((void *) ZF_SET); + CALL_FUNC((uintptr_t)ZF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else @@ -133,7 +133,7 @@ static void BRANCH_COND_E(int pc_offset, uint32_t op_pc, uint32_t offset, int no static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC((void *) VF_SET); + CALL_FUNC((uintptr_t)VF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else @@ -142,7 +142,7 @@ static void BRANCH_COND_O(int pc_offset, uint32_t op_pc, uint32_t offset, int no static void BRANCH_COND_P(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC((void *) PF_SET); + CALL_FUNC((uintptr_t)PF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else @@ -204,7 +204,7 @@ static void BRANCH_COND_S(int pc_offset, uint32_t op_pc, uint32_t offset, int no break; case FLAGS_UNKNOWN: - CALL_FUNC((void *) NF_SET); + CALL_FUNC((uintptr_t)NF_SET); if (not) TEST_ZERO_JUMP_L(0, op_pc+pc_offset+offset, timing_bt); else diff --git a/src/CPU/codegen_ops_misc.h b/src/CPU/codegen_ops_misc.h index 63ee0d6bd..e5d4f59dd 100644 --- a/src/CPU/codegen_ops_misc.h +++ b/src/CPU/codegen_ops_misc.h @@ -27,13 +27,13 @@ static uint32_t ropSTI(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32 static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int host_reg; if ((fetchdat & 0x30) != 0x00) return 0; - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); if ((fetchdat & 0xc0) == 0xc0) host_reg = LOAD_REG_B(fetchdat & 7); @@ -50,18 +50,18 @@ static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ switch (fetchdat & 0x38) { case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC8); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC8); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); break; case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_B(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC8); - STORE_HOST_REG_ADDR_BL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC8); + STORE_HOST_REG_ADDR_BL((uintptr_t)&cpu_state.flags_res, host_reg); break; } @@ -79,14 +79,14 @@ static uint32_t ropFE(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ static uint32_t codegen_temp; static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int host_reg; if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) return 0; if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); if ((fetchdat & 0xc0) == 0xc0) host_reg = LOAD_REG_W(fetchdat & 7); @@ -111,11 +111,11 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint switch (fetchdat & 0x38) { case 0x00: /*INC*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0xc0) == 0xc0) STORE_REG_W_RELEASE(host_reg); else @@ -126,11 +126,11 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint codegen_flags_changed = 1; return op_pc + 1; case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM_W(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC16); - STORE_HOST_REG_ADDR_WL((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC16); + STORE_HOST_REG_ADDR_WL((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0xc0) == 0xc0) STORE_REG_W_RELEASE(host_reg); else @@ -167,21 +167,19 @@ static uint32_t ropFF_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint MEM_STORE_ADDR_EA_W(&_ss, host_reg); SP_MODIFY(-2); return op_pc + 1; - - default: - return -1; } + return 0; } static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int host_reg; if ((fetchdat & 0x30) != 0x00 && (fetchdat & 0x08)) return 0; if ((fetchdat & 0x30) == 0x00) - CALL_FUNC((void *) flags_rebuild_c); + CALL_FUNC((uintptr_t)flags_rebuild_c); if ((fetchdat & 0xc0) == 0xc0) host_reg = LOAD_REG_L(fetchdat & 7); @@ -206,11 +204,11 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint switch (fetchdat & 0x38) { case 0x00: /*INC*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); ADD_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_INC32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_INC32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0xc0) == 0xc0) STORE_REG_L_RELEASE(host_reg); else @@ -221,11 +219,11 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint codegen_flags_changed = 1; return op_pc + 1; case 0x08: /*DEC*/ - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_op1, host_reg); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_op1, host_reg); SUB_HOST_REG_IMM(host_reg, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, 1); - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_DEC32); - STORE_HOST_REG_ADDR((uint32_t)&cpu_state.flags_res, host_reg); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, 1); + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_DEC32); + STORE_HOST_REG_ADDR((uintptr_t)&cpu_state.flags_res, host_reg); if ((fetchdat & 0xc0) == 0xc0) STORE_REG_L_RELEASE(host_reg); else @@ -262,8 +260,6 @@ static uint32_t ropFF_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint MEM_STORE_ADDR_EA_L(&_ss, host_reg); SP_MODIFY(-4); return op_pc + 1; - - default: - return -1; } + return 0; } diff --git a/src/CPU/codegen_ops_mmx.h b/src/CPU/codegen_ops_mmx.h index 1c425daa2..14730cb93 100644 --- a/src/CPU/codegen_ops_mmx.h +++ b/src/CPU/codegen_ops_mmx.h @@ -154,22 +154,22 @@ MMX_OP(ropPSUBSW, MMX_SUBSW) MMX_OP(ropPSUBUSB, MMX_SUBUSB) MMX_OP(ropPSUBUSW, MMX_SUBUSW) -MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW) -MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD) -MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ) -MMX_OP(ropPACKSSWB, MMX_PACKSSWB) -MMX_OP(ropPCMPGTB, MMX_PCMPGTB) -MMX_OP(ropPCMPGTW, MMX_PCMPGTW) -MMX_OP(ropPCMPGTD, MMX_PCMPGTD) -MMX_OP(ropPACKUSWB, MMX_PACKUSWB) -MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW) -MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD) -MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ) -MMX_OP(ropPACKSSDW, MMX_PACKSSDW) +MMX_OP(ropPUNPCKLBW, MMX_PUNPCKLBW); +MMX_OP(ropPUNPCKLWD, MMX_PUNPCKLWD); +MMX_OP(ropPUNPCKLDQ, MMX_PUNPCKLDQ); +MMX_OP(ropPACKSSWB, MMX_PACKSSWB); +MMX_OP(ropPCMPGTB, MMX_PCMPGTB); +MMX_OP(ropPCMPGTW, MMX_PCMPGTW); +MMX_OP(ropPCMPGTD, MMX_PCMPGTD); +MMX_OP(ropPACKUSWB, MMX_PACKUSWB); +MMX_OP(ropPUNPCKHBW, MMX_PUNPCKHBW); +MMX_OP(ropPUNPCKHWD, MMX_PUNPCKHWD); +MMX_OP(ropPUNPCKHDQ, MMX_PUNPCKHDQ); +MMX_OP(ropPACKSSDW, MMX_PACKSSDW); -MMX_OP(ropPCMPEQB, MMX_PCMPEQB) -MMX_OP(ropPCMPEQW, MMX_PCMPEQW) -MMX_OP(ropPCMPEQD, MMX_PCMPEQD) +MMX_OP(ropPCMPEQB, MMX_PCMPEQB); +MMX_OP(ropPCMPEQW, MMX_PCMPEQW); +MMX_OP(ropPCMPEQD, MMX_PCMPEQD); MMX_OP(ropPSRLW, MMX_PSRLW) MMX_OP(ropPSRLD, MMX_PSRLD) @@ -180,9 +180,9 @@ MMX_OP(ropPSLLW, MMX_PSLLW) MMX_OP(ropPSLLD, MMX_PSLLD) MMX_OP(ropPSLLQ, MMX_PSLLQ) -MMX_OP(ropPMULLW, MMX_PMULLW) -MMX_OP(ropPMULHW, MMX_PMULHW) -MMX_OP(ropPMADDWD, MMX_PMADDWD) +MMX_OP(ropPMULLW, MMX_PMULLW); +MMX_OP(ropPMULHW, MMX_PMULHW); +MMX_OP(ropPMADDWD, MMX_PMADDWD); static uint32_t ropPSxxW_imm(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { diff --git a/src/CPU/codegen_ops_mov.h b/src/CPU/codegen_ops_mov.h index 4679c03f4..cb4498343 100644 --- a/src/CPU/codegen_ops_mov.h +++ b/src/CPU/codegen_ops_mov.h @@ -512,22 +512,22 @@ static uint32_t ropMOV_w_seg(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, switch (fetchdat & 0x38) { case 0x00: /*ES*/ - host_reg = LOAD_VAR_WL((uintptr_t) &ES); + host_reg = LOAD_VAR_WL((uintptr_t)&ES); break; case 0x08: /*CS*/ - host_reg = LOAD_VAR_WL((uintptr_t) &CS); + host_reg = LOAD_VAR_WL((uintptr_t)&CS); break; case 0x18: /*DS*/ - host_reg = LOAD_VAR_WL((uintptr_t) &DS); + host_reg = LOAD_VAR_WL((uintptr_t)&DS); break; case 0x10: /*SS*/ - host_reg = LOAD_VAR_WL((uintptr_t) &SS); + host_reg = LOAD_VAR_WL((uintptr_t)&SS); break; case 0x20: /*FS*/ - host_reg = LOAD_VAR_WL((uintptr_t) &FS); + host_reg = LOAD_VAR_WL((uintptr_t)&FS); break; case 0x28: /*GS*/ - host_reg = LOAD_VAR_WL((uintptr_t) &GS); + host_reg = LOAD_VAR_WL((uintptr_t)&GS); break; default: return 0; diff --git a/src/CPU/codegen_ops_shift.h b/src/CPU/codegen_ops_shift.h index 937a82ee8..b67c34544 100644 --- a/src/CPU/codegen_ops_shift.h +++ b/src/CPU/codegen_ops_shift.h @@ -13,29 +13,29 @@ reg = MEM_LOAD_ADDR_EA_ ## size ## _NO_ABRT(target_seg); \ if (immediate) count = fastreadb(cs + op_pc + 1) & 0x1f; \ } \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op2, count); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op2, count); \ \ - res_store((uint32_t)&cpu_state.flags_op1, reg); \ + res_store((uintptr_t)&cpu_state.flags_op1, reg); \ \ switch (fetchdat & 0x38) \ { \ case 0x20: case 0x30: /*SHL*/ \ SHL_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHL ## size2); \ break; \ \ case 0x28: /*SHR*/ \ SHR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SHR ## size2); \ break; \ \ case 0x38: /*SAR*/ \ SAR_ ## size ## _IMM(reg, count); \ - STORE_IMM_ADDR_L((uint32_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \ + STORE_IMM_ADDR_L((uintptr_t)&cpu_state.flags_op, FLAGS_SAR ## size2); \ break; \ } \ \ - res_store((uint32_t)&cpu_state.flags_res, reg); \ + res_store((uintptr_t)&cpu_state.flags_res, reg); \ if ((fetchdat & 0xc0) == 0xc0) \ STORE_REG_ ## size ## _RELEASE(reg); \ else \ @@ -46,7 +46,7 @@ static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int count; int reg; @@ -59,7 +59,7 @@ static uint32_t ropC0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ } static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int count; int reg; @@ -72,7 +72,7 @@ static uint32_t ropC1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 } static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int count; int reg; @@ -86,7 +86,7 @@ static uint32_t ropC1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int count = 1; int reg; @@ -99,7 +99,7 @@ static uint32_t ropD0(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_ } static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int count = 1; int reg; @@ -112,7 +112,7 @@ static uint32_t ropD1_w(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 } static uint32_t ropD1_l(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - x86seg *target_seg; + x86seg *target_seg = NULL; int count = 1; int reg; diff --git a/src/CPU/codegen_ops_stack.h b/src/CPU/codegen_ops_stack.h index 9aadbaa4e..96b900273 100644 --- a/src/CPU/codegen_ops_stack.h +++ b/src/CPU/codegen_ops_stack.h @@ -85,8 +85,6 @@ static uint32_t ropPUSH_imm_b32(uint8_t opcode, uint32_t fetchdat, uint32_t op_3 static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - /* int host_reg; */ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); MEM_LOAD_ADDR_EA_W(&_ss); @@ -97,8 +95,6 @@ static uint32_t ropPOP_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - /* int host_reg; */ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); MEM_LOAD_ADDR_EA_L(&_ss); @@ -110,8 +106,6 @@ static uint32_t ropPOP_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - /* int host_reg; */ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); MEM_LOAD_ADDR_EA_W(&_ss); @@ -122,8 +116,6 @@ static uint32_t ropRET_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin } static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { - /* int host_reg; */ - STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); MEM_LOAD_ADDR_EA_L(&_ss); @@ -136,7 +128,6 @@ static uint32_t ropRET_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { uint16_t offset = fetchdat & 0xffff; - /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); @@ -149,7 +140,6 @@ static uint32_t ropRET_imm_16(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, static uint32_t ropRET_imm_32(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { uint16_t offset = fetchdat & 0xffff; - /* int host_reg; */ STORE_IMM_ADDR_L((uintptr_t)&cpu_state.oldpc, op_old_pc); LOAD_STACK_TO_EA(0); diff --git a/src/CPU/codegen_ops_x86-64.h b/src/CPU/codegen_ops_x86-64.h index 4805be498..f6ec2f055 100644 --- a/src/CPU/codegen_ops_x86-64.h +++ b/src/CPU/codegen_ops_x86-64.h @@ -1,6 +1,7 @@ /*Register allocation : R8-R15 - emulated registers */ +#include #define HOST_REG_XMM_START 0 #define HOST_REG_XMM_END 7 @@ -20,7 +21,7 @@ static inline int find_host_xmm_reg() fatal("Out of host XMM regs!\n"); return c; } -static void call(codeblock_t *block, uintptr_t func) +static inline void call(codeblock_t *block, uintptr_t func) { uintptr_t diff = func - (uintptr_t)&block->data[block_pos + 5]; @@ -42,7 +43,7 @@ static void call(codeblock_t *block, uintptr_t func) } } -static void call_long(uintptr_t func) +static inline void call_long(uintptr_t func) { codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; @@ -54,7 +55,7 @@ static void call_long(uintptr_t func) addbyte(0xd0); } -static void load_param_1_32(codeblock_t *block, uint32_t param) +static inline void load_param_1_32(codeblock_t *block, uint32_t param) { #if WIN64 addbyte(0xb9); /*MOVL $fetchdat,%ecx*/ @@ -63,7 +64,7 @@ static void load_param_1_32(codeblock_t *block, uint32_t param) #endif addlong(param); } -static void load_param_1_reg_32(int reg) +static inline void load_param_1_reg_32(int reg) { #if WIN64 if (reg & 8) @@ -77,7 +78,8 @@ static void load_param_1_reg_32(int reg) addbyte(0xc0 | REG_EDI | (reg << 3)); #endif } -static void load_param_1_64(codeblock_t *block, uint64_t param) +#if 0 +static inline void load_param_1_64(codeblock_t *block, uint64_t param) { addbyte(0x48); #if WIN64 @@ -87,8 +89,9 @@ static void load_param_1_64(codeblock_t *block, uint64_t param) #endif addquad(param); } +#endif -static void load_param_2_32(codeblock_t *block, uint32_t param) +static inline void load_param_2_32(codeblock_t *block, uint32_t param) { #if WIN64 addbyte(0xba); /*MOVL $fetchdat,%edx*/ @@ -97,7 +100,7 @@ static void load_param_2_32(codeblock_t *block, uint32_t param) #endif addlong(param); } -static void load_param_2_reg_32(int reg) +static inline void load_param_2_reg_32(int reg) { #if WIN64 if (reg & 8) @@ -111,7 +114,7 @@ static void load_param_2_reg_32(int reg) addbyte(0xc0 | REG_ESI | (reg << 3)); #endif } -static void load_param_2_64(codeblock_t *block, uint64_t param) +static inline void load_param_2_64(codeblock_t *block, uint64_t param) { addbyte(0x48); #if WIN64 @@ -122,7 +125,7 @@ static void load_param_2_64(codeblock_t *block, uint64_t param) addquad(param); } -static void load_param_3_reg_32(int reg) +static inline void load_param_3_reg_32(int reg) { if (reg & 8) { @@ -149,7 +152,7 @@ static void load_param_3_reg_32(int reg) #endif } } -static void load_param_3_reg_64(int reg) +static inline void load_param_3_reg_64(int reg) { if (reg & 8) { @@ -177,7 +180,7 @@ static void load_param_3_reg_64(int reg) } } -static void CALL_FUNC(uintptr_t func) +static inline void CALL_FUNC(uintptr_t func) { codegen_reg_loaded[0] = codegen_reg_loaded[1] = codegen_reg_loaded[2] = codegen_reg_loaded[3] = 0; codegen_reg_loaded[4] = codegen_reg_loaded[5] = codegen_reg_loaded[6] = codegen_reg_loaded[7] = 0; @@ -189,14 +192,13 @@ static void CALL_FUNC(uintptr_t func) addbyte(0xd0); } -static void RELEASE_REG(int host_reg) +static inline void RELEASE_REG(int host_reg) { } -static int LOAD_REG_B(int reg) +static inline int LOAD_REG_B(int reg) { int host_reg = reg & 3; -// host_reg_mapping[host_reg] = reg; if (!codegen_reg_loaded[reg & 3]) { @@ -213,10 +215,9 @@ static int LOAD_REG_B(int reg) return host_reg | 8; } -static int LOAD_REG_W(int reg) +static inline int LOAD_REG_W(int reg) { int host_reg = reg; -// host_reg_mapping[host_reg] = reg; if (!codegen_reg_loaded[reg & 7]) { @@ -230,10 +231,9 @@ static int LOAD_REG_W(int reg) return host_reg | 8; } -static int LOAD_REG_L(int reg) +static inline int LOAD_REG_L(int reg) { int host_reg = reg; -// host_reg_mapping[host_reg] = reg; if (!codegen_reg_loaded[reg & 7]) { @@ -248,7 +248,7 @@ static int LOAD_REG_L(int reg) return host_reg | 8; } -static int LOAD_REG_IMM(uint32_t imm) +static inline int LOAD_REG_IMM(uint32_t imm) { int host_reg = REG_EBX; @@ -258,7 +258,7 @@ static int LOAD_REG_IMM(uint32_t imm) return host_reg; } -static void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) +static inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) { int dest_reg = LOAD_REG_L(guest_reg & 3) & 7; @@ -359,7 +359,7 @@ static void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) } } } -static void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) +static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) { int dest_reg = LOAD_REG_L(guest_reg & 7) & 7; @@ -387,7 +387,7 @@ static void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) addbyte(cpu_state_offset(regs[guest_reg & 7].w)); } } -static void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) +static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) { if (host_reg & 8) { @@ -410,7 +410,7 @@ static void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) } } -static void STORE_REG_B_RELEASE(int host_reg) +static inline void STORE_REG_B_RELEASE(int host_reg) { if (host_reg & 0x10) { @@ -428,7 +428,7 @@ static void STORE_REG_B_RELEASE(int host_reg) addbyte(cpu_state_offset(regs[host_reg & 7].b)); } } -static void STORE_REG_W_RELEASE(int host_reg) +static inline void STORE_REG_W_RELEASE(int host_reg) { addbyte(0x66); /*MOVW [reg],host_reg*/ addbyte(0x44); @@ -436,7 +436,7 @@ static void STORE_REG_W_RELEASE(int host_reg) addbyte(0x45 | ((host_reg & 7) << 3)); addbyte(cpu_state_offset(regs[host_reg & 7].w)); } -static void STORE_REG_L_RELEASE(int host_reg) +static inline void STORE_REG_L_RELEASE(int host_reg) { addbyte(0x44); /*MOVL [reg],host_reg*/ addbyte(0x89); @@ -444,7 +444,7 @@ static void STORE_REG_L_RELEASE(int host_reg) addbyte(cpu_state_offset(regs[host_reg & 7].l)); } -static void STORE_IMM_REG_B(int reg, uint8_t val) +static inline void STORE_IMM_REG_B(int reg, uint8_t val) { if (reg & 4) { @@ -476,7 +476,7 @@ static void STORE_IMM_REG_B(int reg, uint8_t val) addbyte(cpu_state_offset(regs[reg & 7].b)); } } -static void STORE_IMM_REG_W(int reg, uint16_t val) +static inline void STORE_IMM_REG_W(int reg, uint16_t val) { addbyte(0x66); /*MOVW reg, imm*/ addbyte(0x41); @@ -488,7 +488,7 @@ static void STORE_IMM_REG_W(int reg, uint16_t val) addbyte(0x45 | (reg << 3)); addbyte(cpu_state_offset(regs[reg & 7].w)); } -static void STORE_IMM_REG_L(int reg, uint32_t val) +static inline void STORE_IMM_REG_L(int reg, uint32_t val) { addbyte(0x41); /*MOVL reg, imm*/ addbyte(0xb8 | reg); @@ -499,7 +499,7 @@ static void STORE_IMM_REG_L(int reg, uint32_t val) addbyte(cpu_state_offset(regs[reg & 7].l)); } -static void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) +static inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) { if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) { @@ -533,7 +533,6 @@ static void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { int mod = (fetchdat >> 6) & 3; - int reg = (fetchdat >> 3) & 7; int rm = fetchdat & 7; if (!mod && rm == 6) @@ -655,7 +654,6 @@ static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { int mod = (fetchdat >> 6) & 3; - int reg = (fetchdat >> 3) & 7; int rm = fetchdat & 7; uint32_t new_eaaddr; @@ -847,7 +845,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u return op_ea_seg; } -static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) { if (op_32 & 0x200) return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); @@ -856,7 +854,7 @@ static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint -static void CHECK_SEG_READ(x86seg *seg) +static inline void CHECK_SEG_READ(x86seg *seg) { /*Segments always valid in real/V86 mode*/ if (!(cr0 & 1) || (eflags & VM_FLAG)) @@ -874,7 +872,7 @@ static void CHECK_SEG_READ(x86seg *seg) addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x3c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); addbyte(-1); } else @@ -892,7 +890,7 @@ static void CHECK_SEG_READ(x86seg *seg) seg->checked = 1; } -static void CHECK_SEG_WRITE(x86seg *seg) +static inline void CHECK_SEG_WRITE(x86seg *seg) { /*Segments always valid in real/V86 mode*/ if (!(cr0 & 1) || (eflags & VM_FLAG)) @@ -910,7 +908,7 @@ static void CHECK_SEG_WRITE(x86seg *seg) addbyte(0x83); /*CMP seg->base, -1*/ addbyte(0x3c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); addbyte(-1); } else @@ -928,7 +926,7 @@ static void CHECK_SEG_WRITE(x86seg *seg) seg->checked = 1; } -static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) +static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) return; @@ -936,7 +934,7 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) if (IS_32_ADDR(&seg->base)) { addbyte(0xb8 | REG_ESI); /*MOV ESI, &addr*/ - addlong((uint32_t)seg); + addlong((uint32_t)(uintptr_t)seg); } else { @@ -967,7 +965,7 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) } } -static void MEM_LOAD_ADDR_EA_B(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -979,7 +977,7 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1005,7 +1003,7 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -1030,17 +1028,17 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemb386l); + call_long((uintptr_t)readmemb386l); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } -static void MEM_LOAD_ADDR_EA_W(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -1052,7 +1050,7 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1081,7 +1079,7 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -1109,24 +1107,24 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemwl); + call_long((uintptr_t)readmemwl); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } -static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { addbyte(0x83); /*ADD EAX, offset*/ addbyte(0xc0); addbyte(offset); MEM_LOAD_ADDR_EA_W(seg); } -static void MEM_LOAD_ADDR_EA_L(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -1138,7 +1136,7 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1167,7 +1165,7 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -1194,17 +1192,17 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemll); + call_long((uintptr_t)readmemll); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } -static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -1216,7 +1214,7 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1245,7 +1243,7 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -1273,10 +1271,10 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemql); + call_long((uintptr_t)readmemql); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); @@ -1284,26 +1282,26 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) /*done:*/ } -static void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +static inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_LOAD_ADDR_EA_B(seg); } -static void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) +static inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_LOAD_ADDR_EA_W(seg); } -static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) +static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_LOAD_ADDR_EA_L(seg); } -static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { if (host_reg & 0x10) { @@ -1337,7 +1335,7 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1363,7 +1361,7 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -1399,17 +1397,17 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); load_param_3_reg_32(host_reg); - call_long(writememb386l); + call_long((uintptr_t)writememb386l); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } -static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -1421,7 +1419,7 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1450,7 +1448,7 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -1490,17 +1488,17 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); load_param_3_reg_32(host_reg); - call_long(writememwl); + call_long((uintptr_t)writememwl); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } -static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -1512,7 +1510,7 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1541,7 +1539,7 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -1579,17 +1577,17 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); load_param_3_reg_32(host_reg); - call_long(writememll); + call_long((uintptr_t)writememll); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } -static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -1601,7 +1599,7 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -1630,7 +1628,7 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -1669,10 +1667,10 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); load_param_3_reg_64(host_reg); - call_long(writememql); + call_long((uintptr_t)writememql); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); @@ -1680,26 +1678,26 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) /*done:*/ } -static void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) +static inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_STORE_ADDR_EA_B(seg, host_reg); } -static void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +static inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_STORE_ADDR_EA_W(seg, host_reg); } -static void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +static inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_STORE_ADDR_EA_L(seg, host_reg); } -static void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) +static inline void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) { int temp_reg = REG_ECX; @@ -1729,7 +1727,7 @@ static void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) { addbyte(0x89); /*MOV addr, temp_reg*/ addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); + addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); } else if (IS_32_ADDR(addr)) { @@ -1747,7 +1745,7 @@ static void STORE_HOST_REG_ADDR_BL(uintptr_t addr, int host_reg) addbyte(0x06 | (temp_reg << 3)); } } -static void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) +static inline void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) { int temp_reg = REG_ECX; @@ -1763,7 +1761,7 @@ static void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) { addbyte(0x89); /*MOV addr, temp_reg*/ addbyte(0x45 | (temp_reg << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); + addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); } else if (IS_32_ADDR(addr)) { @@ -1781,7 +1779,7 @@ static void STORE_HOST_REG_ADDR_WL(uintptr_t addr, int host_reg) addbyte(0x06 | (temp_reg << 3)); } } -static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +static inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) { if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) { @@ -1790,7 +1788,7 @@ static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) addbyte(0x44); addbyte(0x89); addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); + addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); } else if (IS_32_ADDR(addr)) { @@ -1815,7 +1813,7 @@ static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) addbyte(0x06 | ((host_reg & 7) << 3)); } } -static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) +static inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) { if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) { @@ -1823,7 +1821,7 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) addbyte(0x44); addbyte(0x89); /*MOVL [addr],host_reg*/ addbyte(0x45 | ((host_reg & 7) << 3)); - addbyte((uint32_t)addr - (uint32_t)&cpu_state - 128); + addbyte((uint32_t)addr - (uint32_t)(uintptr_t)&cpu_state - 128); } else if (IS_32_ADDR(addr)) { @@ -1847,7 +1845,7 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) } } -static void AND_HOST_REG_B(int dst_reg, int src_reg) +static inline void AND_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -1970,7 +1968,7 @@ static void AND_HOST_REG_B(int dst_reg, int src_reg) } } } -static void AND_HOST_REG_W(int dst_reg, int src_reg) +static inline void AND_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2000,7 +1998,7 @@ static void AND_HOST_REG_W(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void AND_HOST_REG_L(int dst_reg, int src_reg) +static inline void AND_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2026,7 +2024,7 @@ static void AND_HOST_REG_L(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void AND_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) { if (host_reg & 0x10) { @@ -2047,7 +2045,7 @@ static void AND_HOST_REG_IMM(int host_reg, uint32_t imm) } } -static int TEST_HOST_REG_B(int dst_reg, int src_reg) +static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & 8) { @@ -2062,7 +2060,7 @@ static int TEST_HOST_REG_B(int dst_reg, int src_reg) return dst_reg & ~0x10; } -static int TEST_HOST_REG_W(int dst_reg, int src_reg) +static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & 8) { @@ -2077,7 +2075,7 @@ static int TEST_HOST_REG_W(int dst_reg, int src_reg) return dst_reg; } -static int TEST_HOST_REG_L(int dst_reg, int src_reg) +static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & 8) { @@ -2092,7 +2090,7 @@ static int TEST_HOST_REG_L(int dst_reg, int src_reg) return dst_reg; } -static int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) { if (host_reg & 8) { @@ -2118,7 +2116,7 @@ static int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) return host_reg; } -static void OR_HOST_REG_B(int dst_reg, int src_reg) +static inline void OR_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2240,7 +2238,7 @@ static void OR_HOST_REG_B(int dst_reg, int src_reg) } } } -static void OR_HOST_REG_W(int dst_reg, int src_reg) +static inline void OR_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2270,7 +2268,7 @@ static void OR_HOST_REG_W(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void OR_HOST_REG_L(int dst_reg, int src_reg) +static inline void OR_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2296,7 +2294,7 @@ static void OR_HOST_REG_L(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void OR_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) { if (host_reg & 0x10) { @@ -2319,10 +2317,9 @@ static void OR_HOST_REG_IMM(int host_reg, uint32_t imm) addbyte(0xc8 | (host_reg & 7)); addlong(imm); } -// fatal("OR to bad register\n"); } -static void XOR_HOST_REG_B(int dst_reg, int src_reg) +static inline void XOR_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2444,7 +2441,7 @@ static void XOR_HOST_REG_B(int dst_reg, int src_reg) } } } -static void XOR_HOST_REG_W(int dst_reg, int src_reg) +static inline void XOR_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2474,7 +2471,7 @@ static void XOR_HOST_REG_W(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void XOR_HOST_REG_L(int dst_reg, int src_reg) +static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2500,7 +2497,7 @@ static void XOR_HOST_REG_L(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) { if (host_reg & 0x10) { @@ -2523,10 +2520,9 @@ static void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) addbyte(0xf0 | (host_reg & 7)); addlong(imm); } -// fatal("XOR to bad register\n"); } -static void ADD_HOST_REG_B(int dst_reg, int src_reg) +static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2620,7 +2616,7 @@ static void ADD_HOST_REG_B(int dst_reg, int src_reg) else fatal("!(dst_reg & src_reg & 8)\n"); } -static void ADD_HOST_REG_W(int dst_reg, int src_reg) +static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2646,7 +2642,7 @@ static void ADD_HOST_REG_W(int dst_reg, int src_reg) else fatal("!(dst_reg & src_reg & 8)\n"); } -static void ADD_HOST_REG_L(int dst_reg, int src_reg) +static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2670,7 +2666,7 @@ static void ADD_HOST_REG_L(int dst_reg, int src_reg) fatal("!(dst_reg & src_reg & 8)\n"); } -static void SUB_HOST_REG_B(int dst_reg, int src_reg) +static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2791,10 +2787,8 @@ static void SUB_HOST_REG_B(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } - -// fatal("!(dst_reg & src_reg & 8) subb %i %i\n", dst_reg, src_reg); } -static void SUB_HOST_REG_W(int dst_reg, int src_reg) +static inline void SUB_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2824,7 +2818,7 @@ static void SUB_HOST_REG_W(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg & 7) | ((src_reg & 7) << 3)); } } -static void SUB_HOST_REG_L(int dst_reg, int src_reg) +static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & src_reg & 8) { @@ -2851,7 +2845,7 @@ static void SUB_HOST_REG_L(int dst_reg, int src_reg) } } -static int CMP_HOST_REG_B(int dst_reg, int src_reg) +static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) { if (dst_reg & 8) { @@ -2866,7 +2860,7 @@ static int CMP_HOST_REG_B(int dst_reg, int src_reg) return dst_reg & ~0x10; } -static int CMP_HOST_REG_W(int dst_reg, int src_reg) +static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) { if (dst_reg & 8) { @@ -2881,7 +2875,7 @@ static int CMP_HOST_REG_W(int dst_reg, int src_reg) return dst_reg; } -static int CMP_HOST_REG_L(int dst_reg, int src_reg) +static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) { if (dst_reg & 8) { @@ -2897,7 +2891,7 @@ static int CMP_HOST_REG_L(int dst_reg, int src_reg) return dst_reg; } -static void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) { if (host_reg & 0x10) { @@ -2917,7 +2911,7 @@ static void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) addbyte(imm); } } -static void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) { addbyte(0x66); /*ADDW host_reg, imm*/ if (host_reg & 8) @@ -2926,7 +2920,7 @@ static void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) addbyte(0xC0 | (host_reg & 7)); addword(imm); } -static void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) { if (host_reg & 8) addbyte(0x41); @@ -2935,7 +2929,7 @@ static void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) addlong(imm); } -static void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) { if (host_reg & 0x10) { @@ -2955,7 +2949,7 @@ static void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) addbyte(imm); } } -static void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) { addbyte(0x66); /*SUBW host_reg, imm*/ if (host_reg & 8) @@ -2964,7 +2958,7 @@ static void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) addbyte(0xE8 | (host_reg & 7)); addword(imm); } -static void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) { if (host_reg & 8) addbyte(0x41); @@ -2973,7 +2967,7 @@ static void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) addlong(imm); } -static int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { if (host_reg & 8) { @@ -2986,9 +2980,9 @@ static int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) SUB_HOST_REG_IMM_B(host_reg, imm); - return host_reg;// & ~0x10; + return host_reg; } -static int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) { if (host_reg & 8) { @@ -3003,7 +2997,7 @@ static int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) return host_reg; } -static int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) +static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) { if (host_reg & 8) { @@ -3019,13 +3013,13 @@ static int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) return host_reg; } -static void LOAD_STACK_TO_EA(int off) +static inline void LOAD_STACK_TO_EA(int off) { if (stack32) { addbyte(0x8b); /*MOVL EAX,[ESP]*/ addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_ESP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); if (off) { addbyte(0x83); /*ADD EAX, off*/ @@ -3038,7 +3032,7 @@ static void LOAD_STACK_TO_EA(int off) addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ addbyte(0xb7); addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_ESP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); if (off) { addbyte(0x66); /*ADD AX, off*/ @@ -3047,13 +3041,13 @@ static void LOAD_STACK_TO_EA(int off) } } } -static void LOAD_EBP_TO_EA(int off) +static inline void LOAD_EBP_TO_EA(int off) { if (stack32) { addbyte(0x8b); /*MOVL EAX,[EBP]*/ addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_EBP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); if (off) { addbyte(0x83); /*ADD EAX, off*/ @@ -3066,7 +3060,7 @@ static void LOAD_EBP_TO_EA(int off) addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ addbyte(0xb7); addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_BP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_BP].l)); if (off) { addbyte(0x66); /*ADD AX, off*/ @@ -3076,7 +3070,7 @@ static void LOAD_EBP_TO_EA(int off) } } -static void SP_MODIFY(int off) +static inline void SP_MODIFY(int off) { if (stack32) { @@ -3084,14 +3078,14 @@ static void SP_MODIFY(int off) { addbyte(0x83); /*ADD [ESP], off*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); addbyte(off); } else { addbyte(0x81); /*ADD [ESP], off*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); addlong(off); } } @@ -3102,7 +3096,7 @@ static void SP_MODIFY(int off) addbyte(0x66); /*ADD [SP], off*/ addbyte(0x83); addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); addbyte(off); } else @@ -3110,13 +3104,13 @@ static void SP_MODIFY(int off) addbyte(0x66); /*ADD [SP], off*/ addbyte(0x81); addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); addword(off); } } } -static void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { addbyte(0x66); /*CMPW host_reg, 0*/ if (host_reg & 8) @@ -3128,19 +3122,19 @@ static void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) { if (host_reg & 8) addbyte(0x41); @@ -3151,20 +3145,20 @@ static void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { addbyte(0x66); /*CMPW host_reg, 0*/ if (host_reg & 8) @@ -3176,19 +3170,19 @@ static void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) { if (host_reg & 8) addbyte(0x41); @@ -3199,20 +3193,20 @@ static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { uint8_t *jump1; @@ -3220,20 +3214,20 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no { addbyte(0x83); /*CMP flags_res, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(flags_res)); + addbyte((uint8_t)cpu_state_offset(flags_res)); addbyte(0); addbyte(0x74); /*JZ +*/ } else { - CALL_FUNC(ZF_SET); + CALL_FUNC((uintptr_t)ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x75); /*JNZ +*/ } jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - CALL_FUNC(CF_SET); + CALL_FUNC((uintptr_t)CF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); if (not) @@ -3246,13 +3240,13 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc+pc_offset+offset); if (timing_bt) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(timing_bt); } addbyte(0xe9); /*JMP end*/ @@ -3261,15 +3255,15 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; } -static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { - CALL_FUNC(NF_SET); + CALL_FUNC((uintptr_t)NF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE BL*/ addbyte(0x95); addbyte(0xc3); - CALL_FUNC(VF_SET); + CALL_FUNC((uintptr_t)VF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE AL*/ @@ -3284,46 +3278,46 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not addbyte(7+5+(timing_bt ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc+pc_offset+offset); if (timing_bt) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(timing_bt); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { uint8_t *jump1; if (codegen_flags_changed && cpu_state.flags_op != FLAGS_UNKNOWN) { addbyte(0x83); /*CMP flags_res, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(flags_res)); + addbyte((uint8_t)cpu_state_offset(flags_res)); addbyte(0); addbyte(0x74); /*JZ +*/ } else { - CALL_FUNC(ZF_SET); + CALL_FUNC((uintptr_t)ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x75); /*JNZ +*/ } jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); - CALL_FUNC(NF_SET); + CALL_FUNC((uintptr_t)NF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE BL*/ addbyte(0x95); addbyte(0xc3); - CALL_FUNC(VF_SET); + CALL_FUNC((uintptr_t)VF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE AL*/ @@ -3340,13 +3334,13 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc+pc_offset+offset); if (timing_bt) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(timing_bt); } addbyte(0xe9); /*JMP end*/ @@ -3355,7 +3349,7 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; } -static int LOAD_VAR_W(uintptr_t addr) +static inline int LOAD_VAR_W(uintptr_t addr) { int host_reg = REG_EBX; @@ -3386,11 +3380,11 @@ static int LOAD_VAR_W(uintptr_t addr) return host_reg; } -static int LOAD_VAR_WL(uintptr_t addr) +static inline int LOAD_VAR_WL(uintptr_t addr) { return LOAD_VAR_W(addr); } -static int LOAD_VAR_L(uintptr_t addr) +static inline int LOAD_VAR_L(uintptr_t addr) { int host_reg = REG_EBX; @@ -3419,7 +3413,7 @@ static int LOAD_VAR_L(uintptr_t addr) return host_reg; } -static int COPY_REG(int src_reg) +static inline int COPY_REG(int src_reg) { if (src_reg & 8) addbyte(0x44); @@ -3429,7 +3423,7 @@ static int COPY_REG(int src_reg) return REG_ECX | (src_reg & 0x10); } -static int LOAD_HOST_REG(int host_reg) +static inline int LOAD_HOST_REG(int host_reg) { if (host_reg & 8) addbyte(0x44); @@ -3439,7 +3433,7 @@ static int LOAD_HOST_REG(int host_reg) return REG_EBX | (host_reg & 0x10); } -static int ZERO_EXTEND_W_B(int reg) +static inline int ZERO_EXTEND_W_B(int reg) { if (reg & 0x10) { @@ -3461,7 +3455,7 @@ static int ZERO_EXTEND_W_B(int reg) return REG_EAX; } -static int ZERO_EXTEND_L_B(int reg) +static inline int ZERO_EXTEND_L_B(int reg) { if (reg & 0x10) { @@ -3483,7 +3477,7 @@ static int ZERO_EXTEND_L_B(int reg) return REG_EAX; } -static int ZERO_EXTEND_L_W(int reg) +static inline int ZERO_EXTEND_L_W(int reg) { if (reg & 8) addbyte(0x41); @@ -3494,7 +3488,7 @@ static int ZERO_EXTEND_L_W(int reg) return REG_EAX; } -static int SIGN_EXTEND_W_B(int reg) +static inline int SIGN_EXTEND_W_B(int reg) { if (reg & 0x10) { @@ -3516,7 +3510,7 @@ static int SIGN_EXTEND_W_B(int reg) return REG_EAX; } -static int SIGN_EXTEND_L_B(int reg) +static inline int SIGN_EXTEND_L_B(int reg) { if (reg & 0x10) { @@ -3538,7 +3532,7 @@ static int SIGN_EXTEND_L_B(int reg) return REG_EAX; } -static int SIGN_EXTEND_L_W(int reg) +static inline int SIGN_EXTEND_L_W(int reg) { if (reg & 8) addbyte(0x41); @@ -3549,7 +3543,7 @@ static int SIGN_EXTEND_L_W(int reg) return REG_EAX; } -static void SHL_B_IMM(int reg, int count) +static inline void SHL_B_IMM(int reg, int count) { if (reg & 0x10) { @@ -3572,7 +3566,7 @@ static void SHL_B_IMM(int reg, int count) addbyte(count); } } -static void SHL_W_IMM(int reg, int count) +static inline void SHL_W_IMM(int reg, int count) { addbyte(0x66); /*SHL reg, count*/ if (reg & 8) @@ -3581,7 +3575,7 @@ static void SHL_W_IMM(int reg, int count) addbyte(0xc0 | (reg & 7) | 0x20); addbyte(count); } -static void SHL_L_IMM(int reg, int count) +static inline void SHL_L_IMM(int reg, int count) { if (reg & 8) addbyte(0x41); @@ -3589,7 +3583,7 @@ static void SHL_L_IMM(int reg, int count) addbyte(0xc0 | (reg & 7) | 0x20); addbyte(count); } -static void SHR_B_IMM(int reg, int count) +static inline void SHR_B_IMM(int reg, int count) { if (reg & 0x10) { @@ -3612,7 +3606,7 @@ static void SHR_B_IMM(int reg, int count) addbyte(count); } } -static void SHR_W_IMM(int reg, int count) +static inline void SHR_W_IMM(int reg, int count) { addbyte(0x66); /*SHR reg, count*/ if (reg & 8) @@ -3621,7 +3615,7 @@ static void SHR_W_IMM(int reg, int count) addbyte(0xc0 | (reg & 7) | 0x28); addbyte(count); } -static void SHR_L_IMM(int reg, int count) +static inline void SHR_L_IMM(int reg, int count) { if (reg & 8) addbyte(0x41); @@ -3629,7 +3623,7 @@ static void SHR_L_IMM(int reg, int count) addbyte(0xc0 | (reg & 7) | 0x28); addbyte(count); } -static void SAR_B_IMM(int reg, int count) +static inline void SAR_B_IMM(int reg, int count) { if (reg & 0x10) { @@ -3652,7 +3646,7 @@ static void SAR_B_IMM(int reg, int count) addbyte(count); } } -static void SAR_W_IMM(int reg, int count) +static inline void SAR_W_IMM(int reg, int count) { addbyte(0x66); /*SAR reg, count*/ if (reg & 8) @@ -3661,7 +3655,7 @@ static void SAR_W_IMM(int reg, int count) addbyte(0xc0 | (reg & 7) | 0x38); addbyte(count); } -static void SAR_L_IMM(int reg, int count) +static inline void SAR_L_IMM(int reg, int count) { if (reg & 8) addbyte(0x41); @@ -3670,7 +3664,7 @@ static void SAR_L_IMM(int reg, int count) addbyte(count); } -static void NEG_HOST_REG_B(int reg) +static inline void NEG_HOST_REG_B(int reg) { if (reg & 0x10) { @@ -3693,7 +3687,7 @@ static void NEG_HOST_REG_B(int reg) addbyte(0xd8 | (reg & 7)); } } -static void NEG_HOST_REG_W(int reg) +static inline void NEG_HOST_REG_W(int reg) { addbyte(0x66); if (reg & 8) @@ -3701,7 +3695,7 @@ static void NEG_HOST_REG_W(int reg) addbyte(0xf7); addbyte(0xd8 | (reg & 7)); } -static void NEG_HOST_REG_L(int reg) +static inline void NEG_HOST_REG_L(int reg) { if (reg & 8) addbyte(0x41); @@ -3710,7 +3704,7 @@ static void NEG_HOST_REG_L(int reg) } -static void FP_ENTER() +static inline void FP_ENTER() { if (codegen_fpu_entered) return; @@ -3726,7 +3720,7 @@ static void FP_ENTER() { addbyte(0x48); /*MOV RAX, &cr0*/ addbyte(0xb8 | REG_EAX); - addquad(&cr0); + addquad((uint64_t)&cr0); addbyte(0xf6); /*TEST [RAX], 0xc*/ addbyte(0 | (REG_EAX << 3)); addbyte(0x0c); @@ -3735,21 +3729,21 @@ static void FP_ENTER() addbyte(7+5+12+5); addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(oldpc)); + addbyte((uint8_t)cpu_state_offset(oldpc)); addlong(op_old_pc); load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC(x86_int); + CALL_FUNC((uintptr_t)x86_int); addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); codegen_fpu_entered = 1; } -static void FP_FXCH(int reg) +static inline void FP_FXCH(int reg) { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x83); /*ADD EAX, reg*/ @@ -3760,7 +3754,7 @@ static void FP_FXCH(int reg) addbyte(0x8b); addbyte(0x54); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x83); /*AND EAX, 7*/ addbyte(0xe0); addbyte(0x07); @@ -3768,65 +3762,65 @@ static void FP_FXCH(int reg) addbyte(0x8b); addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x48); /*MOV ST[RAX*8], RDX*/ addbyte(0x89); addbyte(0x54); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x48); /*MOV ST[RBX*8], RCX*/ addbyte(0x89); addbyte(0x4c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV CL, tag[EAX]*/ addbyte(0x4c); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(0x8a); /*MOV DL, tag[EBX]*/ addbyte(0x54); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(0x88); /*MOV tag[EBX], CL*/ addbyte(0x4c); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(0x88); /*MOV tag[EAX], DL*/ addbyte(0x54); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(0x48); /*MOV RDX, MM[RBX*8]*/ addbyte(0x8b); addbyte(0x54); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x48); /*MOV RCX, MM[RAX*8]*/ addbyte(0x8b); addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x48); /*MOV MM[RAX*8], RDX*/ addbyte(0x89); addbyte(0x54); addbyte(0xc5); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x48); /*MOV MM[RBX*8], RCX*/ addbyte(0x89); addbyte(0x4c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); reg = reg; } -static void FP_FLD(int reg) +static inline void FP_FLD(int reg) { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); if (reg) @@ -3852,7 +3846,7 @@ static void FP_FLD(int reg) addbyte(0x8b); addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x83); /*AND EBX, 7*/ addbyte(0xe3); addbyte(0x07); @@ -3860,45 +3854,45 @@ static void FP_FLD(int reg) addbyte(0x8b); addbyte(0x54); addbyte(0xc5); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x8a); /*MOV AL, [tag+EAX]*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(0x48); /*MOV ST[EBX*8], RCX*/ addbyte(0x89); addbyte(0x4c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x48); /*MOV ST_i64[EBX*8], RDX*/ addbyte(0x89); addbyte(0x54); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x88); /*MOV [tag+EBX], AL*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(0x89); /*MOV [TOP], EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } -static void FP_FST(int reg) +static inline void FP_FST(int reg) { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x48); /*MOV RCX, ST[EAX*8]*/ addbyte(0x8b); addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV BL, [tag+EAX]*/ addbyte(0x5c); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); if (reg) { @@ -3914,22 +3908,22 @@ static void FP_FST(int reg) addbyte(0x89); addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x88); /*MOV [tag+EAX], BL*/ addbyte(0x5c); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); } -static void FP_POP() +static inline void FP_POP() { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xc6); /*MOVB tag[EAX], 3*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(3); addbyte(0x83); /*ADD AL, 1*/ addbyte(0xc0); @@ -3939,17 +3933,17 @@ static void FP_POP() addbyte(7); addbyte(0x89); /*MOV [TOP], EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } -static void FP_POP2() +static inline void FP_POP2() { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xc6); /*MOVB tag[EAX], 3*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(3); addbyte(0x83); /*ADD AL, 2*/ addbyte(0xc0); @@ -3959,14 +3953,14 @@ static void FP_POP2() addbyte(7); addbyte(0x89); /*MOV [TOP], EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } -static void FP_LOAD_S() +static inline void FP_LOAD_S() { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x66); /*MOVD XMM0, EAX*/ addbyte(0x0f); addbyte(0x6e); @@ -3985,24 +3979,24 @@ static void FP_LOAD_S() addbyte(0xc0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); } -static void FP_LOAD_D() +static inline void FP_LOAD_D() { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x83); /*SUB EBX, 1*/ addbyte(0xeb); addbyte(0x01); @@ -4014,24 +4008,24 @@ static void FP_LOAD_D() addbyte(0xc0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x48); /*MOVQ [ST+EBX*8], RAX*/ addbyte(0x89); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); } -static void FP_LOAD_IW() +static inline void FP_LOAD_IW() { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x0f); /*MOVSX EAX, AX*/ addbyte(0xbf); addbyte(0xc0); @@ -4049,24 +4043,24 @@ static void FP_LOAD_IW() addbyte(0xc0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); } -static void FP_LOAD_IL() +static inline void FP_LOAD_IL() { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x83); /*SUB EBX, 1*/ addbyte(0xeb); addbyte(0x01); @@ -4081,24 +4075,24 @@ static void FP_LOAD_IL() addbyte(0xc0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x66); /*MOVQ [ST+EBX*8], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); } -static void FP_LOAD_IQ() +static inline void FP_LOAD_IQ() { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x83); /*SUB EBX, 1*/ addbyte(0xeb); addbyte(0x01); @@ -4117,10 +4111,10 @@ static void FP_LOAD_IQ() addbyte(0x89); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x0f); /*SETE AL*/ addbyte(0x94); addbyte(0xc0); @@ -4129,20 +4123,20 @@ static void FP_LOAD_IQ() addbyte(0xd6); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0c); /*OR AL, TAG_UINT64*/ addbyte(TAG_UINT64); addbyte(0x88); /*MOV [tag+EBX], AL*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); } -static void FP_LOAD_IMM_Q(uint64_t v) +static inline void FP_LOAD_IMM_Q(uint64_t v) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x83); /*SUB EBX, 1*/ addbyte(0xeb); addbyte(0x01); @@ -4152,28 +4146,28 @@ static void FP_LOAD_IMM_Q(uint64_t v) addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addlong(v & 0xffffffff); addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST) + 4); + addbyte((uint8_t)cpu_state_offset(ST) + 4); addlong(v >> 32); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xc6); /*MOV [tag+EBX], (v ? 0 : 1)*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(v ? 0 : 1); } -static void FP_FCHS() +static inline void FP_FCHS() { addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xf2); /*SUBSD XMM0, XMM0*/ addbyte(0x0f); addbyte(0x5c); @@ -4183,25 +4177,25 @@ static void FP_FCHS() addbyte(0x5c); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xf2); /*MOVSD ST[EAX*8], XMM0*/ addbyte(0x0f); addbyte(0x11); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } -static int FP_LOAD_REG(int reg) +static inline int FP_LOAD_REG(int reg) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -4216,7 +4210,7 @@ static int FP_LOAD_REG(int reg) addbyte(0x7e); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xf2); /*CVTSD2SS XMM0, XMM0*/ addbyte(0x0f); addbyte(0x5a); @@ -4228,11 +4222,11 @@ static int FP_LOAD_REG(int reg) return REG_EBX; } -static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -4246,11 +4240,11 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) addbyte(0x8b); addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); *host_reg1 = REG_EBX; } -static int64_t x87_fround(double b) +static inline int64_t x87_fround(double b) { int64_t a, c; @@ -4272,15 +4266,17 @@ static int64_t x87_fround(double b) case 3: /*Chop*/ return (int64_t)b; } + + return 0; } -static int FP_LOAD_REG_INT_W(int reg) +static inline int FP_LOAD_REG_INT_W(int reg) { addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EAX, reg*/ @@ -4295,22 +4291,22 @@ static int FP_LOAD_REG_INT_W(int reg) addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); - CALL_FUNC(x87_fround); + CALL_FUNC((uintptr_t)x87_fround); addbyte(0x93); /*XCHG EBX, EAX*/ return REG_EBX; } -static int FP_LOAD_REG_INT(int reg) +static inline int FP_LOAD_REG_INT(int reg) { addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EAX, reg*/ @@ -4325,22 +4321,22 @@ static int FP_LOAD_REG_INT(int reg) addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); - CALL_FUNC(x87_fround); + CALL_FUNC((uintptr_t)x87_fround); addbyte(0x93); /*XCHG EBX, EAX*/ return REG_EBX; } -static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) { addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EAX, reg*/ @@ -4360,7 +4356,7 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0x8b); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x48); /*XCHG RBX, RAX*/ addbyte(0x93); @@ -4373,7 +4369,7 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0xf6); /*TEST TAG[EAX], TAG_UINT64*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(TAG_UINT64); addbyte(0x74); /*JZ +*/ @@ -4383,7 +4379,7 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0x8b); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0xeb); /*JMP done*/ addbyte(6+12); @@ -4393,9 +4389,9 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); - CALL_FUNC(x87_fround); + CALL_FUNC((uintptr_t)x87_fround); addbyte(0x48); /*XCHG RBX, RAX*/ addbyte(0x93); @@ -4410,11 +4406,11 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) #define FPU_SUB 2 #define FPU_SUBR 3 -static void FP_OP_REG(int op, int dst, int src) +static inline void FP_OP_REG(int op, int dst, int src) { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); if (dst) @@ -4438,7 +4434,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(~TAG_UINT64); if (op == FPU_DIVR || op == FPU_SUBR) { @@ -4447,7 +4443,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x7e); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } else { @@ -4456,7 +4452,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } switch (op) { @@ -4466,7 +4462,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x58); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); break; case FPU_DIV: addbyte(0xf2); /*DIVSD XMM0, ST[RBX*8]*/ @@ -4474,7 +4470,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x5e); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); break; case FPU_DIVR: addbyte(0xf2); /*DIVSD XMM0, ST[RAX*8]*/ @@ -4482,7 +4478,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x5e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); break; case FPU_MUL: addbyte(0xf2); /*MULSD XMM0, ST[RBX*8]*/ @@ -4490,7 +4486,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x59); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); break; case FPU_SUB: addbyte(0xf2); /*SUBSD XMM0, ST[RBX*8]*/ @@ -4498,7 +4494,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x5c); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); break; case FPU_SUBR: addbyte(0xf2); /*SUBSD XMM0, ST[RAX*8]*/ @@ -4506,7 +4502,7 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0x5c); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); break; } addbyte(0x66); /*MOVQ [RSI+RAX*8], XMM0*/ @@ -4514,24 +4510,24 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0xd6); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } -static void FP_OP_MEM(int op) +static inline void FP_OP_MEM(int op) { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x05); - addbyte(cpu_state_offset(tag)); + addbyte((uint8_t)cpu_state_offset(tag)); addbyte(~TAG_UINT64); switch (op) @@ -4580,7 +4576,7 @@ static void FP_OP_MEM(int op) addbyte(0xd6); addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } else { @@ -4589,11 +4585,11 @@ static void FP_OP_MEM(int op) addbyte(0xd6); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } -static void FP_OP_S(int op) +static inline void FP_OP_S(int op) { addbyte(0x66); /*MOVD XMM1, EAX*/ addbyte(0x0f); @@ -4605,7 +4601,7 @@ static void FP_OP_S(int op) addbyte(0xc9); FP_OP_MEM(op); } -static void FP_OP_D(int op) +static inline void FP_OP_D(int op) { addbyte(0x66); /*MOVQ XMM1, RAX*/ addbyte(0x48); @@ -4647,7 +4643,7 @@ static void FP_OP_D(int op) addbyte(0x08); } } -static void FP_OP_IW(int op) +static inline void FP_OP_IW(int op) { addbyte(0x0f); /*MOVSX EAX, AX*/ addbyte(0xbf); @@ -4658,7 +4654,7 @@ static void FP_OP_IW(int op) addbyte(0xc8); FP_OP_MEM(op); } -static void FP_OP_IL(int op) +static inline void FP_OP_IL(int op) { addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ addbyte(0x0f); @@ -4672,11 +4668,11 @@ static void FP_OP_IL(int op) #define C2 (1<<10) #define C3 (1<<14) -static void FP_COMPARE_REG(int dst, int src) +static inline void FP_COMPARE_REG(int dst, int src) { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); if (src || dst) @@ -4691,9 +4687,7 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0x8a); /*MOV CL, [npxs+1]*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); -// addbyte(0xdb); /*FCLEX*/ -// addbyte(0xe2); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); addbyte((~(C0|C2|C3)) >> 8); @@ -4705,13 +4699,13 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0x7e); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x66); /*COMISD XMM0, ST[RAX*8]*/ addbyte(0x0f); addbyte(0x2f); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } else { @@ -4720,13 +4714,13 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x66); /*COMISD XMM0, ST[RBX*8]*/ addbyte(0x0f); addbyte(0x2f); addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } addbyte(0x9f); /*LAHF*/ @@ -4737,26 +4731,24 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } -static void FP_COMPARE_MEM() +static inline void FP_COMPARE_MEM() { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x8a); /*MOV CL, [npxs+1]*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); -// addbyte(0xdb); /*FCLEX*/ -// addbyte(0xe2); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xf3); /*MOVQ XMM0, ST[RAX*8]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); addbyte((~(C0|C2|C3)) >> 8); @@ -4772,9 +4764,9 @@ static void FP_COMPARE_MEM() addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } -static void FP_COMPARE_S() +static inline void FP_COMPARE_S() { addbyte(0x66); /*MOVD XMM1, EAX*/ addbyte(0x0f); @@ -4786,7 +4778,7 @@ static void FP_COMPARE_S() addbyte(0xc9); FP_COMPARE_MEM(); } -static void FP_COMPARE_D() +static inline void FP_COMPARE_D() { addbyte(0x66); /*MOVQ XMM1, RAX*/ addbyte(0x48); @@ -4795,7 +4787,7 @@ static void FP_COMPARE_D() addbyte(0xc8); FP_COMPARE_MEM(); } -static void FP_COMPARE_IW() +static inline void FP_COMPARE_IW() { addbyte(0x0f); /*MOVSX EAX, AX*/ addbyte(0xbf); @@ -4806,7 +4798,7 @@ static void FP_COMPARE_IW() addbyte(0xc8); FP_COMPARE_MEM(); } -static void FP_COMPARE_IL() +static inline void FP_COMPARE_IL() { addbyte(0xf2); /*CVTSI2SD XMM1, EAX*/ addbyte(0x0f); @@ -4815,11 +4807,11 @@ static void FP_COMPARE_IL() FP_COMPARE_MEM(); } -static void UPDATE_NPXC(int reg) +static inline void UPDATE_NPXC(int reg) { } -static void SET_BITS(uintptr_t addr, uint32_t val) +static inline void SET_BITS(uintptr_t addr, uint32_t val) { if (IS_32_ADDR(addr)) { @@ -4860,7 +4852,7 @@ static void SET_BITS(uintptr_t addr, uint32_t val) } } -static void CLEAR_BITS(uintptr_t addr, uint32_t val) +static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) { if (IS_32_ADDR(addr)) { @@ -4904,7 +4896,7 @@ static void CLEAR_BITS(uintptr_t addr, uint32_t val) #define LOAD_Q_REG_1 REG_EAX #define LOAD_Q_REG_2 REG_EDX -static void MMX_ENTER() +static inline void MMX_ENTER() { if (codegen_mmx_entered) return; @@ -4921,7 +4913,7 @@ static void MMX_ENTER() { addbyte(0x48); /*MOV RAX, &cr0*/ addbyte(0xb8 | REG_EAX); - addquad(&cr0); + addquad((uint64_t)&cr0); addbyte(0xf6); /*TEST [RAX], 0xc*/ addbyte(0 | (REG_EAX << 3)); addbyte(0x0c); @@ -4930,10 +4922,10 @@ static void MMX_ENTER() addbyte(7+5+12+5); addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(oldpc)); + addbyte((uint8_t)cpu_state_offset(oldpc)); addlong(op_old_pc); load_param_1_32(&codeblock[block_current], 7); - CALL_FUNC(x86_int); + CALL_FUNC((uintptr_t)x86_int); addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); @@ -4942,35 +4934,35 @@ static void MMX_ENTER() addbyte(0xc0); addbyte(0xc6); /*MOV ISMMX, 1*/ addbyte(0x45); - addbyte(cpu_state_offset(ismmx)); + addbyte((uint8_t)cpu_state_offset(ismmx)); addbyte(1); addbyte(0x89); /*MOV TOP, EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV tag, EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0x89); /*MOV tag+4, EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[4])); + addbyte((uint8_t)cpu_state_offset(tag[4])); codegen_mmx_entered = 1; } extern int mmx_ebx_ecx_loaded; -static int LOAD_MMX_D(int guest_reg) +static inline int LOAD_MMX_D(int guest_reg) { int host_reg = REG_EBX; addbyte(0x8b); /*MOV EBX, reg*/ addbyte(0x44 | (host_reg << 3)); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); return host_reg; } -static void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) { int host_reg = REG_EBX; @@ -4981,11 +4973,11 @@ static void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) addbyte(0x8b); /*MOV RBX, reg*/ addbyte(0x44 | ((host_reg & 7) << 3)); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].q)); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); *host_reg1 = host_reg; } -static int LOAD_MMX_Q_MMX(int guest_reg) +static inline int LOAD_MMX_Q_MMX(int guest_reg) { int dst_reg = find_host_xmm_reg(); host_reg_xmm_mapping[dst_reg] = 100; @@ -4995,12 +4987,12 @@ static int LOAD_MMX_Q_MMX(int guest_reg) addbyte(0x7e); addbyte(0x44 | ((dst_reg & 7) << 3)); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].q)); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); return dst_reg; } -static int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +static inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) { int dst_reg = find_host_xmm_reg(); host_reg_xmm_mapping[dst_reg] = 100; @@ -5017,21 +5009,21 @@ static int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) return dst_reg; } -static void STORE_MMX_LQ(int guest_reg, int host_reg1) +static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) { addbyte(0xC7); /*MOVL [reg],0*/ addbyte(0x44); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].l[1])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); addlong(0); if (host_reg1 & 8) addbyte(0x44); addbyte(0x89); /*MOVL [reg],host_reg*/ addbyte(0x44 | ((host_reg1 & 7) << 3)); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); } -static void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) { if (host_reg1 & 8) addbyte(0x4c); @@ -5040,20 +5032,20 @@ static void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) addbyte(0x89); /*MOV [reg],host_reg*/ addbyte(0x44 | ((host_reg1 & 7) << 3)); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); } -static void STORE_MMX_Q_MMX(int guest_reg, int host_reg) +static inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) { addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x44 | (host_reg << 3)); addbyte(0x25); - addbyte(cpu_state_offset(MM[guest_reg].q)); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); } #define MMX_x86_OP(name, opcode) \ -static void MMX_ ## name(int dst_reg, int src_reg) \ +static inline void MMX_ ## name(int dst_reg, int src_reg) \ { \ addbyte(0x66); /*op dst_reg, src_reg*/ \ addbyte(0x0f); \ @@ -5106,7 +5098,7 @@ MMX_x86_OP(PMULLW, 0xd5); MMX_x86_OP(PMULHW, 0xe5); MMX_x86_OP(PMADDWD, 0xf5); -static void MMX_PACKSSWB(int dst_reg, int src_reg) +static inline void MMX_PACKSSWB(int dst_reg, int src_reg) { addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ addbyte(0x0f); @@ -5118,7 +5110,7 @@ static void MMX_PACKSSWB(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x08); } -static void MMX_PACKUSWB(int dst_reg, int src_reg) +static inline void MMX_PACKUSWB(int dst_reg, int src_reg) { addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ addbyte(0x0f); @@ -5130,7 +5122,7 @@ static void MMX_PACKUSWB(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x08); } -static void MMX_PACKSSDW(int dst_reg, int src_reg) +static inline void MMX_PACKSSDW(int dst_reg, int src_reg) { addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ addbyte(0x0f); @@ -5142,7 +5134,7 @@ static void MMX_PACKSSDW(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x08); } -static void MMX_PUNPCKHBW(int dst_reg, int src_reg) +static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) { addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ addbyte(0x0f); @@ -5154,7 +5146,7 @@ static void MMX_PUNPCKHBW(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x0e); } -static void MMX_PUNPCKHWD(int dst_reg, int src_reg) +static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) { addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ addbyte(0x0f); @@ -5166,7 +5158,7 @@ static void MMX_PUNPCKHWD(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x0e); } -static void MMX_PUNPCKHDQ(int dst_reg, int src_reg) +static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) { addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ addbyte(0x0f); @@ -5179,7 +5171,7 @@ static void MMX_PUNPCKHDQ(int dst_reg, int src_reg) addbyte(0x0e); } -static void MMX_PSRLW_imm(int dst_reg, int amount) +static inline void MMX_PSRLW_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRLW dst_reg, amount*/ addbyte(0x0f); @@ -5187,7 +5179,7 @@ static void MMX_PSRLW_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x10); addbyte(amount); } -static void MMX_PSRAW_imm(int dst_reg, int amount) +static inline void MMX_PSRAW_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRAW dst_reg, amount*/ addbyte(0x0f); @@ -5195,7 +5187,7 @@ static void MMX_PSRAW_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x20); addbyte(amount); } -static void MMX_PSLLW_imm(int dst_reg, int amount) +static inline void MMX_PSLLW_imm(int dst_reg, int amount) { addbyte(0x66); /*PSLLW dst_reg, amount*/ addbyte(0x0f); @@ -5204,7 +5196,7 @@ static void MMX_PSLLW_imm(int dst_reg, int amount) addbyte(amount); } -static void MMX_PSRLD_imm(int dst_reg, int amount) +static inline void MMX_PSRLD_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRLD dst_reg, amount*/ addbyte(0x0f); @@ -5212,7 +5204,7 @@ static void MMX_PSRLD_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x10); addbyte(amount); } -static void MMX_PSRAD_imm(int dst_reg, int amount) +static inline void MMX_PSRAD_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRAD dst_reg, amount*/ addbyte(0x0f); @@ -5220,7 +5212,7 @@ static void MMX_PSRAD_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x20); addbyte(amount); } -static void MMX_PSLLD_imm(int dst_reg, int amount) +static inline void MMX_PSLLD_imm(int dst_reg, int amount) { addbyte(0x66); /*PSLLD dst_reg, amount*/ addbyte(0x0f); @@ -5229,7 +5221,7 @@ static void MMX_PSLLD_imm(int dst_reg, int amount) addbyte(amount); } -static void MMX_PSRLQ_imm(int dst_reg, int amount) +static inline void MMX_PSRLQ_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRLQ dst_reg, amount*/ addbyte(0x0f); @@ -5237,7 +5229,7 @@ static void MMX_PSRLQ_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x10); addbyte(amount); } -static void MMX_PSRAQ_imm(int dst_reg, int amount) +static inline void MMX_PSRAQ_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRAQ dst_reg, amount*/ addbyte(0x0f); @@ -5245,7 +5237,7 @@ static void MMX_PSRAQ_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x20); addbyte(amount); } -static void MMX_PSLLQ_imm(int dst_reg, int amount) +static inline void MMX_PSLLQ_imm(int dst_reg, int amount) { addbyte(0x66); /*PSLLQ dst_reg, amount*/ addbyte(0x0f); @@ -5255,14 +5247,14 @@ static void MMX_PSLLQ_imm(int dst_reg, int amount) } -static void SAVE_EA() +static inline void SAVE_EA() { addbyte(0x89); /*MOV [ESP+0x24], EAX*/ addbyte(0x44); addbyte(0x24); addbyte(0x24); } -static void LOAD_EA() +static inline void LOAD_EA() { addbyte(0x8b); /*MOV EAX, [ESP+0x24]*/ addbyte(0x44); @@ -5272,9 +5264,9 @@ static void LOAD_EA() #define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static void MEM_CHECK_WRITE(x86seg *seg) +static inline void MEM_CHECK_WRITE(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3; + uint8_t *jump1, *jump2, *jump3 = NULL; CHECK_SEG_WRITE(seg); @@ -5288,7 +5280,7 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5307,7 +5299,7 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0x83); /*CMP cr0, 0*/ addbyte(0x3c); addbyte(0x25); - addlong((uint32_t)&cr0); + addlong((uint32_t)(uintptr_t)&cr0); addbyte(0); } else @@ -5326,7 +5318,6 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0x79); /*JNS +*/ jump1 = &codeblock[block_current].data[block_pos]; addbyte(0); -// addbyte(0xc3); /*RET*/ addbyte(0xc1); /*SHR EDI, 12*/ addbyte(0xef); addbyte(12); @@ -5344,7 +5335,7 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ addbyte(0x3c); addbyte(0xfd); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } else @@ -5360,7 +5351,6 @@ static void MEM_CHECK_WRITE(x86seg *seg) addbyte(0x75); /*JNE +*/ jump2 = &codeblock[block_current].data[block_pos]; addbyte(0); -// addbyte(0xc3); /*RET*/ if (!(seg == &_ds && codegen_flat_ds) && !(seg == &_ss && codegen_flat_ss)) *jump3 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump3 - 1; @@ -5374,41 +5364,28 @@ static void MEM_CHECK_WRITE(x86seg *seg) load_param_1_reg_32(REG_EDI); load_param_2_32(&codeblock[block_current], 1); - -// addbyte(0x6a); /*PUSH 1*/ -// addbyte(1); -// addbyte(0x57); /*PUSH EDI*/ - call(&codeblock[block_current], mmutranslatereal); -// addbyte(0x48); /*ADD ESP, 8*/ -// addbyte(0x83); -// addbyte(0xc4); -// addbyte(8); + call(&codeblock[block_current], (uintptr_t)mmutranslatereal); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); -// addbyte(0xc3); /*RET*/ + addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); *jump1 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump1 - 1; *jump2 = (uintptr_t)&codeblock[block_current].data[block_pos] - (uintptr_t)jump2 - 1; - - -// addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ -// addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); } -static void MEM_CHECK_WRITE_W(x86seg *seg) +static inline void MEM_CHECK_WRITE_W(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3, *jump4; + uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; int jump_pos; CHECK_SEG_WRITE(seg); - if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR ESI, ESI*/ addbyte(0xf6); @@ -5418,7 +5395,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5437,7 +5414,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x83); /*CMP cr0, 0*/ addbyte(0x3c); addbyte(0x25); - addlong((uint32_t)&cr0); + addlong((uint32_t)(uintptr_t)&cr0); addbyte(0); } else @@ -5484,7 +5461,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ addbyte(0x3c); addbyte(0xfd); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } else @@ -5505,7 +5482,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ addbyte(0x3c); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } else @@ -5526,17 +5503,17 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], mmutranslatereal); + call(&codeblock[block_current], (uintptr_t)mmutranslatereal); addbyte(0x83); /*ADD EBX, 1*/ addbyte(0xc3); addbyte(1); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ addbyte(0xf7); /*TEST $fff, EBX*/ addbyte(0xc3); @@ -5550,9 +5527,9 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) LOAD_EA(); } -static void MEM_CHECK_WRITE_L(x86seg *seg) +static inline void MEM_CHECK_WRITE_L(x86seg *seg) { - uint8_t *jump1, *jump2, *jump3, *jump4; + uint8_t *jump1, *jump2, *jump3, *jump4 = NULL; int jump_pos; CHECK_SEG_WRITE(seg); @@ -5567,7 +5544,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x8b); /*MOV ESI, seg->base*/ addbyte(0x34); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5586,7 +5563,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x83); /*CMP cr0, 0*/ addbyte(0x3c); addbyte(0x25); - addlong((uint32_t)&cr0); + addlong((uint32_t)(uintptr_t)&cr0); addbyte(0); } else @@ -5633,7 +5610,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x83); /*CMP writelookup2[RDI*8],-1*/ addbyte(0x3c); addbyte(0xfd); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } else @@ -5654,7 +5631,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) addbyte(0x83); /*CMP writelookup2[RSI*8],-1*/ addbyte(0x3c); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); addbyte(-1); } else @@ -5675,17 +5652,17 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) jump_pos = block_pos; load_param_1_reg_32(REG_EBX); load_param_2_32(&codeblock[block_current], 1); - call(&codeblock[block_current], mmutranslatereal); + call(&codeblock[block_current], (uintptr_t)mmutranslatereal); addbyte(0x83); /*ADD EBX, 3*/ addbyte(0xc3); addbyte(3); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); - addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uint32_t)(&codeblock[block_current].data[block_pos]) + 4)); + addlong((uintptr_t)&codeblock[block_current].data[BLOCK_EXIT_OFFSET] - ((uintptr_t)(&codeblock[block_current].data[block_pos]) + 4)); /*If bits 0-11 of the address are now 0 then this crosses a page, so loop back*/ addbyte(0xf7); /*TEST $ffc, EBX*/ addbyte(0xc3); @@ -5699,7 +5676,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) LOAD_EA(); } -static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) +static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -5711,7 +5688,7 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5737,7 +5714,7 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -5762,7 +5739,7 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemb386l); + call_long((uintptr_t)readmemb386l); addbyte(0x89); /*MOV ECX, EAX*/ addbyte(0xc1); /*done:*/ @@ -5771,7 +5748,7 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) return REG_ECX; } -static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) +static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -5783,7 +5760,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5812,7 +5789,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -5824,7 +5801,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x75); /*JE slowpath*/ + addbyte(0x75); /*JNE slowpath*/ addbyte(3+2+4+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); @@ -5840,7 +5817,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemwl); + call_long((uintptr_t)readmemwl); addbyte(0x89); /*MOV ECX, EAX*/ addbyte(0xc1); /*done:*/ @@ -5849,7 +5826,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) return REG_ECX; } -static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) +static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -5861,7 +5838,7 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x8b); /*MOVL ECX, seg->base*/ addbyte(0x0c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5890,7 +5867,7 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)readlookup2); + addlong((uint32_t)(uintptr_t)readlookup2); } else { @@ -5902,14 +5879,14 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) addbyte(0x34); addbyte(0xf2); } - addbyte(0x54); /*JNE slowpath*/ + addbyte(0x75); /*JNE slowpath*/ addbyte(3+2+3+2); addbyte(0x83); /*CMP ESI, -1*/ addbyte(0xf8 | REG_ESI); addbyte(-1); addbyte(0x74); /*JE slowpath*/ addbyte(3+2); - addbyte(0x8b); /*MOV EAX,-3[RDI+RSI]*/ + addbyte(0x8b); /*MOV EAX,[RDI+RSI]*/ addbyte(0x04); addbyte(REG_EDI | (REG_ESI << 3)); addbyte(0xeb); /*JMP done*/ @@ -5917,7 +5894,7 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) /*slowpath:*/ load_param_1_reg_32(REG_ECX); load_param_2_reg_32(REG_EAX); - call_long(readmemll); + call_long((uintptr_t)readmemll); addbyte(0x89); /*MOV ECX, EAX*/ addbyte(0xc1); /*done:*/ @@ -5927,7 +5904,7 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) return REG_ECX; } -static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { if (host_reg & 0x10) { @@ -5951,8 +5928,7 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(8); host_reg = 8; } - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -5962,7 +5938,7 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -5988,7 +5964,7 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -6024,13 +6000,12 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) load_param_3_reg_32(host_reg); load_param_1_reg_32(REG_EBX); load_param_2_reg_32(REG_EAX); - call_long(writememb386l); + call_long((uintptr_t)writememb386l); /*done:*/ } -static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -6040,7 +6015,7 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -6069,7 +6044,7 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -6109,13 +6084,12 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) load_param_3_reg_32(host_reg); load_param_1_reg_32(REG_EBX); load_param_2_reg_32(REG_EAX); - call_long(writememwl); + call_long((uintptr_t)writememwl); /*done:*/ } -static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EBX, EBX*/ addbyte(0xdb); @@ -6125,7 +6099,7 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8b); /*MOVL EBX, seg->base*/ addbyte(0x1c); addbyte(0x25); - addlong((uint32_t)&seg->base); + addlong((uint32_t)(uintptr_t)&seg->base); } else { @@ -6154,7 +6128,7 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0x8b); addbyte(0x34); addbyte(0xf5); - addlong((uint32_t)writelookup2); + addlong((uint32_t)(uintptr_t)writelookup2); } else { @@ -6192,18 +6166,18 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) load_param_3_reg_32(host_reg); load_param_1_reg_32(REG_EBX); load_param_2_reg_32(REG_EAX); - call_long(writememll); + call_long((uintptr_t)writememll); /*done:*/ } -static void LOAD_SEG(int host_reg, void *seg) +static inline void LOAD_SEG(int host_reg, void *seg) { load_param_2_64(&codeblock[block_current], (uint64_t)seg); load_param_1_reg_32(host_reg); - CALL_FUNC(loadseg); + CALL_FUNC((uintptr_t)loadseg); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); diff --git a/src/CPU/codegen_ops_x86.h b/src/CPU/codegen_ops_x86.h index 5251884b7..3af481791 100644 --- a/src/CPU/codegen_ops_x86.h +++ b/src/CPU/codegen_ops_x86.h @@ -8,7 +8,7 @@ #define HOST_REG_END 4 #define HOST_REG_XMM_START 0 #define HOST_REG_XMM_END 7 -static __inline int find_host_reg() +static inline int find_host_reg() { int c; for (c = HOST_REG_START; c < HOST_REG_END; c++) @@ -21,7 +21,7 @@ static __inline int find_host_reg() fatal("Out of host regs!\n"); return c; } -static __inline int find_host_xmm_reg() +static inline int find_host_xmm_reg() { int c; for (c = HOST_REG_XMM_START; c < HOST_REG_XMM_END; c++) @@ -35,14 +35,15 @@ static __inline int find_host_xmm_reg() return c; } -static void STORE_IMM_ADDR_B(uintptr_t addr, uint8_t val) +#if 0 +static inline void STORE_IMM_ADDR_B(uintptr_t addr, uint8_t val) { addbyte(0xC6); /*MOVB [addr],val*/ addbyte(0x05); addlong(addr); addbyte(val); } -static void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) +static inline void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) { addbyte(0x66); /*MOVW [addr],val*/ addbyte(0xC7); @@ -50,7 +51,8 @@ static void STORE_IMM_ADDR_W(uintptr_t addr, uint16_t val) addlong(addr); addword(val); } -static void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) +#endif +static inline void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) { if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) { @@ -68,33 +70,33 @@ static void STORE_IMM_ADDR_L(uintptr_t addr, uint32_t val) } } -static void STORE_IMM_REG_B(int reg, uint8_t val) +static inline void STORE_IMM_REG_B(int reg, uint8_t val) { addbyte(0xC6); /*MOVB [addr],val*/ addbyte(0x45); if (reg & 4) - addbyte(cpu_state_offset(regs[reg & 3].b.h)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); else - addbyte(cpu_state_offset(regs[reg & 3].b.l)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); addbyte(val); } -static void STORE_IMM_REG_W(int reg, uint16_t val) +static inline void STORE_IMM_REG_W(int reg, uint16_t val) { addbyte(0x66); /*MOVW [addr],val*/ addbyte(0xC7); addbyte(0x45); - addbyte(cpu_state_offset(regs[reg & 7].w)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); addword(val); } -static void STORE_IMM_REG_L(int reg, uint32_t val) +static inline void STORE_IMM_REG_L(int reg, uint32_t val) { addbyte(0xC7); /*MOVL [addr],val*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[reg & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); addlong(val); } -static int LOAD_REG_B(int reg) +static inline int LOAD_REG_B(int reg) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = reg; @@ -103,13 +105,13 @@ static int LOAD_REG_B(int reg) addbyte(0xb6); addbyte(0x45 | (host_reg << 3)); if (reg & 4) - addbyte(cpu_state_offset(regs[reg & 3].b.h)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.h)); else - addbyte(cpu_state_offset(regs[reg & 3].b.l)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 3].b.l)); return host_reg; } -static int LOAD_REG_W(int reg) +static inline int LOAD_REG_W(int reg) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = reg; @@ -117,23 +119,23 @@ static int LOAD_REG_W(int reg) addbyte(0x0f); /*MOVZX W[reg],host_reg*/ addbyte(0xb7); addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].w)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 7].w)); return host_reg; } -static int LOAD_REG_L(int reg) +static inline int LOAD_REG_L(int reg) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = reg; addbyte(0x8b); /*MOVL host_reg,[reg]*/ addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[reg & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[reg & 7].l)); return host_reg; } -static int LOAD_VAR_W(uintptr_t addr) +static inline int LOAD_VAR_W(uintptr_t addr) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = 0; @@ -145,7 +147,7 @@ static int LOAD_VAR_W(uintptr_t addr) return host_reg; } -static int LOAD_VAR_WL(uintptr_t addr) +static inline int LOAD_VAR_WL(uintptr_t addr) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = 0; @@ -157,7 +159,7 @@ static int LOAD_VAR_WL(uintptr_t addr) return host_reg; } -static int LOAD_VAR_L(uintptr_t addr) +static inline int LOAD_VAR_L(uintptr_t addr) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = 0; @@ -169,7 +171,7 @@ static int LOAD_VAR_L(uintptr_t addr) return host_reg; } -static int LOAD_REG_IMM(uint32_t imm) +static inline int LOAD_REG_IMM(uint32_t imm) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = 0; @@ -181,7 +183,7 @@ static int LOAD_REG_IMM(uint32_t imm) return host_reg; } -static int LOAD_HOST_REG(int host_reg) +static inline int LOAD_HOST_REG(int host_reg) { int new_host_reg = find_host_reg(); host_reg_mapping[new_host_reg] = 0; @@ -192,64 +194,64 @@ static int LOAD_HOST_REG(int host_reg) return new_host_reg; } -static void STORE_REG_B_RELEASE(int host_reg) +static inline void STORE_REG_B_RELEASE(int host_reg) { addbyte(0x88); /*MOVB [reg],host_reg*/ addbyte(0x45 | (host_reg << 3)); if (host_reg_mapping[host_reg] & 4) - addbyte(cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); + addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.h)); else - addbyte(cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); + addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg] & 3].b.l)); host_reg_mapping[host_reg] = -1; } -static void STORE_REG_W_RELEASE(int host_reg) +static inline void STORE_REG_W_RELEASE(int host_reg) { addbyte(0x66); /*MOVW [reg],host_reg*/ addbyte(0x89); addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); + addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].w)); host_reg_mapping[host_reg] = -1; } -static void STORE_REG_L_RELEASE(int host_reg) +static inline void STORE_REG_L_RELEASE(int host_reg) { addbyte(0x89); /*MOVL [reg],host_reg*/ addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); + addbyte((uint8_t)cpu_state_offset(regs[host_reg_mapping[host_reg]].l)); host_reg_mapping[host_reg] = -1; } -static void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) +static inline void STORE_REG_TARGET_B_RELEASE(int host_reg, int guest_reg) { addbyte(0x88); /*MOVB [guest_reg],host_reg*/ addbyte(0x45 | (host_reg << 3)); if (guest_reg & 4) - addbyte(cpu_state_offset(regs[guest_reg & 3].b.h)); + addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.h)); else - addbyte(cpu_state_offset(regs[guest_reg & 3].b.l)); + addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 3].b.l)); host_reg_mapping[host_reg] = -1; } -static void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) +static inline void STORE_REG_TARGET_W_RELEASE(int host_reg, int guest_reg) { addbyte(0x66); /*MOVW [guest_reg],host_reg*/ addbyte(0x89); addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].w)); + addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].w)); host_reg_mapping[host_reg] = -1; } -static void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) +static inline void STORE_REG_TARGET_L_RELEASE(int host_reg, int guest_reg) { addbyte(0x89); /*MOVL [guest_reg],host_reg*/ addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(regs[guest_reg & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[guest_reg & 7].l)); host_reg_mapping[host_reg] = -1; } -static void RELEASE_REG(int host_reg) +static inline void RELEASE_REG(int host_reg) { host_reg_mapping[host_reg] = -1; } -static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +static inline void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) { if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) { @@ -266,7 +268,7 @@ static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) addlong(addr); } } -static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) +static inline void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) { if (addr >= (uintptr_t)&cpu_state && addr < ((uintptr_t)&cpu_state)+0x100) { @@ -284,29 +286,29 @@ static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) #define STORE_HOST_REG_ADDR_BL STORE_HOST_REG_ADDR #define STORE_HOST_REG_ADDR_WL STORE_HOST_REG_ADDR -static void ADD_HOST_REG_B(int dst_reg, int src_reg) +static inline void ADD_HOST_REG_B(int dst_reg, int src_reg) { addbyte(0x00); /*ADDB dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void ADD_HOST_REG_W(int dst_reg, int src_reg) +static inline void ADD_HOST_REG_W(int dst_reg, int src_reg) { addbyte(0x66); /*ADDW dst_reg, src_reg*/ addbyte(0x01); addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void ADD_HOST_REG_L(int dst_reg, int src_reg) +static inline void ADD_HOST_REG_L(int dst_reg, int src_reg) { addbyte(0x01); /*ADDL dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static inline void ADD_HOST_REG_IMM_B(int host_reg, uint8_t imm) { addbyte(0x80); /*ADDB host_reg, imm*/ addbyte(0xC0 | host_reg); addbyte(imm); } -static void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static inline void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) { if (imm < 0x80 || imm >= 0xff80) { @@ -323,7 +325,7 @@ static void ADD_HOST_REG_IMM_W(int host_reg, uint16_t imm) addword(imm); } } -static void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) { if (imm < 0x80 || imm >= 0xffffff80) { @@ -341,12 +343,12 @@ static void ADD_HOST_REG_IMM(int host_reg, uint32_t imm) #define AND_HOST_REG_B AND_HOST_REG_L #define AND_HOST_REG_W AND_HOST_REG_L -static void AND_HOST_REG_L(int dst_reg, int src_reg) +static inline void AND_HOST_REG_L(int dst_reg, int src_reg) { addbyte(0x21); /*ANDL dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void AND_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void AND_HOST_REG_IMM(int host_reg, uint32_t imm) { if (imm < 0x80 || imm >= 0xffffff80) { @@ -361,25 +363,25 @@ static void AND_HOST_REG_IMM(int host_reg, uint32_t imm) addlong(imm); } } -static int TEST_HOST_REG_B(int dst_reg, int src_reg) +static inline int TEST_HOST_REG_B(int dst_reg, int src_reg) { AND_HOST_REG_B(dst_reg, src_reg); return dst_reg; } -static int TEST_HOST_REG_W(int dst_reg, int src_reg) +static inline int TEST_HOST_REG_W(int dst_reg, int src_reg) { AND_HOST_REG_W(dst_reg, src_reg); return dst_reg; } -static int TEST_HOST_REG_L(int dst_reg, int src_reg) +static inline int TEST_HOST_REG_L(int dst_reg, int src_reg) { AND_HOST_REG_L(dst_reg, src_reg); return dst_reg; } -static int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) { AND_HOST_REG_IMM(host_reg, imm); @@ -388,12 +390,12 @@ static int TEST_HOST_REG_IMM(int host_reg, uint32_t imm) #define OR_HOST_REG_B OR_HOST_REG_L #define OR_HOST_REG_W OR_HOST_REG_L -static void OR_HOST_REG_L(int dst_reg, int src_reg) +static inline void OR_HOST_REG_L(int dst_reg, int src_reg) { addbyte(0x09); /*ORL dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void OR_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void OR_HOST_REG_IMM(int host_reg, uint32_t imm) { if (imm < 0x80 || imm >= 0xffffff80) { @@ -409,46 +411,46 @@ static void OR_HOST_REG_IMM(int host_reg, uint32_t imm) } } -static void NEG_HOST_REG_B(int reg) +static inline void NEG_HOST_REG_B(int reg) { addbyte(0xf6); addbyte(0xd8 | reg); } -static void NEG_HOST_REG_W(int reg) +static inline void NEG_HOST_REG_W(int reg) { addbyte(0x66); addbyte(0xf7); addbyte(0xd8 | reg); } -static void NEG_HOST_REG_L(int reg) +static inline void NEG_HOST_REG_L(int reg) { addbyte(0xf7); addbyte(0xd8 | reg); } -static void SUB_HOST_REG_B(int dst_reg, int src_reg) +static inline void SUB_HOST_REG_B(int dst_reg, int src_reg) { addbyte(0x28); /*SUBB dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void SUB_HOST_REG_W(int dst_reg, int src_reg) +static inline void SUB_HOST_REG_W(int dst_reg, int src_reg) { addbyte(0x66); /*SUBW dst_reg, src_reg*/ addbyte(0x29); addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void SUB_HOST_REG_L(int dst_reg, int src_reg) +static inline void SUB_HOST_REG_L(int dst_reg, int src_reg) { addbyte(0x29); /*SUBL dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static inline void SUB_HOST_REG_IMM_B(int host_reg, uint8_t imm) { addbyte(0x80); /*SUBB host_reg, imm*/ addbyte(0xE8 | host_reg); addbyte(imm); } -static void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static inline void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) { if (imm < 0x80 || imm >= 0xff80) { @@ -465,7 +467,7 @@ static void SUB_HOST_REG_IMM_W(int host_reg, uint16_t imm) addword(imm); } } -static void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) { if (imm < 0x80 || imm >= 0xffffff80) { @@ -481,37 +483,37 @@ static void SUB_HOST_REG_IMM(int host_reg, uint32_t imm) } } -static int CMP_HOST_REG_B(int dst_reg, int src_reg) +static inline int CMP_HOST_REG_B(int dst_reg, int src_reg) { SUB_HOST_REG_B(dst_reg, src_reg); return dst_reg; } -static int CMP_HOST_REG_W(int dst_reg, int src_reg) +static inline int CMP_HOST_REG_W(int dst_reg, int src_reg) { SUB_HOST_REG_W(dst_reg, src_reg); return dst_reg; } -static int CMP_HOST_REG_L(int dst_reg, int src_reg) +static inline int CMP_HOST_REG_L(int dst_reg, int src_reg) { SUB_HOST_REG_L(dst_reg, src_reg); return dst_reg; } -static int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) +static inline int CMP_HOST_REG_IMM_B(int host_reg, uint8_t imm) { SUB_HOST_REG_IMM_B(host_reg, imm); return host_reg; } -static int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) +static inline int CMP_HOST_REG_IMM_W(int host_reg, uint16_t imm) { SUB_HOST_REG_IMM_W(host_reg, imm); return host_reg; } -static int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) +static inline int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) { SUB_HOST_REG_IMM(host_reg, imm); @@ -520,12 +522,12 @@ static int CMP_HOST_REG_IMM_L(int host_reg, uint32_t imm) #define XOR_HOST_REG_B XOR_HOST_REG_L #define XOR_HOST_REG_W XOR_HOST_REG_L -static void XOR_HOST_REG_L(int dst_reg, int src_reg) +static inline void XOR_HOST_REG_L(int dst_reg, int src_reg) { addbyte(0x31); /*XORL dst_reg, src_reg*/ addbyte(0xc0 | dst_reg | (src_reg << 3)); } -static void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) +static inline void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) { if (imm < 0x80 || imm >= 0xffffff80) { @@ -541,64 +543,64 @@ static void XOR_HOST_REG_IMM(int host_reg, uint32_t imm) } } -static void CALL_FUNC(void *dest) +static inline void CALL_FUNC(uintptr_t dest) { addbyte(0xE8); /*CALL*/ - addlong(((uint8_t *)dest - (uint8_t *)(&codeblock[block_current].data[block_pos + 4]))); + addlong(((uintptr_t)dest - (uintptr_t)(&codeblock[block_current].data[block_pos + 4]))); } -static void SHL_B_IMM(int reg, int count) +static inline void SHL_B_IMM(int reg, int count) { addbyte(0xc0); /*SHL reg, count*/ addbyte(0xc0 | reg | 0x20); addbyte(count); } -static void SHL_W_IMM(int reg, int count) +static inline void SHL_W_IMM(int reg, int count) { addbyte(0x66); /*SHL reg, count*/ addbyte(0xc1); addbyte(0xc0 | reg | 0x20); addbyte(count); } -static void SHL_L_IMM(int reg, int count) +static inline void SHL_L_IMM(int reg, int count) { addbyte(0xc1); /*SHL reg, count*/ addbyte(0xc0 | reg | 0x20); addbyte(count); } -static void SHR_B_IMM(int reg, int count) +static inline void SHR_B_IMM(int reg, int count) { addbyte(0xc0); /*SHR reg, count*/ addbyte(0xc0 | reg | 0x28); addbyte(count); } -static void SHR_W_IMM(int reg, int count) +static inline void SHR_W_IMM(int reg, int count) { addbyte(0x66); /*SHR reg, count*/ addbyte(0xc1); addbyte(0xc0 | reg | 0x28); addbyte(count); } -static void SHR_L_IMM(int reg, int count) +static inline void SHR_L_IMM(int reg, int count) { addbyte(0xc1); /*SHR reg, count*/ addbyte(0xc0 | reg | 0x28); addbyte(count); } -static void SAR_B_IMM(int reg, int count) +static inline void SAR_B_IMM(int reg, int count) { addbyte(0xc0); /*SAR reg, count*/ addbyte(0xc0 | reg | 0x38); addbyte(count); } -static void SAR_W_IMM(int reg, int count) +static inline void SAR_W_IMM(int reg, int count) { addbyte(0x66); /*SAR reg, count*/ addbyte(0xc1); addbyte(0xc0 | reg | 0x38); addbyte(count); } -static void SAR_L_IMM(int reg, int count) +static inline void SAR_L_IMM(int reg, int count) { addbyte(0xc1); /*SAR reg, count*/ addbyte(0xc0 | reg | 0x38); @@ -606,7 +608,7 @@ static void SAR_L_IMM(int reg, int count) } -static void CHECK_SEG_READ(x86seg *seg) +static inline void CHECK_SEG_READ(x86seg *seg) { /*Segments always valid in real/V86 mode*/ if (!(cr0 & 1) || (eflags & VM_FLAG)) @@ -629,7 +631,7 @@ static void CHECK_SEG_READ(x86seg *seg) seg->checked = 1; } -static void CHECK_SEG_WRITE(x86seg *seg) +static inline void CHECK_SEG_WRITE(x86seg *seg) { /*Segments always valid in real/V86 mode*/ if (!(cr0 & 1) || (eflags & VM_FLAG)) @@ -652,7 +654,7 @@ static void CHECK_SEG_WRITE(x86seg *seg) seg->checked = 1; } -static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) +static inline void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) return; @@ -680,10 +682,9 @@ static void CHECK_SEG_LIMITS(x86seg *seg, int end_offset) } } -static void MEM_LOAD_ADDR_EA_B(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_B(x86seg *seg) { - if (((seg == &_ds) && (cpu_cur_status & CPU_STATUS_FLATDS)) || - ((seg == &_ss) && (cpu_cur_status & CPU_STATUS_FLATSS))) + if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { addbyte(0x31); /*XOR EDX, EDX*/ addbyte(0xd2); @@ -699,7 +700,7 @@ static void MEM_LOAD_ADDR_EA_B(x86seg *seg) host_reg_mapping[0] = 8; } -static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) +static inline int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -719,7 +720,7 @@ static int MEM_LOAD_ADDR_EA_B_NO_ABRT(x86seg *seg) return REG_ECX; } -static void MEM_LOAD_ADDR_EA_W(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_W(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -737,7 +738,7 @@ static void MEM_LOAD_ADDR_EA_W(x86seg *seg) host_reg_mapping[0] = 8; } -static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) +static inline void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -758,7 +759,7 @@ static void MEM_LOAD_ADDR_EA_W_OFFSET(x86seg *seg, int offset) host_reg_mapping[0] = 8; } -static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) +static inline int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -778,7 +779,7 @@ static int MEM_LOAD_ADDR_EA_W_NO_ABRT(x86seg *seg) return REG_ECX; } -static void MEM_LOAD_ADDR_EA_L(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_L(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -797,7 +798,7 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) host_reg_mapping[0] = 8; } -static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) +static inline int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -818,7 +819,7 @@ static int MEM_LOAD_ADDR_EA_L_NO_ABRT(x86seg *seg) return REG_ECX; } -static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) +static inline void MEM_LOAD_ADDR_EA_Q(x86seg *seg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -837,26 +838,26 @@ static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) host_reg_mapping[0] = 8; } -static void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) +static inline void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_LOAD_ADDR_EA_B(seg); } -static void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) +static inline void MEM_LOAD_ADDR_IMM_W(x86seg *seg, uint32_t addr) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_LOAD_ADDR_EA_W(seg); } -static void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) +static inline void MEM_LOAD_ADDR_IMM_L(x86seg *seg, uint32_t addr) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_LOAD_ADDR_EA_L(seg); } -static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -877,7 +878,7 @@ static void MEM_STORE_ADDR_EA_B(x86seg *seg, int host_reg) addbyte(0xe8); /*CALL mem_store_addr_ea_b*/ addlong(mem_store_addr_ea_b - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -898,7 +899,7 @@ static void MEM_STORE_ADDR_EA_B_NO_ABRT(x86seg *seg, int host_reg) addbyte(0xe8); /*CALL mem_store_addr_ea_b_no_abrt*/ addlong(mem_store_addr_ea_b_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -919,7 +920,7 @@ static void MEM_STORE_ADDR_EA_W(x86seg *seg, int host_reg) addbyte(0xe8); /*CALL mem_store_addr_ea_w*/ addlong(mem_store_addr_ea_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -940,7 +941,7 @@ static void MEM_STORE_ADDR_EA_W_NO_ABRT(x86seg *seg, int host_reg) addbyte(0xe8); /*CALL mem_store_addr_ea_w_no_abrt*/ addlong(mem_store_addr_ea_w_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -961,7 +962,7 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addbyte(0xe8); /*CALL mem_store_addr_ea_l*/ addlong(mem_store_addr_ea_l - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) +static inline void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) { if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) { @@ -982,7 +983,7 @@ static void MEM_STORE_ADDR_EA_L_NO_ABRT(x86seg *seg, int host_reg) addbyte(0xe8); /*CALL mem_store_addr_ea_l_no_abrt*/ addlong(mem_store_addr_ea_l_no_abrt - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +static inline void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) { if (host_reg != REG_EBX) { @@ -1009,19 +1010,19 @@ static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) addlong(mem_store_addr_ea_q - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); } -static void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) +static inline void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_STORE_ADDR_EA_B(seg, host_reg); } -static void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) +static inline void MEM_STORE_ADDR_IMM_L(x86seg *seg, uint32_t addr, int host_reg) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); MEM_STORE_ADDR_EA_L(seg, host_reg); } -static void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) +static inline void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) { addbyte(0xb8); /*MOV EAX, addr*/ addlong(addr); @@ -1029,10 +1030,9 @@ static void MEM_STORE_ADDR_IMM_W(x86seg *seg, uint32_t addr, int host_reg) } -static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) +static inline x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc) { int mod = (fetchdat >> 6) & 3; - int reg = (fetchdat >> 3) & 7; int rm = fetchdat & 7; if (!mod && rm == 6) { @@ -1092,11 +1092,10 @@ static x86seg *FETCH_EA_16(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u return op_ea_seg; } -static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) +static inline x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, int stack_offset) { uint32_t new_eaaddr; int mod = (fetchdat >> 6) & 3; - int reg = (fetchdat >> 3) & 7; int rm = fetchdat & 7; if (rm == 4) @@ -1118,13 +1117,13 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u { addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[sib & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); } break; case 1: addbyte(0x8b); /*MOVL EAX, regs[sib&7].l*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[sib & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); addbyte(0x83); /*ADDL EAX, imm8*/ addbyte(0xc0 | REG_EAX); addbyte((int8_t)(rmdat >> 16)); @@ -1136,7 +1135,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u addlong(new_eaaddr); addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[sib & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); (*op_pc) += 4; break; } @@ -1163,20 +1162,20 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u case 0: addbyte(0x03); /*ADDL EAX, regs[sib&7].l*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); break; case 1: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ + addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ break; case 2: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ + addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI, reg*/ addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(2); /*SHL EDI, 2*/ addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ break; case 3: - addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ + addbyte(0x8B); addbyte(0x45 | (REG_EDI << 3)); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL EDI reg*/ addbyte(0xC1); addbyte(0xE0 | REG_EDI); addbyte(3); /*SHL EDI, 3*/ addbyte(0x01); addbyte(0xc0 | REG_EAX | (REG_EDI << 3)); /*ADDL EAX, EDI*/ break; @@ -1195,7 +1194,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u } addbyte(0x8b); /*MOVL EAX, regs[rm].l*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[rm].l)); + addbyte((uint8_t)cpu_state_offset(regs[rm].l)); cpu_state.eaaddr = cpu_state.regs[rm].l; if (mod) { @@ -1220,7 +1219,7 @@ static x86seg *FETCH_EA_32(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, u return op_ea_seg; } -static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) +static inline x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint32_t *op_pc, uint32_t op_32) { if (op_32 & 0x200) return FETCH_EA_32(op_ea_seg, fetchdat, op_ssegs, op_pc, 0); @@ -1228,13 +1227,13 @@ static x86seg *FETCH_EA(x86seg *op_ea_seg, uint32_t fetchdat, int op_ssegs, uint } -static void LOAD_STACK_TO_EA(int off) +static inline void LOAD_STACK_TO_EA(int off) { if (stack32) { addbyte(0x8b); /*MOVL EAX,[ESP]*/ addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_ESP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); if (off) { addbyte(0x83); /*ADD EAX, off*/ @@ -1247,7 +1246,7 @@ static void LOAD_STACK_TO_EA(int off) addbyte(0x0f); /*MOVZX EAX,W[ESP]*/ addbyte(0xb7); addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_ESP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); if (off) { addbyte(0x66); /*ADD AX, off*/ @@ -1257,13 +1256,13 @@ static void LOAD_STACK_TO_EA(int off) } } -static void LOAD_EBP_TO_EA(int off) +static inline void LOAD_EBP_TO_EA(int off) { if (stack32) { addbyte(0x8b); /*MOVL EAX,[EBP]*/ addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_EBP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].l)); if (off) { addbyte(0x83); /*ADD EAX, off*/ @@ -1276,7 +1275,7 @@ static void LOAD_EBP_TO_EA(int off) addbyte(0x0f); /*MOVZX EAX,W[EBP]*/ addbyte(0xb7); addbyte(0x45 | (REG_EAX << 3)); - addbyte(cpu_state_offset(regs[REG_EBP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_EBP].w)); if (off) { addbyte(0x66); /*ADD AX, off*/ @@ -1286,7 +1285,7 @@ static void LOAD_EBP_TO_EA(int off) } } -static void SP_MODIFY(int off) +static inline void SP_MODIFY(int off) { if (stack32) { @@ -1294,14 +1293,14 @@ static void SP_MODIFY(int off) { addbyte(0x83); /*ADD [ESP], off*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); addbyte(off); } else { addbyte(0x81); /*ADD [ESP], off*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].l)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].l)); addlong(off); } } @@ -1312,7 +1311,7 @@ static void SP_MODIFY(int off) addbyte(0x66); /*ADD [SP], off*/ addbyte(0x83); addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); addbyte(off); } else @@ -1320,14 +1319,14 @@ static void SP_MODIFY(int off) addbyte(0x66); /*ADD [SP], off*/ addbyte(0x81); addbyte(0x45); - addbyte(cpu_state_offset(regs[REG_ESP].w)); + addbyte((uint8_t)cpu_state_offset(regs[REG_ESP].w)); addword(off); } } } -static void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { addbyte(0x66); /*CMPW host_reg, 0*/ addbyte(0x83); @@ -1337,19 +1336,19 @@ static void TEST_ZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) { addbyte(0x83); /*CMPW host_reg, 0*/ addbyte(0xc0 | 0x38 | host_reg); @@ -1358,20 +1357,20 @@ static void TEST_ZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) { addbyte(0x66); /*CMPW host_reg, 0*/ addbyte(0x83); @@ -1381,19 +1380,19 @@ static void TEST_NONZERO_JUMP_W(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) +static inline void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) { addbyte(0x83); /*CMPW host_reg, 0*/ addbyte(0xc0 | 0x38 | host_reg); @@ -1402,30 +1401,30 @@ static void TEST_NONZERO_JUMP_L(int host_reg, uint32_t new_pc, int taken_cycles) addbyte(7+5+(taken_cycles ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(new_pc); if (taken_cycles) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(taken_cycles); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static inline void BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_SUB8: addbyte(0x8a); /*MOV AL, flags_op1*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x3a); /*CMP AL, flags_op2*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x76); /*JBE*/ else @@ -1435,11 +1434,11 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(0x66); /*MOV AX, flags_op1*/ addbyte(0x8b); addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x66); /*CMP AX, flags_op2*/ addbyte(0x3b); addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x76); /*JBE*/ else @@ -1448,10 +1447,10 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no case FLAGS_SUB32: addbyte(0x8b); /*MOV EAX, flags_op1*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x3b); /*CMP EAX, flags_op2*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x76); /*JBE*/ else @@ -1463,13 +1462,13 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no { addbyte(0x83); /*CMP flags_res, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(flags_res)); + addbyte((uint8_t)cpu_state_offset(flags_res)); addbyte(0); addbyte(0x74); /*JZ +*/ } else { - CALL_FUNC(ZF_SET); + CALL_FUNC((uintptr_t)ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x75); /*JNZ +*/ @@ -1478,7 +1477,7 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(5+2+2+7+5+(timing_bt ? 4 : 0)); else addbyte(5+2+2); - CALL_FUNC(CF_SET); + CALL_FUNC((uintptr_t)CF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); if (not) @@ -1490,30 +1489,30 @@ static int BRANCH_COND_BE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(7+5+(timing_bt ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc+pc_offset+offset); if (timing_bt) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(timing_bt); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static inline void BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_SUB8: addbyte(0x8a); /*MOV AL, flags_op1*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x3a); /*CMP AL, flags_op2*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x7c); /*JL*/ else @@ -1523,11 +1522,11 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not addbyte(0x66); /*MOV AX, flags_op1*/ addbyte(0x8b); addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x66); /*CMP AX, flags_op2*/ addbyte(0x3b); addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x7c); /*JL*/ else @@ -1536,10 +1535,10 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not case FLAGS_SUB32: addbyte(0x8b); /*MOV EAX, flags_op1*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x3b); /*CMP EAX, flags_op2*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x7c); /*JL*/ else @@ -1547,13 +1546,13 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not break; default: - CALL_FUNC(NF_SET); + CALL_FUNC((uintptr_t)NF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE BL*/ addbyte(0x95); addbyte(0xc3); - CALL_FUNC(VF_SET); + CALL_FUNC((uintptr_t)VF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE AL*/ @@ -1570,30 +1569,30 @@ static int BRANCH_COND_L(int pc_offset, uint32_t op_pc, uint32_t offset, int not addbyte(7+5+(timing_bt ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc+pc_offset+offset); if (timing_bt) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(timing_bt); } addbyte(0xe9); /*JMP end*/ addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); } -static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) +static inline void BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int not) { switch (codegen_flags_changed ? cpu_state.flags_op : FLAGS_UNKNOWN) { case FLAGS_SUB8: addbyte(0x8a); /*MOV AL, flags_op1*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x3a); /*CMP AL, flags_op2*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x7e); /*JLE*/ else @@ -1603,11 +1602,11 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(0x66); /*MOV AX, flags_op1*/ addbyte(0x8b); addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x66); /*CMP AX, flags_op2*/ addbyte(0x3b); addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x7e); /*JLE*/ else @@ -1616,10 +1615,10 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no case FLAGS_SUB32: addbyte(0x8b); /*MOV EAX, flags_op1*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op1)); + addbyte((uint8_t)cpu_state_offset(flags_op1)); addbyte(0x3b); /*CMP EAX, flags_op2*/ addbyte(0x45); - addbyte(cpu_state_offset(flags_op2)); + addbyte((uint8_t)cpu_state_offset(flags_op2)); if (not) addbyte(0x7e); /*JLE*/ else @@ -1631,13 +1630,13 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no { addbyte(0x83); /*CMP flags_res, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(flags_res)); + addbyte((uint8_t)cpu_state_offset(flags_res)); addbyte(0); addbyte(0x74); /*JZ +*/ } else { - CALL_FUNC(ZF_SET); + CALL_FUNC((uintptr_t)ZF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x75); /*JNZ +*/ @@ -1647,13 +1646,13 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no else addbyte(5+2+3+5+2+3+2+2); - CALL_FUNC(NF_SET); + CALL_FUNC((uintptr_t)NF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE BL*/ addbyte(0x95); addbyte(0xc3); - CALL_FUNC(VF_SET); + CALL_FUNC((uintptr_t)VF_SET); addbyte(0x85); /*TEST EAX,EAX*/ addbyte(0xc0); addbyte(0x0f); /*SETNE AL*/ @@ -1670,13 +1669,13 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no addbyte(7+5+(timing_bt ? 4 : 0)); addbyte(0xC7); /*MOVL [pc], new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc+pc_offset+offset); if (timing_bt) { addbyte(0x83); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addbyte(timing_bt); } addbyte(0xe9); /*JMP end*/ @@ -1684,7 +1683,7 @@ static int BRANCH_COND_LE(int pc_offset, uint32_t op_pc, uint32_t offset, int no } -static void FP_ENTER() +static inline void FP_ENTER() { if (codegen_fpu_entered) return; @@ -1697,7 +1696,7 @@ static void FP_ENTER() addbyte(7+7+5+5); addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(oldpc)); + addbyte((uint8_t)cpu_state_offset(oldpc)); addlong(op_old_pc); addbyte(0xc7); /*MOV [ESP], 7*/ addbyte(0x04); @@ -1711,7 +1710,7 @@ static void FP_ENTER() codegen_fpu_entered = 1; } -static void FP_FLD(int reg) +static inline void FP_FLD(int reg) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -1719,38 +1718,38 @@ static void FP_FLD(int reg) addbyte(0x0f); addbyte(0x7e); addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0xf3); /*MOVQ XMM1, MM[reg][EBP]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x4d); - addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); addbyte(0x66); /*MOVQ ST[-1][EBP], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); addbyte(0x8a); /*MOV AL, tag[reg][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); addbyte(0x66); /*MOVQ MM[-1][EBP], XMM1*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x4d); - addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); addbyte(0x88); /*MOV tag[-1][EBP], AL*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); } else { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); if (reg) @@ -1775,46 +1774,46 @@ static void FP_FLD(int reg) addbyte(0xdd); /*FLD [ST+EAX*8]*/ addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x83); /*AND EBX, 7*/ addbyte(0xe3); addbyte(0x07); addbyte(0x8b); /*MOV EDX, [ST_i64+EAX]*/ addbyte(0x54); addbyte(0xc5); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x8b); /*MOV ECX, [ST_i64+4+EAX]*/ addbyte(0x4c); addbyte(0xc5); - addbyte(cpu_state_offset(MM)+4); + addbyte((uint8_t)cpu_state_offset(MM)+4); addbyte(0x8a); /*MOV AL, [tag+EAX]*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x88); /*MOV [tag+EBX], AL*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0x89); /*MOV [ST_i64+EBX], EDX*/ addbyte(0x54); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x89); /*MOV [ST_i64+EBX+4], ECX*/ addbyte(0x4c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)+4); + addbyte((uint8_t)cpu_state_offset(MM)+4); addbyte(0x89); /*MOV [TOP], EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } } -static void FP_FST(int reg) +static inline void FP_FST(int reg) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -1822,32 +1821,32 @@ static void FP_FST(int reg) addbyte(0x0f); addbyte(0x7e); addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); addbyte(0x88); /*MOV tag[reg][EBP], AL*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); } else { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xdd); /*FLD [ST+EAX*8]*/ addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV BL, [tag+EAX]*/ addbyte(0x5c); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); if (reg) { @@ -1862,15 +1861,15 @@ static void FP_FST(int reg) addbyte(0xdd); /*FSTP [ST+EAX*8]*/ addbyte(0x5c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x88); /*MOV [tag+EAX], BL*/ addbyte(0x5c); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); } } -static void FP_FXCH(int reg) +static inline void FP_FXCH(int reg) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -1878,60 +1877,60 @@ static void FP_FXCH(int reg) addbyte(0x0f); addbyte(0x7e); addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0xf3); /*MOVQ XMM1, ST[reg][EBP]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x4d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); addbyte(0x66); /*MOVQ ST[reg][EBP], XMM0*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); addbyte(0xf3); /*MOVQ XMM2, MM[0][EBP]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x55); - addbyte(cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); addbyte(0x66); /*MOVQ ST[0][EBP], XMM1*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x4d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0xf3); /*MOVQ XMM3, MM[reg][EBP]*/ addbyte(0x0f); addbyte(0x7e); addbyte(0x5d); - addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); addbyte(0x66); /*MOVQ MM[reg][EBP], XMM2*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x55); - addbyte(cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP + reg) & 7].q)); addbyte(0x8a); /*MOV AL, tag[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(0x66); /*MOVQ MM[0][EBP], XMM3*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x5d); - addbyte(cpu_state_offset(MM[cpu_state.TOP].q)); + addbyte((uint8_t)cpu_state_offset(MM[cpu_state.TOP].q)); addbyte(0x8a); /*MOV AH, tag[reg][EBP]*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); addbyte(0x88); /*MOV tag[reg][EBP], AL*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + reg) & 7])); addbyte(0x88); /*MOV tag[0][EBP], AH*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); } else { addbyte(0x8b); /*MOV EAX, [TOP]*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); addbyte(0x83); /*ADD EAX, reg*/ @@ -1941,38 +1940,38 @@ static void FP_FXCH(int reg) addbyte(0xdd); /*FLD [ST+EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x83); /*AND EAX, 7*/ addbyte(0xe0); addbyte(0x07); addbyte(0xdd); /*FLD [ST+EAX*8]*/ addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xdd); /*FSTP [ST+EAX*8]*/ addbyte(0x5c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV CL, tag[EAX]*/ addbyte(0x4c); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0x8a); /*MOV DL, tag[EBX]*/ addbyte(0x54); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0x88); /*MOV tag[EBX], CL*/ addbyte(0x4c); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0x88); /*MOV tag[EAX], DL*/ addbyte(0x54); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0xbe); /*MOVL ESI, ST_int64*/ addlong((uintptr_t)cpu_state.MM); addbyte(0x8b); /*MOV ECX, ST_int64[EAX*8]*/ @@ -2007,7 +2006,7 @@ static void FP_FXCH(int reg) } -static void FP_LOAD_S() +static inline void FP_LOAD_S() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2021,22 +2020,22 @@ static void FP_LOAD_S() addbyte(0x24); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0x0f); /*SETE tag[reg][EBP]*/ addbyte(0x94); addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); addbyte(0xdd); /*FSTP ST[reg][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); block_current = block_current; } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -2053,44 +2052,44 @@ static void FP_LOAD_S() addbyte(0xc0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); } } -static void FP_LOAD_D() +static inline void FP_LOAD_D() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0x89); /*MOV ST[reg][EBP], EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); addbyte(0x09); /*OR EAX, EDX*/ addbyte(0xd0); addbyte(0x89); /*MOV ST[reg][EBP]+4, EDX*/ addbyte(0x55); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0x0f); /*SETE tag[reg][EBP]*/ addbyte(0x94); addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -2114,19 +2113,19 @@ static void FP_LOAD_D() addbyte(0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); } } -static void FP_LOAD_IW() +static inline void FP_LOAD_IW() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2142,21 +2141,21 @@ static void FP_LOAD_IW() addbyte(0x24); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0x0f); /*SETE tag[reg][EBP]*/ addbyte(0x94); addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); addbyte(0xdd); /*FSTP ST[reg][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -2174,19 +2173,19 @@ static void FP_LOAD_IW() addbyte(0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); } } -static void FP_LOAD_IL() +static inline void FP_LOAD_IL() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2200,21 +2199,21 @@ static void FP_LOAD_IL() addbyte(0x24); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0x0f); /*SETE tag[reg][EBP]*/ addbyte(0x94); addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); addbyte(0xdd); /*FSTP ST[reg][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -2232,54 +2231,54 @@ static void FP_LOAD_IL() addbyte(0); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0f); /*SETE [tag+EBX]*/ addbyte(0x94); addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); } } -static void FP_LOAD_IQ() +static inline void FP_LOAD_IQ() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0x89); /*MOV MM[reg][EBP], EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); addbyte(0x09); /*OR EAX, EDX*/ addbyte(0xd0); addbyte(0x89); /*MOV MM[reg][EBP]+4, EDX*/ addbyte(0x55); - addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q) + 4); addbyte(0x0f); /*SETE AL*/ addbyte(0x94); addbyte(0xc0); addbyte(0xdf); /*FILDq MM[reg][EBP]*/ addbyte(0x6d); - addbyte(cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); + addbyte((uint8_t)cpu_state_offset(MM[(cpu_state.TOP - 1) & 7].q)); addbyte(0x0c); /*OR AL, TAG_UINT64*/ addbyte(TAG_UINT64); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0x88); /*MOV tag[reg][EBP], AL*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); addbyte(0xdd); /*FSTP ST[reg][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x83); /*SUB EBX, 1*/ addbyte(0xeb); addbyte(1); @@ -2289,65 +2288,65 @@ static void FP_LOAD_IQ() addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x09); /*OR EAX, EDX*/ addbyte(0xd0); addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ addbyte(0x54); addbyte(0xdd); - addbyte(cpu_state_offset(MM)+4); + addbyte((uint8_t)cpu_state_offset(MM)+4); addbyte(0x83); /*CMP EAX, 0*/ addbyte(0xf8); addbyte(0); addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ addbyte(0x6c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0x0f); /*SETE AL*/ addbyte(0x94); addbyte(0xc0); addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x0c); /*OR AL, TAG_UINT64*/ addbyte(TAG_UINT64); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x88); /*MOV [tag+EBX], AL*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); } } -static void FP_LOAD_IMM_Q(uint64_t v) +static inline void FP_LOAD_IMM_Q(uint64_t v) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xc7); /*MOV ST[reg][EBP], v*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7])); addlong(v & 0xffffffff); addbyte(0xc7); /*MOV ST[reg][EBP]+4, v*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP - 1) & 7]) + 4); addlong(v >> 32); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP - 1) & 7); addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP - 1) & 7])); addbyte(v ? 0 : 1); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x83); /*SUB EBX, 1*/ addbyte(0xeb); addbyte(1); @@ -2357,37 +2356,37 @@ static void FP_LOAD_IMM_Q(uint64_t v) addbyte(0xc7); /*MOV ST[EBP+EBX*8], v*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addlong(v & 0xffffffff); addbyte(0xc7); /*MOV ST[EBP+EBX*8]+4, v*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST) + 4); + addbyte((uint8_t)cpu_state_offset(ST) + 4); addlong(v >> 32); addbyte(0xc6); /*MOVB tag[reg][EBP], 1:0*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(v ? 0 : 1); addbyte(0x89); /*MOV TOP, EBX*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } } -static int FP_LOAD_REG(int reg) +static inline int FP_LOAD_REG(int reg) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xdd); /*FLD ST[reg][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -2400,7 +2399,7 @@ static int FP_LOAD_REG(int reg) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } addbyte(0xd9); /*FSTP [ESP]*/ addbyte(0x1c); @@ -2412,19 +2411,19 @@ static int FP_LOAD_REG(int reg) return REG_EBX; } -static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +static inline void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xdd); /*FLD ST[reg][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + reg) & 7])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -2437,7 +2436,7 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } addbyte(0xdd); /*FSTP [ESP]*/ addbyte(0x1c); @@ -2454,11 +2453,11 @@ static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) *host_reg2 = REG_ECX; } -static int FP_LOAD_REG_INT_W(int reg) +static inline int FP_LOAD_REG_INT_W(int reg) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -2471,28 +2470,28 @@ static int FP_LOAD_REG_INT_W(int reg) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); addbyte(0xdb); /*FISTP [ESP]*/ addbyte(0x1c); addbyte(0x24); addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(old_npxc)); + addbyte((uint8_t)cpu_state_offset(old_npxc)); addbyte(0x8b); /*MOV EBX, [ESP]*/ addbyte(0x1c); addbyte(0x24); return REG_EBX; } -static int FP_LOAD_REG_INT(int reg) +static inline int FP_LOAD_REG_INT(int reg) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -2505,28 +2504,28 @@ static int FP_LOAD_REG_INT(int reg) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); addbyte(0xdb); /*FISTP [ESP]*/ addbyte(0x1c); addbyte(0x24); addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(old_npxc)); + addbyte((uint8_t)cpu_state_offset(old_npxc)); addbyte(0x8b); /*MOV EBX, [ESP]*/ addbyte(0x1c); addbyte(0x24); return REG_EBX; } -static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +static inline void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); if (reg) { addbyte(0x83); /*ADD EBX, reg*/ @@ -2544,11 +2543,11 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ addbyte(0x4c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)+4); + addbyte((uint8_t)cpu_state_offset(MM)+4); addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); return; } @@ -2556,7 +2555,7 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ addbyte(0x44); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(TAG_UINT64); addbyte(0x74); /*JZ +*/ addbyte(4+4+2); @@ -2564,11 +2563,11 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ addbyte(0x4c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)+4); + addbyte((uint8_t)cpu_state_offset(MM)+4); addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(MM)); + addbyte((uint8_t)cpu_state_offset(MM)); addbyte(0xeb); /*JMP done*/ addbyte(4+3+3+3+3+4); @@ -2576,17 +2575,17 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); addbyte(0xdf); /*FISTPQ [ESP]*/ addbyte(0x3c); addbyte(0x24); addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(old_npxc)); + addbyte((uint8_t)cpu_state_offset(old_npxc)); addbyte(0x8b); /*MOV EBX, [ESP]*/ addbyte(0x1c); addbyte(0x24); @@ -2599,28 +2598,28 @@ static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) *host_reg2 = REG_ECX; } -static void FP_POP() +static inline void FP_POP() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(3); addbyte(0xc6); /*MOVB TOP[EBP], (TOP-1) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP + 1) & 7); } else { addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xc6); /*MOVB tag[EAX], 3*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(3); addbyte(0x04); /*ADD AL, 1*/ addbyte(1); @@ -2628,35 +2627,35 @@ static void FP_POP() addbyte(7); addbyte(0x88); /*MOV TOP, AL*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } } -static void FP_POP2() +static inline void FP_POP2() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xc6); /*MOVB tag[0][EBP], 3*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(3); addbyte(0xc6); /*MOVB tag[1][EBP], 3*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[(cpu_state.TOP+1)&7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP+1)&7])); addbyte(3); addbyte(0xc6); /*MOVB TOP[EBP], (TOP+2) & 7*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte((cpu_state.TOP + 2) & 7); } else { addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xc6); /*MOVB tag[EAX], 3*/ addbyte(0x44); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(3); addbyte(0x04); /*ADD AL, 2*/ addbyte(2); @@ -2664,7 +2663,7 @@ static void FP_POP2() addbyte(7); addbyte(0x88); /*MOV TOP, AL*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); } } @@ -2675,7 +2674,7 @@ static void FP_POP2() #define FPU_SUB 0x20 #define FPU_SUBR 0x28 -static void FP_OP_S(int op) +static inline void FP_OP_S(int op) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2684,34 +2683,34 @@ static void FP_OP_S(int op) addbyte(0x24); addbyte(0xdd); /*FLD ST[dst][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(~TAG_UINT64); addbyte(0xd8); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); addbyte(0xdd); /*FSTP ST[dst][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xd8); /*FADD [ESP]*/ addbyte(0x04 | op); @@ -2719,10 +2718,10 @@ static void FP_OP_S(int op) addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } -static void FP_OP_D(int op) +static inline void FP_OP_D(int op) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2737,33 +2736,33 @@ static void FP_OP_D(int op) { addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); } addbyte(0xdd); /*FLD ST[dst][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(~TAG_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); addbyte(0xdd); /*FSTP ST[dst][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(old_npxc)); + addbyte((uint8_t)cpu_state_offset(old_npxc)); } } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -2771,7 +2770,7 @@ static void FP_OP_D(int op) { addbyte(0xd9); /*FLDCW cpu_state.new_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); } addbyte(0x89); /*MOV [ESP+4], EDX*/ addbyte(0x54); @@ -2780,11 +2779,11 @@ static void FP_OP_D(int op) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); @@ -2792,16 +2791,16 @@ static void FP_OP_D(int op) addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); if (((cpu_state.npxc >> 10) & 3) && op == FPU_ADD) { addbyte(0xd9); /*FLDCW cpu_state.old_npxc*/ addbyte(0x6d); - addbyte(cpu_state_offset(old_npxc)); + addbyte((uint8_t)cpu_state_offset(old_npxc)); } } } -static void FP_OP_IW(int op) +static inline void FP_OP_IW(int op) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2811,34 +2810,34 @@ static void FP_OP_IW(int op) addbyte(0x24); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(~TAG_UINT64); addbyte(0xde); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); addbyte(0xdd); /*FSTP ST[0][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xde); /*FADD [ESP]*/ addbyte(0x04 | op); @@ -2846,10 +2845,10 @@ static void FP_OP_IW(int op) addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } -static void FP_OP_IL(int op) +static inline void FP_OP_IL(int op) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2858,34 +2857,34 @@ static void FP_OP_IL(int op) addbyte(0x24); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(~TAG_UINT64); addbyte(0xda); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); addbyte(0xdd); /*FSTP ST[0][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xda); /*FADD [ESP]*/ addbyte(0x04 | op); @@ -2893,10 +2892,11 @@ static void FP_OP_IL(int op) addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } -static void FP_OP_IQ(int op) +#if 0 +static inline void FP_OP_IQ(int op) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2909,23 +2909,23 @@ static void FP_OP_IQ(int op) addbyte(0x04); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x80); /*AND tag[0][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(~TAG_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); addbyte(0x24); addbyte(0xdd); /*FSTP ST[0][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -2936,11 +2936,11 @@ static void FP_OP_IQ(int op) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xdc); /*FADD [ESP]*/ addbyte(0x04 | op); @@ -2948,16 +2948,16 @@ static void FP_OP_IQ(int op) addbyte(0xdd); /*FSTP [ST+EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } - +#endif #define C0 (1<<8) #define C1 (1<<9) #define C2 (1<<10) #define C3 (1<<14) -static void FP_COMPARE_S() +static inline void FP_COMPARE_S() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -2966,10 +2966,10 @@ static void FP_COMPARE_S() addbyte(0x24); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -2987,23 +2987,23 @@ static void FP_COMPARE_S() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3021,10 +3021,10 @@ static void FP_COMPARE_S() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } } -static void FP_COMPARE_D() +static inline void FP_COMPARE_D() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -3037,10 +3037,10 @@ static void FP_COMPARE_D() addbyte(0x04); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3058,13 +3058,13 @@ static void FP_COMPARE_D() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); @@ -3075,10 +3075,10 @@ static void FP_COMPARE_D() addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3096,10 +3096,10 @@ static void FP_COMPARE_D() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } } -static void FP_COMPARE_IW() +static inline void FP_COMPARE_IW() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -3109,10 +3109,10 @@ static void FP_COMPARE_IW() addbyte(0x24); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3130,23 +3130,23 @@ static void FP_COMPARE_IW() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3164,10 +3164,10 @@ static void FP_COMPARE_IW() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } } -static void FP_COMPARE_IL() +static inline void FP_COMPARE_IL() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { @@ -3176,10 +3176,10 @@ static void FP_COMPARE_IL() addbyte(0x24); addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3197,23 +3197,23 @@ static void FP_COMPARE_IL() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } else { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x5d); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV [ESP], EAX*/ addbyte(0x04); addbyte(0x24); addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x8a); /*MOV BL, [npxs+1]*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ @@ -3231,33 +3231,33 @@ static void FP_COMPARE_IL() addbyte(0xe3); addbyte(0x88); /*MOV [npxs+1], BL*/ addbyte(0x5d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } } -static void FP_OP_REG(int op, int dst, int src) +static inline void FP_OP_REG(int op, int dst, int src) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xdd); /*FLD ST[dst][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); addbyte(0xdc); /*FADD ST[src][EBP]*/ addbyte(0x45 | op); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); + addbyte((uint8_t)cpu_state_offset(tag[(cpu_state.TOP + dst) & 7])); addbyte(~TAG_UINT64); addbyte(0xdd); /*FSTP ST[dst][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); } else { addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); if (src || dst) @@ -3275,62 +3275,62 @@ static void FP_OP_REG(int op, int dst, int src) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x1d); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xdc); /*FADD ST[EAX*8]*/ addbyte(0x44 | op); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xdd); /*FSTP ST[EBX*8]*/ addbyte(0x5c); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } else { addbyte(0xdd); /*FLD [ESI+EAX*8]*/ addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xdc); /*FADD ST[EBX*8]*/ addbyte(0x44 | op); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xdd); /*FSTP ST[EAX*8]*/ addbyte(0x5c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } } -static void FP_COMPARE_REG(int dst, int src) +static inline void FP_COMPARE_REG(int dst, int src) { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0x8a); /*MOV CL, [npxs+1]*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0xdd); /*FLD ST[dst][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + dst) & 7])); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ addbyte(0xe1); addbyte((~(C0|C2|C3)) >> 8); addbyte(0xdc); /*FCOMP ST[src][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); + addbyte((uint8_t)cpu_state_offset(ST[(cpu_state.TOP + src) & 7])); addbyte(0xdf); /*FSTSW AX*/ addbyte(0xe0); addbyte(0x80); /*AND AH, (C0|C2|C3)*/ @@ -3340,13 +3340,13 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } else { addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV EBX, EAX*/ addbyte(0xc3); if (src || dst) @@ -3361,7 +3361,7 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0x8a); /*MOV CL, [npxs+1]*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); addbyte(0xdb); /*FCLEX*/ addbyte(0xe2); addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ @@ -3373,22 +3373,22 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0xdd); /*FLD ST[EBX*8]*/ addbyte(0x44); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xdc); /*FCOMP ST[EAX*8]*/ addbyte(0x44 | 0x18); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } else { addbyte(0xdd); /*FLD [ESI+EAX*8]*/ addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0xdc); /*FCOMP ST[EBX*8]*/ addbyte(0x44 | 0x18); addbyte(0xdd); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } addbyte(0xdf); /*FSTSW AX*/ @@ -3400,57 +3400,57 @@ static void FP_COMPARE_REG(int dst, int src) addbyte(0xe1); addbyte(0x88); /*MOV [npxs+1], CL*/ addbyte(0x4d); - addbyte(cpu_state_offset(npxs) + 1); + addbyte((uint8_t)cpu_state_offset(npxs) + 1); } } -static void FP_FCHS() +static inline void FP_FCHS() { if (codeblock[block_current].flags & CODEBLOCK_STATIC_TOP) { addbyte(0xdd); /*FLD ST[0][EBP]*/ addbyte(0x45); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); addbyte(0xd9); /*FCHS*/ addbyte(0xe0); addbyte(0x80); /*AND tag[dst][EBP], ~TAG_UINT64*/ addbyte(0x65); - addbyte(cpu_state_offset(tag[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(tag[cpu_state.TOP])); addbyte(~TAG_UINT64); addbyte(0xdd); /*FSTP ST[dst][EBP]*/ addbyte(0x5d); - addbyte(cpu_state_offset(ST[cpu_state.TOP])); + addbyte((uint8_t)cpu_state_offset(ST[cpu_state.TOP])); } else { addbyte(0x8b); /*MOV EAX, TOP*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0xdd); /*FLD [ESI+EAX*8]*/ addbyte(0x44); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); addbyte(0x80); /*AND tag[EAX], ~TAG_UINT64*/ addbyte(0x64); addbyte(0x05); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(~TAG_UINT64); addbyte(0xd9); /*FCHS*/ addbyte(0xe0); addbyte(0xdd); /*FSTP ST[EAX*8]*/ addbyte(0x5c); addbyte(0xc5); - addbyte(cpu_state_offset(ST)); + addbyte((uint8_t)cpu_state_offset(ST)); } } -static void UPDATE_NPXC(int reg) +static inline void UPDATE_NPXC(int reg) { addbyte(0x66); /*AND cpu_state.new_npxc, ~0xc00*/ addbyte(0x81); addbyte(0x65); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); addword(~0xc00); if (reg) { @@ -3468,24 +3468,24 @@ static void UPDATE_NPXC(int reg) addbyte(0x66); /*OR cpu_state.new_npxc, reg*/ addbyte(0x09); addbyte(0x45 | (reg << 3)); - addbyte(cpu_state_offset(new_npxc)); + addbyte((uint8_t)cpu_state_offset(new_npxc)); } -static int ZERO_EXTEND_W_B(int reg) +static inline int ZERO_EXTEND_W_B(int reg) { addbyte(0x0f); /*MOVZX regl, regb*/ addbyte(0xb6); addbyte(0xc0 | reg | (reg << 3)); return reg; } -static int ZERO_EXTEND_L_B(int reg) +static inline int ZERO_EXTEND_L_B(int reg) { addbyte(0x0f); /*MOVZX regl, regb*/ addbyte(0xb6); addbyte(0xc0 | reg | (reg << 3)); return reg; } -static int ZERO_EXTEND_L_W(int reg) +static inline int ZERO_EXTEND_L_W(int reg) { addbyte(0x0f); /*MOVZX regl, regw*/ addbyte(0xb7); @@ -3493,21 +3493,21 @@ static int ZERO_EXTEND_L_W(int reg) return reg; } -static int SIGN_EXTEND_W_B(int reg) +static inline int SIGN_EXTEND_W_B(int reg) { addbyte(0x0f); /*MOVSX regl, regb*/ addbyte(0xbe); addbyte(0xc0 | reg | (reg << 3)); return reg; } -static int SIGN_EXTEND_L_B(int reg) +static inline int SIGN_EXTEND_L_B(int reg) { addbyte(0x0f); /*MOVSX regl, regb*/ addbyte(0xbe); addbyte(0xc0 | reg | (reg << 3)); return reg; } -static int SIGN_EXTEND_L_W(int reg) +static inline int SIGN_EXTEND_L_W(int reg) { addbyte(0x0f); /*MOVSX regl, regw*/ addbyte(0xbf); @@ -3515,12 +3515,12 @@ static int SIGN_EXTEND_L_W(int reg) return reg; } -static int COPY_REG(int src_reg) +static inline int COPY_REG(int src_reg) { return src_reg; } -static void SET_BITS(uintptr_t addr, uint32_t val) +static inline void SET_BITS(uintptr_t addr, uint32_t val) { if (val & ~0xff) { @@ -3537,7 +3537,7 @@ static void SET_BITS(uintptr_t addr, uint32_t val) addbyte(val); } } -static void CLEAR_BITS(uintptr_t addr, uint32_t val) +static inline void CLEAR_BITS(uintptr_t addr, uint32_t val) { if (val & ~0xff) { @@ -3558,7 +3558,7 @@ static void CLEAR_BITS(uintptr_t addr, uint32_t val) #define LOAD_Q_REG_1 REG_EAX #define LOAD_Q_REG_2 REG_EDX -static void MMX_ENTER() +static inline void MMX_ENTER() { if (codegen_mmx_entered) return; @@ -3571,7 +3571,7 @@ static void MMX_ENTER() addbyte(7+7+5+5); addbyte(0xC7); /*MOVL [oldpc],op_old_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(oldpc)); + addbyte((uint8_t)cpu_state_offset(oldpc)); addlong(op_old_pc); addbyte(0xc7); /*MOV [ESP], 7*/ addbyte(0x04); @@ -3586,35 +3586,35 @@ static void MMX_ENTER() addbyte(0xc0); addbyte(0xc6); /*MOV ISMMX, 1*/ addbyte(0x45); - addbyte(cpu_state_offset(ismmx)); + addbyte((uint8_t)cpu_state_offset(ismmx)); addbyte(1); addbyte(0x89); /*MOV TOP, EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(TOP)); + addbyte((uint8_t)cpu_state_offset(TOP)); addbyte(0x89); /*MOV tag, EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[0])); + addbyte((uint8_t)cpu_state_offset(tag[0])); addbyte(0x89); /*MOV tag+4, EAX*/ addbyte(0x45); - addbyte(cpu_state_offset(tag[4])); + addbyte((uint8_t)cpu_state_offset(tag[4])); codegen_mmx_entered = 1; } extern int mmx_ebx_ecx_loaded; -static int LOAD_MMX_D(int guest_reg) +static inline int LOAD_MMX_D(int guest_reg) { int host_reg = find_host_reg(); host_reg_mapping[host_reg] = 100; addbyte(0x8b); /*MOV EBX, reg*/ addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); return host_reg; } -static int LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) +static inline void LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) { if (!mmx_ebx_ecx_loaded) { @@ -3630,12 +3630,12 @@ static int LOAD_MMX_Q(int guest_reg, int *host_reg1, int *host_reg2) addbyte(0x8b); /*MOV EBX, reg*/ addbyte(0x45 | ((*host_reg1) << 3)); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); addbyte(0x8b); /*MOV ECX, reg+4*/ addbyte(0x45 | ((*host_reg2) << 3)); - addbyte(cpu_state_offset(MM[guest_reg].l[1])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); } -static int LOAD_MMX_Q_MMX(int guest_reg) +static inline int LOAD_MMX_Q_MMX(int guest_reg) { int dst_reg = find_host_xmm_reg(); host_reg_xmm_mapping[dst_reg] = guest_reg; @@ -3644,12 +3644,12 @@ static int LOAD_MMX_Q_MMX(int guest_reg) addbyte(0x0f); addbyte(0x7e); addbyte(0x45 | (dst_reg << 3)); - addbyte(cpu_state_offset(MM[guest_reg].q)); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); return dst_reg; } -static int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) +static inline int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) { int dst_reg = find_host_xmm_reg(); host_reg_xmm_mapping[dst_reg] = 100; @@ -3670,36 +3670,36 @@ static int LOAD_INT_TO_MMX(int src_reg1, int src_reg2) return dst_reg; } -static void STORE_MMX_LQ(int guest_reg, int host_reg1) +static inline void STORE_MMX_LQ(int guest_reg, int host_reg1) { addbyte(0xC7); /*MOVL [reg],0*/ addbyte(0x45); - addbyte(cpu_state_offset(MM[guest_reg].l[1])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); addlong(0); addbyte(0x89); /*MOVL [reg],host_reg*/ addbyte(0x45 | (host_reg1 << 3)); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); } -static void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) +static inline void STORE_MMX_Q(int guest_reg, int host_reg1, int host_reg2) { addbyte(0x89); /*MOVL [reg],host_reg*/ addbyte(0x45 | (host_reg1 << 3)); - addbyte(cpu_state_offset(MM[guest_reg].l[0])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[0])); addbyte(0x89); /*MOVL [reg],host_reg*/ addbyte(0x45 | (host_reg2 << 3)); - addbyte(cpu_state_offset(MM[guest_reg].l[1])); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].l[1])); } -static void STORE_MMX_Q_MMX(int guest_reg, int host_reg) +static inline void STORE_MMX_Q_MMX(int guest_reg, int host_reg) { addbyte(0x66); /*MOVQ [guest_reg],host_reg*/ addbyte(0x0f); addbyte(0xd6); addbyte(0x45 | (host_reg << 3)); - addbyte(cpu_state_offset(MM[guest_reg].q)); + addbyte((uint8_t)cpu_state_offset(MM[guest_reg].q)); } #define MMX_x86_OP(name, opcode) \ -static void MMX_ ## name(int dst_reg, int src_reg) \ +static inline void MMX_ ## name(int dst_reg, int src_reg) \ { \ addbyte(0x66); /*op dst_reg, src_reg*/ \ addbyte(0x0f); \ @@ -3728,31 +3728,31 @@ MMX_x86_OP(SUBSW, 0xe9) MMX_x86_OP(SUBUSB, 0xd8) MMX_x86_OP(SUBUSW, 0xd9) -MMX_x86_OP(PUNPCKLBW, 0x60) -MMX_x86_OP(PUNPCKLWD, 0x61) -MMX_x86_OP(PUNPCKLDQ, 0x62) -MMX_x86_OP(PCMPGTB, 0x64) -MMX_x86_OP(PCMPGTW, 0x65) -MMX_x86_OP(PCMPGTD, 0x66) +MMX_x86_OP(PUNPCKLBW, 0x60); +MMX_x86_OP(PUNPCKLWD, 0x61); +MMX_x86_OP(PUNPCKLDQ, 0x62); +MMX_x86_OP(PCMPGTB, 0x64); +MMX_x86_OP(PCMPGTW, 0x65); +MMX_x86_OP(PCMPGTD, 0x66); -MMX_x86_OP(PCMPEQB, 0x74) -MMX_x86_OP(PCMPEQW, 0x75) -MMX_x86_OP(PCMPEQD, 0x76) +MMX_x86_OP(PCMPEQB, 0x74); +MMX_x86_OP(PCMPEQW, 0x75); +MMX_x86_OP(PCMPEQD, 0x76); -MMX_x86_OP(PSRLW, 0xd1) -MMX_x86_OP(PSRLD, 0xd2) -MMX_x86_OP(PSRLQ, 0xd3) -MMX_x86_OP(PSRAW, 0xe1) -MMX_x86_OP(PSRAD, 0xe2) -MMX_x86_OP(PSLLW, 0xf1) -MMX_x86_OP(PSLLD, 0xf2) -MMX_x86_OP(PSLLQ, 0xf3) +MMX_x86_OP(PSRLW, 0xd1); +MMX_x86_OP(PSRLD, 0xd2); +MMX_x86_OP(PSRLQ, 0xd3); +MMX_x86_OP(PSRAW, 0xe1); +MMX_x86_OP(PSRAD, 0xe2); +MMX_x86_OP(PSLLW, 0xf1); +MMX_x86_OP(PSLLD, 0xf2); +MMX_x86_OP(PSLLQ, 0xf3); -MMX_x86_OP(PMULLW, 0xd5) -MMX_x86_OP(PMULHW, 0xe5) -MMX_x86_OP(PMADDWD, 0xf5) +MMX_x86_OP(PMULLW, 0xd5); +MMX_x86_OP(PMULHW, 0xe5); +MMX_x86_OP(PMADDWD, 0xf5); -static void MMX_PACKSSWB(int dst_reg, int src_reg) +static inline void MMX_PACKSSWB(int dst_reg, int src_reg) { addbyte(0x66); /*PACKSSWB dst_reg, src_reg*/ addbyte(0x0f); @@ -3764,7 +3764,7 @@ static void MMX_PACKSSWB(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x08); } -static void MMX_PACKUSWB(int dst_reg, int src_reg) +static inline void MMX_PACKUSWB(int dst_reg, int src_reg) { addbyte(0x66); /*PACKUSWB dst_reg, src_reg*/ addbyte(0x0f); @@ -3776,7 +3776,7 @@ static void MMX_PACKUSWB(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x08); } -static void MMX_PACKSSDW(int dst_reg, int src_reg) +static inline void MMX_PACKSSDW(int dst_reg, int src_reg) { addbyte(0x66); /*PACKSSDW dst_reg, src_reg*/ addbyte(0x0f); @@ -3788,7 +3788,7 @@ static void MMX_PACKSSDW(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x08); } -static void MMX_PUNPCKHBW(int dst_reg, int src_reg) +static inline void MMX_PUNPCKHBW(int dst_reg, int src_reg) { addbyte(0x66); /*PUNPCKLBW dst_reg, src_reg*/ addbyte(0x0f); @@ -3800,7 +3800,7 @@ static void MMX_PUNPCKHBW(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x0e); } -static void MMX_PUNPCKHWD(int dst_reg, int src_reg) +static inline void MMX_PUNPCKHWD(int dst_reg, int src_reg) { addbyte(0x66); /*PUNPCKLWD dst_reg, src_reg*/ addbyte(0x0f); @@ -3812,7 +3812,7 @@ static void MMX_PUNPCKHWD(int dst_reg, int src_reg) addbyte(0xc0 | (dst_reg << 3) | dst_reg); addbyte(0x0e); } -static void MMX_PUNPCKHDQ(int dst_reg, int src_reg) +static inline void MMX_PUNPCKHDQ(int dst_reg, int src_reg) { addbyte(0x66); /*PUNPCKLDQ dst_reg, src_reg*/ addbyte(0x0f); @@ -3825,7 +3825,7 @@ static void MMX_PUNPCKHDQ(int dst_reg, int src_reg) addbyte(0x0e); } -static void MMX_PSRLW_imm(int dst_reg, int amount) +static inline void MMX_PSRLW_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRLW dst_reg, amount*/ addbyte(0x0f); @@ -3833,7 +3833,7 @@ static void MMX_PSRLW_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x10); addbyte(amount); } -static void MMX_PSRAW_imm(int dst_reg, int amount) +static inline void MMX_PSRAW_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRAW dst_reg, amount*/ addbyte(0x0f); @@ -3841,7 +3841,7 @@ static void MMX_PSRAW_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x20); addbyte(amount); } -static void MMX_PSLLW_imm(int dst_reg, int amount) +static inline void MMX_PSLLW_imm(int dst_reg, int amount) { addbyte(0x66); /*PSLLW dst_reg, amount*/ addbyte(0x0f); @@ -3850,7 +3850,7 @@ static void MMX_PSLLW_imm(int dst_reg, int amount) addbyte(amount); } -static void MMX_PSRLD_imm(int dst_reg, int amount) +static inline void MMX_PSRLD_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRLD dst_reg, amount*/ addbyte(0x0f); @@ -3858,7 +3858,7 @@ static void MMX_PSRLD_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x10); addbyte(amount); } -static void MMX_PSRAD_imm(int dst_reg, int amount) +static inline void MMX_PSRAD_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRAD dst_reg, amount*/ addbyte(0x0f); @@ -3866,7 +3866,7 @@ static void MMX_PSRAD_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x20); addbyte(amount); } -static void MMX_PSLLD_imm(int dst_reg, int amount) +static inline void MMX_PSLLD_imm(int dst_reg, int amount) { addbyte(0x66); /*PSLLD dst_reg, amount*/ addbyte(0x0f); @@ -3875,7 +3875,7 @@ static void MMX_PSLLD_imm(int dst_reg, int amount) addbyte(amount); } -static void MMX_PSRLQ_imm(int dst_reg, int amount) +static inline void MMX_PSRLQ_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRLQ dst_reg, amount*/ addbyte(0x0f); @@ -3883,7 +3883,7 @@ static void MMX_PSRLQ_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x10); addbyte(amount); } -static void MMX_PSRAQ_imm(int dst_reg, int amount) +static inline void MMX_PSRAQ_imm(int dst_reg, int amount) { addbyte(0x66); /*PSRAQ dst_reg, amount*/ addbyte(0x0f); @@ -3891,7 +3891,7 @@ static void MMX_PSRAQ_imm(int dst_reg, int amount) addbyte(0xc0 | dst_reg | 0x20); addbyte(amount); } -static void MMX_PSLLQ_imm(int dst_reg, int amount) +static inline void MMX_PSLLQ_imm(int dst_reg, int amount) { addbyte(0x66); /*PSLLQ dst_reg, amount*/ addbyte(0x0f); @@ -3901,14 +3901,14 @@ static void MMX_PSLLQ_imm(int dst_reg, int amount) } -static void SAVE_EA() +static inline void SAVE_EA() { addbyte(0x89); /*MOV [ESP+12], EAX*/ addbyte(0x44); addbyte(0x24); addbyte(12); } -static void LOAD_EA() +static inline void LOAD_EA() { addbyte(0x8b); /*MOV EAX, [ESP+12]*/ addbyte(0x44); @@ -3917,7 +3917,7 @@ static void LOAD_EA() } #define MEM_CHECK_WRITE_B MEM_CHECK_WRITE -static void MEM_CHECK_WRITE(x86seg *seg) +static inline void MEM_CHECK_WRITE(x86seg *seg) { CHECK_SEG_WRITE(seg); if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) @@ -3935,7 +3935,7 @@ static void MEM_CHECK_WRITE(x86seg *seg) addlong(mem_check_write - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); } -static void MEM_CHECK_WRITE_W(x86seg *seg) +static inline void MEM_CHECK_WRITE_W(x86seg *seg) { CHECK_SEG_WRITE(seg); if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) @@ -3953,7 +3953,7 @@ static void MEM_CHECK_WRITE_W(x86seg *seg) addlong(mem_check_write_w - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); LOAD_EA(); } -static void MEM_CHECK_WRITE_L(x86seg *seg) +static inline void MEM_CHECK_WRITE_L(x86seg *seg) { CHECK_SEG_WRITE(seg); if ((seg == &_ds && codegen_flat_ds) || (seg == &_ss && codegen_flat_ss)) @@ -3972,7 +3972,7 @@ static void MEM_CHECK_WRITE_L(x86seg *seg) LOAD_EA(); } -static void LOAD_SEG(int host_reg, void *seg) +static inline void LOAD_SEG(int host_reg, void *seg) { addbyte(0xc7); /*MOV [ESP+4], seg*/ addbyte(0x44); @@ -3982,10 +3982,10 @@ static void LOAD_SEG(int host_reg, void *seg) addbyte(0x89); /*MOV [ESP], host_reg*/ addbyte(0x04 | (host_reg << 3)); addbyte(0x24); - CALL_FUNC(loadseg); + CALL_FUNC((uintptr_t)loadseg); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE end*/ addbyte(0x85); diff --git a/src/CPU/codegen_timing_686.c b/src/CPU/codegen_timing_686.c index eab10357b..550c7e231 100644 --- a/src/CPU/codegen_timing_686.c +++ b/src/CPU/codegen_timing_686.c @@ -7,12 +7,13 @@ - FPU queue - Out of order execution (beyond most simplistic approximation) */ + #include "../ibm.h" -#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" +#include "../mem.h" #include "codegen.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ @@ -818,7 +819,7 @@ static uint32_t opcode_timings_8x[8] = static int decode_delay; static uint8_t last_prefix; -static __inline int COUNT(uint32_t c, int op_32) +static inline int COUNT(uint32_t c, int op_32) { if (c & CYCLES_HAS_MULTI) { @@ -854,7 +855,7 @@ void codegen_timing_686_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_686_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { - int *timings; + uint32_t *timings; int mod3 = ((fetchdat & 0xc0) == 0xc0); int bit8 = !(opcode & 1); diff --git a/src/CPU/codegen_timing_pentium.c b/src/CPU/codegen_timing_pentium.c index 2812e63ae..e5e4ed13d 100644 --- a/src/CPU/codegen_timing_pentium.c +++ b/src/CPU/codegen_timing_pentium.c @@ -8,12 +8,13 @@ - FPU latencies - MMX latencies */ + #include "../ibm.h" -#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_ops.h" #include "x87.h" +#include "../mem.h" #include "codegen.h" /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ @@ -818,7 +819,7 @@ static uint32_t opcode_timings_8x[8] = static int decode_delay; static uint8_t last_prefix; -static __inline int COUNT(uint32_t c, int op_32) +static inline int COUNT(uint32_t c, int op_32) { if (c & CYCLES_HAS_MULTI) { @@ -886,7 +887,7 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { - int *timings; + uint32_t *timings; int mod3 = ((fetchdat & 0xc0) == 0xc0); int bit8 = !(opcode & 1); diff --git a/src/CPU/codegen_x86.c b/src/CPU/codegen_x86.c index 50fa7bc35..f747fd262 100644 --- a/src/CPU/codegen_x86.c +++ b/src/CPU/codegen_x86.c @@ -1,12 +1,13 @@ #if defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32 + #include #include "../ibm.h" -#include "../mem.h" #include "cpu.h" #include "x86.h" #include "x86_flags.h" #include "x86_ops.h" #include "x87.h" +#include "../mem.h" #include "386_common.h" @@ -115,7 +116,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B() addbyte(8); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*MOVZX EAX, AL*/ addbyte(0xb6); @@ -170,7 +171,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W() addbyte(8); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*MOVZX EAX, AX*/ addbyte(0xb7); @@ -224,7 +225,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L() addbyte(8); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -279,7 +280,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_Q() addbyte(8); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -327,7 +328,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B() addbyte(12); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -381,7 +382,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W() addbyte(12); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -434,7 +435,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L() addbyte(12); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -492,7 +493,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_Q() addbyte(16); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -543,7 +544,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_B_NO_ABRT() #ifndef RELEASE_BUILD addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); #endif addbyte(0x0f); /*MOVZX ECX, AL*/ @@ -612,7 +613,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_W_NO_ABRT() #ifndef RELEASE_BUILD addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); #endif addbyte(0x0f); /*MOVZX ECX, AX*/ @@ -658,7 +659,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() addbyte(0x14); addbyte(0x95); addlong((uint32_t)readlookup2); - addbyte(0x75); /*JNE slowpath*/ + addbyte(0x75); /*JE slowpath*/ addbyte(3+2+3+1); addbyte(0x83); /*CMP EDX, -1*/ addbyte(0xfa); @@ -682,7 +683,7 @@ static uint32_t gen_MEM_LOAD_ADDR_EA_L_NO_ABRT() #ifndef RELEASE_BUILD addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x75); /*JNE mem_abrt_rout*/ addbyte(1); @@ -745,7 +746,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_B_NO_ABRT() #ifndef RELEASE_BUILD addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x75); /*JNE mem_abrt_rout*/ addbyte(1); @@ -811,7 +812,7 @@ static uint32_t gen_MEM_STORE_ADDR_EA_W_NO_ABRT() #ifndef RELEASE_BUILD addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x75); /*JNE mem_abrt_rout*/ addbyte(1); @@ -876,17 +877,17 @@ static uint32_t gen_MEM_STORE_ADDR_EA_L_NO_ABRT() #ifndef RELEASE_BUILD addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x75); /*JNE mem_abrt_rout*/ addbyte(1); #endif addbyte(0xc3); /*RET*/ #ifndef RELEASE_BUILD - addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err*/ + addbyte(0xc7); /*MOV [ESP], gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err*/ addbyte(0x04); addbyte(0x24); - addlong((uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT_err); + addlong((uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT_err); addbyte(0xe8); /*CALL fatal*/ addlong((uint32_t)fatal - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); /*Should not return!*/ @@ -941,7 +942,7 @@ static uint32_t gen_MEM_CHECK_WRITE() addbyte(8); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -1022,7 +1023,7 @@ static uint32_t gen_MEM_CHECK_WRITE_W() addbyte(1); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -1104,7 +1105,7 @@ static uint32_t gen_MEM_CHECK_WRITE_L() addbyte(3); addbyte(0x80); /*CMP abrt, 0*/ addbyte(0x7d); - addbyte(cpu_state_offset(abrt)); + addbyte((uint8_t)cpu_state_offset(abrt)); addbyte(0); addbyte(0x0f); /*JNE mem_abrt_rout*/ addbyte(0x85); @@ -1122,7 +1123,6 @@ static uint32_t gen_MEM_CHECK_WRITE_L() void codegen_init() { - int c; #ifdef __linux__ void *start; size_t len; @@ -1149,7 +1149,6 @@ void codegen_init() exit(-1); } #endif - /* pclog("Codegen is %p\n", (void *)pages[0xfab12 >> 12].block); */ block_current = BLOCK_SIZE; block_pos = 0; @@ -1163,50 +1162,44 @@ void codegen_init() addbyte(0x5b); /*POP EDX*/ addbyte(0xC3); /*RET*/ block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l = gen_MEM_LOAD_ADDR_EA_L(); + mem_load_addr_ea_l = (uint32_t)gen_MEM_LOAD_ADDR_EA_L(); block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w = gen_MEM_LOAD_ADDR_EA_W(); + mem_load_addr_ea_w = (uint32_t)gen_MEM_LOAD_ADDR_EA_W(); block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b = gen_MEM_LOAD_ADDR_EA_B(); + mem_load_addr_ea_b = (uint32_t)gen_MEM_LOAD_ADDR_EA_B(); block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_q = gen_MEM_LOAD_ADDR_EA_Q(); + mem_load_addr_ea_q = (uint32_t)gen_MEM_LOAD_ADDR_EA_Q(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l = gen_MEM_STORE_ADDR_EA_L(); + mem_store_addr_ea_l = (uint32_t)gen_MEM_STORE_ADDR_EA_L(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w = gen_MEM_STORE_ADDR_EA_W(); + mem_store_addr_ea_w = (uint32_t)gen_MEM_STORE_ADDR_EA_W(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b = gen_MEM_STORE_ADDR_EA_B(); + mem_store_addr_ea_b = (uint32_t)gen_MEM_STORE_ADDR_EA_B(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_q = gen_MEM_STORE_ADDR_EA_Q(); + mem_store_addr_ea_q = (uint32_t)gen_MEM_STORE_ADDR_EA_Q(); block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_b_no_abrt = gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); + mem_load_addr_ea_b_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_B_NO_ABRT(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_b_no_abrt = gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); + mem_store_addr_ea_b_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_B_NO_ABRT(); block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_w_no_abrt = gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); + mem_load_addr_ea_w_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_W_NO_ABRT(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_w_no_abrt = gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); + mem_store_addr_ea_w_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_W_NO_ABRT(); block_pos = (block_pos + 15) & ~15; - mem_load_addr_ea_l_no_abrt = gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); + mem_load_addr_ea_l_no_abrt = (uint32_t)gen_MEM_LOAD_ADDR_EA_L_NO_ABRT(); block_pos = (block_pos + 15) & ~15; - mem_store_addr_ea_l_no_abrt = gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); + mem_store_addr_ea_l_no_abrt = (uint32_t)gen_MEM_STORE_ADDR_EA_L_NO_ABRT(); block_pos = (block_pos + 15) & ~15; - mem_check_write = gen_MEM_CHECK_WRITE(); + mem_check_write = (uint32_t)gen_MEM_CHECK_WRITE(); block_pos = (block_pos + 15) & ~15; - mem_check_write_w = gen_MEM_CHECK_WRITE_W(); + mem_check_write_w = (uint32_t)gen_MEM_CHECK_WRITE_W(); block_pos = (block_pos + 15) & ~15; - mem_check_write_l = gen_MEM_CHECK_WRITE_L(); + mem_check_write_l = (uint32_t)gen_MEM_CHECK_WRITE_L(); -#ifdef __MSC__ - __asm { - fstcw cpu_state.old_npxc - } -#else - __asm( + asm( "fstcw %0\n" : "=m" (cpu_state.old_npxc) ); -#endif } void codegen_reset() @@ -1218,6 +1211,20 @@ void codegen_reset() void dump_block() { +/* codeblock_t *block = pages[0x119000 >> 12].block; + + pclog("dump_block:\n"); + while (block) + { + uint32_t start_pc = (block->pc & 0xffc) | (block->phys & ~0xfff); + uint32_t end_pc = (block->endpc & 0xffc) | (block->phys & ~0xfff); + pclog(" %p : %08x-%08x %08x-%08x %p %p\n", (void *)block, start_pc, end_pc, block->pc, block->endpc, (void *)block->prev, (void *)block->next); + if (!block->pc) + fatal("Dead PC=0\n"); + + block = block->next; + } + pclog("dump_block done\n");*/ } static void add_to_block_list(codeblock_t *block) @@ -1297,7 +1304,6 @@ static void remove_from_block_list(codeblock_t *block, uint32_t pc) } else { - /* pclog(" pages.block_2=%p 3 %p %p\n", (void *)block->next_2, (void *)block, (void *)pages[block->phys_2 >> 12].block_2); */ pages[block->phys_2 >> 12].block_2[(block->phys_2 >> 10) & 3] = block->next_2; if (block->next_2) block->next_2->prev_2 = NULL; @@ -1355,7 +1361,6 @@ void codegen_check_flush(page_t *page, uint64_t mask, uint32_t phys_addr) void codegen_block_init(uint32_t phys_addr) { codeblock_t *block; - int has_evicted = 0; page_t *page = &pages[phys_addr >> 12]; if (!page->block[(phys_addr >> 10) & 3]) @@ -1366,7 +1371,6 @@ void codegen_block_init(uint32_t phys_addr) if (block->pc != 0) { - /* pclog("Reuse block : was %08x now %08x\n", block->pc, cs+pc); */ delete_block(block); cpu_recomp_reuse++; } @@ -1384,7 +1388,7 @@ void codegen_block_init(uint32_t phys_addr) block->next_2 = block->prev_2 = NULL; block->page_mask = 0; block->flags = CODEBLOCK_STATIC_TOP; - block->status = cpu_cur_status; + block->status = cpu_cur_status; block->was_recompiled = 0; @@ -1395,7 +1399,6 @@ void codegen_block_init(uint32_t phys_addr) void codegen_block_start_recompile(codeblock_t *block) { - int has_evicted = 0; page_t *page = &pages[block->phys >> 12]; if (!page->block[(block->phys >> 10) & 3]) @@ -1440,8 +1443,6 @@ void codegen_block_start_recompile(codeblock_t *block) addbyte(0xBD); /*MOVL EBP, &cpu_state*/ addlong(((uintptr_t)&cpu_state) + 128); - /* pclog("New block %i for %08X %03x\n", block_current, cs+pc, block_num); */ - last_op32 = -1; last_ea_seg = NULL; last_ssegs = -1; @@ -1499,11 +1500,9 @@ void codegen_block_generate_end_mask() start_pc >>= PAGE_MASK_SHIFT; end_pc >>= PAGE_MASK_SHIFT; - /* pclog("block_end: %08x %08x\n", start_pc, end_pc); */ for (; start_pc <= end_pc; start_pc++) { block->page_mask |= ((uint64_t)1 << start_pc); - /* pclog(" %08x %llx\n", start_pc, block->page_mask); */ } pages[block->phys >> 12].code_present_mask[(block->phys >> 10) & 3] |= block->page_mask; @@ -1531,7 +1530,6 @@ void codegen_block_generate_end_mask() fatal("!page_mask2\n"); if (block->next_2) { - /* pclog(" next_2->pc=%08x\n", block->next_2->pc); */ if (!block->next_2->pc) fatal("block->next_2->pc=0 %p\n", (void *)block->next_2); } @@ -1540,7 +1538,6 @@ void codegen_block_generate_end_mask() } } - /* pclog("block_end: %08x %08x %016llx\n", block->pc, block->endpc, block->page_mask); */ recomp_page = -1; } @@ -1560,14 +1557,14 @@ void codegen_block_end_recompile(codeblock_t *block) { addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addlong(codegen_block_cycles); } if (codegen_block_ins) { addbyte(0x81); /*ADD $codegen_block_ins,ins*/ addbyte(0x45); - addbyte(cpu_state_offset(cpu_recomp_ins)); + addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); addlong(codegen_block_ins); } #if 0 @@ -1596,7 +1593,6 @@ void codegen_block_end_recompile(codeblock_t *block) block->next_2 = block->prev_2 = NULL; codegen_block_generate_end_mask(); add_to_block_list(block); - /* pclog("End block %i\n", block_num); */ if (!(block->flags & CODEBLOCK_HAS_FPU)) block->flags &= ~CODEBLOCK_STATIC_TOP; @@ -1607,29 +1603,6 @@ void codegen_flush() return; } -static int opcode_conditional_jump[256] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, /*00*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*10*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*20*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*30*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*40*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*50*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*60*/ - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*90*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*a0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*b0*/ - - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*d0*/ - 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*e0*/ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*f0*/ -}; - static int opcode_modrm[256] = { 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, /*00*/ @@ -1666,7 +1639,7 @@ int opcode_0f_modrm[256] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*80*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ - 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, /*a0*/ + 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /*a0*/ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, /*b0*/ 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /*c0*/ @@ -1689,7 +1662,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, { addbyte(0xC7); /*MOVL $0,(ssegs)*/ addbyte(0x45); - addbyte(cpu_state_offset(eaaddr)); + addbyte((uint8_t)cpu_state_offset(eaaddr)); addlong((fetchdat >> 8) & 0xffff); (*op_pc) += 2; } @@ -1706,7 +1679,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, break; case 1: addbyte(0xb8); /*MOVL ,%eax*/ - addlong((uint32_t)(int8_t)(rmdat >> 8)); /* pc++; */ + addlong((uint32_t)(int8_t)(rmdat >> 8)); addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ addbyte(0x05); addlong((uint32_t)mod1add[0][cpu_rm]); @@ -1717,7 +1690,7 @@ static x86seg *codegen_generate_ea_16_long(x86seg *op_ea_seg, uint32_t fetchdat, break; case 2: addbyte(0xb8); /*MOVL ,%eax*/ - addlong((fetchdat >> 8) & 0xffff); /* pc++; */ + addlong((fetchdat >> 8) & 0xffff); addbyte(0x03); /*ADDL *mod1add[0][cpu_rm], %eax*/ addbyte(0x05); addlong((uint32_t)mod1add[0][cpu_rm]); @@ -1754,14 +1727,14 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, { new_eaaddr = fastreadl(cs + (*op_pc) + 1); addbyte(0xb8); /*MOVL ,%eax*/ - addlong(new_eaaddr); /* pc++; */ + addlong(new_eaaddr); (*op_pc) += 4; } else { addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[sib & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); } break; case 1: @@ -1770,7 +1743,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, addlong(new_eaaddr); addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[sib & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); (*op_pc)++; break; case 2: @@ -1779,7 +1752,7 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, addlong(new_eaaddr); addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[sib & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[sib & 7].l)); (*op_pc) += 4; break; } @@ -1797,20 +1770,20 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, case 0: addbyte(0x03); /*ADDL regs[sib&7].l, %eax*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); + addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); break; case 1: - addbyte(0x8B); addbyte(0x5D); addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ break; case 2: - addbyte(0x8B); addbyte(0x5D); addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ addbyte(0xC1); addbyte(0xE3); addbyte(2); /*SHL $2,%ebx*/ addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ break; case 3: - addbyte(0x8B); addbyte(0x5D); addbyte(cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ + addbyte(0x8B); addbyte(0x5D); addbyte((uint8_t)cpu_state_offset(regs[(sib >> 3) & 7].l)); /*MOVL armregs[RD],%ebx*/ addbyte(0xC1); addbyte(0xE3); addbyte(3); /*SHL $2,%ebx*/ addbyte(0x01); addbyte(0xD8); /*ADDL %ebx,%eax*/ break; @@ -1826,18 +1799,14 @@ static x86seg *codegen_generate_ea_32_long(x86seg *op_ea_seg, uint32_t fetchdat, new_eaaddr = fastreadl(cs + (*op_pc) + 1); addbyte(0xC7); /*MOVL $new_eaaddr,(eaaddr)*/ addbyte(0x45); - addbyte(cpu_state_offset(eaaddr)); + addbyte((uint8_t)cpu_state_offset(eaaddr)); addlong(new_eaaddr); (*op_pc) += 4; return op_ea_seg; } addbyte(0x8b); /*MOVL regs[sib&7].l, %eax*/ addbyte(0x45); - addbyte(cpu_state_offset(regs[cpu_rm].l)); -#if 0 - addbyte(0xa1); /*MOVL regs[cpu_rm].l, %eax*/ - addlong((uint32_t)&cpu_state.regs[cpu_rm].l); -#endif + addbyte((uint8_t)cpu_state_offset(regs[cpu_rm].l)); cpu_state.eaaddr = cpu_state.regs[cpu_rm].l; if (cpu_mod) { @@ -2025,19 +1994,19 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t generate_call: codegen_timing_opcode(opcode, fetchdat, op_32); - + if ((op_table == x86_dynarec_opcodes && - ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || + ((opcode & 0xf0) == 0x70 || (opcode & 0xfc) == 0xe0 || opcode == 0xc2 || (opcode & 0xfe) == 0xca || (opcode & 0xfc) == 0xcc || (opcode & 0xfc) == 0xe8 || - (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30))) || - (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80)))) + (opcode == 0xff && ((fetchdat & 0x38) >= 0x10 && (fetchdat & 0x38) < 0x30)))) || + (op_table == x86_dynarec_opcodes_0f && ((opcode & 0xf0) == 0x80))) { /*Opcode is likely to cause block to exit, update cycle count*/ if (codegen_block_cycles) { addbyte(0x81); /*SUB $codegen_block_cycles, cyclcs*/ addbyte(0x6d); - addbyte(cpu_state_offset(_cycles)); + addbyte((uint8_t)cpu_state_offset(_cycles)); addlong(codegen_block_cycles); codegen_block_cycles = 0; } @@ -2045,7 +2014,7 @@ generate_call: { addbyte(0x81); /*ADD $codegen_block_ins,ins*/ addbyte(0x45); - addbyte(cpu_state_offset(cpu_recomp_ins)); + addbyte((uint8_t)cpu_state_offset(cpu_recomp_ins)); addlong(codegen_block_ins); codegen_block_ins = 0; } @@ -2079,17 +2048,13 @@ generate_call: } op = op_table[((opcode >> opcode_shift) | op_32) & opcode_mask]; -#if 0 - if (output) - pclog("Generate call at %08X %02X %08X %02X %08X %08X %08X %08X %08X %02X %02X %02X %02X\n", &codeblock[block_current][block_pos], opcode, new_pc, ram[old_pc], EAX, EBX, ECX, EDX, ESI, ram[0x7bd2+6],ram[0x7bd2+7],ram[0x7bd2+8],ram[0x7bd2+9]); -#endif if (op_ssegs != last_ssegs) { last_ssegs = op_ssegs; addbyte(0xC6); /*MOVB [ssegs],op_ssegs*/ addbyte(0x45); - addbyte(cpu_state_offset(ssegs)); + addbyte((uint8_t)cpu_state_offset(ssegs)); addbyte(op_pc + pc_off); } @@ -2108,7 +2073,7 @@ generate_call: addbyte(0xC7); /*MOVL $rm | mod | reg,(rm_mod_reg_data)*/ addbyte(0x45); - addbyte(cpu_state_offset(rm_data.rm_mod_reg_data)); + addbyte((uint8_t)cpu_state_offset(rm_data.rm_mod_reg_data)); addlong(cpu_rm | (cpu_mod << 8) | (cpu_reg << 16)); op_pc += pc_off; @@ -2124,18 +2089,18 @@ generate_call: last_ea_seg = op_ea_seg; addbyte(0xC7); /*MOVL $&_ds,(ea_seg)*/ addbyte(0x45); - addbyte(cpu_state_offset(ea_seg)); + addbyte((uint8_t)cpu_state_offset(ea_seg)); addlong((uint32_t)op_ea_seg); } addbyte(0xC7); /*MOVL pc,new_pc*/ addbyte(0x45); - addbyte(cpu_state_offset(pc)); + addbyte((uint8_t)cpu_state_offset(pc)); addlong(op_pc + pc_off); addbyte(0xC7); /*MOVL $old_pc,(oldpc)*/ addbyte(0x45); - addbyte(cpu_state_offset(oldpc)); + addbyte((uint8_t)cpu_state_offset(oldpc)); addlong(old_pc); if (op_32 != last_op32) @@ -2143,7 +2108,7 @@ generate_call: last_op32 = op_32; addbyte(0xC7); /*MOVL $use32,(op32)*/ addbyte(0x45); - addbyte(cpu_state_offset(op32)); + addbyte((uint8_t)cpu_state_offset(op32)); addlong(op_32); } @@ -2164,11 +2129,6 @@ generate_call: addbyte(0x0F); addbyte(0x85); /*JNZ 0*/ addlong((uint32_t)&block->data[BLOCK_EXIT_OFFSET] - (uint32_t)(&block->data[block_pos + 4])); -#if 0 - addbyte(0xE8); /*CALL*/ - addlong(((uint8_t *)codegen_debug - (uint8_t *)(&block->data[block_pos + 4]))); -#endif - codegen_endpc = (cs + cpu_state.pc) + 8; } diff --git a/src/CPU/x86_ops_call.h b/src/CPU/x86_ops_call.h index 6d27373f4..d1f61021c 100644 --- a/src/CPU/x86_ops_call.h +++ b/src/CPU/x86_ops_call.h @@ -61,7 +61,7 @@ static int opCALL_far_w(uint32_t fetchdat) { uint32_t old_cs, old_pc; uint16_t new_cs, new_pc; - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); new_pc = getwordf(); new_cs = getword(); if (cpu_state.abrt) return 1; @@ -77,7 +77,7 @@ static int opCALL_far_l(uint32_t fetchdat) { uint32_t old_cs, old_pc; uint32_t new_cs, new_pc; - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); new_pc = getlong(); new_cs = getword(); if (cpu_state.abrt) return 1; @@ -95,7 +95,7 @@ static int opFF_w_a16(uint32_t fetchdat) { uint16_t old_cs, new_cs; uint32_t old_pc, new_pc; - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); uint16_t temp; @@ -163,6 +163,7 @@ static int opFF_w_a16(uint32_t fetchdat) break; default: +// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; @@ -171,7 +172,7 @@ static int opFF_w_a32(uint32_t fetchdat) { uint16_t old_cs, new_cs; uint32_t old_pc, new_pc; - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); uint16_t temp; @@ -239,6 +240,7 @@ static int opFF_w_a32(uint32_t fetchdat) break; default: +// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; @@ -248,7 +250,7 @@ static int opFF_l_a16(uint32_t fetchdat) { uint16_t old_cs, new_cs; uint32_t old_pc, new_pc; - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); uint32_t temp; @@ -316,6 +318,7 @@ static int opFF_l_a16(uint32_t fetchdat) break; default: +// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; @@ -324,7 +327,7 @@ static int opFF_l_a32(uint32_t fetchdat) { uint16_t old_cs, new_cs; uint32_t old_pc, new_pc; - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); uint32_t temp; @@ -391,6 +394,7 @@ static int opFF_l_a32(uint32_t fetchdat) break; default: +// fatal("Bad FF opcode %02X\n",rmdat&0x38); x86illegal(); } return cpu_state.abrt; diff --git a/src/CPU/x86_ops_i686.h b/src/CPU/x86_ops_i686.h index 84a10c28b..a61d27025 100644 --- a/src/CPU/x86_ops_i686.h +++ b/src/CPU/x86_ops_i686.h @@ -166,6 +166,7 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) uint8_t ftwb = 0; uint16_t rec_ftw = 0; uint16_t fpus = 0; + uint64_t *p; if (CPUID < 0x650) return ILLEGAL(fetchdat); @@ -258,9 +259,10 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.ismmx = 0; /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times something like this is needed*/ + p = (uint64_t *)cpu_state.tag; if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) + !cpu_state.TOP && !(*p)) cpu_state.ismmx = 1; x87_settag(rec_ftw); @@ -321,7 +323,8 @@ static int opFXSAVESTOR_a16(uint32_t fetchdat) cpu_state.npxc = 0x37F; cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; - *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + p = (uint64_t *)cpu_state.tag; + *p = 0x0303030303030303ll; cpu_state.TOP = 0; cpu_state.ismmx = 0; @@ -341,6 +344,7 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) uint8_t ftwb = 0; uint16_t rec_ftw = 0; uint16_t fpus = 0; + uint64_t *p; if (CPUID < 0x650) return ILLEGAL(fetchdat); @@ -433,9 +437,10 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.ismmx = 0; /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times something like this is needed*/ + p = (uint64_t *)cpu_state.tag; if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) + !cpu_state.TOP && !(*p)) cpu_state.ismmx = 1; x87_settag(rec_ftw); @@ -496,7 +501,8 @@ static int opFXSAVESTOR_a32(uint32_t fetchdat) cpu_state.npxc = 0x37F; cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; - *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + p = (uint64_t *)cpu_state.tag; + *p = 0x0303030303030303ll; cpu_state.TOP = 0; cpu_state.ismmx = 0; diff --git a/src/CPU/x86_ops_int.h b/src/CPU/x86_ops_int.h index dafb1dde5..e488ae83a 100644 --- a/src/CPU/x86_ops_int.h +++ b/src/CPU/x86_ops_int.h @@ -1,6 +1,6 @@ static int opINT3(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); @@ -14,7 +14,7 @@ static int opINT3(uint32_t fetchdat) static int opINT1(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { x86gpf(NULL,0); @@ -28,7 +28,7 @@ static int opINT1(uint32_t fetchdat) static int opINT(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); uint8_t temp; /*if (msw&1) pclog("INT %i %i %i\n",cr0&1,eflags&VM_FLAG,IOPL);*/ @@ -38,6 +38,38 @@ static int opINT(uint32_t fetchdat) return 1; } temp = getbytef(); +// /*if (temp == 0x10 && AH == 0xe) */pclog("INT %02X : %04X %04X %04X %04X %c %04X:%04X\n", temp, AX, BX, CX, DX, (AL < 32) ? ' ' : AL, CS, pc); +// if (CS == 0x0028 && pc == 0xC03813C0) +// output = 3; +/* if (pc == 0x8028009A) + output = 3; + if (pc == 0x80282B6F) + { + __times++; + if (__times == 2) + fatal("WRONG\n"); + } + if (pc == 0x802809CE) + fatal("RIGHT\n");*/ +// if (CS == 0x0028 && pc == 0x80037FE9) +// output = 3; +//if (CS == 0x9087 && pc == 0x3763) +// fatal("Here\n"); +//if (CS==0x9087 && pc == 0x0850) +// output = 1; + +/* if (output && pc == 0x80033008) + { + __times++; + if (__times == 2) + fatal("WRONG\n"); + }*/ +/* if (output && pc == 0x80D8) + { + __times++; + if (__times == 2) + fatal("RIGHT\n"); + }*/ x86_int_sw(temp); PREFETCH_RUN(cycles_old-cycles, 2, -1, 0,0,0,0, 0); @@ -46,7 +78,7 @@ static int opINT(uint32_t fetchdat) static int opINTO(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { diff --git a/src/CPU/x86_ops_ret.h b/src/CPU/x86_ops_ret.h index 4f41a2049..0bc88e466 100644 --- a/src/CPU/x86_ops_ret.h +++ b/src/CPU/x86_ops_ret.h @@ -44,7 +44,7 @@ static int opRETF_a16(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); CPU_BLOCK_END(); RETF_a16(0); @@ -55,7 +55,7 @@ static int opRETF_a16(uint32_t fetchdat) } static int opRETF_a32(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); CPU_BLOCK_END(); RETF_a32(0); @@ -67,8 +67,8 @@ static int opRETF_a32(uint32_t fetchdat) static int opRETF_a16_imm(uint32_t fetchdat) { - int cycles_old = cycles; uint16_t offset = getwordf(); + int cycles_old = cycles; UNUSED(cycles_old); CPU_BLOCK_END(); RETF_a16(offset); @@ -79,8 +79,8 @@ static int opRETF_a16_imm(uint32_t fetchdat) } static int opRETF_a32_imm(uint32_t fetchdat) { - int cycles_old = cycles; uint16_t offset = getwordf(); + int cycles_old = cycles; UNUSED(cycles_old); CPU_BLOCK_END(); RETF_a32(offset); @@ -92,7 +92,7 @@ static int opRETF_a32_imm(uint32_t fetchdat) static int opIRET_286(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { @@ -137,7 +137,7 @@ static int opIRET_286(uint32_t fetchdat) static int opIRET(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { @@ -182,7 +182,7 @@ static int opIRET(uint32_t fetchdat) static int opIRETD(uint32_t fetchdat) { - int cycles_old = cycles; + int cycles_old = cycles; UNUSED(cycles_old); if ((cr0 & 1) && (eflags & VM_FLAG) && (IOPL != 3)) { diff --git a/src/CPU/x87_ops.h b/src/CPU/x87_ops.h index b9320081f..5af874826 100644 --- a/src/CPU/x87_ops.h +++ b/src/CPU/x87_ops.h @@ -54,14 +54,18 @@ static int rounding_modes[4] = {FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZ static __inline void x87_set_mmx() { + uint64_t *p; cpu_state.TOP = 0; - *(uint64_t *)cpu_state.tag = 0; + p = (uint64_t *)cpu_state.tag; + *p = 0; cpu_state.ismmx = 1; } static __inline void x87_emms() { - *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + uint64_t *p; + p = (uint64_t *)cpu_state.tag; + *p = 0x0303030303030303ll; cpu_state.ismmx = 0; } diff --git a/src/CPU/x87_ops_arith.h b/src/CPU/x87_ops_arith.h index 1313839bb..f53ad9213 100644 --- a/src/CPU/x87_ops_arith.h +++ b/src/CPU/x87_ops_arith.h @@ -165,11 +165,14 @@ static int opFCOMP(uint32_t fetchdat) static int opFCOMPP(uint32_t fetchdat) { + uint64_t *p, *q; FP_ENTER(); cpu_state.pc++; if (fplog) pclog("FCOMPP\n"); cpu_state.npxs &= ~(C0|C2|C3); - if ((*(uint64_t *)&ST(0) == ((uint64_t)1 << 63) && *(uint64_t *)&ST(1) == 0) && is386) + p = (uint64_t *)&ST(0); + q = (uint64_t *)&ST(1); + if ((*p == ((uint64_t)1 << 63) && *q == 0) && is386) cpu_state.npxs |= C0; /*Nasty hack to fix 80387 detection*/ else cpu_state.npxs |= x87_compare(ST(0), ST(1)); diff --git a/src/CPU/x87_ops_misc.h b/src/CPU/x87_ops_misc.h index 178261fd5..fd1cc3de6 100644 --- a/src/CPU/x87_ops_misc.h +++ b/src/CPU/x87_ops_misc.h @@ -29,12 +29,14 @@ static int opFCLEX(uint32_t fetchdat) static int opFINIT(uint32_t fetchdat) { + uint64_t *p; FP_ENTER(); cpu_state.pc++; cpu_state.npxc = 0x37F; cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; - *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + p = (uint64_t *)cpu_state.tag; + *p = 0x0303030303030303ll; cpu_state.TOP = 0; cpu_state.ismmx = 0; CLOCK_CYCLES(17); @@ -91,6 +93,7 @@ static int opFSTP(uint32_t fetchdat) static int FSTOR() { + uint64_t *p; FP_ENTER(); switch ((cr0 & 1) | (cpu_state.op32 & 0x100)) { @@ -125,9 +128,10 @@ static int FSTOR() cpu_state.ismmx = 0; /*Horrible hack, but as PCem doesn't keep the FPU stack in 80-bit precision at all times something like this is needed*/ + p = (uint64_t *)cpu_state.tag; if (cpu_state.MM_w4[0] == 0xffff && cpu_state.MM_w4[1] == 0xffff && cpu_state.MM_w4[2] == 0xffff && cpu_state.MM_w4[3] == 0xffff && cpu_state.MM_w4[4] == 0xffff && cpu_state.MM_w4[5] == 0xffff && cpu_state.MM_w4[6] == 0xffff && cpu_state.MM_w4[7] == 0xffff && - !cpu_state.TOP && !(*(uint64_t *)cpu_state.tag)) + !cpu_state.TOP && !(*p)) cpu_state.ismmx = 1; CLOCK_CYCLES((cr0 & 1) ? 34 : 44); @@ -151,6 +155,8 @@ static int opFSTOR_a32(uint32_t fetchdat) static int FSAVE() { + uint64_t *p; + FP_ENTER(); if (fplog) pclog("FSAVE %08X:%08X %i\n", easeg, cpu_state.eaaddr, cpu_state.ismmx); cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | (cpu_state.TOP << 11); @@ -287,7 +293,8 @@ static int FSAVE() cpu_state.npxc = 0x37F; cpu_state.new_npxc = (cpu_state.old_npxc & ~0xc00); cpu_state.npxs = 0; - *(uint64_t *)cpu_state.tag = 0x0303030303030303ll; + p = (uint64_t *)cpu_state.tag; + *p = 0x0303030303030303ll; cpu_state.TOP = 0; cpu_state.ismmx = 0; diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 900e874a9..f915f734c 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -102,7 +102,7 @@ else endif AFLAGS = -msse -msse2 -mfpmath=sse CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ - -fomit-frame-pointer -mstackrealign + -fomit-frame-pointer -mstackrealign -Wall RFLAGS = --input-format=rc -O coff ifeq ($(RELEASE), y) CFLAGS += -DRELEASE_BUILD diff --git a/src/NETWORK/net_ne2000.c b/src/NETWORK/net_ne2000.c index b9fb05a34..43eec0796 100644 --- a/src/NETWORK/net_ne2000.c +++ b/src/NETWORK/net_ne2000.c @@ -1591,8 +1591,8 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) val |= 0x01; /* re-enable IOIN bit */ /*FALLTHROUGH*/ - case 0x11: /* PCI_BAR - case 0x12: /* PCI_BAR + case 0x11: /* PCI_BAR */ + case 0x12: /* PCI_BAR */ case 0x13: /* PCI_BAR */ /* Remove old I/O. */ nic_ioremove(dev, dev->base_address); @@ -1819,6 +1819,11 @@ nic_rom_init(nic_t *dev, wchar_t *s) uint32_t temp; FILE *f; + if (s == NULL) + { + return; + } + if (dev->bios_addr > 0) { if ((f = romfopen(s, L"rb")) != NULL) { fseek(f, 0L, SEEK_END); @@ -1864,6 +1869,7 @@ nic_init(int board) dev = malloc(sizeof(nic_t)); memset(dev, 0x00, sizeof(nic_t)); dev->board = board; + rom = NULL; switch(dev->board) { case NE2K_NE1000: strcpy(dev->name, "NE1000"); diff --git a/src/NETWORK/net_slirp.c b/src/NETWORK/net_slirp.c index 89c8eb1ac..514845fdb 100644 --- a/src/NETWORK/net_slirp.c +++ b/src/NETWORK/net_slirp.c @@ -67,7 +67,6 @@ slirp_tic(void) static void poll_thread(void *arg) { - uint8_t *mac = (uint8_t *)arg; struct queuepacket *qp; event_t *evt; @@ -112,8 +111,6 @@ poll_thread(void *arg) int network_slirp_setup(uint8_t *mac, NETRXCB func, void *arg) { - int rc; - pclog("SLiRP: initializing..\n"); if (slirp_init() != 0) { diff --git a/src/NETWORK/network.c b/src/NETWORK/network.c index 679eaf721..87d2613ac 100644 --- a/src/NETWORK/network.c +++ b/src/NETWORK/network.c @@ -153,8 +153,6 @@ network_close(void) void network_reset(void) { - int i = 0; - pclog("NETWORK: reset (type=%d, card=%d)\n", network_type, network_card); /* Just in case.. */ diff --git a/src/NETWORK/pcap_if.c b/src/NETWORK/pcap_if.c index 3cf321a9d..31ec33f7d 100644 --- a/src/NETWORK/pcap_if.c +++ b/src/NETWORK/pcap_if.c @@ -90,7 +90,7 @@ hex_dump(unsigned char *bufp, int len) while (len-- > 0) { c = bufp[addr]; if ((addr % 16) == 0) - printf("%04x %02x", addr, c); + printf("%04lx %02x", addr, c); else printf(" %02x", c); asci[(addr & 15)] = (uint8_t)isprint(c) ? c : '.'; @@ -175,7 +175,7 @@ start_cap(char *dev) strftime(temp, sizeof(temp), "%H:%M:%S", ltime); /* Process and print the packet. */ - printf("\n<< %s,%.6d len=%d\n", + printf("\n<< %s,%.6ld len=%u\n", temp, hdr->ts.tv_usec, hdr->len); rc = eth_prhdr((unsigned char *)pkt); hex_dump((unsigned char *)pkt+rc, hdr->len-rc); @@ -227,7 +227,6 @@ int main(int argc, char **argv) { dev_t interfaces[32]; - dev_t *dev = interfaces; int numdev, i; /* Try loading the DLL. */ diff --git a/src/SOUND/dbopl.cpp b/src/SOUND/dbopl.cpp index b5d4bfe65..e8002b7cf 100644 --- a/src/SOUND/dbopl.cpp +++ b/src/SOUND/dbopl.cpp @@ -869,6 +869,9 @@ Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { return (this + 2); } break; + case sm2Percussion: + case sm3Percussion: + break; } //Init the operators with the the current vibrato and tremolo values Op( 0 )->Prepare( chip ); @@ -940,6 +943,9 @@ Channel* Channel::BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output ) { output[ i * 2 + 0 ] += sample & maskLeft; output[ i * 2 + 1 ] += sample & maskRight; break; + case sm2Percussion: + case sm3Percussion: + break; } } switch( mode ) { diff --git a/src/VIDEO/vid_ega_render.c b/src/VIDEO/vid_ega_render.c index bd4b6a358..eea08992b 100644 --- a/src/VIDEO/vid_ega_render.c +++ b/src/VIDEO/vid_ega_render.c @@ -180,17 +180,15 @@ void ega_jega_render_blit_text(ega_t *ega, int x, int dl, int start, int width, void ega_render_text_jega(ega_t *ega, int drawcursor) { - int x_add = (enable_overscan) ? 8 : 0; int dl = ega_display_line(ega); uint8_t chr, attr; - uint16_t dat, dat2; - uint32_t charaddr; - int x, xx; - uint32_t fg, bg; + uint16_t dat = 0, dat2; + int x; + uint32_t fg = 0, bg = 0; /* Temporary for DBCS. */ - unsigned int chr_left; - unsigned int bsattr; + unsigned int chr_left = 0; + unsigned int bsattr = 0; int chr_wide = 0; uint32_t bg_ex = 0; uint32_t fg_ex = 0; @@ -208,7 +206,7 @@ void ega_render_text_jega(ega_t *ega, int drawcursor) chr = ega->vram[(ega->ma << 1) & ega->vrammask]; attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; - if (chr_wide = 0) + if (chr_wide == 0) { if (ega->RMOD2 & 0x80) { diff --git a/src/VIDEO/vid_et4000w32.c b/src/VIDEO/vid_et4000w32.c index 254fe8072..d0a2b1e90 100644 --- a/src/VIDEO/vid_et4000w32.c +++ b/src/VIDEO/vid_et4000w32.c @@ -212,7 +212,6 @@ uint8_t et4000w32p_in(uint16_t addr, void *p) { et4000w32p_t *et4000 = (et4000w32p_t *)p; svga_t *svga = &et4000->svga; - uint8_t temp; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60; diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 8b762aeb9..51bd873d9 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1464,7 +1464,7 @@ uint8_t s3_accel_read(uint32_t addr, void *p) void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) { svga_t *svga = &s3->svga; - uint32_t src_dat, dest_dat; + uint32_t src_dat = 0, dest_dat; int frgd_mix, bkgd_mix; int clip_t = s3->accel.multifunc[1] & 0xfff; int clip_l = s3->accel.multifunc[2] & 0xfff; diff --git a/src/VIDEO/vid_s3_virge.c b/src/VIDEO/vid_s3_virge.c index 95f040128..4cb96ab8b 100644 --- a/src/VIDEO/vid_s3_virge.c +++ b/src/VIDEO/vid_s3_virge.c @@ -22,10 +22,10 @@ static int reg_writes = 0, reg_reads = 0; static int dither[4][4] = { - 0, 4, 1, 5, - 6, 2, 7, 3, - 1, 5, 0, 4, - 7, 3, 6, 2, + {0, 4, 1, 5}, + {6, 2, 7, 3}, + {1, 5, 0, 4}, + {7, 3, 6, 2}, }; #define RB_SIZE 256 diff --git a/src/VIDEO/vid_svga_render.c b/src/VIDEO/vid_svga_render.c index c942cf6ab..4c0c5c617 100644 --- a/src/VIDEO/vid_svga_render.c +++ b/src/VIDEO/vid_svga_render.c @@ -511,15 +511,20 @@ void svga_render_2bpp_highres(svga_t *svga) void svga_render_4bpp_lowres(svga_t *svga) { + int x; int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; int dl = svga_display_line(svga); + int offset; + uint32_t *p; + uint32_t *r, *q; + uint8_t edat[4]; + uint8_t dat; if (svga->changedvram[svga->ma >> 12] || svga->changedvram[(svga->ma >> 12) + 1] || svga->fullchange) { - int x; - int offset = ((8 - svga->scrollcache) << 1) + 16; - uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; + offset = ((8 - svga->scrollcache) << 1) + 16; + p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -527,10 +532,9 @@ void svga_render_4bpp_lowres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 16) { - uint8_t edat[4]; - uint8_t dat; - - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); + r = (uint32_t *)(&edat[0]); + q = (uint32_t *)(&svga->vram[svga->ma]); + *r = *q; svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); @@ -559,6 +563,12 @@ void svga_render_4bpp_highres(svga_t *svga) int y_add = (enable_overscan) ? 16 : 0; int x_add = y_add >> 1; int dl = svga_display_line(svga); + int x; + int offset; + uint32_t *p; + uint8_t edat[4]; + uint8_t dat; + uint32_t *r, *q; if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) changed_offset = svga_mask_addr(svga->ma | 0x8000, svga) >> 12; @@ -572,9 +582,8 @@ void svga_render_4bpp_highres(svga_t *svga) if (svga->changedvram[changed_offset] || svga->changedvram[changed_offset2] || svga->fullchange) { - int x; - int offset = (8 - svga->scrollcache) + 24; - uint32_t *p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; + offset = (8 - svga->scrollcache) + 24; + p = &((uint32_t *)buffer32->line[dl])[offset + x_add]; if (svga->firstline_draw == 2000) svga->firstline_draw = svga->displine; @@ -582,13 +591,12 @@ void svga_render_4bpp_highres(svga_t *svga) for (x = 0; x <= svga->hdisp; x += 8) { - uint8_t edat[4]; - uint8_t dat; - - if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga_mask_addr(svga->ma | 0x8000, svga)]); + r = (uint32_t *)(&edat[0]); + if (svga->sc & 1 && !(svga->crtc[0x17] & 1)) + q = (uint32_t *)(&svga->vram[svga_mask_addr(svga->ma | 0x8000, svga)]); else - *(uint32_t *)(&edat[0]) = *(uint32_t *)(&svga->vram[svga->ma]); + q = (uint32_t *)(&svga->vram[svga->ma]); + *r = *q; svga->ma += 4; svga->ma = svga_mask_addr(svga->ma, svga); diff --git a/src/VIDEO/vid_voodoo_codegen_x86.h b/src/VIDEO/vid_voodoo_codegen_x86.h index 5a9f65e46..0cd0fc7eb 100644 --- a/src/VIDEO/vid_voodoo_codegen_x86.h +++ b/src/VIDEO/vid_voodoo_codegen_x86.h @@ -759,10 +759,14 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo addbyte(0x47); addbyte(0xc3); - if (depth_jump_pos) - *(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1; - if (depth_jump_pos) - *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; + if (depth_jump_pos) + { + *(uint8_t *)&code_block[depth_jump_pos] = (block_pos - depth_jump_pos) - 1; + } + if (depth_jump_pos2) + { + *(uint8_t *)&code_block[depth_jump_pos2] = (block_pos - depth_jump_pos2) - 1; + } if ((params->fogMode & (FOG_ENABLE|FOG_CONSTANT|FOG_Z|FOG_ALPHA)) == FOG_ENABLE) { diff --git a/src/WIN/win_d3d.cc b/src/WIN/win_d3d.cc index 97953515f..456b67254 100644 --- a/src/WIN/win_d3d.cc +++ b/src/WIN/win_d3d.cc @@ -71,7 +71,6 @@ static CUSTOMVERTEX d3d_verts[] = int d3d_init(HWND h) { int c; - int ret; for (c = 0; c < 256; c++) pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index 1b1f994ce..cf0474c16 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -30,8 +30,6 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam { HWND h; int val_int; - int num; - char s[80]; switch (message) { diff --git a/src/WIN/win_dynld.c b/src/WIN/win_dynld.c index 9f7d4d3c5..42b245fc5 100644 --- a/src/WIN/win_dynld.c +++ b/src/WIN/win_dynld.c @@ -29,7 +29,7 @@ dynld_module(const char *name, dllimp_t *table) HMODULE h; dllimp_t *imp; void *func; - char **foo; + /* char **foo; */ /* See if we can load the desired module. */ if ((h = LoadLibrary(name)) == NULL) { diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c index 3850201bf..1515fa5ac 100644 --- a/src/WIN/win_midi.c +++ b/src/WIN/win_midi.c @@ -113,25 +113,8 @@ void midi_get_dev_name(int num, char *s) strcpy(s, caps.szPname); } -static int midi_pos, midi_len; -static uint32_t midi_command; -static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 1}; -static int midi_insysex; -static char midi_sysex_data[1024+2]; - -static void midi_send_sysex() -{ - MIDIHDR hdr; - - hdr.lpData = midi_sysex_data; - hdr.dwBufferLength = midi_pos; - hdr.dwFlags = 0; - - midiOutPrepareHeader(midi_out_device, &hdr, sizeof(MIDIHDR)); - midiOutLongMsg(midi_out_device, &hdr, sizeof(MIDIHDR)); - - midi_insysex = 0; -} +static int midi_pos; +static uint8_t midi_sysex_data[1024+2]; void PlayMsg(uint8_t *msg) { @@ -262,7 +245,7 @@ void midi_write(uint8_t val) void midi_reset() { - uint8_t buf[64], used; + uint8_t buf[64]; /* Flush buffers */ midiOutReset(midi_out_device); diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c index 1db962177..b6ec04e3f 100644 --- a/src/WIN/win_serial.c +++ b/src/WIN/win_serial.c @@ -87,8 +87,6 @@ pclog("%s: queued byte %02x (%d)\n", pp->name, b, pp->icnt+1); int bhtty_sstate(BHTTY *pp, void *arg) { - int i = 0; - /* Make sure we can do this. */ if (arg == NULL) { pclog("%s: invalid argument\n", pp->name); @@ -109,8 +107,6 @@ bhtty_sstate(BHTTY *pp, void *arg) int bhtty_gstate(BHTTY *pp, void *arg) { - int i = 0; - /* Make sure we can do this. */ if (arg == NULL) { pclog("%s: invalid argument\n", pp->name); @@ -304,8 +300,6 @@ bhtty_raw(BHTTY *pp, void *arg) int bhtty_speed(BHTTY *pp, long speed) { - int i; - /* Get the current mode and speed. */ if (bhtty_gstate(pp, &pp->dcb) < 0) return(-1); @@ -331,7 +325,6 @@ bhtty_flush(BHTTY *pp) { DWORD dwErrs; COMSTAT cs; - int i = 0; /* First, clear any errors. */ (void)ClearCommError(pp->handle, &dwErrs, &cs); diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index a5749f1d1..ee748741c 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -3130,12 +3130,9 @@ int hard_disk_was_added(void) void hard_disk_add_open(HWND hwnd, int is_existing) { - BOOL ret; - existing = is_existing; hard_disk_added = 0; - ret = DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, - hwnd, win_settings_hard_disks_add_proc); + DialogBox(hinstance, (LPCWSTR)DLG_CFG_HARD_DISKS_ADD, hwnd, win_settings_hard_disks_add_proc); } int ignore_change = 0; diff --git a/src/cdrom_dosbox.cpp b/src/cdrom_dosbox.cpp index 7b621a710..4def610ca 100644 --- a/src/cdrom_dosbox.cpp +++ b/src/cdrom_dosbox.cpp @@ -51,8 +51,6 @@ using namespace std; CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) { - // file = fopen64(filename, "rb"); - // error = (file == NULL); memset(fn, 0, sizeof(fn)); strcpy(fn, filename); error = false; @@ -60,19 +58,16 @@ CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) CDROM_Interface_Image::BinaryFile::~BinaryFile() { - // delete file; memset(fn, 0, sizeof(fn)); } bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, uint64_t seek, uint64_t count) { - uint64_t offs = 0; file = fopen64(fn, "rb"); if (file == NULL) return 0; fseeko64(file, seek, SEEK_SET); - offs = fread(buffer, 1, count, file); + fread(buffer, 1, count, file); fclose(file); - // return (offs == count); return 1; } @@ -179,7 +174,7 @@ bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) return true; } -int CDROM_Interface_Image::GetTrack(int sector) +int CDROM_Interface_Image::GetTrack(unsigned int sector) { vector::iterator i = tracks.begin(); vector::iterator end = tracks.end() - 1; @@ -225,9 +220,6 @@ bool CDROM_Interface_Image::IsMode2(unsigned long sector) bool CDROM_Interface_Image::LoadIsoFile(char* filename) { - int shift = 0; - int totalPregap = 0; - tracks.clear(); // data track diff --git a/src/cdrom_dosbox.h b/src/cdrom_dosbox.h index 243723fe4..dc88bbe45 100644 --- a/src/cdrom_dosbox.h +++ b/src/cdrom_dosbox.h @@ -149,7 +149,7 @@ public: bool HasDataTrack (void); bool HasAudioTracks (void); - int GetTrack (int sector); + int GetTrack (unsigned int sector); private: // player diff --git a/src/cdrom_image.cc b/src/cdrom_image.cc index 810601b24..204708742 100644 --- a/src/cdrom_image.cc +++ b/src/cdrom_image.cc @@ -108,7 +108,6 @@ static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) unsigned char attr; TMSF tmsf; int m = 0, s = 0, f = 0; - uint32_t start_msf = 0, end_msf = 0; cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); if (attr == DATA_TRACK) { @@ -185,13 +184,6 @@ static void image_stop(uint8_t id) cdrom_image[id].cd_state = CD_STOPPED; } -static void image_seek(uint8_t id, uint32_t pos) -{ - if (!cdimg[id] || cdrom_image[id].image_is_iso) return; - cdrom_image[id].cd_pos = pos; - cdrom_image[id].cd_state = CD_STOPPED; -} - static int image_ready(uint8_t id) { if (!cdimg[id]) @@ -771,14 +763,6 @@ read_mode2: } -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - static uint32_t image_size(uint8_t id) { return cdrom_image[id].cdrom_capacity; @@ -905,7 +889,6 @@ static int image_readtoc_raw(uint8_t id, unsigned char *b, int maxlen) int number; unsigned char attr; TMSF tmsf; - int lb; if (!cdimg[id]) return 0; diff --git a/src/cdrom_ioctl.c b/src/cdrom_ioctl.c index 201753e47..0b32b79b7 100644 --- a/src/cdrom_ioctl.c +++ b/src/cdrom_ioctl.c @@ -1047,7 +1047,7 @@ split_block_read_iterate: static int ioctl_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) { int len=4; - long size; + DWORD size; int c,d; uint32_t temp; uint32_t last_block; @@ -1156,9 +1156,7 @@ static int ioctl_readtoc_raw(uint8_t id, uint8_t *b, int maxlen) { int len=4; int size; - uint32_t temp; int i; - int BytesRead = 0; CDROM_READ_TOC_EX toc_ex; CDROM_TOC_FULL_TOC_DATA toc; if (!cdrom_drives[id].host_drive) diff --git a/src/config.c b/src/config.c index 7a044a6c0..1b6b9f561 100644 --- a/src/config.c +++ b/src/config.c @@ -109,6 +109,7 @@ void config_dump(void) } +#if 0 static void config_free(void) { section_t *current_section; @@ -133,6 +134,7 @@ static void config_free(void) current_section = next_section; } } +#endif static wchar_t cfgbuffer[1024]; @@ -477,7 +479,6 @@ void config_delete_var(char *head, char *name) void config_delete_section_if_empty(char *head) { section_t *section; - entry_t *entry; section = find_section(head); diff --git a/src/disc_imd.c b/src/disc_imd.c index b0a8b0016..d511dd46d 100644 --- a/src/disc_imd.c +++ b/src/disc_imd.c @@ -508,10 +508,10 @@ void imd_seek(int drive, int track) int real_sector = 0; int actual_sector = 0; - char *c_map; - char *h_map; + char *c_map = NULL; + char *h_map = NULL; char *r_map; - char *n_map; + char *n_map = NULL; uint8_t *data; uint32_t track_buf_pos[2] = { 0, 0 }; diff --git a/src/disc_img.c b/src/disc_img.c index f9016be4b..4220e5af0 100644 --- a/src/disc_img.c +++ b/src/disc_img.c @@ -61,38 +61,38 @@ uint8_t xdf_gap3_sizes[2][2] = { { 60, 69 }, { 60, 50 } }; uint16_t xdf_trackx_spos[2][8] = { { 0xA7F, 0xF02, 0x11B7, 0xB66, 0xE1B, 0x129E }, { 0x302, 0x7E2, 0xA52, 0x12DA, 0x572, 0xDFA, 0x106A, 0x154A } }; /* XDF: Layout of the sectors in the image. */ -xdf_sector_t xdf_img_layout[2][2][46] = { { { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800, - 0x8101, 0x8201, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600, - 0x0700, 0x0800, 0, - 0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901, 0x8A01, - 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0x9001, 0, 0, - 0, 0, 0 }, - { 0x8300, 0x8600, 0x8201, 0x8200, 0x8601, 0x8301 } +xdf_sector_t xdf_img_layout[2][2][46] = { { { {0x8100}, {0x8200}, {0x8300}, {0x8400}, {0x8500}, {0x8600}, {0x8700}, {0x8800}, + {0x8101}, {0x8201}, {0x0100}, {0x0200}, {0x0300}, {0x0400}, {0x0500}, {0x0600}, + {0x0700}, {0x0800}, { 0}, + {0x8301}, {0x8401}, {0x8501}, {0x8601}, {0x8701}, {0x8801}, {0x8901}, {0x8A01}, + {0x8B01}, {0x8C01}, {0x8D01}, {0x8E01}, {0x8F01}, {0x9001}, { 0}, { 0}, + { 0}, { 0}, { 0} }, + { {0x8300}, {0x8600}, {0x8201}, {0x8200}, {0x8601}, {0x8301} } }, /* 5.25" 2HD */ - { { 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, 0x8800, - 0x8900, 0x8A00, 0x8B00, 0x8101, 0x0100, 0x0200, 0x0300, 0x0400, - 0x0500, 0x0600, 0x0700, 0x0800, 0, 0, 0, - 0x8201, 0x8301, 0x8401, 0x8501, 0x8601, 0x8701, 0x8801, 0x8901, - 0x8A01, 0x8B01, 0x8C01, 0x8D01, 0x8E01, 0x8F01, 0, 0, - 0, 0, 0, 0x9001, 0x9101, 0x9201, 0x9301 }, - { 0x8300, 0x8400, 0x8601, 0x8200, 0x8201, 0x8600, 0x8401, 0x8301 } + { { {0x8100}, {0x8200}, {0x8300}, {0x8400}, {0x8500}, {0x8600}, {0x8700}, {0x8800}, + {0x8900}, {0x8A00}, {0x8B00}, {0x8101}, {0x0100}, {0x0200}, {0x0300}, {0x0400}, + {0x0500}, {0x0600}, {0x0700}, {0x0800}, { 0}, { 0}, { 0}, + {0x8201}, {0x8301}, {0x8401}, {0x8501}, {0x8601}, {0x8701}, {0x8801}, {0x8901}, + {0x8A01}, {0x8B01}, {0x8C01}, {0x8D01}, {0x8E01}, {0x8F01}, { 0}, { 0}, + { 0}, { 0}, { 0}, {0x9001}, {0x9101}, {0x9201}, {0x9301} }, + { {0x8300}, {0x8400}, {0x8601}, {0x8200}, {0x8201}, {0x8600}, {0x8401}, {0x8301} } } /* 3.5" 2HD */ }; /* XDF: Layout of the sectors on the disk's track. */ -xdf_sector_t xdf_disk_layout[2][2][38] = { { { 0x0100, 0x0200, 0x8100, 0x8800, 0x8200, 0x0300, 0x8300, 0x0400, - 0x8400, 0x0500, 0x8500, 0x0600, 0x8600, 0x0700, 0x8700, 0x0800, - 0x8D01, 0x8501, 0x8E01, 0x8601, 0x8F01, 0x8701, 0x9001, 0x8801, - 0x8101, 0x8901, 0x8201, 0x8A01, 0x8301, 0x8B01, 0x8401, 0x8C01 }, - { 0x8300, 0x8200, 0x8600, 0x8201, 0x8301, 0x8601 } +xdf_sector_t xdf_disk_layout[2][2][38] = { { { {0x0100}, {0x0200}, {0x8100}, {0x8800}, {0x8200}, {0x0300}, {0x8300}, {0x0400}, + {0x8400}, {0x0500}, {0x8500}, {0x0600}, {0x8600}, {0x0700}, {0x8700}, {0x0800}, + {0x8D01}, {0x8501}, {0x8E01}, {0x8601}, {0x8F01}, {0x8701}, {0x9001}, {0x8801}, + {0x8101}, {0x8901}, {0x8201}, {0x8A01}, {0x8301}, {0x8B01}, {0x8401}, {0x8C01} }, + { {0x8300}, {0x8200}, {0x8600}, {0x8201}, {0x8301}, {0x8601} } }, /* 5.25" 2HD */ - { { 0x0100, 0x8A00, 0x8100, 0x8B00, 0x8200, 0x0200, 0x8300, 0x0300, - 0x8400, 0x0400, 0x8500, 0x0500, 0x8600, 0x0600, 0x8700, 0x0700, - 0x8800, 0x0800, 0x8900, - 0x9001, 0x8701, 0x9101, 0x8801, 0x9201, 0x8901, 0x9301, 0x8A01, - 0x8101, 0x8B01, 0x8201, 0x8C01, 0x8301, 0x8D01, 0x8401, 0x8E01, - 0x8501, 0x8F01, 0x8601 }, - { 0x8300, 0x8200, 0x8400, 0x8600, 0x8401, 0x8201, 0x8301, 0x8601 }, + { { {0x0100}, {0x8A00}, {0x8100}, {0x8B00}, {0x8200}, {0x0200}, {0x8300}, {0x0300}, + {0x8400}, {0x0400}, {0x8500}, {0x0500}, {0x8600}, {0x0600}, {0x8700}, {0x0700}, + {0x8800}, {0x0800}, {0x8900}, + {0x9001}, {0x8701}, {0x9101}, {0x8801}, {0x9201}, {0x8901}, {0x9301}, {0x8A01}, + {0x8101}, {0x8B01}, {0x8201}, {0x8C01}, {0x8301}, {0x8D01}, {0x8401}, {0x8E01}, + {0x8501}, {0x8F01}, {0x8601} }, + { {0x8300}, {0x8200}, {0x8400}, {0x8600}, {0x8401}, {0x8201}, {0x8301}, {0x8601} }, }, /* 3.5" 2HD */ }; diff --git a/src/ibm.h b/src/ibm.h index f75e5924f..2e22ad740 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -795,3 +795,5 @@ extern void status_settext(char *str); #define SB_RDISK 0x20 #define SB_HDD 0x40 #define SB_TEXT 0x50 + +#define UNUSED(x) (void)x diff --git a/src/intel_flash.c b/src/intel_flash.c index d03e1de94..f807cd63f 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -85,17 +85,21 @@ static uint8_t flash_read(uint32_t addr, void *p) static uint16_t flash_readw(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; + uint16_t *q; addr &= 0x1ffff; if (flash->invert_high_pin) addr ^= 0x10000; - return *(uint16_t *)&(flash->array[addr]); + q = (uint16_t *)&(flash->array[addr]); + return *q; } static uint32_t flash_readl(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; + uint32_t *q; addr &= 0x1ffff; if (flash->invert_high_pin) addr ^= 0x10000; - return *(uint32_t *)&(flash->array[addr]); + q = (uint32_t *)&(flash->array[addr]); + return *q; } static void flash_write(uint32_t addr, uint8_t val, void *p) diff --git a/src/keyboard_amstrad.c b/src/keyboard_amstrad.c index 3765b43ca..f87cfd983 100644 --- a/src/keyboard_amstrad.c +++ b/src/keyboard_amstrad.c @@ -112,7 +112,7 @@ void keyboard_amstrad_write(uint16_t port, uint8_t val, void *priv) uint8_t keyboard_amstrad_read(uint16_t port, void *priv) { - uint8_t temp; + uint8_t temp = 0xff; switch (port) { case 0x60: diff --git a/src/keyboard_olim24.c b/src/keyboard_olim24.c index e031bafad..55c2f1868 100644 --- a/src/keyboard_olim24.c +++ b/src/keyboard_olim24.c @@ -45,7 +45,6 @@ static uint8_t mouse_scancodes[7]; void keyboard_olim24_poll() { keybsenddelay += (1000 * TIMER_USEC); - //pclog("poll %i\n", keyboard_olim24.wantirq); if (keyboard_olim24.wantirq) { keyboard_olim24.wantirq = 0; @@ -108,8 +107,6 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) default: pclog("Bad keyboard command complete %02X\n", keyboard_olim24.command); -// dumpregs(); -// exit(-1); } } } @@ -137,8 +134,6 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) default: pclog("Bad keyboard command %02X\n", val); -// dumpregs(); -// exit(-1); } } @@ -162,8 +157,7 @@ void keyboard_olim24_write(uint16_t port, uint8_t val, void *priv) uint8_t keyboard_olim24_read(uint16_t port, void *priv) { - uint8_t temp; -// pclog("keyboard_olim24 : read %04X ", port); + uint8_t temp = 0xff; switch (port) { case 0x60: @@ -193,10 +187,7 @@ uint8_t keyboard_olim24_read(uint16_t port, void *priv) default: pclog("\nBad olim24 keyboard read %04X\n", port); -// dumpregs(); -// exit(-1); } -// pclog("%02X\n", temp); return temp; } @@ -231,8 +222,6 @@ uint8_t mouse_olim24_poll(int x, int y, int z, int b, void *p) mouse->x += x; mouse->y += y; -// pclog("mouse_poll - %i, %i %i, %i\n", x, y, mouse->x, mouse->y); - if (((key_queue_end - key_queue_start) & 0xf) > 14) return(0xff); if ((b & 1) && !(mouse->b & 1)) @@ -342,7 +331,6 @@ mouse_t mouse_olim24 = void keyboard_olim24_init() { - //return; io_sethandler(0x0060, 0x0002, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); io_sethandler(0x0064, 0x0001, keyboard_olim24_read, NULL, NULL, keyboard_olim24_write, NULL, NULL, NULL); keyboard_olim24_reset(); diff --git a/src/mem.c b/src/mem.c index c401f0841..2f6d2bf46 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1785,11 +1785,13 @@ uint8_t mem_read_romext(uint32_t addr, void *priv) } uint16_t mem_read_romextw(uint32_t addr, void *priv) { - return *(uint16_t *)&romext[addr & 0x7fff]; + uint16_t *p = (uint16_t *)&romext[addr & 0x7fff]; + return *p; } uint32_t mem_read_romextl(uint32_t addr, void *priv) { - return *(uint32_t *)&romext[addr & 0x7fff]; + uint32_t *p = (uint32_t *)&romext[addr & 0x7fff]; + return *p; } void mem_write_null(uint32_t addr, uint8_t val, void *p) diff --git a/src/model.c b/src/model.c index fdae935df..d564138c8 100644 --- a/src/model.c +++ b/src/model.c @@ -159,78 +159,77 @@ int romset; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, "ibmxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"Compaq Portable", ROM_PORTABLE, "portable", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 128, 640, 128, 0, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", { "", cpus_pcjr, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, "genxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, "amixt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, "dtk", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, "pxxt", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, "jukopc", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, "tandy", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", { "", cpus_8088, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, "pc1512", { "", cpus_pc1512, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, "pc200", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, - {"Schneider EuroPC", ROM_EUROPC, "europc", { "", cpus_europc, "", NULL, "", NULL, "", NULL, "", NULL}, 0, 0, 512, 640, 128, 0, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, "pc1640", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, "pc2086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, "pc3086", { "", cpus_8086, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", { "", cpus_ibmat, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 63, ibm_at_init, NULL}, - {"Compaq Portable II", ROM_PORTABLEII, "portableii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_ide_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_scat_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", { "", cpus_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", { "", cpus_ps1_m2011, "", NULL, "", NULL, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, - {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", { "", cpus_ps2_m30_286, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, - {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL}, - {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_headland_init, NULL}, - {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL}, -/* The MegaPC manual says 386DX model of the Amstrad PC70386 exists, but Sarah Walker just *had* to remove 386DX CPU's from some boards. */ - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", { "Intel", cpus_i386DX, "AMD", cpus_Am386DX, "Cyrix", cpus_486DLC, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, - {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, - {"AMI 486 clone", ROM_AMI486, "ami486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, - {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL}, - {"Rise Computer R418", ROM_R418, "r418", { "Intel", cpus_i486, "AMD", cpus_Am486, "Cyrix", cpus_Cx486, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", { "Intel", cpus_Pentium5V, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 128, 0, xt_init, NULL}, + {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device}, + {"Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, + {"VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, + {"Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device}, + {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device}, + {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL}, + {"Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, + {"Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, + {"Schneider EuroPC", ROM_EUROPC, "europc", {{"", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, 0, europc_init, NULL}, + {"Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL}, + {"Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, + {"Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, + {"Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, 63, ibm_at_init, NULL}, + {"Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, + {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_scat_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, + {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, + {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_headland_init, NULL}, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL}, + {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, + {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL}, + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, + {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, + {"AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, + {"AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, + {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL}, + {"Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL}, #if 0 - {"Micro Star 586MC1", ROM_586MC1, "586mc1", { "Intel", cpus_Pentium5V50, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL}, + {"Micro Star 586MC1", ROM_586MC1, "586mc1", {{"Intel", cpus_Pentium5V50}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL}, #endif - {"Intel Premiere/PCI II", ROM_PLATO, "plato", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, "mb500n", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, - {"President Award 430FX PCI", ROM_PRESIDENT, "president", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", { "Intel", cpus_PentiumS5, "IDT", cpus_WinChip, "AMD", cpus_K5, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"AOpen AP53", ROM_AP53, "ap53", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, - {"Acer V35n", ROM_ACERV35N, "acerv35n", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, - {"Epox P55-VA", ROM_P55VA, "p55va", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", { "Intel", cpus_Pentium, "IDT", cpus_WinChip, "Cyrix", cpus_6x86, "AMD", cpus_K56, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL}, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", { "Intel", cpus_PentiumPro, "", NULL, "", NULL, "", NULL, "", NULL}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL}, - {"", -1, "", {"", 0, "", 0, "", 0}, 0,0,0,0, 0} + {"Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, + {"PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, + {"President Award 430FX PCI", ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, + {"AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, + {"Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, + {"Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL}, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL}, + {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0} }; diff --git a/src/mouse_bus.c b/src/mouse_bus.c index 32063bfb0..b8cec9f82 100644 --- a/src/mouse_bus.c +++ b/src/mouse_bus.c @@ -380,7 +380,7 @@ static uint8_t bm_read(uint16_t port, void *priv) { mouse_bus_t *ms = (mouse_bus_t *)priv; - uint8_t r; + uint8_t r = 0xff; if (ms->flags & MOUSE_LOGITECH) r = lt_read(ms, port - ms->port); diff --git a/src/pc.c b/src/pc.c index e72202820..45016bf4a 100644 --- a/src/pc.c +++ b/src/pc.c @@ -289,12 +289,15 @@ void initpc(int argc, wchar_t *argv[]) wchar_t *p; wchar_t *config_file = NULL; int c; - FILE *ff; get_executable_name(pcempath, 511); pclog("executable_name = %ws\n", pcempath); p=get_filename_w(pcempath); *p=L'\0'; pclog("path = %ws\n", pcempath); +#ifdef WALTJE + DIR *dir; + struct direct *dp; +#endif for (c = 1; c < argc; c++) { @@ -325,9 +328,6 @@ void initpc(int argc, wchar_t *argv[]) { /* some (undocumented) test function here.. */ #ifdef WALTJE - DIR *dir; - struct direct *dp; - dir = opendirw(pcempath); if (dir != NULL) { printf("Directory '%ws':\n", pcempath); diff --git a/src/pit.c b/src/pit.c index 53169d27f..144630d5f 100644 --- a/src/pit.c +++ b/src/pit.c @@ -436,7 +436,7 @@ uint8_t pit_read(uint16_t addr, void *p) { PIT *pit = (PIT *)p; int t; - uint8_t temp; + uint8_t temp = 0xff; cycles -= (int)PITCONST; switch (addr&3) { diff --git a/src/scsi_aha154x.c b/src/scsi_aha154x.c index a91abdf87..83d32d55d 100644 --- a/src/scsi_aha154x.c +++ b/src/scsi_aha154x.c @@ -949,15 +949,6 @@ aha_reset(aha_t *dev) } -static void -aha_softreset(void) -{ - if (ResetDev != NULL) { - aha_reset(ResetDev); - } -} - - static void aha_reset_ctrl(aha_t *dev, uint8_t Reset) { @@ -2149,7 +2140,7 @@ uint8_t aha_mca_read(int port, void *p) uint16_t aha_mca_get_port(uint8_t pos_port) { - uint16_t addr; + uint16_t addr = 0; switch (pos_port & 0xC7) { case 0x01: diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index f9a215bee..26dbdc8fa 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -623,15 +623,6 @@ BuslogicReset(Buslogic_t *bl) } -static void -BuslogicSoftReset(void) -{ - if (BuslogicResetDevice != NULL) { - BuslogicReset(BuslogicResetDevice); - } -} - - static void BuslogicResetControl(Buslogic_t *bl, uint8_t Reset) { diff --git a/src/serial.c b/src/serial.c index 035e443f2..ae33dc16d 100644 --- a/src/serial.c +++ b/src/serial.c @@ -116,7 +116,7 @@ enum { #define MCR_OUT1 (0x04) /* 8250 */ #define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ #define MCR_LMS (0x10) -#define MCR_AUTOFLOW (0x20) /* 16750 +#define MCR_AUTOFLOW (0x20) /* 16750 */ /* LSR register bits. */ #define LSR_DR (0x01) @@ -144,6 +144,7 @@ static SERIAL ports[NUM_SERIAL]; /* serial port data */ int serial_do_log; +#if 0 static void serial_log(int lvl, const char *fmt, ...) { @@ -158,6 +159,7 @@ serial_log(int lvl, const char *fmt, ...) } #endif } +#endif static void diff --git a/src/sio.c b/src/sio.c index 96d2ef375..03389a0ed 100644 --- a/src/sio.c +++ b/src/sio.c @@ -36,8 +36,8 @@ void sio_write(int func, int addr, uint8_t val, void *priv) if (func > 0) return; - if (addr >= 0x0f && addr < 0x4c) - return; + if (addr >= 0x0f && addr < 0x4c) + return; switch (addr) { diff --git a/src/tandy_eeprom.c b/src/tandy_eeprom.c index 8d1a9eff2..0a5751d90 100644 --- a/src/tandy_eeprom.c +++ b/src/tandy_eeprom.c @@ -118,7 +118,7 @@ int tandy_eeprom_read() void *tandy_eeprom_init() { tandy_eeprom_t *eeprom = malloc(sizeof(tandy_eeprom_t)); - FILE *f; + FILE *f = NULL; memset(eeprom, 0, sizeof(tandy_eeprom_t)); @@ -148,7 +148,7 @@ void *tandy_eeprom_init() void tandy_eeprom_close(void *p) { tandy_eeprom_t *eeprom = (tandy_eeprom_t *)p; - FILE *f; + FILE *f = NULL; switch (eeprom->romset) { From 89b83f26ea121b12a8ed072a939945c16f1702f8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 19:58:59 +0200 Subject: [PATCH 352/392] Brought the S3 accelerator code in line with the mainline, this means that initial value of 0 for src_dat is gone, but the warnings remain gone as well. --- src/VIDEO/vid_s3.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 51bd873d9..61a24ce64 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1464,7 +1464,7 @@ uint8_t s3_accel_read(uint32_t addr, void *p) void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_t *s3) { svga_t *svga = &s3->svga; - uint32_t src_dat = 0, dest_dat; + uint32_t src_dat, dest_dat; int frgd_mix, bkgd_mix; int clip_t = s3->accel.multifunc[1] & 0xfff; int clip_l = s3->accel.multifunc[2] & 0xfff; @@ -1660,15 +1660,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dest = s3->accel.cy * s3->width; } - - s3->status_9ae9 = 4; /*To avoid the spam from OS/2's drivers*/ - - if ((s3->accel.cmd & 0x100) && !cpu_input) - { - s3->status_9ae9 = 2; /*To avoid the spam from OS/2's drivers*/ - return; /*Wait for data from CPU*/ - } - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; @@ -1694,7 +1685,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ(s3->accel.dest + s3->accel.cx, dest_dat); MIX - + WRITE(s3->accel.dest + s3->accel.cx); } } @@ -1712,7 +1703,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - + if (s3->accel.cmd & 0x80) s3->accel.cy++; else s3->accel.cy--; @@ -1765,9 +1756,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { - READ(s3->accel.src + s3->accel.cx, dest_dat); - - MIX + READ(s3->accel.src + s3->accel.cx, src_dat); + + dest_dat = src_dat; WRITE(s3->accel.dest + s3->accel.dx); } @@ -1791,6 +1782,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.sy < 0) { + s3->accel.cur_x = s3->accel.cx; + s3->accel.cur_y = s3->accel.cy; return; } } @@ -1821,7 +1814,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); - + MIX WRITE(s3->accel.dest + s3->accel.dx); From d2465dd5b3979a52b88314eb3eb1feffad9ac47b Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 16 Jun 2017 14:09:40 -0400 Subject: [PATCH 353/392] More changes (stdarg.h in ide.c and name cleanups and %ws to %S in pc.c) --- src/WIN/86Box.rc | 4 ++-- src/ide.c | 3 ++- src/pc.c | 12 ++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 73f326984..705da1599 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -8,7 +8,7 @@ * * Windows resource script. * - * Version: @(#)86Box.rc 1.0.3 2017/06/16 + * Version: @(#)86Box.rc 1.0.4 2017/06/17 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -186,7 +186,7 @@ FONT 9, "Segoe UI" BEGIN DEFPUSHBUTTON "OK",IDOK,129,94,71,12 ICON 100,IDC_ABOUT_ICON,7,7,20,20 - LTEXT "86Box v2.00 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, waltje, SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + LTEXT "86Box v2.00 - A fork of PCem\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", IDC_ABOUT_ICON,54,7,146,73 CONTROL "",IDC_ABOUT_ICON,"Static",SS_BLACKFRAME | SS_SUNKEN,0, 86,208,1 diff --git a/src/ide.c b/src/ide.c index 4a11ed3a7..1056c7858 100644 --- a/src/ide.c +++ b/src/ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)ide.c 1.0.2 2017/06/16 + * Version: @(#)ide.c 1.0.3 2017/06/17 * * Authors: Sarah Walker, * Miran Grca, @@ -20,6 +20,7 @@ */ #include #include +#include #include #include "86box.h" diff --git a/src/pc.c b/src/pc.c index 45016bf4a..ef35f166e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.4 2017/06/15 + * Version: @(#)pc.c 1.0.5 2017/06/17 * * Authors: Sarah Walker, * Miran Grca, @@ -290,10 +290,10 @@ void initpc(int argc, wchar_t *argv[]) wchar_t *config_file = NULL; int c; get_executable_name(pcempath, 511); - pclog("executable_name = %ws\n", pcempath); + pclog("executable_name = %S\n", pcempath); p=get_filename_w(pcempath); *p=L'\0'; - pclog("path = %ws\n", pcempath); + pclog("path = %S\n", pcempath); #ifdef WALTJE DIR *dir; struct direct *dp; @@ -330,15 +330,15 @@ void initpc(int argc, wchar_t *argv[]) #ifdef WALTJE dir = opendirw(pcempath); if (dir != NULL) { - printf("Directory '%ws':\n", pcempath); + printf("Directory '%S':\n", pcempath); for (;;) { dp = readdir(dir); if (dp == NULL) break; - printf(">> '%ws'\n", dp->d_name); + printf(">> '%S'\n", dp->d_name); } closedir(dir); } else { - printf("Could not open '%ws'..\n", pcempath); + printf("Could not open '%S'..\n", pcempath); } #endif From 2019183c2965ee66503105eca42102f7a92bc184 Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 16 Jun 2017 16:00:44 -0400 Subject: [PATCH 354/392] Removed all model-based one-line header files and moved their info to model.h. Added static to handler functions where needed. --- src/Makefile.mingw | 72 ++++++++--------- src/acer386sx.c | 11 ++- src/acer386sx.h | 4 - src/acerm3a.c | 16 ++-- src/acerm3a.h | 4 - src/ali1429.c | 11 ++- src/ali1429.h | 5 -- src/amstrad.c | 19 +++-- src/amstrad.h | 3 - src/compaq.c | 17 +++- src/compaq.h | 4 - src/headland.c | 12 ++- src/headland.h | 4 - src/i430fx.c | 26 ++++--- src/i430fx.h | 19 ----- src/i430hx.c | 26 ++++--- src/i430hx.h | 19 ----- src/i430lx.c | 26 ++++--- src/i430lx.h | 19 ----- src/i430nx.c | 26 ++++--- src/i430nx.h | 19 ----- src/i430vx.c | 26 ++++--- src/i430vx.h | 19 ----- src/i440fx.c | 26 ++++--- src/i440fx.h | 19 ----- src/jim.c | 14 +++- src/jim.h | 4 - src/keyboard_olim24.h | 2 - src/laserxt.c | 22 ++++-- src/laserxt.h | 1 - src/model.c | 22 +----- src/model.h | 46 ++++++++++- src/mouse.c | 6 +- src/mouse_serial.c | 177 +++++++++++++++++++++--------------------- src/neat.c | 22 ++++-- src/neat.h | 4 - src/olivetti_m24.c | 10 ++- src/olivetti_m24.h | 4 - src/opti495.c | 123 +++++++++++++++-------------- src/opti495.h | 1 - src/pc.c | 6 +- src/ps1.c | 21 +++-- src/ps1.h | 6 -- src/ps2.c | 14 +++- src/ps2.h | 1 - src/scat.c | 67 ++++++++++++---- src/scat.h | 25 ------ src/sis496.c | 23 ++++-- src/sis496.h | 4 - 49 files changed, 539 insertions(+), 538 deletions(-) delete mode 100644 src/acer386sx.h delete mode 100644 src/acerm3a.h delete mode 100644 src/ali1429.h delete mode 100644 src/amstrad.h delete mode 100644 src/compaq.h delete mode 100644 src/headland.h delete mode 100644 src/i430fx.h delete mode 100644 src/i430hx.h delete mode 100644 src/i430lx.h delete mode 100644 src/i430nx.h delete mode 100644 src/i430vx.h delete mode 100644 src/i440fx.h delete mode 100644 src/jim.h delete mode 100644 src/laserxt.h delete mode 100644 src/neat.h delete mode 100644 src/olivetti_m24.h delete mode 100644 src/opti495.h delete mode 100644 src/ps1.h delete mode 100644 src/ps2.h delete mode 100644 src/scat.h delete mode 100644 src/sis496.h diff --git a/src/Makefile.mingw b/src/Makefile.mingw index f915f734c..d92d2d175 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,12 +8,10 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.29 2017/06/16 +# Version: @(#)Makefile.mingw 1.0.30 2017/06/17 # # Authors: Miran Grca, # Fred N. van Kempen, -# Sarah Walker, -# Richard G., # # Name of the executable. @@ -274,13 +272,13 @@ pcap_if.res: pcap_if.rc # Module dependencies. -acer386sx.o: ibm.h cpu/cpu.h io.h acer386sx.h +acer386sx.o: ibm.h cpu/cpu.h io.h device.h model.h -acerm3a.o: ibm.h io.h acerm3a.h +acerm3a.o: ibm.h cpu/cpu.h io.h device.h model.h -ali1429.o: ibm.h cpu/cpu.h io.h mem.h ali1429.h +ali1429.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h -amstrad.o: ibm.h io.h keyboard.h lpt.h mouse.h amstrad.h +amstrad.o: ibm.h cpu/cpu.h io.h device.h model.h keyboard.h lpt.h mouse.h bugger.o: ibm.h io.h bugger.h @@ -291,7 +289,7 @@ cdrom_ioctl.o: ibm.h cdrom.h cdrom_ioctl.h scsi.h cdrom_null.o: ibm.h cdrom.h cdrom_ioctl.h -compaq.o: ibm.h mem.h +compaq.o: ibm.h cpu/cpu.h mem.h device.h model.h config.o: cdrom.h config.h device.h disc.h fdc.h fdd.h ibm.h \ cpu/cpu.h gameport.h ide.h hdd.h model.h mouse.h \ @@ -343,19 +341,19 @@ hdd_image.o: ibm.h ide.h hdd_image.h hdd_esdi.o: ibm.h device.h dma.h hdd_image.h io.h mca.h mem.h \ pic.h rom.h timer.h hdd_esdi.h -headland.o: ibm.h cpu/cpu.h io.h mem.h headland.h +headland.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h -i430fx.o: ibm.h mem.h pci.h i430fx.h +i430fx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h -i430hx.o: ibm.h io.h mem.h pci.h i430hx.h +i430hx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h -i430lx.o: ibm.h mem.h pci.h i430lx.h +i430lx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h -i430nx.o: ibm.h mem.h pci.h i430nx.h +i430nx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h -i430vx.o: ibm.h io.h mem.h pci.h i430vx.h +i430vx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h -i440fx.o: ibm.h io.h mem.h pci.h i440fx.h +i440fx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h i82335.o: ibm.h io.h mem.h @@ -367,7 +365,7 @@ intel_flash.o: ibm.h cpu/cpu.h device.h mem.h model.h rom.h io.o: ibm.h io.h -jim.o: ibm.h io.h +jim.o: ibm.h cpu/cpu.h io.h device.h model.h joystick_ch_flightstick_pro.o: ibm.h device.h timer.h gameport.h \ joystick_standard.h plat_joystick.h @@ -399,7 +397,7 @@ keyboard_pcjr.o: ibm.h io.h mem.h nmi.h pic.h pit.h timer.h \ keyboard_xt.o: ibm.h io.h mem.h pic.h pit.h timer.h device.h tandy_eeprom.h \ sound/sound.h sound/snd_speaker.h keyboard.h keyboard_xt.h -laserxt.o: ibm.h io.h mem.h +laserxt.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h lpt.o: ibm.h io.h lpt.h @@ -416,22 +414,20 @@ mfm_at.o: ibm.h device.h hdd_image.h io.h pic.h timer.h mfm_at.h mfm_xebec.o: ibm.h device.h dma.h hdd_image.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h -model.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h mouse.h \ - mouse_ps2.h cdrom.h acerm3a.h ali1429.h amstrad.h compaq.h \ - disc.h dma.h fdc.h fdc37c665.h fdc37c669.h fdc37c932fr.h \ - gameport.h headland.h i430fx.h i430hx.h i430lx.h i430nx.h \ - i430vx.h i440fx.h i82335.h ide.h intel.h intel_flash.h jim.h \ +model.o: ibm.h io.h mem.h rom.h device.h model.h cpu/cpu.h \ + mouse.h mouse_ps2.h cdrom.h disc.h dma.h fdc.h \ + fdc37c665.h fdc37c669.h fdc37c932fr.h \ + gameport.h i82335.h ide.h intel.h intel_flash.h \ keyboard_amstrad.h keyboard_at.h keyboard_olim24.h \ - keyboard_pcjr.h keyboard_xt.h laserxt.h lpt.h mem.h memregs.h \ - neat.h nmi.h nvr.h olivetti_m24.h opti495.h pc87306.h pci.h \ - pic.h piix.h pit.h ps1.h ps2.h ps2_mca.h scat.h serial.h \ - sis496.h sis85c471.h sio.h sound/snd_ps1.h sound/snd_pssj.h \ + keyboard_pcjr.h keyboard_xt.h lpt.h mem.h memregs.h \ + nmi.h nvr.h pc87306.h pci.h pic.h piix.h pit.h ps2_mca.h \ + serial.h sis85c471.h sio.h sound/snd_ps1.h sound/snd_pssj.h \ sound/snd_sn76489.h tandy_eeprom.h tandy_rom.h \ video/vid_pcjr.h video/vid_tandy.h w83877f.h wd76c10.h \ xtide.h bugger.h -mouse.o: ibm.h mouse.h mouse_serial.h mouse_ps2.h mouse_bus.h \ - amstrad.h keyboard_olim24.h +mouse.o: ibm.h cpu/cpu.h device.h model.h \ + mouse.h mouse_serial.h mouse_ps2.h mouse_bus.h keyboard_olim24.h mouse_bus.o: ibm.h io.h pic.h mouse.h mouse_bus.h plat_mouse.h @@ -439,28 +435,28 @@ mouse_ps2.o: ibm.h keyboard_at.h mouse.h mouse_ps2.h plat_mouse.h mouse_serial.o: ibm.h timer.h serial.h mouse.h mouse_serial.h -neat.o: ibm.h io.h neat.h +neat.o: ibm.h cpu/cpu.h io.h device.h model.h nmi.o: ibm.h io.h nmi.h nvr.o: ibm.h cpu/cpu.h device.h io.h mem.h model.h nvr.h \ pic.h rom.h timer.h rtc.h -olivetti_m24.o: ibm.h io.h olivetti_m24.h +olivetti_m24.o: ibm.h cpu/cpu.h io.h device.h model.h -opti495.o: ibm.h cpu/cpu.h io.h mem.h +opti495.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h pc.o: 86box.h ibm.h mem.h cpu/cpu.h cpu/x86_ops.h cpu/codegen.h \ - dma.h nvr.h pic.h pit.h timer.h device.h ali1429.h disc.h \ + dma.h nvr.h pic.h pit.h timer.h device.h model.h disc.h \ disc_86f.h disc_fdi.h disc_imd.h disc_img.h disc_td0.h \ disc_random.h config.h fdc.h fdd.h gameport.h plat_joystick.h \ plat_midi.h hdd.h ide.h cdrom.h cdrom_ioctl.h cdrom_image.h \ cdrom_null.h scsi.h keyboard.h plat_keyboard.h keyboard_at.h \ - model.h mouse.h plat_mouse.h network/network.h serial.h \ + mouse.h plat_mouse.h network/network.h serial.h \ sound/sound.h sound/snd_cms.h sound/snd_dbopl.h \ sound/snd_mpu401.h sound/snd_opl.h sound/snd_gus.h \ sound/snd_sb.h sound/snd_speaker.h sound/snd_ssi2001.h \ - video/video.h video/vid_voodoo.h amstrad.h win/plat_ui.h + video/video.h video/vid_voodoo.h win/plat_ui.h pc87306.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h pc87306.h @@ -475,9 +471,9 @@ pit.o: ibm.h cpu/cpu.h dma.h io.h pic.h pit.h device.h timer.h \ ppi.o: ibm.h pit.h plat_keyboard.h plat_mouse.h -ps1.o: ibm.h io.h mem.h ps1.h rom.h lpt.h serial.h +ps1.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h lpt.h serial.h -ps2.o: ibm.h io.h mem.h ps2.h rom.h lpt.h serial.h +ps2.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h lpt.h serial.h ps2_mca.o: ibm.h cpu/cpu.h cpu/x86.h io.h mca.h mem.h rom.h device.h \ lpt.h ps2_mca.h ps2_nvr.h serial.h @@ -488,7 +484,7 @@ rom.o: config.h ibm.h mem.h rom.h rtc.o: nvr.h rtc.h -scat.o: ibm.h io.h scat.h mem.h +scat.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h scsi.o: 86box.h ibm.h timer.h device.h cdrom.h scsi.h \ scsi_aha154x.h scsi_buslogic.h @@ -507,7 +503,7 @@ serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h sio.o: ibm.h cdrom.h disc.h dma.h fdc.h keyboard_at.h ide.h \ io.h mem.h pci.h sio.h -sis496.o: ibm.h device.h io.h mem.h pci.h sis496.h +sis496.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h sis50x.o: ibm.h device.h io.h mem.h pci.h sis50x.h diff --git a/src/acer386sx.c b/src/acer386sx.c index 4f6ce5eed..47f0cbca8 100644 --- a/src/acer386sx.c +++ b/src/acer386sx.c @@ -4,14 +4,15 @@ #include "ibm.h" #include "cpu/cpu.h" #include "io.h" -#include "acer386sx.h" +#include "device.h" +#include "model.h" static int acer_index = 0; static uint8_t acer_regs[256]; -void acer386sx_write(uint16_t addr, uint8_t val, void *priv) +static void acer386sx_write(uint16_t addr, uint8_t val, void *priv) { if (addr & 1) acer_regs[acer_index] = val; @@ -19,7 +20,8 @@ void acer386sx_write(uint16_t addr, uint8_t val, void *priv) acer_index = val; } -uint8_t acer386sx_read(uint16_t addr, void *priv) + +static uint8_t acer386sx_read(uint16_t addr, void *priv) { if (addr & 1) { @@ -31,7 +33,8 @@ uint8_t acer386sx_read(uint16_t addr, void *priv) return acer_index; } -void acer386sx_init() + +void acer386sx_init(void) { io_sethandler(0x0022, 0x0002, acer386sx_read, NULL, NULL, acer386sx_write, NULL, NULL, NULL); } diff --git a/src/acer386sx.h b/src/acer386sx.h deleted file mode 100644 index e84de8235..000000000 --- a/src/acer386sx.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void acer386sx_init(); diff --git a/src/acerm3a.c b/src/acerm3a.c index 769d3c0e0..a348d2b05 100644 --- a/src/acerm3a.c +++ b/src/acerm3a.c @@ -2,18 +2,23 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" -#include "acerm3a.h" +#include "device.h" +#include "model.h" + static int acerm3a_index; -static void acerm3a_out(uint16_t port, uint8_t val, void *p) + +static void acerm3a_write(uint16_t port, uint8_t val, void *p) { if (port == 0xea) acerm3a_index = val; } -static uint8_t acerm3a_in(uint16_t port, void *p) + +static uint8_t acerm3a_read(uint16_t port, void *p) { if (port == 0xeb) { @@ -26,7 +31,8 @@ static uint8_t acerm3a_in(uint16_t port, void *p) return 0xff; } -void acerm3a_io_init() + +void acerm3a_io_init(void) { - io_sethandler(0x00ea, 0x0002, acerm3a_in, NULL, NULL, acerm3a_out, NULL, NULL, NULL); + io_sethandler(0x00ea, 0x0002, acerm3a_read, NULL, NULL, acerm3a_write, NULL, NULL, NULL); } diff --git a/src/acerm3a.h b/src/acerm3a.h deleted file mode 100644 index 300531940..000000000 --- a/src/acerm3a.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void acerm3a_io_init(); diff --git a/src/ali1429.c b/src/ali1429.c index e0c348829..7c24efcb2 100644 --- a/src/ali1429.c +++ b/src/ali1429.c @@ -6,13 +6,15 @@ #include "cpu/cpu.h" #include "io.h" #include "mem.h" +#include "device.h" +#include "model.h" -#include "ali1429.h" static int ali1429_index; static uint8_t ali1429_regs[256]; -static void ali1429_recalc() + +static void ali1429_recalc(void) { int c; @@ -75,12 +77,13 @@ uint8_t ali1429_read(uint16_t port, void *priv) } -void ali1429_reset() +void ali1429_reset(void) { memset(ali1429_regs, 0xff, 256); } -void ali1429_init() + +void ali1429_init(void) { io_sethandler(0x0022, 0x0002, ali1429_read, NULL, NULL, ali1429_write, NULL, NULL, NULL); } diff --git a/src/ali1429.h b/src/ali1429.h deleted file mode 100644 index baea23a44..000000000 --- a/src/ali1429.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void ali1429_init(); -void ali1429_reset(); diff --git a/src/amstrad.c b/src/amstrad.c index a6dacab9c..cb18923d7 100644 --- a/src/amstrad.c +++ b/src/amstrad.c @@ -1,15 +1,18 @@ #include #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" +#include "device.h" +#include "model.h" #include "keyboard.h" #include "lpt.h" #include "mouse.h" -#include "amstrad.h" static uint8_t amstrad_dead; -uint8_t amstrad_read(uint16_t port, void *priv) + +static uint8_t amstrad_read(uint16_t port, void *priv) { pclog("amstrad_read : %04X\n",port); switch (port) @@ -26,7 +29,8 @@ uint8_t amstrad_read(uint16_t port, void *priv) return 0xff; } -void amstrad_write(uint16_t port, uint8_t val, void *priv) + +static void amstrad_write(uint16_t port, uint8_t val, void *priv) { switch (port) { @@ -36,6 +40,7 @@ void amstrad_write(uint16_t port, uint8_t val, void *priv) } } + static uint8_t mousex, mousey; static void amstrad_mouse_write(uint16_t addr, uint8_t val, void *p) { @@ -80,7 +85,8 @@ static uint8_t mouse_amstrad_poll(int x, int y, int z, int b, void *p) return(0); } -static void *mouse_amstrad_init() + +static void *mouse_amstrad_init(void) { mouse_amstrad_t *mouse = (mouse_amstrad_t *)malloc(sizeof(mouse_amstrad_t)); memset(mouse, 0, sizeof(mouse_amstrad_t)); @@ -88,6 +94,7 @@ static void *mouse_amstrad_init() return mouse; } + static void mouse_amstrad_close(void *p) { mouse_amstrad_t *mouse = (mouse_amstrad_t *)p; @@ -95,6 +102,7 @@ static void mouse_amstrad_close(void *p) free(mouse); } + mouse_t mouse_amstrad = { "Amstrad mouse", @@ -105,7 +113,8 @@ mouse_t mouse_amstrad = mouse_amstrad_poll }; -void amstrad_init() + +void amstrad_init(void) { lpt2_remove_ams(); diff --git a/src/amstrad.h b/src/amstrad.h deleted file mode 100644 index 1d4130f49..000000000 --- a/src/amstrad.h +++ /dev/null @@ -1,3 +0,0 @@ -void amstrad_init(); - -extern mouse_t mouse_amstrad; diff --git a/src/compaq.c b/src/compaq.c index a8f8e8570..b5dae9e7b 100644 --- a/src/compaq.c +++ b/src/compaq.c @@ -2,7 +2,11 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "mem.h" +#include "device.h" +#include "model.h" + /* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */ @@ -14,30 +18,40 @@ uint8_t compaq_read_ram(uint32_t addr, void *priv) addreadlookup(mem_logical_addr, addr); return ram[addr]; } + + uint16_t compaq_read_ramw(uint32_t addr, void *priv) { addr = (addr & 0x7ffff) + 0x80000; addreadlookup(mem_logical_addr, addr); return *(uint16_t *)&ram[addr]; } + + uint32_t compaq_read_raml(uint32_t addr, void *priv) { addr = (addr & 0x7ffff) + 0x80000; addreadlookup(mem_logical_addr, addr); return *(uint32_t *)&ram[addr]; } + + void compaq_write_ram(uint32_t addr, uint8_t val, void *priv) { addr = (addr & 0x7ffff) + 0x80000; addwritelookup(mem_logical_addr, addr); mem_write_ramb_page(addr, val, &pages[addr >> 12]); } + + void compaq_write_ramw(uint32_t addr, uint16_t val, void *priv) { addr = (addr & 0x7ffff) + 0x80000; addwritelookup(mem_logical_addr, addr); mem_write_ramw_page(addr, val, &pages[addr >> 12]); } + + void compaq_write_raml(uint32_t addr, uint32_t val, void *priv) { addr = (addr & 0x7ffff) + 0x80000; @@ -45,7 +59,8 @@ void compaq_write_raml(uint32_t addr, uint32_t val, void *priv) mem_write_raml_page(addr, val, &pages[addr >> 12]); } -void compaq_init() + +void compaq_init(void) { mem_mapping_add(&compaq_ram_mapping, 0xfa0000, 0x60000, compaq_read_ram, compaq_read_ramw, compaq_read_raml, diff --git a/src/compaq.h b/src/compaq.h deleted file mode 100644 index d9944de71..000000000 --- a/src/compaq.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void compaq_init(); diff --git a/src/headland.c b/src/headland.c index 62e6dd076..a80c1b876 100644 --- a/src/headland.c +++ b/src/headland.c @@ -5,13 +5,15 @@ #include "cpu/cpu.h" #include "io.h" #include "mem.h" +#include "device.h" +#include "model.h" -#include "headland.h" static int headland_index; static uint8_t headland_regs[256]; -void headland_write(uint16_t addr, uint8_t val, void *priv) + +static void headland_write(uint16_t addr, uint8_t val, void *priv) { if (addr & 1) { @@ -31,7 +33,8 @@ void headland_write(uint16_t addr, uint8_t val, void *priv) headland_index = val; } -uint8_t headland_read(uint16_t addr, void *priv) + +static uint8_t headland_read(uint16_t addr, void *priv) { if (addr & 1) { @@ -42,7 +45,8 @@ uint8_t headland_read(uint16_t addr, void *priv) return headland_index; } -void headland_init() + +void headland_init(void) { io_sethandler(0x0022, 0x0002, headland_read, NULL, NULL, headland_write, NULL, NULL, NULL); } diff --git a/src/headland.h b/src/headland.h deleted file mode 100644 index 0425237bb..000000000 --- a/src/headland.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void headland_init(); diff --git a/src/i430fx.c b/src/i430fx.c index a5100d789..4ea5db75c 100644 --- a/src/i430fx.c +++ b/src/i430fx.c @@ -8,24 +8,25 @@ * * Implementation of the Intel 430FX PCISet chip. * - * Version: @(#)i430fx.c 1.0.0 2017/05/30 + * Version: @(#)i430fx.c 1.0.1 2017/06/17 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include - #include "ibm.h" +#include "cpu/cpu.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "i430fx.h" static uint8_t card_i430fx[256]; + static void i430fx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) @@ -46,7 +47,8 @@ static void i430fx_map(uint32_t addr, uint32_t size, int state) flushmmucache_nopc(); } -void i430fx_write(int func, int addr, uint8_t val, void *priv) + +static void i430fx_write(int func, int addr, uint8_t val, void *priv) { if (func) return; @@ -127,7 +129,8 @@ void i430fx_write(int func, int addr, uint8_t val, void *priv) card_i430fx[addr] = val; } -uint8_t i430fx_read(int func, int addr, void *priv) + +static uint8_t i430fx_read(int func, int addr, void *priv) { if (func) return 0xff; @@ -135,7 +138,8 @@ uint8_t i430fx_read(int func, int addr, void *priv) return card_i430fx[addr]; } -void i430fx_reset(void) + +static void i430fx_reset(void) { memset(card_i430fx, 0, 256); card_i430fx[0x00] = 0x86; card_i430fx[0x01] = 0x80; /*Intel*/ @@ -168,12 +172,14 @@ void i430fx_reset(void) } } -void i430fx_pci_reset(void) + +static void i430fx_pci_reset(void) { i430fx_write(0, 0x59, 0x00, NULL); } -void i430fx_init() + +void i430fx_init(void) { pci_add_specific(0, i430fx_read, i430fx_write, NULL); diff --git a/src/i430fx.h b/src/i430fx.h deleted file mode 100644 index 1904ea0f5..000000000 --- a/src/i430fx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430FX PCISet chip. - * - * Version: @(#)i430fx.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -void i430fx_init(); diff --git a/src/i430hx.c b/src/i430hx.c index 1e83fa513..699fab21b 100644 --- a/src/i430hx.c +++ b/src/i430hx.c @@ -8,25 +8,26 @@ * * Implementation of the Intel 430HX PCISet chip. * - * Version: @(#)i430hx.c 1.0.0 2017/05/30 + * Version: @(#)i430hx.c 1.0.1 2017/06/17 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include - #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "i430hx.h" static uint8_t card_i430hx[256]; + static void i430hx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) @@ -47,7 +48,8 @@ static void i430hx_map(uint32_t addr, uint32_t size, int state) flushmmucache_nopc(); } -void i430hx_write(int func, int addr, uint8_t val, void *priv) + +static void i430hx_write(int func, int addr, uint8_t val, void *priv) { if (func) return; @@ -126,7 +128,8 @@ void i430hx_write(int func, int addr, uint8_t val, void *priv) card_i430hx[addr] = val; } -uint8_t i430hx_read(int func, int addr, void *priv) + +static uint8_t i430hx_read(int func, int addr, void *priv) { if (func) return 0xff; @@ -134,7 +137,8 @@ uint8_t i430hx_read(int func, int addr, void *priv) return card_i430hx[addr]; } -void i430hx_reset(void) + +static void i430hx_reset(void) { memset(card_i430hx, 0, 256); card_i430hx[0x00] = 0x86; card_i430hx[0x01] = 0x80; /*Intel*/ @@ -156,12 +160,14 @@ void i430hx_reset(void) card_i430hx[0x72] = 0x02; } -void i430hx_pci_reset(void) + +static void i430hx_pci_reset(void) { i430hx_write(0, 0x59, 0x00, NULL); } -void i430hx_init() + +void i430hx_init(void) { pci_add_specific(0, i430hx_read, i430hx_write, NULL); diff --git a/src/i430hx.h b/src/i430hx.h deleted file mode 100644 index 4ef96e6ae..000000000 --- a/src/i430hx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430HX PCISet chip. - * - * Version: @(#)i430hx.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -void i430hx_init(); diff --git a/src/i430lx.c b/src/i430lx.c index ff22680bf..be015391d 100644 --- a/src/i430lx.c +++ b/src/i430lx.c @@ -8,24 +8,25 @@ * * Implementation of the Intel 430LX PCISet chip. * - * Version: @(#)i430lx.c 1.0.0 2017/05/30 + * Version: @(#)i430lx.c 1.0.1 2017/06/17 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include - #include "ibm.h" +#include "cpu/cpu.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "i430lx.h" static uint8_t card_i430lx[256]; + static void i430lx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) @@ -46,7 +47,8 @@ static void i430lx_map(uint32_t addr, uint32_t size, int state) flushmmucache_nopc(); } -void i430lx_write(int func, int addr, uint8_t val, void *priv) + +static void i430lx_write(int func, int addr, uint8_t val, void *priv) { if (func) return; @@ -130,7 +132,8 @@ void i430lx_write(int func, int addr, uint8_t val, void *priv) card_i430lx[addr] = val; } -uint8_t i430lx_read(int func, int addr, void *priv) + +static uint8_t i430lx_read(int func, int addr, void *priv) { if (func) return 0xff; @@ -138,7 +141,8 @@ uint8_t i430lx_read(int func, int addr, void *priv) return card_i430lx[addr]; } -void i430lx_reset(void) + +static void i430lx_reset(void) { memset(card_i430lx, 0, 256); card_i430lx[0x00] = 0x86; card_i430lx[0x01] = 0x80; /*Intel*/ @@ -153,12 +157,14 @@ void i430lx_reset(void) card_i430lx[0x60] = card_i430lx[0x61] = card_i430lx[0x62] = card_i430lx[0x63] = card_i430lx[0x64] = 0x02; } -void i430lx_pci_reset(void) + +static void i430lx_pci_reset(void) { i430lx_write(0, 0x59, 0x00, NULL); } -void i430lx_init() + +void i430lx_init(void) { pci_add_specific(0, i430lx_read, i430lx_write, NULL); diff --git a/src/i430lx.h b/src/i430lx.h deleted file mode 100644 index 23153f7f4..000000000 --- a/src/i430lx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430LX PCISet chip. - * - * Version: @(#)i430lx.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -void i430lx_init(); diff --git a/src/i430nx.c b/src/i430nx.c index 2827b293b..b17bde0fe 100644 --- a/src/i430nx.c +++ b/src/i430nx.c @@ -8,24 +8,25 @@ * * Implementation of the Intel 430NX PCISet chip. * - * Version: @(#)i430nx.c 1.0.0 2017/05/30 + * Version: @(#)i430nx.c 1.0.1 2017/06/17 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include - #include "ibm.h" +#include "cpu/cpu.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "i430nx.h" static uint8_t card_i430nx[256]; + static void i430nx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) @@ -46,7 +47,8 @@ static void i430nx_map(uint32_t addr, uint32_t size, int state) flushmmucache_nopc(); } -void i430nx_write(int func, int addr, uint8_t val, void *priv) + +static void i430nx_write(int func, int addr, uint8_t val, void *priv) { if (func) return; @@ -127,7 +129,8 @@ void i430nx_write(int func, int addr, uint8_t val, void *priv) card_i430nx[addr] = val; } -uint8_t i430nx_read(int func, int addr, void *priv) + +static uint8_t i430nx_read(int func, int addr, void *priv) { if (func) return 0xff; @@ -135,7 +138,8 @@ uint8_t i430nx_read(int func, int addr, void *priv) return card_i430nx[addr]; } -void i430nx_reset(void) + +static void i430nx_reset(void) { memset(card_i430nx, 0, 256); card_i430nx[0x00] = 0x86; card_i430nx[0x01] = 0x80; /*Intel*/ @@ -151,12 +155,14 @@ void i430nx_reset(void) card_i430nx[0x66] = card_i430nx[0x67] = 0x02; } -void i430nx_pci_reset(void) + +static void i430nx_pci_reset(void) { i430nx_write(0, 0x59, 0x00, NULL); } -void i430nx_init() + +void i430nx_init(void) { pci_add_specific(0, i430nx_read, i430nx_write, NULL); diff --git a/src/i430nx.h b/src/i430nx.h deleted file mode 100644 index 93d1466bb..000000000 --- a/src/i430nx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430NX PCISet chip. - * - * Version: @(#)i430nx.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -void i430nx_init(); diff --git a/src/i430vx.c b/src/i430vx.c index be47835fa..967701251 100644 --- a/src/i430vx.c +++ b/src/i430vx.c @@ -8,25 +8,26 @@ * * Implementation of the Intel 430VX PCISet chip. * - * Version: @(#)i430vx.c 1.0.1 2017/06/02 + * Version: @(#)i430vx.c 1.0.2 2017/06/17 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include - #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "i430vx.h" static uint8_t card_i430vx[256]; + static void i430vx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) @@ -47,7 +48,8 @@ static void i430vx_map(uint32_t addr, uint32_t size, int state) flushmmucache_nopc(); } -void i430vx_write(int func, int addr, uint8_t val, void *priv) + +static void i430vx_write(int func, int addr, uint8_t val, void *priv) { if (func) return; @@ -129,7 +131,8 @@ void i430vx_write(int func, int addr, uint8_t val, void *priv) card_i430vx[addr] = val; } -uint8_t i430vx_read(int func, int addr, void *priv) + +static uint8_t i430vx_read(int func, int addr, void *priv) { if (func) return 0xff; @@ -137,7 +140,8 @@ uint8_t i430vx_read(int func, int addr, void *priv) return card_i430vx[addr]; } -void i430vx_reset(void) + +static void i430vx_reset(void) { memset(card_i430vx, 0, 256); card_i430vx[0x00] = 0x86; card_i430vx[0x01] = 0x80; /*Intel*/ @@ -159,12 +163,14 @@ void i430vx_reset(void) card_i430vx[0x78] = 0x23; } -void i430vx_pci_reset(void) + +static void i430vx_pci_reset(void) { i430vx_write(0, 0x59, 0x00, NULL); } -void i430vx_init() + +void i430vx_init(void) { pci_add_specific(0, i430vx_read, i430vx_write, NULL); diff --git a/src/i430vx.h b/src/i430vx.h deleted file mode 100644 index 8ed77f3fe..000000000 --- a/src/i430vx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 430VX PCISet chip. - * - * Version: @(#)i430vx.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -void i430vx_init(); diff --git a/src/i440fx.c b/src/i440fx.c index 1a19b10bc..811215c63 100644 --- a/src/i440fx.c +++ b/src/i440fx.c @@ -8,25 +8,26 @@ * * Implementation of the Intel 440FX PCISet chip. * - * Version: @(#)i440fx.c 1.0.0 2017/05/30 + * Version: @(#)i440fx.c 1.0.1 2017/06/17 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #include - #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "i440fx.h" static uint8_t card_i440fx[256]; + static void i440fx_map(uint32_t addr, uint32_t size, int state) { switch (state & 3) @@ -47,7 +48,8 @@ static void i440fx_map(uint32_t addr, uint32_t size, int state) flushmmucache_nopc(); } -void i440fx_write(int func, int addr, uint8_t val, void *priv) + +static void i440fx_write(int func, int addr, uint8_t val, void *priv) { if (func) return; @@ -126,7 +128,8 @@ void i440fx_write(int func, int addr, uint8_t val, void *priv) card_i440fx[addr] = val; } -uint8_t i440fx_read(int func, int addr, void *priv) + +static uint8_t i440fx_read(int func, int addr, void *priv) { if (func) return 0xff; @@ -134,7 +137,8 @@ uint8_t i440fx_read(int func, int addr, void *priv) return card_i440fx[addr]; } -void i440fx_reset(void) + +static void i440fx_reset(void) { memset(card_i440fx, 0, 256); card_i440fx[0x00] = 0x86; card_i440fx[0x01] = 0x80; /*Intel*/ @@ -160,12 +164,14 @@ void i440fx_reset(void) card_i440fx[0x72] = 0x02; } -void i440fx_pci_reset(void) + +static void i440fx_pci_reset(void) { i440fx_write(0, 0x59, 0x00, NULL); } -void i440fx_init() + +void i440fx_init(void) { pci_add_specific(0, i440fx_read, i440fx_write, NULL); diff --git a/src/i440fx.h b/src/i440fx.h deleted file mode 100644 index 3ce8b744f..000000000 --- a/src/i440fx.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of the Intel 440FX PCISet chip. - * - * Version: @(#)i440fx.h 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - -void i440fx_init(); diff --git a/src/jim.c b/src/jim.c index ea7c5d64d..6ac1b16f0 100644 --- a/src/jim.c +++ b/src/jim.c @@ -4,9 +4,14 @@ #include #include #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" +#include "device.h" +#include "model.h" + uint8_t europcdat[16]; + struct { uint8_t dat[16]; @@ -14,7 +19,8 @@ struct int addr; } europc_rtc; -void writejim(uint16_t addr, uint8_t val, void *p) + +static void writejim(uint16_t addr, uint8_t val, void *p) { if ((addr&0xFF0)==0x250) europcdat[addr&0xF]=val; switch (addr) @@ -39,7 +45,8 @@ void writejim(uint16_t addr, uint8_t val, void *p) } } -uint8_t readjim(uint16_t addr, void *p) + +static uint8_t readjim(uint16_t addr, void *p) { switch (addr) { @@ -61,7 +68,8 @@ uint8_t readjim(uint16_t addr, void *p) return 0; } -void jim_init() + +void jim_init(void) { uint8_t viddat; memset(europc_rtc.dat,0,16); diff --git a/src/jim.h b/src/jim.h deleted file mode 100644 index 64eb006dc..000000000 --- a/src/jim.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void jim_init(); diff --git a/src/keyboard_olim24.h b/src/keyboard_olim24.h index 5ea3af04f..305a3e245 100644 --- a/src/keyboard_olim24.h +++ b/src/keyboard_olim24.h @@ -1,5 +1,3 @@ void keyboard_olim24_init(); void keyboard_olim24_reset(); void keyboard_olim24_poll(); - -extern mouse_t mouse_olim24; diff --git a/src/laserxt.c b/src/laserxt.c index 9ba6e3500..33afbce37 100644 --- a/src/laserxt.c +++ b/src/laserxt.c @@ -1,14 +1,19 @@ /*This is the chipset used in the LaserXT series model*/ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" +#include "device.h" +#include "model.h" + static int laserxt_emspage[4]; static int laserxt_emscontrol[4]; static mem_mapping_t laserxt_ems_mapping[4]; static int laserxt_ems_baseaddr_index = 0; -uint32_t get_laserxt_ems_addr(uint32_t addr) + +static uint32_t get_laserxt_ems_addr(uint32_t addr) { if(laserxt_emspage[(addr >> 14) & 3] & 0x80) { @@ -17,7 +22,8 @@ uint32_t get_laserxt_ems_addr(uint32_t addr) return addr; } -void laserxt_write(uint16_t port, uint8_t val, void *priv) + +static void laserxt_write(uint16_t port, uint8_t val, void *priv) { int i; uint32_t paddr, vaddr; @@ -68,7 +74,8 @@ void laserxt_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t laserxt_read(uint16_t port, void *priv) + +static uint8_t laserxt_read(uint16_t port, void *priv) { switch (port) { @@ -82,14 +89,16 @@ uint8_t laserxt_read(uint16_t port, void *priv) return 0xff; } -void mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) + +static void mem_write_laserxtems(uint32_t addr, uint8_t val, void *priv) { addr = get_laserxt_ems_addr(addr); if (addr < (mem_size << 10)) ram[addr] = val; } -uint8_t mem_read_laserxtems(uint32_t addr, void *priv) + +static uint8_t mem_read_laserxtems(uint32_t addr, void *priv) { uint8_t val = 0xFF; addr = get_laserxt_ems_addr(addr); @@ -98,7 +107,8 @@ uint8_t mem_read_laserxtems(uint32_t addr, void *priv) return val; } -void laserxt_init() + +void laserxt_init(void) { int i; diff --git a/src/laserxt.h b/src/laserxt.h deleted file mode 100644 index 08919ff6a..000000000 --- a/src/laserxt.h +++ /dev/null @@ -1 +0,0 @@ -void laserxt_init(); diff --git a/src/model.c b/src/model.c index d564138c8..7645ae58e 100644 --- a/src/model.c +++ b/src/model.c @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)model.c 1.0.1 2017/06/03 + * Version: @(#)model.c 1.0.2 2017/06/17 * * Authors: Sarah Walker, * Miran Grca, @@ -29,10 +29,6 @@ #include "mouse_ps2.h" #include "cdrom.h" -#include "acerm3a.h" -#include "ali1429.h" -#include "amstrad.h" -#include "compaq.h" #include "disc.h" #include "dma.h" #include "fdc.h" @@ -40,43 +36,27 @@ #include "fdc37c669.h" #include "fdc37c932fr.h" #include "gameport.h" -#include "headland.h" -#include "i430fx.h" -#include "i430hx.h" -#include "i430lx.h" -#include "i430nx.h" -#include "i430vx.h" -#include "i440fx.h" #include "i82335.h" #include "ide.h" #include "intel.h" #include "intel_flash.h" -#include "jim.h" #include "keyboard_amstrad.h" #include "keyboard_at.h" #include "keyboard_olim24.h" #include "keyboard_pcjr.h" #include "keyboard_xt.h" -#include "laserxt.h" #include "lpt.h" #include "mem.h" #include "memregs.h" -#include "neat.h" #include "nmi.h" #include "nvr.h" -#include "olivetti_m24.h" -#include "opti495.h" #include "pc87306.h" #include "pci.h" #include "pic.h" #include "piix.h" #include "pit.h" -#include "ps1.h" -#include "ps2.h" #include "ps2_mca.h" -#include "scat.h" #include "serial.h" -#include "sis496.h" #include "sis85c471.h" #include "sio.h" #include "sound/snd_ps1.h" diff --git a/src/model.h b/src/model.h index 0fc8b6227..02b8ddcb8 100644 --- a/src/model.h +++ b/src/model.h @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)model.h 1.0.1 2017/06/03 + * Version: @(#)model.h 1.0.2 2017/06/17 * * Authors: Sarah Walker, * Miran Grca, @@ -50,10 +50,12 @@ typedef struct { } MODEL; -extern MODEL models[]; -extern int model; +/* Global variables. */ +extern MODEL models[]; +extern int model; +/* Core functions. */ extern int model_count(void); extern int model_getromset(void); extern int model_getmodel(int romset); @@ -66,4 +68,42 @@ extern int model_getromset_ex(int m); extern char *model_get_internal_name_ex(int m); extern int model_get_nvrmask(int m); + +/* Global variables for boards and systems. */ +#ifdef EMU_MOUSE_H +extern mouse_t mouse_amstrad; +extern mouse_t mouse_olim24; +#endif + + +/* Initialization functions for boards and systems. */ +extern void acer386sx_init(void); +extern void acerm3a_io_init(void); +extern void ali1429_init(void); +extern void ali1429_reset(void); +extern void amstrad_init(void); +extern void compaq_init(void); +extern void headland_init(void); +extern void i430fx_init(void); +extern void i430hx_init(void); +extern void i430lx_init(void); +extern void i430nx_init(void); +extern void i430vx_init(void); +extern void i440fx_init(void); +extern void jim_init(void); +extern void laserxt_init(void); +extern void neat_init(void); +extern void olivetti_m24_init(void); +extern void opti495_init(void); + +extern void ps1mb_init(void); +extern void ps1mb_m2121_init(void); +extern void ps1mb_m2133_init(void); + +extern void ps2board_init(void); + +extern void scat_init(void); +extern void sis496_init(void); + + #endif /*EMU_MODEL_H*/ diff --git a/src/mouse.c b/src/mouse.c index 08850d4d7..85075d40b 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,10 +1,12 @@ #include "ibm.h" +#include "cpu/cpu.h" +#include "device.h" #include "mouse.h" #include "mouse_serial.h" #include "mouse_ps2.h" #include "mouse_bus.h" -#include "amstrad.h" -#include "keyboard_olim24.h" +#include "model.h" +//#include "keyboard_olim24.h" static mouse_t *mouse_list[] = { diff --git a/src/mouse_serial.c b/src/mouse_serial.c index bb855ecc0..fdda61e13 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * Based on the 86Box Serial Mouse driver as a framework. * - * Version: @(#)mouse_serial.c 1.0.3 2017/05/07 + * Version: @(#)mouse_serial.c 1.0.4 2017/06/11 * * Author: Fred N. van Kempen, */ @@ -22,13 +22,18 @@ #include "mouse_serial.h" +#define SERMOUSE_TYPE_MSYSTEMS 1 /* Mouse Systems */ +#define SERMOUSE_TYPE_MICROSOFT 2 /* Microsoft */ +#define SERMOUSE_TYPE_LOGITECH 3 /* Logitech */ + + typedef struct mouse_serial_t { - int port; + int8_t port, + type; int pos, delay; int oldb; SERIAL *serial; - int is_ms_format; } mouse_serial_t; @@ -51,12 +56,16 @@ sermouse_timer(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; ms->delay = 0; - if (ms->pos == -1) - { - ms->pos = 0; + switch(ms->type) { + case SERMOUSE_TYPE_MICROSOFT: /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M'); + serial_write_fifo(ms->serial, 'M', 1); + break; + + default: + /* No action needed. */ + break; } } @@ -65,53 +74,63 @@ static uint8_t sermouse_poll(int x, int y, int z, int b, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - uint8_t data[3]; + uint8_t buff[16]; + int len; if (!x && !y && b == ms->oldb) return(1); ms->oldb = b; + + if (ms->type == SERMOUSE_TYPE_MSYSTEMS) y = -y; + if (x>127) x = 127; if (y>127) y = 127; if (x<-128) x = -128; if (y<-128) y = -128; - /* Use Microsoft format. */ - data[0] = 0x40; - data[0] |= (((y>>6)&3)<<2); - data[0] |= ((x>>6)&3); - if (b&1) data[0] |= 0x20; - if (b&2) data[0] |= 0x10; - data[1] = x & 0x3F; - data[2] = y & 0x3F; + len = 0; + switch(ms->type) { + case SERMOUSE_TYPE_MSYSTEMS: + buff[0] = 0x80; + buff[0] |= (b&0x01) ? 0x00 : 0x04; /* left button */ + buff[0] |= (b&0x02) ? 0x00 : 0x01; /* middle button */ + buff[0] |= (b&0x04) ? 0x00 : 0x02; /* right button */ + buff[1] = x; + buff[2] = y; + buff[3] = x; /* same as byte 1 */ + buff[4] = y; /* same as byte 2 */ + len = 5; + break; + + case SERMOUSE_TYPE_MICROSOFT: + buff[0] = 0x40; + buff[0] |= (((y>>6)&03)<<2); + buff[0] |= ((x>>6)&03); + if (b&0x01) buff[0] |= 0x20; + if (b&0x02) buff[0] |= 0x10; + buff[1] = x & 0x3F; + buff[2] = y & 0x3F; + len = 3; + break; + + case SERMOUSE_TYPE_LOGITECH: + break; + } + +#if 0 + pclog("Mouse_Serial(%d): [", ms->type); + for (b=0; bserial, data[0]); - serial_write_fifo(ms->serial, data[1]); - serial_write_fifo(ms->serial, data[2]); + for (b=0; bserial, buff[b], 1); return(0); } -static void * -sermouse_init(void) -{ - mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); - memset(ms, 0x00, sizeof(mouse_serial_t)); - ms->port = SERMOUSE_PORT; - - /* Attach a serial port to the mouse. */ - ms->serial = serial_attach(ms->port, sermouse_callback, ms); - - timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); - - return(ms); -} - - static void sermouse_close(void *priv) { @@ -124,59 +143,14 @@ sermouse_close(void *priv) } -mouse_t mouse_serial_microsoft = { - "Microsoft 2-button mouse (serial)", - "msserial", - MOUSE_TYPE_SERIAL, - sermouse_init, - sermouse_close, - sermouse_poll -}; - -static uint8_t -mssystems_mouse_poll(int x, int y, int z, int b, void *priv) -{ - mouse_serial_t *ms = (mouse_serial_t *)priv; - uint8_t data[5]; - - if (!x && !y && b == ms->oldb) return(1); - - ms->oldb = b; - - y=-y; - - if (x>127) x = 127; - if (y>127) y = 127; - if (x<-128) x = -128; - if (y<-128) y = -128; - - data[0] = 0x80; - data[0] |= (b & 0x01 ? 0x00 : 0x04); /*Left button*/ - data[0] |= (b & 0x02 ? 0x00 : 0x01); /*Middle button*/ - data[0] |= (b & 0x04 ? 0x00 : 0x02); /*Right button*/ - data[1] = x; - data[2] = y; - data[3] = x;/*Same as byte 1*/ - data[4] = y;/*Same as byte 2*/ - - pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); - - serial_write_fifo(ms->serial, data[0]); - serial_write_fifo(ms->serial, data[1]); - serial_write_fifo(ms->serial, data[2]); - serial_write_fifo(ms->serial, data[3]); - serial_write_fifo(ms->serial, data[4]); - - return(0); -} - static void * -mssystems_mouse_init(void) +sermouse_init(int type) { mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); memset(ms, 0x00, sizeof(mouse_serial_t)); ms->port = SERMOUSE_PORT; - + ms->type = type; + /* Attach a serial port to the mouse. */ ms->serial = serial_attach(ms->port, sermouse_callback, ms); @@ -185,11 +159,36 @@ mssystems_mouse_init(void) return(ms); } + +static void * +sermouse_init_microsoft(void) +{ + return(sermouse_init(SERMOUSE_TYPE_MICROSOFT)); +} + + +static void * +sermouse_init_msystems(void) +{ + return(sermouse_init(SERMOUSE_TYPE_MSYSTEMS)); +} + + mouse_t mouse_msystems = { "Mouse Systems Mouse (serial)", "mssystems", MOUSE_TYPE_MSYSTEMS, - mssystems_mouse_init, + sermouse_init_msystems, sermouse_close, - mssystems_mouse_poll -}; \ No newline at end of file + sermouse_poll +}; + + +mouse_t mouse_serial_microsoft = { + "Microsoft 2-button mouse (serial)", + "msserial", + MOUSE_TYPE_SERIAL, + sermouse_init_microsoft, + sermouse_close, + sermouse_poll +}; diff --git a/src/neat.c b/src/neat.c index ef50ab080..85063e591 100644 --- a/src/neat.c +++ b/src/neat.c @@ -3,14 +3,18 @@ */ /*This is the chipset used in the AMI 286 clone model*/ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" -#include "neat.h" +#include "device.h" +#include "model.h" + static uint8_t neat_regs[256]; static int neat_index; static int neat_emspage[4]; -void neat_write(uint16_t port, uint8_t val, void *priv) + +static void neat_write(uint16_t port, uint8_t val, void *priv) { switch (port) { @@ -38,7 +42,8 @@ void neat_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t neat_read(uint16_t port, void *priv) + +static uint8_t neat_read(uint16_t port, void *priv) { switch (port) { @@ -51,17 +56,22 @@ uint8_t neat_read(uint16_t port, void *priv) return 0xff; } -void neat_writeems(uint32_t addr, uint8_t val) + +#if NOT_USED +static void neat_writeems(uint32_t addr, uint8_t val) { ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)] = val; } -uint8_t neat_readems(uint32_t addr) + +static uint8_t neat_readems(uint32_t addr) { return ram[(neat_emspage[(addr >> 14) & 3] << 14) + (addr & 0x3FFF)]; } +#endif -void neat_init() + +void neat_init(void) { io_sethandler(0x0022, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); io_sethandler(0x0208, 0x0002, neat_read, NULL, NULL, neat_write, NULL, NULL, NULL); diff --git a/src/neat.h b/src/neat.h deleted file mode 100644 index 7a9b7d07d..000000000 --- a/src/neat.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void neat_init(); diff --git a/src/olivetti_m24.c b/src/olivetti_m24.c index d60f312ce..3c9e24ba7 100644 --- a/src/olivetti_m24.c +++ b/src/olivetti_m24.c @@ -2,10 +2,13 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" -#include "olivetti_m24.h" +#include "device.h" +#include "model.h" -uint8_t olivetti_m24_read(uint16_t port, void *priv) + +static uint8_t olivetti_m24_read(uint16_t port, void *priv) { switch (port) { @@ -17,7 +20,8 @@ uint8_t olivetti_m24_read(uint16_t port, void *priv) return 0xff; } -void olivetti_m24_init() + +void olivetti_m24_init(void) { io_sethandler(0x0066, 0x0002, olivetti_m24_read, NULL, NULL, NULL, NULL, NULL, NULL); } diff --git a/src/olivetti_m24.h b/src/olivetti_m24.h deleted file mode 100644 index 89ee10595..000000000 --- a/src/olivetti_m24.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void olivetti_m24_init(); diff --git a/src/opti495.c b/src/opti495.c index 9bf55d854..b9a6e2e30 100644 --- a/src/opti495.c +++ b/src/opti495.c @@ -1,63 +1,7 @@ /*OPTi 82C495 emulation - This is the chipset used in the AMI386 model*/ -#include "ibm.h" -#include "cpu/cpu.h" -#include "io.h" -#include "mem.h" + This is the chipset used in the AMI386 model -static uint8_t optiregs[0x10]; -static int optireg; - -static void opti495_write(uint16_t addr, uint8_t val, void *p) -{ - switch (addr) - { - case 0x22: - optireg=val; - break; - case 0x24: - printf("Writing OPTI reg %02X %02X\n",optireg,val); - if (optireg>=0x20 && optireg<=0x2C) - { - optiregs[optireg-0x20]=val; - if (optireg == 0x21) - { - cpu_cache_ext_enabled = val & 0x10; - cpu_update_waitstates(); - } - if (optireg == 0x22) - { - shadowbios = !(val & 0x80); - shadowbios_write = val & 0x80; - if (shadowbios) - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); - else - mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); - } - } - break; - } -} - -static uint8_t opti495_read(uint16_t addr, void *p) -{ - switch (addr) - { - case 0x24: - if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20]; - break; - } - return 0xFF; -} - -void opti495_init() -{ - io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); - io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); - optiregs[0x22-0x20] = 0x80; -} - -/*Details for the chipset from Ralph Brown's interrupt list + Details for the chipset from Ralph Brown's interrupt list This describes the OPTi 82C493, the 82C495 seems similar except there is one more register (2C) @@ -306,5 +250,66 @@ Bit(s) Description (Table P0188) Note: the block address is forced to be a multiple of the block size by ignoring the appropriate number of the least-significant bits SeeAlso: #P0178,#P0187 - */ +#include "ibm.h" +#include "cpu/cpu.h" +#include "io.h" +#include "mem.h" +#include "device.h" +#include "model.h" + + +static uint8_t optiregs[0x10]; +static int optireg; + + +static void opti495_write(uint16_t addr, uint8_t val, void *p) +{ + switch (addr) + { + case 0x22: + optireg=val; + break; + case 0x24: + printf("Writing OPTI reg %02X %02X\n",optireg,val); + if (optireg>=0x20 && optireg<=0x2C) + { + optiregs[optireg-0x20]=val; + if (optireg == 0x21) + { + cpu_cache_ext_enabled = val & 0x10; + cpu_update_waitstates(); + } + if (optireg == 0x22) + { + shadowbios = !(val & 0x80); + shadowbios_write = val & 0x80; + if (shadowbios) + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_INTERNAL | MEM_WRITE_DISABLED); + else + mem_set_mem_state(0xf0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_INTERNAL); + } + } + break; + } +} + + +static uint8_t opti495_read(uint16_t addr, void *p) +{ + switch (addr) + { + case 0x24: + if (optireg>=0x20 && optireg<=0x2C) return optiregs[optireg-0x20]; + break; + } + return 0xFF; +} + + +void opti495_init(void) +{ + io_sethandler(0x0022, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); + io_sethandler(0x0024, 0x0001, opti495_read, NULL, NULL, opti495_write, NULL, NULL, NULL); + optiregs[0x22-0x20] = 0x80; +} diff --git a/src/opti495.h b/src/opti495.h deleted file mode 100644 index 814f313fa..000000000 --- a/src/opti495.h +++ /dev/null @@ -1 +0,0 @@ -void opti495_init(); diff --git a/src/pc.c b/src/pc.c index ef35f166e..ef456f18f 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Emulation core dispatcher. * - * Version: @(#)pc.c 1.0.5 2017/06/17 + * Version: @(#)pc.c 1.0.6 2017/06/17 * * Authors: Sarah Walker, * Miran Grca, @@ -31,8 +31,8 @@ #include "pit.h" #include "timer.h" #include "device.h" +#include "model.h" -#include "ali1429.h" #include "disc.h" #include "disc_86f.h" #include "disc_fdi.h" @@ -56,7 +56,6 @@ #include "keyboard.h" #include "plat_keyboard.h" #include "keyboard_at.h" -#include "model.h" #include "mouse.h" #include "plat_mouse.h" #include "network/network.h" @@ -72,7 +71,6 @@ #include "sound/snd_ssi2001.h" #include "video/video.h" #include "video/vid_voodoo.h" -#include "amstrad.h" #include "plat_ui.h" #ifdef WALTJE # define UNICODE diff --git a/src/ps1.c b/src/ps1.c index 0e7d5148c..f75a0f205 100644 --- a/src/ps1.c +++ b/src/ps1.c @@ -2,25 +2,30 @@ see COPYING for more details */ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" -#include "ps1.h" #include "rom.h" +#include "device.h" +#include "model.h" #include "lpt.h" #include "serial.h" + static rom_t ps1_high_rom; static uint8_t ps1_92, ps1_94, ps1_102, ps1_103, ps1_104, ps1_105, ps1_190; static int ps1_e0_addr; static uint8_t ps1_e0_regs[256]; + static struct { uint8_t status, int_status; uint8_t attention, ctrl; } ps1_hd; -uint8_t ps1_read(uint16_t port, void *p) + +static uint8_t ps1_read(uint16_t port, void *p) { uint8_t temp; @@ -59,7 +64,8 @@ uint8_t ps1_read(uint16_t port, void *p) return temp; } -void ps1_write(uint16_t port, uint8_t val, void *p) + +static void ps1_write(uint16_t port, uint8_t val, void *p) { switch (port) { @@ -120,7 +126,8 @@ void ps1_write(uint16_t port, uint8_t val, void *p) } } -void ps1mb_init() + +void ps1mb_init(void) { io_sethandler(0x0091, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, ps1_read, NULL, NULL, ps1_write, NULL, NULL, NULL); @@ -207,7 +214,7 @@ static uint8_t ps1_m2121_read(uint16_t port, void *p) return temp; } -static void ps1_m2121_recalc_memory() +static void ps1_m2121_recalc_memory(void) { /*Enable first 512kb*/ mem_set_mem_state(0x00000, 0x80000, (ps1_e0_regs[0] & 0x01) ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); @@ -277,7 +284,7 @@ void ps1_m2121_write(uint16_t port, uint8_t val, void *p) } } -void ps1mb_m2121_init() +void ps1mb_m2121_init(void) { io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); @@ -300,7 +307,7 @@ void ps1mb_m2121_init() mem_remap_top_384k(); } -void ps1mb_m2133_init() +void ps1mb_m2133_init(void) { io_sethandler(0x0091, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, ps1_m2121_read, NULL, NULL, ps1_m2121_write, NULL, NULL, NULL); diff --git a/src/ps1.h b/src/ps1.h deleted file mode 100644 index 506983665..000000000 --- a/src/ps1.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void ps1mb_init(); -void ps1mb_m2121_init(); -void ps1mb_m2133_init(); diff --git a/src/ps2.c b/src/ps2.c index 1f91591d1..6d9075358 100644 --- a/src/ps2.c +++ b/src/ps2.c @@ -1,20 +1,25 @@ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" -#include "ps2.h" #include "rom.h" +#include "device.h" +#include "model.h" #include "lpt.h" #include "serial.h" + static uint8_t ps2_92, ps2_94, ps2_102, ps2_103, ps2_104, ps2_105, ps2_190; + static struct { uint8_t status, int_status; uint8_t attention, ctrl; } ps2_hd; -uint8_t ps2_read(uint16_t port, void *p) + +static uint8_t ps2_read(uint16_t port, void *p) { uint8_t temp; @@ -53,7 +58,7 @@ uint8_t ps2_read(uint16_t port, void *p) return temp; } -void ps2_write(uint16_t port, uint8_t val, void *p) +static void ps2_write(uint16_t port, uint8_t val, void *p) { switch (port) { @@ -114,7 +119,8 @@ void ps2_write(uint16_t port, uint8_t val, void *p) } } -void ps2board_init() + +void ps2board_init(void) { io_sethandler(0x0091, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0092, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); diff --git a/src/ps2.h b/src/ps2.h deleted file mode 100644 index 92fb6e077..000000000 --- a/src/ps2.h +++ /dev/null @@ -1 +0,0 @@ -void ps2board_init(); diff --git a/src/scat.c b/src/scat.c index 4759d0270..fdcca8a11 100644 --- a/src/scat.c +++ b/src/scat.c @@ -3,9 +3,34 @@ */ /*This is the chipset used in the Award 286 clone model*/ #include "ibm.h" +#include "cpu/cpu.h" #include "io.h" -#include "scat.h" #include "mem.h" +#include "device.h" +#include "model.h" + + +#define SCAT_DMA_WAIT_STATE_CONTROL 0x01 +#define SCAT_VERSION 0x40 +#define SCAT_CLOCK_CONTROL 0x41 +#define SCAT_PERIPHERAL_CONTROL 0x44 +#define SCAT_MISCELLANEOUS_STATUS 0x45 +#define SCAT_POWER_MANAGEMENT 0x46 +#define SCAT_ROM_ENABLE 0x48 +#define SCAT_RAM_WRITE_PROTECT 0x49 +#define SCAT_SHADOW_RAM_ENABLE_1 0x4A +#define SCAT_SHADOW_RAM_ENABLE_2 0x4B +#define SCAT_SHADOW_RAM_ENABLE_3 0x4C +#define SCAT_DRAM_CONFIGURATION 0x4D +#define SCAT_EXTENDED_BOUNDARY 0x4E +#define SCAT_EMS_CONTROL 0x4F + + +typedef struct { + uint8_t regs_2x8; + uint8_t regs_2x9; +} scat_t; + static uint8_t scat_regs[256]; static int scat_index; @@ -17,7 +42,8 @@ static uint32_t scat_xms_bound; static mem_mapping_t scat_shadowram_mapping; static mem_mapping_t scat_512k_clip_mapping; -void scat_shadow_state_update() + +static void scat_shadow_state_update(void) { int i, val; @@ -54,7 +80,8 @@ void scat_shadow_state_update() flushmmucache(); } -void scat_set_xms_bound(uint8_t val) + +static void scat_set_xms_bound(uint8_t val) { uint32_t max_xms_size = (mem_size >= 16384) ? 0xFC0000 : mem_size << 10; @@ -128,7 +155,8 @@ void scat_set_xms_bound(uint8_t val) } } -uint32_t get_scat_addr(uint32_t addr, scat_t *p) + +static uint32_t get_scat_addr(uint32_t addr, scat_t *p) { if (p && (scat_regs[SCAT_EMS_CONTROL] & 0x80) && (p->regs_2x9 & 0x80)) { @@ -142,7 +170,8 @@ uint32_t get_scat_addr(uint32_t addr, scat_t *p) return addr; } -void scat_write(uint16_t port, uint8_t val, void *priv) + +static void scat_write(uint16_t port, uint8_t val, void *priv) { uint8_t scat_reg_valid = 0, scat_shadow_update = 0, index; uint32_t base_addr, virt_addr; @@ -334,7 +363,8 @@ void scat_write(uint16_t port, uint8_t val, void *priv) } } -uint8_t scat_read(uint16_t port, void *priv) + +static uint8_t scat_read(uint16_t port, void *priv) { uint8_t val = 0xff, index; switch (port) @@ -407,7 +437,8 @@ uint8_t scat_read(uint16_t port, void *priv) return val; } -uint8_t mem_read_scatems(uint32_t addr, void *priv) + +static uint8_t mem_read_scatems(uint32_t addr, void *priv) { uint8_t val = 0xff; scat_t *stat = (scat_t *)priv; @@ -418,7 +449,9 @@ uint8_t mem_read_scatems(uint32_t addr, void *priv) return val; } -uint16_t mem_read_scatemsw(uint32_t addr, void *priv) + + +static uint16_t mem_read_scatemsw(uint32_t addr, void *priv) { uint16_t val = 0xffff; scat_t *stat = (scat_t *)priv; @@ -429,7 +462,9 @@ uint16_t mem_read_scatemsw(uint32_t addr, void *priv) return val; } -uint32_t mem_read_scatemsl(uint32_t addr, void *priv) + + +static uint32_t mem_read_scatemsl(uint32_t addr, void *priv) { uint32_t val = 0xffffffff; scat_t *stat = (scat_t *)priv; @@ -441,7 +476,8 @@ uint32_t mem_read_scatemsl(uint32_t addr, void *priv) return val; } -void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) + +static void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) { scat_t *stat = (scat_t *)priv; @@ -449,7 +485,9 @@ void mem_write_scatems(uint32_t addr, uint8_t val, void *priv) if (addr < (mem_size << 10)) mem_write_ram(addr, val, priv); } -void mem_write_scatemsw(uint32_t addr, uint16_t val, void *priv) + + +static void mem_write_scatemsw(uint32_t addr, uint16_t val, void *priv) { scat_t *stat = (scat_t *)priv; @@ -457,7 +495,9 @@ void mem_write_scatemsw(uint32_t addr, uint16_t val, void *priv) if (addr < (mem_size << 10)) mem_write_ramw(addr, val, priv); } -void mem_write_scatemsl(uint32_t addr, uint32_t val, void *priv) + + +static void mem_write_scatemsl(uint32_t addr, uint32_t val, void *priv) { scat_t *stat = (scat_t *)priv; @@ -466,7 +506,8 @@ void mem_write_scatemsl(uint32_t addr, uint32_t val, void *priv) mem_write_raml(addr, val, priv); } -void scat_init() + +void scat_init(void) { int i; diff --git a/src/scat.h b/src/scat.h deleted file mode 100644 index 040a0a69a..000000000 --- a/src/scat.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright holders: Greatpsycho - see COPYING for more details -*/ -#define SCAT_DMA_WAIT_STATE_CONTROL 0x01 -#define SCAT_VERSION 0x40 -#define SCAT_CLOCK_CONTROL 0x41 -#define SCAT_PERIPHERAL_CONTROL 0x44 -#define SCAT_MISCELLANEOUS_STATUS 0x45 -#define SCAT_POWER_MANAGEMENT 0x46 -#define SCAT_ROM_ENABLE 0x48 -#define SCAT_RAM_WRITE_PROTECT 0x49 -#define SCAT_SHADOW_RAM_ENABLE_1 0x4A -#define SCAT_SHADOW_RAM_ENABLE_2 0x4B -#define SCAT_SHADOW_RAM_ENABLE_3 0x4C -#define SCAT_DRAM_CONFIGURATION 0x4D -#define SCAT_EXTENDED_BOUNDARY 0x4E -#define SCAT_EMS_CONTROL 0x4F - -typedef struct scat_t -{ - uint8_t regs_2x8; - uint8_t regs_2x9; -} scat_t; - -void scat_init(); diff --git a/src/sis496.c b/src/sis496.c index cb4d9303d..aff1b3eaa 100644 --- a/src/sis496.c +++ b/src/sis496.c @@ -3,21 +3,24 @@ */ #include #include "ibm.h" -#include "device.h" +#include "cpu/cpu.h" #include "io.h" #include "mem.h" #include "pci.h" +#include "device.h" +#include "model.h" -#include "sis496.h" typedef struct sis496_t { uint8_t pci_conf[256]; } sis496_t; + sis496_t sis496; -void sis496_recalcmapping(void) + +static void sis496_recalcmapping(void) { int c; @@ -50,7 +53,8 @@ void sis496_recalcmapping(void) shadowbios = (sis496.pci_conf[0x44] & 0xf0); } -void sis496_write(int func, int addr, uint8_t val, void *p) + +static void sis496_write(int func, int addr, uint8_t val, void *p) { switch (addr) { @@ -99,12 +103,14 @@ void sis496_write(int func, int addr, uint8_t val, void *p) sis496.pci_conf[addr] = val; } -uint8_t sis496_read(int func, int addr, void *p) + +static uint8_t sis496_read(int func, int addr, void *p) { return sis496.pci_conf[addr]; } -void sis496_reset(void) + +static void sis496_reset(void) { memset(&sis496, 0, sizeof(sis496_t)); @@ -128,7 +134,8 @@ void sis496_reset(void) sis496.pci_conf[0x0e] = 0x00; /*Single function device*/ } -void sis496_pci_reset(void) + +static void sis496_pci_reset(void) { uint8_t val = 0; @@ -136,6 +143,7 @@ void sis496_pci_reset(void) sis496_write(0, 0x44, val & 0xf, NULL); /* Turn off shadow BIOS but keep the lower 4 bits. */ } + void sis496_init(void) { pci_add_specific(5, sis496_read, sis496_write, NULL); @@ -149,6 +157,7 @@ void sis496_init(void) pci_set_card_routing(11, PCI_INTC); } + void sis496_close(void *p) { sis496_t *sis496 = (sis496_t *)p; diff --git a/src/sis496.h b/src/sis496.h deleted file mode 100644 index fbb73be49..000000000 --- a/src/sis496.h +++ /dev/null @@ -1,4 +0,0 @@ -/* Copyright holders: Kotori - see COPYING for more details -*/ -void sis496_init(void); From ce09beb9c8cc40e3088844d1d947cefcda20cca2 Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 16 Jun 2017 16:34:31 -0400 Subject: [PATCH 355/392] Rest of serial driver - WORK IN PROGRESS - MIGHT BREAK - DONT CHANGE ! --- src/WIN/win_serial.c | 1 - src/serial.c | 236 +++++++++++++++++++++++++++++-------------- src/serial.h | 20 +++- 3 files changed, 173 insertions(+), 84 deletions(-) diff --git a/src/WIN/win_serial.c b/src/WIN/win_serial.c index b6ec04e3f..e44cf36d0 100644 --- a/src/WIN/win_serial.c +++ b/src/WIN/win_serial.c @@ -17,7 +17,6 @@ * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. */ -#define _WIN32_WINNT 0x0501 #include #include #include diff --git a/src/serial.c b/src/serial.c index ae33dc16d..c02ef6dae 100644 --- a/src/serial.c +++ b/src/serial.c @@ -15,25 +15,29 @@ * * So, for the PC, the offerings were for an IBM Asynchronous * Communications Adapter, and, later, a model for synchronous - * communications. - * - * The "Async Adapter" was based on the NS8250 UART chip, and - * is what we now call the "serial" or "com" port of the PC. + * communications. The "Async Adapter" was based on the NS8250 + * UART chip, and is what we now call the "com" port of the PC. * * Of course, many system builders came up with similar boards, * and even more boards were designed where several I/O functions - * were combined into a single board: the Multi-I/O adapters. - * Initially, these had all the chips as-is, but later many of - * these functions were integrated into a single MIO chip. + * were combined into a single "multi-I/O" board, as that saved + * space and buts slots. Initially, these had the chips as-is, + * but later many of these functions were integrated into a + * single "super-I/O" chip. * - * This file implements the standard NS8250 series of chips, with - * support for the later (16450 and 16550) FIFO additions. On the - * lower half of the driver, we interface to the host system's - * serial ports for real-world access. + * This file implements the standard NS8250, as well as the later + * 16450 and 16550 series, which fixed bugs and added features + * like FIFO buffers, higher line speeds and DMA transfers. + * + * On the lower half of the driver we interface to the host + * system's serial ports for real-world access. * * Based on the 86Box serial port driver as a framework. * - * Version: @(#)serial.c 1.0.7 2017/06/04 + * **NOTE** This module is currently UNDER CONSTRUCTION, do not mess + * with it please! + * + * Version: @(#)serial.c 1.0.8 2017/06/17 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -74,10 +78,10 @@ enum { # define IID_IDTX (0x02) # define IID_IDRX (0x04) # define IID_IDERR (0x06) -# define IID_IDTMO (0x0c) -#define IIR_IIRFE (0xc0) +# define IID_IDTMO (0x0c) /* 16550+ */ +#define IIR_IIRFE (0xc0) /* 16550+ */ # define IIR_FIFO64 (0x20) -# define IIR_FIFOBAD (0x80) /* 16550 */ +# define IIR_FIFOBAD (0x80) # define IIR_FIFOENB (0xc0) /* FCR register bits. */ @@ -144,7 +148,6 @@ static SERIAL ports[NUM_SERIAL]; /* serial port data */ int serial_do_log; -#if 0 static void serial_log(int lvl, const char *fmt, ...) { @@ -159,7 +162,6 @@ serial_log(int lvl, const char *fmt, ...) } #endif } -#endif static void @@ -186,11 +188,20 @@ update_ints(SERIAL *sp) sp->iir = IID_IDMDM; } - /* Raise or clear the level-based IRQ. */ - if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) - picintlevel(1 << sp->irq); - else - picintc(1 << sp->irq); +pclog("Serial%d: intr, IIR=%02X, type=%d, mcr=%02X\n",sp->port, sp->iir, sp->type, sp->mctrl); + if (sp->type < UART_TYPE_16450) { + /* Edge-triggered, so always send a pulse. */ +// if ((sp->mctrl & MCR_OUT2) || PCJR) + picint(1 << sp->irq); + } else { + /* Raise or clear the level-based IRQ. */ + if ((sp->mctrl & MCR_OUT2) || PCJR) { + if (stat) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); + } + } } @@ -212,13 +223,14 @@ serial_timer(void *priv) /* Write data to the (input) FIFO. Used by MOUSE driver. */ void -serial_write_fifo(SERIAL *sp, uint8_t dat) +serial_write_fifo(SERIAL *sp, uint8_t dat, int intr) { - /* Stuff data into FIFO. */ + /* Stuff data into RX FIFO. */ sp->fifo[sp->fifo_write] = dat; sp->fifo_write = (sp->fifo_write + 1) & 0xFF; - if (! (sp->lsr & LSR_DR)) { + /* If requested, generate interrupt. */ + if (intr && !(sp->lsr & LSR_DR)) { sp->lsr |= LSR_DR; sp->int_status |= SERINT_RECEIVE; update_ints(sp); @@ -226,12 +238,31 @@ serial_write_fifo(SERIAL *sp, uint8_t dat) } +/* Grab data from the RX fifo. */ static uint8_t -read_fifo(SERIAL *sp) +serial_read_fifo(SERIAL *sp) { - if (sp->fifo_read != sp->fifo_write) { + if (sp->fifo_read != sp->fifo_write) { + /* Grab data from the fifo. */ sp->dat = sp->fifo[sp->fifo_read]; - sp->fifo_read = (sp->fifo_read + 1) & 0xFF; + sp->fifo_read = (sp->fifo_read+1) & 0xFF; + + /* If we have more, generate (new) int. */ + if (sp->fifo_read != sp->fifo_write) { +#if 1 + sp->receive_delay = 1000*TIMER_USEC; +#else + if (sp->bh != NULL) { + sp->int_status |= SERINT_RECEIVE; + sp->lsr |= LSR_DR; + + /* Update interrupt state. */ + update_ints(sp); + } else { + sp->receive_delay = 1000*TIMER_USEC; + } +#endif + } } return(sp->dat); @@ -253,41 +284,46 @@ serial_write(uint16_t addr, uint8_t val, void *priv) switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { + /* DLAB set, set DLAB low byte. */ sp->dlab1 = val; - return; - } - sp->thr = val; - if (sp->bh != NULL) { - /* We are linked, so send to BH layer. */ - bhtty_write((BHTTY *)sp->bh, sp->thr); + } else { + /* DLAB clear, regular data write. */ + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ + bhtty_write((BHTTY *)sp->bh, sp->thr); + } - /* The WRITE completed, we are ready for more. */ + /* WRITE completed, we are ready for more. */ sp->lsr |= LSR_THRE; sp->int_status |= SERINT_TRANSMIT; update_ints(sp); - } else { - /* Not linked. Just fake LOOPBACK mode. */ - if (! (sp->mctrl & MCR_LMS)) - serial_write_fifo(sp, val); - } - if (sp->mctrl & MCR_LMS) { - /* Echo data back to RX. */ - serial_write_fifo(sp, val); + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val, 1); + } } break; case 1: /* IER / DLAB2 */ if (sp->lcr & LCR_DLAB) { + /* DLAB set, set DLAB high byte. */ sp->dlab2 = val; - return; + } else { + /* DLAB clear, set IER register bits. */ + sp->ier = (val & IER_MASK); + + /* Generate interrupt if needed. */ + update_ints(sp); } - sp->ier = (val & IER_MASK); - update_ints(sp); break; case 2: /* FCR */ - sp->fcr = val; + if (sp->type >= UART_TYPE_16550A) { +serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val, sp->type); + sp->fcr = val; + } break; case 3: /* LCR */ @@ -315,12 +351,17 @@ serial_write(uint16_t addr, uint8_t val, void *priv) #ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); #endif + sp->lcr = val; if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); - sp->lcr = val; break; - case 4: + case 4: /*MCR*/ + if (sp->bh == NULL) { + /* Not linked, force LOOPBACK mode. */ + val |= MCR_LMS; + } + if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { /* * This is old code for use by the Serial Mouse @@ -355,28 +396,28 @@ serial_write(uint16_t addr, uint8_t val, void *priv) } } sp->mctrl = val; + if (val & MCR_LMS) { /* loopback mode */ uint8_t new_msr; - /*FIXME: WTF does this do?? --FvK */ new_msr = (val & 0x0c) << 4; new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; - if ((sp->msr ^ new_msr) & 0x10) - new_msr |= MCR_DTR; - if ((sp->msr ^ new_msr) & 0x20) - new_msr |= MCR_RTS; - if ((sp->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((sp->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; + if ((sp->msr ^ new_msr) & MSR_CTS) + new_msr |= MSR_DCTS; + if ((sp->msr ^ new_msr) & MSR_DSR) + new_msr |= MSR_DDSR; + if ((sp->msr ^ new_msr) & MSR_DCD) + new_msr |= MSR_DDCD; + if ((sp->msr & MSR_TERI) && !(new_msr & MSR_RI)) + new_msr |= MSR_TERI; sp->msr = new_msr; } break; - case 5: + case 5: /*LSR*/ sp->lsr = val; if (sp->lsr & LSR_DR) sp->int_status |= SERINT_RECEIVE; @@ -387,7 +428,7 @@ serial_write(uint16_t addr, uint8_t val, void *priv) update_ints(sp); break; - case 6: + case 6: /*MSR*/ sp->msr = val; if (sp->msr & MSR_MASK) sp->int_status |= SERINT_MSR; @@ -395,7 +436,9 @@ serial_write(uint16_t addr, uint8_t val, void *priv) break; case 7: - sp->scratch = val; + if (sp->type > UART_TYPE_8250) { + sp->scratch = val; + } break; } } @@ -413,8 +456,17 @@ serial_rd_done(void *arg, int num) if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; /* Stuff it into the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); +#if 1 + serial_write_fifo(sp, sp->hold, 0); +#else + serial_write_fifo(sp, sp->hold, 1); +#endif } + +#if 1 + /* We have data waiting for us.. delay a little, and then read it. */ + timer_add(serial_timer, &sp->receive_delay, &sp->receive_delay, sp); +#endif } @@ -428,30 +480,48 @@ serial_read(uint16_t addr, void *priv) switch (addr&0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { + /* DLAB set, read DLAB low byte. */ ret = sp->dlab1; } else { - sp->lsr &= ~LSR_DR; + /* + * DLAB clear, regular data read. + * First, clear the RXDATA interrupt. + */ sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); - if ((sp->bh == NULL) && - (sp->fifo_read != sp->fifo_write)) - sp->receive_delay = 1000 * TIMER_USEC; + sp->lsr &= ~LSR_DR; + + /* If there is data in the RX FIFO, grab it. */ + ret = serial_read_fifo(sp); +pclog("Serial%d: read RBR: %02X\n",sp->port, ret); } break; case 1: /* LCR / DLAB2 */ - ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; + if (sp->lcr & LCR_DLAB) { + /* DLAB set, read DLAB high byte. */ + ret = sp->dlab2; + } else { + /* DLAB clear, read IER register bits. */ + ret = sp->ier; + } break; case 2: /* IIR */ ret = sp->iir; +pclog("Serial%d: read IIR: %02X\n",sp->port, sp->iir); + if ((ret & IIR_IID) == IID_IDTX) { + /* Transmit is done. */ sp->int_status &= ~SERINT_TRANSMIT; update_ints(sp); } - if (sp->fcr & 0x01) - ret |= 0xc0; + + if (sp->type >= UART_TYPE_16550A) { + /* If FIFO enabled.. */ + if (sp->fcr & 0x01) + /* Report FIFO active. */ + ret |= 0xc0; + } break; case 3: /* LCR */ @@ -463,6 +533,10 @@ serial_read(uint16_t addr, void *priv) break; case 5: /* LSR */ + /* Clear interrupt state. */ + sp->int_status &= ~SERINT_LSR; + update_ints(sp); + if (sp->lsr & LSR_THRE) sp->lsr |= LSR_TEMT; sp->lsr |= LSR_THRE; @@ -472,19 +546,24 @@ serial_read(uint16_t addr, void *priv) #if 0 sp->lsr |= (LSR_THRE | LSR_TEMT); #endif - sp->int_status &= ~SERINT_LSR; - update_ints(sp); break; case 6: - ret = sp->msr; - sp->msr &= ~0x0f; + /* Clear MSR interrupt status. */ sp->int_status &= ~SERINT_MSR; update_ints(sp); + + /* Grab current modem status. */ + ret = sp->msr; + + /* Reset the delta bits. */ + sp->msr &= ~0x0f; break; case 7: - ret = sp->scratch; + if (sp->type > UART_TYPE_8250) { + ret = sp->scratch; + } break; } @@ -563,6 +642,7 @@ serial_init(void) sp = &ports[i]; memset(sp, 0x00, sizeof(SERIAL)); sp->port = (i+1); + sp->type = UART_TYPE_8250; if (i == 0) serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); @@ -570,9 +650,9 @@ serial_init(void) serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); } -#ifdef WALTJE /* Link to host port. */ - serial_link(1, "COM1"); +#ifdef WALTJE +// serial_link(1, "COM1"); serial_link(2, "COM2"); #endif } diff --git a/src/serial.h b/src/serial.h index 4602429f0..09b1b24e6 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,7 +8,7 @@ * * Definitions for the SERIAL card. * - * Version: @(#)serial.h 1.0.4 2017/06/03 + * Version: @(#)serial.h 1.0.5 2017/06/07 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -24,16 +24,27 @@ #define SERIAL2_IRQ 3 +/* Supported UART types. */ +#define UART_TYPE_8250 0 /* standard NS8250 */ +#define UART_TYPE_8250A 1 /* updated NS8250(A) */ +#define UART_TYPE_16450 2 /* 16450 */ +#define UART_TYPE_16550 3 /* 16550 (broken fifo) */ +#define UART_TYPE_16550A 4 /* 16550a (working fifo) */ +#define UART_TYPE_16670 5 /* 64b fifo */ + + typedef struct _serial_ { int8_t port; /* port number (1,2,..) */ int8_t irq; /* IRQ channel used */ uint16_t addr; /* I/O address used */ + int8_t type; /* UART type */ + uint8_t int_status; uint8_t lsr, thr, mctrl, rcr, /* UART registers */ iir, ier, lcr, msr; uint8_t dlab1, dlab2; - uint8_t dat; - uint8_t int_status; + uint8_t dat, + hold; uint8_t scratch; uint8_t fcr; @@ -41,7 +52,6 @@ typedef struct _serial_ { void (*rts_callback)(void *); void *rts_callback_p; - uint8_t hold; uint8_t fifo[256]; int fifo_read, fifo_write; @@ -58,7 +68,7 @@ extern void serial_setup(int port, uint16_t addr, int irq); extern void serial_remove(int port); extern SERIAL *serial_attach(int, void *, void *); extern int serial_link(int, char *); -extern void serial_write_fifo(SERIAL *, uint8_t); +extern void serial_write_fifo(SERIAL *, uint8_t, int); #endif /*EMU_SERIAL_H*/ From 5fca563dd08cddd49457d0fb01aac9f9ed2d261b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 22:54:08 +0200 Subject: [PATCH 356/392] Changed type of string literals in all (I hope) structs to const char *, reduces .EXE file size by about 200 kB. --- src/CPU/cpu.h | 2 +- src/NETWORK/network.c | 4 ++-- src/NETWORK/network.h | 4 ++-- src/SOUND/sound.c | 8 ++++---- src/VIDEO/video.c | 8 ++++---- src/WIN/win_deviceconfig.c | 24 ++++++++++++------------ src/WIN/win_settings.c | 6 +++--- src/device.c | 24 ++++++++++++------------ src/device.h | 10 +++++----- src/gameport.c | 12 ++++++------ src/gameport.h | 8 ++++---- src/hdd.c | 8 ++++---- src/model.c | 6 +++--- src/model.h | 6 +++--- src/mouse.c | 4 ++-- src/mouse.h | 4 ++-- src/scsi.c | 8 ++++---- 17 files changed, 73 insertions(+), 73 deletions(-) diff --git a/src/CPU/cpu.h b/src/CPU/cpu.h index b792b36b8..39ff3153f 100644 --- a/src/CPU/cpu.h +++ b/src/CPU/cpu.h @@ -87,7 +87,7 @@ extern int timing_misaligned; typedef struct { - char name[32]; + const char *name; int cpu_type; int speed; int rspeed; diff --git a/src/NETWORK/network.c b/src/NETWORK/network.c index 87d2613ac..79bb4ac13 100644 --- a/src/NETWORK/network.c +++ b/src/NETWORK/network.c @@ -207,7 +207,7 @@ network_card_available(int card) char * network_card_getname(int card) { - return(net_cards[card].name); + return((char *) net_cards[card].name); } @@ -233,7 +233,7 @@ network_card_has_config(int card) char * network_card_get_internal_name(int card) { - return(net_cards[card].internal_name); + return((char *) net_cards[card].internal_name); } diff --git a/src/NETWORK/network.h b/src/NETWORK/network.h index 1c3e748a1..df2241822 100644 --- a/src/NETWORK/network.h +++ b/src/NETWORK/network.h @@ -32,8 +32,8 @@ typedef void (*NETRXCB)(void *, uint8_t *, int); typedef struct { - char name[64]; - char internal_name[32]; + const char *name; + const char *internal_name; device_t *device; void *private; int (*poll)(void *); diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 369065411..5487a4f5c 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -42,8 +42,8 @@ static int sound_card_last = 0; typedef struct { - char name[64]; - char internal_name[24]; + const char *name; + const char *internal_name; device_t *device; } SOUND_CARD; @@ -80,7 +80,7 @@ int sound_card_available(int card) char *sound_card_getname(int card) { - return sound_cards[card].name; + return (char *) sound_cards[card].name; } device_t *sound_card_getdevice(int card) @@ -97,7 +97,7 @@ int sound_card_has_config(int card) char *sound_card_get_internal_name(int card) { - return sound_cards[card].internal_name; + return (char *) sound_cards[card].internal_name; } int sound_card_get_from_internal_name(char *s) diff --git a/src/VIDEO/video.c b/src/VIDEO/video.c index fa541958c..aad86f57c 100644 --- a/src/VIDEO/video.c +++ b/src/VIDEO/video.c @@ -64,8 +64,8 @@ int cga_palette = 0; typedef struct { - char name[64]; - char internal_name[24]; + const char *name; + const char *internal_name; device_t *device; int legacy_id; } VIDEO_CARD; @@ -120,7 +120,7 @@ int video_card_available(int card) char *video_card_getname(int card) { - return video_cards[card].name; + return (char *) video_cards[card].name; } device_t *video_card_getdevice(int card) @@ -168,7 +168,7 @@ int video_new_to_old(int card) char *video_get_internal_name(int card) { - return video_cards[card].internal_name; + return (char *) video_cards[card].internal_name; } int video_get_video_from_internal_name(char *s) diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index cf0474c16..200f579fd 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -47,7 +47,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam switch (config->type) { case CONFIG_BINARY: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); SendMessage(h, BM_SETCHECK, val_int, 0); @@ -55,7 +55,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam break; case CONFIG_SELECTION: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); c = 0; while (selection->description[0]) @@ -71,7 +71,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam break; case CONFIG_HEX16: - val_int = config_get_hex16(config_device->name, config->name, config->default_int); + val_int = config_get_hex16((char *) config_device->name, (char *) config->name, config->default_int); c = 0; while (selection->description[0]) @@ -87,7 +87,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam break; case CONFIG_HEX20: - val_int = config_get_hex20(config_device->name, config->name, config->default_int); + val_int = config_get_hex20((char *) config_device->name, (char *) config->name, config->default_int); c = 0; while (selection->description[0]) @@ -125,7 +125,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam switch (config->type) { case CONFIG_BINARY: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); if (val_int != SendMessage(h, BM_GETCHECK, 0, 0)) changed = 1; @@ -134,7 +134,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam break; case CONFIG_SELECTION: - val_int = config_get_int(config_device->name, config->name, config->default_int); + val_int = config_get_int((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -148,7 +148,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam break; case CONFIG_HEX16: - val_int = config_get_hex16(config_device->name, config->name, config->default_int); + val_int = config_get_hex16((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -162,7 +162,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam break; case CONFIG_HEX20: - val_int = config_get_hex20(config_device->name, config->name, config->default_int); + val_int = config_get_hex20((char *) config_device->name, (char *) config->name, config->default_int); c = SendMessage(h, CB_GETCURSEL, 0, 0); @@ -201,7 +201,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam switch (config->type) { case CONFIG_BINARY: - config_set_int(config_device->name, config->name, SendMessage(h, BM_GETCHECK, 0, 0)); + config_set_int((char *) config_device->name, (char *) config->name, SendMessage(h, BM_GETCHECK, 0, 0)); id++; break; @@ -210,7 +210,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_int(config_device->name, config->name, selection->value); + config_set_int((char *) config_device->name, (char *) config->name, selection->value); id += 2; break; @@ -219,7 +219,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_hex16(config_device->name, config->name, selection->value); + config_set_hex16((char *) config_device->name, (char *) config->name, selection->value); id += 2; break; @@ -228,7 +228,7 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) selection++; - config_set_hex20(config_device->name, config->name, selection->value); + config_set_hex20((char *) config_device->name, (char *) config->name, selection->value); id += 2; break; diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index d16435b22..9e2ec7281 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -421,7 +421,7 @@ static void win_settings_machine_recalc_cpu_m(HWND hdlg) c = 0; while (models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].cpu_type != -1) { - stransi = models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; + stransi = (char *) models[romstomodel[temp_romset]].cpu[temp_cpu_m].cpus[c].name; mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); c++; @@ -466,7 +466,7 @@ static void win_settings_machine_recalc_model(HWND hdlg) c = 0; while (models[romstomodel[temp_romset]].cpu[c].cpus != NULL && c < 4) { - stransi = models[romstomodel[temp_romset]].cpu[c].name; + stransi = (char *) models[romstomodel[temp_romset]].cpu[c].name; mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)lptsTemp); c++; @@ -533,7 +533,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w { if (romspresent[models[c].id]) { - stransi = models[c].name; + stransi = (char *) models[c].name; mbstowcs(lptsTemp, stransi, strlen(stransi) + 1); SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); modeltolist[c] = d; diff --git a/src/device.c b/src/device.c index 9d8968f82..876c400ad 100644 --- a/src/device.c +++ b/src/device.c @@ -158,7 +158,7 @@ int device_get_config_int(char *s) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_int(current_device->name, s, config->default_int); + return config_get_int((char *) current_device->name, s, config->default_int); config++; } @@ -172,7 +172,7 @@ int device_get_config_int_ex(char *s, int default_int) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_int(current_device->name, s, default_int); + return config_get_int((char *) current_device->name, s, default_int); config++; } @@ -186,7 +186,7 @@ int device_get_config_hex16(char *s) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_hex16(current_device->name, s, config->default_int); + return config_get_hex16((char *) current_device->name, s, config->default_int); config++; } @@ -200,7 +200,7 @@ int device_get_config_hex20(char *s) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_hex20(current_device->name, s, config->default_int); + return config_get_hex20((char *) current_device->name, s, config->default_int); config++; } @@ -214,7 +214,7 @@ int device_get_config_mac(char *s, int default_int) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_mac(current_device->name, s, default_int); + return config_get_mac((char *) current_device->name, s, default_int); config++; } @@ -229,7 +229,7 @@ void device_set_config_int(char *s, int val) { if (!strcmp(s, config->name)) { - config_set_int(current_device->name, s, val); + config_set_int((char *) current_device->name, s, val); return; } @@ -246,7 +246,7 @@ void device_set_config_hex16(char *s, int val) { if (!strcmp(s, config->name)) { - config_set_hex16(current_device->name, s, val); + config_set_hex16((char *) current_device->name, s, val); return; } @@ -263,7 +263,7 @@ void device_set_config_hex20(char *s, int val) { if (!strcmp(s, config->name)) { - config_set_hex20(current_device->name, s, val); + config_set_hex20((char *) current_device->name, s, val); return; } @@ -280,7 +280,7 @@ void device_set_config_mac(char *s, int val) { if (!strcmp(s, config->name)) { - config_set_mac(current_device->name, s, val); + config_set_mac((char *) current_device->name, s, val); return; } @@ -296,7 +296,7 @@ char *device_get_config_string(char *s) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_string(current_device->name, s, config->default_string); + return config_get_string((char *) current_device->name, s, (char *) config->default_string); config++; } @@ -316,7 +316,7 @@ int model_get_config_int(char *s) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_int(device->name, s, config->default_int); + return config_get_int((char *) device->name, s, config->default_int); config++; } @@ -336,7 +336,7 @@ char *model_get_config_string(char *s) while (config->type != -1) { if (!strcmp(s, config->name)) - return config_get_string(device->name, s, config->default_string); + return config_get_string((char *) device->name, s, (char *) config->default_string); config++; } diff --git a/src/device.h b/src/device.h index e5613f836..35c842479 100644 --- a/src/device.h +++ b/src/device.h @@ -41,23 +41,23 @@ enum typedef struct device_config_selection_t { - char description[256]; + const char *description; int value; } device_config_selection_t; typedef struct device_config_t { - char name[256]; - char description[256]; + const char *name; + const char *description; int type; - char default_string[256]; + const char *default_string; int default_int; device_config_selection_t selection[16]; } device_config_t; typedef struct device_t { - char name[50]; + const char *name; uint32_t flags; void *(*init)(); void (*close)(void *p); diff --git a/src/gameport.c b/src/gameport.c index a80d962b7..310954103 100644 --- a/src/gameport.c +++ b/src/gameport.c @@ -37,7 +37,7 @@ static joystick_if_t *joystick_list[] = { &joystick_standard, &joystick_standard_4button, - &joystick_standard_6button, + &joystick_standard_6button, &joystick_standard_8button, &joystick_ch_flightstick_pro, &joystick_sw_pad, @@ -50,7 +50,7 @@ char *joystick_get_name(int joystick) { if (!joystick_list[joystick]) return NULL; - return joystick_list[joystick]->name; + return (char *) joystick_list[joystick]->name; } int joystick_get_max_joysticks(int joystick) @@ -73,19 +73,19 @@ int joystick_get_pov_count(int joystick) return joystick_list[joystick]->pov_count; } - char *joystick_get_axis_name(int joystick, int id) +char *joystick_get_axis_name(int joystick, int id) { - return joystick_list[joystick]->axis_names[id]; + return (char *) joystick_list[joystick]->axis_names[id]; } char *joystick_get_button_name(int joystick, int id) { - return joystick_list[joystick]->button_names[id]; + return (char *) joystick_list[joystick]->button_names[id]; } char *joystick_get_pov_name(int joystick, int id) { - return joystick_list[joystick]->pov_names[id]; + return (char *) joystick_list[joystick]->pov_names[id]; } typedef struct gameport_axis_t diff --git a/src/gameport.h b/src/gameport.h index dbe01246a..4765c479a 100644 --- a/src/gameport.h +++ b/src/gameport.h @@ -6,7 +6,7 @@ extern device_t gameport_201_device; typedef struct { - char name[80]; + const char *name; void *(*init)(); void (*close)(void *p); uint8_t (*read)(void *p); @@ -15,9 +15,9 @@ typedef struct void (*a0_over)(void *p); int axis_count, button_count, pov_count; int max_joysticks; - char axis_names[8][32]; - char button_names[32][32]; - char pov_names[4][32]; + const char *axis_names[8]; + const char *button_names[32]; + const char *pov_names[4]; } joystick_if_t; extern int joystick_type; diff --git a/src/hdd.c b/src/hdd.c index 7fdb21d95..ab167c1ee 100644 --- a/src/hdd.c +++ b/src/hdd.c @@ -19,8 +19,8 @@ hard_disk_t hdc[HDC_NUM]; static struct { - char name[50]; - char internal_name[16]; + const char *name; + const char *internal_name; device_t *device; int is_mfm; } hdd_controllers[] = @@ -39,12 +39,12 @@ static struct char *hdd_controller_get_name(int hdd) { - return hdd_controllers[hdd].name; + return (char *) hdd_controllers[hdd].name; } char *hdd_controller_get_internal_name(int hdd) { - return hdd_controllers[hdd].internal_name; + return (char *) hdd_controllers[hdd].internal_name; } int hdd_controller_get_flags(int hdd) diff --git a/src/model.c b/src/model.c index 7645ae58e..4303bf005 100644 --- a/src/model.c +++ b/src/model.c @@ -244,7 +244,7 @@ int model_getmodel(int romset) char *model_getname() { - return models[model].name; + return (char *) models[model].name; } @@ -255,12 +255,12 @@ device_t *model_getdevice(int model) char *model_get_internal_name(void) { - return models[model].internal_name; + return (char *) models[model].internal_name; } char *model_get_internal_name_ex(int m) { - return models[m].internal_name; + return (char *) models[m].internal_name; } int model_get_nvrmask(int m) diff --git a/src/model.h b/src/model.h index 02b8ddcb8..5dfda40ce 100644 --- a/src/model.h +++ b/src/model.h @@ -33,11 +33,11 @@ typedef struct { - char name[32]; + const char *name; int id; - char internal_name[24]; + const char *internal_name; struct { - char name[16]; + const char *name; CPU *cpus; } cpu[5]; int fixed_gfxcard; diff --git a/src/mouse.c b/src/mouse.c index 85075d40b..19c0240d7 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -58,14 +58,14 @@ mouse_get_name(int mouse) { if (!mouse_list[mouse]) return(NULL); - return(mouse_list[mouse]->name); + return((char *) mouse_list[mouse]->name); } char * mouse_get_internal_name(int mouse) { - return(mouse_list[mouse]->internal_name); + return((char *) mouse_list[mouse]->internal_name); } diff --git a/src/mouse.h b/src/mouse.h index 25aa07888..4ba694906 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -16,8 +16,8 @@ typedef struct { - char name[80]; - char internal_name[24]; + const char *name; + const char *internal_name; int type; void *(*init)(void); void (*close)(void *p); diff --git a/src/scsi.c b/src/scsi.c index 186a2495a..c296429a2 100644 --- a/src/scsi.c +++ b/src/scsi.c @@ -39,8 +39,8 @@ int scsi_card_last = 0; typedef struct { - char name[64]; - char internal_name[32]; + const char *name; + const char *internal_name; device_t *device; void (*reset)(void *p); } SCSI_CARD; @@ -68,7 +68,7 @@ int scsi_card_available(int card) char *scsi_card_getname(int card) { - return(scsi_cards[card].name); + return((char *) scsi_cards[card].name); } @@ -88,7 +88,7 @@ int scsi_card_has_config(int card) char *scsi_card_get_internal_name(int card) { - return(scsi_cards[card].internal_name); + return((char *) scsi_cards[card].internal_name); } From c9aac82b9451f32233aa25051af1984a0573c40c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 23:30:42 +0200 Subject: [PATCH 357/392] Changed all instances of pclog to serial_log in the serial code. --- src/serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/serial.c b/src/serial.c index c02ef6dae..8cb4b43b5 100644 --- a/src/serial.c +++ b/src/serial.c @@ -188,7 +188,7 @@ update_ints(SERIAL *sp) sp->iir = IID_IDMDM; } -pclog("Serial%d: intr, IIR=%02X, type=%d, mcr=%02X\n",sp->port, sp->iir, sp->type, sp->mctrl); +serial_log(0, "Serial%d: intr, IIR=%02X, type=%d, mcr=%02X\n",sp->port, sp->iir, sp->type, sp->mctrl); if (sp->type < UART_TYPE_16450) { /* Edge-triggered, so always send a pulse. */ // if ((sp->mctrl & MCR_OUT2) || PCJR) @@ -492,7 +492,7 @@ serial_read(uint16_t addr, void *priv) /* If there is data in the RX FIFO, grab it. */ ret = serial_read_fifo(sp); -pclog("Serial%d: read RBR: %02X\n",sp->port, ret); +serial_log(0, "Serial%d: read RBR: %02X\n",sp->port, ret); } break; @@ -508,7 +508,7 @@ pclog("Serial%d: read RBR: %02X\n",sp->port, ret); case 2: /* IIR */ ret = sp->iir; -pclog("Serial%d: read IIR: %02X\n",sp->port, sp->iir); +serial_log(0, "Serial%d: read IIR: %02X\n",sp->port, sp->iir); if ((ret & IIR_IID) == IID_IDTX) { /* Transmit is done. */ From 20178cb1bbf9af7aa9af6438e972cff3eac5467c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 16 Jun 2017 23:47:08 +0200 Subject: [PATCH 358/392] Reversed serial port and serial mouse code to the old ones. --- src/mouse_serial.c | 177 +++++++++++++++++----------------- src/serial.c | 236 +++++++++++++++------------------------------ src/serial.h | 20 +--- 3 files changed, 172 insertions(+), 261 deletions(-) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index fdda61e13..bb855ecc0 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * Based on the 86Box Serial Mouse driver as a framework. * - * Version: @(#)mouse_serial.c 1.0.4 2017/06/11 + * Version: @(#)mouse_serial.c 1.0.3 2017/05/07 * * Author: Fred N. van Kempen, */ @@ -22,18 +22,13 @@ #include "mouse_serial.h" -#define SERMOUSE_TYPE_MSYSTEMS 1 /* Mouse Systems */ -#define SERMOUSE_TYPE_MICROSOFT 2 /* Microsoft */ -#define SERMOUSE_TYPE_LOGITECH 3 /* Logitech */ - - typedef struct mouse_serial_t { - int8_t port, - type; + int port; int pos, delay; int oldb; SERIAL *serial; + int is_ms_format; } mouse_serial_t; @@ -56,16 +51,12 @@ sermouse_timer(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; ms->delay = 0; + if (ms->pos == -1) + { + ms->pos = 0; - switch(ms->type) { - case SERMOUSE_TYPE_MICROSOFT: /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M', 1); - break; - - default: - /* No action needed. */ - break; + serial_write_fifo(ms->serial, 'M'); } } @@ -74,63 +65,53 @@ static uint8_t sermouse_poll(int x, int y, int z, int b, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - uint8_t buff[16]; - int len; + uint8_t data[3]; if (!x && !y && b == ms->oldb) return(1); ms->oldb = b; - - if (ms->type == SERMOUSE_TYPE_MSYSTEMS) y = -y; - if (x>127) x = 127; if (y>127) y = 127; if (x<-128) x = -128; if (y<-128) y = -128; - len = 0; - switch(ms->type) { - case SERMOUSE_TYPE_MSYSTEMS: - buff[0] = 0x80; - buff[0] |= (b&0x01) ? 0x00 : 0x04; /* left button */ - buff[0] |= (b&0x02) ? 0x00 : 0x01; /* middle button */ - buff[0] |= (b&0x04) ? 0x00 : 0x02; /* right button */ - buff[1] = x; - buff[2] = y; - buff[3] = x; /* same as byte 1 */ - buff[4] = y; /* same as byte 2 */ - len = 5; - break; - - case SERMOUSE_TYPE_MICROSOFT: - buff[0] = 0x40; - buff[0] |= (((y>>6)&03)<<2); - buff[0] |= ((x>>6)&03); - if (b&0x01) buff[0] |= 0x20; - if (b&0x02) buff[0] |= 0x10; - buff[1] = x & 0x3F; - buff[2] = y & 0x3F; - len = 3; - break; - - case SERMOUSE_TYPE_LOGITECH: - break; - } - -#if 0 - pclog("Mouse_Serial(%d): [", ms->type); - for (b=0; b>6)&3)<<2); + data[0] |= ((x>>6)&3); + if (b&1) data[0] |= 0x20; + if (b&2) data[0] |= 0x10; + data[1] = x & 0x3F; + data[2] = y & 0x3F; /* Send the packet to the bottom-half of the attached port. */ - for (b=0; bserial, buff[b], 1); +#if 0 + pclog("Mouse_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); +#endif + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); return(0); } +static void * +sermouse_init(void) +{ + mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(ms, 0x00, sizeof(mouse_serial_t)); + ms->port = SERMOUSE_PORT; + + /* Attach a serial port to the mouse. */ + ms->serial = serial_attach(ms->port, sermouse_callback, ms); + + timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); + + return(ms); +} + + static void sermouse_close(void *priv) { @@ -143,14 +124,59 @@ sermouse_close(void *priv) } +mouse_t mouse_serial_microsoft = { + "Microsoft 2-button mouse (serial)", + "msserial", + MOUSE_TYPE_SERIAL, + sermouse_init, + sermouse_close, + sermouse_poll +}; + +static uint8_t +mssystems_mouse_poll(int x, int y, int z, int b, void *priv) +{ + mouse_serial_t *ms = (mouse_serial_t *)priv; + uint8_t data[5]; + + if (!x && !y && b == ms->oldb) return(1); + + ms->oldb = b; + + y=-y; + + if (x>127) x = 127; + if (y>127) y = 127; + if (x<-128) x = -128; + if (y<-128) y = -128; + + data[0] = 0x80; + data[0] |= (b & 0x01 ? 0x00 : 0x04); /*Left button*/ + data[0] |= (b & 0x02 ? 0x00 : 0x01); /*Middle button*/ + data[0] |= (b & 0x04 ? 0x00 : 0x02); /*Right button*/ + data[1] = x; + data[2] = y; + data[3] = x;/*Same as byte 1*/ + data[4] = y;/*Same as byte 2*/ + + pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); + + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); + serial_write_fifo(ms->serial, data[3]); + serial_write_fifo(ms->serial, data[4]); + + return(0); +} + static void * -sermouse_init(int type) +mssystems_mouse_init(void) { mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); memset(ms, 0x00, sizeof(mouse_serial_t)); ms->port = SERMOUSE_PORT; - ms->type = type; - + /* Attach a serial port to the mouse. */ ms->serial = serial_attach(ms->port, sermouse_callback, ms); @@ -159,36 +185,11 @@ sermouse_init(int type) return(ms); } - -static void * -sermouse_init_microsoft(void) -{ - return(sermouse_init(SERMOUSE_TYPE_MICROSOFT)); -} - - -static void * -sermouse_init_msystems(void) -{ - return(sermouse_init(SERMOUSE_TYPE_MSYSTEMS)); -} - - mouse_t mouse_msystems = { "Mouse Systems Mouse (serial)", "mssystems", MOUSE_TYPE_MSYSTEMS, - sermouse_init_msystems, + mssystems_mouse_init, sermouse_close, - sermouse_poll -}; - - -mouse_t mouse_serial_microsoft = { - "Microsoft 2-button mouse (serial)", - "msserial", - MOUSE_TYPE_SERIAL, - sermouse_init_microsoft, - sermouse_close, - sermouse_poll -}; + mssystems_mouse_poll +}; \ No newline at end of file diff --git a/src/serial.c b/src/serial.c index 8cb4b43b5..ae33dc16d 100644 --- a/src/serial.c +++ b/src/serial.c @@ -15,29 +15,25 @@ * * So, for the PC, the offerings were for an IBM Asynchronous * Communications Adapter, and, later, a model for synchronous - * communications. The "Async Adapter" was based on the NS8250 - * UART chip, and is what we now call the "com" port of the PC. + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. * * Of course, many system builders came up with similar boards, * and even more boards were designed where several I/O functions - * were combined into a single "multi-I/O" board, as that saved - * space and buts slots. Initially, these had the chips as-is, - * but later many of these functions were integrated into a - * single "super-I/O" chip. + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. * - * This file implements the standard NS8250, as well as the later - * 16450 and 16550 series, which fixed bugs and added features - * like FIFO buffers, higher line speeds and DMA transfers. - * - * On the lower half of the driver we interface to the host - * system's serial ports for real-world access. + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. * * Based on the 86Box serial port driver as a framework. * - * **NOTE** This module is currently UNDER CONSTRUCTION, do not mess - * with it please! - * - * Version: @(#)serial.c 1.0.8 2017/06/17 + * Version: @(#)serial.c 1.0.7 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -78,10 +74,10 @@ enum { # define IID_IDTX (0x02) # define IID_IDRX (0x04) # define IID_IDERR (0x06) -# define IID_IDTMO (0x0c) /* 16550+ */ -#define IIR_IIRFE (0xc0) /* 16550+ */ +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) # define IIR_FIFO64 (0x20) -# define IIR_FIFOBAD (0x80) +# define IIR_FIFOBAD (0x80) /* 16550 */ # define IIR_FIFOENB (0xc0) /* FCR register bits. */ @@ -148,6 +144,7 @@ static SERIAL ports[NUM_SERIAL]; /* serial port data */ int serial_do_log; +#if 0 static void serial_log(int lvl, const char *fmt, ...) { @@ -162,6 +159,7 @@ serial_log(int lvl, const char *fmt, ...) } #endif } +#endif static void @@ -188,20 +186,11 @@ update_ints(SERIAL *sp) sp->iir = IID_IDMDM; } -serial_log(0, "Serial%d: intr, IIR=%02X, type=%d, mcr=%02X\n",sp->port, sp->iir, sp->type, sp->mctrl); - if (sp->type < UART_TYPE_16450) { - /* Edge-triggered, so always send a pulse. */ -// if ((sp->mctrl & MCR_OUT2) || PCJR) - picint(1 << sp->irq); - } else { - /* Raise or clear the level-based IRQ. */ - if ((sp->mctrl & MCR_OUT2) || PCJR) { - if (stat) - picintlevel(1 << sp->irq); - else - picintc(1 << sp->irq); - } - } + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); } @@ -223,14 +212,13 @@ serial_timer(void *priv) /* Write data to the (input) FIFO. Used by MOUSE driver. */ void -serial_write_fifo(SERIAL *sp, uint8_t dat, int intr) +serial_write_fifo(SERIAL *sp, uint8_t dat) { - /* Stuff data into RX FIFO. */ + /* Stuff data into FIFO. */ sp->fifo[sp->fifo_write] = dat; sp->fifo_write = (sp->fifo_write + 1) & 0xFF; - /* If requested, generate interrupt. */ - if (intr && !(sp->lsr & LSR_DR)) { + if (! (sp->lsr & LSR_DR)) { sp->lsr |= LSR_DR; sp->int_status |= SERINT_RECEIVE; update_ints(sp); @@ -238,31 +226,12 @@ serial_write_fifo(SERIAL *sp, uint8_t dat, int intr) } -/* Grab data from the RX fifo. */ static uint8_t -serial_read_fifo(SERIAL *sp) +read_fifo(SERIAL *sp) { - if (sp->fifo_read != sp->fifo_write) { - /* Grab data from the fifo. */ + if (sp->fifo_read != sp->fifo_write) { sp->dat = sp->fifo[sp->fifo_read]; - sp->fifo_read = (sp->fifo_read+1) & 0xFF; - - /* If we have more, generate (new) int. */ - if (sp->fifo_read != sp->fifo_write) { -#if 1 - sp->receive_delay = 1000*TIMER_USEC; -#else - if (sp->bh != NULL) { - sp->int_status |= SERINT_RECEIVE; - sp->lsr |= LSR_DR; - - /* Update interrupt state. */ - update_ints(sp); - } else { - sp->receive_delay = 1000*TIMER_USEC; - } -#endif - } + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; } return(sp->dat); @@ -284,46 +253,41 @@ serial_write(uint16_t addr, uint8_t val, void *priv) switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { - /* DLAB set, set DLAB low byte. */ sp->dlab1 = val; - } else { - /* DLAB clear, regular data write. */ - sp->thr = val; - if (sp->bh != NULL) { - /* We are linked, so send to BH layer. */ - bhtty_write((BHTTY *)sp->bh, sp->thr); - } + return; + } + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ + bhtty_write((BHTTY *)sp->bh, sp->thr); - /* WRITE completed, we are ready for more. */ + /* The WRITE completed, we are ready for more. */ sp->lsr |= LSR_THRE; sp->int_status |= SERINT_TRANSMIT; update_ints(sp); + } else { + /* Not linked. Just fake LOOPBACK mode. */ + if (! (sp->mctrl & MCR_LMS)) + serial_write_fifo(sp, val); + } - if (sp->mctrl & MCR_LMS) { - /* Echo data back to RX. */ - serial_write_fifo(sp, val, 1); - } + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val); } break; case 1: /* IER / DLAB2 */ if (sp->lcr & LCR_DLAB) { - /* DLAB set, set DLAB high byte. */ sp->dlab2 = val; - } else { - /* DLAB clear, set IER register bits. */ - sp->ier = (val & IER_MASK); - - /* Generate interrupt if needed. */ - update_ints(sp); + return; } + sp->ier = (val & IER_MASK); + update_ints(sp); break; case 2: /* FCR */ - if (sp->type >= UART_TYPE_16550A) { -serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val, sp->type); - sp->fcr = val; - } + sp->fcr = val; break; case 3: /* LCR */ @@ -351,17 +315,12 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val #ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); #endif - sp->lcr = val; if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; break; - case 4: /*MCR*/ - if (sp->bh == NULL) { - /* Not linked, force LOOPBACK mode. */ - val |= MCR_LMS; - } - + case 4: if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { /* * This is old code for use by the Serial Mouse @@ -396,28 +355,28 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val } } sp->mctrl = val; - if (val & MCR_LMS) { /* loopback mode */ uint8_t new_msr; + /*FIXME: WTF does this do?? --FvK */ new_msr = (val & 0x0c) << 4; new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; - if ((sp->msr ^ new_msr) & MSR_CTS) - new_msr |= MSR_DCTS; - if ((sp->msr ^ new_msr) & MSR_DSR) - new_msr |= MSR_DDSR; - if ((sp->msr ^ new_msr) & MSR_DCD) - new_msr |= MSR_DDCD; - if ((sp->msr & MSR_TERI) && !(new_msr & MSR_RI)) - new_msr |= MSR_TERI; + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; sp->msr = new_msr; } break; - case 5: /*LSR*/ + case 5: sp->lsr = val; if (sp->lsr & LSR_DR) sp->int_status |= SERINT_RECEIVE; @@ -428,7 +387,7 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val update_ints(sp); break; - case 6: /*MSR*/ + case 6: sp->msr = val; if (sp->msr & MSR_MASK) sp->int_status |= SERINT_MSR; @@ -436,9 +395,7 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val break; case 7: - if (sp->type > UART_TYPE_8250) { - sp->scratch = val; - } + sp->scratch = val; break; } } @@ -456,17 +413,8 @@ serial_rd_done(void *arg, int num) if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; /* Stuff it into the FIFO and set intr. */ -#if 1 - serial_write_fifo(sp, sp->hold, 0); -#else - serial_write_fifo(sp, sp->hold, 1); -#endif + serial_write_fifo(sp, sp->hold); } - -#if 1 - /* We have data waiting for us.. delay a little, and then read it. */ - timer_add(serial_timer, &sp->receive_delay, &sp->receive_delay, sp); -#endif } @@ -480,48 +428,30 @@ serial_read(uint16_t addr, void *priv) switch (addr&0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { - /* DLAB set, read DLAB low byte. */ ret = sp->dlab1; } else { - /* - * DLAB clear, regular data read. - * First, clear the RXDATA interrupt. - */ - sp->int_status &= ~SERINT_RECEIVE; sp->lsr &= ~LSR_DR; - - /* If there is data in the RX FIFO, grab it. */ - ret = serial_read_fifo(sp); -serial_log(0, "Serial%d: read RBR: %02X\n",sp->port, ret); + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; } break; case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) { - /* DLAB set, read DLAB high byte. */ - ret = sp->dlab2; - } else { - /* DLAB clear, read IER register bits. */ - ret = sp->ier; - } + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; break; case 2: /* IIR */ ret = sp->iir; -serial_log(0, "Serial%d: read IIR: %02X\n",sp->port, sp->iir); - if ((ret & IIR_IID) == IID_IDTX) { - /* Transmit is done. */ sp->int_status &= ~SERINT_TRANSMIT; update_ints(sp); } - - if (sp->type >= UART_TYPE_16550A) { - /* If FIFO enabled.. */ - if (sp->fcr & 0x01) - /* Report FIFO active. */ - ret |= 0xc0; - } + if (sp->fcr & 0x01) + ret |= 0xc0; break; case 3: /* LCR */ @@ -533,10 +463,6 @@ serial_log(0, "Serial%d: read IIR: %02X\n",sp->port, sp->iir); break; case 5: /* LSR */ - /* Clear interrupt state. */ - sp->int_status &= ~SERINT_LSR; - update_ints(sp); - if (sp->lsr & LSR_THRE) sp->lsr |= LSR_TEMT; sp->lsr |= LSR_THRE; @@ -546,24 +472,19 @@ serial_log(0, "Serial%d: read IIR: %02X\n",sp->port, sp->iir); #if 0 sp->lsr |= (LSR_THRE | LSR_TEMT); #endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); break; case 6: - /* Clear MSR interrupt status. */ + ret = sp->msr; + sp->msr &= ~0x0f; sp->int_status &= ~SERINT_MSR; update_ints(sp); - - /* Grab current modem status. */ - ret = sp->msr; - - /* Reset the delta bits. */ - sp->msr &= ~0x0f; break; case 7: - if (sp->type > UART_TYPE_8250) { - ret = sp->scratch; - } + ret = sp->scratch; break; } @@ -642,7 +563,6 @@ serial_init(void) sp = &ports[i]; memset(sp, 0x00, sizeof(SERIAL)); sp->port = (i+1); - sp->type = UART_TYPE_8250; if (i == 0) serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); @@ -650,9 +570,9 @@ serial_init(void) serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); } - /* Link to host port. */ #ifdef WALTJE -// serial_link(1, "COM1"); + /* Link to host port. */ + serial_link(1, "COM1"); serial_link(2, "COM2"); #endif } diff --git a/src/serial.h b/src/serial.h index 09b1b24e6..4602429f0 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,7 +8,7 @@ * * Definitions for the SERIAL card. * - * Version: @(#)serial.h 1.0.5 2017/06/07 + * Version: @(#)serial.h 1.0.4 2017/06/03 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -24,27 +24,16 @@ #define SERIAL2_IRQ 3 -/* Supported UART types. */ -#define UART_TYPE_8250 0 /* standard NS8250 */ -#define UART_TYPE_8250A 1 /* updated NS8250(A) */ -#define UART_TYPE_16450 2 /* 16450 */ -#define UART_TYPE_16550 3 /* 16550 (broken fifo) */ -#define UART_TYPE_16550A 4 /* 16550a (working fifo) */ -#define UART_TYPE_16670 5 /* 64b fifo */ - - typedef struct _serial_ { int8_t port; /* port number (1,2,..) */ int8_t irq; /* IRQ channel used */ uint16_t addr; /* I/O address used */ - int8_t type; /* UART type */ - uint8_t int_status; uint8_t lsr, thr, mctrl, rcr, /* UART registers */ iir, ier, lcr, msr; uint8_t dlab1, dlab2; - uint8_t dat, - hold; + uint8_t dat; + uint8_t int_status; uint8_t scratch; uint8_t fcr; @@ -52,6 +41,7 @@ typedef struct _serial_ { void (*rts_callback)(void *); void *rts_callback_p; + uint8_t hold; uint8_t fifo[256]; int fifo_read, fifo_write; @@ -68,7 +58,7 @@ extern void serial_setup(int port, uint16_t addr, int irq); extern void serial_remove(int port); extern SERIAL *serial_attach(int, void *, void *); extern int serial_link(int, char *); -extern void serial_write_fifo(SERIAL *, uint8_t, int); +extern void serial_write_fifo(SERIAL *, uint8_t); #endif /*EMU_SERIAL_H*/ From 1351cdefb600a0adc57c8aa8e5242957c6e968f6 Mon Sep 17 00:00:00 2001 From: waltje Date: Fri, 16 Jun 2017 17:52:00 -0400 Subject: [PATCH 359/392] Reverted to old (but slightly modified) serial driver. --- src/serial.c | 232 +++++++++++++++++---------------------------------- 1 file changed, 75 insertions(+), 157 deletions(-) diff --git a/src/serial.c b/src/serial.c index c02ef6dae..b108b49f9 100644 --- a/src/serial.c +++ b/src/serial.c @@ -15,29 +15,25 @@ * * So, for the PC, the offerings were for an IBM Asynchronous * Communications Adapter, and, later, a model for synchronous - * communications. The "Async Adapter" was based on the NS8250 - * UART chip, and is what we now call the "com" port of the PC. + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. * * Of course, many system builders came up with similar boards, * and even more boards were designed where several I/O functions - * were combined into a single "multi-I/O" board, as that saved - * space and buts slots. Initially, these had the chips as-is, - * but later many of these functions were integrated into a - * single "super-I/O" chip. + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. * - * This file implements the standard NS8250, as well as the later - * 16450 and 16550 series, which fixed bugs and added features - * like FIFO buffers, higher line speeds and DMA transfers. - * - * On the lower half of the driver we interface to the host - * system's serial ports for real-world access. + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. * * Based on the 86Box serial port driver as a framework. * - * **NOTE** This module is currently UNDER CONSTRUCTION, do not mess - * with it please! - * - * Version: @(#)serial.c 1.0.8 2017/06/17 + * Version: @(#)serial.c 1.0.7 2017/06/04 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -78,10 +74,10 @@ enum { # define IID_IDTX (0x02) # define IID_IDRX (0x04) # define IID_IDERR (0x06) -# define IID_IDTMO (0x0c) /* 16550+ */ -#define IIR_IIRFE (0xc0) /* 16550+ */ +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) # define IIR_FIFO64 (0x20) -# define IIR_FIFOBAD (0x80) +# define IIR_FIFOBAD (0x80) /* 16550 */ # define IIR_FIFOENB (0xc0) /* FCR register bits. */ @@ -188,20 +184,11 @@ update_ints(SERIAL *sp) sp->iir = IID_IDMDM; } -pclog("Serial%d: intr, IIR=%02X, type=%d, mcr=%02X\n",sp->port, sp->iir, sp->type, sp->mctrl); - if (sp->type < UART_TYPE_16450) { - /* Edge-triggered, so always send a pulse. */ -// if ((sp->mctrl & MCR_OUT2) || PCJR) - picint(1 << sp->irq); - } else { - /* Raise or clear the level-based IRQ. */ - if ((sp->mctrl & MCR_OUT2) || PCJR) { - if (stat) - picintlevel(1 << sp->irq); - else - picintc(1 << sp->irq); - } - } + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); } @@ -223,14 +210,13 @@ serial_timer(void *priv) /* Write data to the (input) FIFO. Used by MOUSE driver. */ void -serial_write_fifo(SERIAL *sp, uint8_t dat, int intr) +serial_write_fifo(SERIAL *sp, uint8_t dat, int flag) { - /* Stuff data into RX FIFO. */ + /* Stuff data into FIFO. */ sp->fifo[sp->fifo_write] = dat; sp->fifo_write = (sp->fifo_write + 1) & 0xFF; - /* If requested, generate interrupt. */ - if (intr && !(sp->lsr & LSR_DR)) { + if (! (sp->lsr & LSR_DR)) { sp->lsr |= LSR_DR; sp->int_status |= SERINT_RECEIVE; update_ints(sp); @@ -238,31 +224,12 @@ serial_write_fifo(SERIAL *sp, uint8_t dat, int intr) } -/* Grab data from the RX fifo. */ static uint8_t -serial_read_fifo(SERIAL *sp) +read_fifo(SERIAL *sp) { - if (sp->fifo_read != sp->fifo_write) { - /* Grab data from the fifo. */ + if (sp->fifo_read != sp->fifo_write) { sp->dat = sp->fifo[sp->fifo_read]; - sp->fifo_read = (sp->fifo_read+1) & 0xFF; - - /* If we have more, generate (new) int. */ - if (sp->fifo_read != sp->fifo_write) { -#if 1 - sp->receive_delay = 1000*TIMER_USEC; -#else - if (sp->bh != NULL) { - sp->int_status |= SERINT_RECEIVE; - sp->lsr |= LSR_DR; - - /* Update interrupt state. */ - update_ints(sp); - } else { - sp->receive_delay = 1000*TIMER_USEC; - } -#endif - } + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; } return(sp->dat); @@ -284,46 +251,41 @@ serial_write(uint16_t addr, uint8_t val, void *priv) switch (addr & 0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { - /* DLAB set, set DLAB low byte. */ sp->dlab1 = val; - } else { - /* DLAB clear, regular data write. */ - sp->thr = val; - if (sp->bh != NULL) { - /* We are linked, so send to BH layer. */ - bhtty_write((BHTTY *)sp->bh, sp->thr); - } + return; + } + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ + bhtty_write((BHTTY *)sp->bh, sp->thr); - /* WRITE completed, we are ready for more. */ + /* The WRITE completed, we are ready for more. */ sp->lsr |= LSR_THRE; sp->int_status |= SERINT_TRANSMIT; update_ints(sp); - - if (sp->mctrl & MCR_LMS) { - /* Echo data back to RX. */ + } else { + /* Not linked. Just fake LOOPBACK mode. */ + if (! (sp->mctrl & MCR_LMS)) serial_write_fifo(sp, val, 1); - } + } + + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val, 1); } break; case 1: /* IER / DLAB2 */ if (sp->lcr & LCR_DLAB) { - /* DLAB set, set DLAB high byte. */ sp->dlab2 = val; - } else { - /* DLAB clear, set IER register bits. */ - sp->ier = (val & IER_MASK); - - /* Generate interrupt if needed. */ - update_ints(sp); + return; } + sp->ier = (val & IER_MASK); + update_ints(sp); break; case 2: /* FCR */ - if (sp->type >= UART_TYPE_16550A) { -serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val, sp->type); - sp->fcr = val; - } + sp->fcr = val; break; case 3: /* LCR */ @@ -351,17 +313,12 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val #ifdef ENABLE_SERIAL_LOG serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); #endif - sp->lcr = val; if (sp->bh != NULL) bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; break; - case 4: /*MCR*/ - if (sp->bh == NULL) { - /* Not linked, force LOOPBACK mode. */ - val |= MCR_LMS; - } - + case 4: if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { /* * This is old code for use by the Serial Mouse @@ -396,28 +353,28 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val } } sp->mctrl = val; - if (val & MCR_LMS) { /* loopback mode */ uint8_t new_msr; + /*FIXME: WTF does this do?? --FvK */ new_msr = (val & 0x0c) << 4; new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; - if ((sp->msr ^ new_msr) & MSR_CTS) - new_msr |= MSR_DCTS; - if ((sp->msr ^ new_msr) & MSR_DSR) - new_msr |= MSR_DDSR; - if ((sp->msr ^ new_msr) & MSR_DCD) - new_msr |= MSR_DDCD; - if ((sp->msr & MSR_TERI) && !(new_msr & MSR_RI)) - new_msr |= MSR_TERI; + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; sp->msr = new_msr; } break; - case 5: /*LSR*/ + case 5: sp->lsr = val; if (sp->lsr & LSR_DR) sp->int_status |= SERINT_RECEIVE; @@ -428,7 +385,7 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val update_ints(sp); break; - case 6: /*MSR*/ + case 6: sp->msr = val; if (sp->msr & MSR_MASK) sp->int_status |= SERINT_MSR; @@ -436,9 +393,7 @@ serial_log(0, "Serial%d: tried to enable FIFO (%02x), type %d!\n", sp->port, val break; case 7: - if (sp->type > UART_TYPE_8250) { - sp->scratch = val; - } + sp->scratch = val; break; } } @@ -456,17 +411,8 @@ serial_rd_done(void *arg, int num) if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; /* Stuff it into the FIFO and set intr. */ -#if 1 - serial_write_fifo(sp, sp->hold, 0); -#else serial_write_fifo(sp, sp->hold, 1); -#endif } - -#if 1 - /* We have data waiting for us.. delay a little, and then read it. */ - timer_add(serial_timer, &sp->receive_delay, &sp->receive_delay, sp); -#endif } @@ -480,48 +426,30 @@ serial_read(uint16_t addr, void *priv) switch (addr&0x07) { case 0: /* DATA / DLAB1 */ if (sp->lcr & LCR_DLAB) { - /* DLAB set, read DLAB low byte. */ ret = sp->dlab1; } else { - /* - * DLAB clear, regular data read. - * First, clear the RXDATA interrupt. - */ - sp->int_status &= ~SERINT_RECEIVE; sp->lsr &= ~LSR_DR; - - /* If there is data in the RX FIFO, grab it. */ - ret = serial_read_fifo(sp); -pclog("Serial%d: read RBR: %02X\n",sp->port, ret); + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; } break; case 1: /* LCR / DLAB2 */ - if (sp->lcr & LCR_DLAB) { - /* DLAB set, read DLAB high byte. */ - ret = sp->dlab2; - } else { - /* DLAB clear, read IER register bits. */ - ret = sp->ier; - } + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; break; case 2: /* IIR */ ret = sp->iir; -pclog("Serial%d: read IIR: %02X\n",sp->port, sp->iir); - if ((ret & IIR_IID) == IID_IDTX) { - /* Transmit is done. */ sp->int_status &= ~SERINT_TRANSMIT; update_ints(sp); } - - if (sp->type >= UART_TYPE_16550A) { - /* If FIFO enabled.. */ - if (sp->fcr & 0x01) - /* Report FIFO active. */ - ret |= 0xc0; - } + if (sp->fcr & 0x01) + ret |= 0xc0; break; case 3: /* LCR */ @@ -533,10 +461,6 @@ pclog("Serial%d: read IIR: %02X\n",sp->port, sp->iir); break; case 5: /* LSR */ - /* Clear interrupt state. */ - sp->int_status &= ~SERINT_LSR; - update_ints(sp); - if (sp->lsr & LSR_THRE) sp->lsr |= LSR_TEMT; sp->lsr |= LSR_THRE; @@ -546,24 +470,19 @@ pclog("Serial%d: read IIR: %02X\n",sp->port, sp->iir); #if 0 sp->lsr |= (LSR_THRE | LSR_TEMT); #endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); break; case 6: - /* Clear MSR interrupt status. */ + ret = sp->msr; + sp->msr &= ~0x0f; sp->int_status &= ~SERINT_MSR; update_ints(sp); - - /* Grab current modem status. */ - ret = sp->msr; - - /* Reset the delta bits. */ - sp->msr &= ~0x0f; break; case 7: - if (sp->type > UART_TYPE_8250) { - ret = sp->scratch; - } + ret = sp->scratch; break; } @@ -642,7 +561,6 @@ serial_init(void) sp = &ports[i]; memset(sp, 0x00, sizeof(SERIAL)); sp->port = (i+1); - sp->type = UART_TYPE_8250; if (i == 0) serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); @@ -650,9 +568,9 @@ serial_init(void) serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); } - /* Link to host port. */ #ifdef WALTJE -// serial_link(1, "COM1"); + /* Link to host port. */ + serial_link(1, "COM1"); serial_link(2, "COM2"); #endif } From 66ff71ca554c878c3a5901b4a47805eb50ef4bb0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Jun 2017 00:50:51 +0200 Subject: [PATCH 360/392] Applied the latest mainline PCem commits. --- src/CPU/codegen_timing_pentium.c | 185 +++++++++++++++++++++++++------ src/SOUND/snd_gus.c | 60 ++++++---- src/dma.c | 3 +- 3 files changed, 197 insertions(+), 51 deletions(-) diff --git a/src/CPU/codegen_timing_pentium.c b/src/CPU/codegen_timing_pentium.c index e5e4ed13d..9533027f4 100644 --- a/src/CPU/codegen_timing_pentium.c +++ b/src/CPU/codegen_timing_pentium.c @@ -42,6 +42,11 @@ static int pair_timings[4][4] = #define CYCLES_RMW (2 << 0) #define CYCLES_BRANCH (3 << 0) +/*Instruction has immediate data. Can only be used with PAIR_U/PAIR_V/PAIR_UV*/ +#define CYCLES_HASIMM (3 << 2) +#define CYCLES_IMM8 (1 << 2) +#define CYCLES_IMM1632 (2 << 2) + #define CYCLES_MASK ((1 << 7) - 1) /*Instruction is MMX shift or pack/unpack instruction*/ @@ -62,6 +67,8 @@ static int pair_timings[4][4] = /*Instruction is FXCH and only pairs in V pipe with FX pairable instruction*/ #define PAIR_FXCH (6 << 29) +#define PAIR_FPU (4 << 29) + #define PAIR_MASK (7 << 29) /*Instruction has input dependency on register in REG field*/ @@ -296,38 +303,38 @@ static uint32_t opcode_timings_mod3[256] = /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* ADD ADD PUSH ES POP ES*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), /* OR OR OR OR*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID, + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID, /* ADC ADC ADC ADC*/ /*10*/ PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* ADC ADC PUSH SS POP SS*/ - PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), + PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), /* SBB SBB SBB SBB*/ PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), + PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), /* AND AND AND AND*/ /*20*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* AND AND DAA*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* SUB SUB SUB SUB*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* XOR XOR XOR XOR*/ /*30*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* XOR XOR AAA*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* CMP CMP CMP CMP*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | SRCDEP_REG, /* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* INC EAX INC ECX INC EDX INC EBX*/ /*40*/ PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_UV | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_UV | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX, @@ -810,14 +817,20 @@ static uint32_t opcode_timings_df_mod3[8] = PAIR_NP | CYCLES(2), INVALID, INVALID, INVALID }; +static uint32_t opcode_timings_81[8] = +{ + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | SRCDEP_REG | CYCLES_IMM1632 +}; static uint32_t opcode_timings_8x[8] = { - PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, - PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RM | SRCDEP_REG | CYCLES_IMM8 }; static int decode_delay; static uint8_t last_prefix; +static int prefixes; static inline int COUNT(uint32_t c, int op_32) { @@ -831,6 +844,10 @@ static inline int COUNT(uint32_t c, int op_32) return c & 0xffff; if ((c & PAIR_MASK) == PAIR_FX) return c & 0xffff; + if ((c & PAIR_MASK) == PAIR_FXCH) + return c & 0xffff; + if ((c & PAIR_UV) && !(c & PAIR_FPU)) + c &= 3; switch (c & CYCLES_MASK) { case CYCLES_REG: @@ -848,6 +865,80 @@ static inline int COUNT(uint32_t c, int op_32) return c; } +static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32) +{ + if (op_32 & 0x200) + { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) + { + /*Has SIB*/ + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) + return 1; + } + else + { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) + return 1; + } + } + else + { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) + return 1; + } + return 0; +} + +/*The instruction is only of interest here if it's longer than 7 bytes, as that's the + limit on Pentium MMX parallel decoding*/ +static inline int codegen_timing_instr_length(uint32_t timing, uint32_t fetchdat, int op_32) +{ + int len = prefixes; + if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) + { + len += 2; /*Opcode + ModR/M*/ + if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) + len++; + if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; + + if (op_32 & 0x200) + { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) + { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } + else + { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } + else + { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; + } + } + + return len; +} + void codegen_timing_pentium_block_start() { u_pipe_full = decode_delay = 0; @@ -856,10 +947,12 @@ void codegen_timing_pentium_block_start() void codegen_timing_pentium_start() { last_prefix = 0; + prefixes = 0; } void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) { + prefixes++; if (cpu_hasMMX && prefix == 0x0f) { /*On Pentium MMX 0fh prefix is 'free'*/ @@ -933,11 +1026,16 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) default: switch (opcode) { - case 0x80: case 0x81: case 0x82: case 0x83: + case 0x80: case 0x82: case 0x83: timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; if (!mod3) opcode = (fetchdat >> 3) & 7; break; + case 0x81: + timings = mod3 ? opcode_timings_mod3 : opcode_timings_81; + if (!mod3) + opcode = (fetchdat >> 3) & 7; + break; case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; @@ -980,23 +1078,38 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && !decode_delay) { - int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; - int t2 = timings[opcode] & CYCLES_MASK; - int t_pair; + int has_displacement; - if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) - fatal("Pair out of range\n"); + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) + { + int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; + int t2 = timings[opcode] & CYCLES_MASK; + int t_pair; - t_pair = pair_timings[t1][t2]; - if (t_pair < 1) - fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); + if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) + t1 &= 3; + if (!(timings[opcode] & PAIR_FPU)) + t2 &= 3; + + if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) + fatal("Pair out of range\n"); + + t_pair = pair_timings[t1][t2]; + if (t_pair < 1) + fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); - codegen_block_cycles += t_pair; - decode_delay = (-t_pair) + 1; + codegen_block_cycles += t_pair; + decode_delay = (-t_pair) + 1; - /*Instruction can pair with previous*/ - u_pipe_full = 0; - return; + /*Instruction can pair with previous*/ + u_pipe_full = 0; + return; + } } nopair: /*Instruction can not pair with previous*/ @@ -1008,13 +1121,23 @@ nopair: if ((timings[opcode] & PAIR_U) && !decode_delay) { - /*Instruction might pair with next*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8); - return; + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) + { + /*Instruction might pair with next*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8); + return; + } } /*Instruction can not pair and must run now*/ diff --git a/src/SOUND/snd_gus.c b/src/SOUND/snd_gus.c index bf625dfb2..3981b4960 100644 --- a/src/SOUND/snd_gus.c +++ b/src/SOUND/snd_gus.c @@ -2,14 +2,14 @@ #include #include #include "../ibm.h" + +#include "../device.h" +#include "../dma.h" #include "../io.h" #include "../pic.h" -#include "../dma.h" -#include "../timer.h" -#include "../device.h" #include "sound.h" #include "snd_gus.h" - +#include "../timer.h" typedef struct gus_t { @@ -235,7 +235,7 @@ void writegus(uint16_t addr, uint8_t val, void *p) case 0xA: /*Current addr high*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1F00FFFF)|(val<<16); -gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); + gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); break; case 0xB: /*Current addr low*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFFFF00)|val; @@ -257,10 +257,6 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); switch (gus->global) { case 0: /*Voice control*/ - if (!(val&1) && gus->ctrl[gus->voice]&1) - { - } - gus->ctrl[gus->voice] = val & 0x7f; old = gus->waveirqs[gus->voice]; @@ -307,7 +303,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8); break; case 0xB: /*Current addr low*/ gus->cur[gus->voice]=(gus->cur[gus->voice]&0x1FFF00FF)|(val<<8); -gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); + gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); break; case 0xC: /*Pan*/ gus->pan_l[gus->voice] = 15 - (val & 0xf); @@ -341,13 +337,27 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); while (c<65536) { int dma_result; - d = gus->ram[gus->dmaaddr]; - if (val & 0x80) d ^= 0x80; - dma_result = dma_channel_write(gus->dma, d); - if (dma_result == DMA_NODATA) - break; + if (val & 0x04) + { + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); + d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8); + if (val & 0x80) + d ^= 0x8080; + dma_result = dma_channel_write(gus->dma, d); + if (dma_result == DMA_NODATA) + break; + } + else + { + d = gus->ram[gus->dmaaddr]; + if (val & 0x80) + d ^= 0x80; + dma_result = dma_channel_write(gus->dma, d); + if (dma_result == DMA_NODATA) + break; + } gus->dmaaddr++; - gus->dmaaddr&=0xFFFFF; + gus->dmaaddr &= 0xFFFFF; c++; if (dma_result & DMA_OVER) break; @@ -363,10 +373,22 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8); d = dma_channel_read(gus->dma); if (d == DMA_NODATA) break; - if (val&0x80) d^=0x80; - gus->ram[gus->dmaaddr]=d; + if (val & 0x04) + { + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); + if (val & 0x80) + d ^= 0x8080; + gus->ram[gus_addr] = d & 0xff; + gus->ram[gus_addr +1] = (d >> 8) & 0xff; + } + else + { + if (val & 0x80) + d ^= 0x80; + gus->ram[gus->dmaaddr] = d; + } gus->dmaaddr++; - gus->dmaaddr&=0xFFFFF; + gus->dmaaddr &= 0xFFFFF; c++; if (d & DMA_OVER) break; diff --git a/src/dma.c b/src/dma.c index 96f98bd96..ae95ffafa 100644 --- a/src/dma.c +++ b/src/dma.c @@ -705,11 +705,12 @@ int dma_channel_write(int channel, uint16_t val) dma16.cc[channel] = dma16.cb[channel] + 1; dma16.ac[channel] = dma16.ab[channel]; } + else dma16.m |= (1 << channel); dma16.stat |= (1 << channel); } - if (dma.m & (1 << channel)) + if (dma16.m & (1 << channel)) return DMA_OVER; } return 0; From c68b460b53e0f95dc00d06bb1d4b1973afb9c1ce Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 17 Jun 2017 01:01:40 +0200 Subject: [PATCH 361/392] Fixed (again) massive OS/2 S3 Trio64 driver spam and MIX + src_dat variable initialized properly + warning gone. --- src/VIDEO/vid_s3.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 61a24ce64..3079eec9b 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1444,7 +1444,6 @@ uint8_t s3_accel_read(uint32_t addr, void *p) case 0xf: dest_dat = ~(src_dat | dest_dat); break; \ } - #define WRITE(addr) if (s3->bpp == 0) \ { \ svga->vram[(addr) & s3->vram_mask] = dest_dat; \ @@ -1660,6 +1659,15 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dest = s3->accel.cy * s3->width; } + + s3->status_9ae9 = 4; /*To avoid the spam from OS/2's drivers*/ + + if ((s3->accel.cmd & 0x100) && !cpu_input) + { + s3->status_9ae9 = 2; /*To avoid the spam from OS/2's drivers*/ + return; /*Wait for data from CPU*/ + } + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ frgd_mix = (s3->accel.frgd_mix >> 5) & 3; @@ -1685,7 +1693,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ(s3->accel.dest + s3->accel.cx, dest_dat); MIX - + WRITE(s3->accel.dest + s3->accel.cx); } } @@ -1703,7 +1711,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.cmd & 0x20) s3->accel.cx -= (s3->accel.maj_axis_pcnt & 0xfff) + 1; else s3->accel.cx += (s3->accel.maj_axis_pcnt & 0xfff) + 1; s3->accel.sx = s3->accel.maj_axis_pcnt & 0xfff; - + if (s3->accel.cmd & 0x80) s3->accel.cy++; else s3->accel.cy--; @@ -1747,19 +1755,19 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - + if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && - (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7) + (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && (s3->accel.bkgd_mix & 0xf) == 7) { - while (1) - { + while (count-- && s3->accel.sy >= 0) + { if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { READ(s3->accel.src + s3->accel.cx, src_dat); - - dest_dat = src_dat; - + + dest_dat = src_dat; + WRITE(s3->accel.dest + s3->accel.dx); } @@ -1782,15 +1790,13 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; return; } } } } else - { + { while (count-- && s3->accel.sy >= 0) { if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && @@ -1798,8 +1804,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat { if (vram_mask) { - READ(s3->accel.src + s3->accel.cx, mix_dat) - mix_dat = mix_dat ? mix_mask : 0; + READ(s3->accel.src + s3->accel.cx, mix_dat) + mix_dat = mix_dat ? mix_mask : 0; } switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { @@ -1814,7 +1820,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat compare_mode < 2) { READ(s3->accel.dest + s3->accel.dx, dest_dat); - + MIX WRITE(s3->accel.dest + s3->accel.dx); From 9b6aaaa5fd87a71a71c42bed96be911c8713ac13 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 17 Jun 2017 07:23:49 +0200 Subject: [PATCH 362/392] Reverted the serial code to the working one again. --- src/mouse_serial.c | 177 ++++++------ src/serial.c | 660 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 749 insertions(+), 88 deletions(-) create mode 100644 src/serial.c diff --git a/src/mouse_serial.c b/src/mouse_serial.c index fdda61e13..bb855ecc0 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * Based on the 86Box Serial Mouse driver as a framework. * - * Version: @(#)mouse_serial.c 1.0.4 2017/06/11 + * Version: @(#)mouse_serial.c 1.0.3 2017/05/07 * * Author: Fred N. van Kempen, */ @@ -22,18 +22,13 @@ #include "mouse_serial.h" -#define SERMOUSE_TYPE_MSYSTEMS 1 /* Mouse Systems */ -#define SERMOUSE_TYPE_MICROSOFT 2 /* Microsoft */ -#define SERMOUSE_TYPE_LOGITECH 3 /* Logitech */ - - typedef struct mouse_serial_t { - int8_t port, - type; + int port; int pos, delay; int oldb; SERIAL *serial; + int is_ms_format; } mouse_serial_t; @@ -56,16 +51,12 @@ sermouse_timer(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; ms->delay = 0; + if (ms->pos == -1) + { + ms->pos = 0; - switch(ms->type) { - case SERMOUSE_TYPE_MICROSOFT: /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M', 1); - break; - - default: - /* No action needed. */ - break; + serial_write_fifo(ms->serial, 'M'); } } @@ -74,63 +65,53 @@ static uint8_t sermouse_poll(int x, int y, int z, int b, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - uint8_t buff[16]; - int len; + uint8_t data[3]; if (!x && !y && b == ms->oldb) return(1); ms->oldb = b; - - if (ms->type == SERMOUSE_TYPE_MSYSTEMS) y = -y; - if (x>127) x = 127; if (y>127) y = 127; if (x<-128) x = -128; if (y<-128) y = -128; - len = 0; - switch(ms->type) { - case SERMOUSE_TYPE_MSYSTEMS: - buff[0] = 0x80; - buff[0] |= (b&0x01) ? 0x00 : 0x04; /* left button */ - buff[0] |= (b&0x02) ? 0x00 : 0x01; /* middle button */ - buff[0] |= (b&0x04) ? 0x00 : 0x02; /* right button */ - buff[1] = x; - buff[2] = y; - buff[3] = x; /* same as byte 1 */ - buff[4] = y; /* same as byte 2 */ - len = 5; - break; - - case SERMOUSE_TYPE_MICROSOFT: - buff[0] = 0x40; - buff[0] |= (((y>>6)&03)<<2); - buff[0] |= ((x>>6)&03); - if (b&0x01) buff[0] |= 0x20; - if (b&0x02) buff[0] |= 0x10; - buff[1] = x & 0x3F; - buff[2] = y & 0x3F; - len = 3; - break; - - case SERMOUSE_TYPE_LOGITECH: - break; - } - -#if 0 - pclog("Mouse_Serial(%d): [", ms->type); - for (b=0; b>6)&3)<<2); + data[0] |= ((x>>6)&3); + if (b&1) data[0] |= 0x20; + if (b&2) data[0] |= 0x10; + data[1] = x & 0x3F; + data[2] = y & 0x3F; /* Send the packet to the bottom-half of the attached port. */ - for (b=0; bserial, buff[b], 1); +#if 0 + pclog("Mouse_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); +#endif + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); return(0); } +static void * +sermouse_init(void) +{ + mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(ms, 0x00, sizeof(mouse_serial_t)); + ms->port = SERMOUSE_PORT; + + /* Attach a serial port to the mouse. */ + ms->serial = serial_attach(ms->port, sermouse_callback, ms); + + timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); + + return(ms); +} + + static void sermouse_close(void *priv) { @@ -143,14 +124,59 @@ sermouse_close(void *priv) } +mouse_t mouse_serial_microsoft = { + "Microsoft 2-button mouse (serial)", + "msserial", + MOUSE_TYPE_SERIAL, + sermouse_init, + sermouse_close, + sermouse_poll +}; + +static uint8_t +mssystems_mouse_poll(int x, int y, int z, int b, void *priv) +{ + mouse_serial_t *ms = (mouse_serial_t *)priv; + uint8_t data[5]; + + if (!x && !y && b == ms->oldb) return(1); + + ms->oldb = b; + + y=-y; + + if (x>127) x = 127; + if (y>127) y = 127; + if (x<-128) x = -128; + if (y<-128) y = -128; + + data[0] = 0x80; + data[0] |= (b & 0x01 ? 0x00 : 0x04); /*Left button*/ + data[0] |= (b & 0x02 ? 0x00 : 0x01); /*Middle button*/ + data[0] |= (b & 0x04 ? 0x00 : 0x02); /*Right button*/ + data[1] = x; + data[2] = y; + data[3] = x;/*Same as byte 1*/ + data[4] = y;/*Same as byte 2*/ + + pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); + + serial_write_fifo(ms->serial, data[0]); + serial_write_fifo(ms->serial, data[1]); + serial_write_fifo(ms->serial, data[2]); + serial_write_fifo(ms->serial, data[3]); + serial_write_fifo(ms->serial, data[4]); + + return(0); +} + static void * -sermouse_init(int type) +mssystems_mouse_init(void) { mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); memset(ms, 0x00, sizeof(mouse_serial_t)); ms->port = SERMOUSE_PORT; - ms->type = type; - + /* Attach a serial port to the mouse. */ ms->serial = serial_attach(ms->port, sermouse_callback, ms); @@ -159,36 +185,11 @@ sermouse_init(int type) return(ms); } - -static void * -sermouse_init_microsoft(void) -{ - return(sermouse_init(SERMOUSE_TYPE_MICROSOFT)); -} - - -static void * -sermouse_init_msystems(void) -{ - return(sermouse_init(SERMOUSE_TYPE_MSYSTEMS)); -} - - mouse_t mouse_msystems = { "Mouse Systems Mouse (serial)", "mssystems", MOUSE_TYPE_MSYSTEMS, - sermouse_init_msystems, + mssystems_mouse_init, sermouse_close, - sermouse_poll -}; - - -mouse_t mouse_serial_microsoft = { - "Microsoft 2-button mouse (serial)", - "msserial", - MOUSE_TYPE_SERIAL, - sermouse_init_microsoft, - sermouse_close, - sermouse_poll -}; + mssystems_mouse_poll +}; \ No newline at end of file diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 000000000..ae33dc16d --- /dev/null +++ b/src/serial.c @@ -0,0 +1,660 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of NS8250-series UART devices. + * + * The original IBM-PC design did not have any serial ports of + * any kind. Rather, these were offered as add-on devices, most + * likely because a) most people did not need one at the time, + * and, b) this way, IBM could make more money off them. + * + * So, for the PC, the offerings were for an IBM Asynchronous + * Communications Adapter, and, later, a model for synchronous + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. + * + * Of course, many system builders came up with similar boards, + * and even more boards were designed where several I/O functions + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. + * + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. + * + * Based on the 86Box serial port driver as a framework. + * + * Version: @(#)serial.c 1.0.7 2017/06/04 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#include +#include "ibm.h" +#include "io.h" +#include "pic.h" +#include "timer.h" +#include "serial.h" +#include "plat_serial.h" + + +#define NUM_SERIAL 2 /* we support 2 ports */ + + +enum { + SERINT_LSR = 1, + SERINT_RECEIVE = 2, + SERINT_TRANSMIT = 4, + SERINT_MSR = 8 +}; + + +/* IER register bits. */ +#define IER_RDAIE (0x01) +#define IER_THREIE (0x02) +#define IER_RXLSIE (0x04) +#define IER_MSIE (0x08) +#define IER_SLEEP (0x10) /* NS16750 */ +#define IER_LOWPOWER (0x20) /* NS16750 */ +#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ + +/* IIR register bits. */ +#define IIR_IP (0x01) +#define IIR_IID (0x0e) +# define IID_IDMDM (0x00) +# define IID_IDTX (0x02) +# define IID_IDRX (0x04) +# define IID_IDERR (0x06) +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) +# define IIR_FIFO64 (0x20) +# define IIR_FIFOBAD (0x80) /* 16550 */ +# define IIR_FIFOENB (0xc0) + +/* FCR register bits. */ +#define FCR_FCRFE (0x01) +#define FCR_RFR (0x02) +#define FCR_TFR (0x04) +#define FCR_SELDMA1 (0x08) +#define FCR_FENB64 (0x20) /* 16750 */ +#define FCR_RTLS (0xc0) +# define FCR_RTLS1 (0x00) +# define FCR_RTLS4 (0x40) +# define FCR_RTLS8 (0x80) +# define FCR_RTLS14 (0xc0) + +/* LCR register bits. */ +#define LCR_WLS (0x03) +# define WLS_BITS5 (0x00) +# define WLS_BITS6 (0x01) +# define WLS_BITS7 (0x02) +# define WLS_BITS8 (0x03) +#define LCR_SBS (0x04) +#define LCR_PE (0x08) +#define LCR_EP (0x10) +#define LCR_PS (0x20) +# define PAR_NONE (0x00) +# define PAR_EVEN (LCR_PE | LCR_EP) +# define PAR_ODD (LCR_PE) +# define PAR_MARK (LCR_PE | LCR_PS) +# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) +#define LCR_BC (0x40) +#define LCR_DLAB (0x80) + +/* MCR register bits. */ +#define MCR_DTR (0x01) +#define MCR_RTS (0x02) +#define MCR_OUT1 (0x04) /* 8250 */ +#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ +#define MCR_LMS (0x10) +#define MCR_AUTOFLOW (0x20) /* 16750 */ + +/* LSR register bits. */ +#define LSR_DR (0x01) +#define LSR_OE (0x02) +#define LSR_PE (0x04) +#define LSR_FE (0x08) +#define LSR_BI (0x10) +#define LSR_THRE (0x20) +#define LSR_TEMT (0x40) +#define LSR_RXFE (0x80) + +/* MSR register bits. */ +#define MSR_DCTS (0x01) +#define MSR_DDSR (0x02) +#define MSR_TERI (0x04) +#define MSR_DDCD (0x08) +#define MSR_CTS (0x10) +#define MSR_DSR (0x20) +#define MSR_RI (0x40) +#define MSR_DCD (0x80) +#define MSR_MASK (0x0f) + + +static SERIAL ports[NUM_SERIAL]; /* serial port data */ + int serial_do_log; + + +#if 0 +static void +serial_log(int lvl, const char *fmt, ...) +{ +#ifdef ENABLE_SERIAL_LOG + va_list ap; + + if (serial_do_log >= lvl) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); + } +#endif +} +#endif + + +static void +update_ints(SERIAL *sp) +{ + int stat = 0; + + sp->iir = IIR_IP; + if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { + /* Line Status interrupt. */ + stat = 1; + sp->iir = IID_IDERR; + } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { + /* Received Data available. */ + stat = 1; + sp->iir = IID_IDRX; + } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { + /* Transmit Data empty. */ + stat = 1; + sp->iir = IID_IDTX; + } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { + /* Modem Status interrupt. */ + stat = 1; + sp->iir = IID_IDMDM; + } + + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); +} + + +/* Fake interrupt generator, needed for Serial Mouse. */ +static void +serial_timer(void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + + sp->receive_delay = 0; + + if (sp->fifo_read != sp->fifo_write) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } +} + + +/* Write data to the (input) FIFO. Used by MOUSE driver. */ +void +serial_write_fifo(SERIAL *sp, uint8_t dat) +{ + /* Stuff data into FIFO. */ + sp->fifo[sp->fifo_write] = dat; + sp->fifo_write = (sp->fifo_write + 1) & 0xFF; + + if (! (sp->lsr & LSR_DR)) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } +} + + +static uint8_t +read_fifo(SERIAL *sp) +{ + if (sp->fifo_read != sp->fifo_write) { + sp->dat = sp->fifo[sp->fifo_read]; + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; + } + + return(sp->dat); +} + + +/* Handle a WRITE operation to one of our registers. */ +static void +serial_write(uint16_t addr, uint8_t val, void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + uint8_t wl, sb, pa; + uint16_t baud; + long speed; + +#if ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: write(%04x, %02x)\n", sp->port, addr, val); +#endif + switch (addr & 0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab1 = val; + return; + } + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ + bhtty_write((BHTTY *)sp->bh, sp->thr); + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + } else { + /* Not linked. Just fake LOOPBACK mode. */ + if (! (sp->mctrl & MCR_LMS)) + serial_write_fifo(sp, val); + } + + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val); + } + break; + + case 1: /* IER / DLAB2 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab2 = val; + return; + } + sp->ier = (val & IER_MASK); + update_ints(sp); + break; + + case 2: /* FCR */ + sp->fcr = val; + break; + + case 3: /* LCR */ + if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { + /* We dropped DLAB, so handle baudrate. */ + baud = ((sp->dlab2<<8) | sp->dlab1); + if (baud > 0) { + speed = 115200UL/baud; +#ifdef ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", + sp->port, baud, speed); +#endif + if ((sp->bh != NULL) && (speed > 0)) + bhtty_speed((BHTTY *)sp->bh, speed); + } else { +#ifdef ENABLE_SERIAL_LOG + serial_log(1, "Serial%d: divisor %u invalid!\n", + sp->port, baud); +#endif + } + } + wl = (val & LCR_WLS) + 5; /* databits */ + sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ + pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; +#ifdef ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); +#endif + if (sp->bh != NULL) + bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; + break; + + case 4: + if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { + /* + * This is old code for use by the Serial Mouse + * driver. If the user toggles RTS, serial mice + * are expected to send an ID, to inform any + * enumerator there 'is' something. + */ + if (sp->rts_callback) { + sp->rts_callback(sp->rts_callback_p); +#ifdef ENABLE_SERIAL_LOG + serial_log(1, "RTS raised; sending ID\n"); +#endif + } + } + + if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { + if (sp->bh != NULL) { + /* Linked, start host port. */ + (void)bhtty_active(sp->bh, 1); + } else { + /* Not linked, start RX timer. */ + timer_add(serial_timer, + &sp->receive_delay, + &sp->receive_delay, sp); + + /* Fake CTS, DSR and DCD (for now.) */ + sp->msr = (MSR_CTS | MSR_DCTS | + MSR_DSR | MSR_DDSR | + MSR_DCD | MSR_DDCD); + sp->int_status |= SERINT_MSR; + update_ints(sp); + } + } + sp->mctrl = val; + if (val & MCR_LMS) { /* loopback mode */ + uint8_t new_msr; + + /*FIXME: WTF does this do?? --FvK */ + new_msr = (val & 0x0c) << 4; + new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; + new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; + + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + sp->msr = new_msr; + } + break; + + case 5: + sp->lsr = val; + if (sp->lsr & LSR_DR) + sp->int_status |= SERINT_RECEIVE; + if (sp->lsr & 0x1e) + sp->int_status |= SERINT_LSR; + if (sp->lsr & LSR_THRE) + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + break; + + case 6: + sp->msr = val; + if (sp->msr & MSR_MASK) + sp->int_status |= SERINT_MSR; + update_ints(sp); + break; + + case 7: + sp->scratch = val; + break; + } +} + + +/* BHTTY READ COMPLETE handler. */ +static void +serial_rd_done(void *arg, int num) +{ + SERIAL *sp = (SERIAL *)arg; + + /* We can do at least 'num' bytes.. */ + while (num-- > 0) { + /* Get a byte from them. */ + if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; + + /* Stuff it into the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold); + } +} + + +/* Handle a READ operation from one of our registers. */ +static uint8_t +serial_read(uint16_t addr, void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + uint8_t ret = 0x00; + + switch (addr&0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + ret = sp->dlab1; + } else { + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; + } + break; + + case 1: /* LCR / DLAB2 */ + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; + break; + + case 2: /* IIR */ + ret = sp->iir; + if ((ret & IIR_IID) == IID_IDTX) { + sp->int_status &= ~SERINT_TRANSMIT; + update_ints(sp); + } + if (sp->fcr & 0x01) + ret |= 0xc0; + break; + + case 3: /* LCR */ + ret = sp->lcr; + break; + + case 4: /* MCR */ + ret = sp->mctrl; + break; + + case 5: /* LSR */ + if (sp->lsr & LSR_THRE) + sp->lsr |= LSR_TEMT; + sp->lsr |= LSR_THRE; + ret = sp->lsr; + if (sp->lsr & 0x1f) + sp->lsr &= ~0x1e; +#if 0 + sp->lsr |= (LSR_THRE | LSR_TEMT); +#endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); + break; + + case 6: + ret = sp->msr; + sp->msr &= ~0x0f; + sp->int_status &= ~SERINT_MSR; + update_ints(sp); + break; + + case 7: + ret = sp->scratch; + break; + } + + return(ret); +} + + +/* Set up a serial port for use. */ +void +serial_setup(int port, uint16_t addr, int irq) +{ + SERIAL *sp; + +#ifdef ENABLE_SERIAL_LOG + serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); +#endif + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + /* Set up the basic info. */ + if (sp->addr != 0x0000) { + /* Unlink the previous handler. Just in case. */ + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); + } + sp->addr = addr; + sp->irq = irq; + + /* Request an I/O range. */ + io_sethandler(sp->addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); +} + + +/* Release all resources held by a serial port. */ +void +serial_remove(int port) +{ + SERIAL *sp; + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + // FIXME: stop timer, if enabled! + + /* Close the host device. */ + if (sp->bh != NULL) + (void)serial_link(port, NULL); + + /* Release our I/O range. */ + if (sp->addr != 0x0000) { + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); + } + sp->addr = 0x0000; + sp->irq = 0; +} + + +/* Initialize the serial ports. */ +void +serial_init(void) +{ + SERIAL *sp; + int i; + +#if ENABLE_SERIAL_LOG + serial_do_log = ENABLE_SERIAL_LOG; +#endif + + /* FIXME: we should probably initialize the platform module here. */ + + /* Initialize each port. */ + for (i=0; iport = (i+1); + + if (i == 0) + serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); + } + +#ifdef WALTJE + /* Link to host port. */ + serial_link(1, "COM1"); + serial_link(2, "COM2"); +#endif +} + + +/* + * Reset the serial ports. + * + * This should be a per-port function. + */ +void +serial_reset(void) +{ + SERIAL *sp; + int i; + + for (i=0; iiir = sp->ier = sp->lcr = sp->mctrl = 0x00; + sp->fifo_read = sp->fifo_write = 0x00; + } +} + + +/* Link a serial port to a host (serial) port. */ +int +serial_link(int port, char *arg) +{ + SERIAL *sp; + BHTTY *bh; + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + if (arg != NULL) { + /* Make sure we're not already linked. */ + if (sp->bh != NULL) { +#if ENABLE_SERIAL_LOG + serial_log(0, "Serial%d already linked!\n", port); +#endif + return(-1); + } + + /* Request a port from the host system. */ + bh = bhtty_open(arg, 0); + if (bh == NULL) { +#if ENABLE_SERIAL_LOG + serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); +#endif + return(-1); + } + sp->bh = bh; + + /* Set up bottom-half I/O callback info. */ + bh->rd_done = serial_rd_done; + bh->rd_arg = sp; + } else { + /* If we are linked, unlink it. */ + if (sp->bh != NULL) { + bhtty_close((BHTTY *)sp->bh); + sp->bh = NULL; + } + + } + + return(0); +} + + +/* Attach another device (MOUSE) to a serial port. */ +SERIAL * +serial_attach(int port, void *func, void *arg) +{ + SERIAL *sp; + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + /* Set up callback info. */ + sp->rts_callback = func; + sp->rts_callback_p = arg; + + return(sp); +} From 8b03a29638e82cb11f004eab7ec85f0241d3358e Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 17 Jun 2017 03:31:11 -0400 Subject: [PATCH 363/392] Fix up the serial mess. New mouse_serial.ch, new serial.h, updated (but old) serial.c. --- src/mouse_serial.c | 177 ++++++------ src/serial.c | 660 --------------------------------------------- src/serial.h | 29 +- 3 files changed, 108 insertions(+), 758 deletions(-) delete mode 100644 src/serial.c diff --git a/src/mouse_serial.c b/src/mouse_serial.c index bb855ecc0..5095ca949 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * Based on the 86Box Serial Mouse driver as a framework. * - * Version: @(#)mouse_serial.c 1.0.3 2017/05/07 + * Version: @(#)mouse_serial.c 1.0.5 2017/06/18 * * Author: Fred N. van Kempen, */ @@ -22,13 +22,18 @@ #include "mouse_serial.h" +#define SERMOUSE_TYPE_MSYSTEMS 1 /* Mouse Systems */ +#define SERMOUSE_TYPE_MICROSOFT 2 /* Microsoft */ +#define SERMOUSE_TYPE_LOGITECH 3 /* Logitech */ + + typedef struct mouse_serial_t { - int port; + int8_t port, + type; int pos, delay; int oldb; SERIAL *serial; - int is_ms_format; } mouse_serial_t; @@ -51,12 +56,16 @@ sermouse_timer(void *priv) mouse_serial_t *ms = (mouse_serial_t *)priv; ms->delay = 0; - if (ms->pos == -1) - { - ms->pos = 0; + switch(ms->type) { + case SERMOUSE_TYPE_MICROSOFT: /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M'); + serial_write_fifo(ms->serial, 'M', 1); + break; + + default: + /* No action needed. */ + break; } } @@ -65,53 +74,63 @@ static uint8_t sermouse_poll(int x, int y, int z, int b, void *priv) { mouse_serial_t *ms = (mouse_serial_t *)priv; - uint8_t data[3]; + uint8_t buff[16]; + int len; if (!x && !y && b == ms->oldb) return(1); ms->oldb = b; + + if (ms->type == SERMOUSE_TYPE_MSYSTEMS) y = -y; + if (x>127) x = 127; if (y>127) y = 127; if (x<-128) x = -128; if (y<-128) y = -128; - /* Use Microsoft format. */ - data[0] = 0x40; - data[0] |= (((y>>6)&3)<<2); - data[0] |= ((x>>6)&3); - if (b&1) data[0] |= 0x20; - if (b&2) data[0] |= 0x10; - data[1] = x & 0x3F; - data[2] = y & 0x3F; + len = 0; + switch(ms->type) { + case SERMOUSE_TYPE_MSYSTEMS: + buff[0] = 0x80; + buff[0] |= (b&0x01) ? 0x00 : 0x04; /* left button */ + buff[0] |= (b&0x02) ? 0x00 : 0x01; /* middle button */ + buff[0] |= (b&0x04) ? 0x00 : 0x02; /* right button */ + buff[1] = x; + buff[2] = y; + buff[3] = x; /* same as byte 1 */ + buff[4] = y; /* same as byte 2 */ + len = 5; + break; + + case SERMOUSE_TYPE_MICROSOFT: + buff[0] = 0x40; + buff[0] |= (((y>>6)&03)<<2); + buff[0] |= ((x>>6)&03); + if (b&0x01) buff[0] |= 0x20; + if (b&0x02) buff[0] |= 0x10; + buff[1] = x & 0x3F; + buff[2] = y & 0x3F; + len = 3; + break; + + case SERMOUSE_TYPE_LOGITECH: + break; + } + +#if 0 + pclog("Mouse_Serial(%d): [", ms->type); + for (b=0; bserial, data[0]); - serial_write_fifo(ms->serial, data[1]); - serial_write_fifo(ms->serial, data[2]); + for (b=0; bserial, buff[b], 1); return(0); } -static void * -sermouse_init(void) -{ - mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); - memset(ms, 0x00, sizeof(mouse_serial_t)); - ms->port = SERMOUSE_PORT; - - /* Attach a serial port to the mouse. */ - ms->serial = serial_attach(ms->port, sermouse_callback, ms); - - timer_add(sermouse_timer, &ms->delay, &ms->delay, ms); - - return(ms); -} - - static void sermouse_close(void *priv) { @@ -124,59 +143,14 @@ sermouse_close(void *priv) } -mouse_t mouse_serial_microsoft = { - "Microsoft 2-button mouse (serial)", - "msserial", - MOUSE_TYPE_SERIAL, - sermouse_init, - sermouse_close, - sermouse_poll -}; - -static uint8_t -mssystems_mouse_poll(int x, int y, int z, int b, void *priv) -{ - mouse_serial_t *ms = (mouse_serial_t *)priv; - uint8_t data[5]; - - if (!x && !y && b == ms->oldb) return(1); - - ms->oldb = b; - - y=-y; - - if (x>127) x = 127; - if (y>127) y = 127; - if (x<-128) x = -128; - if (y<-128) y = -128; - - data[0] = 0x80; - data[0] |= (b & 0x01 ? 0x00 : 0x04); /*Left button*/ - data[0] |= (b & 0x02 ? 0x00 : 0x01); /*Middle button*/ - data[0] |= (b & 0x04 ? 0x00 : 0x02); /*Right button*/ - data[1] = x; - data[2] = y; - data[3] = x;/*Same as byte 1*/ - data[4] = y;/*Same as byte 2*/ - - pclog("Mouse_Systems_Serial: data %02X %02X %02X\n", data[0], data[1], data[2]); - - serial_write_fifo(ms->serial, data[0]); - serial_write_fifo(ms->serial, data[1]); - serial_write_fifo(ms->serial, data[2]); - serial_write_fifo(ms->serial, data[3]); - serial_write_fifo(ms->serial, data[4]); - - return(0); -} - static void * -mssystems_mouse_init(void) +sermouse_init(int type) { mouse_serial_t *ms = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); memset(ms, 0x00, sizeof(mouse_serial_t)); ms->port = SERMOUSE_PORT; - + ms->type = type; + /* Attach a serial port to the mouse. */ ms->serial = serial_attach(ms->port, sermouse_callback, ms); @@ -185,11 +159,36 @@ mssystems_mouse_init(void) return(ms); } + +static void * +sermouse_init_microsoft(void) +{ + return(sermouse_init(SERMOUSE_TYPE_MICROSOFT)); +} + + +static void * +sermouse_init_msystems(void) +{ + return(sermouse_init(SERMOUSE_TYPE_MSYSTEMS)); +} + + mouse_t mouse_msystems = { "Mouse Systems Mouse (serial)", "mssystems", MOUSE_TYPE_MSYSTEMS, - mssystems_mouse_init, + sermouse_init_msystems, sermouse_close, - mssystems_mouse_poll -}; \ No newline at end of file + sermouse_poll +}; + + +mouse_t mouse_serial_microsoft = { + "Microsoft 2-button mouse (serial)", + "msserial", + MOUSE_TYPE_SERIAL, + sermouse_init_microsoft, + sermouse_close, + sermouse_poll +}; diff --git a/src/serial.c b/src/serial.c deleted file mode 100644 index ae33dc16d..000000000 --- a/src/serial.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Implementation of NS8250-series UART devices. - * - * The original IBM-PC design did not have any serial ports of - * any kind. Rather, these were offered as add-on devices, most - * likely because a) most people did not need one at the time, - * and, b) this way, IBM could make more money off them. - * - * So, for the PC, the offerings were for an IBM Asynchronous - * Communications Adapter, and, later, a model for synchronous - * communications. - * - * The "Async Adapter" was based on the NS8250 UART chip, and - * is what we now call the "serial" or "com" port of the PC. - * - * Of course, many system builders came up with similar boards, - * and even more boards were designed where several I/O functions - * were combined into a single board: the Multi-I/O adapters. - * Initially, these had all the chips as-is, but later many of - * these functions were integrated into a single MIO chip. - * - * This file implements the standard NS8250 series of chips, with - * support for the later (16450 and 16550) FIFO additions. On the - * lower half of the driver, we interface to the host system's - * serial ports for real-world access. - * - * Based on the 86Box serial port driver as a framework. - * - * Version: @(#)serial.c 1.0.7 2017/06/04 - * - * Author: Fred N. van Kempen, - * Copyright 2017 Fred N. van Kempen. - */ -#include -#include "ibm.h" -#include "io.h" -#include "pic.h" -#include "timer.h" -#include "serial.h" -#include "plat_serial.h" - - -#define NUM_SERIAL 2 /* we support 2 ports */ - - -enum { - SERINT_LSR = 1, - SERINT_RECEIVE = 2, - SERINT_TRANSMIT = 4, - SERINT_MSR = 8 -}; - - -/* IER register bits. */ -#define IER_RDAIE (0x01) -#define IER_THREIE (0x02) -#define IER_RXLSIE (0x04) -#define IER_MSIE (0x08) -#define IER_SLEEP (0x10) /* NS16750 */ -#define IER_LOWPOWER (0x20) /* NS16750 */ -#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ - -/* IIR register bits. */ -#define IIR_IP (0x01) -#define IIR_IID (0x0e) -# define IID_IDMDM (0x00) -# define IID_IDTX (0x02) -# define IID_IDRX (0x04) -# define IID_IDERR (0x06) -# define IID_IDTMO (0x0c) -#define IIR_IIRFE (0xc0) -# define IIR_FIFO64 (0x20) -# define IIR_FIFOBAD (0x80) /* 16550 */ -# define IIR_FIFOENB (0xc0) - -/* FCR register bits. */ -#define FCR_FCRFE (0x01) -#define FCR_RFR (0x02) -#define FCR_TFR (0x04) -#define FCR_SELDMA1 (0x08) -#define FCR_FENB64 (0x20) /* 16750 */ -#define FCR_RTLS (0xc0) -# define FCR_RTLS1 (0x00) -# define FCR_RTLS4 (0x40) -# define FCR_RTLS8 (0x80) -# define FCR_RTLS14 (0xc0) - -/* LCR register bits. */ -#define LCR_WLS (0x03) -# define WLS_BITS5 (0x00) -# define WLS_BITS6 (0x01) -# define WLS_BITS7 (0x02) -# define WLS_BITS8 (0x03) -#define LCR_SBS (0x04) -#define LCR_PE (0x08) -#define LCR_EP (0x10) -#define LCR_PS (0x20) -# define PAR_NONE (0x00) -# define PAR_EVEN (LCR_PE | LCR_EP) -# define PAR_ODD (LCR_PE) -# define PAR_MARK (LCR_PE | LCR_PS) -# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) -#define LCR_BC (0x40) -#define LCR_DLAB (0x80) - -/* MCR register bits. */ -#define MCR_DTR (0x01) -#define MCR_RTS (0x02) -#define MCR_OUT1 (0x04) /* 8250 */ -#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ -#define MCR_LMS (0x10) -#define MCR_AUTOFLOW (0x20) /* 16750 */ - -/* LSR register bits. */ -#define LSR_DR (0x01) -#define LSR_OE (0x02) -#define LSR_PE (0x04) -#define LSR_FE (0x08) -#define LSR_BI (0x10) -#define LSR_THRE (0x20) -#define LSR_TEMT (0x40) -#define LSR_RXFE (0x80) - -/* MSR register bits. */ -#define MSR_DCTS (0x01) -#define MSR_DDSR (0x02) -#define MSR_TERI (0x04) -#define MSR_DDCD (0x08) -#define MSR_CTS (0x10) -#define MSR_DSR (0x20) -#define MSR_RI (0x40) -#define MSR_DCD (0x80) -#define MSR_MASK (0x0f) - - -static SERIAL ports[NUM_SERIAL]; /* serial port data */ - int serial_do_log; - - -#if 0 -static void -serial_log(int lvl, const char *fmt, ...) -{ -#ifdef ENABLE_SERIAL_LOG - va_list ap; - - if (serial_do_log >= lvl) { - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - fflush(stdout); - } -#endif -} -#endif - - -static void -update_ints(SERIAL *sp) -{ - int stat = 0; - - sp->iir = IIR_IP; - if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { - /* Line Status interrupt. */ - stat = 1; - sp->iir = IID_IDERR; - } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { - /* Received Data available. */ - stat = 1; - sp->iir = IID_IDRX; - } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { - /* Transmit Data empty. */ - stat = 1; - sp->iir = IID_IDTX; - } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { - /* Modem Status interrupt. */ - stat = 1; - sp->iir = IID_IDMDM; - } - - /* Raise or clear the level-based IRQ. */ - if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) - picintlevel(1 << sp->irq); - else - picintc(1 << sp->irq); -} - - -/* Fake interrupt generator, needed for Serial Mouse. */ -static void -serial_timer(void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - - sp->receive_delay = 0; - - if (sp->fifo_read != sp->fifo_write) { - sp->lsr |= LSR_DR; - sp->int_status |= SERINT_RECEIVE; - update_ints(sp); - } -} - - -/* Write data to the (input) FIFO. Used by MOUSE driver. */ -void -serial_write_fifo(SERIAL *sp, uint8_t dat) -{ - /* Stuff data into FIFO. */ - sp->fifo[sp->fifo_write] = dat; - sp->fifo_write = (sp->fifo_write + 1) & 0xFF; - - if (! (sp->lsr & LSR_DR)) { - sp->lsr |= LSR_DR; - sp->int_status |= SERINT_RECEIVE; - update_ints(sp); - } -} - - -static uint8_t -read_fifo(SERIAL *sp) -{ - if (sp->fifo_read != sp->fifo_write) { - sp->dat = sp->fifo[sp->fifo_read]; - sp->fifo_read = (sp->fifo_read + 1) & 0xFF; - } - - return(sp->dat); -} - - -/* Handle a WRITE operation to one of our registers. */ -static void -serial_write(uint16_t addr, uint8_t val, void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - uint8_t wl, sb, pa; - uint16_t baud; - long speed; - -#if ENABLE_SERIAL_LOG - serial_log(2, "Serial%d: write(%04x, %02x)\n", sp->port, addr, val); -#endif - switch (addr & 0x07) { - case 0: /* DATA / DLAB1 */ - if (sp->lcr & LCR_DLAB) { - sp->dlab1 = val; - return; - } - sp->thr = val; - if (sp->bh != NULL) { - /* We are linked, so send to BH layer. */ - bhtty_write((BHTTY *)sp->bh, sp->thr); - - /* The WRITE completed, we are ready for more. */ - sp->lsr |= LSR_THRE; - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); - } else { - /* Not linked. Just fake LOOPBACK mode. */ - if (! (sp->mctrl & MCR_LMS)) - serial_write_fifo(sp, val); - } - - if (sp->mctrl & MCR_LMS) { - /* Echo data back to RX. */ - serial_write_fifo(sp, val); - } - break; - - case 1: /* IER / DLAB2 */ - if (sp->lcr & LCR_DLAB) { - sp->dlab2 = val; - return; - } - sp->ier = (val & IER_MASK); - update_ints(sp); - break; - - case 2: /* FCR */ - sp->fcr = val; - break; - - case 3: /* LCR */ - if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { - /* We dropped DLAB, so handle baudrate. */ - baud = ((sp->dlab2<<8) | sp->dlab1); - if (baud > 0) { - speed = 115200UL/baud; -#ifdef ENABLE_SERIAL_LOG - serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", - sp->port, baud, speed); -#endif - if ((sp->bh != NULL) && (speed > 0)) - bhtty_speed((BHTTY *)sp->bh, speed); - } else { -#ifdef ENABLE_SERIAL_LOG - serial_log(1, "Serial%d: divisor %u invalid!\n", - sp->port, baud); -#endif - } - } - wl = (val & LCR_WLS) + 5; /* databits */ - sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ - pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; -#ifdef ENABLE_SERIAL_LOG - serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); -#endif - if (sp->bh != NULL) - bhtty_params((BHTTY *)sp->bh, wl, pa, sb); - sp->lcr = val; - break; - - case 4: - if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { - /* - * This is old code for use by the Serial Mouse - * driver. If the user toggles RTS, serial mice - * are expected to send an ID, to inform any - * enumerator there 'is' something. - */ - if (sp->rts_callback) { - sp->rts_callback(sp->rts_callback_p); -#ifdef ENABLE_SERIAL_LOG - serial_log(1, "RTS raised; sending ID\n"); -#endif - } - } - - if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { - if (sp->bh != NULL) { - /* Linked, start host port. */ - (void)bhtty_active(sp->bh, 1); - } else { - /* Not linked, start RX timer. */ - timer_add(serial_timer, - &sp->receive_delay, - &sp->receive_delay, sp); - - /* Fake CTS, DSR and DCD (for now.) */ - sp->msr = (MSR_CTS | MSR_DCTS | - MSR_DSR | MSR_DDSR | - MSR_DCD | MSR_DDCD); - sp->int_status |= SERINT_MSR; - update_ints(sp); - } - } - sp->mctrl = val; - if (val & MCR_LMS) { /* loopback mode */ - uint8_t new_msr; - - /*FIXME: WTF does this do?? --FvK */ - new_msr = (val & 0x0c) << 4; - new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; - new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; - - if ((sp->msr ^ new_msr) & 0x10) - new_msr |= MCR_DTR; - if ((sp->msr ^ new_msr) & 0x20) - new_msr |= MCR_RTS; - if ((sp->msr ^ new_msr) & 0x80) - new_msr |= 0x08; - if ((sp->msr & 0x40) && !(new_msr & 0x40)) - new_msr |= 0x04; - - sp->msr = new_msr; - } - break; - - case 5: - sp->lsr = val; - if (sp->lsr & LSR_DR) - sp->int_status |= SERINT_RECEIVE; - if (sp->lsr & 0x1e) - sp->int_status |= SERINT_LSR; - if (sp->lsr & LSR_THRE) - sp->int_status |= SERINT_TRANSMIT; - update_ints(sp); - break; - - case 6: - sp->msr = val; - if (sp->msr & MSR_MASK) - sp->int_status |= SERINT_MSR; - update_ints(sp); - break; - - case 7: - sp->scratch = val; - break; - } -} - - -/* BHTTY READ COMPLETE handler. */ -static void -serial_rd_done(void *arg, int num) -{ - SERIAL *sp = (SERIAL *)arg; - - /* We can do at least 'num' bytes.. */ - while (num-- > 0) { - /* Get a byte from them. */ - if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; - - /* Stuff it into the FIFO and set intr. */ - serial_write_fifo(sp, sp->hold); - } -} - - -/* Handle a READ operation from one of our registers. */ -static uint8_t -serial_read(uint16_t addr, void *priv) -{ - SERIAL *sp = (SERIAL *)priv; - uint8_t ret = 0x00; - - switch (addr&0x07) { - case 0: /* DATA / DLAB1 */ - if (sp->lcr & LCR_DLAB) { - ret = sp->dlab1; - } else { - sp->lsr &= ~LSR_DR; - sp->int_status &= ~SERINT_RECEIVE; - update_ints(sp); - ret = read_fifo(sp); - if ((sp->bh == NULL) && - (sp->fifo_read != sp->fifo_write)) - sp->receive_delay = 1000 * TIMER_USEC; - } - break; - - case 1: /* LCR / DLAB2 */ - ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; - break; - - case 2: /* IIR */ - ret = sp->iir; - if ((ret & IIR_IID) == IID_IDTX) { - sp->int_status &= ~SERINT_TRANSMIT; - update_ints(sp); - } - if (sp->fcr & 0x01) - ret |= 0xc0; - break; - - case 3: /* LCR */ - ret = sp->lcr; - break; - - case 4: /* MCR */ - ret = sp->mctrl; - break; - - case 5: /* LSR */ - if (sp->lsr & LSR_THRE) - sp->lsr |= LSR_TEMT; - sp->lsr |= LSR_THRE; - ret = sp->lsr; - if (sp->lsr & 0x1f) - sp->lsr &= ~0x1e; -#if 0 - sp->lsr |= (LSR_THRE | LSR_TEMT); -#endif - sp->int_status &= ~SERINT_LSR; - update_ints(sp); - break; - - case 6: - ret = sp->msr; - sp->msr &= ~0x0f; - sp->int_status &= ~SERINT_MSR; - update_ints(sp); - break; - - case 7: - ret = sp->scratch; - break; - } - - return(ret); -} - - -/* Set up a serial port for use. */ -void -serial_setup(int port, uint16_t addr, int irq) -{ - SERIAL *sp; - -#ifdef ENABLE_SERIAL_LOG - serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); -#endif - - /* Grab the desired port block. */ - sp = &ports[port-1]; - - /* Set up the basic info. */ - if (sp->addr != 0x0000) { - /* Unlink the previous handler. Just in case. */ - io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, sp); - } - sp->addr = addr; - sp->irq = irq; - - /* Request an I/O range. */ - io_sethandler(sp->addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, sp); -} - - -/* Release all resources held by a serial port. */ -void -serial_remove(int port) -{ - SERIAL *sp; - - /* Grab the desired port block. */ - sp = &ports[port-1]; - - // FIXME: stop timer, if enabled! - - /* Close the host device. */ - if (sp->bh != NULL) - (void)serial_link(port, NULL); - - /* Release our I/O range. */ - if (sp->addr != 0x0000) { - io_removehandler(sp->addr, 8, - serial_read, NULL, NULL, serial_write, NULL, NULL, sp); - } - sp->addr = 0x0000; - sp->irq = 0; -} - - -/* Initialize the serial ports. */ -void -serial_init(void) -{ - SERIAL *sp; - int i; - -#if ENABLE_SERIAL_LOG - serial_do_log = ENABLE_SERIAL_LOG; -#endif - - /* FIXME: we should probably initialize the platform module here. */ - - /* Initialize each port. */ - for (i=0; iport = (i+1); - - if (i == 0) - serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); - else - serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); - } - -#ifdef WALTJE - /* Link to host port. */ - serial_link(1, "COM1"); - serial_link(2, "COM2"); -#endif -} - - -/* - * Reset the serial ports. - * - * This should be a per-port function. - */ -void -serial_reset(void) -{ - SERIAL *sp; - int i; - - for (i=0; iiir = sp->ier = sp->lcr = sp->mctrl = 0x00; - sp->fifo_read = sp->fifo_write = 0x00; - } -} - - -/* Link a serial port to a host (serial) port. */ -int -serial_link(int port, char *arg) -{ - SERIAL *sp; - BHTTY *bh; - - /* Grab the desired port block. */ - sp = &ports[port-1]; - - if (arg != NULL) { - /* Make sure we're not already linked. */ - if (sp->bh != NULL) { -#if ENABLE_SERIAL_LOG - serial_log(0, "Serial%d already linked!\n", port); -#endif - return(-1); - } - - /* Request a port from the host system. */ - bh = bhtty_open(arg, 0); - if (bh == NULL) { -#if ENABLE_SERIAL_LOG - serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); -#endif - return(-1); - } - sp->bh = bh; - - /* Set up bottom-half I/O callback info. */ - bh->rd_done = serial_rd_done; - bh->rd_arg = sp; - } else { - /* If we are linked, unlink it. */ - if (sp->bh != NULL) { - bhtty_close((BHTTY *)sp->bh); - sp->bh = NULL; - } - - } - - return(0); -} - - -/* Attach another device (MOUSE) to a serial port. */ -SERIAL * -serial_attach(int port, void *func, void *arg) -{ - SERIAL *sp; - - /* Grab the desired port block. */ - sp = &ports[port-1]; - - /* Set up callback info. */ - sp->rts_callback = func; - sp->rts_callback_p = arg; - - return(sp); -} diff --git a/src/serial.h b/src/serial.h index 4602429f0..fec2d2b5c 100644 --- a/src/serial.h +++ b/src/serial.h @@ -8,7 +8,7 @@ * * Definitions for the SERIAL card. * - * Version: @(#)serial.h 1.0.4 2017/06/03 + * Version: @(#)serial.h 1.0.6 2017/06/17 * * Author: Fred N. van Kempen, * Copyright 2017 Fred N. van Kempen. @@ -18,22 +18,33 @@ /* Default settings for the standard ports. */ -#define SERIAL1_ADDR 0x03f8 -#define SERIAL1_IRQ 4 -#define SERIAL2_ADDR 0x02f8 -#define SERIAL2_IRQ 3 +#define SERIAL1_ADDR 0x03f8 +#define SERIAL1_IRQ 4 +#define SERIAL2_ADDR 0x02f8 +#define SERIAL2_IRQ 3 + + +/* Supported UART types. */ +#define UART_TYPE_8250 0 /* standard NS8250 */ +#define UART_TYPE_8250A 1 /* updated NS8250(A) */ +#define UART_TYPE_16450 2 /* 16450 */ +#define UART_TYPE_16550 3 /* 16550 (broken fifo) */ +#define UART_TYPE_16550A 4 /* 16550a (working fifo) */ +#define UART_TYPE_16670 5 /* 16670 (64b fifo) */ typedef struct _serial_ { int8_t port; /* port number (1,2,..) */ int8_t irq; /* IRQ channel used */ uint16_t addr; /* I/O address used */ + int8_t type; /* UART type */ + uint8_t int_status; uint8_t lsr, thr, mctrl, rcr, /* UART registers */ iir, ier, lcr, msr; uint8_t dlab1, dlab2; - uint8_t dat; - uint8_t int_status; + uint8_t dat, + hold; uint8_t scratch; uint8_t fcr; @@ -41,7 +52,6 @@ typedef struct _serial_ { void (*rts_callback)(void *); void *rts_callback_p; - uint8_t hold; uint8_t fifo[256]; int fifo_read, fifo_write; @@ -58,7 +68,8 @@ extern void serial_setup(int port, uint16_t addr, int irq); extern void serial_remove(int port); extern SERIAL *serial_attach(int, void *, void *); extern int serial_link(int, char *); -extern void serial_write_fifo(SERIAL *, uint8_t); + +extern void serial_write_fifo(SERIAL *, uint8_t, int); #endif /*EMU_SERIAL_H*/ From 9c9f7b1b9adb6188d53a5a4f09e0dcc17d848c93 Mon Sep 17 00:00:00 2001 From: waltje Date: Sat, 17 Jun 2017 03:36:38 -0400 Subject: [PATCH 364/392] And now the missing new/updated serial.c.. --- src/serial.c | 645 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 645 insertions(+) create mode 100644 src/serial.c diff --git a/src/serial.c b/src/serial.c new file mode 100644 index 000000000..ad200a9ba --- /dev/null +++ b/src/serial.c @@ -0,0 +1,645 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Implementation of NS8250-series UART devices. + * + * The original IBM-PC design did not have any serial ports of + * any kind. Rather, these were offered as add-on devices, most + * likely because a) most people did not need one at the time, + * and, b) this way, IBM could make more money off them. + * + * So, for the PC, the offerings were for an IBM Asynchronous + * Communications Adapter, and, later, a model for synchronous + * communications. + * + * The "Async Adapter" was based on the NS8250 UART chip, and + * is what we now call the "serial" or "com" port of the PC. + * + * Of course, many system builders came up with similar boards, + * and even more boards were designed where several I/O functions + * were combined into a single board: the Multi-I/O adapters. + * Initially, these had all the chips as-is, but later many of + * these functions were integrated into a single MIO chip. + * + * This file implements the standard NS8250 series of chips, with + * support for the later (16450 and 16550) FIFO additions. On the + * lower half of the driver, we interface to the host system's + * serial ports for real-world access. + * + * **NOTE** TEMPORARY VERSION, DO NOT UPDATE/CHANGE !! + * + * Based on the 86Box serial port driver as a framework. + * + * Version: @(#)serial.c 1.0.8 2017/06/18 + * + * Author: Fred N. van Kempen, + * Copyright 2017 Fred N. van Kempen. + */ +#include +#include "ibm.h" +#include "io.h" +#include "pic.h" +#include "timer.h" +#include "serial.h" +#include "plat_serial.h" + + +#define NUM_SERIAL 2 /* we support 2 ports */ + + +enum { + SERINT_LSR = 1, + SERINT_RECEIVE = 2, + SERINT_TRANSMIT = 4, + SERINT_MSR = 8 +}; + + +/* IER register bits. */ +#define IER_RDAIE (0x01) +#define IER_THREIE (0x02) +#define IER_RXLSIE (0x04) +#define IER_MSIE (0x08) +#define IER_SLEEP (0x10) /* NS16750 */ +#define IER_LOWPOWER (0x20) /* NS16750 */ +#define IER_MASK (0x0f) /* not including SLEEP|LOWP */ + +/* IIR register bits. */ +#define IIR_IP (0x01) +#define IIR_IID (0x0e) +# define IID_IDMDM (0x00) +# define IID_IDTX (0x02) +# define IID_IDRX (0x04) +# define IID_IDERR (0x06) +# define IID_IDTMO (0x0c) +#define IIR_IIRFE (0xc0) +# define IIR_FIFO64 (0x20) +# define IIR_FIFOBAD (0x80) /* 16550 */ +# define IIR_FIFOENB (0xc0) + +/* FCR register bits. */ +#define FCR_FCRFE (0x01) +#define FCR_RFR (0x02) +#define FCR_TFR (0x04) +#define FCR_SELDMA1 (0x08) +#define FCR_FENB64 (0x20) /* 16750 */ +#define FCR_RTLS (0xc0) +# define FCR_RTLS1 (0x00) +# define FCR_RTLS4 (0x40) +# define FCR_RTLS8 (0x80) +# define FCR_RTLS14 (0xc0) + +/* LCR register bits. */ +#define LCR_WLS (0x03) +# define WLS_BITS5 (0x00) +# define WLS_BITS6 (0x01) +# define WLS_BITS7 (0x02) +# define WLS_BITS8 (0x03) +#define LCR_SBS (0x04) +#define LCR_PE (0x08) +#define LCR_EP (0x10) +#define LCR_PS (0x20) +# define PAR_NONE (0x00) +# define PAR_EVEN (LCR_PE | LCR_EP) +# define PAR_ODD (LCR_PE) +# define PAR_MARK (LCR_PE | LCR_PS) +# define PAR_SPACE (LCR_PE | LCR_PS | LCR_EP) +#define LCR_BC (0x40) +#define LCR_DLAB (0x80) + +/* MCR register bits. */ +#define MCR_DTR (0x01) +#define MCR_RTS (0x02) +#define MCR_OUT1 (0x04) /* 8250 */ +#define MCR_OUT2 (0x08) /* 8250, INTEN on IBM-PC */ +#define MCR_LMS (0x10) +#define MCR_AUTOFLOW (0x20) /* 16750 */ + +/* LSR register bits. */ +#define LSR_DR (0x01) +#define LSR_OE (0x02) +#define LSR_PE (0x04) +#define LSR_FE (0x08) +#define LSR_BI (0x10) +#define LSR_THRE (0x20) +#define LSR_TEMT (0x40) +#define LSR_RXFE (0x80) + +/* MSR register bits. */ +#define MSR_DCTS (0x01) +#define MSR_DDSR (0x02) +#define MSR_TERI (0x04) +#define MSR_DDCD (0x08) +#define MSR_CTS (0x10) +#define MSR_DSR (0x20) +#define MSR_RI (0x40) +#define MSR_DCD (0x80) +#define MSR_MASK (0x0f) + + +static SERIAL ports[NUM_SERIAL]; /* serial port data */ + int serial_do_log; + + +static void +serial_log(int lvl, const char *fmt, ...) +{ +#ifdef ENABLE_SERIAL_LOG + va_list ap; + + if (serial_do_log >= lvl) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); + } +#endif +} + + +static void +update_ints(SERIAL *sp) +{ + int stat = 0; + + sp->iir = IIR_IP; + if ((sp->ier & IER_RXLSIE) && (sp->int_status & SERINT_LSR)) { + /* Line Status interrupt. */ + stat = 1; + sp->iir = IID_IDERR; + } else if ((sp->ier & IER_RDAIE) && (sp->int_status & SERINT_RECEIVE)) { + /* Received Data available. */ + stat = 1; + sp->iir = IID_IDRX; + } else if ((sp->ier & IER_THREIE) && (sp->int_status & SERINT_TRANSMIT)) { + /* Transmit Data empty. */ + stat = 1; + sp->iir = IID_IDTX; + } else if ((sp->ier & IER_MSIE) && (sp->int_status & SERINT_MSR)) { + /* Modem Status interrupt. */ + stat = 1; + sp->iir = IID_IDMDM; + } + + /* Raise or clear the level-based IRQ. */ + if (stat && ((sp->mctrl & MCR_OUT2) || PCJR)) + picintlevel(1 << sp->irq); + else + picintc(1 << sp->irq); +} + + +/* Fake interrupt generator, needed for Serial Mouse. */ +static void +serial_timer(void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + + sp->receive_delay = 0; + + if (sp->fifo_read != sp->fifo_write) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } +} + + +/* Write data to the (input) FIFO. Used by MOUSE driver. */ +void +serial_write_fifo(SERIAL *sp, uint8_t dat, int flag) +{ + /* Stuff data into FIFO. */ + sp->fifo[sp->fifo_write] = dat; + sp->fifo_write = (sp->fifo_write + 1) & 0xFF; + + if (! (sp->lsr & LSR_DR)) { + sp->lsr |= LSR_DR; + sp->int_status |= SERINT_RECEIVE; + update_ints(sp); + } +} + + +static uint8_t +read_fifo(SERIAL *sp) +{ + if (sp->fifo_read != sp->fifo_write) { + sp->dat = sp->fifo[sp->fifo_read]; + sp->fifo_read = (sp->fifo_read + 1) & 0xFF; + } + + return(sp->dat); +} + + +/* Handle a WRITE operation to one of our registers. */ +static void +serial_write(uint16_t addr, uint8_t val, void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + uint8_t wl, sb, pa; + uint16_t baud; + long speed; + +#if ENABLE_SERIAL_LOG + serial_log(2, "Serial%d: write(%04x, %02x)\n", sp->port, addr, val); +#endif + switch (addr & 0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab1 = val; + return; + } + sp->thr = val; + if (sp->bh != NULL) { + /* We are linked, so send to BH layer. */ + bhtty_write((BHTTY *)sp->bh, sp->thr); + + /* The WRITE completed, we are ready for more. */ + sp->lsr |= LSR_THRE; + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + } else { + /* Not linked. Just fake LOOPBACK mode. */ + if (! (sp->mctrl & MCR_LMS)) + serial_write_fifo(sp, val, 1); + } + + if (sp->mctrl & MCR_LMS) { + /* Echo data back to RX. */ + serial_write_fifo(sp, val, 1); + } + break; + + case 1: /* IER / DLAB2 */ + if (sp->lcr & LCR_DLAB) { + sp->dlab2 = val; + return; + } + sp->ier = (val & IER_MASK); + update_ints(sp); + break; + + case 2: /* FCR */ + sp->fcr = val; + break; + + case 3: /* LCR */ + if ((sp->lcr & LCR_DLAB) && !(val & LCR_DLAB)) { + /* We dropped DLAB, so handle baudrate. */ + baud = ((sp->dlab2<<8) | sp->dlab1); + if (baud > 0) { + speed = 115200UL/baud; + serial_log(2, "Serial%d: divisor %u, baudrate %ld\n", + sp->port, baud, speed); + if ((sp->bh != NULL) && (speed > 0)) + bhtty_speed((BHTTY *)sp->bh, speed); + } else { + serial_log(1, "Serial%d: divisor %u invalid!\n", + sp->port, baud); + } + } + wl = (val & LCR_WLS) + 5; /* databits */ + sb = (val & LCR_SBS) ? 2 : 1; /* stopbits */ + pa = (val & (LCR_PE|LCR_EP|LCR_PS)) >> 3; + serial_log(2, "Serial%d: WL=%d SB=%d PA=%d\n", sp->port, wl, sb, pa); + if (sp->bh != NULL) + bhtty_params((BHTTY *)sp->bh, wl, pa, sb); + sp->lcr = val; + break; + + case 4: + if ((val & MCR_RTS) && !(sp->mctrl & MCR_RTS)) { + /* + * This is old code for use by the Serial Mouse + * driver. If the user toggles RTS, serial mice + * are expected to send an ID, to inform any + * enumerator there 'is' something. + */ + if (sp->rts_callback) { + sp->rts_callback(sp->rts_callback_p); + serial_log(1, "RTS raised; sending ID\n"); + } + } + + if ((val & MCR_OUT2) && !(sp->mctrl & MCR_OUT2)) { + if (sp->bh != NULL) { + /* Linked, start host port. */ + (void)bhtty_active(sp->bh, 1); + } else { + /* Not linked, start RX timer. */ + timer_add(serial_timer, + &sp->receive_delay, + &sp->receive_delay, sp); + + /* Fake CTS, DSR and DCD (for now.) */ + sp->msr = (MSR_CTS | MSR_DCTS | + MSR_DSR | MSR_DDSR | + MSR_DCD | MSR_DDCD); + sp->int_status |= SERINT_MSR; + update_ints(sp); + } + } + sp->mctrl = val; + if (val & MCR_LMS) { /* loopback mode */ + uint8_t new_msr; + + /*FIXME: WTF does this do?? --FvK */ + new_msr = (val & 0x0c) << 4; + new_msr |= (val & MCR_RTS) ? MCR_LMS : 0; + new_msr |= (val & MCR_DTR) ? MCR_AUTOFLOW : 0; + + if ((sp->msr ^ new_msr) & 0x10) + new_msr |= MCR_DTR; + if ((sp->msr ^ new_msr) & 0x20) + new_msr |= MCR_RTS; + if ((sp->msr ^ new_msr) & 0x80) + new_msr |= 0x08; + if ((sp->msr & 0x40) && !(new_msr & 0x40)) + new_msr |= 0x04; + + sp->msr = new_msr; + } + break; + + case 5: + sp->lsr = val; + if (sp->lsr & LSR_DR) + sp->int_status |= SERINT_RECEIVE; + if (sp->lsr & 0x1e) + sp->int_status |= SERINT_LSR; + if (sp->lsr & LSR_THRE) + sp->int_status |= SERINT_TRANSMIT; + update_ints(sp); + break; + + case 6: + sp->msr = val; + if (sp->msr & MSR_MASK) + sp->int_status |= SERINT_MSR; + update_ints(sp); + break; + + case 7: + sp->scratch = val; + break; + } +} + + +/* BHTTY READ COMPLETE handler. */ +static void +serial_rd_done(void *arg, int num) +{ + SERIAL *sp = (SERIAL *)arg; + + /* We can do at least 'num' bytes.. */ + while (num-- > 0) { + /* Get a byte from them. */ + if (bhtty_read(sp->bh, &sp->hold, 1) < 0) break; + + /* Stuff it into the FIFO and set intr. */ + serial_write_fifo(sp, sp->hold, 1); + } +} + + +/* Handle a READ operation from one of our registers. */ +static uint8_t +serial_read(uint16_t addr, void *priv) +{ + SERIAL *sp = (SERIAL *)priv; + uint8_t ret = 0x00; + + switch (addr&0x07) { + case 0: /* DATA / DLAB1 */ + if (sp->lcr & LCR_DLAB) { + ret = sp->dlab1; + } else { + sp->lsr &= ~LSR_DR; + sp->int_status &= ~SERINT_RECEIVE; + update_ints(sp); + ret = read_fifo(sp); + if ((sp->bh == NULL) && + (sp->fifo_read != sp->fifo_write)) + sp->receive_delay = 1000 * TIMER_USEC; + } + break; + + case 1: /* LCR / DLAB2 */ + ret = (sp->lcr & LCR_DLAB) ? sp->dlab2 : sp->ier; + break; + + case 2: /* IIR */ + ret = sp->iir; + if ((ret & IIR_IID) == IID_IDTX) { + sp->int_status &= ~SERINT_TRANSMIT; + update_ints(sp); + } + if (sp->fcr & 0x01) + ret |= 0xc0; + break; + + case 3: /* LCR */ + ret = sp->lcr; + break; + + case 4: /* MCR */ + ret = sp->mctrl; + break; + + case 5: /* LSR */ + if (sp->lsr & LSR_THRE) + sp->lsr |= LSR_TEMT; + sp->lsr |= LSR_THRE; + ret = sp->lsr; + if (sp->lsr & 0x1f) + sp->lsr &= ~0x1e; +#if 0 + sp->lsr |= (LSR_THRE | LSR_TEMT); +#endif + sp->int_status &= ~SERINT_LSR; + update_ints(sp); + break; + + case 6: + ret = sp->msr; + sp->msr &= ~0x0f; + sp->int_status &= ~SERINT_MSR; + update_ints(sp); + break; + + case 7: + ret = sp->scratch; + break; + } + + return(ret); +} + + +/* Set up a serial port for use. */ +void +serial_setup(int port, uint16_t addr, int irq) +{ + SERIAL *sp; + + serial_log(0, "Serial%d: I/O=%04x, IRQ=%d\n", port, addr, irq); + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + /* Set up the basic info. */ + if (sp->addr != 0x0000) { + /* Unlink the previous handler. Just in case. */ + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); + } + sp->addr = addr; + sp->irq = irq; + + /* Request an I/O range. */ + io_sethandler(sp->addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); +} + + +/* Release all resources held by a serial port. */ +void +serial_remove(int port) +{ + SERIAL *sp; + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + // FIXME: stop timer, if enabled! + + /* Close the host device. */ + if (sp->bh != NULL) + (void)serial_link(port, NULL); + + /* Release our I/O range. */ + if (sp->addr != 0x0000) { + io_removehandler(sp->addr, 8, + serial_read, NULL, NULL, serial_write, NULL, NULL, sp); + } + sp->addr = 0x0000; + sp->irq = 0; +} + + +/* Initialize the serial ports. */ +void +serial_init(void) +{ + SERIAL *sp; + int i; + +#if ENABLE_SERIAL_LOG + serial_do_log = ENABLE_SERIAL_LOG; +#endif + + /* FIXME: we should probably initialize the platform module here. */ + + /* Initialize each port. */ + for (i=0; iport = (i+1); + + if (i == 0) + serial_setup(sp->port, SERIAL1_ADDR, SERIAL1_IRQ); + else + serial_setup(sp->port, SERIAL2_ADDR, SERIAL2_IRQ); + } + +#ifdef WALTJE + /* Link to host port. */ + serial_link(2, "COM2"); +#endif +} + + +/* + * Reset the serial ports. + * + * This should be a per-port function. + */ +void +serial_reset(void) +{ + SERIAL *sp; + int i; + + for (i=0; iiir = sp->ier = sp->lcr = sp->mctrl = 0x00; + sp->fifo_read = sp->fifo_write = 0x00; + } +} + + +/* Link a serial port to a host (serial) port. */ +int +serial_link(int port, char *arg) +{ + SERIAL *sp; + BHTTY *bh; + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + if (arg != NULL) { + /* Make sure we're not already linked. */ + if (sp->bh != NULL) { + serial_log(0, "Serial%d already linked!\n", port); + return(-1); + } + + /* Request a port from the host system. */ + bh = bhtty_open(arg, 0); + if (bh == NULL) { + serial_log(0, "Serial%d unable to link to '%s' !\n", port, arg); + return(-1); + } + sp->bh = bh; + + /* Set up bottom-half I/O callback info. */ + bh->rd_done = serial_rd_done; + bh->rd_arg = sp; + } else { + /* If we are linked, unlink it. */ + if (sp->bh != NULL) { + bhtty_close((BHTTY *)sp->bh); + sp->bh = NULL; + } + + } + + return(0); +} + + +/* Attach another device (MOUSE) to a serial port. */ +SERIAL * +serial_attach(int port, void *func, void *arg) +{ + SERIAL *sp; + + /* Grab the desired port block. */ + sp = &ports[port-1]; + + /* Set up callback info. */ + sp->rts_callback = func; + sp->rts_callback_p = arg; + + return(sp); +} From bb03e645391434b4d3db1064157fb0089e4fd2ea Mon Sep 17 00:00:00 2001 From: waltje Date: Sun, 18 Jun 2017 22:31:49 -0400 Subject: [PATCH 365/392] Small fixes for openal and some dynamic linking stuff. Bug in libopenal.a makes this not work, so we're still on openall.dll ... --- src/Makefile.mingw | 13 ++- src/SOUND/openal.c | 273 +++++++++++++++++++++++---------------------- 2 files changed, 147 insertions(+), 139 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d92d2d175..f143c592a 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -62,7 +62,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/resid-fp video lzf network network/slirp win +VPATH = . cpu sound sound/resid-fp sound/openal video lzf network network/slirp win PLAT = win/ ifeq ($(X64), y) CPP = g++.exe -m64 @@ -170,12 +170,13 @@ NETOBJ = network.o \ net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ + openal.o \ + dbopl.o nukedopl.o \ convolve.o convolve-sse.o envelope.o extfilt.o \ filter.o pot.o sid.o voice.o wave6581__ST.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ - dbopl.o nukedopl.o openal.o \ snd_speaker.o snd_ps1.o snd_pssj.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ @@ -220,9 +221,11 @@ OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ LZFOBJ = lzf_c.o lzf_d.o -LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ - -mwindows -lcomctl32 -lwinmm -lwsock32 -liphlpapi -lpsapi \ - -static-libstdc++ -static -lstdc++ -static-libgcc -static -lgcc +LIBS = -mwindows \ + -lopenal.dll \ + -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \ + -lcomctl32 -lkernel32 -lwsock32 -lwinmm -liphlpapi -lpsapi \ + -static -lstdc++ -lgcc # Build rules. diff --git a/src/SOUND/openal.c b/src/SOUND/openal.c index b044c0e5a..bda40f44e 100644 --- a/src/SOUND/openal.c +++ b/src/SOUND/openal.c @@ -3,6 +3,10 @@ #include #include #ifdef USE_OPENAL +# undef AL_API +# undef ALC_API +# define AL_LIBTYPE_STATIC +# define ALC_LIBTYPE_STATIC # include # include # include @@ -11,219 +15,220 @@ #include "sound.h" -FILE *allog; +#define FREQ 48000 +#define BUFLEN SOUNDBUFLEN + + #ifdef USE_OPENAL ALuint buffers[4]; /* front and back buffers */ ALuint buffers_cd[4]; /* front and back buffers */ static ALuint source[2]; /* audio source */ #endif -#define FREQ 48000 -#define BUFLEN SOUNDBUFLEN -void closeal(void); -ALvoid alutInit(ALint *argc,ALbyte **argv) +ALvoid alutInit(ALint *argc,ALbyte **argv) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *Context; + ALCdevice *Device; - /* Open device */ - Device=alcOpenDevice((ALCchar *)""); + /* Open device */ + Device = alcOpenDevice((ALCchar *)""); + if (Device != NULL) { /* Create context(s) */ - Context=alcCreateContext(Device,NULL); - /* Set active context */ - alcMakeContextCurrent(Context); - /* Register extensions */ + Context = alcCreateContext(Device, NULL); + if (Context != NULL) { + /* Set active context */ + alcMakeContextCurrent(Context); + } + } } -ALvoid alutExit(ALvoid) + +ALvoid alutExit(ALvoid) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *Context; + ALCdevice *Device; - /* Unregister extensions */ - - /* Get active context */ - Context=alcGetCurrentContext(); + /* Get active context */ + Context = alcGetCurrentContext(); + if (Context != NULL) { /* Get device for active context */ - Device=alcGetContextsDevice(Context); - /* Disable context */ - alcMakeContextCurrent(NULL); + Device = alcGetContextsDevice(Context); + if (Device != NULL) { + /* Disable context */ + alcMakeContextCurrent(NULL); + + /* Close device */ + alcCloseDevice(Device); + } + /* Release context(s) */ alcDestroyContext(Context); - /* Close device */ - alcCloseDevice(Device); -} -void initalmain(int argc, char *argv[]) -{ -#ifdef USE_OPENAL - alutInit(0,0); - atexit(closeal); -#endif + } } + void closeal(void) { #ifdef USE_OPENAL - alutExit(); + alutExit(); #endif } + +void initalmain(int argc, char *argv[]) +{ +#ifdef USE_OPENAL + alutInit(0,0); + atexit(closeal); +#endif +} + + void inital(ALvoid) { #ifdef USE_OPENAL - int c; + float buf[BUFLEN*2]; + float cd_buf[CD_BUFLEN*2]; + int16_t buf_int16[BUFLEN*2]; + int16_t cd_buf_int16[CD_BUFLEN*2]; + int c; - float buf[BUFLEN*2]; - - float cd_buf[CD_BUFLEN*2]; - - int16_t buf_int16[BUFLEN*2]; - - int16_t cd_buf_int16[CD_BUFLEN*2]; - - alGenBuffers(4, buffers); - alGenBuffers(4, buffers_cd); + alGenBuffers(4, buffers); + alGenBuffers(4, buffers_cd); - alGenSources(2, source); + alGenSources(2, source); - alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); - alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); - memset(buf,0,BUFLEN*2*sizeof(float)); - memset(cd_buf,0,BUFLEN*2*sizeof(float)); + alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); - for (c = 0; c < 4; c++) - { - if (sound_is_float) - { - alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - } - else - { - alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - } - } + memset(buf,0,BUFLEN*2*sizeof(float)); + memset(cd_buf,0,BUFLEN*2*sizeof(float)); - alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_cd); - alSourcePlay(source[0]); - alSourcePlay(source[1]); + for (c = 0; c < 4; c++) { + if (sound_is_float) { + alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + } else { + alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + } + } + + alSourceQueueBuffers(source[0], 4, buffers); + alSourceQueueBuffers(source[1], 4, buffers_cd); + alSourcePlay(source[0]); + alSourcePlay(source[1]); #endif } + void givealbuffer(float *buf) { #ifdef USE_OPENAL - int processed; - int state; - ALuint buffer; + int processed; + int state; + ALuint buffer; - alGetSourcei(source[0], AL_SOURCE_STATE, &state); + alGetSourcei(source[0], AL_SOURCE_STATE, &state); - if (state==0x1014) - { - alSourcePlay(source[0]); - } - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) { + alSourcePlay(source[0]); + } + alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) - { - alSourceUnqueueBuffers(source[0], 1, &buffer); + if (processed>=1) { + alSourceUnqueueBuffers(source[0], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alSourceQueueBuffers(source[0], 1, &buffer); - } + alSourceQueueBuffers(source[0], 1, &buffer); + } #endif } + void givealbuffer_int16(int16_t *buf) { #ifdef USE_OPENAL - int processed; - int state; - ALuint buffer; + int processed; + int state; + ALuint buffer; - alGetSourcei(source[0], AL_SOURCE_STATE, &state); + alGetSourcei(source[0], AL_SOURCE_STATE, &state); - if (state==0x1014) - { - alSourcePlay(source[0]); - } - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) { + alSourcePlay(source[0]); + } + alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) - { - alSourceUnqueueBuffers(source[0], 1, &buffer); + if (processed>=1) { + alSourceUnqueueBuffers(source[0], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO16, buf, BUFLEN*2*sizeof(int16_t), FREQ); + alBufferData(buffer, AL_FORMAT_STEREO16, buf, BUFLEN*2*sizeof(int16_t), FREQ); - alSourceQueueBuffers(source[0], 1, &buffer); - } + alSourceQueueBuffers(source[0], 1, &buffer); + } #endif } + void givealbuffer_cd(float *buf) { #ifdef USE_OPENAL - int processed; - int state; + int processed; + int state; - alGetSourcei(source[1], AL_SOURCE_STATE, &state); + alGetSourcei(source[1], AL_SOURCE_STATE, &state); - if (state==0x1014) - { - alSourcePlay(source[1]); - } - alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) { + alSourcePlay(source[1]); + } + alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) - { - ALuint buffer; + if (processed>=1) { + ALuint buffer; - alSourceUnqueueBuffers(source[1], 1, &buffer); + alSourceUnqueueBuffers(source[1], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - alSourceQueueBuffers(source[1], 1, &buffer); - } + alSourceQueueBuffers(source[1], 1, &buffer); + } #endif } + void givealbuffer_cd_int16(int16_t *buf) { #ifdef USE_OPENAL - int processed; - int state; + int processed; + int state; - alGetSourcei(source[1], AL_SOURCE_STATE, &state); + alGetSourcei(source[1], AL_SOURCE_STATE, &state); - if (state==0x1014) - { - alSourcePlay(source[1]); - } - alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) { + alSourcePlay(source[1]); + } + alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) - { - ALuint buffer; + if (processed>=1) { + ALuint buffer; - alSourceUnqueueBuffers(source[1], 1, &buffer); + alSourceUnqueueBuffers(source[1], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - alSourceQueueBuffers(source[1], 1, &buffer); - } + alSourceQueueBuffers(source[1], 1, &buffer); + } #endif } From 1e7668f1dbc6c6e1e344550ae715b43fa2f47037 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Jun 2017 06:46:08 +0200 Subject: [PATCH 366/392] Applied the recent mainline PCem commits (and fixed the Pentium machines); Ported the Roland MT-32 emulation (using MUNT) from bit's MT32 emulation branch of PCem; Sanitized the OpenAL give buffer code in openal.c a bit; NVR path is now specifiable in the Settings dialog; Added Logitech 3-button serial mouse per protocol description by waltje; The RTL8029AS and the BT-958D now actually use the PCI IRQ routing; Fixed BT-958D PCI device initialization on the bus; PCI IRQ routing now respects the edge/level setting set on ports 4D0/4D1. --- src/CPU/codegen_timing_pentium.c | 697 +++-- src/Makefile.mingw | 22 +- src/NETWORK/net_ne2000.c | 2 +- src/SOUND/midi.c | 247 ++ src/SOUND/midi.h | 35 + src/SOUND/midi_mt32.c | 323 +++ src/SOUND/midi_mt32.h | 1 + src/SOUND/midi_system.c | 62 + src/SOUND/midi_system.h | 1 + src/SOUND/munt/Analog.cpp | 424 +++ src/SOUND/munt/Analog.h | 53 + src/SOUND/munt/BReverbModel.cpp | 662 +++++ src/SOUND/munt/BReverbModel.h | 48 + src/SOUND/munt/Enumerations.h | 188 ++ src/SOUND/munt/File.cpp | 77 + src/SOUND/munt/File.h | 73 + src/SOUND/munt/FileStream.cpp | 83 + src/SOUND/munt/FileStream.h | 46 + src/SOUND/munt/LA32FloatWaveGenerator.cpp | 360 +++ src/SOUND/munt/LA32FloatWaveGenerator.h | 132 + src/SOUND/munt/LA32Ramp.cpp | 155 ++ src/SOUND/munt/LA32Ramp.h | 46 + src/SOUND/munt/LA32WaveGenerator.cpp | 422 +++ src/SOUND/munt/LA32WaveGenerator.h | 266 ++ src/SOUND/munt/MemoryRegion.h | 132 + src/SOUND/munt/MidiEventQueue.h | 71 + src/SOUND/munt/MidiStreamParser.cpp | 289 +++ src/SOUND/munt/MidiStreamParser.h | 124 + src/SOUND/munt/Part.cpp | 695 +++++ src/SOUND/munt/Part.h | 153 ++ src/SOUND/munt/Partial.cpp | 403 +++ src/SOUND/munt/Partial.h | 129 + src/SOUND/munt/PartialManager.cpp | 298 +++ src/SOUND/munt/PartialManager.h | 64 + src/SOUND/munt/Poly.cpp | 190 ++ src/SOUND/munt/Poly.h | 70 + src/SOUND/munt/ROMInfo.cpp | 117 + src/SOUND/munt/ROMInfo.h | 80 + src/SOUND/munt/SampleRateConverter.cpp | 110 + src/SOUND/munt/SampleRateConverter.h | 71 + src/SOUND/munt/Structures.h | 259 ++ src/SOUND/munt/Synth.cpp | 2286 +++++++++++++++++ src/SOUND/munt/Synth.h | 484 ++++ src/SOUND/munt/TVA.cpp | 370 +++ src/SOUND/munt/TVA.h | 100 + src/SOUND/munt/TVF.cpp | 233 ++ src/SOUND/munt/TVF.h | 61 + src/SOUND/munt/TVP.cpp | 330 +++ src/SOUND/munt/TVP.h | 74 + src/SOUND/munt/Tables.cpp | 97 + src/SOUND/munt/Tables.h | 62 + src/SOUND/munt/Types.h | 32 + src/SOUND/munt/c_interface/c_interface.cpp | 635 +++++ src/SOUND/munt/c_interface/c_interface.h | 418 +++ src/SOUND/munt/c_interface/c_types.h | 322 +++ src/SOUND/munt/c_interface/cpp_interface.h | 468 ++++ src/SOUND/munt/config.h | 38 + src/SOUND/munt/globals.h | 119 + src/SOUND/munt/internals.h | 118 + src/SOUND/munt/mmath.h | 68 + src/SOUND/munt/mt32emu.h | 84 + src/SOUND/munt/sha1/sha1.cpp | 185 ++ src/SOUND/munt/sha1/sha1.h | 49 + .../munt/srchelper/InternalResampler.cpp | 74 + src/SOUND/munt/srchelper/InternalResampler.h | 42 + .../munt/srchelper/SamplerateAdapter.cpp | 99 + src/SOUND/munt/srchelper/SamplerateAdapter.h | 48 + src/SOUND/munt/srchelper/SoxrAdapter.cpp | 106 + src/SOUND/munt/srchelper/SoxrAdapter.h | 45 + .../srchelper/srctools/include/FIRResampler.h | 67 + .../srctools/include/FloatSampleProvider.h | 34 + .../srctools/include/IIR2xResampler.h | 100 + .../srctools/include/LinearResampler.h | 42 + .../srctools/include/ResamplerModel.h | 63 + .../srctools/include/ResamplerStage.h | 38 + .../srctools/include/SincResampler.h | 46 + .../srchelper/srctools/src/FIRResampler.cpp | 107 + .../srchelper/srctools/src/IIR2xResampler.cpp | 229 ++ .../srctools/src/LinearResampler.cpp | 47 + .../srchelper/srctools/src/ResamplerModel.cpp | 153 ++ .../srchelper/srctools/src/SincResampler.cpp | 136 + src/SOUND/openal.c | 176 +- src/SOUND/snd_mpu401.c | 4 +- src/SOUND/snd_sb_dsp.c | 2 +- src/SOUND/sound.c | 13 +- src/SOUND/sound.h | 6 +- src/WIN/86Box.rc | 106 +- src/WIN/plat_midi.h | 17 +- src/WIN/plat_ticks.h | 2 + src/WIN/resource.h | 16 +- src/WIN/win.c | 16 +- src/WIN/win_deviceconfig.c | 74 +- src/WIN/win_language.c | 11 +- src/WIN/win_language.h | 2 + src/WIN/win_midi.c | 194 +- src/WIN/win_settings.c | 165 +- src/config.c | 39 +- src/config.h | 1 + src/device.h | 15 +- src/ibm.h | 2 + src/ide.c | 58 +- src/ide.h | 3 + src/mem.c | 119 +- src/model.c | 34 +- src/mouse.c | 1 + src/mouse_serial.c | 39 + src/mouse_serial.h | 1 + src/pc.c | 63 +- src/pci.c | 10 +- src/rom.c | 16 + src/rom.h | 1 + src/scsi_buslogic.c | 26 +- 112 files changed, 16289 insertions(+), 732 deletions(-) create mode 100644 src/SOUND/midi.c create mode 100644 src/SOUND/midi.h create mode 100644 src/SOUND/midi_mt32.c create mode 100644 src/SOUND/midi_mt32.h create mode 100644 src/SOUND/midi_system.c create mode 100644 src/SOUND/midi_system.h create mode 100644 src/SOUND/munt/Analog.cpp create mode 100644 src/SOUND/munt/Analog.h create mode 100644 src/SOUND/munt/BReverbModel.cpp create mode 100644 src/SOUND/munt/BReverbModel.h create mode 100644 src/SOUND/munt/Enumerations.h create mode 100644 src/SOUND/munt/File.cpp create mode 100644 src/SOUND/munt/File.h create mode 100644 src/SOUND/munt/FileStream.cpp create mode 100644 src/SOUND/munt/FileStream.h create mode 100644 src/SOUND/munt/LA32FloatWaveGenerator.cpp create mode 100644 src/SOUND/munt/LA32FloatWaveGenerator.h create mode 100644 src/SOUND/munt/LA32Ramp.cpp create mode 100644 src/SOUND/munt/LA32Ramp.h create mode 100644 src/SOUND/munt/LA32WaveGenerator.cpp create mode 100644 src/SOUND/munt/LA32WaveGenerator.h create mode 100644 src/SOUND/munt/MemoryRegion.h create mode 100644 src/SOUND/munt/MidiEventQueue.h create mode 100644 src/SOUND/munt/MidiStreamParser.cpp create mode 100644 src/SOUND/munt/MidiStreamParser.h create mode 100644 src/SOUND/munt/Part.cpp create mode 100644 src/SOUND/munt/Part.h create mode 100644 src/SOUND/munt/Partial.cpp create mode 100644 src/SOUND/munt/Partial.h create mode 100644 src/SOUND/munt/PartialManager.cpp create mode 100644 src/SOUND/munt/PartialManager.h create mode 100644 src/SOUND/munt/Poly.cpp create mode 100644 src/SOUND/munt/Poly.h create mode 100644 src/SOUND/munt/ROMInfo.cpp create mode 100644 src/SOUND/munt/ROMInfo.h create mode 100644 src/SOUND/munt/SampleRateConverter.cpp create mode 100644 src/SOUND/munt/SampleRateConverter.h create mode 100644 src/SOUND/munt/Structures.h create mode 100644 src/SOUND/munt/Synth.cpp create mode 100644 src/SOUND/munt/Synth.h create mode 100644 src/SOUND/munt/TVA.cpp create mode 100644 src/SOUND/munt/TVA.h create mode 100644 src/SOUND/munt/TVF.cpp create mode 100644 src/SOUND/munt/TVF.h create mode 100644 src/SOUND/munt/TVP.cpp create mode 100644 src/SOUND/munt/TVP.h create mode 100644 src/SOUND/munt/Tables.cpp create mode 100644 src/SOUND/munt/Tables.h create mode 100644 src/SOUND/munt/Types.h create mode 100644 src/SOUND/munt/c_interface/c_interface.cpp create mode 100644 src/SOUND/munt/c_interface/c_interface.h create mode 100644 src/SOUND/munt/c_interface/c_types.h create mode 100644 src/SOUND/munt/c_interface/cpp_interface.h create mode 100644 src/SOUND/munt/config.h create mode 100644 src/SOUND/munt/globals.h create mode 100644 src/SOUND/munt/internals.h create mode 100644 src/SOUND/munt/mmath.h create mode 100644 src/SOUND/munt/mt32emu.h create mode 100644 src/SOUND/munt/sha1/sha1.cpp create mode 100644 src/SOUND/munt/sha1/sha1.h create mode 100644 src/SOUND/munt/srchelper/InternalResampler.cpp create mode 100644 src/SOUND/munt/srchelper/InternalResampler.h create mode 100644 src/SOUND/munt/srchelper/SamplerateAdapter.cpp create mode 100644 src/SOUND/munt/srchelper/SamplerateAdapter.h create mode 100644 src/SOUND/munt/srchelper/SoxrAdapter.cpp create mode 100644 src/SOUND/munt/srchelper/SoxrAdapter.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/FIRResampler.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/FloatSampleProvider.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/IIR2xResampler.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/LinearResampler.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/ResamplerModel.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/ResamplerStage.h create mode 100644 src/SOUND/munt/srchelper/srctools/include/SincResampler.h create mode 100644 src/SOUND/munt/srchelper/srctools/src/FIRResampler.cpp create mode 100644 src/SOUND/munt/srchelper/srctools/src/IIR2xResampler.cpp create mode 100644 src/SOUND/munt/srchelper/srctools/src/LinearResampler.cpp create mode 100644 src/SOUND/munt/srchelper/srctools/src/ResamplerModel.cpp create mode 100644 src/SOUND/munt/srchelper/srctools/src/SincResampler.cpp create mode 100644 src/WIN/plat_ticks.h diff --git a/src/CPU/codegen_timing_pentium.c b/src/CPU/codegen_timing_pentium.c index e5e4ed13d..ecea3125d 100644 --- a/src/CPU/codegen_timing_pentium.c +++ b/src/CPU/codegen_timing_pentium.c @@ -2,10 +2,10 @@ - U/V integer pairing - FPU/FXCH pairing - Prefix decode delay (including shadowing) + - FPU latencies Elements not taken into account : - Branch prediction (beyond most simplistic approximation) - PMMX decode queue - - FPU latencies - MMX latencies */ @@ -17,6 +17,8 @@ #include "../mem.h" #include "codegen.h" + + /*Instruction has different execution time for 16 and 32 bit data. Does not pair */ #define CYCLES_HAS_MULTI (1 << 28) @@ -37,69 +39,126 @@ static int pair_timings[4][4] = /*Instruction follows either register timing, read-modify, or read-modify-write. May be pairable*/ -#define CYCLES_REG (0 << 0) -#define CYCLES_RM (1 << 0) -#define CYCLES_RMW (2 << 0) -#define CYCLES_BRANCH (3 << 0) +#define CYCLES_REG (0ull << 0) +#define CYCLES_RM (1ull << 0) +#define CYCLES_RMW (2ull << 0) +#define CYCLES_BRANCH (3ull << 0) -#define CYCLES_MASK ((1 << 7) - 1) +/*Instruction has immediate data. Can only be used with PAIR_U/PAIR_V/PAIR_UV*/ +#define CYCLES_HASIMM (3ull << 2) +#define CYCLES_IMM8 (1ull << 2) +#define CYCLES_IMM1632 (2ull << 2) + +#define CYCLES_MASK ((1ull << 7) - 1) /*Instruction is MMX shift or pack/unpack instruction*/ -#define MMX_SHIFTPACK (1 << 7) +#define MMX_SHIFTPACK (1ull << 7) /*Instruction is MMX multiply instruction*/ -#define MMX_MULTIPLY (1 << 8) +#define MMX_MULTIPLY (1ull << 8) /*Instruction does not pair*/ -#define PAIR_NP (0 << 29) +#define PAIR_NP (0ull << 29) /*Instruction pairs in U pipe only*/ -#define PAIR_U (1 << 29) +#define PAIR_U (1ull << 29) /*Instruction pairs in V pipe only*/ -#define PAIR_V (2 << 29) +#define PAIR_V (2ull << 29) /*Instruction pairs in both U and V pipes*/ -#define PAIR_UV (3 << 29) +#define PAIR_UV (3ull << 29) /*Instruction pairs in U pipe only and only with FXCH*/ -#define PAIR_FX (5 << 29) +#define PAIR_FX (5ull << 29) /*Instruction is FXCH and only pairs in V pipe with FX pairable instruction*/ -#define PAIR_FXCH (6 << 29) +#define PAIR_FXCH (6ull << 29) -#define PAIR_MASK (7 << 29) +#define PAIR_FPU (4ull << 29) + +#define PAIR_MASK (7ull << 29) /*Instruction has input dependency on register in REG field*/ -#define SRCDEP_REG (1 << 9) +#define SRCDEP_REG (1ull << 9) /*Instruction has input dependency on register in R/M field*/ -#define SRCDEP_RM (1 << 10) +#define SRCDEP_RM (1ull << 10) /*Instruction modifies register in REG field*/ -#define DSTDEP_REG (1 << 11) +#define DSTDEP_REG (1ull << 11) /*Instruction modifies register in R/M field*/ -#define DSTDEP_RM (1 << 12) +#define DSTDEP_RM (1ull << 12) /*Instruction has input dependency on given register*/ -#define SRCDEP_EAX (1 << 13) -#define SRCDEP_ECX (1 << 14) -#define SRCDEP_EDX (1 << 15) -#define SRCDEP_EBX (1 << 16) -#define SRCDEP_ESP (1 << 17) -#define SRCDEP_EBP (1 << 18) -#define SRCDEP_ESI (1 << 19) -#define SRCDEP_EDI (1 << 20) +#define SRCDEP_EAX (1ull << 13) +#define SRCDEP_ECX (1ull << 14) +#define SRCDEP_EDX (1ull << 15) +#define SRCDEP_EBX (1ull << 16) +#define SRCDEP_ESP (1ull << 17) +#define SRCDEP_EBP (1ull << 18) +#define SRCDEP_ESI (1ull << 19) +#define SRCDEP_EDI (1ull << 20) /*Instruction modifies given register*/ -#define DSTDEP_EAX (1 << 21) -#define DSTDEP_ECX (1 << 22) -#define DSTDEP_EDX (1 << 23) -#define DSTDEP_EBX (1 << 24) -#define DSTDEP_ESP (1 << 25) -#define DSTDEP_EBP (1 << 26) -#define DSTDEP_ESI (1 << 27) -#define DSTDEP_EDI (1 << 28) +#define DSTDEP_EAX (1ull << 21) +#define DSTDEP_ECX (1ull << 22) +#define DSTDEP_EDX (1ull << 23) +#define DSTDEP_EBX (1ull << 24) +#define DSTDEP_ESP (1ull << 25) +#define DSTDEP_EBP (1ull << 26) +#define DSTDEP_ESI (1ull << 27) +#define DSTDEP_EDI (1ull << 28) + +/*Instruction pops the FPU stack*/ +#define FPU_POP (1ull << 32) +/*Instruction pops the FPU stack twice*/ +#define FPU_POP2 (1ull << 33) +/*Instruction pushes onto the FPU stack*/ +#define FPU_PUSH (1ull << 34) + +/*Instruction writes to ST(0)*/ +#define FPU_WRITE_ST0 (1ull << 35) +/*Instruction reads from ST(0)*/ +#define FPU_READ_ST0 (1ull << 36) +/*Instruction reads from and writes to ST(0)*/ +#define FPU_RW_ST0 (3ull << 35) + +/*Instruction reads from ST(1)*/ +#define FPU_READ_ST1 (1ull << 37) +/*Instruction writes to ST(1)*/ +#define FPU_WRITE_ST1 (1ull << 38) +/*Instruction reads from and writes to ST(1)*/ +#define FPU_RW_ST1 (3ull << 37) + +/*Instruction reads from ST(reg)*/ +#define FPU_READ_STREG (1ull << 39) +/*Instruction writes to ST(reg)*/ +#define FPU_WRITE_STREG (1ull << 40) +/*Instruction reads from and writes to ST(reg)*/ +#define FPU_RW_STREG (3ull << 39) + +/*comp_time = cycles until instruction complete + i_overlap = cycles that overlap with integer + f_overlap = cycles that overlap with subsequent FPU*/ +#define FPU_CYCLES(comp_time, i_overlap, f_overlap) ((uint64_t)comp_time) | ((uint64_t)i_overlap << 41) | ((uint64_t)f_overlap << 49) | PAIR_FPU + +#define FPU_COMP_TIME(timing) (timing & 0xff) +#define FPU_I_OVERLAP(timing) ((timing >> 41) & 0xff) +#define FPU_F_OVERLAP(timing) ((timing >> 49) & 0xff) + +#define FPU_I_LATENCY(timing) (FPU_COMP_TIME(timing) - FPU_I_OVERLAP(timing)) + +#define FPU_F_LATENCY(timing) (FPU_I_OVERLAP(timing) - FPU_F_OVERLAP(timing)) + +#define FPU_RESULT_LATENCY(timing) ((timing >> 41) & 0xff) + +#define FPU_FXCH (1ull << 56) #define INVALID 0 static int u_pipe_full; static uint32_t u_pipe_opcode; -static uint32_t *u_pipe_timings; +static uint64_t *u_pipe_timings; static uint32_t u_pipe_op_32; static uint32_t u_pipe_regmask; +static uint32_t u_pipe_fetchdat; +static int u_pipe_decode_delay_offset; + +static int fpu_latency; +static int fpu_st_latency[8]; #define REGMASK_SHIFTPACK (1 << 8) #define REGMASK_MULTIPLY (1 << 8) @@ -155,7 +214,7 @@ static uint32_t get_dstdep_mask(uint32_t data, uint32_t fetchdat, int bit8) return mask; } -static uint32_t opcode_timings[256] = +static uint64_t opcode_timings[256] = { /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG | DSTDEP_REG, @@ -291,43 +350,43 @@ static uint32_t opcode_timings[256] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_RMW, INVALID }; -static uint32_t opcode_timings_mod3[256] = +static uint64_t opcode_timings_mod3[256] = { /* ADD ADD ADD ADD*/ /*00*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* ADD ADD PUSH ES POP ES*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), /* OR OR OR OR*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* OR OR PUSH CS */ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID, + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), INVALID, /* ADC ADC ADC ADC*/ /*10*/ PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* ADC ADC PUSH SS POP SS*/ - PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), + PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), /* SBB SBB SBB SBB*/ PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_U | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* SBB SBB PUSH DS POP DS*/ - PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), + PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_U | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(3), /* AND AND AND AND*/ /*20*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* AND AND DAA*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* SUB SUB SUB SUB*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* SUB SUB DAS*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* XOR XOR XOR XOR*/ /*30*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM | DSTDEP_REG, /* XOR XOR AAA*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* CMP CMP CMP CMP*/ PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_REG | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | SRCDEP_REG, /* CMP CMP AAS*/ - PAIR_UV | CYCLES_REG | SRCDEP_EAX | SRCDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3), + PAIR_UV | CYCLES_REG | SRCDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_EAX, INVALID, PAIR_NP | CYCLES(3), /* INC EAX INC ECX INC EDX INC EBX*/ /*40*/ PAIR_UV | CYCLES_REG | SRCDEP_EAX | DSTDEP_EAX, PAIR_UV | CYCLES_REG | SRCDEP_ECX | DSTDEP_ECX, PAIR_UV | CYCLES_REG | SRCDEP_EDX | DSTDEP_EDX, PAIR_UV | CYCLES_REG | SRCDEP_EBX | DSTDEP_EBX, @@ -428,7 +487,7 @@ static uint32_t opcode_timings_mod3[256] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), PAIR_UV | CYCLES_REG, INVALID }; -static uint32_t opcode_timings_0f[256] = +static uint64_t opcode_timings_0f[256] = { /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, @@ -510,7 +569,7 @@ static uint32_t opcode_timings_0f[256] = PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, PAIR_U | CYCLES_RM, INVALID, }; -static uint32_t opcode_timings_0f_mod3[256] = +static uint64_t opcode_timings_0f_mod3[256] = { /*00*/ PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(10), INVALID, PAIR_NP | CYCLES(195), PAIR_NP | CYCLES(7), INVALID, @@ -593,53 +652,53 @@ static uint32_t opcode_timings_0f_mod3[256] = PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, PAIR_UV | CYCLES_REG, INVALID, }; -static uint32_t opcode_timings_shift[8] = +static uint64_t opcode_timings_shift[8] = { PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, PAIR_U | CYCLES_RMW, }; -static uint32_t opcode_timings_shift_mod3[8] = +static uint64_t opcode_timings_shift_mod3[8] = { PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, PAIR_U | CYCLES_REG | DSTDEP_RM, }; -static uint32_t opcode_timings_f6[8] = +static uint64_t opcode_timings_f6[8] = { /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) }; -static uint32_t opcode_timings_f6_mod3[8] = +static uint64_t opcode_timings_f6_mod3[8] = { /* TST NOT NEG*/ PAIR_UV | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(11), PAIR_NP | CYCLES(17), PAIR_NP | CYCLES(22) }; -static uint32_t opcode_timings_f7[8] = +static uint64_t opcode_timings_f7[8] = { /* TST NOT NEG*/ PAIR_UV | CYCLES_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) }; -static uint32_t opcode_timings_f7_mod3[8] = +static uint64_t opcode_timings_f7_mod3[8] = { /* TST NOT NEG*/ PAIR_UV | CYCLES_REG | SRCDEP_RM, INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), /* MUL IMUL DIV IDIV*/ PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(11,10), PAIR_NP | CYCLES_MULTI(25,41), PAIR_NP | CYCLES_MULTI(30,46) }; -static uint32_t opcode_timings_ff[8] = +static uint64_t opcode_timings_ff[8] = { /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_RMW, PAIR_UV | CYCLES_RMW, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), /* JMP JMP far PUSH*/ PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID }; -static uint32_t opcode_timings_ff_mod3[8] = +static uint64_t opcode_timings_ff_mod3[8] = { /* INC DEC CALL CALL far*/ PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_UV | CYCLES_REG | SRCDEP_RM | DSTDEP_RM, PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(0), @@ -647,82 +706,83 @@ static uint32_t opcode_timings_ff_mod3[8] = PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(0), PAIR_NP | CYCLES(2), INVALID }; -static uint32_t opcode_timings_d8[8] = +static uint64_t opcode_timings_d8[8] = { -/* FADDs FMULs FCOMs FCOMPs*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), -/* FSUBs FSUBRs FDIVs FDIVRs*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(39), PAIR_FX | CYCLES(39) +/* FADDs FMULs FCOMs FCOMPs*/ + PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_CYCLES(1,0,0), PAIR_FX | FPU_POP | FPU_READ_ST0 | FPU_CYCLES(1,0,0), +/* FSUBs FSUBRs FDIVs FDIVRs*/ + PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(39,38,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(39,38,2) }; -static uint32_t opcode_timings_d8_mod3[8] = +static uint64_t opcode_timings_d8_mod3[8] = { -/* FADD FMUL FCOM FCOMP*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), -/* FSUB FSUBR FDIV FDIVR*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(39), PAIR_FX | CYCLES(39) +/* FADD FMUL FCOM FCOMP*/ + PAIR_FX | FPU_RW_ST0 | FPU_READ_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_READ_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_POP | FPU_READ_ST0 | FPU_READ_STREG | FPU_CYCLES(1,0,0), +/* FSUB FSUBR FDIV FDIVR*/ + PAIR_FX | FPU_RW_ST0 | FPU_READ_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_READ_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_READ_STREG | FPU_CYCLES(39,38,2), PAIR_FX | FPU_RW_ST0 | FPU_READ_STREG | FPU_CYCLES(39,38,2) }; -static uint32_t opcode_timings_d9[8] = +static uint64_t opcode_timings_d9[8] = { -/* FLDs FSTs FSTPs*/ - PAIR_FX | CYCLES(1), INVALID, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* FLDENV FLDCW FSTENV FSTCW*/ - PAIR_NP | CYCLES(32), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(48), PAIR_NP | CYCLES(2) +/* FLDs FSTs FSTPs*/ + PAIR_FX | FPU_PUSH | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_READ_ST0 | FPU_CYCLES(2,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(2,0,0), +/* FLDENV FLDCW FSTENV FSTCW*/ + PAIR_NP | FPU_CYCLES(32,0,0), PAIR_NP | FPU_CYCLES(8,0,0), PAIR_NP | FPU_CYCLES(48,0,0), PAIR_NP | FPU_CYCLES(2,0,0) }; -static uint32_t opcode_timings_d9_mod3[64] = +static uint64_t opcode_timings_d9_mod3[64] = { /*FLD*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), + PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), + PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_FX | FPU_PUSH | FPU_READ_STREG | FPU_CYCLES(1,0,0), /*FXCH*/ - PAIR_V | CYCLES(0), PAIR_V | CYCLES(0), PAIR_V | CYCLES(0), PAIR_V | CYCLES(0), - PAIR_V | CYCLES(0), PAIR_V | CYCLES(0), PAIR_V | CYCLES(0), PAIR_V | CYCLES(0), + PAIR_FXCH | FPU_FXCH | CYCLES(0), PAIR_FXCH | FPU_FXCH | CYCLES(0), PAIR_FXCH | FPU_FXCH | CYCLES(0), PAIR_FXCH | FPU_FXCH | CYCLES(0), + PAIR_FXCH | FPU_FXCH | CYCLES(0), PAIR_FXCH | FPU_FXCH | CYCLES(0), PAIR_FXCH | FPU_FXCH | CYCLES(0), PAIR_FXCH | FPU_FXCH | CYCLES(0), /*FNOP*/ - PAIR_NP | CYCLES(3), INVALID, INVALID, INVALID, - INVALID, INVALID, INVALID, INVALID, + PAIR_NP | FPU_CYCLES(3,0,0), INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, /*FSTP*/ - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), -/* opFCHS opFABS*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(3), INVALID, INVALID, -/* opFTST opFXAM*/ - PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(21), INVALID, INVALID, -/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ - PAIR_NP | CYCLES(2), CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), -/* opFLDEG2 opFLDLN2 opFLDZ*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(2), INVALID, -/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ - PAIR_NP | CYCLES(13), PAIR_NP | CYCLES(22), PAIR_NP | CYCLES(100), PAIR_NP | CYCLES(100), -/* opFDECSTP opFINCSTP,*/ - INVALID, INVALID, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(1), -/* opFPREM opFSQRT opFSINCOS*/ - PAIR_NP | CYCLES(70), INVALID, PAIR_NP | CYCLES(70), PAIR_NP | CYCLES(50), -/* opFRNDINT opFSCALE opFSIN opFCOS*/ - PAIR_NP | CYCLES(9), PAIR_NP | CYCLES(20), PAIR_NP | CYCLES(50), PAIR_NP | CYCLES(50) + PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), + PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), +/* opFCHS opFABS*/ + PAIR_FX | FPU_CYCLES(1,0,0), PAIR_FX | FPU_CYCLES(1,0,0), INVALID, INVALID, +/* opFTST opFXAM*/ + PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(21,4,0), INVALID, INVALID, +/* opFLD1 opFLDL2T opFLDL2E opFLDPI*/ + PAIR_NP | FPU_PUSH | FPU_CYCLES(2,0,0), PAIR_NP | FPU_PUSH | FPU_CYCLES(5,2,2), PAIR_NP | FPU_PUSH | FPU_CYCLES(5,2,2), PAIR_NP | FPU_PUSH | FPU_CYCLES(5,2,2), +/* opFLDEG2 opFLDLN2 opFLDZ*/ + PAIR_NP | FPU_PUSH | FPU_CYCLES(5,2,2), PAIR_NP | FPU_PUSH | FPU_CYCLES(5,2,2), PAIR_NP | FPU_PUSH | FPU_CYCLES(2,0,0), INVALID, +/* opF2XM1 opFYL2X opFPTAN opFPATAN*/ + PAIR_NP | FPU_CYCLES(53,2,2), PAIR_NP | FPU_CYCLES(103,2,2), PAIR_NP | FPU_CYCLES(120,36,0), PAIR_NP | FPU_CYCLES(112,2,2), +/* opFDECSTP opFINCSTP,*/ + INVALID, INVALID, PAIR_NP | FPU_CYCLES(2,0,0), PAIR_NP | FPU_CYCLES(2,0,0), +/* opFPREM opFSQRT opFSINCOS*/ + PAIR_NP | FPU_CYCLES(64,2,2), INVALID, PAIR_NP | FPU_CYCLES(70,69,2), PAIR_NP | FPU_CYCLES(89,2,2), +/* opFRNDINT opFSCALE opFSIN opFCOS*/ + PAIR_NP | FPU_CYCLES(9,0,0), PAIR_NP | FPU_CYCLES(20,5,0), PAIR_NP | FPU_CYCLES(65,2,2), PAIR_NP | FPU_CYCLES(65,2,2) }; -static uint32_t opcode_timings_da[8] = +static uint64_t opcode_timings_da[8] = { -/* FIADDl FIMULl FICOMl FICOMPl*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), -/* FISUBl FISUBRl FIDIVl FIDIVRl*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(42), PAIR_NP | CYCLES(42) +/* FIADDl FIMULl FICOMl FICOMPl*/ + PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_READ_ST0 | FPU_CYCLES(4,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(4,0,0), +/* FISUBl FISUBRl FIDIVl FIDIVRl*/ + PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(42,38,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(42,38,2) }; -static uint32_t opcode_timings_da_mod3[8] = +static uint64_t opcode_timings_da_mod3[8] = { - INVALID, INVALID, INVALID, INVALID, - INVALID, PAIR_NP | CYCLES(5), INVALID, INVALID + INVALID, INVALID, INVALID, INVALID, +/* FCOMPP*/ + INVALID, PAIR_NP | FPU_POP2 | FPU_CYCLES(1,0,0), INVALID, INVALID }; -static uint32_t opcode_timings_db[8] = +static uint64_t opcode_timings_db[8] = { -/* FLDil FSTil FSTPil*/ - PAIR_NP | CYCLES(1), INVALID, PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), -/* FLDe FSTPe*/ - INVALID, PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(3) +/* FLDil FSTil FSTPil*/ + PAIR_NP | FPU_PUSH | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_READ_ST0 | FPU_CYCLES(6,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(6,0,0), +/* FLDe FSTPe*/ + INVALID, PAIR_NP | FPU_PUSH | FPU_CYCLES(3,0,0), INVALID, PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(3,0,0) }; -static uint32_t opcode_timings_db_mod3[64] = +static uint64_t opcode_timings_db_mod3[64] = { INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -736,10 +796,10 @@ static uint32_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, -/* opFNOP opFCLEX opFINIT*/ - INVALID, PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(7), PAIR_NP | CYCLES(17), -/* opFNOP opFNOP*/ - PAIR_NP | CYCLES(3), PAIR_NP | CYCLES(3), INVALID, INVALID, +/* opFNOP opFCLEX opFINIT*/ + INVALID, PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(7,0,0), PAIR_NP | FPU_CYCLES(17,0,0), +/* opFNOP opFNOP*/ + PAIR_NP | FPU_CYCLES(1,0,0), PAIR_NP | FPU_CYCLES(1,0,0), INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, INVALID, @@ -751,76 +811,84 @@ static uint32_t opcode_timings_db_mod3[64] = INVALID, INVALID, INVALID, INVALID, }; -static uint32_t opcode_timings_dc[8] = +static uint64_t opcode_timings_dc[8] = { -/* FADDd FMULd FCOMd FCOMPd*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), -/* FSUBd FSUBRd FDIVd FDIVRd*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(39), PAIR_FX | CYCLES(39) +/* FADDd FMULd FCOMd FCOMPd*/ + PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_CYCLES(1,0,0), PAIR_FX | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(1,0,0), +/* FSUBd FSUBRd FDIVd FDIVRd*/ + PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(3,2,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(39,38,2), PAIR_FX | FPU_RW_ST0 | FPU_CYCLES(39,38,2) }; -static uint32_t opcode_timings_dc_mod3[8] = +static uint64_t opcode_timings_dc_mod3[8] = { -/* opFADDr opFMULr*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), INVALID, INVALID, -/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(39), PAIR_FX | CYCLES(39) +/* opFADDr opFMULr*/ + PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_CYCLES(3,2,2), INVALID, INVALID, +/* opFSUBRr opFSUBr opFDIVRr opFDIVr*/ + PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_CYCLES(39,38,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_CYCLES(39,38,2) }; -static uint32_t opcode_timings_dd[8] = +static uint64_t opcode_timings_dd[8] = { -/* FLDd FSTd FSTPd*/ - PAIR_FX | CYCLES(1), INVALID, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* FRSTOR FSAVE FSTSW*/ - PAIR_NP | CYCLES(70), INVALID, PAIR_NP | CYCLES(127), PAIR_NP | CYCLES(2) +/* FLDd FSTd FSTPd*/ + PAIR_FX | FPU_PUSH | FPU_CYCLES(1,0,0), INVALID, PAIR_NP | FPU_READ_ST0 | FPU_CYCLES(2,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(2,0,0), +/* FRSTOR FSAVE FSTSW*/ + PAIR_NP | FPU_CYCLES(70,0,0), INVALID, PAIR_NP | FPU_CYCLES(127,0,0), PAIR_NP | FPU_CYCLES(6,0,0) }; -static uint32_t opcode_timings_dd_mod3[8] = +static uint64_t opcode_timings_dd_mod3[8] = { -/* FFFREE FST FSTP*/ - PAIR_NP | CYCLES(3), INVALID, PAIR_NP | CYCLES(2), PAIR_NP | CYCLES(2), -/* FUCOM FUCOMP*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), INVALID, INVALID +/* FFFREE FST FSTP*/ + PAIR_NP | FPU_CYCLES(2,0,0), INVALID, PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_WRITE_STREG | FPU_POP | FPU_CYCLES(1,0,0), +/* FUCOM FUCOMP*/ + PAIR_NP | FPU_READ_ST0 | FPU_READ_STREG | FPU_CYCLES(1,0,0), PAIR_NP | FPU_READ_ST0 | FPU_READ_STREG | FPU_POP | FPU_CYCLES(1,0,0), INVALID, INVALID }; -static uint32_t opcode_timings_de[8] = +static uint64_t opcode_timings_de[8] = { -/* FIADDw FIMULw FICOMw FICOMPw*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), -/* FISUBw FISUBRw FIDIVw FIDIVRw*/ - PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(4), PAIR_NP | CYCLES(42), PAIR_NP | CYCLES(42) +/* FIADDw FIMULw FICOMw FICOMPw*/ + PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_READ_ST0 | FPU_CYCLES(4,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(4,0,0), +/* FISUBw FISUBRw FIDIVw FIDIVRw*/ + PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(6,2,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(42,38,2), PAIR_NP | FPU_RW_ST0 | FPU_CYCLES(42,38,2) }; -static uint32_t opcode_timings_de_mod3[8] = +static uint64_t opcode_timings_de_mod3[8] = { -/* FADD FMUL FCOMPP*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), INVALID, PAIR_FX | CYCLES(1), -/* FSUB FSUBR FDIV FDIVR*/ - PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(1), PAIR_FX | CYCLES(39), PAIR_FX | CYCLES(39) +/* FADDP FMULP FCOMPP*/ + PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_POP | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_POP | FPU_CYCLES(3,2,2), INVALID, PAIR_FX | FPU_READ_ST0 | FPU_READ_ST1 | FPU_POP2 | FPU_CYCLES(1,0,0), +/* FSUBP FSUBRP FDIVP FDIVRP*/ + PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_POP | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_POP | FPU_CYCLES(3,2,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_POP | FPU_CYCLES(39,38,2), PAIR_FX | FPU_READ_ST0 | FPU_RW_STREG | FPU_POP | FPU_CYCLES(39,38,2) }; -static uint32_t opcode_timings_df[8] = +static uint64_t opcode_timings_df[8] = { -/* FILDiw FISTiw FISTPiw*/ - PAIR_NP | CYCLES(1), INVALID, PAIR_NP | CYCLES(6), PAIR_NP | CYCLES(6), -/* FILDiq FBSTP FISTPiq*/ - INVALID, PAIR_NP | CYCLES(1), PAIR_NP | CYCLES(148), PAIR_NP | CYCLES(6) +/* FILDiw FISTiw FISTPiw*/ + PAIR_NP | FPU_PUSH | FPU_CYCLES(3,2,2), INVALID, PAIR_NP | FPU_READ_ST0 | FPU_CYCLES(6,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(6,0,0), +/* FILDiq FBSTP FISTPiq*/ + INVALID, PAIR_NP | FPU_PUSH | FPU_CYCLES(3,2,2), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(148,0,0), PAIR_NP | FPU_READ_ST0 | FPU_POP | FPU_CYCLES(6,0,0) }; -static uint32_t opcode_timings_df_mod3[8] = +static uint64_t opcode_timings_df_mod3[8] = { - INVALID, INVALID, INVALID, INVALID, + INVALID, INVALID, INVALID, INVALID, /* FSTSW AX*/ - PAIR_NP | CYCLES(2), INVALID, INVALID, INVALID + PAIR_NP | FPU_CYCLES(6,0,0), INVALID, INVALID, INVALID }; -static uint32_t opcode_timings_8x[8] = +static uint64_t opcode_timings_81[8] = { - PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, - PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RMW | SRCDEP_REG, PAIR_UV | CYCLES_RM | SRCDEP_REG + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM1632, PAIR_UV | CYCLES_RM | SRCDEP_REG | CYCLES_IMM1632 +}; +static uint64_t opcode_timings_8x[8] = +{ + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, + PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RMW | SRCDEP_REG | CYCLES_IMM8, PAIR_UV | CYCLES_RM | SRCDEP_REG | CYCLES_IMM8 }; -static int decode_delay; +static int decode_delay, decode_delay_offset; static uint8_t last_prefix; +static int prefixes; -static inline int COUNT(uint32_t c, int op_32) +static inline int COUNT(uint64_t c, int op_32) { + if ((c & PAIR_FPU) && !(c & FPU_FXCH)) + return FPU_I_LATENCY(c); if (c & CYCLES_HAS_MULTI) { if (op_32 & 0x100) @@ -831,6 +899,10 @@ static inline int COUNT(uint32_t c, int op_32) return c & 0xffff; if ((c & PAIR_MASK) == PAIR_FX) return c & 0xffff; + if ((c & PAIR_MASK) == PAIR_FXCH) + return c & 0xffff; + if ((c & PAIR_UV) && !(c & PAIR_FPU)) + c &= 3; switch (c & CYCLES_MASK) { case CYCLES_REG: @@ -843,23 +915,136 @@ static inline int COUNT(uint32_t c, int op_32) return cpu_hasMMX ? 1 : 2; } - fatal("Illegal COUNT %08x\n", c); + fatal("Illegal COUNT %016llx\n", c); return c; } +static int codegen_fpu_latencies(uint64_t timings, int reg) +{ + int latency = fpu_latency; + + if ((timings & FPU_RW_ST0) && fpu_st_latency[0] && fpu_st_latency[0] > latency) + latency = fpu_st_latency[0]; + if ((timings & FPU_RW_ST1) && fpu_st_latency[1] && fpu_st_latency[1] > latency) + latency = fpu_st_latency[1]; + if ((timings & FPU_RW_STREG) && fpu_st_latency[reg] && fpu_st_latency[reg] > latency) + latency = fpu_st_latency[reg]; + + return latency; +} + +#define SUB_AND_CLAMP(latency, count) \ + latency -= count; \ + if (latency < 0) \ + latency = 0 + +static void codegen_fpu_latency_clock(int count) +{ + SUB_AND_CLAMP(fpu_latency, count); + SUB_AND_CLAMP(fpu_st_latency[0], count); + SUB_AND_CLAMP(fpu_st_latency[1], count); + SUB_AND_CLAMP(fpu_st_latency[2], count); + SUB_AND_CLAMP(fpu_st_latency[3], count); + SUB_AND_CLAMP(fpu_st_latency[4], count); + SUB_AND_CLAMP(fpu_st_latency[5], count); + SUB_AND_CLAMP(fpu_st_latency[6], count); + SUB_AND_CLAMP(fpu_st_latency[7], count); +} + +static inline int codegen_timing_has_displacement(uint32_t fetchdat, int op_32) +{ + if (op_32 & 0x200) + { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) + { + /*Has SIB*/ + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0x700) == 0x500) + return 1; + } + else + { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x05) + return 1; + } + } + else + { + if ((fetchdat & 0xc0) == 0x40 || (fetchdat & 0xc0) == 0x80 || (fetchdat & 0xc7) == 0x06) + return 1; + } + return 0; +} + +/*The instruction is only of interest here if it's longer than 7 bytes, as that's the + limit on Pentium MMX parallel decoding*/ +static inline int codegen_timing_instr_length(uint64_t timing, uint32_t fetchdat, int op_32) +{ + int len = prefixes; + if ((timing & CYCLES_MASK) == CYCLES_RM || (timing & CYCLES_MASK) == CYCLES_RMW) + { + len += 2; /*Opcode + ModR/M*/ + if ((timing & CYCLES_HASIMM) == CYCLES_IMM8) + len++; + if ((timing & CYCLES_HASIMM) == CYCLES_IMM1632) + len += (op_32 & 0x100) ? 4 : 2; + + if (op_32 & 0x200) + { + if ((fetchdat & 7) == 4 && (fetchdat & 0xc0) != 0xc0) + { + /* Has SIB*/ + len++; + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0x700) == 0x500) + len += 4; + } + else + { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 4; + else if ((fetchdat & 0xc7) == 0x05) + len += 4; + } + } + else + { + if ((fetchdat & 0xc0) == 0x40) + len++; + else if ((fetchdat & 0xc0) == 0x80) + len += 2; + else if ((fetchdat & 0xc7) == 0x06) + len += 2; + } + } + + return len; +} + void codegen_timing_pentium_block_start() { - u_pipe_full = decode_delay = 0; + u_pipe_full = decode_delay = decode_delay_offset = 0; } void codegen_timing_pentium_start() { last_prefix = 0; + prefixes = 0; } void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) { + prefixes++; + if ((prefix & 0xf8) == 0xd8) + { + last_prefix = prefix; + return; + } if (cpu_hasMMX && prefix == 0x0f) { /*On Pentium MMX 0fh prefix is 'free'*/ @@ -869,7 +1054,7 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) if (cpu_hasMMX && (prefix == 0x66 || prefix == 0x67)) { /*On Pentium MMX 66h and 67h prefixes take 2 clocks*/ - decode_delay += 2; + decode_delay_offset += 2; last_prefix = prefix; return; } @@ -881,13 +1066,86 @@ void codegen_timing_pentium_prefix(uint8_t prefix, uint32_t fetchdat) } /*On Pentium all prefixes take 1 cycle to decode. Decode may be shadowed by execution of previous instructions*/ - decode_delay++; + decode_delay_offset++; last_prefix = prefix; } +static void codegen_instruction(uint64_t *timings, uint8_t opcode, uint32_t fetchdat, int decode_delay_offset, int op_32) +{ + int instr_cycles, latency = 0; + + if ((timings[opcode] & PAIR_FPU) && !(timings[opcode] & FPU_FXCH)) + instr_cycles = latency = codegen_fpu_latencies(timings[opcode], fetchdat & 7); + else + { + instr_cycles = 0; + } + + if ((decode_delay + decode_delay_offset) > 0) + codegen_fpu_latency_clock(decode_delay + decode_delay_offset + instr_cycles); + else + codegen_fpu_latency_clock(instr_cycles); + instr_cycles += COUNT(timings[opcode], op_32); + if ((decode_delay + decode_delay_offset) > 0) + codegen_block_cycles += instr_cycles + decode_delay + decode_delay_offset; + else + codegen_block_cycles += instr_cycles; + decode_delay = (-instr_cycles) + 1; + + if (timings[opcode] & FPU_POP) + { + int c; + + for (c = 0; c < 7; c++) + fpu_st_latency[c] = fpu_st_latency[c+1]; + fpu_st_latency[7] = 0; + } + if (timings[opcode] & FPU_POP2) + { + int c; + + for (c = 0; c < 6; c++) + fpu_st_latency[c] = fpu_st_latency[c+2]; + fpu_st_latency[6] = fpu_st_latency[7] = 0; + } + if ((timings[opcode] & PAIR_FPU) && !(timings[opcode] & FPU_FXCH)) + { + fpu_latency = FPU_F_LATENCY(timings[opcode]); + } + + if (timings[opcode] & FPU_PUSH) + { + int c; + + for (c = 0; c < 7; c++) + fpu_st_latency[c+1] = fpu_st_latency[c]; + fpu_st_latency[0] = 0; + } + if (timings[opcode] & FPU_WRITE_ST0) + { + fpu_st_latency[0] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (timings[opcode] & FPU_WRITE_ST1) + { + fpu_st_latency[1] = FPU_RESULT_LATENCY(timings[opcode]); + } + if (timings[opcode] & FPU_WRITE_STREG) + { + int reg = fetchdat & 7; + if (timings[opcode] & FPU_POP) + reg--; + if (reg >= 0 && + !(reg == 0 && (timings[opcode] & FPU_WRITE_ST0)) && + !(reg == 1 && (timings[opcode] & FPU_WRITE_ST1))) + { + fpu_st_latency[reg] = FPU_RESULT_LATENCY(timings[opcode]); + } + } +} + void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) { - uint32_t *timings; + uint64_t *timings; int mod3 = ((fetchdat & 0xc0) == 0xc0); int bit8 = !(opcode & 1); @@ -933,11 +1191,16 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) default: switch (opcode) { - case 0x80: case 0x81: case 0x82: case 0x83: + case 0x80: case 0x82: case 0x83: timings = mod3 ? opcode_timings_mod3 : opcode_timings_8x; if (!mod3) opcode = (fetchdat >> 3) & 7; break; + case 0x81: + timings = mod3 ? opcode_timings_mod3 : opcode_timings_81; + if (!mod3) + opcode = (fetchdat >> 3) & 7; + break; case 0xc0: case 0xc1: case 0xd0: case 0xd1: case 0xd2: case 0xd3: timings = mod3 ? opcode_timings_shift_mod3 : opcode_timings_shift; @@ -963,9 +1226,6 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) } } - if (decode_delay < 0) - decode_delay = 0; - if (u_pipe_full) { uint8_t regmask = get_srcdep_mask(timings[opcode], fetchdat, bit8); @@ -977,49 +1237,92 @@ void codegen_timing_pentium_opcode(uint8_t opcode, uint32_t fetchdat, int op_32) if ((timings[opcode] & PAIR_MASK) == PAIR_FXCH && (u_pipe_timings[u_pipe_opcode] & PAIR_MASK) != PAIR_FX) goto nopair; - - if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && !decode_delay) - { - int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; - int t2 = timings[opcode] & CYCLES_MASK; - int t_pair; - - if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) - fatal("Pair out of range\n"); - - t_pair = pair_timings[t1][t2]; - if (t_pair < 1) - fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); - codegen_block_cycles += t_pair; - decode_delay = (-t_pair) + 1; - - /*Instruction can pair with previous*/ + if ((u_pipe_timings[u_pipe_opcode] & PAIR_MASK) == PAIR_FX && + (timings[opcode] & PAIR_MASK) == PAIR_FXCH) + { + int temp; + + codegen_instruction(u_pipe_timings, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32); + + temp = fpu_st_latency[fetchdat & 7]; + fpu_st_latency[fetchdat & 7] = fpu_st_latency[0]; + fpu_st_latency[0] = temp; + u_pipe_full = 0; + decode_delay_offset = 0; return; } + + if ((timings[opcode] & PAIR_V) && !(u_pipe_regmask & regmask) && (decode_delay+decode_delay_offset+u_pipe_decode_delay_offset) <= 0) + { + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if (!has_displacement && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) + { + int t1 = u_pipe_timings[u_pipe_opcode] & CYCLES_MASK; + int t2 = timings[opcode] & CYCLES_MASK; + int t_pair; + uint64_t temp_timing; + + if (!(u_pipe_timings[u_pipe_opcode] & PAIR_FPU)) + t1 &= 3; + if (!(timings[opcode] & PAIR_FPU)) + t2 &= 3; + + if (t1 < 0 || t2 < 0 || t1 > CYCLES_BRANCH || t2 > CYCLES_BRANCH) + fatal("Pair out of range\n"); + + t_pair = pair_timings[t1][t2]; + if (t_pair < 1) + fatal("Illegal pair timings : t1=%i t2=%i u_opcode=%02x v_opcode=%02x\n", t1, t2, u_pipe_opcode, opcode); + + /*Instruction can pair with previous*/ + temp_timing = t_pair; + codegen_instruction(&temp_timing, 0, 0, 0, 0); + u_pipe_full = 0; + decode_delay_offset = 0; + return; + } + } nopair: /*Instruction can not pair with previous*/ /*Run previous now*/ - codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32) + decode_delay; - decode_delay = (-COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32)) + 1; + codegen_instruction(u_pipe_timings, u_pipe_opcode, u_pipe_fetchdat, u_pipe_decode_delay_offset, u_pipe_op_32); u_pipe_full = 0; } - if ((timings[opcode] & PAIR_U) && !decode_delay) + if ((timings[opcode] & PAIR_U) && (decode_delay + decode_delay_offset) <= 0) { - /*Instruction might pair with next*/ - u_pipe_full = 1; - u_pipe_opcode = opcode; - u_pipe_timings = timings; - u_pipe_op_32 = op_32; - u_pipe_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8); - return; + int has_displacement; + + if (timings[opcode] & CYCLES_HASIMM) + has_displacement = codegen_timing_has_displacement(fetchdat, op_32); + else + has_displacement = 0; + + if ((!has_displacement || cpu_hasMMX) && (!cpu_hasMMX || codegen_timing_instr_length(timings[opcode], fetchdat, op_32) <= 7)) + { + /*Instruction might pair with next*/ + u_pipe_full = 1; + u_pipe_opcode = opcode; + u_pipe_timings = timings; + u_pipe_op_32 = op_32; + u_pipe_regmask = get_dstdep_mask(timings[opcode], fetchdat, bit8); + u_pipe_fetchdat = fetchdat; + u_pipe_decode_delay_offset = decode_delay_offset; + decode_delay_offset = 0; + return; + } } /*Instruction can not pair and must run now*/ - - codegen_block_cycles += COUNT(timings[opcode], op_32) + decode_delay; - decode_delay = (-COUNT(timings[opcode], op_32)) + 1; + codegen_instruction(timings, opcode, fetchdat, decode_delay_offset, op_32); + decode_delay_offset = 0; } void codegen_timing_pentium_block_end() @@ -1027,7 +1330,7 @@ void codegen_timing_pentium_block_end() if (u_pipe_full) { /*Run previous now*/ - codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32) + decode_delay; + codegen_block_cycles += COUNT(u_pipe_timings[u_pipe_opcode], u_pipe_op_32) + decode_delay + decode_delay_offset; u_pipe_full = 0; } } diff --git a/src/Makefile.mingw b/src/Makefile.mingw index d92d2d175..858bbd8e8 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -62,7 +62,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/resid-fp video lzf network network/slirp win +VPATH = . cpu sound sound/munt sound/munt/c_interface sound/munt/sha1 sound/munt/srchelper sound/resid-fp video lzf network network/slirp win PLAT = win/ ifeq ($(X64), y) CPP = g++.exe -m64 @@ -76,9 +76,17 @@ WINDRES = windres.exe OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) ifeq ($(X64), y) - DFLAGS = + ifeq ($(OPTIM), y) + DFLAGS = -march=native + else + DFLAGS = + endif else - DFLAGS = -march=i686 + ifeq ($(OPTIM), y) + DFLAGS = -march=native + else + DFLAGS = -march=i686 + endif endif ifeq ($(DEBUG), y) DFLAGS += -ggdb -DDEBUG @@ -175,7 +183,13 @@ SNDOBJ = sound.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ + Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ + LA32FloatWaveGenerator.o LA32WaveGenerator.o \ + MidiStreamParser.o Part.o Partial.o PartialManager.o \ + Poly.o ROMInfo.o Synth.o Tables.o TVA.o TVF.o TVP.o \ + sha1.o c_interface.o \ dbopl.o nukedopl.o openal.o \ + midi.o midi_mt32.o midi_system.o \ snd_speaker.o snd_ps1.o snd_pssj.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ @@ -222,7 +236,7 @@ LZFOBJ = lzf_c.o lzf_d.o LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ -mwindows -lcomctl32 -lwinmm -lwsock32 -liphlpapi -lpsapi \ - -static-libstdc++ -static -lstdc++ -static-libgcc -static -lgcc + -static -static-libgcc -static-libstdc++ -lstdc++ -lgcc # Build rules. diff --git a/src/NETWORK/net_ne2000.c b/src/NETWORK/net_ne2000.c index 43eec0796..026e72619 100644 --- a/src/NETWORK/net_ne2000.c +++ b/src/NETWORK/net_ne2000.c @@ -243,7 +243,7 @@ nelog(int lvl, const char *fmt, ...) static void nic_interrupt(nic_t *dev, int set) { - if ((PCI && dev->is_pci) && (dev->base_irq == 0xff)) { + if (PCI && dev->is_pci) { if (set) pci_set_irq(dev->card, PCI_INTA); else diff --git a/src/SOUND/midi.c b/src/SOUND/midi.c new file mode 100644 index 000000000..d8b1a8d8f --- /dev/null +++ b/src/SOUND/midi.c @@ -0,0 +1,247 @@ +#include +#include +#include +#include +#include "../device.h" +#include "midi.h" +#include "../ibm.h" + +#include "../WIN/plat_midi.h" +#include "../WIN/plat_ticks.h" +#include "midi_system.h" +#include "midi_mt32.h" + +int midi_device_current = 0; +static int midi_device_last = 0; + +typedef struct +{ + const char *name; + const char *internal_name; + device_t *device; +} MIDI_DEVICE; + +static MIDI_DEVICE devices[] = +{ + {"None", "none", NULL}, + {SYSTEM_MIDI_NAME, SYSTEM_MIDI_INTERNAL_NAME, &system_midi_device}, + {"Roland MT-32 Emulation", "mt32", &mt32_device}, + {"", "", NULL} +}; + +static midi_device_t* m_device = NULL; + +int midi_device_available(int card) +{ + if (devices[card].device) + return device_available(devices[card].device); + + return 1; +} + +char *midi_device_getname(int card) +{ + return (char *) devices[card].name; +} + +device_t *midi_device_getdevice(int card) +{ + return devices[card].device; +} + +int midi_device_has_config(int card) +{ + if (!devices[card].device) + return 0; + return devices[card].device->config ? 1 : 0; +} + +char *midi_device_get_internal_name(int card) +{ + return (char *) devices[card].internal_name; +} + +int midi_device_get_from_internal_name(char *s) +{ + int c = 0; + + while (strlen(devices[c].internal_name)) + { + if (!strcmp(devices[c].internal_name, s)) + return c; + c++; + } + + return 0; +} + +void midi_device_init() +{ + if (devices[midi_device_current].device) + device_add(devices[midi_device_current].device); + midi_device_last = midi_device_current; +} + +static uint8_t midi_rt_buf[1024]; +static uint8_t midi_cmd_buf[1024]; +static int midi_cmd_pos = 0; +static int midi_cmd_len = 0; +static uint8_t midi_status = 0; +static unsigned int midi_sysex_start = 0; +static unsigned int midi_sysex_delay = 0; + +uint8_t MIDI_evt_len[256] = { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 + + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 + 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 + + 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 + + 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 +}; + +static unsigned int midi_pos; +static uint8_t midi_sysex_data[1024+2]; + +void midi_init(midi_device_t* device) +{ + memset(midi_rt_buf, 0, sizeof(midi_rt_buf)); + memset(midi_cmd_buf, 0, sizeof(midi_cmd_buf)); + + midi_cmd_pos = midi_cmd_len = 0; + midi_status = 0; + + midi_sysex_start = midi_sysex_delay = 0; + + m_device = device; + +} + +void midi_close() +{ + m_device = NULL; +} + +void midi_poll() +{ + if (m_device && m_device->poll) m_device->poll(); +} + +void play_msg(uint8_t *msg) +{ + if (m_device->play_msg) m_device->play_msg(msg); +} + + +void play_sysex(uint8_t *sysex, unsigned int len) +{ + if (m_device->play_sysex) m_device->play_sysex(sysex, len); +} + +#define SYSEX_SIZE 1024 +#define RAWBUF 1024 + +void midi_write(uint8_t val) +{ + if (!m_device) return; + + if (m_device->write && m_device->write(val)) return; + + uint32_t passed_ticks; + + if (midi_sysex_start) + { + passed_ticks = get_ticks() - midi_sysex_start; + if (passed_ticks < midi_sysex_delay) + { + delay_ms(midi_sysex_delay - passed_ticks); + } + } + + /* Test for a realtime MIDI message */ + if (val >= 0xf8) + { + midi_rt_buf[0] = val; + play_msg(midi_rt_buf); + return; + } + + /* Test for a active sysex transfer */ + + if (midi_status == 0xf0) + { + if (!(val & 0x80)) + { + if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; + return; + } + else + { + midi_sysex_data[midi_pos++] = 0xf7; + + if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) + { + /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ + } + else + { + play_sysex(midi_sysex_data, midi_pos); + if (midi_sysex_start) + { + if (midi_sysex_data[5] == 0x7f) + { + midi_sysex_delay = 290; /* All parameters reset */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) + { + midi_sysex_delay = 145; /* Viking Child */ + } + else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) + { + midi_sysex_delay = 30; /* Dark Sun 1 */ + } + else + midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; + + midi_sysex_start = get_ticks(); + } + } + } + } + + + if (val & 0x80) + { + midi_status = val; + midi_cmd_pos = 0; + midi_cmd_len = MIDI_evt_len[val]; + if (midi_status == 0xf0) + { + midi_sysex_data[0] = 0xf0; + midi_pos = 1; + } + } + + if (midi_cmd_len) + { + midi_cmd_buf[midi_cmd_pos++] = val; + if (midi_cmd_pos >= midi_cmd_len) + { + play_msg(midi_cmd_buf); + midi_cmd_pos = 1; + } + } +} diff --git a/src/SOUND/midi.h b/src/SOUND/midi.h new file mode 100644 index 000000000..371c79eb4 --- /dev/null +++ b/src/SOUND/midi.h @@ -0,0 +1,35 @@ +extern int midi_device_current; + +int midi_device_available(int card); +char *midi_device_getname(int card); +struct device_t *midi_device_getdevice(int card); +int midi_device_has_config(int card); +char *midi_device_get_internal_name(int card); +int midi_device_get_from_internal_name(char *s); +void midi_device_init(); + +typedef struct midi_device_t +{ + void (*play_sysex)(uint8_t *sysex, unsigned int len); + void (*play_msg)(uint8_t *msg); + void (*poll)(); + int (*write)(uint8_t val); +} midi_device_t; + +void midi_init(midi_device_t* device); +void midi_close(); +void midi_write(uint8_t val); +void midi_poll(); + +#if 0 +#ifdef _WIN32 +#define SYSTEM_MIDI_NAME "Windows MIDI" +#define SYSTEM_MIDI_INTERNAL_NAME "windows_midi" +#else +#define SYSTEM_MIDI_NAME "System MIDI" +#define SYSTEM_MIDI_INTERNAL_NAME "system_midi" +#endif +#else +#define SYSTEM_MIDI_NAME "System MIDI" +#define SYSTEM_MIDI_INTERNAL_NAME "system_midi" +#endif \ No newline at end of file diff --git a/src/SOUND/midi_mt32.c b/src/SOUND/midi_mt32.c new file mode 100644 index 000000000..6233f9ae4 --- /dev/null +++ b/src/SOUND/midi_mt32.c @@ -0,0 +1,323 @@ +#include +#include +#include +#include "munt/c_interface/c_interface.h" +#include "../WIN/plat_thread.h" +#include "../ibm.h" +#include "../device.h" +#include "../mem.h" +#include "../rom.h" +#include "midi_mt32.h" +#include "midi.h" +#include "sound.h" + +extern void givealbuffer_midi(void *buf, uint32_t size); +extern void pclog(const char *format, ...); +extern void al_set_midi(int freq, int buf_size); + +static const mt32emu_report_handler_i_v0 handler_v0 = { + /** Returns the actual interface version ID */ + NULL, //mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); + + /** Callback for debug messages, in vprintf() format */ + NULL, //void (*printDebug)(void *instance_data, const char *fmt, va_list list); + /** Callbacks for reporting errors */ + NULL, //void (*onErrorControlROM)(void *instance_data); + NULL, //void (*onErrorPCMROM)(void *instance_data); + /** Callback for reporting about displaying a new custom message on LCD */ + NULL, //void (*showLCDMessage)(void *instance_data, const char *message); + /** Callback for reporting actual processing of a MIDI message */ + NULL, //void (*onMIDIMessagePlayed)(void *instance_data); + /** + * Callback for reporting an overflow of the input MIDI queue. + * Returns MT32EMU_BOOL_TRUE if a recovery action was taken + * and yet another attempt to enqueue the MIDI event is desired. + */ + NULL, //mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); + /** + * Callback invoked when a System Realtime MIDI message is detected in functions + * mt32emu_parse_stream and mt32emu_play_short_message and the likes. + */ + NULL, //void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); + /** Callbacks for reporting system events */ + NULL, //void (*onDeviceReset)(void *instance_data); + NULL, //void (*onDeviceReconfig)(void *instance_data); + /** Callbacks for reporting changes of reverb settings */ + NULL, //void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); + NULL, //void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); + NULL, //void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); + /** Callbacks for reporting various information */ + NULL, //void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); + NULL, //void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); +}; + +static const mt32emu_report_handler_i handler = { &handler_v0 }; + +static mt32emu_context context = NULL; +static int roms_present = -1; + +mt32emu_return_code mt32_check(const char* func, mt32emu_return_code ret, mt32emu_return_code expected) +{ + if (ret != expected) + { + pclog("%s() failed, expected %d but returned %d\n", func, expected, ret); + return 0; + } + return 1; +} + +int mt32_available() +{ + if (roms_present < 0) + roms_present = (rom_present(L"roms/mt32/mt32_control.rom") && rom_present(L"roms/mt32/mt32_pcm.rom")); + return roms_present; +} + +static thread_t *thread_h = NULL; +static event_t *event = NULL; + +#define RENDER_RATE 30 + +static uint32_t samplerate = 44100; +static int buf_size = 0; +static float* buffer = NULL; +static int16_t* buffer_int16 = NULL; +static int midi_pos = 0; + +void mt32_stream(float* stream, int len) +{ + if (context) mt32emu_render_float(context, stream, len); +} + +void mt32_stream_int16(int16_t* stream, int len) +{ + if (context) mt32emu_render_bit16s(context, stream, len); +} + +void mt32_poll() +{ + midi_pos++; + if (midi_pos == 48000/RENDER_RATE) + { + midi_pos = 0; + thread_set_event(event); + } +} + +extern int soundon; + +static void mt32_thread(void *param) +{ + while (1) + { + thread_wait_event(event, -1); + if (sound_is_float) + { + memset(buffer, 0, buf_size * sizeof(float)); + mt32_stream(buffer, (samplerate/RENDER_RATE)); + if (soundon) + givealbuffer_midi(buffer, buf_size); + } + else + { + memset(buffer_int16, 0, buf_size * sizeof(int16_t)); + mt32_stream_int16(buffer_int16, (samplerate/RENDER_RATE)); + if (soundon) + givealbuffer_midi(buffer_int16, buf_size); + } + } +} + +void mt32_msg(uint8_t* val) +{ + if (context) mt32_check("mt32emu_play_msg", mt32emu_play_msg(context, *(uint32_t*)val), MT32EMU_RC_OK); +} + +void mt32_sysex(uint8_t* data, unsigned int len) +{ + if (context) mt32_check("mt32emu_play_sysex", mt32emu_play_sysex(context, data, len), MT32EMU_RC_OK); +} + +void* mt32_init() +{ + wchar_t s[512]; + char fn[512]; + context = mt32emu_create_context(handler, NULL); + if (!rom_getfile(L"roms/mt32/mt32_control.rom", s, 512)) return 0; + wcstombs(fn, s, (wcslen(s) << 1) + 2); + if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_CONTROL_ROM)) return 0; + if (!rom_getfile(L"roms/mt32/mt32_pcm.rom", s, 512)) return 0; + wcstombs(fn, s, (wcslen(s) << 1) + 2); + if (!mt32_check("mt32emu_add_rom_file", mt32emu_add_rom_file(context, fn), MT32EMU_RC_ADDED_PCM_ROM)) return 0; + + if (!mt32_check("mt32emu_open_synth", mt32emu_open_synth(context), MT32EMU_RC_OK)) return 0; + + event = thread_create_event(); + thread_h = thread_create(mt32_thread, 0); + samplerate = mt32emu_get_actual_stereo_output_samplerate(context); + buf_size = samplerate/RENDER_RATE*2; + if (sound_is_float) + { + buffer = malloc(buf_size * sizeof(float)); + buffer_int16 = NULL; + } + else + { + buffer = NULL; + buffer_int16 = malloc(buf_size * sizeof(int16_t)); + } + + mt32emu_set_output_gain(context, device_get_config_int("output_gain")/100.0f); + mt32emu_set_reverb_enabled(context, device_get_config_int("reverb")); + mt32emu_set_reverb_output_gain(context, device_get_config_int("reverb_output_gain")/100.0f); + mt32emu_set_reversed_stereo_enabled(context, device_get_config_int("reversed_stereo")); + + pclog("mt32 output gain: %f\n", mt32emu_get_output_gain(context)); + pclog("mt32 reverb output gain: %f\n", mt32emu_get_reverb_output_gain(context)); + pclog("mt32 reverb: %d\n", mt32emu_is_reverb_enabled(context)); + pclog("mt32 reversed stereo: %d\n", mt32emu_is_reversed_stereo_enabled(context)); + + al_set_midi(samplerate, buf_size); + + pclog("mt32 (Munt %s) initialized, samplerate %d, buf_size %d\n", mt32emu_get_library_version_string(), samplerate, buf_size); + + midi_device_t* dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = mt32_msg; + dev->play_sysex = mt32_sysex; + dev->poll = mt32_poll; + + midi_init(dev); + + return dev; +} + +void mt32_close(void* p) +{ + if (!p) return; + + if (thread_h) + thread_kill(thread_h); + if (event) + thread_destroy_event(event); + event = NULL; + thread_h = NULL; + + if (context) + { + mt32emu_close_synth(context); + mt32emu_free_context(context); + } + context = NULL; + + if (buffer) + free(buffer); + buffer = NULL; + + if (buffer_int16) + free(buffer_int16); + buffer_int16 = NULL; + + midi_close(); + + free((midi_device_t*)p); + + pclog("mt32 closed\n"); +} + +static device_config_t mt32_config[] = +{ + { + .name = "output_gain", + .description = "Output Gain", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "100%", + .value = 100 + }, + { + .description = "75%", + .value = 75 + }, + { + .description = "50%", + .value = 50 + }, + { + .description = "25%", + .value = 25 + }, + { + .description = "0%", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 100 + }, + { + .name = "reverb", + .description = "Reverb", + .type = CONFIG_BINARY, + .default_int = 1 + }, + { + .name = "reverb_output_gain", + .description = "Reverb Output Gain", + .type = CONFIG_SELECTION, + .selection = + { + { + .description = "100%", + .value = 100 + }, + { + .description = "75%", + .value = 75 + }, + { + .description = "50%", + .value = 50 + }, + { + .description = "25%", + .value = 25 + }, + { + .description = "0%", + .value = 0 + }, + { + .description = "" + } + }, + .default_int = 100 + }, + { + .name = "reversed_stereo", + .description = "Reversed stereo", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .type = -1 + } +}; + +device_t mt32_device = +{ + "Roland MT-32 Emulation", + 0, + mt32_init, + mt32_close, + mt32_available, + NULL, + NULL, + NULL, + mt32_config +}; diff --git a/src/SOUND/midi_mt32.h b/src/SOUND/midi_mt32.h new file mode 100644 index 000000000..9a80989a6 --- /dev/null +++ b/src/SOUND/midi_mt32.h @@ -0,0 +1 @@ +extern device_t mt32_device; diff --git a/src/SOUND/midi_system.c b/src/SOUND/midi_system.c new file mode 100644 index 000000000..d69fc3a4b --- /dev/null +++ b/src/SOUND/midi_system.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include "../device.h" +#include "../WIN/plat_midi.h" +#include "midi_system.h" +#include "midi.h" + +void* system_midi_init() +{ + midi_device_t* dev = malloc(sizeof(midi_device_t)); + memset(dev, 0, sizeof(midi_device_t)); + + dev->play_msg = plat_midi_play_msg; + dev->play_sysex = plat_midi_play_sysex; + dev->write = plat_midi_write; + + plat_midi_init(); + + midi_init(dev); + + return dev; +} + +void system_midi_close(void* p) +{ + plat_midi_close(); + + midi_close(); +} + +int system_midi_available() +{ + return plat_midi_get_num_devs(); +} + +static device_config_t system_midi_config[] = +{ + { + .name = "midi", + .description = "MIDI out device", + .type = CONFIG_MIDI, + .default_int = 0 + }, + { + .type = -1 + } +}; + +device_t system_midi_device = +{ + SYSTEM_MIDI_NAME, + 0, + system_midi_init, + system_midi_close, + system_midi_available, + NULL, + NULL, + NULL, + system_midi_config +}; diff --git a/src/SOUND/midi_system.h b/src/SOUND/midi_system.h new file mode 100644 index 000000000..7afbb4c45 --- /dev/null +++ b/src/SOUND/midi_system.h @@ -0,0 +1 @@ +extern device_t system_midi_device; diff --git a/src/SOUND/munt/Analog.cpp b/src/SOUND/munt/Analog.cpp new file mode 100644 index 000000000..2901198f2 --- /dev/null +++ b/src/SOUND/munt/Analog.cpp @@ -0,0 +1,424 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "Analog.h" +#include "Synth.h" + +namespace MT32Emu { + +/* FIR approximation of the overall impulse response of the cascade composed of the sample & hold circuit and the low pass filter + * of the MT-32 first generation. + * The coefficients below are found by windowing the inverse DFT of the 1024 pin frequency response converted to the minimum phase. + * The frequency response of the LPF is computed directly, the effect of the S&H is approximated by multiplying the LPF frequency + * response by the corresponding sinc. Although, the LPF has DC gain of 3.2, we ignore this in the emulation and use normalised model. + * The peak gain of the normalised cascade appears about 1.7 near 11.8 kHz. Relative error doesn't exceed 1% for the frequencies + * below 12.5 kHz. In the higher frequency range, the relative error is below 8%. Peak error value is at 16 kHz. + */ +static const FloatSample COARSE_LPF_FLOAT_TAPS_MT32[] = { + 1.272473681f, -0.220267785f, -0.158039905f, 0.179603785f, -0.111484097f, 0.054137498f, -0.023518029f, 0.010997169f, -0.006935698f +}; + +// Similar approximation for new MT-32 and CM-32L/LAPC-I LPF. As the voltage controlled amplifier was introduced, LPF has unity DC gain. +// The peak gain value shifted towards higher frequencies and a bit higher about 1.83 near 13 kHz. +static const FloatSample COARSE_LPF_FLOAT_TAPS_CM32L[] = { + 1.340615635f, -0.403331694f, 0.036005517f, 0.066156844f, -0.069672532f, 0.049563806f, -0.031113416f, 0.019169774f, -0.012421368f +}; + +static const unsigned int COARSE_LPF_INT_FRACTION_BITS = 14; + +// Integer versions of the FIRs above multiplied by (1 << 14) and rounded. +static const IntSampleEx COARSE_LPF_INT_TAPS_MT32[] = { + 20848, -3609, -2589, 2943, -1827, 887, -385, 180, -114 +}; + +static const IntSampleEx COARSE_LPF_INT_TAPS_CM32L[] = { + 21965, -6608, 590, 1084, -1142, 812, -510, 314, -204 +}; + +/* Combined FIR that both approximates the impulse response of the analogue circuits of sample & hold and the low pass filter + * in the audible frequency range (below 20 kHz) and attenuates unwanted mirror spectra above 28 kHz as well. It is a polyphase + * filter intended for resampling the signal to 48 kHz yet for applying high frequency boost. + * As with the filter above, the analogue LPF frequency response is obtained for 1536 pin grid for range up to 96 kHz and multiplied + * by the corresponding sinc. The result is further squared, windowed and passed to generalised Parks-McClellan routine as a desired response. + * Finally, the minimum phase factor is found that's essentially the coefficients below. + * Relative error in the audible frequency range doesn't exceed 0.0006%, attenuation in the stopband is better than 100 dB. + * This level of performance makes it nearly bit-accurate for standard 16-bit sample resolution. + */ + +// FIR version for MT-32 first generation. +static const FloatSample ACCURATE_LPF_TAPS_MT32[] = { + 0.003429281f, 0.025929869f, 0.096587777f, 0.228884848f, 0.372413431f, 0.412386503f, 0.263980018f, + -0.014504962f, -0.237394528f, -0.257043496f, -0.103436603f, 0.063996095f, 0.124562333f, 0.083703206f, + 0.013921662f, -0.033475018f, -0.046239712f, -0.029310921f, 0.00126585f, 0.021060961f, 0.017925605f, + 0.003559874f, -0.005105248f, -0.005647917f, -0.004157918f, -0.002065664f, 0.00158747f, 0.003762585f, + 0.001867137f, -0.001090028f, -0.001433979f, -0.00022367f, 4.34308E-05f, -0.000247827f, 0.000157087f, + 0.000605823f, 0.000197317f, -0.000370511f, -0.000261202f, 9.96069E-05f, 9.85073E-05f, -5.28754E-05f, + -1.00912E-05f, 7.69943E-05f, 2.03162E-05f, -5.67967E-05f, -3.30637E-05f, 1.61958E-05f, 1.73041E-05f +}; + +// FIR version for new MT-32 and CM-32L/LAPC-I. +static const FloatSample ACCURATE_LPF_TAPS_CM32L[] = { + 0.003917452f, 0.030693861f, 0.116424199f, 0.275101674f, 0.43217361f, 0.431247894f, 0.183255659f, + -0.174955671f, -0.354240244f, -0.212401714f, 0.072259178f, 0.204655344f, 0.108336211f, -0.039099027f, + -0.075138174f, -0.026261906f, 0.00582663f, 0.003052193f, 0.00613657f, 0.017017951f, 0.008732535f, + -0.011027427f, -0.012933664f, 0.001158097f, 0.006765958f, 0.00046778f, -0.002191106f, 0.001561017f, + 0.001842871f, -0.001996876f, -0.002315836f, 0.000980965f, 0.001817454f, -0.000243272f, -0.000972848f, + 0.000149941f, 0.000498886f, -0.000204436f, -0.000347415f, 0.000142386f, 0.000249137f, -4.32946E-05f, + -0.000131231f, 3.88575E-07f, 4.48813E-05f, -1.31906E-06f, -1.03499E-05f, 7.71971E-06f, 2.86721E-06f +}; + +// According to the CM-64 PCB schematic, there is a difference in the values of the LPF entrance resistors for the reverb and non-reverb channels. +// This effectively results in non-unity LPF DC gain for the reverb channel of 0.68 while the LPF has unity DC gain for the LA32 output channels. +// In emulation, the reverb output gain is multiplied by this factor to compensate for the LPF gain difference. +static const float CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR = 0.68f; + +static const unsigned int OUTPUT_GAIN_FRACTION_BITS = 8; +static const float OUTPUT_GAIN_MULTIPLIER = float(1 << OUTPUT_GAIN_FRACTION_BITS); + +static const unsigned int COARSE_LPF_DELAY_LINE_LENGTH = 8; // Must be a power of 2 +static const unsigned int ACCURATE_LPF_DELAY_LINE_LENGTH = 16; // Must be a power of 2 +static const unsigned int ACCURATE_LPF_NUMBER_OF_PHASES = 3; // Upsampling factor +static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_REGULAR = 2; // Downsampling factor +static const unsigned int ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED = 1; // No downsampling +static const Bit32u ACCURATE_LPF_DELTAS_REGULAR[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 1, 0 }, { 1, 2, 1 } }; +static const Bit32u ACCURATE_LPF_DELTAS_OVERSAMPLED[][ACCURATE_LPF_NUMBER_OF_PHASES] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 } }; + +template +class AbstractLowPassFilter { +public: + static AbstractLowPassFilter &createLowPassFilter(const AnalogOutputMode mode, const bool oldMT32AnalogLPF); + + virtual ~AbstractLowPassFilter() {} + virtual SampleEx process(const SampleEx sample) = 0; + + virtual bool hasNextSample() const { + return false; + } + + virtual unsigned int getOutputSampleRate() const { + return SAMPLE_RATE; + } + + virtual unsigned int estimateInSampleCount(const unsigned int outSamples) const { + return outSamples; + } + + virtual void addPositionIncrement(const unsigned int) {} +}; + +template +class NullLowPassFilter : public AbstractLowPassFilter { +public: + SampleEx process(const SampleEx sample) { + return sample; + } +}; + +template +class CoarseLowPassFilter : public AbstractLowPassFilter { +private: + const SampleEx * const lpfTaps; + SampleEx ringBuffer[COARSE_LPF_DELAY_LINE_LENGTH]; + unsigned int ringBufferPosition; + +public: + static inline const SampleEx *getLPFTaps(const bool oldMT32AnalogLPF); + static inline SampleEx normaliseSample(const SampleEx sample); + + explicit CoarseLowPassFilter(const bool oldMT32AnalogLPF) : + lpfTaps(getLPFTaps(oldMT32AnalogLPF)), + ringBufferPosition(0) + { + Synth::muteSampleBuffer(ringBuffer, COARSE_LPF_DELAY_LINE_LENGTH); + } + + SampleEx process(const SampleEx inSample) { + static const unsigned int DELAY_LINE_MASK = COARSE_LPF_DELAY_LINE_LENGTH - 1; + + SampleEx sample = lpfTaps[COARSE_LPF_DELAY_LINE_LENGTH] * ringBuffer[ringBufferPosition]; + ringBuffer[ringBufferPosition] = Synth::clipSampleEx(inSample); + + for (unsigned int i = 0; i < COARSE_LPF_DELAY_LINE_LENGTH; i++) { + sample += lpfTaps[i] * ringBuffer[(i + ringBufferPosition) & DELAY_LINE_MASK]; + } + + ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK; + + return normaliseSample(sample); + } +}; + +class AccurateLowPassFilter : public AbstractLowPassFilter, public AbstractLowPassFilter { +private: + const FloatSample * const LPF_TAPS; + const Bit32u (* const deltas)[ACCURATE_LPF_NUMBER_OF_PHASES]; + const unsigned int phaseIncrement; + const unsigned int outputSampleRate; + + FloatSample ringBuffer[ACCURATE_LPF_DELAY_LINE_LENGTH]; + unsigned int ringBufferPosition; + unsigned int phase; + +public: + AccurateLowPassFilter(const bool oldMT32AnalogLPF, const bool oversample); + FloatSample process(const FloatSample sample); + IntSampleEx process(const IntSampleEx sample); + bool hasNextSample() const; + unsigned int getOutputSampleRate() const; + unsigned int estimateInSampleCount(const unsigned int outSamples) const; + void addPositionIncrement(const unsigned int positionIncrement); +}; + +static inline IntSampleEx normaliseSample(const IntSampleEx sample) { + return sample >> OUTPUT_GAIN_FRACTION_BITS; +} + +static inline FloatSample normaliseSample(const FloatSample sample) { + return sample; +} + +static inline float getActualReverbOutputGain(const float reverbGain, const bool mt32ReverbCompatibilityMode) { + return mt32ReverbCompatibilityMode ? reverbGain : reverbGain * CM32L_REVERB_TO_LA32_ANALOG_OUTPUT_GAIN_FACTOR; +} + +static inline IntSampleEx getIntOutputGain(const float outputGain) { + return IntSampleEx(((OUTPUT_GAIN_MULTIPLIER < outputGain) ? OUTPUT_GAIN_MULTIPLIER : outputGain) * OUTPUT_GAIN_MULTIPLIER); +} + +template +class AnalogImpl : public Analog { +public: + AbstractLowPassFilter &leftChannelLPF; + AbstractLowPassFilter &rightChannelLPF; + SampleEx synthGain; + SampleEx reverbGain; + + AnalogImpl(const AnalogOutputMode mode, const bool oldMT32AnalogLPF) : + leftChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, oldMT32AnalogLPF)), + rightChannelLPF(AbstractLowPassFilter::createLowPassFilter(mode, oldMT32AnalogLPF)), + synthGain(0), + reverbGain(0) + {} + + ~AnalogImpl() { + delete &leftChannelLPF; + delete &rightChannelLPF; + } + + unsigned int getOutputSampleRate() const { + return leftChannelLPF.getOutputSampleRate(); + } + + Bit32u getDACStreamsLength(const Bit32u outputLength) const { + return leftChannelLPF.estimateInSampleCount(outputLength); + } + + void setSynthOutputGain(const float synthGain); + void setReverbOutputGain(const float reverbGain, const bool mt32ReverbCompatibilityMode); + + bool process(IntSample *outStream, const IntSample *nonReverbLeft, const IntSample *nonReverbRight, const IntSample *reverbDryLeft, const IntSample *reverbDryRight, const IntSample *reverbWetLeft, const IntSample *reverbWetRight, Bit32u outLength); + bool process(FloatSample *outStream, const FloatSample *nonReverbLeft, const FloatSample *nonReverbRight, const FloatSample *reverbDryLeft, const FloatSample *reverbDryRight, const FloatSample *reverbWetLeft, const FloatSample *reverbWetRight, Bit32u outLength); + + template + void produceOutput(Sample *outStream, const Sample *nonReverbLeft, const Sample *nonReverbRight, const Sample *reverbDryLeft, const Sample *reverbDryRight, const Sample *reverbWetLeft, const Sample *reverbWetRight, Bit32u outLength) { + if (outStream == NULL) { + leftChannelLPF.addPositionIncrement(outLength); + rightChannelLPF.addPositionIncrement(outLength); + return; + } + + while (0 < (outLength--)) { + SampleEx outSampleL; + SampleEx outSampleR; + + if (leftChannelLPF.hasNextSample()) { + outSampleL = leftChannelLPF.process(0); + outSampleR = rightChannelLPF.process(0); + } else { + SampleEx inSampleL = (SampleEx(*(nonReverbLeft++)) + SampleEx(*(reverbDryLeft++))) * synthGain + SampleEx(*(reverbWetLeft++)) * reverbGain; + SampleEx inSampleR = (SampleEx(*(nonReverbRight++)) + SampleEx(*(reverbDryRight++))) * synthGain + SampleEx(*(reverbWetRight++)) * reverbGain; + + outSampleL = leftChannelLPF.process(normaliseSample(inSampleL)); + outSampleR = rightChannelLPF.process(normaliseSample(inSampleR)); + } + + *(outStream++) = Synth::clipSampleEx(outSampleL); + *(outStream++) = Synth::clipSampleEx(outSampleR); + } + } +}; + +Analog *Analog::createAnalog(const AnalogOutputMode mode, const bool oldMT32AnalogLPF, const RendererType rendererType) { + switch (rendererType) + { + case RendererType_BIT16S: + return new AnalogImpl(mode, oldMT32AnalogLPF); + case RendererType_FLOAT: + return new AnalogImpl(mode, oldMT32AnalogLPF); + } + return NULL; +} + +template<> +bool AnalogImpl::process(IntSample *outStream, const IntSample *nonReverbLeft, const IntSample *nonReverbRight, const IntSample *reverbDryLeft, const IntSample *reverbDryRight, const IntSample *reverbWetLeft, const IntSample *reverbWetRight, Bit32u outLength) { + produceOutput(outStream, nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, outLength); + return true; +} + +template<> +bool AnalogImpl::process(IntSample *, const IntSample *, const IntSample *, const IntSample *, const IntSample *, const IntSample *, const IntSample *, Bit32u) { + return false; +} + +template<> +bool AnalogImpl::process(FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, const FloatSample *, Bit32u) { + return false; +} + +template<> +bool AnalogImpl::process(FloatSample *outStream, const FloatSample *nonReverbLeft, const FloatSample *nonReverbRight, const FloatSample *reverbDryLeft, const FloatSample *reverbDryRight, const FloatSample *reverbWetLeft, const FloatSample *reverbWetRight, Bit32u outLength) { + produceOutput(outStream, nonReverbLeft, nonReverbRight, reverbDryLeft, reverbDryRight, reverbWetLeft, reverbWetRight, outLength); + return true; +} + +template<> +void AnalogImpl::setSynthOutputGain(const float useSynthGain) { + synthGain = getIntOutputGain(useSynthGain); +} + +template<> +void AnalogImpl::setReverbOutputGain(const float useReverbGain, const bool mt32ReverbCompatibilityMode) { + reverbGain = getIntOutputGain(getActualReverbOutputGain(useReverbGain, mt32ReverbCompatibilityMode)); +} + +template<> +void AnalogImpl::setSynthOutputGain(const float useSynthGain) { + synthGain = useSynthGain; +} + +template<> +void AnalogImpl::setReverbOutputGain(const float useReverbGain, const bool mt32ReverbCompatibilityMode) { + reverbGain = getActualReverbOutputGain(useReverbGain, mt32ReverbCompatibilityMode); +} + +template<> +AbstractLowPassFilter &AbstractLowPassFilter::createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF) { + switch (mode) { + case AnalogOutputMode_COARSE: + return *new CoarseLowPassFilter(oldMT32AnalogLPF); + case AnalogOutputMode_ACCURATE: + return *new AccurateLowPassFilter(oldMT32AnalogLPF, false); + case AnalogOutputMode_OVERSAMPLED: + return *new AccurateLowPassFilter(oldMT32AnalogLPF, true); + default: + return *new NullLowPassFilter; + } +} + +template<> +AbstractLowPassFilter &AbstractLowPassFilter::createLowPassFilter(AnalogOutputMode mode, bool oldMT32AnalogLPF) { + switch (mode) { + case AnalogOutputMode_COARSE: + return *new CoarseLowPassFilter(oldMT32AnalogLPF); + case AnalogOutputMode_ACCURATE: + return *new AccurateLowPassFilter(oldMT32AnalogLPF, false); + case AnalogOutputMode_OVERSAMPLED: + return *new AccurateLowPassFilter(oldMT32AnalogLPF, true); + default: + return *new NullLowPassFilter; + } +} + +template<> +const IntSampleEx *CoarseLowPassFilter::getLPFTaps(const bool oldMT32AnalogLPF) { + return oldMT32AnalogLPF ? COARSE_LPF_INT_TAPS_MT32 : COARSE_LPF_INT_TAPS_CM32L; +} + +template<> +const FloatSample *CoarseLowPassFilter::getLPFTaps(const bool oldMT32AnalogLPF) { + return oldMT32AnalogLPF ? COARSE_LPF_FLOAT_TAPS_MT32 : COARSE_LPF_FLOAT_TAPS_CM32L; +} + +template<> +IntSampleEx CoarseLowPassFilter::normaliseSample(const IntSampleEx sample) { + return sample >> COARSE_LPF_INT_FRACTION_BITS; +} + +template<> +FloatSample CoarseLowPassFilter::normaliseSample(const FloatSample sample) { + return sample; +} + +AccurateLowPassFilter::AccurateLowPassFilter(const bool oldMT32AnalogLPF, const bool oversample) : + LPF_TAPS(oldMT32AnalogLPF ? ACCURATE_LPF_TAPS_MT32 : ACCURATE_LPF_TAPS_CM32L), + deltas(oversample ? ACCURATE_LPF_DELTAS_OVERSAMPLED : ACCURATE_LPF_DELTAS_REGULAR), + phaseIncrement(oversample ? ACCURATE_LPF_PHASE_INCREMENT_OVERSAMPLED : ACCURATE_LPF_PHASE_INCREMENT_REGULAR), + outputSampleRate(SAMPLE_RATE * ACCURATE_LPF_NUMBER_OF_PHASES / phaseIncrement), + ringBufferPosition(0), + phase(0) +{ + Synth::muteSampleBuffer(ringBuffer, ACCURATE_LPF_DELAY_LINE_LENGTH); +} + +FloatSample AccurateLowPassFilter::process(const FloatSample inSample) { + static const unsigned int DELAY_LINE_MASK = ACCURATE_LPF_DELAY_LINE_LENGTH - 1; + + FloatSample sample = (phase == 0) ? LPF_TAPS[ACCURATE_LPF_DELAY_LINE_LENGTH * ACCURATE_LPF_NUMBER_OF_PHASES] * ringBuffer[ringBufferPosition] : 0.0f; + if (!hasNextSample()) { + ringBuffer[ringBufferPosition] = inSample; + } + + for (unsigned int tapIx = phase, delaySampleIx = 0; delaySampleIx < ACCURATE_LPF_DELAY_LINE_LENGTH; delaySampleIx++, tapIx += ACCURATE_LPF_NUMBER_OF_PHASES) { + sample += LPF_TAPS[tapIx] * ringBuffer[(delaySampleIx + ringBufferPosition) & DELAY_LINE_MASK]; + } + + phase += phaseIncrement; + if (ACCURATE_LPF_NUMBER_OF_PHASES <= phase) { + phase -= ACCURATE_LPF_NUMBER_OF_PHASES; + ringBufferPosition = (ringBufferPosition - 1) & DELAY_LINE_MASK; + } + + return ACCURATE_LPF_NUMBER_OF_PHASES * sample; +} + +IntSampleEx AccurateLowPassFilter::process(const IntSampleEx sample) { + return IntSampleEx(process(FloatSample(sample))); +} + +bool AccurateLowPassFilter::hasNextSample() const { + return phaseIncrement <= phase; +} + +unsigned int AccurateLowPassFilter::getOutputSampleRate() const { + return outputSampleRate; +} + +unsigned int AccurateLowPassFilter::estimateInSampleCount(const unsigned int outSamples) const { + Bit32u cycleCount = outSamples / ACCURATE_LPF_NUMBER_OF_PHASES; + Bit32u remainder = outSamples - cycleCount * ACCURATE_LPF_NUMBER_OF_PHASES; + return cycleCount * phaseIncrement + deltas[remainder][phase]; +} + +void AccurateLowPassFilter::addPositionIncrement(const unsigned int positionIncrement) { + phase = (phase + positionIncrement * phaseIncrement) % ACCURATE_LPF_NUMBER_OF_PHASES; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/Analog.h b/src/SOUND/munt/Analog.h new file mode 100644 index 000000000..edaab4fe2 --- /dev/null +++ b/src/SOUND/munt/Analog.h @@ -0,0 +1,53 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_ANALOG_H +#define MT32EMU_ANALOG_H + +#include "globals.h" +#include "internals.h" +#include "Enumerations.h" +#include "Types.h" + +namespace MT32Emu { + +/* Analog class is dedicated to perform fair emulation of analogue circuitry of hardware units that is responsible + * for processing output signal after the DAC. It appears that the analogue circuit labeled "LPF" on the schematic + * also applies audible changes to the signal spectra. There is a significant boost of higher frequencies observed + * aside from quite poor attenuation of the mirror spectra above 16 kHz which is due to a relatively low filter order. + * + * As the final mixing of multiplexed output signal is performed after the DAC, this function is migrated here from Synth. + * Saying precisely, mixing is performed within the LPF as the entrance resistors are actually components of a LPF + * designed using the multiple feedback topology. Nevertheless, the schematic separates them. + */ +class Analog { +public: + static Analog *createAnalog(const AnalogOutputMode mode, const bool oldMT32AnalogLPF, const RendererType rendererType); + + virtual ~Analog() {}; + virtual unsigned int getOutputSampleRate() const = 0; + virtual Bit32u getDACStreamsLength(const Bit32u outputLength) const = 0; + virtual void setSynthOutputGain(const float synthGain) = 0; + virtual void setReverbOutputGain(const float reverbGain, const bool mt32ReverbCompatibilityMode) = 0; + + virtual bool process(IntSample *outStream, const IntSample *nonReverbLeft, const IntSample *nonReverbRight, const IntSample *reverbDryLeft, const IntSample *reverbDryRight, const IntSample *reverbWetLeft, const IntSample *reverbWetRight, Bit32u outLength) = 0; + virtual bool process(FloatSample *outStream, const FloatSample *nonReverbLeft, const FloatSample *nonReverbRight, const FloatSample *reverbDryLeft, const FloatSample *reverbDryRight, const FloatSample *reverbWetLeft, const FloatSample *reverbWetRight, Bit32u outLength) = 0; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_ANALOG_H diff --git a/src/SOUND/munt/BReverbModel.cpp b/src/SOUND/munt/BReverbModel.cpp new file mode 100644 index 000000000..af559a92a --- /dev/null +++ b/src/SOUND/munt/BReverbModel.cpp @@ -0,0 +1,662 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "BReverbModel.h" +#include "Synth.h" + +// Analysing of state of reverb RAM address lines gives exact sizes of the buffers of filters used. This also indicates that +// the reverb model implemented in the real devices consists of three series allpass filters preceded by a non-feedback comb (or a delay with a LPF) +// and followed by three parallel comb filters + +namespace MT32Emu { + +// Because LA-32 chip makes it's output available to process by the Boss chip with a significant delay, +// the Boss chip puts to the buffer the LA32 dry output when it is ready and performs processing of the _previously_ latched data. +// Of course, the right way would be to use a dedicated variable for this, but our reverb model is way higher level, +// so we can simply increase the input buffer size. +static const Bit32u PROCESS_DELAY = 1; + +static const Bit32u MODE_3_ADDITIONAL_DELAY = 1; +static const Bit32u MODE_3_FEEDBACK_DELAY = 1; + +// Avoid denormals degrading performance, using biased input +static const FloatSample BIAS = 1e-20f; + +struct BReverbSettings { + const Bit32u numberOfAllpasses; + const Bit32u * const allpassSizes; + const Bit32u numberOfCombs; + const Bit32u * const combSizes; + const Bit32u * const outLPositions; + const Bit32u * const outRPositions; + const Bit8u * const filterFactors; + const Bit8u * const feedbackFactors; + const Bit8u * const dryAmps; + const Bit8u * const wetLevels; + const Bit8u lpfAmp; +}; + +// Default reverb settings for "new" reverb model implemented in CM-32L / LAPC-I. +// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog). +static const BReverbSettings &getCM32L_LAPCSettings(const ReverbMode mode) { + static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3; + static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78}; + static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Well, actually there are 3 comb filters, but the entrance LPF + delay can be processed via a hacked comb. + static const Bit32u MODE_0_COMBS[] = {705 + PROCESS_DELAY, 2349, 2839, 3632}; + static const Bit32u MODE_0_OUTL[] = {2349, 141, 1960}; + static const Bit32u MODE_0_OUTR[] = {1174, 1570, 145}; + static const Bit8u MODE_0_COMB_FACTOR[] = {0xA0, 0x60, 0x60, 0x60}; + static const Bit8u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; + static const Bit8u MODE_0_DRY_AMP[] = {0xA0, 0xA0, 0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xD0}; + static const Bit8u MODE_0_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0}; + static const Bit8u MODE_0_LPF_AMP = 0x60; + + static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3; + static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176}; + static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as for mode 0 above + static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519}; + static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518}; + static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274}; + static const Bit8u MODE_1_COMB_FACTOR[] = {0x80, 0x60, 0x60, 0x60}; + static const Bit8u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; + static const Bit8u MODE_1_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xB0, 0xE0}; + static const Bit8u MODE_1_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0}; + static const Bit8u MODE_1_LPF_AMP = 0x60; + + static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3; + static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157}; + static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as for mode 0 above + static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539}; + static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769}; + static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1}; + static const Bit8u MODE_2_COMB_FACTOR[] = {0, 0x20, 0x20, 0x20}; + static const Bit8u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0, + 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0, + 0x30, 0x58, 0x78, 0x88, 0xA0, 0xB8, 0xC0, 0xD0}; + static const Bit8u MODE_2_DRY_AMP[] = {0xA0, 0xA0, 0xB0, 0xB0, 0xB0, 0xB0, 0xC0, 0xE0}; + static const Bit8u MODE_2_WET_AMP[] = {0x10, 0x30, 0x50, 0x70, 0x90, 0xC0, 0xF0, 0xF0}; + static const Bit8u MODE_2_LPF_AMP = 0x80; + + static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0; + static const Bit32u MODE_3_NUMBER_OF_COMBS = 1; + static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY}; + static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000}; + static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000}; + static const Bit8u MODE_3_COMB_FACTOR[] = {0x68}; + static const Bit8u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60}; + static const Bit8u MODE_3_DRY_AMP[] = {0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, + 0x20, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50}; + static const Bit8u MODE_3_WET_AMP[] = {0x18, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8}; + + static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP}; + static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP}; + static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP}; + static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0}; + + static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS}; + + return *REVERB_SETTINGS[mode]; +} + +// Default reverb settings for "old" reverb model implemented in MT-32. +// Found by tracing reverb RAM data lines (thanks go to Lord_Nightmare & balrog). +static const BReverbSettings &getMT32Settings(const ReverbMode mode) { + static const Bit32u MODE_0_NUMBER_OF_ALLPASSES = 3; + static const Bit32u MODE_0_ALLPASSES[] = {994, 729, 78}; + static const Bit32u MODE_0_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation + static const Bit32u MODE_0_COMBS[] = {575 + PROCESS_DELAY, 2040, 2752, 3629}; + static const Bit32u MODE_0_OUTL[] = {2040, 687, 1814}; + static const Bit32u MODE_0_OUTR[] = {1019, 2072, 1}; + static const Bit8u MODE_0_COMB_FACTOR[] = {0xB0, 0x60, 0x60, 0x60}; + static const Bit8u MODE_0_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; + static const Bit8u MODE_0_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; + static const Bit8u MODE_0_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0}; + static const Bit8u MODE_0_LPF_AMP = 0x80; + + static const Bit32u MODE_1_NUMBER_OF_ALLPASSES = 3; + static const Bit32u MODE_1_ALLPASSES[] = {1324, 809, 176}; + static const Bit32u MODE_1_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation + static const Bit32u MODE_1_COMBS[] = {961 + PROCESS_DELAY, 2619, 3545, 4519}; + static const Bit32u MODE_1_OUTL[] = {2618, 1760, 4518}; + static const Bit32u MODE_1_OUTR[] = {1300, 3532, 2274}; + static const Bit8u MODE_1_COMB_FACTOR[] = {0x90, 0x60, 0x60, 0x60}; + static const Bit8u MODE_1_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; + static const Bit8u MODE_1_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; + static const Bit8u MODE_1_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0}; + static const Bit8u MODE_1_LPF_AMP = 0x80; + + static const Bit32u MODE_2_NUMBER_OF_ALLPASSES = 3; + static const Bit32u MODE_2_ALLPASSES[] = {969, 644, 157}; + static const Bit32u MODE_2_NUMBER_OF_COMBS = 4; // Same as above in the new model implementation + static const Bit32u MODE_2_COMBS[] = {116 + PROCESS_DELAY, 2259, 2839, 3539}; + static const Bit32u MODE_2_OUTL[] = {2259, 718, 1769}; + static const Bit32u MODE_2_OUTR[] = {1136, 2128, 1}; + static const Bit8u MODE_2_COMB_FACTOR[] = {0, 0x60, 0x60, 0x60}; + static const Bit8u MODE_2_COMB_FEEDBACK[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x48, 0x60, 0x70, 0x78, 0x80, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98, + 0x28, 0x48, 0x60, 0x78, 0x80, 0x88, 0x90, 0x98}; + static const Bit8u MODE_2_DRY_AMP[] = {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}; + static const Bit8u MODE_2_WET_AMP[] = {0x10, 0x20, 0x30, 0x40, 0x50, 0x70, 0xA0, 0xE0}; + static const Bit8u MODE_2_LPF_AMP = 0x80; + + static const Bit32u MODE_3_NUMBER_OF_ALLPASSES = 0; + static const Bit32u MODE_3_NUMBER_OF_COMBS = 1; + static const Bit32u MODE_3_DELAY[] = {16000 + MODE_3_FEEDBACK_DELAY + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY}; + static const Bit32u MODE_3_OUTL[] = {400, 624, 960, 1488, 2256, 3472, 5280, 8000}; + static const Bit32u MODE_3_OUTR[] = {800, 1248, 1920, 2976, 4512, 6944, 10560, 16000}; + static const Bit8u MODE_3_COMB_FACTOR[] = {0x68}; + static const Bit8u MODE_3_COMB_FEEDBACK[] = {0x68, 0x60}; + static const Bit8u MODE_3_DRY_AMP[] = {0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x10, 0x20, 0x20, 0x10, 0x20, 0x10, 0x20, 0x10}; + static const Bit8u MODE_3_WET_AMP[] = {0x08, 0x18, 0x28, 0x40, 0x60, 0x80, 0xA8, 0xF8}; + + static const BReverbSettings REVERB_MODE_0_SETTINGS = {MODE_0_NUMBER_OF_ALLPASSES, MODE_0_ALLPASSES, MODE_0_NUMBER_OF_COMBS, MODE_0_COMBS, MODE_0_OUTL, MODE_0_OUTR, MODE_0_COMB_FACTOR, MODE_0_COMB_FEEDBACK, MODE_0_DRY_AMP, MODE_0_WET_AMP, MODE_0_LPF_AMP}; + static const BReverbSettings REVERB_MODE_1_SETTINGS = {MODE_1_NUMBER_OF_ALLPASSES, MODE_1_ALLPASSES, MODE_1_NUMBER_OF_COMBS, MODE_1_COMBS, MODE_1_OUTL, MODE_1_OUTR, MODE_1_COMB_FACTOR, MODE_1_COMB_FEEDBACK, MODE_1_DRY_AMP, MODE_1_WET_AMP, MODE_1_LPF_AMP}; + static const BReverbSettings REVERB_MODE_2_SETTINGS = {MODE_2_NUMBER_OF_ALLPASSES, MODE_2_ALLPASSES, MODE_2_NUMBER_OF_COMBS, MODE_2_COMBS, MODE_2_OUTL, MODE_2_OUTR, MODE_2_COMB_FACTOR, MODE_2_COMB_FEEDBACK, MODE_2_DRY_AMP, MODE_2_WET_AMP, MODE_2_LPF_AMP}; + static const BReverbSettings REVERB_MODE_3_SETTINGS = {MODE_3_NUMBER_OF_ALLPASSES, NULL, MODE_3_NUMBER_OF_COMBS, MODE_3_DELAY, MODE_3_OUTL, MODE_3_OUTR, MODE_3_COMB_FACTOR, MODE_3_COMB_FEEDBACK, MODE_3_DRY_AMP, MODE_3_WET_AMP, 0}; + + static const BReverbSettings * const REVERB_SETTINGS[] = {&REVERB_MODE_0_SETTINGS, &REVERB_MODE_1_SETTINGS, &REVERB_MODE_2_SETTINGS, &REVERB_MODE_3_SETTINGS}; + + return *REVERB_SETTINGS[mode]; +} + +static inline IntSample weirdMul(IntSample sample, Bit8u addMask, Bit8u carryMask) { +#if MT32EMU_BOSS_REVERB_PRECISE_MODE + // This algorithm tries to emulate exactly Boss multiplication operation (at least this is what we see on reverb RAM data lines). + Bit8u mask = 0x80; + IntSampleEx res = 0; + for (int i = 0; i < 8; i++) { + IntSampleEx carry = (sample < 0) && (mask & carryMask) > 0 ? sample & 1 : 0; + sample >>= 1; + res += (mask & addMask) > 0 ? sample + carry : 0; + mask >>= 1; + } + return IntSample(res); +#else + (void)carryMask; + return IntSample((IntSampleEx(sample) * addMask) >> 8); +#endif +} + +static inline FloatSample weirdMul(FloatSample sample, Bit8u addMask, Bit8u carryMask) { + (void)carryMask; + return sample * addMask / 256.0f; +} + +static inline IntSample halveSample(IntSample sample) { + return sample >> 1; +} + +static inline FloatSample halveSample(FloatSample sample) { + return 0.5f * sample; +} + +static inline IntSample quarterSample(IntSample sample) { +#if MT32EMU_BOSS_REVERB_PRECISE_MODE + return (sample >> 1) / 2; +#else + return sample >> 2; +#endif +} + +static inline FloatSample quarterSample(FloatSample sample) { + return 0.25f * sample; +} + +static inline IntSample addDCBias(IntSample sample) { + return sample; +} + +static inline FloatSample addDCBias(FloatSample sample) { + return sample + BIAS; +} + +static inline IntSample addAllpassNoise(IntSample sample) { +#if MT32EMU_BOSS_REVERB_PRECISE_MODE + // This introduces reverb noise which actually makes output from the real Boss chip nondeterministic + return sample - 1; +#else + return sample; +#endif +} + +static inline FloatSample addAllpassNoise(FloatSample sample) { + return sample; +} + +/* NOTE: + * Thanks to Mok for discovering, the adder in BOSS reverb chip is found to perform addition with saturation to avoid integer overflow. + * Analysing of the algorithm suggests that the overflow is most probable when the combs output is added below. + * So, despite this isn't actually accurate, we only add the check here for performance reasons. + */ +static inline IntSample mixCombs(IntSample out1, IntSample out2, IntSample out3) { +#if MT32EMU_BOSS_REVERB_PRECISE_MODE + return Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(Synth::clipSampleEx(IntSampleEx(out1) + (IntSampleEx(out1) >> 1)) + IntSampleEx(out2)) + (IntSampleEx(out2) >> 1)) + IntSampleEx(out3)); +#else + return Synth::clipSampleEx(IntSampleEx(out1) + (IntSampleEx(out1) >> 1) + IntSampleEx(out2) + (IntSampleEx(out2) >> 1) + IntSampleEx(out3)); +#endif +} + +static inline FloatSample mixCombs(FloatSample out1, FloatSample out2, FloatSample out3) { + return 1.5f * (out1 + out2) + out3; +} + +template +class RingBuffer { + static inline Sample sampleValueThreshold(); + +protected: + Sample *buffer; + const Bit32u size; + Bit32u index; + +public: + RingBuffer(const Bit32u newsize) : size(newsize), index(0) { + buffer = new Sample[size]; + } + + virtual ~RingBuffer() { + delete[] buffer; + buffer = NULL; + } + + Sample next() { + if (++index >= size) { + index = 0; + } + return buffer[index]; + } + + bool isEmpty() const { + if (buffer == NULL) return true; + + Sample *buf = buffer; + for (Bit32u i = 0; i < size; i++) { + if (*buf < -sampleValueThreshold() || *buf > sampleValueThreshold()) return false; + buf++; + } + return true; + } + + void mute() { + Synth::muteSampleBuffer(buffer, size); + } +}; + +template<> +IntSample RingBuffer::sampleValueThreshold() { + return 8; +} + +template<> +FloatSample RingBuffer::sampleValueThreshold() { + return 0.001f; +} + +template +class AllpassFilter : public RingBuffer { +public: + AllpassFilter(const Bit32u useSize) : RingBuffer(useSize) {} + + // This model corresponds to the allpass filter implementation of the real CM-32L device + // found from sample analysis + Sample process(const Sample in) { + const Sample bufferOut = this->next(); + + // store input - feedback / 2 + this->buffer[this->index] = in - halveSample(bufferOut); + + // return buffer output + feedforward / 2 + return bufferOut + halveSample(this->buffer[this->index]); + } +}; + +template +class CombFilter : public RingBuffer { +protected: + const Bit8u filterFactor; + Bit8u feedbackFactor; + +public: + CombFilter(const Bit32u useSize, const Bit8u useFilterFactor) : RingBuffer(useSize), filterFactor(useFilterFactor) {} + + // This model corresponds to the comb filter implementation of the real CM-32L device + void process(const Sample in) { + + // the previously stored value + const Sample last = this->buffer[this->index]; + + // prepare input + feedback + const Sample filterIn = in + weirdMul(this->next(), feedbackFactor, 0xF0); + + // store input + feedback processed by a low-pass filter + this->buffer[this->index] = weirdMul(last, filterFactor, 0xC0) - filterIn; + } + + Sample getOutputAt(const Bit32u outIndex) const { + return this->buffer[(this->size + this->index - outIndex) % this->size]; + } + + void setFeedbackFactor(const Bit8u useFeedbackFactor) { + feedbackFactor = useFeedbackFactor; + } +}; + +template +class DelayWithLowPassFilter : public CombFilter { + Bit8u amp; + +public: + DelayWithLowPassFilter(const Bit32u useSize, const Bit8u useFilterFactor, const Bit8u useAmp) + : CombFilter(useSize, useFilterFactor), amp(useAmp) {} + + void process(const Sample in) { + // the previously stored value + const Sample last = this->buffer[this->index]; + + // move to the next index + this->next(); + + // low-pass filter process + Sample lpfOut = weirdMul(last, this->filterFactor, 0xFF) + in; + + // store lpfOut multiplied by LPF amp factor + this->buffer[this->index] = weirdMul(lpfOut, amp, 0xFF); + } +}; + +template +class TapDelayCombFilter : public CombFilter { + Bit32u outL; + Bit32u outR; + +public: + TapDelayCombFilter(const Bit32u useSize, const Bit8u useFilterFactor) : CombFilter(useSize, useFilterFactor) {} + + void process(const Sample in) { + // the previously stored value + const Sample last = this->buffer[this->index]; + + // move to the next index + this->next(); + + // prepare input + feedback + // Actually, the size of the filter varies with the TIME parameter, the feedback sample is taken from the position just below the right output + const Sample filterIn = in + weirdMul(this->getOutputAt(outR + MODE_3_FEEDBACK_DELAY), this->feedbackFactor, 0xF0); + + // store input + feedback processed by a low-pass filter + this->buffer[this->index] = weirdMul(last, this->filterFactor, 0xF0) - filterIn; + } + + Sample getLeftOutput() const { + return this->getOutputAt(outL + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY); + } + + Sample getRightOutput() const { + return this->getOutputAt(outR + PROCESS_DELAY + MODE_3_ADDITIONAL_DELAY); + } + + void setOutputPositions(const Bit32u useOutL, const Bit32u useOutR) { + outL = useOutL; + outR = useOutR; + } +}; + +template +class BReverbModelImpl : public BReverbModel { +public: + AllpassFilter **allpasses; + CombFilter **combs; + + const BReverbSettings ¤tSettings; + const bool tapDelayMode; + Bit8u dryAmp; + Bit8u wetLevel; + + BReverbModelImpl(const ReverbMode mode, const bool mt32CompatibleModel) : + allpasses(NULL), combs(NULL), + currentSettings(mt32CompatibleModel ? getMT32Settings(mode) : getCM32L_LAPCSettings(mode)), + tapDelayMode(mode == REVERB_MODE_TAP_DELAY) + {} + + ~BReverbModelImpl() { + close(); + } + + bool isOpen() const { + return combs != NULL; + } + + void open() { + if (isOpen()) return; + if (currentSettings.numberOfAllpasses > 0) { + allpasses = new AllpassFilter*[currentSettings.numberOfAllpasses]; + for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { + allpasses[i] = new AllpassFilter(currentSettings.allpassSizes[i]); + } + } + combs = new CombFilter*[currentSettings.numberOfCombs]; + if (tapDelayMode) { + *combs = new TapDelayCombFilter(*currentSettings.combSizes, *currentSettings.filterFactors); + } else { + combs[0] = new DelayWithLowPassFilter(currentSettings.combSizes[0], currentSettings.filterFactors[0], currentSettings.lpfAmp); + for (Bit32u i = 1; i < currentSettings.numberOfCombs; i++) { + combs[i] = new CombFilter(currentSettings.combSizes[i], currentSettings.filterFactors[i]); + } + } + mute(); + } + + void close() { + if (allpasses != NULL) { + for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { + if (allpasses[i] != NULL) { + delete allpasses[i]; + allpasses[i] = NULL; + } + } + delete[] allpasses; + allpasses = NULL; + } + if (combs != NULL) { + for (Bit32u i = 0; i < currentSettings.numberOfCombs; i++) { + if (combs[i] != NULL) { + delete combs[i]; + combs[i] = NULL; + } + } + delete[] combs; + combs = NULL; + } + } + + void mute() { + if (allpasses != NULL) { + for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { + allpasses[i]->mute(); + } + } + if (combs != NULL) { + for (Bit32u i = 0; i < currentSettings.numberOfCombs; i++) { + combs[i]->mute(); + } + } + } + + void setParameters(Bit8u time, Bit8u level) { + if (!isOpen()) return; + level &= 7; + time &= 7; + if (tapDelayMode) { + TapDelayCombFilter *comb = static_cast *> (*combs); + comb->setOutputPositions(currentSettings.outLPositions[time], currentSettings.outRPositions[time & 7]); + comb->setFeedbackFactor(currentSettings.feedbackFactors[((level < 3) || (time < 6)) ? 0 : 1]); + } else { + for (Bit32u i = 1; i < currentSettings.numberOfCombs; i++) { + combs[i]->setFeedbackFactor(currentSettings.feedbackFactors[(i << 3) + time]); + } + } + if (time == 0 && level == 0) { + dryAmp = wetLevel = 0; + } else { + if (tapDelayMode && ((time == 0) || (time == 1 && level == 1))) { + // Looks like MT-32 implementation has some minor quirks in this mode: + // for odd level values, the output level changes sometimes depending on the time value which doesn't seem right. + dryAmp = currentSettings.dryAmps[level + 8]; + } else { + dryAmp = currentSettings.dryAmps[level]; + } + wetLevel = currentSettings.wetLevels[level]; + } + } + + bool isActive() const { + if (!isOpen()) return false; + for (Bit32u i = 0; i < currentSettings.numberOfAllpasses; i++) { + if (!allpasses[i]->isEmpty()) return true; + } + for (Bit32u i = 0; i < currentSettings.numberOfCombs; i++) { + if (!combs[i]->isEmpty()) return true; + } + return false; + } + + bool isMT32Compatible(const ReverbMode mode) const { + return ¤tSettings == &getMT32Settings(mode); + } + + template + void produceOutput(const Sample *inLeft, const Sample *inRight, Sample *outLeft, Sample *outRight, Bit32u numSamples) { + if (!isOpen()) { + Synth::muteSampleBuffer(outLeft, numSamples); + Synth::muteSampleBuffer(outRight, numSamples); + return; + } + + while ((numSamples--) > 0) { + Sample dry; + + if (tapDelayMode) { + dry = halveSample(*(inLeft++)) + halveSample(*(inRight++)); + } else { + dry = quarterSample(*(inLeft++)) + quarterSample(*(inRight++)); + } + + // Looks like dryAmp doesn't change in MT-32 but it does in CM-32L / LAPC-I + dry = weirdMul(addDCBias(dry), dryAmp, 0xFF); + + if (tapDelayMode) { + TapDelayCombFilter *comb = static_cast *>(*combs); + comb->process(dry); + if (outLeft != NULL) { + *(outLeft++) = weirdMul(comb->getLeftOutput(), wetLevel, 0xFF); + } + if (outRight != NULL) { + *(outRight++) = weirdMul(comb->getRightOutput(), wetLevel, 0xFF); + } + } else { + DelayWithLowPassFilter * const entranceDelay = static_cast *>(combs[0]); + // If the output position is equal to the comb size, get it now in order not to loose it + Sample link = entranceDelay->getOutputAt(currentSettings.combSizes[0] - 1); + + // Entrance LPF. Note, comb.process() differs a bit here. + entranceDelay->process(dry); + + link = allpasses[0]->process(addAllpassNoise(link)); + link = allpasses[1]->process(link); + link = allpasses[2]->process(link); + + // If the output position is equal to the comb size, get it now in order not to loose it + Sample outL1 = combs[1]->getOutputAt(currentSettings.outLPositions[0] - 1); + + combs[1]->process(link); + combs[2]->process(link); + combs[3]->process(link); + + if (outLeft != NULL) { + Sample outL2 = combs[2]->getOutputAt(currentSettings.outLPositions[1]); + Sample outL3 = combs[3]->getOutputAt(currentSettings.outLPositions[2]); + Sample outSample = mixCombs(outL1, outL2, outL3); + *(outLeft++) = weirdMul(outSample, wetLevel, 0xFF); + } + if (outRight != NULL) { + Sample outR1 = combs[1]->getOutputAt(currentSettings.outRPositions[0]); + Sample outR2 = combs[2]->getOutputAt(currentSettings.outRPositions[1]); + Sample outR3 = combs[3]->getOutputAt(currentSettings.outRPositions[2]); + Sample outSample = mixCombs(outR1, outR2, outR3); + *(outRight++) = weirdMul(outSample, wetLevel, 0xFF); + } + } // if (tapDelayMode) + } // while ((numSamples--) > 0) + } // produceOutput + + bool process(const IntSample *inLeft, const IntSample *inRight, IntSample *outLeft, IntSample *outRight, Bit32u numSamples); + bool process(const FloatSample *inLeft, const FloatSample *inRight, FloatSample *outLeft, FloatSample *outRight, Bit32u numSamples); +}; + +BReverbModel *BReverbModel::createBReverbModel(const ReverbMode mode, const bool mt32CompatibleModel, const RendererType rendererType) { + switch (rendererType) + { + case RendererType_BIT16S: + return new BReverbModelImpl(mode, mt32CompatibleModel); + case RendererType_FLOAT: + return new BReverbModelImpl(mode, mt32CompatibleModel); + } + return NULL; +} + +template <> +bool BReverbModelImpl::process(const IntSample *inLeft, const IntSample *inRight, IntSample *outLeft, IntSample *outRight, Bit32u numSamples) { + produceOutput(inLeft, inRight, outLeft, outRight, numSamples); + return true; +} + +template <> +bool BReverbModelImpl::process(const FloatSample *, const FloatSample *, FloatSample *, FloatSample *, Bit32u) { + return false; +} + +template <> +bool BReverbModelImpl::process(const IntSample *, const IntSample *, IntSample *, IntSample *, Bit32u) { + return false; +} + +template <> +bool BReverbModelImpl::process(const FloatSample *inLeft, const FloatSample *inRight, FloatSample *outLeft, FloatSample *outRight, Bit32u numSamples) { + produceOutput(inLeft, inRight, outLeft, outRight, numSamples); + return true; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/BReverbModel.h b/src/SOUND/munt/BReverbModel.h new file mode 100644 index 000000000..2d0c5b5ff --- /dev/null +++ b/src/SOUND/munt/BReverbModel.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_B_REVERB_MODEL_H +#define MT32EMU_B_REVERB_MODEL_H + +#include "globals.h" +#include "internals.h" +#include "Enumerations.h" +#include "Types.h" + +namespace MT32Emu { + +class BReverbModel { +public: + static BReverbModel *createBReverbModel(const ReverbMode mode, const bool mt32CompatibleModel, const RendererType rendererType); + + virtual ~BReverbModel() {}; + virtual bool isOpen() const = 0; + // After construction or a close(), open() must be called at least once before any other call (with the exception of close()). + virtual void open() = 0; + // May be called multiple times without an open() in between. + virtual void close() = 0; + virtual void mute() = 0; + virtual void setParameters(Bit8u time, Bit8u level) = 0; + virtual bool isActive() const = 0; + virtual bool isMT32Compatible(const ReverbMode mode) const = 0; + virtual bool process(const IntSample *inLeft, const IntSample *inRight, IntSample *outLeft, IntSample *outRight, Bit32u numSamples) = 0; + virtual bool process(const FloatSample *inLeft, const FloatSample *inRight, FloatSample *outLeft, FloatSample *outRight, Bit32u numSamples) = 0; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_B_REVERB_MODEL_H diff --git a/src/SOUND/munt/Enumerations.h b/src/SOUND/munt/Enumerations.h new file mode 100644 index 000000000..8dad8e88e --- /dev/null +++ b/src/SOUND/munt/Enumerations.h @@ -0,0 +1,188 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/* Using two guards since this file may be included twice with different MT32EMU_C_ENUMERATIONS define. */ + +#if (!defined MT32EMU_CPP_ENUMERATIONS_H && !defined MT32EMU_C_ENUMERATIONS) || (!defined MT32EMU_C_ENUMERATIONS_H && defined MT32EMU_C_ENUMERATIONS) + +#ifdef MT32EMU_C_ENUMERATIONS + +#define MT32EMU_C_ENUMERATIONS_H + +#define MT32EMU_DAC_INPUT_MODE_NAME mt32emu_dac_input_mode +#define MT32EMU_DAC_INPUT_MODE(ident) MT32EMU_DAC_##ident + +#define MT32EMU_MIDI_DELAY_MODE_NAME mt32emu_midi_delay_mode +#define MT32EMU_MIDI_DELAY_MODE(ident) MT32EMU_MDM_##ident + +#define MT32EMU_ANALOG_OUTPUT_MODE_NAME mt32emu_analog_output_mode +#define MT32EMU_ANALOG_OUTPUT_MODE(ident) MT32EMU_AOM_##ident + +#define MT32EMU_PARTIAL_STATE_NAME mt32emu_partial_state +#define MT32EMU_PARTIAL_STATE(ident) MT32EMU_PS_##ident + +#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME mt32emu_samplerate_conversion_quality +#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY(ident) MT32EMU_SRCQ_##ident + +#define MT32EMU_RENDERER_TYPE_NAME mt32emu_renderer_type +#define MT32EMU_RENDERER_TYPE(ident) MT32EMU_RT_##ident + +#else /* #ifdef MT32EMU_C_ENUMERATIONS */ + +#define MT32EMU_CPP_ENUMERATIONS_H + +#define MT32EMU_DAC_INPUT_MODE_NAME DACInputMode +#define MT32EMU_DAC_INPUT_MODE(ident) DACInputMode_##ident + +#define MT32EMU_MIDI_DELAY_MODE_NAME MIDIDelayMode +#define MT32EMU_MIDI_DELAY_MODE(ident) MIDIDelayMode_##ident + +#define MT32EMU_ANALOG_OUTPUT_MODE_NAME AnalogOutputMode +#define MT32EMU_ANALOG_OUTPUT_MODE(ident) AnalogOutputMode_##ident + +#define MT32EMU_PARTIAL_STATE_NAME PartialState +#define MT32EMU_PARTIAL_STATE(ident) PartialState_##ident + +#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME SamplerateConversionQuality +#define MT32EMU_SAMPLERATE_CONVERSION_QUALITY(ident) SamplerateConversionQuality_##ident + +#define MT32EMU_RENDERER_TYPE_NAME RendererType +#define MT32EMU_RENDERER_TYPE(ident) RendererType_##ident + +namespace MT32Emu { + +#endif /* #ifdef MT32EMU_C_ENUMERATIONS */ + +/** + * Methods for emulating the connection between the LA32 and the DAC, which involves + * some hacks in the real devices for doubling the volume. + * See also http://en.wikipedia.org/wiki/Roland_MT-32#Digital_overflow + */ +enum MT32EMU_DAC_INPUT_MODE_NAME { + /** + * Produces samples at double the volume, without tricks. + * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range) + * Higher quality than the real devices + */ + MT32EMU_DAC_INPUT_MODE(NICE), + + /** + * Produces samples that exactly match the bits output from the emulated LA32. + * Nicer overdrive characteristics than the DAC hacks (it simply clips samples within range) + * Much less likely to overdrive than any other mode. + * Half the volume of any of the other modes. + * Output gain is ignored for both LA32 and reverb output. + * Perfect for developers while debugging :) + */ + MT32EMU_DAC_INPUT_MODE(PURE), + + /** + * Re-orders the LA32 output bits as in early generation MT-32s (according to Wikipedia). + * Bit order at DAC (where each number represents the original LA32 output bit number, and XX means the bit is always low): + * 15 13 12 11 10 09 08 07 06 05 04 03 02 01 00 XX + */ + MT32EMU_DAC_INPUT_MODE(GENERATION1), + + /** + * Re-orders the LA32 output bits as in later generations (personally confirmed on my CM-32L - KG). + * Bit order at DAC (where each number represents the original LA32 output bit number): + * 15 13 12 11 10 09 08 07 06 05 04 03 02 01 00 14 + */ + MT32EMU_DAC_INPUT_MODE(GENERATION2) +}; + +/** Methods for emulating the effective delay of incoming MIDI messages introduced by a MIDI interface. */ +enum MT32EMU_MIDI_DELAY_MODE_NAME { + /** Process incoming MIDI events immediately. */ + MT32EMU_MIDI_DELAY_MODE(IMMEDIATE), + + /** + * Delay incoming short MIDI messages as if they where transferred via a MIDI cable to a real hardware unit and immediate sysex processing. + * This ensures more accurate timing of simultaneous NoteOn messages. + */ + MT32EMU_MIDI_DELAY_MODE(DELAY_SHORT_MESSAGES_ONLY), + + /** Delay all incoming MIDI events as if they where transferred via a MIDI cable to a real hardware unit.*/ + MT32EMU_MIDI_DELAY_MODE(DELAY_ALL) +}; + +/** Methods for emulating the effects of analogue circuits of real hardware units on the output signal. */ +enum MT32EMU_ANALOG_OUTPUT_MODE_NAME { + /** Only digital path is emulated. The output samples correspond to the digital signal at the DAC entrance. */ + MT32EMU_ANALOG_OUTPUT_MODE(DIGITAL_ONLY), + /** Coarse emulation of LPF circuit. High frequencies are boosted, sample rate remains unchanged. */ + MT32EMU_ANALOG_OUTPUT_MODE(COARSE), + /** + * Finer emulation of LPF circuit. Output signal is upsampled to 48 kHz to allow emulation of audible mirror spectra above 16 kHz, + * which is passed through the LPF circuit without significant attenuation. + */ + MT32EMU_ANALOG_OUTPUT_MODE(ACCURATE), + /** + * Same as AnalogOutputMode_ACCURATE mode but the output signal is 2x oversampled, i.e. the output sample rate is 96 kHz. + * This makes subsequent resampling easier. Besides, due to nonlinear passband of the LPF emulated, it takes fewer number of MACs + * compared to a regular LPF FIR implementations. + */ + MT32EMU_ANALOG_OUTPUT_MODE(OVERSAMPLED) +}; + +enum MT32EMU_PARTIAL_STATE_NAME { + MT32EMU_PARTIAL_STATE(INACTIVE), + MT32EMU_PARTIAL_STATE(ATTACK), + MT32EMU_PARTIAL_STATE(SUSTAIN), + MT32EMU_PARTIAL_STATE(RELEASE) +}; + +enum MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME { + /** Use this only when the speed is more important than the audio quality. */ + MT32EMU_SAMPLERATE_CONVERSION_QUALITY(FASTEST), + MT32EMU_SAMPLERATE_CONVERSION_QUALITY(FAST), + MT32EMU_SAMPLERATE_CONVERSION_QUALITY(GOOD), + MT32EMU_SAMPLERATE_CONVERSION_QUALITY(BEST) +}; + +enum MT32EMU_RENDERER_TYPE_NAME { + /** Use 16-bit signed samples in the renderer and the accurate wave generator model based on logarithmic fixed-point computations and LUTs. Maximum emulation accuracy and speed. */ + MT32EMU_RENDERER_TYPE(BIT16S), + /** Use float samples in the renderer and simplified wave generator model. Maximum output quality and minimum noise. */ + MT32EMU_RENDERER_TYPE(FLOAT) +}; + +#ifndef MT32EMU_C_ENUMERATIONS + +} // namespace MT32Emu + +#endif + +#undef MT32EMU_DAC_INPUT_MODE_NAME +#undef MT32EMU_DAC_INPUT_MODE + +#undef MT32EMU_MIDI_DELAY_MODE_NAME +#undef MT32EMU_MIDI_DELAY_MODE + +#undef MT32EMU_ANALOG_OUTPUT_MODE_NAME +#undef MT32EMU_ANALOG_OUTPUT_MODE + +#undef MT32EMU_PARTIAL_STATE_NAME +#undef MT32EMU_PARTIAL_STATE + +#undef MT32EMU_SAMPLERATE_CONVERSION_QUALITY_NAME +#undef MT32EMU_SAMPLERATE_CONVERSION_QUALITY + +#undef MT32EMU_RENDERER_TYPE_NAME +#undef MT32EMU_RENDERER_TYPE + +#endif /* #if (!defined MT32EMU_CPP_ENUMERATIONS_H && !defined MT32EMU_C_ENUMERATIONS) || (!defined MT32EMU_C_ENUMERATIONS_H && defined MT32EMU_C_ENUMERATIONS) */ diff --git a/src/SOUND/munt/File.cpp b/src/SOUND/munt/File.cpp new file mode 100644 index 000000000..a5967b4f3 --- /dev/null +++ b/src/SOUND/munt/File.cpp @@ -0,0 +1,77 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "File.h" +#include "sha1/sha1.h" + +namespace MT32Emu { + +AbstractFile::AbstractFile() : sha1DigestCalculated(false) { + sha1Digest[0] = 0; + + reserved = NULL; +} + +AbstractFile::AbstractFile(const SHA1Digest &useSHA1Digest) : sha1DigestCalculated(true) { + memcpy(sha1Digest, useSHA1Digest, sizeof(SHA1Digest) - 1); + sha1Digest[sizeof(SHA1Digest) - 1] = 0; // Ensure terminator char. + + reserved = NULL; +} + +const File::SHA1Digest &AbstractFile::getSHA1() { + if (sha1DigestCalculated) { + return sha1Digest; + } + sha1DigestCalculated = true; + + size_t size = getSize(); + if (size == 0) { + return sha1Digest; + } + + const Bit8u *data = getData(); + if (data == NULL) { + return sha1Digest; + } + + unsigned char fileDigest[20]; + + sha1::calc(data, int(size), fileDigest); + sha1::toHexString(fileDigest, sha1Digest); + return sha1Digest; +} + +ArrayFile::ArrayFile(const Bit8u *useData, size_t useSize) : data(useData), size(useSize) +{} + +ArrayFile::ArrayFile(const Bit8u *useData, size_t useSize, const SHA1Digest &useSHA1Digest) : AbstractFile(useSHA1Digest), data(useData), size(useSize) +{} + +size_t ArrayFile::getSize() { + return size; +} + +const Bit8u *ArrayFile::getData() { + return data; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/File.h b/src/SOUND/munt/File.h new file mode 100644 index 000000000..91a0a7fe6 --- /dev/null +++ b/src/SOUND/munt/File.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_FILE_H +#define MT32EMU_FILE_H + +#include + +#include "globals.h" +#include "Types.h" + +namespace MT32Emu { + +class MT32EMU_EXPORT File { +public: + // Includes terminator char. + typedef char SHA1Digest[41]; + + virtual ~File() {} + virtual size_t getSize() = 0; + virtual const Bit8u *getData() = 0; + virtual const SHA1Digest &getSHA1() = 0; + + virtual void close() = 0; +}; + +class MT32EMU_EXPORT AbstractFile : public File { +public: + const SHA1Digest &getSHA1(); + +protected: + AbstractFile(); + AbstractFile(const SHA1Digest &sha1Digest); + +private: + bool sha1DigestCalculated; + SHA1Digest sha1Digest; + + // Binary compatibility helper. + void *reserved; +}; + +class MT32EMU_EXPORT ArrayFile : public AbstractFile { +public: + ArrayFile(const Bit8u *data, size_t size); + ArrayFile(const Bit8u *data, size_t size, const SHA1Digest &sha1Digest); + + size_t getSize(); + const Bit8u *getData(); + void close() {} + +private: + const Bit8u *data; + size_t size; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_FILE_H diff --git a/src/SOUND/munt/FileStream.cpp b/src/SOUND/munt/FileStream.cpp new file mode 100644 index 000000000..48ecc84b1 --- /dev/null +++ b/src/SOUND/munt/FileStream.cpp @@ -0,0 +1,83 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "internals.h" + +#include "FileStream.h" + +namespace MT32Emu { + +using std::ios_base; + +FileStream::FileStream() : ifsp(*new std::ifstream), data(NULL), size(0) +{} + +FileStream::~FileStream() { + // destructor closes ifsp + delete &ifsp; + delete[] data; +} + +size_t FileStream::getSize() { + if (size != 0) { + return size; + } + if (!ifsp.is_open()) { + return 0; + } + ifsp.seekg(0, ios_base::end); + size = size_t(ifsp.tellg()); + return size; +} + +const Bit8u *FileStream::getData() { + if (data != NULL) { + return data; + } + if (!ifsp.is_open()) { + return NULL; + } + if (getSize() == 0) { + return NULL; + } + Bit8u *fileData = new Bit8u[size]; + if (fileData == NULL) { + return NULL; + } + ifsp.seekg(0); + ifsp.read(reinterpret_cast(fileData), std::streamsize(size)); + if (size_t(ifsp.tellg()) != size) { + delete[] fileData; + return NULL; + } + data = fileData; + close(); + return data; +} + +bool FileStream::open(const char *filename) { + ifsp.clear(); + ifsp.open(filename, ios_base::in | ios_base::binary); + return !ifsp.fail(); +} + +void FileStream::close() { + ifsp.close(); + ifsp.clear(); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/FileStream.h b/src/SOUND/munt/FileStream.h new file mode 100644 index 000000000..ea5de6952 --- /dev/null +++ b/src/SOUND/munt/FileStream.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_FILE_STREAM_H +#define MT32EMU_FILE_STREAM_H + +#include + +#include "globals.h" +#include "Types.h" +#include "File.h" + +namespace MT32Emu { + +class FileStream : public AbstractFile { +public: + MT32EMU_EXPORT FileStream(); + MT32EMU_EXPORT ~FileStream(); + MT32EMU_EXPORT size_t getSize(); + MT32EMU_EXPORT const Bit8u *getData(); + MT32EMU_EXPORT bool open(const char *filename); + MT32EMU_EXPORT void close(); + +private: + std::ifstream &ifsp; + const Bit8u *data; + size_t size; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_FILE_STREAM_H diff --git a/src/SOUND/munt/LA32FloatWaveGenerator.cpp b/src/SOUND/munt/LA32FloatWaveGenerator.cpp new file mode 100644 index 000000000..5cc04fdeb --- /dev/null +++ b/src/SOUND/munt/LA32FloatWaveGenerator.cpp @@ -0,0 +1,360 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "LA32FloatWaveGenerator.h" +#include "mmath.h" +#include "Tables.h" + +namespace MT32Emu { + +static const float MIDDLE_CUTOFF_VALUE = 128.0f; +static const float RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE = 144.0f; +static const float MAX_CUTOFF_VALUE = 240.0f; + +float LA32FloatWaveGenerator::getPCMSample(unsigned int position) { + if (position >= pcmWaveLength) { + if (!pcmWaveLooped) { + return 0; + } + position = position % pcmWaveLength; + } + Bit16s pcmSample = pcmWaveAddress[position]; + float sampleValue = EXP2F(((pcmSample & 32767) - 32787.0f) / 2048.0f); + return ((pcmSample & 32768) == 0) ? sampleValue : -sampleValue; +} + +void LA32FloatWaveGenerator::initSynth(const bool useSawtoothWaveform, const Bit8u usePulseWidth, const Bit8u useResonance) { + sawtoothWaveform = useSawtoothWaveform; + pulseWidth = usePulseWidth; + resonance = useResonance; + + wavePos = 0.0f; + lastFreq = 0.0f; + + pcmWaveAddress = NULL; + active = true; +} + +void LA32FloatWaveGenerator::initPCM(const Bit16s * const usePCMWaveAddress, const Bit32u usePCMWaveLength, const bool usePCMWaveLooped, const bool usePCMWaveInterpolated) { + pcmWaveAddress = usePCMWaveAddress; + pcmWaveLength = usePCMWaveLength; + pcmWaveLooped = usePCMWaveLooped; + pcmWaveInterpolated = usePCMWaveInterpolated; + + pcmPosition = 0.0f; + active = true; +} + +// ampVal - Logarithmic amp of the wave generator +// pitch - Logarithmic frequency of the resulting wave +// cutoffRampVal - Composed of the base cutoff in range [78..178] left-shifted by 18 bits and the TVF modifier +float LA32FloatWaveGenerator::generateNextSample(const Bit32u ampVal, const Bit16u pitch, const Bit32u cutoffRampVal) { + if (!active) { + return 0.0f; + } + + float sample = 0.0f; + + // SEMI-CONFIRMED: From sample analysis: + // (1) Tested with a single partial playing PCM wave 77 with pitchCoarse 36 and no keyfollow, velocity follow, etc. + // This gives results within +/- 2 at the output (before any DAC bitshifting) + // when sustaining at levels 156 - 255 with no modifiers. + // (2) Tested with a special square wave partial (internal capture ID tva5) at TVA envelope levels 155-255. + // This gives deltas between -1 and 0 compared to the real output. Note that this special partial only produces + // positive amps, so negative still needs to be explored, as well as lower levels. + // + // Also still partially unconfirmed is the behaviour when ramping between levels, as well as the timing. + + float amp = EXP2F(ampVal / -1024.0f / 4096.0f); + float freq = EXP2F(pitch / 4096.0f - 16.0f) * SAMPLE_RATE; + + if (isPCMWave()) { + // Render PCM waveform + int len = pcmWaveLength; + int intPCMPosition = int(pcmPosition); + if (intPCMPosition >= len && !pcmWaveLooped) { + // We're now past the end of a non-looping PCM waveform so it's time to die. + deactivate(); + return 0.0f; + } + float positionDelta = freq * 2048.0f / SAMPLE_RATE; + + // Linear interpolation + float firstSample = getPCMSample(intPCMPosition); + // We observe that for partial structures with ring modulation the interpolation is not applied to the slave PCM partial. + // It's assumed that the multiplication circuitry intended to perform the interpolation on the slave PCM partial + // is borrowed by the ring modulation circuit (or the LA32 chip has a similar lack of resources assigned to each partial pair). + if (pcmWaveInterpolated) { + sample = firstSample + (getPCMSample(intPCMPosition + 1) - firstSample) * (pcmPosition - intPCMPosition); + } else { + sample = firstSample; + } + + float newPCMPosition = pcmPosition + positionDelta; + if (pcmWaveLooped) { + newPCMPosition = fmod(newPCMPosition, float(pcmWaveLength)); + } + pcmPosition = newPCMPosition; + } else { + // Render synthesised waveform + wavePos *= lastFreq / freq; + lastFreq = freq; + + float resAmp = EXP2F(1.0f - (32 - resonance) / 4.0f); + { + //static const float resAmpFactor = EXP2F(-7); + //resAmp = EXP2I(resonance << 10) * resAmpFactor; + } + + // The cutoffModifier may not be supposed to be directly added to the cutoff - + // it may for example need to be multiplied in some way. + // The 240 cutoffVal limit was determined via sample analysis (internal Munt capture IDs: glop3, glop4). + // More research is needed to be sure that this is correct, however. + float cutoffVal = cutoffRampVal / 262144.0f; + if (cutoffVal > MAX_CUTOFF_VALUE) { + cutoffVal = MAX_CUTOFF_VALUE; + } + + // Wave length in samples + float waveLen = SAMPLE_RATE / freq; + + // Init cosineLen + float cosineLen = 0.5f * waveLen; + if (cutoffVal > MIDDLE_CUTOFF_VALUE) { + cosineLen *= EXP2F((cutoffVal - MIDDLE_CUTOFF_VALUE) / -16.0f); // found from sample analysis + } + + // Start playing in center of first cosine segment + // relWavePos is shifted by a half of cosineLen + float relWavePos = wavePos + 0.5f * cosineLen; + if (relWavePos > waveLen) { + relWavePos -= waveLen; + } + + // Ratio of positive segment to wave length + float pulseLen = 0.5f; + if (pulseWidth > 128) { + pulseLen = EXP2F((64 - pulseWidth) / 64.0f); + //static const float pulseLenFactor = EXP2F(-192 / 64); + //pulseLen = EXP2I((256 - pulseWidthVal) << 6) * pulseLenFactor; + } + pulseLen *= waveLen; + + float hLen = pulseLen - cosineLen; + + // Ignore pulsewidths too high for given freq + if (hLen < 0.0f) { + hLen = 0.0f; + } + + // Ignore pulsewidths too high for given freq and cutoff + float lLen = waveLen - hLen - 2 * cosineLen; + if (lLen < 0.0f) { + lLen = 0.0f; + } + + // Correct resAmp for cutoff in range 50..66 + if ((cutoffVal >= MIDDLE_CUTOFF_VALUE) && (cutoffVal < RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE)) { + resAmp *= sin(FLOAT_PI * (cutoffVal - MIDDLE_CUTOFF_VALUE) / 32.0f); + } + + // Produce filtered square wave with 2 cosine waves on slopes + + // 1st cosine segment + if (relWavePos < cosineLen) { + sample = -cos(FLOAT_PI * relWavePos / cosineLen); + } else + + // high linear segment + if (relWavePos < (cosineLen + hLen)) { + sample = 1.f; + } else + + // 2nd cosine segment + if (relWavePos < (2 * cosineLen + hLen)) { + sample = cos(FLOAT_PI * (relWavePos - (cosineLen + hLen)) / cosineLen); + } else { + + // low linear segment + sample = -1.f; + } + + if (cutoffVal < MIDDLE_CUTOFF_VALUE) { + + // Attenuate samples below cutoff 50 + // Found by sample analysis + sample *= EXP2F(-0.125f * (MIDDLE_CUTOFF_VALUE - cutoffVal)); + } else { + + // Add resonance sine. Effective for cutoff > 50 only + float resSample = 1.0f; + + // Resonance decay speed factor + float resAmpDecayFactor = Tables::getInstance().resAmpDecayFactor[resonance >> 2]; + + // Now relWavePos counts from the middle of first cosine + relWavePos = wavePos; + + // negative segments + if (!(relWavePos < (cosineLen + hLen))) { + resSample = -resSample; + relWavePos -= cosineLen + hLen; + + // From the digital captures, the decaying speed of the resonance sine is found a bit different for the positive and the negative segments + resAmpDecayFactor += 0.25f; + } + + // Resonance sine WG + resSample *= sin(FLOAT_PI * relWavePos / cosineLen); + + // Resonance sine amp + float resAmpFadeLog2 = -0.125f * resAmpDecayFactor * (relWavePos / cosineLen); // seems to be exact + float resAmpFade = EXP2F(resAmpFadeLog2); + + // Now relWavePos set negative to the left from center of any cosine + relWavePos = wavePos; + + // negative segment + if (!(wavePos < (waveLen - 0.5f * cosineLen))) { + relWavePos -= waveLen; + } else + + // positive segment + if (!(wavePos < (hLen + 0.5f * cosineLen))) { + relWavePos -= cosineLen + hLen; + } + + // To ensure the output wave has no breaks, two different windows are appied to the beginning and the ending of the resonance sine segment + if (relWavePos < 0.5f * cosineLen) { + float syncSine = sin(FLOAT_PI * relWavePos / cosineLen); + if (relWavePos < 0.0f) { + // The window is synchronous square sine here + resAmpFade *= syncSine * syncSine; + } else { + // The window is synchronous sine here + resAmpFade *= syncSine; + } + } + + sample += resSample * resAmp * resAmpFade; + } + + // sawtooth waves + if (sawtoothWaveform) { + sample *= cos(FLOAT_2PI * wavePos / waveLen); + } + + wavePos++; + + // wavePos isn't supposed to be > waveLen + if (wavePos > waveLen) { + wavePos -= waveLen; + } + } + + // Multiply sample with current TVA value + sample *= amp; + return sample; +} + +void LA32FloatWaveGenerator::deactivate() { + active = false; +} + +bool LA32FloatWaveGenerator::isActive() const { + return active; +} + +bool LA32FloatWaveGenerator::isPCMWave() const { + return pcmWaveAddress != NULL; +} + +void LA32FloatPartialPair::init(const bool useRingModulated, const bool useMixed) { + ringModulated = useRingModulated; + mixed = useMixed; + masterOutputSample = 0.0f; + slaveOutputSample = 0.0f; +} + +void LA32FloatPartialPair::initSynth(const PairType useMaster, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance) { + if (useMaster == MASTER) { + master.initSynth(sawtoothWaveform, pulseWidth, resonance); + } else { + slave.initSynth(sawtoothWaveform, pulseWidth, resonance); + } +} + +void LA32FloatPartialPair::initPCM(const PairType useMaster, const Bit16s *pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped) { + if (useMaster == MASTER) { + master.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, true); + } else { + slave.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, !ringModulated); + } +} + +void LA32FloatPartialPair::generateNextSample(const PairType useMaster, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff) { + if (useMaster == MASTER) { + masterOutputSample = master.generateNextSample(amp, pitch, cutoff); + } else { + slaveOutputSample = slave.generateNextSample(amp, pitch, cutoff); + } +} + +static inline float produceDistortedSample(float sample) { + if (sample < -1.0f) { + return sample + 2.0f; + } else if (1.0f < sample) { + return sample - 2.0f; + } + return sample; +} + +float LA32FloatPartialPair::nextOutSample() { + if (!ringModulated) { + return masterOutputSample + slaveOutputSample; + } + /* + * SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion. + * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191. + * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case. + * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space, + * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication. + * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning. + */ + float ringModulatedSample = produceDistortedSample(masterOutputSample) * produceDistortedSample(slaveOutputSample); + return mixed ? masterOutputSample + ringModulatedSample : ringModulatedSample; +} + +void LA32FloatPartialPair::deactivate(const PairType useMaster) { + if (useMaster == MASTER) { + master.deactivate(); + masterOutputSample = 0.0f; + } else { + slave.deactivate(); + slaveOutputSample = 0.0f; + } +} + +bool LA32FloatPartialPair::isActive(const PairType useMaster) const { + return useMaster == MASTER ? master.isActive() : slave.isActive(); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/LA32FloatWaveGenerator.h b/src/SOUND/munt/LA32FloatWaveGenerator.h new file mode 100644 index 000000000..7e92d0a67 --- /dev/null +++ b/src/SOUND/munt/LA32FloatWaveGenerator.h @@ -0,0 +1,132 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_LA32_FLOAT_WAVE_GENERATOR_H +#define MT32EMU_LA32_FLOAT_WAVE_GENERATOR_H + +#include "globals.h" +#include "internals.h" +#include "Types.h" +#include "LA32WaveGenerator.h" + +namespace MT32Emu { + +/** + * LA32WaveGenerator is aimed to represent the exact model of LA32 wave generator. + * The output square wave is created by adding high / low linear segments in-between + * the rising and falling cosine segments. Basically, it's very similar to the phase distortion synthesis. + * Behaviour of a true resonance filter is emulated by adding decaying sine wave. + * The beginning and the ending of the resonant sine is multiplied by a cosine window. + * To synthesise sawtooth waves, the resulting square wave is multiplied by synchronous cosine wave. + */ +class LA32FloatWaveGenerator { + //*************************************************************************** + // The local copy of partial parameters below + //*************************************************************************** + + bool active; + + // True means the resulting square wave is to be multiplied by the synchronous cosine + bool sawtoothWaveform; + + // Values in range [1..31] + // Value 1 correspong to the minimum resonance + Bit8u resonance; + + // Processed value in range [0..255] + // Values in range [0..128] have no effect and the resulting wave remains symmetrical + // Value 255 corresponds to the maximum possible asymmetric of the resulting wave + Bit8u pulseWidth; + + // Logarithmic PCM sample start address + const Bit16s *pcmWaveAddress; + + // Logarithmic PCM sample length + Bit32u pcmWaveLength; + + // true for looped logarithmic PCM samples + bool pcmWaveLooped; + + // false for slave PCM partials in the structures with the ring modulation + bool pcmWaveInterpolated; + + //*************************************************************************** + // Internal variables below + //*************************************************************************** + + float wavePos; + float lastFreq; + float pcmPosition; + + float getPCMSample(unsigned int position); + +public: + // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters + void initSynth(const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); + + // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters + void initPCM(const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped, const bool pcmWaveInterpolated); + + // Update parameters with respect to TVP, TVA and TVF, and generate next sample + float generateNextSample(const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); + + // Deactivate the WG engine + void deactivate(); + + // Return active state of the WG engine + bool isActive() const; + + // Return true if the WG engine generates PCM wave samples + bool isPCMWave() const; +}; // class LA32FloatWaveGenerator + +class LA32FloatPartialPair : public LA32PartialPair { + LA32FloatWaveGenerator master; + LA32FloatWaveGenerator slave; + bool ringModulated; + bool mixed; + float masterOutputSample; + float slaveOutputSample; + +public: + // ringModulated should be set to false for the structures with mixing or stereo output + // ringModulated should be set to true for the structures with ring modulation + // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output + void init(const bool ringModulated, const bool mixed); + + // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters + void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); + + // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters + void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped); + + // Update parameters with respect to TVP, TVA and TVF, and generate next sample + void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); + + // Perform mixing / ring modulation and return the result + float nextOutSample(); + + // Deactivate the WG engine + void deactivate(const PairType master); + + // Return active state of the WG engine + bool isActive(const PairType master) const; +}; // class LA32FloatPartialPair + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_LA32_FLOAT_WAVE_GENERATOR_H diff --git a/src/SOUND/munt/LA32Ramp.cpp b/src/SOUND/munt/LA32Ramp.cpp new file mode 100644 index 000000000..fda38d440 --- /dev/null +++ b/src/SOUND/munt/LA32Ramp.cpp @@ -0,0 +1,155 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/* +Some notes on this class: + +This emulates the LA-32's implementation of "ramps". A ramp in this context is a smooth transition from one value to another, handled entirely within the LA-32. +The LA-32 provides this feature for amplitude and filter cutoff values. + +The 8095 starts ramps on the LA-32 by setting two values in memory-mapped registers: + +(1) The target value (between 0 and 255) for the ramp to end on. This is represented by the "target" argument to startRamp(). +(2) The speed at which that value should be approached. This is represented by the "increment" argument to startRamp(). + +Once the ramp target value has been hit, the LA-32 raises an interrupt. + +Note that the starting point of the ramp is whatever internal value the LA-32 had when the registers were set. This is usually the end point of a previously completed ramp. + +Our handling of the "target" and "increment" values is based on sample analysis and a little guesswork. +Here's what we're pretty confident about: + - The most significant bit of "increment" indicates the direction that the LA32's current internal value ("current" in our emulation) should change in. + Set means downward, clear means upward. + - The lower 7 bits of "increment" indicate how quickly "current" should be changed. + - If "increment" is 0, no change to "current" is made and no interrupt is raised. [SEMI-CONFIRMED by sample analysis] + - Otherwise, if the MSb is set: + - If "current" already corresponds to a value <= "target", "current" is set immediately to the equivalent of "target" and an interrupt is raised. + - Otherwise, "current" is gradually reduced (at a rate determined by the lower 7 bits of "increment"), and once it reaches the equivalent of "target" an interrupt is raised. + - Otherwise (the MSb is unset): + - If "current" already corresponds to a value >= "target", "current" is set immediately to the equivalent of "target" and an interrupt is raised. + - Otherwise, "current" is gradually increased (at a rate determined by the lower 7 bits of "increment"), and once it reaches the equivalent of "target" an interrupt is raised. + +We haven't fully explored: + - Values when ramping between levels (though this is probably correct). + - Transition timing (may not be 100% accurate, especially for very fast ramps). +*/ + +#include "internals.h" + +#include "LA32Ramp.h" +#include "Tables.h" + +namespace MT32Emu { + +// SEMI-CONFIRMED from sample analysis. +const int TARGET_MULT = 0x40000; +const unsigned int MAX_CURRENT = 0xFF * TARGET_MULT; + +// We simulate the delay in handling "target was reached" interrupts by waiting +// this many samples before setting interruptRaised. +// FIXME: This should vary with the sample rate, but doesn't. +// SEMI-CONFIRMED: Since this involves asynchronous activity between the LA32 +// and the 8095, a good value is hard to pin down. +// This one matches observed behaviour on a few digital captures I had handy, +// and should be double-checked. We may also need a more sophisticated delay +// scheme eventually. +const int INTERRUPT_TIME = 7; + +LA32Ramp::LA32Ramp() : + current(0), + largeTarget(0), + largeIncrement(0), + interruptCountdown(0), + interruptRaised(false) { +} + +void LA32Ramp::startRamp(Bit8u target, Bit8u increment) { + // CONFIRMED: From sample analysis, this appears to be very accurate. + if (increment == 0) { + largeIncrement = 0; + } else { + // Three bits in the fractional part, no need to interpolate + // (unsigned int)(EXP2F(((increment & 0x7F) + 24) / 8.0f) + 0.125f) + Bit32u expArg = increment & 0x7F; + largeIncrement = 8191 - Tables::getInstance().exp9[~(expArg << 6) & 511]; + largeIncrement <<= expArg >> 3; + largeIncrement += 64; + largeIncrement >>= 9; + } + descending = (increment & 0x80) != 0; + if (descending) { + // CONFIRMED: From sample analysis, descending increments are slightly faster + largeIncrement++; + } + + largeTarget = target * TARGET_MULT; + interruptCountdown = 0; + interruptRaised = false; +} + +Bit32u LA32Ramp::nextValue() { + if (interruptCountdown > 0) { + if (--interruptCountdown == 0) { + interruptRaised = true; + } + } else if (largeIncrement != 0) { + // CONFIRMED from sample analysis: When increment is 0, the LA32 does *not* change the current value at all (and of course doesn't fire an interrupt). + if (descending) { + // Lowering current value + if (largeIncrement > current) { + current = largeTarget; + interruptCountdown = INTERRUPT_TIME; + } else { + current -= largeIncrement; + if (current <= largeTarget) { + current = largeTarget; + interruptCountdown = INTERRUPT_TIME; + } + } + } else { + // Raising current value + if (MAX_CURRENT - current < largeIncrement) { + current = largeTarget; + interruptCountdown = INTERRUPT_TIME; + } else { + current += largeIncrement; + if (current >= largeTarget) { + current = largeTarget; + interruptCountdown = INTERRUPT_TIME; + } + } + } + } + return current; +} + +bool LA32Ramp::checkInterrupt() { + bool wasRaised = interruptRaised; + interruptRaised = false; + return wasRaised; +} + +void LA32Ramp::reset() { + current = 0; + largeTarget = 0; + largeIncrement = 0; + descending = false; + interruptCountdown = 0; + interruptRaised = false; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/LA32Ramp.h b/src/SOUND/munt/LA32Ramp.h new file mode 100644 index 000000000..25e70c22a --- /dev/null +++ b/src/SOUND/munt/LA32Ramp.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_LA32RAMP_H +#define MT32EMU_LA32RAMP_H + +#include "globals.h" +#include "Types.h" + +namespace MT32Emu { + +class LA32Ramp { +private: + Bit32u current; + unsigned int largeTarget; + unsigned int largeIncrement; + bool descending; + + int interruptCountdown; + bool interruptRaised; + +public: + LA32Ramp(); + void startRamp(Bit8u target, Bit8u increment); + Bit32u nextValue(); + bool checkInterrupt(); + void reset(); +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_LA32RAMP_H diff --git a/src/SOUND/munt/LA32WaveGenerator.cpp b/src/SOUND/munt/LA32WaveGenerator.cpp new file mode 100644 index 000000000..9bdf40610 --- /dev/null +++ b/src/SOUND/munt/LA32WaveGenerator.cpp @@ -0,0 +1,422 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "LA32WaveGenerator.h" +#include "Tables.h" + +namespace MT32Emu { + +static const Bit32u SINE_SEGMENT_RELATIVE_LENGTH = 1 << 18; +static const Bit32u MIDDLE_CUTOFF_VALUE = 128 << 18; +static const Bit32u RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE = 144 << 18; +static const Bit32u MAX_CUTOFF_VALUE = 240 << 18; +static const LogSample SILENCE = {65535, LogSample::POSITIVE}; + +Bit16u LA32Utilites::interpolateExp(const Bit16u fract) { + Bit16u expTabIndex = fract >> 3; + Bit16u extraBits = ~fract & 7; + Bit16u expTabEntry2 = 8191 - Tables::getInstance().exp9[expTabIndex]; + Bit16u expTabEntry1 = expTabIndex == 0 ? 8191 : (8191 - Tables::getInstance().exp9[expTabIndex - 1]); + return expTabEntry2 + (((expTabEntry1 - expTabEntry2) * extraBits) >> 3); +} + +Bit16s LA32Utilites::unlog(const LogSample &logSample) { + //Bit16s sample = (Bit16s)EXP2F(13.0f - logSample.logValue / 1024.0f); + Bit32u intLogValue = logSample.logValue >> 12; + Bit16u fracLogValue = logSample.logValue & 4095; + Bit16s sample = interpolateExp(fracLogValue) >> intLogValue; + return logSample.sign == LogSample::POSITIVE ? sample : -sample; +} + +void LA32Utilites::addLogSamples(LogSample &logSample1, const LogSample &logSample2) { + Bit32u logSampleValue = logSample1.logValue + logSample2.logValue; + logSample1.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; + logSample1.sign = logSample1.sign == logSample2.sign ? LogSample::POSITIVE : LogSample::NEGATIVE; +} + +Bit32u LA32WaveGenerator::getSampleStep() { + // sampleStep = EXP2F(pitch / 4096.0f + 4.0f) + Bit32u sampleStep = LA32Utilites::interpolateExp(~pitch & 4095); + sampleStep <<= pitch >> 12; + sampleStep >>= 8; + sampleStep &= ~1; + return sampleStep; +} + +Bit32u LA32WaveGenerator::getResonanceWaveLengthFactor(Bit32u effectiveCutoffValue) { + // resonanceWaveLengthFactor = (Bit32u)EXP2F(12.0f + effectiveCutoffValue / 4096.0f); + Bit32u resonanceWaveLengthFactor = LA32Utilites::interpolateExp(~effectiveCutoffValue & 4095); + resonanceWaveLengthFactor <<= effectiveCutoffValue >> 12; + return resonanceWaveLengthFactor; +} + +Bit32u LA32WaveGenerator::getHighLinearLength(Bit32u effectiveCutoffValue) { + // Ratio of positive segment to wave length + Bit32u effectivePulseWidthValue = 0; + if (pulseWidth > 128) { + effectivePulseWidthValue = (pulseWidth - 128) << 6; + } + + Bit32u highLinearLength = 0; + // highLinearLength = EXP2F(19.0f - effectivePulseWidthValue / 4096.0f + effectiveCutoffValue / 4096.0f) - 2 * SINE_SEGMENT_RELATIVE_LENGTH; + if (effectivePulseWidthValue < effectiveCutoffValue) { + Bit32u expArg = effectiveCutoffValue - effectivePulseWidthValue; + highLinearLength = LA32Utilites::interpolateExp(~expArg & 4095); + highLinearLength <<= 7 + (expArg >> 12); + highLinearLength -= 2 * SINE_SEGMENT_RELATIVE_LENGTH; + } + return highLinearLength; +} + +void LA32WaveGenerator::computePositions(Bit32u highLinearLength, Bit32u lowLinearLength, Bit32u resonanceWaveLengthFactor) { + // Assuming 12-bit multiplication used here + squareWavePosition = resonanceSinePosition = (wavePosition >> 8) * (resonanceWaveLengthFactor >> 4); + if (squareWavePosition < SINE_SEGMENT_RELATIVE_LENGTH) { + phase = POSITIVE_RISING_SINE_SEGMENT; + return; + } + squareWavePosition -= SINE_SEGMENT_RELATIVE_LENGTH; + if (squareWavePosition < highLinearLength) { + phase = POSITIVE_LINEAR_SEGMENT; + return; + } + squareWavePosition -= highLinearLength; + if (squareWavePosition < SINE_SEGMENT_RELATIVE_LENGTH) { + phase = POSITIVE_FALLING_SINE_SEGMENT; + return; + } + squareWavePosition -= SINE_SEGMENT_RELATIVE_LENGTH; + resonanceSinePosition = squareWavePosition; + if (squareWavePosition < SINE_SEGMENT_RELATIVE_LENGTH) { + phase = NEGATIVE_FALLING_SINE_SEGMENT; + return; + } + squareWavePosition -= SINE_SEGMENT_RELATIVE_LENGTH; + if (squareWavePosition < lowLinearLength) { + phase = NEGATIVE_LINEAR_SEGMENT; + return; + } + squareWavePosition -= lowLinearLength; + phase = NEGATIVE_RISING_SINE_SEGMENT; +} + +void LA32WaveGenerator::advancePosition() { + wavePosition += getSampleStep(); + wavePosition %= 4 * SINE_SEGMENT_RELATIVE_LENGTH; + + Bit32u effectiveCutoffValue = (cutoffVal > MIDDLE_CUTOFF_VALUE) ? (cutoffVal - MIDDLE_CUTOFF_VALUE) >> 10 : 0; + Bit32u resonanceWaveLengthFactor = getResonanceWaveLengthFactor(effectiveCutoffValue); + Bit32u highLinearLength = getHighLinearLength(effectiveCutoffValue); + Bit32u lowLinearLength = (resonanceWaveLengthFactor << 8) - 4 * SINE_SEGMENT_RELATIVE_LENGTH - highLinearLength; + computePositions(highLinearLength, lowLinearLength, resonanceWaveLengthFactor); + + resonancePhase = ResonancePhase(((resonanceSinePosition >> 18) + (phase > POSITIVE_FALLING_SINE_SEGMENT ? 2 : 0)) & 3); +} + +void LA32WaveGenerator::generateNextSquareWaveLogSample() { + Bit32u logSampleValue; + switch (phase) { + case POSITIVE_RISING_SINE_SEGMENT: + case NEGATIVE_FALLING_SINE_SEGMENT: + logSampleValue = Tables::getInstance().logsin9[(squareWavePosition >> 9) & 511]; + break; + case POSITIVE_FALLING_SINE_SEGMENT: + case NEGATIVE_RISING_SINE_SEGMENT: + logSampleValue = Tables::getInstance().logsin9[~(squareWavePosition >> 9) & 511]; + break; + case POSITIVE_LINEAR_SEGMENT: + case NEGATIVE_LINEAR_SEGMENT: + default: + logSampleValue = 0; + break; + } + logSampleValue <<= 2; + logSampleValue += amp >> 10; + if (cutoffVal < MIDDLE_CUTOFF_VALUE) { + logSampleValue += (MIDDLE_CUTOFF_VALUE - cutoffVal) >> 9; + } + + squareLogSample.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; + squareLogSample.sign = phase < NEGATIVE_FALLING_SINE_SEGMENT ? LogSample::POSITIVE : LogSample::NEGATIVE; +} + +void LA32WaveGenerator::generateNextResonanceWaveLogSample() { + Bit32u logSampleValue; + if (resonancePhase == POSITIVE_FALLING_RESONANCE_SINE_SEGMENT || resonancePhase == NEGATIVE_RISING_RESONANCE_SINE_SEGMENT) { + logSampleValue = Tables::getInstance().logsin9[~(resonanceSinePosition >> 9) & 511]; + } else { + logSampleValue = Tables::getInstance().logsin9[(resonanceSinePosition >> 9) & 511]; + } + logSampleValue <<= 2; + logSampleValue += amp >> 10; + + // From the digital captures, the decaying speed of the resonance sine is found a bit different for the positive and the negative segments + Bit32u decayFactor = phase < NEGATIVE_FALLING_SINE_SEGMENT ? resAmpDecayFactor : resAmpDecayFactor + 1; + // Unsure about resonanceSinePosition here. It's possible that dedicated counter & decrement are used. Although, cutoff is finely ramped, so maybe not. + logSampleValue += resonanceAmpSubtraction + (((resonanceSinePosition >> 4) * decayFactor) >> 8); + + // To ensure the output wave has no breaks, two different windows are appied to the beginning and the ending of the resonance sine segment + if (phase == POSITIVE_RISING_SINE_SEGMENT || phase == NEGATIVE_FALLING_SINE_SEGMENT) { + // The window is synchronous sine here + logSampleValue += Tables::getInstance().logsin9[(squareWavePosition >> 9) & 511] << 2; + } else if (phase == POSITIVE_FALLING_SINE_SEGMENT || phase == NEGATIVE_RISING_SINE_SEGMENT) { + // The window is synchronous square sine here + logSampleValue += Tables::getInstance().logsin9[~(squareWavePosition >> 9) & 511] << 3; + } + + if (cutoffVal < MIDDLE_CUTOFF_VALUE) { + // For the cutoff values below the cutoff middle point, it seems the amp of the resonance wave is expotentially decayed + logSampleValue += 31743 + ((MIDDLE_CUTOFF_VALUE - cutoffVal) >> 9); + } else if (cutoffVal < RESONANCE_DECAY_THRESHOLD_CUTOFF_VALUE) { + // For the cutoff values below this point, the amp of the resonance wave is sinusoidally decayed + Bit32u sineIx = (cutoffVal - MIDDLE_CUTOFF_VALUE) >> 13; + logSampleValue += Tables::getInstance().logsin9[sineIx] << 2; + } + + // After all the amp decrements are added, it should be safe now to adjust the amp of the resonance wave to what we see on captures + logSampleValue -= 1 << 12; + + resonanceLogSample.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; + resonanceLogSample.sign = resonancePhase < NEGATIVE_FALLING_RESONANCE_SINE_SEGMENT ? LogSample::POSITIVE : LogSample::NEGATIVE; +} + +void LA32WaveGenerator::generateNextSawtoothCosineLogSample(LogSample &logSample) const { + Bit32u sawtoothCosinePosition = wavePosition + (1 << 18); + if ((sawtoothCosinePosition & (1 << 18)) > 0) { + logSample.logValue = Tables::getInstance().logsin9[~(sawtoothCosinePosition >> 9) & 511]; + } else { + logSample.logValue = Tables::getInstance().logsin9[(sawtoothCosinePosition >> 9) & 511]; + } + logSample.logValue <<= 2; + logSample.sign = ((sawtoothCosinePosition & (1 << 19)) == 0) ? LogSample::POSITIVE : LogSample::NEGATIVE; +} + +void LA32WaveGenerator::pcmSampleToLogSample(LogSample &logSample, const Bit16s pcmSample) const { + Bit32u logSampleValue = (32787 - (pcmSample & 32767)) << 1; + logSampleValue += amp >> 10; + logSample.logValue = logSampleValue < 65536 ? Bit16u(logSampleValue) : 65535; + logSample.sign = pcmSample < 0 ? LogSample::NEGATIVE : LogSample::POSITIVE; +} + +void LA32WaveGenerator::generateNextPCMWaveLogSamples() { + // This should emulate the ladder we see in the PCM captures for pitches 01, 02, 07, etc. + // The most probable cause is the factor in the interpolation formula is one bit less + // accurate than the sample position counter + pcmInterpolationFactor = (wavePosition & 255) >> 1; + Bit32u pcmWaveTableIx = wavePosition >> 8; + pcmSampleToLogSample(firstPCMLogSample, pcmWaveAddress[pcmWaveTableIx]); + if (pcmWaveInterpolated) { + pcmWaveTableIx++; + if (pcmWaveTableIx < pcmWaveLength) { + pcmSampleToLogSample(secondPCMLogSample, pcmWaveAddress[pcmWaveTableIx]); + } else { + if (pcmWaveLooped) { + pcmWaveTableIx -= pcmWaveLength; + pcmSampleToLogSample(secondPCMLogSample, pcmWaveAddress[pcmWaveTableIx]); + } else { + secondPCMLogSample = SILENCE; + } + } + } else { + secondPCMLogSample = SILENCE; + } + // pcmSampleStep = (Bit32u)EXP2F(pitch / 4096.0f + 3.0f); + Bit32u pcmSampleStep = LA32Utilites::interpolateExp(~pitch & 4095); + pcmSampleStep <<= pitch >> 12; + // Seeing the actual lengths of the PCM wave for pitches 00..12, + // the pcmPosition counter can be assumed to have 8-bit fractions + pcmSampleStep >>= 9; + wavePosition += pcmSampleStep; + if (wavePosition >= (pcmWaveLength << 8)) { + if (pcmWaveLooped) { + wavePosition -= pcmWaveLength << 8; + } else { + deactivate(); + } + } +} + +void LA32WaveGenerator::initSynth(const bool useSawtoothWaveform, const Bit8u usePulseWidth, const Bit8u useResonance) { + sawtoothWaveform = useSawtoothWaveform; + pulseWidth = usePulseWidth; + resonance = useResonance; + + wavePosition = 0; + + squareWavePosition = 0; + phase = POSITIVE_RISING_SINE_SEGMENT; + + resonanceSinePosition = 0; + resonancePhase = POSITIVE_RISING_RESONANCE_SINE_SEGMENT; + resonanceAmpSubtraction = (32 - resonance) << 10; + resAmpDecayFactor = Tables::getInstance().resAmpDecayFactor[resonance >> 2] << 2; + + pcmWaveAddress = NULL; + active = true; +} + +void LA32WaveGenerator::initPCM(const Bit16s * const usePCMWaveAddress, const Bit32u usePCMWaveLength, const bool usePCMWaveLooped, const bool usePCMWaveInterpolated) { + pcmWaveAddress = usePCMWaveAddress; + pcmWaveLength = usePCMWaveLength; + pcmWaveLooped = usePCMWaveLooped; + pcmWaveInterpolated = usePCMWaveInterpolated; + + wavePosition = 0; + active = true; +} + +void LA32WaveGenerator::generateNextSample(const Bit32u useAmp, const Bit16u usePitch, const Bit32u useCutoffVal) { + if (!active) { + return; + } + + amp = useAmp; + pitch = usePitch; + + if (isPCMWave()) { + generateNextPCMWaveLogSamples(); + return; + } + + // The 240 cutoffVal limit was determined via sample analysis (internal Munt capture IDs: glop3, glop4). + // More research is needed to be sure that this is correct, however. + cutoffVal = (useCutoffVal > MAX_CUTOFF_VALUE) ? MAX_CUTOFF_VALUE : useCutoffVal; + + generateNextSquareWaveLogSample(); + generateNextResonanceWaveLogSample(); + if (sawtoothWaveform) { + LogSample cosineLogSample; + generateNextSawtoothCosineLogSample(cosineLogSample); + LA32Utilites::addLogSamples(squareLogSample, cosineLogSample); + LA32Utilites::addLogSamples(resonanceLogSample, cosineLogSample); + } + advancePosition(); +} + +LogSample LA32WaveGenerator::getOutputLogSample(const bool first) const { + if (!isActive()) { + return SILENCE; + } + if (isPCMWave()) { + return first ? firstPCMLogSample : secondPCMLogSample; + } + return first ? squareLogSample : resonanceLogSample; +} + +void LA32WaveGenerator::deactivate() { + active = false; +} + +bool LA32WaveGenerator::isActive() const { + return active; +} + +bool LA32WaveGenerator::isPCMWave() const { + return pcmWaveAddress != NULL; +} + +Bit32u LA32WaveGenerator::getPCMInterpolationFactor() const { + return pcmInterpolationFactor; +} + +void LA32IntPartialPair::init(const bool useRingModulated, const bool useMixed) { + ringModulated = useRingModulated; + mixed = useMixed; +} + +void LA32IntPartialPair::initSynth(const PairType useMaster, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance) { + if (useMaster == MASTER) { + master.initSynth(sawtoothWaveform, pulseWidth, resonance); + } else { + slave.initSynth(sawtoothWaveform, pulseWidth, resonance); + } +} + +void LA32IntPartialPair::initPCM(const PairType useMaster, const Bit16s *pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped) { + if (useMaster == MASTER) { + master.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, true); + } else { + slave.initPCM(pcmWaveAddress, pcmWaveLength, pcmWaveLooped, !ringModulated); + } +} + +void LA32IntPartialPair::generateNextSample(const PairType useMaster, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff) { + if (useMaster == MASTER) { + master.generateNextSample(amp, pitch, cutoff); + } else { + slave.generateNextSample(amp, pitch, cutoff); + } +} + +Bit16s LA32IntPartialPair::unlogAndMixWGOutput(const LA32WaveGenerator &wg) { + if (!wg.isActive()) { + return 0; + } + Bit16s firstSample = LA32Utilites::unlog(wg.getOutputLogSample(true)); + Bit16s secondSample = LA32Utilites::unlog(wg.getOutputLogSample(false)); + if (wg.isPCMWave()) { + return Bit16s(firstSample + (((Bit32s(secondSample) - Bit32s(firstSample)) * wg.getPCMInterpolationFactor()) >> 7)); + } + return firstSample + secondSample; +} + +Bit16s LA32IntPartialPair::nextOutSample() { + if (!ringModulated) { + return unlogAndMixWGOutput(master) + unlogAndMixWGOutput(slave); + } + + /* + * SEMI-CONFIRMED: Ring modulation model derived from sample analysis of specially constructed patches which exploit distortion. + * LA32 ring modulator found to produce distorted output in case if the absolute value of maximal amplitude of one of the input partials exceeds 8191. + * This is easy to reproduce using synth partials with resonance values close to the maximum. It looks like an integer overflow happens in this case. + * As the distortion is strictly bound to the amplitude of the complete mixed square + resonance wave in the linear space, + * it is reasonable to assume the ring modulation is performed also in the linear space by sample multiplication. + * Most probably the overflow is caused by limited precision of the multiplication circuit as the very similar distortion occurs with panning. + */ + Bit16s nonOverdrivenMasterSample = unlogAndMixWGOutput(master); // Store master partial sample for further mixing + Bit16s masterSample = nonOverdrivenMasterSample << 2; + masterSample >>= 2; + + /* SEMI-CONFIRMED from sample analysis: + * We observe that for partial structures with ring modulation the interpolation is not applied to the slave PCM partial. + * It's assumed that the multiplication circuitry intended to perform the interpolation on the slave PCM partial + * is borrowed by the ring modulation circuit (or the LA32 chip has a similar lack of resources assigned to each partial pair). + */ + Bit16s slaveSample = slave.isPCMWave() ? LA32Utilites::unlog(slave.getOutputLogSample(true)) : unlogAndMixWGOutput(slave); + slaveSample <<= 2; + slaveSample >>= 2; + Bit16s ringModulatedSample = Bit16s((Bit32s(masterSample) * Bit32s(slaveSample)) >> 13); + return mixed ? nonOverdrivenMasterSample + ringModulatedSample : ringModulatedSample; +} + +void LA32IntPartialPair::deactivate(const PairType useMaster) { + if (useMaster == MASTER) { + master.deactivate(); + } else { + slave.deactivate(); + } +} + +bool LA32IntPartialPair::isActive(const PairType useMaster) const { + return useMaster == MASTER ? master.isActive() : slave.isActive(); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/LA32WaveGenerator.h b/src/SOUND/munt/LA32WaveGenerator.h new file mode 100644 index 000000000..c206daa63 --- /dev/null +++ b/src/SOUND/munt/LA32WaveGenerator.h @@ -0,0 +1,266 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_LA32_WAVE_GENERATOR_H +#define MT32EMU_LA32_WAVE_GENERATOR_H + +#include "globals.h" +#include "internals.h" +#include "Types.h" + +namespace MT32Emu { + +/** + * LA32 performs wave generation in the log-space that allows replacing multiplications by cheap additions + * It's assumed that only low-bit multiplications occur in a few places which are unavoidable like these: + * - interpolation of exponent table (obvious, a delta value has 4 bits) + * - computation of resonance amp decay envelope (the table contains values with 1-2 "1" bits except the very first value 31 but this case can be found using inversion) + * - interpolation of PCM samples (obvious, the wave position counter is in the linear space, there is no log() table in the chip) + * and it seems to be implemented in the same way as in the Boss chip, i.e. right shifted additions which involved noticeable precision loss + * Subtraction is supposed to be replaced by simple inversion + * As the logarithmic sine is always negative, all the logarithmic values are treated as decrements + */ +struct LogSample { + // 16-bit fixed point value, includes 12-bit fractional part + // 4-bit integer part allows to present any 16-bit sample in the log-space + // Obviously, the log value doesn't contain the sign of the resulting sample + Bit16u logValue; + enum { + POSITIVE, + NEGATIVE + } sign; +}; + +class LA32Utilites { +public: + static Bit16u interpolateExp(const Bit16u fract); + static Bit16s unlog(const LogSample &logSample); + static void addLogSamples(LogSample &logSample1, const LogSample &logSample2); +}; + +/** + * LA32WaveGenerator is aimed to represent the exact model of LA32 wave generator. + * The output square wave is created by adding high / low linear segments in-between + * the rising and falling cosine segments. Basically, it's very similar to the phase distortion synthesis. + * Behaviour of a true resonance filter is emulated by adding decaying sine wave. + * The beginning and the ending of the resonant sine is multiplied by a cosine window. + * To synthesise sawtooth waves, the resulting square wave is multiplied by synchronous cosine wave. + */ +class LA32WaveGenerator { + //*************************************************************************** + // The local copy of partial parameters below + //*************************************************************************** + + bool active; + + // True means the resulting square wave is to be multiplied by the synchronous cosine + bool sawtoothWaveform; + + // Logarithmic amp of the wave generator + Bit32u amp; + + // Logarithmic frequency of the resulting wave + Bit16u pitch; + + // Values in range [1..31] + // Value 1 correspong to the minimum resonance + Bit8u resonance; + + // Processed value in range [0..255] + // Values in range [0..128] have no effect and the resulting wave remains symmetrical + // Value 255 corresponds to the maximum possible asymmetric of the resulting wave + Bit8u pulseWidth; + + // Composed of the base cutoff in range [78..178] left-shifted by 18 bits and the TVF modifier + Bit32u cutoffVal; + + // Logarithmic PCM sample start address + const Bit16s *pcmWaveAddress; + + // Logarithmic PCM sample length + Bit32u pcmWaveLength; + + // true for looped logarithmic PCM samples + bool pcmWaveLooped; + + // false for slave PCM partials in the structures with the ring modulation + bool pcmWaveInterpolated; + + //*************************************************************************** + // Internal variables below + //*************************************************************************** + + // Relative position within either the synth wave or the PCM sampled wave + // 0 - start of the positive rising sine segment of the square wave or start of the PCM sample + // 1048576 (2^20) - end of the negative rising sine segment of the square wave + // For PCM waves, the address of the currently playing sample equals (wavePosition / 256) + Bit32u wavePosition; + + // Relative position within a square wave phase: + // 0 - start of the phase + // 262144 (2^18) - end of a sine phase in the square wave + Bit32u squareWavePosition; + + // Relative position within the positive or negative wave segment: + // 0 - start of the corresponding positive or negative segment of the square wave + // 262144 (2^18) - corresponds to end of the first sine phase in the square wave + // The same increment sampleStep is used to indicate the current position + // since the length of the resonance wave is always equal to four square wave sine segments. + Bit32u resonanceSinePosition; + + // The amp of the resonance sine wave grows with the resonance value + // As the resonance value cannot change while the partial is active, it is initialised once + Bit32u resonanceAmpSubtraction; + + // The decay speed of resonance sine wave, depends on the resonance value + Bit32u resAmpDecayFactor; + + // Fractional part of the pcmPosition + Bit32u pcmInterpolationFactor; + + // Current phase of the square wave + enum { + POSITIVE_RISING_SINE_SEGMENT, + POSITIVE_LINEAR_SEGMENT, + POSITIVE_FALLING_SINE_SEGMENT, + NEGATIVE_FALLING_SINE_SEGMENT, + NEGATIVE_LINEAR_SEGMENT, + NEGATIVE_RISING_SINE_SEGMENT + } phase; + + // Current phase of the resonance wave + enum ResonancePhase { + POSITIVE_RISING_RESONANCE_SINE_SEGMENT, + POSITIVE_FALLING_RESONANCE_SINE_SEGMENT, + NEGATIVE_FALLING_RESONANCE_SINE_SEGMENT, + NEGATIVE_RISING_RESONANCE_SINE_SEGMENT + } resonancePhase; + + // Resulting log-space samples of the square and resonance waves + LogSample squareLogSample; + LogSample resonanceLogSample; + + // Processed neighbour log-space samples of the PCM wave + LogSample firstPCMLogSample; + LogSample secondPCMLogSample; + + //*************************************************************************** + // Internal methods below + //*************************************************************************** + + Bit32u getSampleStep(); + Bit32u getResonanceWaveLengthFactor(Bit32u effectiveCutoffValue); + Bit32u getHighLinearLength(Bit32u effectiveCutoffValue); + + void computePositions(Bit32u highLinearLength, Bit32u lowLinearLength, Bit32u resonanceWaveLengthFactor); + void advancePosition(); + + void generateNextSquareWaveLogSample(); + void generateNextResonanceWaveLogSample(); + void generateNextSawtoothCosineLogSample(LogSample &logSample) const; + + void pcmSampleToLogSample(LogSample &logSample, const Bit16s pcmSample) const; + void generateNextPCMWaveLogSamples(); + +public: + // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters + void initSynth(const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); + + // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters + void initPCM(const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped, const bool pcmWaveInterpolated); + + // Update parameters with respect to TVP, TVA and TVF, and generate next sample + void generateNextSample(const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); + + // WG output in the log-space consists of two components which are to be added (or ring modulated) in the linear-space afterwards + LogSample getOutputLogSample(const bool first) const; + + // Deactivate the WG engine + void deactivate(); + + // Return active state of the WG engine + bool isActive() const; + + // Return true if the WG engine generates PCM wave samples + bool isPCMWave() const; + + // Return current PCM interpolation factor + Bit32u getPCMInterpolationFactor() const; +}; // class LA32WaveGenerator + +// LA32PartialPair contains a structure of two partials being mixed / ring modulated +class LA32PartialPair { +public: + enum PairType { + MASTER, + SLAVE + }; + + virtual ~LA32PartialPair() {} + + // ringModulated should be set to false for the structures with mixing or stereo output + // ringModulated should be set to true for the structures with ring modulation + // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output + virtual void init(const bool ringModulated, const bool mixed) = 0; + + // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters + virtual void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance) = 0; + + // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters + virtual void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped) = 0; + + // Deactivate the WG engine + virtual void deactivate(const PairType master) = 0; +}; // class LA32PartialPair + +class LA32IntPartialPair : public LA32PartialPair { + LA32WaveGenerator master; + LA32WaveGenerator slave; + bool ringModulated; + bool mixed; + + static Bit16s unlogAndMixWGOutput(const LA32WaveGenerator &wg); + +public: + // ringModulated should be set to false for the structures with mixing or stereo output + // ringModulated should be set to true for the structures with ring modulation + // mixed is used for the structures with ring modulation and indicates whether the master partial output is mixed to the ring modulator output + void init(const bool ringModulated, const bool mixed); + + // Initialise the WG engine for generation of synth partial samples and set up the invariant parameters + void initSynth(const PairType master, const bool sawtoothWaveform, const Bit8u pulseWidth, const Bit8u resonance); + + // Initialise the WG engine for generation of PCM partial samples and set up the invariant parameters + void initPCM(const PairType master, const Bit16s * const pcmWaveAddress, const Bit32u pcmWaveLength, const bool pcmWaveLooped); + + // Update parameters with respect to TVP, TVA and TVF, and generate next sample + void generateNextSample(const PairType master, const Bit32u amp, const Bit16u pitch, const Bit32u cutoff); + + // Perform mixing / ring modulation of WG output and return the result + // Although, LA32 applies panning itself, we assume it is applied in the mixer, not within a pair + Bit16s nextOutSample(); + + // Deactivate the WG engine + void deactivate(const PairType master); + + // Return active state of the WG engine + bool isActive(const PairType master) const; +}; // class LA32IntPartialPair + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_LA32_WAVE_GENERATOR_H diff --git a/src/SOUND/munt/MemoryRegion.h b/src/SOUND/munt/MemoryRegion.h new file mode 100644 index 000000000..807f14782 --- /dev/null +++ b/src/SOUND/munt/MemoryRegion.h @@ -0,0 +1,132 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_MEMORY_REGION_H +#define MT32EMU_MEMORY_REGION_H + +#include + +#include "globals.h" +#include "Types.h" +#include "Structures.h" + +namespace MT32Emu { + +enum MemoryRegionType { + MR_PatchTemp, MR_RhythmTemp, MR_TimbreTemp, MR_Patches, MR_Timbres, MR_System, MR_Display, MR_Reset +}; + +class Synth; + +class MemoryRegion { +private: + Synth *synth; + Bit8u *realMemory; + Bit8u *maxTable; +public: + MemoryRegionType type; + Bit32u startAddr, entrySize, entries; + + MemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable, MemoryRegionType useType, Bit32u useStartAddr, Bit32u useEntrySize, Bit32u useEntries) { + synth = useSynth; + realMemory = useRealMemory; + maxTable = useMaxTable; + type = useType; + startAddr = useStartAddr; + entrySize = useEntrySize; + entries = useEntries; + } + int lastTouched(Bit32u addr, Bit32u len) const { + return (offset(addr) + len - 1) / entrySize; + } + int firstTouchedOffset(Bit32u addr) const { + return offset(addr) % entrySize; + } + int firstTouched(Bit32u addr) const { + return offset(addr) / entrySize; + } + Bit32u regionEnd() const { + return startAddr + entrySize * entries; + } + bool contains(Bit32u addr) const { + return addr >= startAddr && addr < regionEnd(); + } + int offset(Bit32u addr) const { + return addr - startAddr; + } + Bit32u getClampedLen(Bit32u addr, Bit32u len) const { + if (addr + len > regionEnd()) + return regionEnd() - addr; + return len; + } + Bit32u next(Bit32u addr, Bit32u len) const { + if (addr + len > regionEnd()) { + return regionEnd() - addr; + } + return 0; + } + Bit8u getMaxValue(int off) const { + if (maxTable == NULL) + return 0xFF; + return maxTable[off % entrySize]; + } + Bit8u *getRealMemory() const { + return realMemory; + } + bool isReadable() const { + return getRealMemory() != NULL; + } + void read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const; + void write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init = false) const; +}; // class MemoryRegion + +class PatchTempMemoryRegion : public MemoryRegion { +public: + PatchTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_PatchTemp, MT32EMU_MEMADDR(0x030000), sizeof(MemParams::PatchTemp), 9) {} +}; +class RhythmTempMemoryRegion : public MemoryRegion { +public: + RhythmTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_RhythmTemp, MT32EMU_MEMADDR(0x030110), sizeof(MemParams::RhythmTemp), 85) {} +}; +class TimbreTempMemoryRegion : public MemoryRegion { +public: + TimbreTempMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_TimbreTemp, MT32EMU_MEMADDR(0x040000), sizeof(TimbreParam), 8) {} +}; +class PatchesMemoryRegion : public MemoryRegion { +public: + PatchesMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Patches, MT32EMU_MEMADDR(0x050000), sizeof(PatchParam), 128) {} +}; +class TimbresMemoryRegion : public MemoryRegion { +public: + TimbresMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_Timbres, MT32EMU_MEMADDR(0x080000), sizeof(MemParams::PaddedTimbre), 64 + 64 + 64 + 64) {} +}; +class SystemMemoryRegion : public MemoryRegion { +public: + SystemMemoryRegion(Synth *useSynth, Bit8u *useRealMemory, Bit8u *useMaxTable) : MemoryRegion(useSynth, useRealMemory, useMaxTable, MR_System, MT32EMU_MEMADDR(0x100000), sizeof(MemParams::System), 1) {} +}; +class DisplayMemoryRegion : public MemoryRegion { +public: + DisplayMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Display, MT32EMU_MEMADDR(0x200000), SYSEX_BUFFER_SIZE - 1, 1) {} +}; +class ResetMemoryRegion : public MemoryRegion { +public: + ResetMemoryRegion(Synth *useSynth) : MemoryRegion(useSynth, NULL, NULL, MR_Reset, MT32EMU_MEMADDR(0x7F0000), 0x3FFF, 1) {} +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_MEMORY_REGION_H diff --git a/src/SOUND/munt/MidiEventQueue.h b/src/SOUND/munt/MidiEventQueue.h new file mode 100644 index 000000000..c5174d6cc --- /dev/null +++ b/src/SOUND/munt/MidiEventQueue.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_MIDI_EVENT_QUEUE_H +#define MT32EMU_MIDI_EVENT_QUEUE_H + +#include "globals.h" +#include "Types.h" + +namespace MT32Emu { + +/** + * Used to safely store timestamped MIDI events in a local queue. + */ +struct MidiEvent { + Bit32u shortMessageData; + const Bit8u *sysexData; + Bit32u sysexLength; + Bit32u timestamp; + + ~MidiEvent(); + void setShortMessage(Bit32u shortMessageData, Bit32u timestamp); + void setSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp); +}; + +/** + * Simple queue implementation using a ring buffer to store incoming MIDI event before the synth actually processes it. + * It is intended to: + * - get rid of prerenderer while retaining graceful partial abortion + * - add fair emulation of the MIDI interface delays + * - extend the synth interface with the default implementation of a typical rendering loop. + * THREAD SAFETY: + * It is safe to use either in a single thread environment or when there are only two threads - one performs only reading + * and one performs only writing. More complicated usage requires external synchronisation. + */ +class MidiEventQueue { +private: + MidiEvent * const ringBuffer; + const Bit32u ringBufferMask; + volatile Bit32u startPosition; + volatile Bit32u endPosition; + +public: + MidiEventQueue(Bit32u ringBufferSize = DEFAULT_MIDI_EVENT_QUEUE_SIZE); // Must be a power of 2 + ~MidiEventQueue(); + void reset(); + bool pushShortMessage(Bit32u shortMessageData, Bit32u timestamp); + bool pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp); + const MidiEvent *peekMidiEvent(); + void dropMidiEvent(); + bool isFull() const; + bool inline isEmpty() const; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_MIDI_EVENT_QUEUE_H diff --git a/src/SOUND/munt/MidiStreamParser.cpp b/src/SOUND/munt/MidiStreamParser.cpp new file mode 100644 index 000000000..3a70bec18 --- /dev/null +++ b/src/SOUND/munt/MidiStreamParser.cpp @@ -0,0 +1,289 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "internals.h" + +#include "MidiStreamParser.h" +#include "Synth.h" + +using namespace MT32Emu; + +DefaultMidiStreamParser::DefaultMidiStreamParser(Synth &useSynth, Bit32u initialStreamBufferCapacity) : + MidiStreamParser(initialStreamBufferCapacity), synth(useSynth), timestampSet(false) {} + +void DefaultMidiStreamParser::setTimestamp(const Bit32u useTimestamp) { + timestampSet = true; + timestamp = useTimestamp; +} + +void DefaultMidiStreamParser::resetTimestamp() { + timestampSet = false; +} + +void DefaultMidiStreamParser::handleShortMessage(const Bit32u message) { + do { + if (timestampSet) { + if (synth.playMsg(message, timestamp)) return; + } + else { + if (synth.playMsg(message)) return; + } + } while (synth.reportHandler->onMIDIQueueOverflow()); +} + +void DefaultMidiStreamParser::handleSysex(const Bit8u *stream, const Bit32u length) { + do { + if (timestampSet) { + if (synth.playSysex(stream, length, timestamp)) return; + } + else { + if (synth.playSysex(stream, length)) return; + } + } while (synth.reportHandler->onMIDIQueueOverflow()); +} + +void DefaultMidiStreamParser::handleSystemRealtimeMessage(const Bit8u realtime) { + synth.reportHandler->onMIDISystemRealtime(realtime); +} + +void DefaultMidiStreamParser::printDebug(const char *debugMessage) { + synth.printDebug("%s", debugMessage); +} + +MidiStreamParser::MidiStreamParser(Bit32u initialStreamBufferCapacity) : + MidiStreamParserImpl(*this, *this, initialStreamBufferCapacity) {} + +MidiStreamParserImpl::MidiStreamParserImpl(MidiReceiver &useReceiver, MidiReporter &useReporter, Bit32u initialStreamBufferCapacity) : + midiReceiver(useReceiver), midiReporter(useReporter) +{ + if (initialStreamBufferCapacity < SYSEX_BUFFER_SIZE) initialStreamBufferCapacity = SYSEX_BUFFER_SIZE; + if (MAX_STREAM_BUFFER_SIZE < initialStreamBufferCapacity) initialStreamBufferCapacity = MAX_STREAM_BUFFER_SIZE; + streamBufferCapacity = initialStreamBufferCapacity; + streamBuffer = new Bit8u[streamBufferCapacity]; + streamBufferSize = 0; + runningStatus = 0; + + reserved = NULL; +} + +MidiStreamParserImpl::~MidiStreamParserImpl() { + delete[] streamBuffer; +} + +void MidiStreamParserImpl::parseStream(const Bit8u *stream, Bit32u length) { + while (length > 0) { + Bit32u parsedMessageLength = 0; + if (0xF8 <= *stream) { + // Process System Realtime immediately and go on + midiReceiver.handleSystemRealtimeMessage(*stream); + parsedMessageLength = 1; + // No effect on the running status + } else if (streamBufferSize > 0) { + // Check if there is something in streamBuffer waiting for being processed + if (*streamBuffer == 0xF0) { + parsedMessageLength = parseSysexFragment(stream, length); + } else { + parsedMessageLength = parseShortMessageDataBytes(stream, length); + } + } else { + if (*stream == 0xF0) { + runningStatus = 0; // SysEx clears the running status + parsedMessageLength = parseSysex(stream, length); + } else { + parsedMessageLength = parseShortMessageStatus(stream); + } + } + + // Parsed successfully + stream += parsedMessageLength; + length -= parsedMessageLength; + } +} + +void MidiStreamParserImpl::processShortMessage(const Bit32u message) { + // Adds running status to the MIDI message if it doesn't contain one + Bit8u status = Bit8u(message); + if (0xF8 <= status) { + midiReceiver.handleSystemRealtimeMessage(status); + } else if (processStatusByte(status)) { + midiReceiver.handleShortMessage((message << 8) | status); + } else if (0x80 <= status) { // If no running status available yet, skip this message + midiReceiver.handleShortMessage(message); + } +} + +// We deal with SysEx messages below 512 bytes long in most cases. Nevertheless, it seems reasonable to support a possibility +// to load bulk dumps using a single message. However, this is known to fail with a real device due to limited input buffer size. +bool MidiStreamParserImpl::checkStreamBufferCapacity(const bool preserveContent) { + if (streamBufferSize < streamBufferCapacity) return true; + if (streamBufferCapacity < MAX_STREAM_BUFFER_SIZE) { + Bit8u *oldStreamBuffer = streamBuffer; + streamBufferCapacity = MAX_STREAM_BUFFER_SIZE; + streamBuffer = new Bit8u[streamBufferCapacity]; + if (preserveContent) memcpy(streamBuffer, oldStreamBuffer, streamBufferSize); + delete[] oldStreamBuffer; + return true; + } + return false; +} + +// Checks input byte whether it is a status byte. If not, replaces it with running status when available. +// Returns true if the input byte was changed to running status. +bool MidiStreamParserImpl::processStatusByte(Bit8u &status) { + if (status < 0x80) { + // First byte isn't status, try running status + if (runningStatus < 0x80) { + // No running status available yet + midiReporter.printDebug("processStatusByte: No valid running status yet, MIDI message ignored"); + return false; + } + status = runningStatus; + return true; + } else if (status < 0xF0) { + // Store current status as running for a Voice message + runningStatus = status; + } else if (status < 0xF8) { + // System Common clears running status + runningStatus = 0; + } // System Realtime doesn't affect running status + return false; +} + +// Returns # of bytes parsed +Bit32u MidiStreamParserImpl::parseShortMessageStatus(const Bit8u stream[]) { + Bit8u status = *stream; + Bit32u parsedLength = processStatusByte(status) ? 0 : 1; + if (0x80 <= status) { // If no running status available yet, skip one byte + *streamBuffer = status; + ++streamBufferSize; + } + return parsedLength; +} + +// Returns # of bytes parsed +Bit32u MidiStreamParserImpl::parseShortMessageDataBytes(const Bit8u stream[], Bit32u length) { + const Bit32u shortMessageLength = Synth::getShortMessageLength(*streamBuffer); + Bit32u parsedLength = 0; + + // Append incoming bytes to streamBuffer + while ((streamBufferSize < shortMessageLength) && (length-- > 0)) { + Bit8u dataByte = *(stream++); + if (dataByte < 0x80) { + // Add data byte to streamBuffer + streamBuffer[streamBufferSize++] = dataByte; + } else if (dataByte < 0xF8) { + // Discard invalid bytes and start over + char s[128]; + sprintf(s, "parseShortMessageDataBytes: Invalid short message: status %02x, expected length %i, actual %i -> ignored", *streamBuffer, shortMessageLength, streamBufferSize); + midiReporter.printDebug(s); + streamBufferSize = 0; // Clear streamBuffer + return parsedLength; + } else { + // Bypass System Realtime message + midiReceiver.handleSystemRealtimeMessage(dataByte); + } + ++parsedLength; + } + if (streamBufferSize < shortMessageLength) return parsedLength; // Still lacks data bytes + + // Assemble short message + Bit32u shortMessage = streamBuffer[0]; + for (Bit32u i = 1; i < shortMessageLength; ++i) { + shortMessage |= streamBuffer[i] << (i << 3); + } + midiReceiver.handleShortMessage(shortMessage); + streamBufferSize = 0; // Clear streamBuffer + return parsedLength; +} + +// Returns # of bytes parsed +Bit32u MidiStreamParserImpl::parseSysex(const Bit8u stream[], const Bit32u length) { + // Find SysEx length + Bit32u sysexLength = 1; + while (sysexLength < length) { + Bit8u nextByte = stream[sysexLength++]; + if (0x80 <= nextByte) { + if (nextByte == 0xF7) { + // End of SysEx + midiReceiver.handleSysex(stream, sysexLength); + return sysexLength; + } + if (0xF8 <= nextByte) { + // The System Realtime message must be processed right after return + // but the SysEx is actually fragmented and to be reconstructed in streamBuffer + --sysexLength; + break; + } + // Illegal status byte in SysEx message, aborting + midiReporter.printDebug("parseSysex: SysEx message lacks end-of-sysex (0xf7), ignored"); + // Continue parsing from that point + return sysexLength - 1; + } + } + + // Store incomplete SysEx message for further processing + streamBufferSize = sysexLength; + if (checkStreamBufferCapacity(false)) { + memcpy(streamBuffer, stream, sysexLength); + } else { + // Not enough buffer capacity, don't care about the real buffer content, just mark the first byte + *streamBuffer = *stream; + streamBufferSize = streamBufferCapacity; + } + return sysexLength; +} + +// Returns # of bytes parsed +Bit32u MidiStreamParserImpl::parseSysexFragment(const Bit8u stream[], const Bit32u length) { + Bit32u parsedLength = 0; + while (parsedLength < length) { + Bit8u nextByte = stream[parsedLength++]; + if (nextByte < 0x80) { + // Add SysEx data byte to streamBuffer + if (checkStreamBufferCapacity(true)) streamBuffer[streamBufferSize++] = nextByte; + continue; + } + if (0xF8 <= nextByte) { + // Bypass System Realtime message + midiReceiver.handleSystemRealtimeMessage(nextByte); + continue; + } + if (nextByte != 0xF7) { + // Illegal status byte in SysEx message, aborting + midiReporter.printDebug("parseSysexFragment: SysEx message lacks end-of-sysex (0xf7), ignored"); + // Clear streamBuffer and continue parsing from that point + streamBufferSize = 0; + --parsedLength; + break; + } + // End of SysEx + if (checkStreamBufferCapacity(true)) { + streamBuffer[streamBufferSize++] = nextByte; + midiReceiver.handleSysex(streamBuffer, streamBufferSize); + streamBufferSize = 0; // Clear streamBuffer + break; + } + // Encountered streamBuffer overrun + midiReporter.printDebug("parseSysexFragment: streamBuffer overrun while receiving SysEx message, ignored. Max allowed size of fragmented SysEx is 32768 bytes."); + streamBufferSize = 0; // Clear streamBuffer + break; + } + return parsedLength; +} diff --git a/src/SOUND/munt/MidiStreamParser.h b/src/SOUND/munt/MidiStreamParser.h new file mode 100644 index 000000000..881ec032f --- /dev/null +++ b/src/SOUND/munt/MidiStreamParser.h @@ -0,0 +1,124 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_MIDI_STREAM_PARSER_H +#define MT32EMU_MIDI_STREAM_PARSER_H + +#include "globals.h" +#include "Types.h" + +namespace MT32Emu { + +class Synth; + +// Interface for a user-supplied class to receive parsed well-formed MIDI messages. +class MT32EMU_EXPORT MidiReceiver { +public: + // Invoked when a complete short MIDI message is parsed in the input MIDI stream. + virtual void handleShortMessage(const Bit32u message) = 0; + + // Invoked when a complete well-formed System Exclusive MIDI message is parsed in the input MIDI stream. + virtual void handleSysex(const Bit8u stream[], const Bit32u length) = 0; + + // Invoked when a System Realtime MIDI message is parsed in the input MIDI stream. + virtual void handleSystemRealtimeMessage(const Bit8u realtime) = 0; + +protected: + ~MidiReceiver() {} +}; + +// Interface for a user-supplied class to receive notifications of input MIDI stream parse errors. +class MT32EMU_EXPORT MidiReporter { +public: + // Invoked when an error occurs during processing the input MIDI stream. + virtual void printDebug(const char *debugMessage) = 0; + +protected: + ~MidiReporter() {} +}; + +// Provides a context for parsing a stream of MIDI events coming from a single source. +// There can be multiple MIDI sources feeding MIDI events to a single Synth object. +// NOTE: Calls from multiple threads which feed a single Synth object with data must be explicitly synchronised, +// although, no synchronisation is required with the rendering thread. +class MT32EMU_EXPORT MidiStreamParserImpl { +public: + // The first two arguments provide for implementations of essential interfaces needed. + // The third argument specifies streamBuffer initial capacity. The buffer capacity should be large enough to fit the longest SysEx expected. + // If a longer SysEx occurs, streamBuffer is reallocated to the maximum size of MAX_STREAM_BUFFER_SIZE (32768 bytes). + // Default capacity is SYSEX_BUFFER_SIZE (1000 bytes) which is enough to fit SysEx messages in common use. + MidiStreamParserImpl(MidiReceiver &, MidiReporter &, Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE); + virtual ~MidiStreamParserImpl(); + + // Parses a block of raw MIDI bytes. All the parsed MIDI messages are sent in sequence to the user-supplied methods for further processing. + // SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages. + // NOTE: the total length of a SysEx message being fragmented shall not exceed MAX_STREAM_BUFFER_SIZE (32768 bytes). + void parseStream(const Bit8u *stream, Bit32u length); + + // Convenience method which accepts a Bit32u-encoded short MIDI message and sends it to the user-supplied method for further processing. + // The short MIDI message may contain no status byte, the running status is used in this case. + void processShortMessage(const Bit32u message); + +private: + Bit8u runningStatus; + Bit8u *streamBuffer; + Bit32u streamBufferCapacity; + Bit32u streamBufferSize; + MidiReceiver &midiReceiver; + MidiReporter &midiReporter; + + // Binary compatibility helper. + void *reserved; + + bool checkStreamBufferCapacity(const bool preserveContent); + bool processStatusByte(Bit8u &status); + Bit32u parseShortMessageStatus(const Bit8u stream[]); + Bit32u parseShortMessageDataBytes(const Bit8u stream[], Bit32u length); + Bit32u parseSysex(const Bit8u stream[], const Bit32u length); + Bit32u parseSysexFragment(const Bit8u stream[], const Bit32u length); +}; // class MidiStreamParserImpl + +// An abstract class that provides a context for parsing a stream of MIDI events coming from a single source. +class MT32EMU_EXPORT MidiStreamParser : public MidiStreamParserImpl, protected MidiReceiver, protected MidiReporter { +public: + // The argument specifies streamBuffer initial capacity. The buffer capacity should be large enough to fit the longest SysEx expected. + // If a longer SysEx occurs, streamBuffer is reallocated to the maximum size of MAX_STREAM_BUFFER_SIZE (32768 bytes). + // Default capacity is SYSEX_BUFFER_SIZE (1000 bytes) which is enough to fit SysEx messages in common use. + explicit MidiStreamParser(Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE); +}; + +class MT32EMU_EXPORT DefaultMidiStreamParser : public MidiStreamParser { +public: + explicit DefaultMidiStreamParser(Synth &synth, Bit32u initialStreamBufferCapacity = SYSEX_BUFFER_SIZE); + void setTimestamp(const Bit32u useTimestamp); + void resetTimestamp(); + +protected: + void handleShortMessage(const Bit32u message); + void handleSysex(const Bit8u *stream, const Bit32u length); + void handleSystemRealtimeMessage(const Bit8u realtime); + void printDebug(const char *debugMessage); + +private: + Synth &synth; + bool timestampSet; + Bit32u timestamp; +}; + +} // namespace MT32Emu + +#endif // MT32EMU_MIDI_STREAM_PARSER_H diff --git a/src/SOUND/munt/Part.cpp b/src/SOUND/munt/Part.cpp new file mode 100644 index 000000000..85cc23970 --- /dev/null +++ b/src/SOUND/munt/Part.cpp @@ -0,0 +1,695 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "internals.h" + +#include "Part.h" +#include "Partial.h" +#include "PartialManager.h" +#include "Poly.h" +#include "Synth.h" + +namespace MT32Emu { + +static const Bit8u PartialStruct[13] = { + 0, 0, 2, 2, 1, 3, + 3, 0, 3, 0, 2, 1, 3 +}; + +static const Bit8u PartialMixStruct[13] = { + 0, 1, 0, 1, 1, 0, + 1, 3, 3, 2, 2, 2, 2 +}; + +RhythmPart::RhythmPart(Synth *useSynth, unsigned int usePartNum): Part(useSynth, usePartNum) { + strcpy(name, "Rhythm"); + rhythmTemp = &synth->mt32ram.rhythmTemp[0]; + refresh(); +} + +Part::Part(Synth *useSynth, unsigned int usePartNum) { + synth = useSynth; + partNum = usePartNum; + patchCache[0].dirty = true; + holdpedal = false; + patchTemp = &synth->mt32ram.patchTemp[partNum]; + if (usePartNum == 8) { + // Nasty hack for rhythm + timbreTemp = NULL; + } else { + sprintf(name, "Part %d", partNum + 1); + timbreTemp = &synth->mt32ram.timbreTemp[partNum]; + } + currentInstr[0] = 0; + currentInstr[10] = 0; + modulation = 0; + expression = 100; + pitchBend = 0; + activePartialCount = 0; + memset(patchCache, 0, sizeof(patchCache)); +} + +Part::~Part() { + while (!activePolys.isEmpty()) { + delete activePolys.takeFirst(); + } +} + +void Part::setDataEntryMSB(unsigned char midiDataEntryMSB) { + if (nrpn) { + // The last RPN-related control change was for an NRPN, + // which the real synths don't support. + return; + } + if (rpn != 0) { + // The RPN has been set to something other than 0, + // which is the only RPN that these synths support + return; + } + patchTemp->patch.benderRange = midiDataEntryMSB > 24 ? 24 : midiDataEntryMSB; + updatePitchBenderRange(); +} + +void Part::setNRPN() { + nrpn = true; +} + +void Part::setRPNLSB(unsigned char midiRPNLSB) { + nrpn = false; + rpn = (rpn & 0xFF00) | midiRPNLSB; +} + +void Part::setRPNMSB(unsigned char midiRPNMSB) { + nrpn = false; + rpn = (rpn & 0x00FF) | (midiRPNMSB << 8); +} + +void Part::setHoldPedal(bool pressed) { + if (holdpedal && !pressed) { + holdpedal = false; + stopPedalHold(); + } else { + holdpedal = pressed; + } +} + +Bit32s Part::getPitchBend() const { + return pitchBend; +} + +void Part::setBend(unsigned int midiBend) { + // CONFIRMED: + pitchBend = ((signed(midiBend) - 8192) * pitchBenderRange) >> 14; // PORTABILITY NOTE: Assumes arithmetic shift +} + +Bit8u Part::getModulation() const { + return modulation; +} + +void Part::setModulation(unsigned int midiModulation) { + modulation = Bit8u(midiModulation); +} + +void Part::resetAllControllers() { + modulation = 0; + expression = 100; + pitchBend = 0; + setHoldPedal(false); +} + +void Part::reset() { + resetAllControllers(); + allSoundOff(); + rpn = 0xFFFF; +} + +void RhythmPart::refresh() { + // (Re-)cache all the mapped timbres ahead of time + for (unsigned int drumNum = 0; drumNum < synth->controlROMMap->rhythmSettingsCount; drumNum++) { + int drumTimbreNum = rhythmTemp[drumNum].timbre; + if (drumTimbreNum >= 127) { // 94 on MT-32 + continue; + } + PatchCache *cache = drumCache[drumNum]; + backupCacheToPartials(cache); + for (int t = 0; t < 4; t++) { + // Common parameters, stored redundantly + cache[t].dirty = true; + cache[t].reverb = rhythmTemp[drumNum].reverbSwitch > 0; + } + } + updatePitchBenderRange(); +} + +void Part::refresh() { + backupCacheToPartials(patchCache); + for (int t = 0; t < 4; t++) { + // Common parameters, stored redundantly + patchCache[t].dirty = true; + patchCache[t].reverb = patchTemp->patch.reverbSwitch > 0; + } + memcpy(currentInstr, timbreTemp->common.name, 10); + synth->newTimbreSet(partNum, patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, currentInstr); + updatePitchBenderRange(); +} + +const char *Part::getCurrentInstr() const { + return ¤tInstr[0]; +} + +void RhythmPart::refreshTimbre(unsigned int absTimbreNum) { + for (int m = 0; m < 85; m++) { + if (rhythmTemp[m].timbre == absTimbreNum - 128) { + drumCache[m][0].dirty = true; + } + } +} + +void Part::refreshTimbre(unsigned int absTimbreNum) { + if (getAbsTimbreNum() == absTimbreNum) { + memcpy(currentInstr, timbreTemp->common.name, 10); + patchCache[0].dirty = true; + } +} + +void Part::setPatch(const PatchParam *patch) { + patchTemp->patch = *patch; +} + +void RhythmPart::setTimbre(TimbreParam * /*timbre*/) { + synth->printDebug("%s: Attempted to call setTimbre() - doesn't make sense for rhythm", name); +} + +void Part::setTimbre(TimbreParam *timbre) { + *timbreTemp = *timbre; +} + +unsigned int RhythmPart::getAbsTimbreNum() const { + synth->printDebug("%s: Attempted to call getAbsTimbreNum() - doesn't make sense for rhythm", name); + return 0; +} + +unsigned int Part::getAbsTimbreNum() const { + return (patchTemp->patch.timbreGroup * 64) + patchTemp->patch.timbreNum; +} + +#if MT32EMU_MONITOR_MIDI > 0 +void RhythmPart::setProgram(unsigned int patchNum) { + synth->printDebug("%s: Attempt to set program (%d) on rhythm is invalid", name, patchNum); +} +#else +void RhythmPart::setProgram(unsigned int) { } +#endif + +void Part::setProgram(unsigned int patchNum) { + setPatch(&synth->mt32ram.patches[patchNum]); + holdpedal = false; + allSoundOff(); + setTimbre(&synth->mt32ram.timbres[getAbsTimbreNum()].timbre); + refresh(); +} + +void Part::updatePitchBenderRange() { + pitchBenderRange = patchTemp->patch.benderRange * 683; +} + +void Part::backupCacheToPartials(PatchCache cache[4]) { + // check if any partials are still playing with the old patch cache + // if so then duplicate the cached data from the part to the partial so that + // we can change the part's cache without affecting the partial. + // We delay this until now to avoid a copy operation with every note played + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + poly->backupCacheToPartials(cache); + } +} + +void Part::cacheTimbre(PatchCache cache[4], const TimbreParam *timbre) { + backupCacheToPartials(cache); + int partialCount = 0; + for (int t = 0; t < 4; t++) { + if (((timbre->common.partialMute >> t) & 0x1) == 1) { + cache[t].playPartial = true; + partialCount++; + } else { + cache[t].playPartial = false; + continue; + } + + // Calculate and cache common parameters + cache[t].srcPartial = timbre->partial[t]; + + cache[t].pcm = timbre->partial[t].wg.pcmWave; + + switch (t) { + case 0: + cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure12)] & 0x2) ? true : false; + cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure12)]; + cache[t].structurePosition = 0; + cache[t].structurePair = 1; + break; + case 1: + cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure12)] & 0x1) ? true : false; + cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure12)]; + cache[t].structurePosition = 1; + cache[t].structurePair = 0; + break; + case 2: + cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure34)] & 0x2) ? true : false; + cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure34)]; + cache[t].structurePosition = 0; + cache[t].structurePair = 3; + break; + case 3: + cache[t].PCMPartial = (PartialStruct[int(timbre->common.partialStructure34)] & 0x1) ? true : false; + cache[t].structureMix = PartialMixStruct[int(timbre->common.partialStructure34)]; + cache[t].structurePosition = 1; + cache[t].structurePair = 2; + break; + default: + break; + } + + cache[t].partialParam = &timbre->partial[t]; + + cache[t].waveform = timbre->partial[t].wg.waveform; + } + for (int t = 0; t < 4; t++) { + // Common parameters, stored redundantly + cache[t].dirty = false; + cache[t].partialCount = partialCount; + cache[t].sustain = (timbre->common.noSustain == 0); + } + //synth->printDebug("Res 1: %d 2: %d 3: %d 4: %d", cache[0].waveform, cache[1].waveform, cache[2].waveform, cache[3].waveform); + +#if MT32EMU_MONITOR_INSTRUMENTS > 0 + synth->printDebug("%s (%s): Recached timbre", name, currentInstr); + for (int i = 0; i < 4; i++) { + synth->printDebug(" %d: play=%s, pcm=%s (%d), wave=%d", i, cache[i].playPartial ? "YES" : "NO", cache[i].PCMPartial ? "YES" : "NO", timbre->partial[i].wg.pcmWave, timbre->partial[i].wg.waveform); + } +#endif +} + +const char *Part::getName() const { + return name; +} + +void Part::setVolume(unsigned int midiVolume) { + // CONFIRMED: This calculation matches the table used in the control ROM + patchTemp->outputLevel = Bit8u(midiVolume * 100 / 127); + //synth->printDebug("%s (%s): Set volume to %d", name, currentInstr, midiVolume); +} + +Bit8u Part::getVolume() const { + return patchTemp->outputLevel; +} + +Bit8u Part::getExpression() const { + return expression; +} + +void Part::setExpression(unsigned int midiExpression) { + // CONFIRMED: This calculation matches the table used in the control ROM + expression = Bit8u(midiExpression * 100 / 127); +} + +void RhythmPart::setPan(unsigned int midiPan) { + // CONFIRMED: This does change patchTemp, but has no actual effect on playback. +#if MT32EMU_MONITOR_MIDI > 0 + synth->printDebug("%s: Pointlessly setting pan (%d) on rhythm part", name, midiPan); +#endif + Part::setPan(midiPan); +} + +void Part::setPan(unsigned int midiPan) { + // NOTE: Panning is inverted compared to GM. + + // CM-32L: Divide by 8.5 + patchTemp->panpot = Bit8u((midiPan << 3) / 68); + // FIXME: MT-32: Divide by 9 + //patchTemp->panpot = Bit8u(midiPan / 9); + + //synth->printDebug("%s (%s): Set pan to %d", name, currentInstr, panpot); +} + +/** + * Applies key shift to a MIDI key and converts it into an internal key value in the range 12-108. + */ +unsigned int Part::midiKeyToKey(unsigned int midiKey) { + int key = midiKey + patchTemp->patch.keyShift; + if (key < 36) { + // After keyShift is applied, key < 36, so move up by octaves + while (key < 36) { + key += 12; + } + } else if (key > 132) { + // After keyShift is applied, key > 132, so move down by octaves + while (key > 132) { + key -= 12; + } + } + key -= 24; + return key; +} + +void RhythmPart::noteOn(unsigned int midiKey, unsigned int velocity) { + if (midiKey < 24 || midiKey > 108) { /*> 87 on MT-32)*/ + synth->printDebug("%s: Attempted to play invalid key %d (velocity %d)", name, midiKey, velocity); + return; + } + unsigned int key = midiKey; + unsigned int drumNum = key - 24; + int drumTimbreNum = rhythmTemp[drumNum].timbre; + const int drumTimbreCount = 64 + synth->controlROMMap->timbreRCount; // 94 on MT-32, 128 on LAPC-I/CM32-L + if (drumTimbreNum == 127 || drumTimbreNum >= drumTimbreCount) { // timbre #127 is OFF, no sense to play it + synth->printDebug("%s: Attempted to play unmapped key %d (velocity %d)", name, midiKey, velocity); + return; + } + // CONFIRMED: Two special cases described by Mok + if (drumTimbreNum == 64 + 6) { + noteOff(0); + key = 1; + } else if (drumTimbreNum == 64 + 7) { + // This noteOff(0) is not performed on MT-32, only LAPC-I + noteOff(0); + key = 0; + } + int absTimbreNum = drumTimbreNum + 128; + TimbreParam *timbre = &synth->mt32ram.timbres[absTimbreNum].timbre; + memcpy(currentInstr, timbre->common.name, 10); + if (drumCache[drumNum][0].dirty) { + cacheTimbre(drumCache[drumNum], timbre); + } +#if MT32EMU_MONITOR_INSTRUMENTS > 0 + synth->printDebug("%s (%s): Start poly (drum %d, timbre %d): midiKey %u, key %u, velo %u, mod %u, exp %u, bend %u", name, currentInstr, drumNum, absTimbreNum, midiKey, key, velocity, modulation, expression, pitchBend); +#if MT32EMU_MONITOR_INSTRUMENTS > 1 + // According to info from Mok, keyShift does not appear to affect anything on rhythm part on LAPC-I, but may do on MT-32 - needs investigation + synth->printDebug(" Patch: (timbreGroup %u), (timbreNum %u), (keyShift %u), fineTune %u, benderRange %u, assignMode %u, (reverbSwitch %u)", patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, patchTemp->patch.keyShift, patchTemp->patch.fineTune, patchTemp->patch.benderRange, patchTemp->patch.assignMode, patchTemp->patch.reverbSwitch); + synth->printDebug(" PatchTemp: outputLevel %u, (panpot %u)", patchTemp->outputLevel, patchTemp->panpot); + synth->printDebug(" RhythmTemp: timbre %u, outputLevel %u, panpot %u, reverbSwitch %u", rhythmTemp[drumNum].timbre, rhythmTemp[drumNum].outputLevel, rhythmTemp[drumNum].panpot, rhythmTemp[drumNum].reverbSwitch); +#endif +#endif + playPoly(drumCache[drumNum], &rhythmTemp[drumNum], midiKey, key, velocity); +} + +void Part::noteOn(unsigned int midiKey, unsigned int velocity) { + unsigned int key = midiKeyToKey(midiKey); + if (patchCache[0].dirty) { + cacheTimbre(patchCache, timbreTemp); + } +#if MT32EMU_MONITOR_INSTRUMENTS > 0 + synth->printDebug("%s (%s): Start poly: midiKey %u, key %u, velo %u, mod %u, exp %u, bend %u", name, currentInstr, midiKey, key, velocity, modulation, expression, pitchBend); +#if MT32EMU_MONITOR_INSTRUMENTS > 1 + synth->printDebug(" Patch: timbreGroup %u, timbreNum %u, keyShift %u, fineTune %u, benderRange %u, assignMode %u, reverbSwitch %u", patchTemp->patch.timbreGroup, patchTemp->patch.timbreNum, patchTemp->patch.keyShift, patchTemp->patch.fineTune, patchTemp->patch.benderRange, patchTemp->patch.assignMode, patchTemp->patch.reverbSwitch); + synth->printDebug(" PatchTemp: outputLevel %u, panpot %u", patchTemp->outputLevel, patchTemp->panpot); +#endif +#endif + playPoly(patchCache, NULL, midiKey, key, velocity); +} + +bool Part::abortFirstPoly(unsigned int key) { + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + if (poly->getKey() == key) { + return poly->startAbort(); + } + } + return false; +} + +bool Part::abortFirstPoly(PolyState polyState) { + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + if (poly->getState() == polyState) { + return poly->startAbort(); + } + } + return false; +} + +bool Part::abortFirstPolyPreferHeld() { + if (abortFirstPoly(POLY_Held)) { + return true; + } + return abortFirstPoly(); +} + +bool Part::abortFirstPoly() { + if (activePolys.isEmpty()) { + return false; + } + return activePolys.getFirst()->startAbort(); +} + +void Part::playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity) { + // CONFIRMED: Even in single-assign mode, we don't abort playing polys if the timbre to play is completely muted. + unsigned int needPartials = cache[0].partialCount; + if (needPartials == 0) { + synth->printDebug("%s (%s): Completely muted instrument", name, currentInstr); + return; + } + + if ((patchTemp->patch.assignMode & 2) == 0) { + // Single-assign mode + abortFirstPoly(key); + if (synth->isAbortingPoly()) return; + } + + if (!synth->partialManager->freePartials(needPartials, partNum)) { +#if MT32EMU_MONITOR_PARTIALS > 0 + synth->printDebug("%s (%s): Insufficient free partials to play key %d (velocity %d); needed=%d, free=%d, assignMode=%d", name, currentInstr, midiKey, velocity, needPartials, synth->partialManager->getFreePartialCount(), patchTemp->patch.assignMode); + synth->printPartialUsage(); +#endif + return; + } + if (synth->isAbortingPoly()) return; + + Poly *poly = synth->partialManager->assignPolyToPart(this); + if (poly == NULL) { + synth->printDebug("%s (%s): No free poly to play key %d (velocity %d)", name, currentInstr, midiKey, velocity); + return; + } + if (patchTemp->patch.assignMode & 1) { + // Priority to data first received + activePolys.prepend(poly); + } else { + activePolys.append(poly); + } + + Partial *partials[4]; + for (int x = 0; x < 4; x++) { + if (cache[x].playPartial) { + partials[x] = synth->partialManager->allocPartial(partNum); + activePartialCount++; + } else { + partials[x] = NULL; + } + } + poly->reset(key, velocity, cache[0].sustain, partials); + + for (int x = 0; x < 4; x++) { + if (partials[x] != NULL) { +#if MT32EMU_MONITOR_PARTIALS > 2 + synth->printDebug("%s (%s): Allocated partial %d", name, currentInstr, partials[x]->debugGetPartialNum()); +#endif + partials[x]->startPartial(this, poly, &cache[x], rhythmTemp, partials[cache[x].structurePair]); + } + } +#if MT32EMU_MONITOR_PARTIALS > 1 + synth->printPartialUsage(); +#endif + synth->reportHandler->onPolyStateChanged(Bit8u(partNum)); +} + +void Part::allNotesOff() { + // The MIDI specification states - and Mok confirms - that all notes off (0x7B) + // should treat the hold pedal as usual. + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + // FIXME: This has special handling of key 0 in NoteOff that Mok has not yet confirmed applies to AllNotesOff. + // if (poly->canSustain() || poly->getKey() == 0) { + // FIXME: The real devices are found to be ignoring non-sustaining polys while processing AllNotesOff. Need to be confirmed. + if (poly->canSustain()) { + poly->noteOff(holdpedal); + } + } +} + +void Part::allSoundOff() { + // MIDI "All sound off" (0x78) should release notes immediately regardless of the hold pedal. + // This controller is not actually implemented by the synths, though (according to the docs and Mok) - + // we're only using this method internally. + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + poly->startDecay(); + } +} + +void Part::stopPedalHold() { + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + poly->stopPedalHold(); + } +} + +void RhythmPart::noteOff(unsigned int midiKey) { + stopNote(midiKey); +} + +void Part::noteOff(unsigned int midiKey) { + stopNote(midiKeyToKey(midiKey)); +} + +void Part::stopNote(unsigned int key) { +#if MT32EMU_MONITOR_INSTRUMENTS > 0 + synth->printDebug("%s (%s): stopping key %d", name, currentInstr, key); +#endif + + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + // Generally, non-sustaining instruments ignore note off. They die away eventually anyway. + // Key 0 (only used by special cases on rhythm part) reacts to note off even if non-sustaining or pedal held. + if (poly->getKey() == key && (poly->canSustain() || key == 0)) { + if (poly->noteOff(holdpedal && key != 0)) { + break; + } + } + } +} + +const MemParams::PatchTemp *Part::getPatchTemp() const { + return patchTemp; +} + +unsigned int Part::getActivePartialCount() const { + return activePartialCount; +} + +const Poly *Part::getFirstActivePoly() const { + return activePolys.getFirst(); +} + +unsigned int Part::getActiveNonReleasingPartialCount() const { + unsigned int activeNonReleasingPartialCount = 0; + for (Poly *poly = activePolys.getFirst(); poly != NULL; poly = poly->getNext()) { + if (poly->getState() != POLY_Releasing) { + activeNonReleasingPartialCount += poly->getActivePartialCount(); + } + } + return activeNonReleasingPartialCount; +} + +Synth *Part::getSynth() const { + return synth; +} + +void Part::partialDeactivated(Poly *poly) { + activePartialCount--; + if (!poly->isActive()) { + activePolys.remove(poly); + synth->partialManager->polyFreed(poly); + synth->reportHandler->onPolyStateChanged(Bit8u(partNum)); + } +} + +PolyList::PolyList() : firstPoly(NULL), lastPoly(NULL) {} + +bool PolyList::isEmpty() const { +#ifdef MT32EMU_POLY_LIST_DEBUG + if ((firstPoly == NULL || lastPoly == NULL) && firstPoly != lastPoly) { + printf("PolyList: desynchronised firstPoly & lastPoly pointers\n"); + } +#endif + return firstPoly == NULL && lastPoly == NULL; +} + +Poly *PolyList::getFirst() const { + return firstPoly; +} + +Poly *PolyList::getLast() const { + return lastPoly; +} + +void PolyList::prepend(Poly *poly) { +#ifdef MT32EMU_POLY_LIST_DEBUG + if (poly->getNext() != NULL) { + printf("PolyList: Non-NULL next field in a Poly being prepended is ignored\n"); + } +#endif + poly->setNext(firstPoly); + firstPoly = poly; + if (lastPoly == NULL) { + lastPoly = poly; + } +} + +void PolyList::append(Poly *poly) { +#ifdef MT32EMU_POLY_LIST_DEBUG + if (poly->getNext() != NULL) { + printf("PolyList: Non-NULL next field in a Poly being appended is ignored\n"); + } +#endif + poly->setNext(NULL); + if (lastPoly != NULL) { +#ifdef MT32EMU_POLY_LIST_DEBUG + if (lastPoly->getNext() != NULL) { + printf("PolyList: Non-NULL next field in the lastPoly\n"); + } +#endif + lastPoly->setNext(poly); + } + lastPoly = poly; + if (firstPoly == NULL) { + firstPoly = poly; + } +} + +Poly *PolyList::takeFirst() { + Poly *oldFirst = firstPoly; + firstPoly = oldFirst->getNext(); + if (firstPoly == NULL) { +#ifdef MT32EMU_POLY_LIST_DEBUG + if (lastPoly != oldFirst) { + printf("PolyList: firstPoly != lastPoly in a list with a single Poly\n"); + } +#endif + lastPoly = NULL; + } + oldFirst->setNext(NULL); + return oldFirst; +} + +void PolyList::remove(Poly * const polyToRemove) { + if (polyToRemove == firstPoly) { + takeFirst(); + return; + } + for (Poly *poly = firstPoly; poly != NULL; poly = poly->getNext()) { + if (poly->getNext() == polyToRemove) { + if (polyToRemove == lastPoly) { +#ifdef MT32EMU_POLY_LIST_DEBUG + if (lastPoly->getNext() != NULL) { + printf("PolyList: Non-NULL next field in the lastPoly\n"); + } +#endif + lastPoly = poly; + } + poly->setNext(polyToRemove->getNext()); + polyToRemove->setNext(NULL); + break; + } + } +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/Part.h b/src/SOUND/munt/Part.h new file mode 100644 index 000000000..a4de1060b --- /dev/null +++ b/src/SOUND/munt/Part.h @@ -0,0 +1,153 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_PART_H +#define MT32EMU_PART_H + +#include "globals.h" +#include "internals.h" +#include "Types.h" +#include "Structures.h" + +namespace MT32Emu { + +class Poly; +class Synth; + +class PolyList { +private: + Poly *firstPoly; + Poly *lastPoly; + +public: + PolyList(); + bool isEmpty() const; + Poly *getFirst() const; + Poly *getLast() const; + void prepend(Poly *poly); + void append(Poly *poly); + Poly *takeFirst(); + void remove(Poly * const poly); +}; + +class Part { +private: + // Direct pointer to sysex-addressable memory dedicated to this part (valid for parts 1-8, NULL for rhythm) + TimbreParam *timbreTemp; + + // 0=Part 1, .. 7=Part 8, 8=Rhythm + unsigned int partNum; + + bool holdpedal; + + unsigned int activePartialCount; + PatchCache patchCache[4]; + PolyList activePolys; + + void setPatch(const PatchParam *patch); + unsigned int midiKeyToKey(unsigned int midiKey); + + bool abortFirstPoly(unsigned int key); + +protected: + Synth *synth; + // Direct pointer into sysex-addressable memory + MemParams::PatchTemp *patchTemp; + char name[8]; // "Part 1".."Part 8", "Rhythm" + char currentInstr[11]; + Bit8u modulation; + Bit8u expression; + Bit32s pitchBend; + bool nrpn; + Bit16u rpn; + Bit16u pitchBenderRange; // (patchTemp->patch.benderRange * 683) at the time of the last MIDI program change or MIDI data entry. + + void backupCacheToPartials(PatchCache cache[4]); + void cacheTimbre(PatchCache cache[4], const TimbreParam *timbre); + void playPoly(const PatchCache cache[4], const MemParams::RhythmTemp *rhythmTemp, unsigned int midiKey, unsigned int key, unsigned int velocity); + void stopNote(unsigned int key); + const char *getName() const; + +public: + Part(Synth *synth, unsigned int usePartNum); + virtual ~Part(); + void reset(); + void setDataEntryMSB(unsigned char midiDataEntryMSB); + void setNRPN(); + void setRPNLSB(unsigned char midiRPNLSB); + void setRPNMSB(unsigned char midiRPNMSB); + void resetAllControllers(); + virtual void noteOn(unsigned int midiKey, unsigned int velocity); + virtual void noteOff(unsigned int midiKey); + void allNotesOff(); + void allSoundOff(); + Bit8u getVolume() const; // Internal volume, 0-100, exposed for use by ExternalInterface + void setVolume(unsigned int midiVolume); + Bit8u getModulation() const; + void setModulation(unsigned int midiModulation); + Bit8u getExpression() const; + void setExpression(unsigned int midiExpression); + virtual void setPan(unsigned int midiPan); + Bit32s getPitchBend() const; + void setBend(unsigned int midiBend); + virtual void setProgram(unsigned int midiProgram); + void setHoldPedal(bool pedalval); + void stopPedalHold(); + void updatePitchBenderRange(); + virtual void refresh(); + virtual void refreshTimbre(unsigned int absTimbreNum); + virtual void setTimbre(TimbreParam *timbre); + virtual unsigned int getAbsTimbreNum() const; + const char *getCurrentInstr() const; + const Poly *getFirstActivePoly() const; + unsigned int getActivePartialCount() const; + unsigned int getActiveNonReleasingPartialCount() const; + Synth *getSynth() const; + + const MemParams::PatchTemp *getPatchTemp() const; + + // This should only be called by Poly + void partialDeactivated(Poly *poly); + + // These are rather specialised, and should probably only be used by PartialManager + bool abortFirstPoly(PolyState polyState); + // Abort the first poly in PolyState_HELD, or if none exists, the first active poly in any state. + bool abortFirstPolyPreferHeld(); + bool abortFirstPoly(); +}; // class Part + +class RhythmPart: public Part { + // Pointer to the area of the MT-32's memory dedicated to rhythm + const MemParams::RhythmTemp *rhythmTemp; + + // This caches the timbres/settings in use by the rhythm part + PatchCache drumCache[85][4]; +public: + RhythmPart(Synth *synth, unsigned int usePartNum); + void refresh(); + void refreshTimbre(unsigned int timbreNum); + void setTimbre(TimbreParam *timbre); + void noteOn(unsigned int key, unsigned int velocity); + void noteOff(unsigned int midiKey); + unsigned int getAbsTimbreNum() const; + void setPan(unsigned int midiPan); + void setProgram(unsigned int patchNum); +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_PART_H diff --git a/src/SOUND/munt/Partial.cpp b/src/SOUND/munt/Partial.cpp new file mode 100644 index 000000000..72a3af0ab --- /dev/null +++ b/src/SOUND/munt/Partial.cpp @@ -0,0 +1,403 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "Partial.h" +#include "Part.h" +#include "Poly.h" +#include "Synth.h" +#include "Tables.h" +#include "TVA.h" +#include "TVF.h" +#include "TVP.h" + +namespace MT32Emu { + +static const Bit8u PAN_NUMERATOR_MASTER[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7}; +static const Bit8u PAN_NUMERATOR_SLAVE[] = {0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7}; + +// We assume the pan is applied using the same 13-bit multiplier circuit that is also used for ring modulation +// because of the observed sample overflow, so the panSetting values are likely mapped in a similar way via a LUT. +// FIXME: Sample analysis suggests that the use of panSetting is linear, but there are some quirks that still need to be resolved. +static Bit32s getPANFactor(Bit32s panSetting) { + static const Bit32s PAN_FACTORS_COUNT = 15; + static Bit32s PAN_FACTORS[PAN_FACTORS_COUNT]; + static bool firstRun = true; + + if (firstRun) { + firstRun = false; + for (Bit32u i = 1; i < PAN_FACTORS_COUNT; i++) { + PAN_FACTORS[i] = Bit32s(0.5 + i * 8192.0 / double(PAN_FACTORS_COUNT - 1)); + } + } + return PAN_FACTORS[panSetting]; +} + +Partial::Partial(Synth *useSynth, int useDebugPartialNum) : + synth(useSynth), debugPartialNum(useDebugPartialNum), sampleNum(0), + floatMode(useSynth->getSelectedRendererType() == RendererType_FLOAT) { + // Initialisation of tva, tvp and tvf uses 'this' pointer + // and thus should not be in the initializer list to avoid a compiler warning + tva = new TVA(this, &Ramp); + tvp = new TVP(this); + tvf = new TVF(this, &cutoffModifierRamp); + ownerPart = -1; + poly = NULL; + pair = NULL; + switch (synth->getSelectedRendererType()) { + case RendererType_BIT16S: + la32Pair = new LA32IntPartialPair; + break; + case RendererType_FLOAT: + la32Pair = new LA32FloatPartialPair; + break; + default: + la32Pair = NULL; + } +} + +Partial::~Partial() { + delete la32Pair; + delete tva; + delete tvp; + delete tvf; +} + +// Only used for debugging purposes +int Partial::debugGetPartialNum() const { + return debugPartialNum; +} + +// Only used for debugging purposes +Bit32u Partial::debugGetSampleNum() const { + return sampleNum; +} + +int Partial::getOwnerPart() const { + return ownerPart; +} + +bool Partial::isActive() const { + return ownerPart > -1; +} + +const Poly *Partial::getPoly() const { + return poly; +} + +void Partial::activate(int part) { + // This just marks the partial as being assigned to a part + ownerPart = part; +} + +void Partial::deactivate() { + if (!isActive()) { + return; + } + ownerPart = -1; + if (poly != NULL) { + poly->partialDeactivated(this); + } +#if MT32EMU_MONITOR_PARTIALS > 2 + synth->printDebug("[+%lu] [Partial %d] Deactivated", sampleNum, debugPartialNum); + synth->printPartialUsage(sampleNum); +#endif + if (isRingModulatingSlave()) { + pair->la32Pair->deactivate(LA32PartialPair::SLAVE); + } else { + la32Pair->deactivate(LA32PartialPair::MASTER); + if (hasRingModulatingSlave()) { + pair->deactivate(); + pair = NULL; + } + } + if (pair != NULL) { + pair->pair = NULL; + } +} + +void Partial::startPartial(const Part *part, Poly *usePoly, const PatchCache *usePatchCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial) { + if (usePoly == NULL || usePatchCache == NULL) { + synth->printDebug("[Partial %d] *** Error: Starting partial for owner %d, usePoly=%s, usePatchCache=%s", debugPartialNum, ownerPart, usePoly == NULL ? "*** NULL ***" : "OK", usePatchCache == NULL ? "*** NULL ***" : "OK"); + return; + } + patchCache = usePatchCache; + poly = usePoly; + mixType = patchCache->structureMix; + structurePosition = patchCache->structurePosition; + + Bit8u panSetting = rhythmTemp != NULL ? rhythmTemp->panpot : part->getPatchTemp()->panpot; + if (mixType == 3) { + if (structurePosition == 0) { + panSetting = PAN_NUMERATOR_MASTER[panSetting] << 1; + } else { + panSetting = PAN_NUMERATOR_SLAVE[panSetting] << 1; + } + // Do a normal mix independent of any pair partial. + mixType = 0; + pairPartial = NULL; + } else { + // Mok wanted an option for smoother panning, and we love Mok. +#ifndef INACCURATE_SMOOTH_PAN + // CONFIRMED by Mok: exactly bytes like this (right shifted?) are sent to the LA32. + panSetting &= 0x0E; +#endif + } + + leftPanValue = synth->reversedStereoEnabled ? 14 - panSetting : panSetting; + rightPanValue = 14 - leftPanValue; + + if (!floatMode) { + leftPanValue = getPANFactor(leftPanValue); + rightPanValue = getPANFactor(rightPanValue); + } + + // SEMI-CONFIRMED: From sample analysis: + // Found that timbres with 3 or 4 partials (i.e. one using two partial pairs) are mixed in two different ways. + // Either partial pairs are added or subtracted, it depends on how the partial pairs are allocated. + // It seems that partials are grouped into quarters and if the partial pairs are allocated in different quarters the subtraction happens. + // Though, this matters little for the majority of timbres, it becomes crucial for timbres which contain several partials that sound very close. + // In this case that timbre can sound totally different depending of the way it is mixed up. + // Most easily this effect can be displayed with the help of a special timbre consisting of several identical square wave partials (3 or 4). + // Say, it is 3-partial timbre. Just play any two notes simultaneously and the polys very probably are mixed differently. + // Moreover, the partial allocator retains the last partial assignment it did and all the subsequent notes will sound the same as the last released one. + // The situation is better with 4-partial timbres since then a whole quarter is assigned for each poly. However, if a 3-partial timbre broke the normal + // whole-quarter assignment or after some partials got aborted, even 4-partial timbres can be found sounding differently. + // This behaviour is also confirmed with two more special timbres: one with identical sawtooth partials, and one with PCM wave 02. + // For my personal taste, this behaviour rather enriches the sounding and should be emulated. + // Also, the current partial allocator model probably needs to be refined. + if (debugPartialNum & 8) { + leftPanValue = -leftPanValue; + rightPanValue = -rightPanValue; + } + + if (patchCache->PCMPartial) { + pcmNum = patchCache->pcm; + if (synth->controlROMMap->pcmCount > 128) { + // CM-32L, etc. support two "banks" of PCMs, selectable by waveform type parameter. + if (patchCache->waveform > 1) { + pcmNum += 128; + } + } + pcmWave = &synth->pcmWaves[pcmNum]; + } else { + pcmWave = NULL; + } + + // CONFIRMED: pulseWidthVal calculation is based on information from Mok + pulseWidthVal = (poly->getVelocity() - 64) * (patchCache->srcPartial.wg.pulseWidthVeloSensitivity - 7) + Tables::getInstance().pulseWidth100To255[patchCache->srcPartial.wg.pulseWidth]; + if (pulseWidthVal < 0) { + pulseWidthVal = 0; + } else if (pulseWidthVal > 255) { + pulseWidthVal = 255; + } + + pair = pairPartial; + alreadyOutputed = false; + tva->reset(part, patchCache->partialParam, rhythmTemp); + tvp->reset(part, patchCache->partialParam); + tvf->reset(patchCache->partialParam, tvp->getBasePitch()); + + LA32PartialPair::PairType pairType; + LA32PartialPair *useLA32Pair; + if (isRingModulatingSlave()) { + pairType = LA32PartialPair::SLAVE; + useLA32Pair = pair->la32Pair; + } else { + pairType = LA32PartialPair::MASTER; + la32Pair->init(hasRingModulatingSlave(), mixType == 1); + useLA32Pair = la32Pair; + } + if (isPCM()) { + useLA32Pair->initPCM(pairType, &synth->pcmROMData[pcmWave->addr], pcmWave->len, pcmWave->loop); + } else { + useLA32Pair->initSynth(pairType, (patchCache->waveform & 1) != 0, pulseWidthVal, patchCache->srcPartial.tvf.resonance + 1); + } + if (!hasRingModulatingSlave()) { + la32Pair->deactivate(LA32PartialPair::SLAVE); + } +} + +Bit32u Partial::getAmpValue() { + // SEMI-CONFIRMED: From sample analysis: + // (1) Tested with a single partial playing PCM wave 77 with pitchCoarse 36 and no keyfollow, velocity follow, etc. + // This gives results within +/- 2 at the output (before any DAC bitshifting) + // when sustaining at levels 156 - 255 with no modifiers. + // (2) Tested with a special square wave partial (internal capture ID tva5) at TVA envelope levels 155-255. + // This gives deltas between -1 and 0 compared to the real output. Note that this special partial only produces + // positive amps, so negative still needs to be explored, as well as lower levels. + // + // Also still partially unconfirmed is the behaviour when ramping between levels, as well as the timing. + // TODO: The tests above were performed using the float model, to be refined + Bit32u ampRampVal = 67117056 - ampRamp.nextValue(); + if (ampRamp.checkInterrupt()) { + tva->handleInterrupt(); + } + return ampRampVal; +} + +Bit32u Partial::getCutoffValue() { + if (isPCM()) { + return 0; + } + Bit32u cutoffModifierRampVal = cutoffModifierRamp.nextValue(); + if (cutoffModifierRamp.checkInterrupt()) { + tvf->handleInterrupt(); + } + return (tvf->getBaseCutoff() << 18) + cutoffModifierRampVal; +} + +bool Partial::hasRingModulatingSlave() const { + return pair != NULL && structurePosition == 0 && (mixType == 1 || mixType == 2); +} + +bool Partial::isRingModulatingSlave() const { + return pair != NULL && structurePosition == 1 && (mixType == 1 || mixType == 2); +} + +bool Partial::isPCM() const { + return pcmWave != NULL; +} + +const ControlROMPCMStruct *Partial::getControlROMPCMStruct() const { + if (pcmWave != NULL) { + return pcmWave->controlROMPCMStruct; + } + return NULL; +} + +Synth *Partial::getSynth() const { + return synth; +} + +TVA *Partial::getTVA() const { + return tva; +} + +void Partial::backupCache(const PatchCache &cache) { + if (patchCache == &cache) { + cachebackup = cache; + patchCache = &cachebackup; + } +} + +bool Partial::canProduceOutput() { + if (!isActive() || alreadyOutputed || isRingModulatingSlave()) { + return false; + } + if (poly == NULL) { + synth->printDebug("[Partial %d] *** ERROR: poly is NULL at Partial::produceOutput()!", debugPartialNum); + return false; + } + return true; +} + +template +bool Partial::generateNextSample(LA32PairImpl *la32PairImpl) { + if (!tva->isPlaying() || !la32PairImpl->isActive(LA32PartialPair::MASTER)) { + deactivate(); + return false; + } + la32PairImpl->generateNextSample(LA32PartialPair::MASTER, getAmpValue(), tvp->nextPitch(), getCutoffValue()); + if (hasRingModulatingSlave()) { + la32PairImpl->generateNextSample(LA32PartialPair::SLAVE, pair->getAmpValue(), pair->tvp->nextPitch(), pair->getCutoffValue()); + if (!pair->tva->isPlaying() || !la32PairImpl->isActive(LA32PartialPair::SLAVE)) { + pair->deactivate(); + if (mixType == 2) { + deactivate(); + return false; + } + } + } + return true; +} + +void Partial::produceAndMixSample(IntSample *&leftBuf, IntSample *&rightBuf, LA32IntPartialPair *la32IntPair) { + IntSampleEx sample = la32IntPair->nextOutSample(); + + // FIXME: LA32 may produce distorted sound in case if the absolute value of maximal amplitude of the input exceeds 8191 + // when the panning value is non-zero. Most probably the distortion occurs in the same way it does with ring modulation, + // and it seems to be caused by limited precision of the common multiplication circuit. + // From analysis of this overflow, it is obvious that the right channel output is actually found + // by subtraction of the left channel output from the input. + // Though, it is unknown whether this overflow is exploited somewhere. + + IntSampleEx leftOut = ((sample * leftPanValue) >> 13) + IntSampleEx(*leftBuf); + IntSampleEx rightOut = ((sample * rightPanValue) >> 13) + IntSampleEx(*rightBuf); + *(leftBuf++) = Synth::clipSampleEx(leftOut); + *(rightBuf++) = Synth::clipSampleEx(rightOut); +} + +void Partial::produceAndMixSample(FloatSample *&leftBuf, FloatSample *&rightBuf, LA32FloatPartialPair *la32FloatPair) { + FloatSample sample = la32FloatPair->nextOutSample(); + FloatSample leftOut = (sample * leftPanValue) / 14.0f; + FloatSample rightOut = (sample * rightPanValue) / 14.0f; + *(leftBuf++) += leftOut; + *(rightBuf++) += rightOut; +} + +template +bool Partial::doProduceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length, LA32PairImpl *la32PairImpl) { + if (!canProduceOutput()) return false; + alreadyOutputed = true; + + for (sampleNum = 0; sampleNum < length; sampleNum++) { + if (!generateNextSample(la32PairImpl)) break; + produceAndMixSample(leftBuf, rightBuf, la32PairImpl); + } + sampleNum = 0; + return true; +} + +bool Partial::produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u length) { + if (floatMode) { + synth->printDebug("Partial: Invalid call to produceOutput()!\n", synth->getSelectedRendererType()); + return false; + } + return doProduceOutput(leftBuf, rightBuf, length, static_cast(la32Pair)); +} + +bool Partial::produceOutput(FloatSample *leftBuf, FloatSample *rightBuf, Bit32u length) { + if (!floatMode) { + synth->printDebug("Partial: Invalid call to produceOutput()!\n", synth->getSelectedRendererType()); + return false; + } + return doProduceOutput(leftBuf, rightBuf, length, static_cast(la32Pair)); +} + +bool Partial::shouldReverb() { + if (!isActive()) { + return false; + } + return patchCache->reverb; +} + +void Partial::startAbort() { + // This is called when the partial manager needs to terminate partials for re-use by a new Poly. + tva->startAbort(); +} + +void Partial::startDecayAll() { + tva->startDecay(); + tvp->startDecay(); + tvf->startDecay(); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/Partial.h b/src/SOUND/munt/Partial.h new file mode 100644 index 000000000..bdb65952e --- /dev/null +++ b/src/SOUND/munt/Partial.h @@ -0,0 +1,129 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_PARTIAL_H +#define MT32EMU_PARTIAL_H + +#include "globals.h" +#include "internals.h" +#include "Types.h" +#include "Structures.h" +#include "LA32Ramp.h" +#include "LA32WaveGenerator.h" +#include "LA32FloatWaveGenerator.h" + +namespace MT32Emu { + +class Part; +class Poly; +class Synth; +class TVA; +class TVF; +class TVP; +struct ControlROMPCMStruct; + +// A partial represents one of up to four waveform generators currently playing within a poly. +class Partial { +private: + Synth *synth; + const int debugPartialNum; // Only used for debugging + // Number of the sample currently being rendered by produceOutput(), or 0 if no run is in progress + // This is only kept available for debugging purposes. + Bit32u sampleNum; + + // Actually, this is a 4-bit register but we abuse this to emulate inverted mixing. + // Also we double the value to enable INACCURATE_SMOOTH_PAN, with respect to MoK. + Bit32s leftPanValue, rightPanValue; + + int ownerPart; // -1 if unassigned + int mixType; + int structurePosition; // 0 or 1 of a structure pair + + // Only used for PCM partials + int pcmNum; + // FIXME: Give this a better name (e.g. pcmWaveInfo) + PCMWaveEntry *pcmWave; + + // Final pulse width value, with velfollow applied, matching what is sent to the LA32. + // Range: 0-255 + int pulseWidthVal; + + Poly *poly; + Partial *pair; + + TVA *tva; + TVP *tvp; + TVF *tvf; + + LA32Ramp ampRamp; + LA32Ramp cutoffModifierRamp; + + // TODO: This should be owned by PartialPair + LA32PartialPair *la32Pair; + const bool floatMode; + + const PatchCache *patchCache; + PatchCache cachebackup; + + Bit32u getAmpValue(); + Bit32u getCutoffValue(); + + template + bool doProduceOutput(Sample *leftBuf, Sample *rightBuf, Bit32u length, LA32PairImpl *la32PairImpl); + bool canProduceOutput(); + template + bool generateNextSample(LA32PairImpl *la32PairImpl); + void produceAndMixSample(IntSample *&leftBuf, IntSample *&rightBuf, LA32IntPartialPair *la32IntPair); + void produceAndMixSample(FloatSample *&leftBuf, FloatSample *&rightBuf, LA32FloatPartialPair *la32FloatPair); + +public: + bool alreadyOutputed; + + Partial(Synth *synth, int debugPartialNum); + ~Partial(); + + int debugGetPartialNum() const; + Bit32u debugGetSampleNum() const; + + int getOwnerPart() const; + const Poly *getPoly() const; + bool isActive() const; + void activate(int part); + void deactivate(void); + void startPartial(const Part *part, Poly *usePoly, const PatchCache *useCache, const MemParams::RhythmTemp *rhythmTemp, Partial *pairPartial); + void startAbort(); + void startDecayAll(); + bool shouldReverb(); + bool hasRingModulatingSlave() const; + bool isRingModulatingSlave() const; + bool isPCM() const; + const ControlROMPCMStruct *getControlROMPCMStruct() const; + Synth *getSynth() const; + TVA *getTVA() const; + + void backupCache(const PatchCache &cache); + + // Returns true only if data written to buffer + // These functions produce processed stereo samples + // made from combining this single partial with its pair, if it has one. + bool produceOutput(IntSample *leftBuf, IntSample *rightBuf, Bit32u length); + bool produceOutput(FloatSample *leftBuf, FloatSample *rightBuf, Bit32u length); +}; // class Partial + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_PARTIAL_H diff --git a/src/SOUND/munt/PartialManager.cpp b/src/SOUND/munt/PartialManager.cpp new file mode 100644 index 000000000..6c622a9aa --- /dev/null +++ b/src/SOUND/munt/PartialManager.cpp @@ -0,0 +1,298 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "internals.h" + +#include "PartialManager.h" +#include "Part.h" +#include "Partial.h" +#include "Poly.h" +#include "Synth.h" + +namespace MT32Emu { + +PartialManager::PartialManager(Synth *useSynth, Part **useParts) { + synth = useSynth; + parts = useParts; + partialTable = new Partial *[synth->getPartialCount()]; + freePolys = new Poly *[synth->getPartialCount()]; + firstFreePolyIndex = 0; + for (unsigned int i = 0; i < synth->getPartialCount(); i++) { + partialTable[i] = new Partial(synth, i); + freePolys[i] = new Poly(); + } +} + +PartialManager::~PartialManager(void) { + for (unsigned int i = 0; i < synth->getPartialCount(); i++) { + delete partialTable[i]; + if (freePolys[i] != NULL) delete freePolys[i]; + } + delete[] partialTable; + delete[] freePolys; +} + +void PartialManager::clearAlreadyOutputed() { + for (unsigned int i = 0; i < synth->getPartialCount(); i++) { + partialTable[i]->alreadyOutputed = false; + } +} + +bool PartialManager::shouldReverb(int i) { + return partialTable[i]->shouldReverb(); +} + +bool PartialManager::produceOutput(int i, IntSample *leftBuf, IntSample *rightBuf, Bit32u bufferLength) { + return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength); +} + +bool PartialManager::produceOutput(int i, FloatSample *leftBuf, FloatSample *rightBuf, Bit32u bufferLength) { + return partialTable[i]->produceOutput(leftBuf, rightBuf, bufferLength); +} + +void PartialManager::deactivateAll() { + for (unsigned int i = 0; i < synth->getPartialCount(); i++) { + partialTable[i]->deactivate(); + } +} + +unsigned int PartialManager::setReserve(Bit8u *rset) { + unsigned int pr = 0; + for (int x = 0; x <= 8; x++) { + numReservedPartialsForPart[x] = rset[x]; + pr += rset[x]; + } + return pr; +} + +Partial *PartialManager::allocPartial(int partNum) { + Partial *outPartial = NULL; + + // Get the first inactive partial + for (unsigned int partialNum = 0; partialNum < synth->getPartialCount(); partialNum++) { + if (!partialTable[partialNum]->isActive()) { + outPartial = partialTable[partialNum]; + break; + } + } + if (outPartial != NULL) { + outPartial->activate(partNum); + } + return outPartial; +} + +unsigned int PartialManager::getFreePartialCount(void) { + int count = 0; + for (unsigned int i = 0; i < synth->getPartialCount(); i++) { + if (!partialTable[i]->isActive()) { + count++; + } + } + return count; +} + +// This function is solely used to gather data for debug output at the moment. +void PartialManager::getPerPartPartialUsage(unsigned int perPartPartialUsage[9]) { + memset(perPartPartialUsage, 0, 9 * sizeof(unsigned int)); + for (unsigned int i = 0; i < synth->getPartialCount(); i++) { + if (partialTable[i]->isActive()) { + perPartPartialUsage[partialTable[i]->getOwnerPart()]++; + } + } +} + +// Finds the lowest-priority part that is exceeding its reserved partial allocation and has a poly +// in POLY_Releasing, then kills its first releasing poly. +// Parts with higher priority than minPart are not checked. +// Assumes that getFreePartials() has been called to make numReservedPartialsForPart up-to-date. +bool PartialManager::abortFirstReleasingPolyWhereReserveExceeded(int minPart) { + if (minPart == 8) { + // Rhythm is highest priority + minPart = -1; + } + for (int partNum = 7; partNum >= minPart; partNum--) { + int usePartNum = partNum == -1 ? 8 : partNum; + if (parts[usePartNum]->getActivePartialCount() > numReservedPartialsForPart[usePartNum]) { + // This part has exceeded its reserved partial count. + // If it has any releasing polys, kill its first one and we're done. + if (parts[usePartNum]->abortFirstPoly(POLY_Releasing)) { + return true; + } + } + } + return false; +} + +// Finds the lowest-priority part that is exceeding its reserved partial allocation and has a poly, then kills +// its first poly in POLY_Held - or failing that, its first poly in any state. +// Parts with higher priority than minPart are not checked. +// Assumes that getFreePartials() has been called to make numReservedPartialsForPart up-to-date. +bool PartialManager::abortFirstPolyPreferHeldWhereReserveExceeded(int minPart) { + if (minPart == 8) { + // Rhythm is highest priority + minPart = -1; + } + for (int partNum = 7; partNum >= minPart; partNum--) { + int usePartNum = partNum == -1 ? 8 : partNum; + if (parts[usePartNum]->getActivePartialCount() > numReservedPartialsForPart[usePartNum]) { + // This part has exceeded its reserved partial count. + // If it has any polys, kill its first (preferably held) one and we're done. + if (parts[usePartNum]->abortFirstPolyPreferHeld()) { + return true; + } + } + } + return false; +} + +bool PartialManager::freePartials(unsigned int needed, int partNum) { + // CONFIRMED: Barring bugs, this matches the real LAPC-I according to information from Mok. + + // BUG: There's a bug in the LAPC-I implementation: + // When allocating for rhythm part, or when allocating for a part that is using fewer partials than it has reserved, + // held and playing polys on the rhythm part can potentially be aborted before releasing polys on the rhythm part. + // This bug isn't present on MT-32. + // I consider this to be a bug because I think that playing polys should always have priority over held polys, + // and held polys should always have priority over releasing polys. + + // NOTE: This code generally aborts polys in parts (according to certain conditions) in the following order: + // 7, 6, 5, 4, 3, 2, 1, 0, 8 (rhythm) + // (from lowest priority, meaning most likely to have polys aborted, to highest priority, meaning least likely) + + if (needed == 0) { + return true; + } + + // Note that calling getFreePartialCount() also ensures that numReservedPartialsPerPart is up-to-date + if (getFreePartialCount() >= needed) { + return true; + } + + // Note: These #ifdefs are temporary until we have proper "quirk" configuration. + // Also, the MT-32 version isn't properly confirmed yet. +#ifdef MT32EMU_QUIRK_FREE_PARTIALS_MT32 + // On MT-32, we bail out before even killing releasing partials if the allocating part has exceeded its reserve and is configured for priority-to-earlier-polys. + if (parts[partNum]->getActiveNonReleasingPartialCount() + needed > numReservedPartialsForPart[partNum] && (synth->getPart(partNum)->getPatchTemp()->patch.assignMode & 1)) { + return false; + } +#endif + + for (;;) { +#ifdef MT32EMU_QUIRK_FREE_PARTIALS_MT32 + // Abort releasing polys in parts that have exceeded their partial reservation (working backwards from part 7, with rhythm last) + if (!abortFirstReleasingPolyWhereReserveExceeded(-1)) { + break; + } +#else + // Abort releasing polys in non-rhythm parts that have exceeded their partial reservation (working backwards from part 7) + if (!abortFirstReleasingPolyWhereReserveExceeded(0)) { + break; + } +#endif + if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { + return true; + } + } + + if (parts[partNum]->getActiveNonReleasingPartialCount() + needed > numReservedPartialsForPart[partNum]) { + // With the new partials we're freeing for, we would end up using more partials than we have reserved. + if (synth->getPart(partNum)->getPatchTemp()->patch.assignMode & 1) { + // Priority is given to earlier polys, so just give up + return false; + } + // Only abort held polys in the target part and parts that have a lower priority + // (higher part number = lower priority, except for rhythm, which has the highest priority). + for (;;) { + if (!abortFirstPolyPreferHeldWhereReserveExceeded(partNum)) { + break; + } + if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { + return true; + } + } + if (needed > numReservedPartialsForPart[partNum]) { + return false; + } + } else { + // At this point, we're certain that we've reserved enough partials to play our poly. + // Check all parts from lowest to highest priority to see whether they've exceeded their + // reserve, and abort their polys until until we have enough free partials or they're within + // their reserve allocation. + for (;;) { + if (!abortFirstPolyPreferHeldWhereReserveExceeded(-1)) { + break; + } + if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { + return true; + } + } + } + + // Abort polys in the target part until there are enough free partials for the new one + for (;;) { + if (!parts[partNum]->abortFirstPolyPreferHeld()) { + break; + } + if (synth->isAbortingPoly() || getFreePartialCount() >= needed) { + return true; + } + } + + // Aww, not enough partials for you. + return false; +} + +const Partial *PartialManager::getPartial(unsigned int partialNum) const { + if (partialNum > synth->getPartialCount() - 1) { + return NULL; + } + return partialTable[partialNum]; +} + +Poly *PartialManager::assignPolyToPart(Part *part) { + if (firstFreePolyIndex < synth->getPartialCount()) { + Poly *poly = freePolys[firstFreePolyIndex]; + freePolys[firstFreePolyIndex] = NULL; + firstFreePolyIndex++; + poly->setPart(part); + return poly; + } + return NULL; +} + +void PartialManager::polyFreed(Poly *poly) { + if (0 == firstFreePolyIndex) { + synth->printDebug("Cannot return freed poly, currently active polys:\n"); + for (Bit32u partNum = 0; partNum < 9; partNum++) { + const Poly *activePoly = synth->getPart(partNum)->getFirstActivePoly(); + Bit32u polyCount = 0; + while (activePoly != NULL) { + activePoly = activePoly->getNext(); + polyCount++; + } + synth->printDebug("Part: %i, active poly count: %i\n", partNum, polyCount); + } + } + poly->setPart(NULL); + firstFreePolyIndex--; + freePolys[firstFreePolyIndex] = poly; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/PartialManager.h b/src/SOUND/munt/PartialManager.h new file mode 100644 index 000000000..46d8eeb98 --- /dev/null +++ b/src/SOUND/munt/PartialManager.h @@ -0,0 +1,64 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_PARTIALMANAGER_H +#define MT32EMU_PARTIALMANAGER_H + +#include "globals.h" +#include "internals.h" +#include "Types.h" + +namespace MT32Emu { + +class Part; +class Partial; +class Poly; +class Synth; + +class PartialManager { +private: + Synth *synth; + Part **parts; + Poly **freePolys; + Partial **partialTable; + Bit8u numReservedPartialsForPart[9]; + Bit32u firstFreePolyIndex; + + bool abortFirstReleasingPolyWhereReserveExceeded(int minPart); + bool abortFirstPolyPreferHeldWhereReserveExceeded(int minPart); + +public: + PartialManager(Synth *synth, Part **parts); + ~PartialManager(); + Partial *allocPartial(int partNum); + unsigned int getFreePartialCount(void); + void getPerPartPartialUsage(unsigned int perPartPartialUsage[9]); + bool freePartials(unsigned int needed, int partNum); + unsigned int setReserve(Bit8u *rset); + void deactivateAll(); + bool produceOutput(int i, IntSample *leftBuf, IntSample *rightBuf, Bit32u bufferLength); + bool produceOutput(int i, FloatSample *leftBuf, FloatSample *rightBuf, Bit32u bufferLength); + bool shouldReverb(int i); + void clearAlreadyOutputed(); + const Partial *getPartial(unsigned int partialNum) const; + Poly *assignPolyToPart(Part *part); + void polyFreed(Poly *poly); +}; // class PartialManager + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_PARTIALMANAGER_H diff --git a/src/SOUND/munt/Poly.cpp b/src/SOUND/munt/Poly.cpp new file mode 100644 index 000000000..44b8d2446 --- /dev/null +++ b/src/SOUND/munt/Poly.cpp @@ -0,0 +1,190 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "Poly.h" +#include "Part.h" +#include "Partial.h" +#include "Synth.h" + +namespace MT32Emu { + +Poly::Poly() { + part = NULL; + key = 255; + velocity = 255; + sustain = false; + activePartialCount = 0; + for (int i = 0; i < 4; i++) { + partials[i] = NULL; + } + state = POLY_Inactive; + next = NULL; +} + +void Poly::setPart(Part *usePart) { + part = usePart; +} + +void Poly::reset(unsigned int newKey, unsigned int newVelocity, bool newSustain, Partial **newPartials) { + if (isActive()) { + // This should never happen + part->getSynth()->printDebug("Resetting active poly. Active partial count: %i\n", activePartialCount); + for (int i = 0; i < 4; i++) { + if (partials[i] != NULL && partials[i]->isActive()) { + partials[i]->deactivate(); + activePartialCount--; + } + } + state = POLY_Inactive; + } + + key = newKey; + velocity = newVelocity; + sustain = newSustain; + + activePartialCount = 0; + for (int i = 0; i < 4; i++) { + partials[i] = newPartials[i]; + if (newPartials[i] != NULL) { + activePartialCount++; + state = POLY_Playing; + } + } +} + +bool Poly::noteOff(bool pedalHeld) { + // Generally, non-sustaining instruments ignore note off. They die away eventually anyway. + // Key 0 (only used by special cases on rhythm part) reacts to note off even if non-sustaining or pedal held. + if (state == POLY_Inactive || state == POLY_Releasing) { + return false; + } + if (pedalHeld) { + if (state == POLY_Held) { + return false; + } + state = POLY_Held; + } else { + startDecay(); + } + return true; +} + +bool Poly::stopPedalHold() { + if (state != POLY_Held) { + return false; + } + return startDecay(); +} + +bool Poly::startDecay() { + if (state == POLY_Inactive || state == POLY_Releasing) { + return false; + } + state = POLY_Releasing; + + for (int t = 0; t < 4; t++) { + Partial *partial = partials[t]; + if (partial != NULL) { + partial->startDecayAll(); + } + } + return true; +} + +bool Poly::startAbort() { + if (state == POLY_Inactive || part->getSynth()->isAbortingPoly()) { + return false; + } + for (int t = 0; t < 4; t++) { + Partial *partial = partials[t]; + if (partial != NULL) { + partial->startAbort(); + part->getSynth()->abortingPoly = this; + } + } + return true; +} + +void Poly::backupCacheToPartials(PatchCache cache[4]) { + for (int partialNum = 0; partialNum < 4; partialNum++) { + Partial *partial = partials[partialNum]; + if (partial != NULL) { + partial->backupCache(cache[partialNum]); + } + } +} + +/** + * Returns the internal key identifier. + * For non-rhythm, this is within the range 12 to 108. + * For rhythm on MT-32, this is 0 or 1 (special cases) or within the range 24 to 87. + * For rhythm on devices with extended PCM sounds (e.g. CM-32L), this is 0, 1 or 24 to 108 + */ +unsigned int Poly::getKey() const { + return key; +} + +unsigned int Poly::getVelocity() const { + return velocity; +} + +bool Poly::canSustain() const { + return sustain; +} + +PolyState Poly::getState() const { + return state; +} + +unsigned int Poly::getActivePartialCount() const { + return activePartialCount; +} + +bool Poly::isActive() const { + return state != POLY_Inactive; +} + +// This is called by Partial to inform the poly that the Partial has deactivated +void Poly::partialDeactivated(Partial *partial) { + for (int i = 0; i < 4; i++) { + if (partials[i] == partial) { + partials[i] = NULL; + activePartialCount--; + } + } + if (activePartialCount == 0) { + state = POLY_Inactive; + if (part->getSynth()->abortingPoly == this) { + part->getSynth()->abortingPoly = NULL; + } + } + part->partialDeactivated(this); +} + +Poly *Poly::getNext() const { + return next; +} + +void Poly::setNext(Poly *poly) { + next = poly; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/Poly.h b/src/SOUND/munt/Poly.h new file mode 100644 index 000000000..b2d4eceaf --- /dev/null +++ b/src/SOUND/munt/Poly.h @@ -0,0 +1,70 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_POLY_H +#define MT32EMU_POLY_H + +#include "globals.h" +#include "internals.h" + +namespace MT32Emu { + +class Part; +class Partial; +struct PatchCache; + +class Poly { +private: + Part *part; + unsigned int key; + unsigned int velocity; + unsigned int activePartialCount; + bool sustain; + + PolyState state; + + Partial *partials[4]; + + Poly *next; + +public: + Poly(); + void setPart(Part *usePart); + void reset(unsigned int key, unsigned int velocity, bool sustain, Partial **partials); + bool noteOff(bool pedalHeld); + bool stopPedalHold(); + bool startDecay(); + bool startAbort(); + + void backupCacheToPartials(PatchCache cache[4]); + + unsigned int getKey() const; + unsigned int getVelocity() const; + bool canSustain() const; + PolyState getState() const; + unsigned int getActivePartialCount() const; + bool isActive() const; + + void partialDeactivated(Partial *partial); + + Poly *getNext() const; + void setNext(Poly *poly); +}; // class Poly + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_POLY_H diff --git a/src/SOUND/munt/ROMInfo.cpp b/src/SOUND/munt/ROMInfo.cpp new file mode 100644 index 000000000..3eef26adf --- /dev/null +++ b/src/SOUND/munt/ROMInfo.cpp @@ -0,0 +1,117 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "ROMInfo.h" + +namespace MT32Emu { + +static const ROMInfo *getKnownROMInfoFromList(Bit32u index) { + // Known ROMs + static const ROMInfo CTRL_MT32_V1_04 = {65536, "5a5cb5a77d7d55ee69657c2f870416daed52dea7", ROMInfo::Control, "ctrl_mt32_1_04", "MT-32 Control v1.04", ROMInfo::Full, NULL}; + static const ROMInfo CTRL_MT32_V1_05 = {65536, "e17a3a6d265bf1fa150312061134293d2b58288c", ROMInfo::Control, "ctrl_mt32_1_05", "MT-32 Control v1.05", ROMInfo::Full, NULL}; + static const ROMInfo CTRL_MT32_V1_06 = {65536, "a553481f4e2794c10cfe597fef154eef0d8257de", ROMInfo::Control, "ctrl_mt32_1_06", "MT-32 Control v1.06", ROMInfo::Full, NULL}; + static const ROMInfo CTRL_MT32_V1_07 = {65536, "b083518fffb7f66b03c23b7eb4f868e62dc5a987", ROMInfo::Control, "ctrl_mt32_1_07", "MT-32 Control v1.07", ROMInfo::Full, NULL}; + static const ROMInfo CTRL_MT32_BLUER = {65536, "7b8c2a5ddb42fd0732e2f22b3340dcf5360edf92", ROMInfo::Control, "ctrl_mt32_bluer", "MT-32 Control BlueRidge", ROMInfo::Full, NULL}; + + static const ROMInfo CTRL_CM32L_V1_00 = {65536, "73683d585cd6948cc19547942ca0e14a0319456d", ROMInfo::Control, "ctrl_cm32l_1_00", "CM-32L/LAPC-I Control v1.00", ROMInfo::Full, NULL}; + static const ROMInfo CTRL_CM32L_V1_02 = {65536, "a439fbb390da38cada95a7cbb1d6ca199cd66ef8", ROMInfo::Control, "ctrl_cm32l_1_02", "CM-32L/LAPC-I Control v1.02", ROMInfo::Full, NULL}; + + static const ROMInfo PCM_MT32 = {524288, "f6b1eebc4b2d200ec6d3d21d51325d5b48c60252", ROMInfo::PCM, "pcm_mt32", "MT-32 PCM ROM", ROMInfo::Full, NULL}; + static const ROMInfo PCM_CM32L = {1048576, "289cc298ad532b702461bfc738009d9ebe8025ea", ROMInfo::PCM, "pcm_cm32l", "CM-32L/CM-64/LAPC-I PCM ROM", ROMInfo::Full, NULL}; + + static const ROMInfo * const ROM_INFOS[] = { + &CTRL_MT32_V1_04, + &CTRL_MT32_V1_05, + &CTRL_MT32_V1_06, + &CTRL_MT32_V1_07, + &CTRL_MT32_BLUER, + &CTRL_CM32L_V1_00, + &CTRL_CM32L_V1_02, + &PCM_MT32, + &PCM_CM32L, + NULL}; + + return ROM_INFOS[index]; +} + +const ROMInfo* ROMInfo::getROMInfo(File *file) { + size_t fileSize = file->getSize(); + for (Bit32u i = 0; getKnownROMInfoFromList(i) != NULL; i++) { + const ROMInfo *romInfo = getKnownROMInfoFromList(i); + if (fileSize == romInfo->fileSize && !strcmp(file->getSHA1(), romInfo->sha1Digest)) { + return romInfo; + } + } + return NULL; +} + +void ROMInfo::freeROMInfo(const ROMInfo *romInfo) { + (void) romInfo; +} + +static Bit32u getROMCount() { + Bit32u count; + for(count = 0; getKnownROMInfoFromList(count) != NULL; count++) { + } + return count; +} + +const ROMInfo** ROMInfo::getROMInfoList(Bit32u types, Bit32u pairTypes) { + const ROMInfo **romInfoList = new const ROMInfo*[getROMCount() + 1]; + const ROMInfo **currentROMInList = romInfoList; + for (Bit32u i = 0; getKnownROMInfoFromList(i) != NULL; i++) { + const ROMInfo *romInfo = getKnownROMInfoFromList(i); + if ((types & (1 << romInfo->type)) && (pairTypes & (1 << romInfo->pairType))) { + *currentROMInList++ = romInfo; + } + } + *currentROMInList = NULL; + return romInfoList; +} + +void ROMInfo::freeROMInfoList(const ROMInfo **romInfoList) { + delete[] romInfoList; +} + +ROMImage::ROMImage(File *useFile) : file(useFile), romInfo(ROMInfo::getROMInfo(file)) +{} + +ROMImage::~ROMImage() { + ROMInfo::freeROMInfo(romInfo); +} + +const ROMImage* ROMImage::makeROMImage(File *file) { + return new ROMImage(file); +} + +void ROMImage::freeROMImage(const ROMImage *romImage) { + delete romImage; +} + +File* ROMImage::getFile() const { + return file; +} + +const ROMInfo* ROMImage::getROMInfo() const { + return romInfo; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/ROMInfo.h b/src/SOUND/munt/ROMInfo.h new file mode 100644 index 000000000..cd4a1c5ac --- /dev/null +++ b/src/SOUND/munt/ROMInfo.h @@ -0,0 +1,80 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_ROMINFO_H +#define MT32EMU_ROMINFO_H + +#include + +#include "globals.h" +#include "File.h" + +namespace MT32Emu { + +// Defines vital info about ROM file to be used by synth and applications + +struct ROMInfo { +public: + size_t fileSize; + const File::SHA1Digest &sha1Digest; + enum Type {PCM, Control, Reverb} type; + const char *shortName; + const char *description; + enum PairType {Full, FirstHalf, SecondHalf, Mux0, Mux1} pairType; + ROMInfo *pairROMInfo; + + // Returns a ROMInfo struct by inspecting the size and the SHA1 hash + MT32EMU_EXPORT static const ROMInfo* getROMInfo(File *file); + + // Currently no-op + MT32EMU_EXPORT static void freeROMInfo(const ROMInfo *romInfo); + + // Allows retrieving a NULL-terminated list of ROMInfos for a range of types and pairTypes + // (specified by bitmasks) + // Useful for GUI/console app to output information on what ROMs it supports + MT32EMU_EXPORT static const ROMInfo** getROMInfoList(Bit32u types, Bit32u pairTypes); + + // Frees the list of ROMInfos given + MT32EMU_EXPORT static void freeROMInfoList(const ROMInfo **romInfos); +}; + +// Synth::open() is to require a full control ROMImage and a full PCM ROMImage to work + +class ROMImage { +private: + File * const file; + const ROMInfo * const romInfo; + + ROMImage(File *file); + ~ROMImage(); + +public: + // Creates a ROMImage object given a ROMInfo and a File. Keeps a reference + // to the File and ROMInfo given, which must be freed separately by the user + // after the ROMImage is freed + MT32EMU_EXPORT static const ROMImage* makeROMImage(File *file); + + // Must only be done after all Synths using the ROMImage are deleted + MT32EMU_EXPORT static void freeROMImage(const ROMImage *romImage); + + MT32EMU_EXPORT File *getFile() const; + MT32EMU_EXPORT const ROMInfo *getROMInfo() const; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_ROMINFO_H diff --git a/src/SOUND/munt/SampleRateConverter.cpp b/src/SOUND/munt/SampleRateConverter.cpp new file mode 100644 index 000000000..2d7866ba6 --- /dev/null +++ b/src/SOUND/munt/SampleRateConverter.cpp @@ -0,0 +1,110 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "SampleRateConverter.h" + +#if MT32EMU_WITH_LIBSOXR_RESAMPLER +#include "srchelper/SoxrAdapter.h" +#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER +#include "srchelper/SamplerateAdapter.h" +#else +#include "srchelper/InternalResampler.h" +#endif + +#include "Synth.h" + +using namespace MT32Emu; + +static inline void *createDelegate(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality) { +#if MT32EMU_WITH_LIBSOXR_RESAMPLER + return new SoxrAdapter(synth, targetSampleRate, quality); +#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER + return new SamplerateAdapter(synth, targetSampleRate, quality); +#else + return new InternalResampler(synth, targetSampleRate, quality); +#endif +} + +AnalogOutputMode SampleRateConverter::getBestAnalogOutputMode(double targetSampleRate) { + if (Synth::getStereoOutputSampleRate(AnalogOutputMode_ACCURATE) < targetSampleRate) { + return AnalogOutputMode_OVERSAMPLED; + } else if (Synth::getStereoOutputSampleRate(AnalogOutputMode_COARSE) < targetSampleRate) { + return AnalogOutputMode_ACCURATE; + } + return AnalogOutputMode_COARSE; +} + +SampleRateConverter::SampleRateConverter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality useQuality) : + synthInternalToTargetSampleRateRatio(SAMPLE_RATE / targetSampleRate), + useSynthDelegate(useSynth.getStereoOutputSampleRate() == targetSampleRate), + srcDelegate(useSynthDelegate ? &useSynth : createDelegate(useSynth, targetSampleRate, useQuality)) +{} + +SampleRateConverter::~SampleRateConverter() { + if (!useSynthDelegate) { +#if MT32EMU_WITH_LIBSOXR_RESAMPLER + delete static_cast(srcDelegate); +#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER + delete static_cast(srcDelegate); +#else + delete static_cast(srcDelegate); +#endif + } +} + +void SampleRateConverter::getOutputSamples(float *buffer, unsigned int length) { + if (useSynthDelegate) { + static_cast(srcDelegate)->render(buffer, length); + return; + } + +#if MT32EMU_WITH_LIBSOXR_RESAMPLER + static_cast(srcDelegate)->getOutputSamples(buffer, length); +#elif MT32EMU_WITH_LIBSAMPLERATE_RESAMPLER + static_cast(srcDelegate)->getOutputSamples(buffer, length); +#else + static_cast(srcDelegate)->getOutputSamples(buffer, length); +#endif +} + +void SampleRateConverter::getOutputSamples(Bit16s *outBuffer, unsigned int length) { + static const unsigned int CHANNEL_COUNT = 2; + + if (useSynthDelegate) { + static_cast(srcDelegate)->render(outBuffer, length); + return; + } + + float floatBuffer[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]; + while (length > 0) { + const unsigned int size = MAX_SAMPLES_PER_RUN < length ? MAX_SAMPLES_PER_RUN : length; + getOutputSamples(floatBuffer, size); + float *outs = floatBuffer; + float *ends = floatBuffer + CHANNEL_COUNT * size; + while (outs < ends) { + *(outBuffer++) = Synth::convertSample(*(outs++)); + } + length -= size; + } +} + +double SampleRateConverter::convertOutputToSynthTimestamp(double outputTimestamp) const { + return outputTimestamp * synthInternalToTargetSampleRateRatio; +} + +double SampleRateConverter::convertSynthToOutputTimestamp(double synthTimestamp) const { + return synthTimestamp / synthInternalToTargetSampleRateRatio; +} diff --git a/src/SOUND/munt/SampleRateConverter.h b/src/SOUND/munt/SampleRateConverter.h new file mode 100644 index 000000000..437f9b29f --- /dev/null +++ b/src/SOUND/munt/SampleRateConverter.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_SAMPLE_RATE_CONVERTER_H +#define MT32EMU_SAMPLE_RATE_CONVERTER_H + +#include "globals.h" +#include "Types.h" +#include "Enumerations.h" + +namespace MT32Emu { + +class Synth; + +/* SampleRateConverter class allows to convert the synthesiser output to any desired sample rate. + * It processes the completely mixed stereo output signal as it passes the analogue circuit emulation, + * so emulating the synthesiser output signal passing further through an ADC. + * Several conversion quality options are provided which allow to trade-off the conversion speed vs. the passband width. + * All the options except FASTEST guarantee full suppression of the aliasing noise in terms of the 16-bit integer samples. + */ +class MT32EMU_EXPORT SampleRateConverter { +public: + // Returns the value of AnalogOutputMode for which the output signal may retain its full frequency spectrum + // at the sample rate specified by the targetSampleRate argument. + static AnalogOutputMode getBestAnalogOutputMode(double targetSampleRate); + + // Creates a SampleRateConverter instance that converts output signal from the synth to the given sample rate + // with the specified conversion quality. + SampleRateConverter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); + ~SampleRateConverter(); + + // Fills the provided output buffer with the results of the sample rate conversion. + // The input samples are automatically retrieved from the synth as necessary. + void getOutputSamples(MT32Emu::Bit16s *buffer, unsigned int length); + + // Fills the provided output buffer with the results of the sample rate conversion. + // The input samples are automatically retrieved from the synth as necessary. + void getOutputSamples(float *buffer, unsigned int length); + + // Returns the number of samples produced at the internal synth sample rate (32000 Hz) + // that correspond to the number of samples at the target sample rate. + // Intended to facilitate audio time synchronisation. + double convertOutputToSynthTimestamp(double outputTimestamp) const; + + // Returns the number of samples produced at the target sample rate + // that correspond to the number of samples at the internal synth sample rate (32000 Hz). + // Intended to facilitate audio time synchronisation. + double convertSynthToOutputTimestamp(double synthTimestamp) const; + +private: + const double synthInternalToTargetSampleRateRatio; + const bool useSynthDelegate; + void * const srcDelegate; +}; // class SampleRateConverter + +} // namespace MT32Emu + +#endif // MT32EMU_SAMPLE_RATE_CONVERTER_H diff --git a/src/SOUND/munt/Structures.h b/src/SOUND/munt/Structures.h new file mode 100644 index 000000000..d3abf4ee7 --- /dev/null +++ b/src/SOUND/munt/Structures.h @@ -0,0 +1,259 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_STRUCTURES_H +#define MT32EMU_STRUCTURES_H + +#include "globals.h" +#include "Types.h" + +namespace MT32Emu { + +// MT32EMU_MEMADDR() converts from sysex-padded, MT32EMU_SYSEXMEMADDR converts to it +// Roland provides documentation using the sysex-padded addresses, so we tend to use that in code and output +#define MT32EMU_MEMADDR(x) ((((x) & 0x7f0000) >> 2) | (((x) & 0x7f00) >> 1) | ((x) & 0x7f)) +#define MT32EMU_SYSEXMEMADDR(x) ((((x) & 0x1FC000) << 2) | (((x) & 0x3F80) << 1) | ((x) & 0x7f)) + +#ifdef _MSC_VER +#define MT32EMU_ALIGN_PACKED __declspec(align(1)) +#else +#define MT32EMU_ALIGN_PACKED __attribute__((packed)) +#endif + +// The following structures represent the MT-32's memory +// Since sysex allows this memory to be written to in blocks of bytes, +// we keep this packed so that we can copy data into the various +// banks directly +#if defined(_MSC_VER) || defined(__MINGW32__) +#pragma pack(push, 1) +#else +#pragma pack(1) +#endif + +struct TimbreParam { + struct CommonParam { + char name[10]; + Bit8u partialStructure12; // 1 & 2 0-12 (1-13) + Bit8u partialStructure34; // 3 & 4 0-12 (1-13) + Bit8u partialMute; // 0-15 (0000-1111) + Bit8u noSustain; // ENV MODE 0-1 (Normal, No sustain) + } MT32EMU_ALIGN_PACKED common; + + struct PartialParam { + struct WGParam { + Bit8u pitchCoarse; // 0-96 (C1,C#1-C9) + Bit8u pitchFine; // 0-100 (-50 to +50 (cents - confirmed by Mok)) + Bit8u pitchKeyfollow; // 0-16 (-1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2) + Bit8u pitchBenderEnabled; // 0-1 (OFF, ON) + Bit8u waveform; // MT-32: 0-1 (SQU/SAW); LAPC-I: WG WAVEFORM/PCM BANK 0 - 3 (SQU/1, SAW/1, SQU/2, SAW/2) + Bit8u pcmWave; // 0-127 (1-128) + Bit8u pulseWidth; // 0-100 + Bit8u pulseWidthVeloSensitivity; // 0-14 (-7 - +7) + } MT32EMU_ALIGN_PACKED wg; + + struct PitchEnvParam { + Bit8u depth; // 0-10 + Bit8u veloSensitivity; // 0-100 + Bit8u timeKeyfollow; // 0-4 + Bit8u time[4]; // 0-100 + Bit8u level[5]; // 0-100 (-50 - +50) // [3]: SUSTAIN LEVEL, [4]: END LEVEL + } MT32EMU_ALIGN_PACKED pitchEnv; + + struct PitchLFOParam { + Bit8u rate; // 0-100 + Bit8u depth; // 0-100 + Bit8u modSensitivity; // 0-100 + } MT32EMU_ALIGN_PACKED pitchLFO; + + struct TVFParam { + Bit8u cutoff; // 0-100 + Bit8u resonance; // 0-30 + Bit8u keyfollow; // -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2 + Bit8u biasPoint; // 0-127 (<1A-<7C >1A-7C) + Bit8u biasLevel; // 0-14 (-7 - +7) + Bit8u envDepth; // 0-100 + Bit8u envVeloSensitivity; // 0-100 + Bit8u envDepthKeyfollow; // DEPTH KEY FOLL0W 0-4 + Bit8u envTimeKeyfollow; // TIME KEY FOLLOW 0-4 + Bit8u envTime[5]; // 0-100 + Bit8u envLevel[4]; // 0-100 // [3]: SUSTAIN LEVEL + } MT32EMU_ALIGN_PACKED tvf; + + struct TVAParam { + Bit8u level; // 0-100 + Bit8u veloSensitivity; // 0-100 + Bit8u biasPoint1; // 0-127 (<1A-<7C >1A-7C) + Bit8u biasLevel1; // 0-12 (-12 - 0) + Bit8u biasPoint2; // 0-127 (<1A-<7C >1A-7C) + Bit8u biasLevel2; // 0-12 (-12 - 0) + Bit8u envTimeKeyfollow; // TIME KEY FOLLOW 0-4 + Bit8u envTimeVeloSensitivity; // VELOS KEY FOLL0W 0-4 + Bit8u envTime[5]; // 0-100 + Bit8u envLevel[4]; // 0-100 // [3]: SUSTAIN LEVEL + } MT32EMU_ALIGN_PACKED tva; + } MT32EMU_ALIGN_PACKED partial[4]; // struct PartialParam +} MT32EMU_ALIGN_PACKED; // struct TimbreParam + +struct PatchParam { + Bit8u timbreGroup; // TIMBRE GROUP 0-3 (group A, group B, Memory, Rhythm) + Bit8u timbreNum; // TIMBRE NUMBER 0-63 + Bit8u keyShift; // KEY SHIFT 0-48 (-24 - +24 semitones) + Bit8u fineTune; // FINE TUNE 0-100 (-50 - +50 cents) + Bit8u benderRange; // BENDER RANGE 0-24 + Bit8u assignMode; // ASSIGN MODE 0-3 (POLY1, POLY2, POLY3, POLY4) + Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON) + Bit8u dummy; // (DUMMY) +} MT32EMU_ALIGN_PACKED; + +const unsigned int SYSTEM_MASTER_TUNE_OFF = 0; +const unsigned int SYSTEM_REVERB_MODE_OFF = 1; +const unsigned int SYSTEM_REVERB_TIME_OFF = 2; +const unsigned int SYSTEM_REVERB_LEVEL_OFF = 3; +const unsigned int SYSTEM_RESERVE_SETTINGS_START_OFF = 4; +const unsigned int SYSTEM_RESERVE_SETTINGS_END_OFF = 12; +const unsigned int SYSTEM_CHAN_ASSIGN_START_OFF = 13; +const unsigned int SYSTEM_CHAN_ASSIGN_END_OFF = 21; +const unsigned int SYSTEM_MASTER_VOL_OFF = 22; + +struct MemParams { + // NOTE: The MT-32 documentation only specifies PatchTemp areas for parts 1-8. + // The LAPC-I documentation specified an additional area for rhythm at the end, + // where all parameters but fine tune, assign mode and output level are ignored + struct PatchTemp { + PatchParam patch; + Bit8u outputLevel; // OUTPUT LEVEL 0-100 + Bit8u panpot; // PANPOT 0-14 (R-L) + Bit8u dummyv[6]; + } MT32EMU_ALIGN_PACKED patchTemp[9]; + + struct RhythmTemp { + Bit8u timbre; // TIMBRE 0-94 (M1-M64,R1-30,OFF); LAPC-I: 0-127 (M01-M64,R01-R63) + Bit8u outputLevel; // OUTPUT LEVEL 0-100 + Bit8u panpot; // PANPOT 0-14 (R-L) + Bit8u reverbSwitch; // REVERB SWITCH 0-1 (OFF,ON) + } MT32EMU_ALIGN_PACKED rhythmTemp[85]; + + TimbreParam timbreTemp[8]; + + PatchParam patches[128]; + + // NOTE: There are only 30 timbres in the "rhythm" bank for MT-32; the additional 34 are for LAPC-I and above + struct PaddedTimbre { + TimbreParam timbre; + Bit8u padding[10]; + } MT32EMU_ALIGN_PACKED timbres[64 + 64 + 64 + 64]; // Group A, Group B, Memory, Rhythm + + struct System { + Bit8u masterTune; // MASTER TUNE 0-127 432.1-457.6Hz + Bit8u reverbMode; // REVERB MODE 0-3 (room, hall, plate, tap delay) + Bit8u reverbTime; // REVERB TIME 0-7 (1-8) + Bit8u reverbLevel; // REVERB LEVEL 0-7 (1-8) + Bit8u reserveSettings[9]; // PARTIAL RESERVE (PART 1) 0-32 + Bit8u chanAssign[9]; // MIDI CHANNEL (PART1) 0-16 (1-16,OFF) + Bit8u masterVol; // MASTER VOLUME 0-100 + } MT32EMU_ALIGN_PACKED system; +}; // struct MemParams + +struct SoundGroup { + Bit8u timbreNumberTableAddrLow; + Bit8u timbreNumberTableAddrHigh; + Bit8u displayPosition; + Bit8u name[9]; + Bit8u timbreCount; + Bit8u pad; +} MT32EMU_ALIGN_PACKED; + +#if defined(_MSC_VER) || defined(__MINGW32__) +#pragma pack(pop) +#else +#pragma pack() +#endif + +struct ControlROMFeatureSet { + unsigned int quirkPitchEnvelopeOverflow : 1; + + // Features below don't actually depend on control ROM version, which is used to identify hardware model + unsigned int defaultReverbMT32Compatible : 1; + unsigned int oldMT32AnalogLPF : 1; +}; + +struct ControlROMMap { + const char *shortName; + const ControlROMFeatureSet &featureSet; + Bit16u pcmTable; // 4 * pcmCount bytes + Bit16u pcmCount; + Bit16u timbreAMap; // 128 bytes + Bit16u timbreAOffset; + bool timbreACompressed; + Bit16u timbreBMap; // 128 bytes + Bit16u timbreBOffset; + bool timbreBCompressed; + Bit16u timbreRMap; // 2 * timbreRCount bytes + Bit16u timbreRCount; + Bit16u rhythmSettings; // 4 * rhythmSettingsCount bytes + Bit16u rhythmSettingsCount; + Bit16u reserveSettings; // 9 bytes + Bit16u panSettings; // 8 bytes + Bit16u programSettings; // 8 bytes + Bit16u rhythmMaxTable; // 4 bytes + Bit16u patchMaxTable; // 16 bytes + Bit16u systemMaxTable; // 23 bytes + Bit16u timbreMaxTable; // 72 bytes + Bit16u soundGroupsTable; // 14 bytes each entry + Bit16u soundGroupsCount; +}; + +struct ControlROMPCMStruct { + Bit8u pos; + Bit8u len; + Bit8u pitchLSB; + Bit8u pitchMSB; +}; + +struct PCMWaveEntry { + Bit32u addr; + Bit32u len; + bool loop; + ControlROMPCMStruct *controlROMPCMStruct; +}; + +// This is basically a per-partial, pre-processed combination of timbre and patch/rhythm settings +struct PatchCache { + bool playPartial; + bool PCMPartial; + int pcm; + Bit8u waveform; + + Bit32u structureMix; + int structurePosition; + int structurePair; + + // The following fields are actually common to all partials in the timbre + bool dirty; + Bit32u partialCount; + bool sustain; + bool reverb; + + TimbreParam::PartialParam srcPartial; + + // The following directly points into live sysex-addressable memory + const TimbreParam::PartialParam *partialParam; +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_STRUCTURES_H diff --git a/src/SOUND/munt/Synth.cpp b/src/SOUND/munt/Synth.cpp new file mode 100644 index 000000000..e8464fc90 --- /dev/null +++ b/src/SOUND/munt/Synth.cpp @@ -0,0 +1,2286 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "Synth.h" +#include "Analog.h" +#include "BReverbModel.h" +#include "File.h" +#include "MemoryRegion.h" +#include "MidiEventQueue.h" +#include "Part.h" +#include "Partial.h" +#include "PartialManager.h" +#include "Poly.h" +#include "ROMInfo.h" +#include "TVA.h" + +namespace MT32Emu { + +// MIDI interface data transfer rate in samples. Used to simulate the transfer delay. +static const double MIDI_DATA_TRANSFER_RATE = double(SAMPLE_RATE) / 31250.0 * 8.0; + +// FIXME: there should be more specific feature sets for various MT-32 control ROM versions +static const ControlROMFeatureSet OLD_MT32_COMPATIBLE = { true, true, true }; +static const ControlROMFeatureSet CM32L_COMPATIBLE = { false, false, false }; + +static const ControlROMMap ControlROMMaps[7] = { + // ID Features PCMmap PCMc tmbrA tmbrAO, tmbrAC tmbrB tmbrBO tmbrBC tmbrR trC rhythm rhyC rsrv panpot prog rhyMax patMax sysMax timMax sndGrp sGC + { "ctrl_mt32_1_04", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73A6, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A, 0x7064, 19 }, + { "ctrl_mt32_1_05", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57C7, 0x57E2, 0x57D0, 0x5252, 0x525E, 0x526E, 0x520A, 0x70CA, 19 }, + { "ctrl_mt32_1_06", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x7414, 85, 0x57D9, 0x57F4, 0x57E2, 0x5264, 0x5270, 0x5280, 0x521C, 0x70CA, 19 }, + { "ctrl_mt32_1_07", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x73fe, 85, 0x57B1, 0x57CC, 0x57BA, 0x523C, 0x5248, 0x5258, 0x51F4, 0x70B0, 19 }, // MT-32 revision 1 + {"ctrl_mt32_bluer", OLD_MT32_COMPATIBLE, 0x3000, 128, 0x8000, 0x0000, false, 0xC000, 0x4000, false, 0x3200, 30, 0x741C, 85, 0x57E5, 0x5800, 0x57EE, 0x5270, 0x527C, 0x528C, 0x5228, 0x70CE, 19 }, // MT-32 Blue Ridge mod + {"ctrl_cm32l_1_00", CM32L_COMPATIBLE, 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F65, 0x4F80, 0x4F6E, 0x48A1, 0x48A5, 0x48BE, 0x48D5, 0x5A6C, 19 }, + {"ctrl_cm32l_1_02", CM32L_COMPATIBLE, 0x8100, 256, 0x8000, 0x8000, true, 0x8080, 0x8000, true, 0x8500, 64, 0x8580, 85, 0x4F93, 0x4FAE, 0x4F9C, 0x48CB, 0x48CF, 0x48E8, 0x48FF, 0x5A96, 19 } // CM-32L + // (Note that all but CM-32L ROM actually have 86 entries for rhythmTemp) +}; + +static const PartialState PARTIAL_PHASE_TO_STATE[8] = { + PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK, PartialState_ATTACK, + PartialState_SUSTAIN, PartialState_SUSTAIN, PartialState_RELEASE, PartialState_INACTIVE +}; + +static inline PartialState getPartialState(PartialManager *partialManager, unsigned int partialNum) { + const Partial *partial = partialManager->getPartial(partialNum); + return partial->isActive() ? PARTIAL_PHASE_TO_STATE[partial->getTVA()->getPhase()] : PartialState_INACTIVE; +} + +template +static inline void convertSampleFormat(const I *inBuffer, O *outBuffer, const Bit32u len) { + if (inBuffer == NULL || outBuffer == NULL) return; + + const I *inBufferEnd = inBuffer + len; + while (inBuffer < inBufferEnd) { + *(outBuffer++) = Synth::convertSample(*(inBuffer++)); + } +} + +class Renderer { +protected: + Synth &synth; + + void printDebug(const char *msg) const { + synth.printDebug(msg); + } + + bool isActivated() const { + return synth.activated; + } + + bool isAbortingPoly() const { + return synth.isAbortingPoly(); + } + + Analog &getAnalog() const { + return *synth.analog; + } + + MidiEventQueue &getMidiQueue() { + return *synth.midiQueue; + } + + PartialManager &getPartialManager() { + return *synth.partialManager; + } + + BReverbModel &getReverbModel() { + return *synth.reverbModel; + } + + Bit32u getRenderedSampleCount() { + return synth.renderedSampleCount; + } + + void incRenderedSampleCount(const Bit32u count) { + synth.renderedSampleCount += count; + } + +public: + Renderer(Synth &useSynth) : synth(useSynth) {} + + virtual ~Renderer() {} + + virtual void render(IntSample *stereoStream, Bit32u len) = 0; + virtual void render(FloatSample *stereoStream, Bit32u len) = 0; + virtual void renderStreams(const DACOutputStreams &streams, Bit32u len) = 0; + virtual void renderStreams(const DACOutputStreams &streams, Bit32u len) = 0; +}; + +template +class RendererImpl : public Renderer { + // These buffers are used for building the output streams as they are found at the DAC entrance. + // The output is mixed down to stereo interleaved further in the analog circuitry emulation. + Sample tmpNonReverbLeft[MAX_SAMPLES_PER_RUN], tmpNonReverbRight[MAX_SAMPLES_PER_RUN]; + Sample tmpReverbDryLeft[MAX_SAMPLES_PER_RUN], tmpReverbDryRight[MAX_SAMPLES_PER_RUN]; + Sample tmpReverbWetLeft[MAX_SAMPLES_PER_RUN], tmpReverbWetRight[MAX_SAMPLES_PER_RUN]; + + const DACOutputStreams tmpBuffers; + DACOutputStreams createTmpBuffers() { + DACOutputStreams buffers = { + tmpNonReverbLeft, tmpNonReverbRight, + tmpReverbDryLeft, tmpReverbDryRight, + tmpReverbWetLeft, tmpReverbWetRight + }; + return buffers; + } + +public: + RendererImpl(Synth &useSynth) : + Renderer(useSynth), + tmpBuffers(createTmpBuffers()) + {} + + void render(IntSample *stereoStream, Bit32u len); + void render(FloatSample *stereoStream, Bit32u len); + void renderStreams(const DACOutputStreams &streams, Bit32u len); + void renderStreams(const DACOutputStreams &streams, Bit32u len); + + template + void doRenderAndConvert(O *stereoStream, Bit32u len); + void doRender(Sample *stereoStream, Bit32u len); + + template + void doRenderAndConvertStreams(const DACOutputStreams &streams, Bit32u len); + void doRenderStreams(const DACOutputStreams &streams, Bit32u len); + void produceLA32Output(Sample *buffer, Bit32u len); + void convertSamplesToOutput(Sample *buffer, Bit32u len); + void produceStreams(const DACOutputStreams &streams, Bit32u len); +}; + +class Extensions { +public: + RendererType selectedRendererType; +}; + +Bit32u Synth::getLibraryVersionInt() { + return (MT32EMU_VERSION_MAJOR << 16) | (MT32EMU_VERSION_MINOR << 8) | (MT32EMU_VERSION_PATCH); +} + +const char *Synth::getLibraryVersionString() { + return MT32EMU_VERSION; +} + +Bit8u Synth::calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum) { + unsigned int checksum = -initChecksum; + for (unsigned int i = 0; i < len; i++) { + checksum -= data[i]; + } + return Bit8u(checksum & 0x7f); +} + +Bit32u Synth::getStereoOutputSampleRate(AnalogOutputMode analogOutputMode) { + static const unsigned int SAMPLE_RATES[] = {SAMPLE_RATE, SAMPLE_RATE, SAMPLE_RATE * 3 / 2, SAMPLE_RATE * 3}; + + return SAMPLE_RATES[analogOutputMode]; +} + +Synth::Synth(ReportHandler *useReportHandler) : + mt32ram(*new MemParams), + mt32default(*new MemParams), + extensions(*new Extensions) +{ + opened = false; + reverbOverridden = false; + partialCount = DEFAULT_MAX_PARTIALS; + controlROMMap = NULL; + controlROMFeatures = NULL; + + if (useReportHandler == NULL) { + reportHandler = new ReportHandler; + isDefaultReportHandler = true; + } else { + reportHandler = useReportHandler; + isDefaultReportHandler = false; + } + + for (int i = 0; i < 4; i++) { + reverbModels[i] = NULL; + } + reverbModel = NULL; + analog = NULL; + renderer = NULL; + setDACInputMode(DACInputMode_NICE); + setMIDIDelayMode(MIDIDelayMode_DELAY_SHORT_MESSAGES_ONLY); + setOutputGain(1.0f); + setReverbOutputGain(1.0f); + setReversedStereoEnabled(false); + selectRendererType(RendererType_BIT16S); + + patchTempMemoryRegion = NULL; + rhythmTempMemoryRegion = NULL; + timbreTempMemoryRegion = NULL; + patchesMemoryRegion = NULL; + timbresMemoryRegion = NULL; + systemMemoryRegion = NULL; + displayMemoryRegion = NULL; + resetMemoryRegion = NULL; + paddedTimbreMaxTable = NULL; + + partialManager = NULL; + pcmWaves = NULL; + pcmROMData = NULL; + soundGroupNames = NULL; + midiQueue = NULL; + lastReceivedMIDIEventTimestamp = 0; + memset(parts, 0, sizeof(parts)); + renderedSampleCount = 0; +} + +Synth::~Synth() { + close(); // Make sure we're closed and everything is freed + if (isDefaultReportHandler) { + delete reportHandler; + } + delete &mt32ram; + delete &mt32default; + delete &extensions; +} + +void ReportHandler::showLCDMessage(const char *data) { + printf("WRITE-LCD: %s\n", data); +} + +void ReportHandler::printDebug(const char *fmt, va_list list) { + vprintf(fmt, list); + printf("\n"); +} + +void Synth::newTimbreSet(Bit8u partNum, Bit8u timbreGroup, Bit8u timbreNumber, const char patchName[]) { + const char *soundGroupName; + switch (timbreGroup) { + case 1: + timbreNumber += 64; + // Fall-through + case 0: + soundGroupName = soundGroupNames[soundGroupIx[timbreNumber]]; + break; + case 2: + soundGroupName = soundGroupNames[controlROMMap->soundGroupsCount - 2]; + break; + case 3: + soundGroupName = soundGroupNames[controlROMMap->soundGroupsCount - 1]; + break; + default: + soundGroupName = NULL; + break; + } + reportHandler->onProgramChanged(partNum, soundGroupName, patchName); +} + +void Synth::printDebug(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); +#if MT32EMU_DEBUG_SAMPLESTAMPS > 0 + reportHandler->printDebug("[%u]", (va_list)&renderedSampleCount); +#endif + reportHandler->printDebug(fmt, ap); + va_end(ap); +} + +void Synth::setReverbEnabled(bool newReverbEnabled) { + if (!opened) return; + if (isReverbEnabled() == newReverbEnabled) return; + if (newReverbEnabled) { + bool oldReverbOverridden = reverbOverridden; + reverbOverridden = false; + refreshSystemReverbParameters(); + reverbOverridden = oldReverbOverridden; + } else { +#if MT32EMU_REDUCE_REVERB_MEMORY + reverbModel->close(); +#endif + reverbModel = NULL; + } +} + +bool Synth::isReverbEnabled() const { + return reverbModel != NULL; +} + +void Synth::setReverbOverridden(bool newReverbOverridden) { + reverbOverridden = newReverbOverridden; +} + +bool Synth::isReverbOverridden() const { + return reverbOverridden; +} + +void Synth::setReverbCompatibilityMode(bool mt32CompatibleMode) { + if (!opened || (isMT32ReverbCompatibilityMode() == mt32CompatibleMode)) return; + bool oldReverbEnabled = isReverbEnabled(); + setReverbEnabled(false); + for (int i = 0; i < 4; i++) { + delete reverbModels[i]; + } + initReverbModels(mt32CompatibleMode); + setReverbEnabled(oldReverbEnabled); + setReverbOutputGain(reverbOutputGain); +} + +bool Synth::isMT32ReverbCompatibilityMode() const { + return opened && (reverbModels[REVERB_MODE_ROOM]->isMT32Compatible(REVERB_MODE_ROOM)); +} + +bool Synth::isDefaultReverbMT32Compatible() const { + return opened && controlROMFeatures->defaultReverbMT32Compatible; +} + +void Synth::setDACInputMode(DACInputMode mode) { + dacInputMode = mode; +} + +DACInputMode Synth::getDACInputMode() const { + return dacInputMode; +} + +void Synth::setMIDIDelayMode(MIDIDelayMode mode) { + midiDelayMode = mode; +} + +MIDIDelayMode Synth::getMIDIDelayMode() const { + return midiDelayMode; +} + +void Synth::setOutputGain(float newOutputGain) { + if (newOutputGain < 0.0f) newOutputGain = -newOutputGain; + outputGain = newOutputGain; + if (analog != NULL) analog->setSynthOutputGain(newOutputGain); +} + +float Synth::getOutputGain() const { + return outputGain; +} + +void Synth::setReverbOutputGain(float newReverbOutputGain) { + if (newReverbOutputGain < 0.0f) newReverbOutputGain = -newReverbOutputGain; + reverbOutputGain = newReverbOutputGain; + if (analog != NULL) analog->setReverbOutputGain(newReverbOutputGain, isMT32ReverbCompatibilityMode()); +} + +float Synth::getReverbOutputGain() const { + return reverbOutputGain; +} + +void Synth::setReversedStereoEnabled(bool enabled) { + reversedStereoEnabled = enabled; +} + +bool Synth::isReversedStereoEnabled() const { + return reversedStereoEnabled; +} + +bool Synth::loadControlROM(const ROMImage &controlROMImage) { + File *file = controlROMImage.getFile(); + const ROMInfo *controlROMInfo = controlROMImage.getROMInfo(); + if ((controlROMInfo == NULL) + || (controlROMInfo->type != ROMInfo::Control) + || (controlROMInfo->pairType != ROMInfo::Full)) { +#if MT32EMU_MONITOR_INIT + printDebug("Invalid Control ROM Info provided"); +#endif + return false; + } + +#if MT32EMU_MONITOR_INIT + printDebug("Found Control ROM: %s, %s", controlROMInfo->shortName, controlROMInfo->description); +#endif + const Bit8u *fileData = file->getData(); + memcpy(controlROMData, fileData, CONTROL_ROM_SIZE); + + // Control ROM successfully loaded, now check whether it's a known type + controlROMMap = NULL; + controlROMFeatures = NULL; + for (unsigned int i = 0; i < sizeof(ControlROMMaps) / sizeof(ControlROMMaps[0]); i++) { + if (strcmp(controlROMInfo->shortName, ControlROMMaps[i].shortName) == 0) { + controlROMMap = &ControlROMMaps[i]; + controlROMFeatures = &controlROMMap->featureSet; + return true; + } + } +#if MT32EMU_MONITOR_INIT + printDebug("Control ROM failed to load"); +#endif + return false; +} + +bool Synth::loadPCMROM(const ROMImage &pcmROMImage) { + File *file = pcmROMImage.getFile(); + const ROMInfo *pcmROMInfo = pcmROMImage.getROMInfo(); + if ((pcmROMInfo == NULL) + || (pcmROMInfo->type != ROMInfo::PCM) + || (pcmROMInfo->pairType != ROMInfo::Full)) { + return false; + } +#if MT32EMU_MONITOR_INIT + printDebug("Found PCM ROM: %s, %s", pcmROMInfo->shortName, pcmROMInfo->description); +#endif + size_t fileSize = file->getSize(); + if (fileSize != (2 * pcmROMSize)) { +#if MT32EMU_MONITOR_INIT + printDebug("PCM ROM file has wrong size (expected %d, got %d)", 2 * pcmROMSize, fileSize); +#endif + return false; + } + const Bit8u *fileData = file->getData(); + for (size_t i = 0; i < pcmROMSize; i++) { + Bit8u s = *(fileData++); + Bit8u c = *(fileData++); + + int order[16] = {0, 9, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 8}; + + Bit16s log = 0; + for (int u = 0; u < 15; u++) { + int bit; + if (order[u] < 8) { + bit = (s >> (7 - order[u])) & 0x1; + } else { + bit = (c >> (7 - (order[u] - 8))) & 0x1; + } + log = log | Bit16s(bit << (15 - u)); + } + pcmROMData[i] = log; + } + return true; +} + +bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) { + ControlROMPCMStruct *tps = reinterpret_cast(&controlROMData[mapAddress]); + for (int i = 0; i < count; i++) { + Bit32u rAddr = tps[i].pos * 0x800; + Bit32u rLenExp = (tps[i].len & 0x70) >> 4; + Bit32u rLen = 0x800 << rLenExp; + if (rAddr + rLen > pcmROMSize) { + printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen); + return false; + } + pcmWaves[i].addr = rAddr; + pcmWaves[i].len = rLen; + pcmWaves[i].loop = (tps[i].len & 0x80) != 0; + pcmWaves[i].controlROMPCMStruct = &tps[i]; + //int pitch = (tps[i].pitchMSB << 8) | tps[i].pitchLSB; + //bool unaffectedByMasterTune = (tps[i].len & 0x01) == 0; + //printDebug("PCM %d: pos=%d, len=%d, pitch=%d, loop=%s, unaffectedByMasterTune=%s", i, rAddr, rLen, pitch, pcmWaves[i].loop ? "YES" : "NO", unaffectedByMasterTune ? "YES" : "NO"); + } + return false; +} + +bool Synth::initCompressedTimbre(Bit16u timbreNum, const Bit8u *src, Bit32u srcLen) { + // "Compressed" here means that muted partials aren't present in ROM (except in the case of partial 0 being muted). + // Instead the data from the previous unmuted partial is used. + if (srcLen < sizeof(TimbreParam::CommonParam)) { + return false; + } + TimbreParam *timbre = &mt32ram.timbres[timbreNum].timbre; + timbresMemoryRegion->write(timbreNum, 0, src, sizeof(TimbreParam::CommonParam), true); + unsigned int srcPos = sizeof(TimbreParam::CommonParam); + unsigned int memPos = sizeof(TimbreParam::CommonParam); + for (int t = 0; t < 4; t++) { + if (t != 0 && ((timbre->common.partialMute >> t) & 0x1) == 0x00) { + // This partial is muted - we'll copy the previously copied partial, then + srcPos -= sizeof(TimbreParam::PartialParam); + } else if (srcPos + sizeof(TimbreParam::PartialParam) >= srcLen) { + return false; + } + timbresMemoryRegion->write(timbreNum, memPos, src + srcPos, sizeof(TimbreParam::PartialParam)); + srcPos += sizeof(TimbreParam::PartialParam); + memPos += sizeof(TimbreParam::PartialParam); + } + return true; +} + +bool Synth::initTimbres(Bit16u mapAddress, Bit16u offset, Bit16u count, Bit16u startTimbre, bool compressed) { + const Bit8u *timbreMap = &controlROMData[mapAddress]; + for (Bit16u i = 0; i < count * 2; i += 2) { + Bit16u address = (timbreMap[i + 1] << 8) | timbreMap[i]; + if (!compressed && (address + offset + sizeof(TimbreParam) > CONTROL_ROM_SIZE)) { + printDebug("Control ROM error: Timbre map entry 0x%04x for timbre %d points to invalid timbre address 0x%04x", i, startTimbre, address); + return false; + } + address += offset; + if (compressed) { + if (!initCompressedTimbre(startTimbre, &controlROMData[address], CONTROL_ROM_SIZE - address)) { + printDebug("Control ROM error: Timbre map entry 0x%04x for timbre %d points to invalid timbre at 0x%04x", i, startTimbre, address); + return false; + } + } else { + timbresMemoryRegion->write(startTimbre, 0, &controlROMData[address], sizeof(TimbreParam), true); + } + startTimbre++; + } + return true; +} + +void Synth::initReverbModels(bool mt32CompatibleMode) { + reverbModels[REVERB_MODE_ROOM] = BReverbModel::createBReverbModel(REVERB_MODE_ROOM, mt32CompatibleMode, getSelectedRendererType()); + reverbModels[REVERB_MODE_HALL] = BReverbModel::createBReverbModel(REVERB_MODE_HALL, mt32CompatibleMode, getSelectedRendererType()); + reverbModels[REVERB_MODE_PLATE] = BReverbModel::createBReverbModel(REVERB_MODE_PLATE, mt32CompatibleMode, getSelectedRendererType()); + reverbModels[REVERB_MODE_TAP_DELAY] = BReverbModel::createBReverbModel(REVERB_MODE_TAP_DELAY, mt32CompatibleMode, getSelectedRendererType()); +#if !MT32EMU_REDUCE_REVERB_MEMORY + for (int i = REVERB_MODE_ROOM; i <= REVERB_MODE_TAP_DELAY; i++) { + reverbModels[i]->open(); + } +#endif +} + +void Synth::initSoundGroups(char newSoundGroupNames[][9]) { + memcpy(soundGroupIx, &controlROMData[controlROMMap->soundGroupsTable - sizeof(soundGroupIx)], sizeof(soundGroupIx)); + const SoundGroup *table = reinterpret_cast(&controlROMData[controlROMMap->soundGroupsTable]); + for (unsigned int i = 0; i < controlROMMap->soundGroupsCount; i++) { + memcpy(&newSoundGroupNames[i][0], table[i].name, sizeof(table[i].name)); + } +} + +bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode) { + return open(controlROMImage, pcmROMImage, DEFAULT_MAX_PARTIALS, analogOutputMode); +} + +bool Synth::open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, Bit32u usePartialCount, AnalogOutputMode analogOutputMode) { + if (opened) { + return false; + } + partialCount = usePartialCount; + abortingPoly = NULL; + + // This is to help detect bugs + memset(&mt32ram, '?', sizeof(mt32ram)); + +#if MT32EMU_MONITOR_INIT + printDebug("Loading Control ROM"); +#endif + if (!loadControlROM(controlROMImage)) { + printDebug("Init Error - Missing or invalid Control ROM image"); + reportHandler->onErrorControlROM(); + dispose(); + return false; + } + + initMemoryRegions(); + + // 512KB PCM ROM for MT-32, etc. + // 1MB PCM ROM for CM-32L, LAPC-I, CM-64, CM-500 + // Note that the size below is given in samples (16-bit), not bytes + pcmROMSize = controlROMMap->pcmCount == 256 ? 512 * 1024 : 256 * 1024; + pcmROMData = new Bit16s[pcmROMSize]; + +#if MT32EMU_MONITOR_INIT + printDebug("Loading PCM ROM"); +#endif + if (!loadPCMROM(pcmROMImage)) { + printDebug("Init Error - Missing PCM ROM image"); + reportHandler->onErrorPCMROM(); + dispose(); + return false; + } + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Reverb Models"); +#endif + bool mt32CompatibleReverb = controlROMFeatures->defaultReverbMT32Compatible; +#if MT32EMU_MONITOR_INIT + printDebug("Using %s Compatible Reverb Models", mt32CompatibleReverb ? "MT-32" : "CM-32L"); +#endif + initReverbModels(mt32CompatibleReverb); + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Timbre Bank A"); +#endif + if (!initTimbres(controlROMMap->timbreAMap, controlROMMap->timbreAOffset, 0x40, 0, controlROMMap->timbreACompressed)) { + dispose(); + return false; + } + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Timbre Bank B"); +#endif + if (!initTimbres(controlROMMap->timbreBMap, controlROMMap->timbreBOffset, 0x40, 64, controlROMMap->timbreBCompressed)) { + dispose(); + return false; + } + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Timbre Bank R"); +#endif + if (!initTimbres(controlROMMap->timbreRMap, 0, controlROMMap->timbreRCount, 192, true)) { + dispose(); + return false; + } + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Timbre Bank M"); +#endif + // CM-64 seems to initialise all bytes in this bank to 0. + memset(&mt32ram.timbres[128], 0, sizeof(mt32ram.timbres[128]) * 64); + + partialManager = new PartialManager(this, parts); + + pcmWaves = new PCMWaveEntry[controlROMMap->pcmCount]; + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising PCM List"); +#endif + initPCMList(controlROMMap->pcmTable, controlROMMap->pcmCount); + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Rhythm Temp"); +#endif + memcpy(mt32ram.rhythmTemp, &controlROMData[controlROMMap->rhythmSettings], controlROMMap->rhythmSettingsCount * 4); + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising Patches"); +#endif + for (Bit8u i = 0; i < 128; i++) { + PatchParam *patch = &mt32ram.patches[i]; + patch->timbreGroup = i / 64; + patch->timbreNum = i % 64; + patch->keyShift = 24; + patch->fineTune = 50; + patch->benderRange = 12; + patch->assignMode = 0; + patch->reverbSwitch = 1; + patch->dummy = 0; + } + +#if MT32EMU_MONITOR_INIT + printDebug("Initialising System"); +#endif + // The MT-32 manual claims that "Standard pitch" is 442Hz. + mt32ram.system.masterTune = 0x4A; // Confirmed on CM-64 + mt32ram.system.reverbMode = 0; // Confirmed + mt32ram.system.reverbTime = 5; // Confirmed + mt32ram.system.reverbLevel = 3; // Confirmed + memcpy(mt32ram.system.reserveSettings, &controlROMData[controlROMMap->reserveSettings], 9); // Confirmed + for (Bit8u i = 0; i < 9; i++) { + // This is the default: {1, 2, 3, 4, 5, 6, 7, 8, 9} + // An alternative configuration can be selected by holding "Master Volume" + // and pressing "PART button 1" on the real MT-32's frontpanel. + // The channel assignment is then {0, 1, 2, 3, 4, 5, 6, 7, 9} + mt32ram.system.chanAssign[i] = i + 1; + } + mt32ram.system.masterVol = 100; // Confirmed + + bool oldReverbOverridden = reverbOverridden; + reverbOverridden = false; + refreshSystem(); + reverbOverridden = oldReverbOverridden; + + char(*writableSoundGroupNames)[9] = new char[controlROMMap->soundGroupsCount][9]; + soundGroupNames = writableSoundGroupNames; + initSoundGroups(writableSoundGroupNames); + + for (int i = 0; i < 9; i++) { + MemParams::PatchTemp *patchTemp = &mt32ram.patchTemp[i]; + + // Note that except for the rhythm part, these patch fields will be set in setProgram() below anyway. + patchTemp->patch.timbreGroup = 0; + patchTemp->patch.timbreNum = 0; + patchTemp->patch.keyShift = 24; + patchTemp->patch.fineTune = 50; + patchTemp->patch.benderRange = 12; + patchTemp->patch.assignMode = 0; + patchTemp->patch.reverbSwitch = 1; + patchTemp->patch.dummy = 0; + + patchTemp->outputLevel = 80; + patchTemp->panpot = controlROMData[controlROMMap->panSettings + i]; + memset(patchTemp->dummyv, 0, sizeof(patchTemp->dummyv)); + patchTemp->dummyv[1] = 127; + + if (i < 8) { + parts[i] = new Part(this, i); + parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]); + } else { + parts[i] = new RhythmPart(this, i); + } + } + + // For resetting mt32 mid-execution + mt32default = mt32ram; + + midiQueue = new MidiEventQueue(); + + analog = Analog::createAnalog(analogOutputMode, controlROMFeatures->oldMT32AnalogLPF, getSelectedRendererType()); +#if MT32EMU_MONITOR_INIT + static const char *ANALOG_OUTPUT_MODES[] = { "Digital only", "Coarse", "Accurate", "Oversampled2x" }; + printDebug("Using Analog output mode %s", ANALOG_OUTPUT_MODES[analogOutputMode]); +#endif + setOutputGain(outputGain); + setReverbOutputGain(reverbOutputGain); + + switch (getSelectedRendererType()) { + case RendererType_BIT16S: + renderer = new RendererImpl(*this); +#if MT32EMU_MONITOR_INIT + printDebug("Using integer 16-bit samples in renderer and wave generator"); +#endif + break; + case RendererType_FLOAT: + renderer = new RendererImpl(*this); +#if MT32EMU_MONITOR_INIT + printDebug("Using float 32-bit samples in renderer and wave generator"); +#endif + break; + default: + printDebug("Synth: Unknown renderer type %i\n", getSelectedRendererType()); + dispose(); + return false; + } + + opened = true; + activated = false; + +#if MT32EMU_MONITOR_INIT + printDebug("*** Initialisation complete ***"); +#endif + return true; +} + +void Synth::dispose() { + opened = false; + + delete midiQueue; + midiQueue = NULL; + + delete renderer; + renderer = NULL; + + delete analog; + analog = NULL; + + delete partialManager; + partialManager = NULL; + + for (int i = 0; i < 9; i++) { + delete parts[i]; + parts[i] = NULL; + } + + delete[] soundGroupNames; + soundGroupNames = NULL; + + delete[] pcmWaves; + pcmWaves = NULL; + + delete[] pcmROMData; + pcmROMData = NULL; + + deleteMemoryRegions(); + + for (int i = 0; i < 4; i++) { + delete reverbModels[i]; + reverbModels[i] = NULL; + } + reverbModel = NULL; + controlROMFeatures = NULL; + controlROMMap = NULL; +} + +void Synth::close() { + if (opened) { + dispose(); + } +} + +bool Synth::isOpen() const { + return opened; +} + +void Synth::flushMIDIQueue() { + if (midiQueue != NULL) { + for (;;) { + const MidiEvent *midiEvent = midiQueue->peekMidiEvent(); + if (midiEvent == NULL) break; + if (midiEvent->sysexData == NULL) { + playMsgNow(midiEvent->shortMessageData); + } else { + playSysexNow(midiEvent->sysexData, midiEvent->sysexLength); + } + midiQueue->dropMidiEvent(); + } + lastReceivedMIDIEventTimestamp = renderedSampleCount; + } +} + +Bit32u Synth::setMIDIEventQueueSize(Bit32u useSize) { + static const Bit32u MAX_QUEUE_SIZE = (1 << 24); // This results in about 256 Mb - much greater than any reasonable value + + if (midiQueue == NULL) return 0; + flushMIDIQueue(); + + // Find a power of 2 that is >= useSize + Bit32u binarySize = 1; + if (useSize < MAX_QUEUE_SIZE) { + // Using simple linear search as this isn't time critical + while (binarySize < useSize) binarySize <<= 1; + } else { + binarySize = MAX_QUEUE_SIZE; + } + delete midiQueue; + midiQueue = new MidiEventQueue(binarySize); + return binarySize; +} + +Bit32u Synth::getShortMessageLength(Bit32u msg) { + if ((msg & 0xF0) == 0xF0) { + switch (msg & 0xFF) { + case 0xF1: + case 0xF3: + return 2; + case 0xF2: + return 3; + default: + return 1; + } + } + // NOTE: This calculation isn't quite correct + // as it doesn't consider the running status byte + return ((msg & 0xE0) == 0xC0) ? 2 : 3; +} + +Bit32u Synth::addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp) { + Bit32u transferTime = Bit32u(double(len) * MIDI_DATA_TRANSFER_RATE); + // Dealing with wrapping + if (Bit32s(timestamp - lastReceivedMIDIEventTimestamp) < 0) { + timestamp = lastReceivedMIDIEventTimestamp; + } + timestamp += transferTime; + lastReceivedMIDIEventTimestamp = timestamp; + return timestamp; +} + +bool Synth::playMsg(Bit32u msg) { + return playMsg(msg, renderedSampleCount); +} + +bool Synth::playMsg(Bit32u msg, Bit32u timestamp) { + if ((msg & 0xF8) == 0xF8) { + reportHandler->onMIDISystemRealtime(Bit8u(msg)); + return true; + } + if (midiQueue == NULL) return false; + if (midiDelayMode != MIDIDelayMode_IMMEDIATE) { + timestamp = addMIDIInterfaceDelay(getShortMessageLength(msg), timestamp); + } + if (!activated) activated = true; + do { + if (midiQueue->pushShortMessage(msg, timestamp)) return true; + } while (reportHandler->onMIDIQueueOverflow()); + return false; +} + +bool Synth::playSysex(const Bit8u *sysex, Bit32u len) { + return playSysex(sysex, len, renderedSampleCount); +} + +bool Synth::playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp) { + if (midiQueue == NULL) return false; + if (midiDelayMode == MIDIDelayMode_DELAY_ALL) { + timestamp = addMIDIInterfaceDelay(len, timestamp); + } + if (!activated) activated = true; + do { + if (midiQueue->pushSysex(sysex, len, timestamp)) return true; + } while (reportHandler->onMIDIQueueOverflow()); + return false; +} + +void Synth::playMsgNow(Bit32u msg) { + if (!opened) return; + + // NOTE: Active sense IS implemented in real hardware. However, realtime processing is clearly out of the library scope. + // It is assumed that realtime consumers of the library respond to these MIDI events as appropriate. + + Bit8u code = Bit8u((msg & 0x0000F0) >> 4); + Bit8u chan = Bit8u(msg & 0x00000F); + Bit8u note = Bit8u((msg & 0x007F00) >> 8); + Bit8u velocity = Bit8u((msg & 0x7F0000) >> 16); + + //printDebug("Playing chan %d, code 0x%01x note: 0x%02x", chan, code, note); + + Bit8u part = chantable[chan]; + if (part > 8) { +#if MT32EMU_MONITOR_MIDI > 0 + printDebug("Play msg on unreg chan %d (%d): code=0x%01x, vel=%d", chan, part, code, velocity); +#endif + return; + } + playMsgOnPart(part, code, note, velocity); +} + +void Synth::playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity) { + if (!opened) return; + + Bit32u bend; + + if (!activated) activated = true; + //printDebug("Synth::playMsgOnPart(%02x, %02x, %02x, %02x)", part, code, note, velocity); + switch (code) { + case 0x8: + //printDebug("Note OFF - Part %d", part); + // The MT-32 ignores velocity for note off + parts[part]->noteOff(note); + break; + case 0x9: + //printDebug("Note ON - Part %d, Note %d Vel %d", part, note, velocity); + if (velocity == 0) { + // MIDI defines note-on with velocity 0 as being the same as note-off with velocity 40 + parts[part]->noteOff(note); + } else { + parts[part]->noteOn(note, velocity); + } + break; + case 0xB: // Control change + switch (note) { + case 0x01: // Modulation + //printDebug("Modulation: %d", velocity); + parts[part]->setModulation(velocity); + break; + case 0x06: + parts[part]->setDataEntryMSB(velocity); + break; + case 0x07: // Set volume + //printDebug("Volume set: %d", velocity); + parts[part]->setVolume(velocity); + break; + case 0x0A: // Pan + //printDebug("Pan set: %d", velocity); + parts[part]->setPan(velocity); + break; + case 0x0B: + //printDebug("Expression set: %d", velocity); + parts[part]->setExpression(velocity); + break; + case 0x40: // Hold (sustain) pedal + //printDebug("Hold pedal set: %d", velocity); + parts[part]->setHoldPedal(velocity >= 64); + break; + + case 0x62: + case 0x63: + parts[part]->setNRPN(); + break; + case 0x64: + parts[part]->setRPNLSB(velocity); + break; + case 0x65: + parts[part]->setRPNMSB(velocity); + break; + + case 0x79: // Reset all controllers + //printDebug("Reset all controllers"); + parts[part]->resetAllControllers(); + break; + + case 0x7B: // All notes off + //printDebug("All notes off"); + parts[part]->allNotesOff(); + break; + + case 0x7C: + case 0x7D: + case 0x7E: + case 0x7F: + // CONFIRMED:Mok: A real LAPC-I responds to these controllers as follows: + parts[part]->setHoldPedal(false); + parts[part]->allNotesOff(); + break; + + default: +#if MT32EMU_MONITOR_MIDI > 0 + printDebug("Unknown MIDI Control code: 0x%02x - vel 0x%02x", note, velocity); +#endif + return; + } + + break; + case 0xC: // Program change + //printDebug("Program change %01x", note); + parts[part]->setProgram(note); + break; + case 0xE: // Pitch bender + bend = (velocity << 7) | (note); + //printDebug("Pitch bender %02x", bend); + parts[part]->setBend(bend); + break; + default: +#if MT32EMU_MONITOR_MIDI > 0 + printDebug("Unknown Midi code: 0x%01x - %02x - %02x", code, note, velocity); +#endif + return; + } + reportHandler->onMIDIMessagePlayed(); +} + +void Synth::playSysexNow(const Bit8u *sysex, Bit32u len) { + if (len < 2) { + printDebug("playSysex: Message is too short for sysex (%d bytes)", len); + } + if (sysex[0] != 0xF0) { + printDebug("playSysex: Message lacks start-of-sysex (0xF0)"); + return; + } + // Due to some programs (e.g. Java) sending buffers with junk at the end, we have to go through and find the end marker rather than relying on len. + Bit32u endPos; + for (endPos = 1; endPos < len; endPos++) { + if (sysex[endPos] == 0xF7) { + break; + } + } + if (endPos == len) { + printDebug("playSysex: Message lacks end-of-sysex (0xf7)"); + return; + } + playSysexWithoutFraming(sysex + 1, endPos - 1); +} + +void Synth::playSysexWithoutFraming(const Bit8u *sysex, Bit32u len) { + if (len < 4) { + printDebug("playSysexWithoutFraming: Message is too short (%d bytes)!", len); + return; + } + if (sysex[0] != SYSEX_MANUFACTURER_ROLAND) { + printDebug("playSysexWithoutFraming: Header not intended for this device manufacturer: %02x %02x %02x %02x", int(sysex[0]), int(sysex[1]), int(sysex[2]), int(sysex[3])); + return; + } + if (sysex[2] == SYSEX_MDL_D50) { + printDebug("playSysexWithoutFraming: Header is intended for model D-50 (not yet supported): %02x %02x %02x %02x", int(sysex[0]), int(sysex[1]), int(sysex[2]), int(sysex[3])); + return; + } else if (sysex[2] != SYSEX_MDL_MT32) { + printDebug("playSysexWithoutFraming: Header not intended for model MT-32: %02x %02x %02x %02x", int(sysex[0]), int(sysex[1]), int(sysex[2]), int(sysex[3])); + return; + } + playSysexWithoutHeader(sysex[1], sysex[3], sysex + 4, len - 4); +} + +void Synth::playSysexWithoutHeader(Bit8u device, Bit8u command, const Bit8u *sysex, Bit32u len) { + if (device > 0x10) { + // We have device ID 0x10 (default, but changeable, on real MT-32), < 0x10 is for channels + printDebug("playSysexWithoutHeader: Message is not intended for this device ID (provided: %02x, expected: 0x10 or channel)", int(device)); + return; + } + // This is checked early in the real devices (before any sysex length checks or further processing) + // FIXME: Response to SYSEX_CMD_DAT reset with partials active (and in general) is untested. + if ((command == SYSEX_CMD_DT1 || command == SYSEX_CMD_DAT) && sysex[0] == 0x7F) { + reset(); + return; + } + + if (command == SYSEX_CMD_EOD) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("playSysexWithoutHeader: Ignored unsupported command %02x", command); +#endif + return; + } + if (len < 4) { + printDebug("playSysexWithoutHeader: Message is too short (%d bytes)!", len); + return; + } + Bit8u checksum = calcSysexChecksum(sysex, len - 1); + if (checksum != sysex[len - 1]) { + printDebug("playSysexWithoutHeader: Message checksum is incorrect (provided: %02x, expected: %02x)!", sysex[len - 1], checksum); + return; + } + len -= 1; // Exclude checksum + switch (command) { + case SYSEX_CMD_WSD: +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("playSysexWithoutHeader: Ignored unsupported command %02x", command); +#endif + break; + case SYSEX_CMD_DAT: + /* Outcommented until we (ever) actually implement handshake communication + if (hasActivePartials()) { + printDebug("playSysexWithoutHeader: Got SYSEX_CMD_DAT but partials are active - ignoring"); + // FIXME: We should send SYSEX_CMD_RJC in this case + break; + } + */ + // Deliberate fall-through + case SYSEX_CMD_DT1: + writeSysex(device, sysex, len); + break; + case SYSEX_CMD_RQD: + if (hasActivePartials()) { + printDebug("playSysexWithoutHeader: Got SYSEX_CMD_RQD but partials are active - ignoring"); + // FIXME: We should send SYSEX_CMD_RJC in this case + break; + } + // Deliberate fall-through + case SYSEX_CMD_RQ1: + readSysex(device, sysex, len); + break; + default: + printDebug("playSysexWithoutHeader: Unsupported command %02x", command); + return; + } +} + +void Synth::readSysex(Bit8u /*device*/, const Bit8u * /*sysex*/, Bit32u /*len*/) const { + // NYI +} + +void Synth::writeSysex(Bit8u device, const Bit8u *sysex, Bit32u len) { + if (!opened) return; + reportHandler->onMIDIMessagePlayed(); + Bit32u addr = (sysex[0] << 16) | (sysex[1] << 8) | (sysex[2]); + addr = MT32EMU_MEMADDR(addr); + sysex += 3; + len -= 3; + //printDebug("Sysex addr: 0x%06x", MT32EMU_SYSEXMEMADDR(addr)); + // NOTE: Please keep both lower and upper bounds in each check, for ease of reading + + // Process channel-specific sysex by converting it to device-global + if (device < 0x10) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("WRITE-CHANNEL: Channel %d temp area 0x%06x", device, MT32EMU_SYSEXMEMADDR(addr)); +#endif + if (/*addr >= MT32EMU_MEMADDR(0x000000) && */addr < MT32EMU_MEMADDR(0x010000)) { + int offset; + if (chantable[device] > 8) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Channel not mapped to a part... 0 offset)"); +#endif + offset = 0; + } else if (chantable[device] == 8) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Channel mapped to rhythm... 0 offset)"); +#endif + offset = 0; + } else { + offset = chantable[device] * sizeof(MemParams::PatchTemp); +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Setting extra offset to %d)", offset); +#endif + } + addr += MT32EMU_MEMADDR(0x030000) + offset; + } else if (/*addr >= MT32EMU_MEMADDR(0x010000) && */ addr < MT32EMU_MEMADDR(0x020000)) { + addr += MT32EMU_MEMADDR(0x030110) - MT32EMU_MEMADDR(0x010000); + } else if (/*addr >= MT32EMU_MEMADDR(0x020000) && */ addr < MT32EMU_MEMADDR(0x030000)) { + int offset; + if (chantable[device] > 8) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Channel not mapped to a part... 0 offset)"); +#endif + offset = 0; + } else if (chantable[device] == 8) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Channel mapped to rhythm... 0 offset)"); +#endif + offset = 0; + } else { + offset = chantable[device] * sizeof(TimbreParam); +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Setting extra offset to %d)", offset); +#endif + } + addr += MT32EMU_MEMADDR(0x040000) - MT32EMU_MEMADDR(0x020000) + offset; + } else { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" Invalid channel"); +#endif + return; + } + } + + // Process device-global sysex (possibly converted from channel-specific sysex above) + for (;;) { + // Find the appropriate memory region + const MemoryRegion *region = findMemoryRegion(addr); + + if (region == NULL) { + printDebug("Sysex write to unrecognised address %06x, len %d", MT32EMU_SYSEXMEMADDR(addr), len); + break; + } + writeMemoryRegion(region, addr, region->getClampedLen(addr, len), sysex); + + Bit32u next = region->next(addr, len); + if (next == 0) { + break; + } + addr += next; + sysex += next; + len -= next; + } +} + +void Synth::readMemory(Bit32u addr, Bit32u len, Bit8u *data) { + if (!opened) return; + const MemoryRegion *region = findMemoryRegion(addr); + if (region != NULL) { + readMemoryRegion(region, addr, len, data); + } +} + +void Synth::initMemoryRegions() { + // Timbre max tables are slightly more complicated than the others, which are used directly from the ROM. + // The ROM (sensibly) just has maximums for TimbreParam.commonParam followed by just one TimbreParam.partialParam, + // so we produce a table with all partialParams filled out, as well as padding for PaddedTimbre, for quick lookup. + paddedTimbreMaxTable = new Bit8u[sizeof(MemParams::PaddedTimbre)]; + memcpy(&paddedTimbreMaxTable[0], &controlROMData[controlROMMap->timbreMaxTable], sizeof(TimbreParam::CommonParam) + sizeof(TimbreParam::PartialParam)); // commonParam and one partialParam + int pos = sizeof(TimbreParam::CommonParam) + sizeof(TimbreParam::PartialParam); + for (int i = 0; i < 3; i++) { + memcpy(&paddedTimbreMaxTable[pos], &controlROMData[controlROMMap->timbreMaxTable + sizeof(TimbreParam::CommonParam)], sizeof(TimbreParam::PartialParam)); + pos += sizeof(TimbreParam::PartialParam); + } + memset(&paddedTimbreMaxTable[pos], 0, 10); // Padding + patchTempMemoryRegion = new PatchTempMemoryRegion(this, reinterpret_cast(&mt32ram.patchTemp[0]), &controlROMData[controlROMMap->patchMaxTable]); + rhythmTempMemoryRegion = new RhythmTempMemoryRegion(this, reinterpret_cast(&mt32ram.rhythmTemp[0]), &controlROMData[controlROMMap->rhythmMaxTable]); + timbreTempMemoryRegion = new TimbreTempMemoryRegion(this, reinterpret_cast(&mt32ram.timbreTemp[0]), paddedTimbreMaxTable); + patchesMemoryRegion = new PatchesMemoryRegion(this, reinterpret_cast(&mt32ram.patches[0]), &controlROMData[controlROMMap->patchMaxTable]); + timbresMemoryRegion = new TimbresMemoryRegion(this, reinterpret_cast(&mt32ram.timbres[0]), paddedTimbreMaxTable); + systemMemoryRegion = new SystemMemoryRegion(this, reinterpret_cast(&mt32ram.system), &controlROMData[controlROMMap->systemMaxTable]); + displayMemoryRegion = new DisplayMemoryRegion(this); + resetMemoryRegion = new ResetMemoryRegion(this); +} + +void Synth::deleteMemoryRegions() { + delete patchTempMemoryRegion; + patchTempMemoryRegion = NULL; + delete rhythmTempMemoryRegion; + rhythmTempMemoryRegion = NULL; + delete timbreTempMemoryRegion; + timbreTempMemoryRegion = NULL; + delete patchesMemoryRegion; + patchesMemoryRegion = NULL; + delete timbresMemoryRegion; + timbresMemoryRegion = NULL; + delete systemMemoryRegion; + systemMemoryRegion = NULL; + delete displayMemoryRegion; + displayMemoryRegion = NULL; + delete resetMemoryRegion; + resetMemoryRegion = NULL; + + delete[] paddedTimbreMaxTable; + paddedTimbreMaxTable = NULL; +} + +MemoryRegion *Synth::findMemoryRegion(Bit32u addr) { + MemoryRegion *regions[] = { + patchTempMemoryRegion, + rhythmTempMemoryRegion, + timbreTempMemoryRegion, + patchesMemoryRegion, + timbresMemoryRegion, + systemMemoryRegion, + displayMemoryRegion, + resetMemoryRegion, + NULL + }; + for (int pos = 0; regions[pos] != NULL; pos++) { + if (regions[pos]->contains(addr)) { + return regions[pos]; + } + } + return NULL; +} + +void Synth::readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data) { + unsigned int first = region->firstTouched(addr); + //unsigned int last = region->lastTouched(addr, len); + unsigned int off = region->firstTouchedOffset(addr); + len = region->getClampedLen(addr, len); + + unsigned int m; + + if (region->isReadable()) { + region->read(first, off, data, len); + } else { + // FIXME: We might want to do these properly in future + for (m = 0; m < len; m += 2) { + data[m] = 0xff; + if (m + 1 < len) { + data[m+1] = Bit8u(region->type); + } + } + } +} + +void Synth::writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data) { + unsigned int first = region->firstTouched(addr); + unsigned int last = region->lastTouched(addr, len); + unsigned int off = region->firstTouchedOffset(addr); + switch (region->type) { + case MR_PatchTemp: + region->write(first, off, data, len); + //printDebug("Patch temp: Patch %d, offset %x, len %d", off/16, off % 16, len); + + for (unsigned int i = first; i <= last; i++) { + int absTimbreNum = mt32ram.patchTemp[i].patch.timbreGroup * 64 + mt32ram.patchTemp[i].patch.timbreNum; + char timbreName[11]; + memcpy(timbreName, mt32ram.timbres[absTimbreNum].timbre.common.name, 10); + timbreName[10] = 0; +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("WRITE-PARTPATCH (%d-%d@%d..%d): %d; timbre=%d (%s), outlevel=%d", first, last, off, off + len, i, absTimbreNum, timbreName, mt32ram.patchTemp[i].outputLevel); +#endif + if (parts[i] != NULL) { + if (i != 8) { + // Note: Confirmed on CM-64 that we definitely *should* update the timbre here, + // but only in the case that the sysex actually writes to those values + if (i == first && off > 2) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Not updating timbre, since those values weren't touched)"); +#endif + } else { + parts[i]->setTimbre(&mt32ram.timbres[parts[i]->getAbsTimbreNum()].timbre); + } + } + parts[i]->refresh(); + } + } + break; + case MR_RhythmTemp: + region->write(first, off, data, len); + for (unsigned int i = first; i <= last; i++) { + int timbreNum = mt32ram.rhythmTemp[i].timbre; + char timbreName[11]; + if (timbreNum < 94) { + memcpy(timbreName, mt32ram.timbres[128 + timbreNum].timbre.common.name, 10); + timbreName[10] = 0; + } else { + strcpy(timbreName, "[None]"); + } +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("WRITE-RHYTHM (%d-%d@%d..%d): %d; level=%02x, panpot=%02x, reverb=%02x, timbre=%d (%s)", first, last, off, off + len, i, mt32ram.rhythmTemp[i].outputLevel, mt32ram.rhythmTemp[i].panpot, mt32ram.rhythmTemp[i].reverbSwitch, mt32ram.rhythmTemp[i].timbre, timbreName); +#endif + } + if (parts[8] != NULL) { + parts[8]->refresh(); + } + break; + case MR_TimbreTemp: + region->write(first, off, data, len); + for (unsigned int i = first; i <= last; i++) { + char instrumentName[11]; + memcpy(instrumentName, mt32ram.timbreTemp[i].common.name, 10); + instrumentName[10] = 0; +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("WRITE-PARTTIMBRE (%d-%d@%d..%d): timbre=%d (%s)", first, last, off, off + len, i, instrumentName); +#endif + if (parts[i] != NULL) { + parts[i]->refresh(); + } + } + break; + case MR_Patches: + region->write(first, off, data, len); +#if MT32EMU_MONITOR_SYSEX > 0 + for (unsigned int i = first; i <= last; i++) { + PatchParam *patch = &mt32ram.patches[i]; + int patchAbsTimbreNum = patch->timbreGroup * 64 + patch->timbreNum; + char instrumentName[11]; + memcpy(instrumentName, mt32ram.timbres[patchAbsTimbreNum].timbre.common.name, 10); + instrumentName[10] = 0; + Bit8u *n = (Bit8u *)patch; + printDebug("WRITE-PATCH (%d-%d@%d..%d): %d; timbre=%d (%s) %02X%02X%02X%02X%02X%02X%02X%02X", first, last, off, off + len, i, patchAbsTimbreNum, instrumentName, n[0], n[1], n[2], n[3], n[4], n[5], n[6], n[7]); + } +#endif + break; + case MR_Timbres: + // Timbres + first += 128; + last += 128; + region->write(first, off, data, len); + for (unsigned int i = first; i <= last; i++) { +#if MT32EMU_MONITOR_TIMBRES >= 1 + TimbreParam *timbre = &mt32ram.timbres[i].timbre; + char instrumentName[11]; + memcpy(instrumentName, timbre->common.name, 10); + instrumentName[10] = 0; + printDebug("WRITE-TIMBRE (%d-%d@%d..%d): %d; name=\"%s\"", first, last, off, off + len, i, instrumentName); +#if MT32EMU_MONITOR_TIMBRES >= 2 +#define DT(x) printDebug(" " #x ": %d", timbre->x) + DT(common.partialStructure12); + DT(common.partialStructure34); + DT(common.partialMute); + DT(common.noSustain); + +#define DTP(x) \ + DT(partial[x].wg.pitchCoarse); \ + DT(partial[x].wg.pitchFine); \ + DT(partial[x].wg.pitchKeyfollow); \ + DT(partial[x].wg.pitchBenderEnabled); \ + DT(partial[x].wg.waveform); \ + DT(partial[x].wg.pcmWave); \ + DT(partial[x].wg.pulseWidth); \ + DT(partial[x].wg.pulseWidthVeloSensitivity); \ + DT(partial[x].pitchEnv.depth); \ + DT(partial[x].pitchEnv.veloSensitivity); \ + DT(partial[x].pitchEnv.timeKeyfollow); \ + DT(partial[x].pitchEnv.time[0]); \ + DT(partial[x].pitchEnv.time[1]); \ + DT(partial[x].pitchEnv.time[2]); \ + DT(partial[x].pitchEnv.time[3]); \ + DT(partial[x].pitchEnv.level[0]); \ + DT(partial[x].pitchEnv.level[1]); \ + DT(partial[x].pitchEnv.level[2]); \ + DT(partial[x].pitchEnv.level[3]); \ + DT(partial[x].pitchEnv.level[4]); \ + DT(partial[x].pitchLFO.rate); \ + DT(partial[x].pitchLFO.depth); \ + DT(partial[x].pitchLFO.modSensitivity); \ + DT(partial[x].tvf.cutoff); \ + DT(partial[x].tvf.resonance); \ + DT(partial[x].tvf.keyfollow); \ + DT(partial[x].tvf.biasPoint); \ + DT(partial[x].tvf.biasLevel); \ + DT(partial[x].tvf.envDepth); \ + DT(partial[x].tvf.envVeloSensitivity); \ + DT(partial[x].tvf.envDepthKeyfollow); \ + DT(partial[x].tvf.envTimeKeyfollow); \ + DT(partial[x].tvf.envTime[0]); \ + DT(partial[x].tvf.envTime[1]); \ + DT(partial[x].tvf.envTime[2]); \ + DT(partial[x].tvf.envTime[3]); \ + DT(partial[x].tvf.envTime[4]); \ + DT(partial[x].tvf.envLevel[0]); \ + DT(partial[x].tvf.envLevel[1]); \ + DT(partial[x].tvf.envLevel[2]); \ + DT(partial[x].tvf.envLevel[3]); \ + DT(partial[x].tva.level); \ + DT(partial[x].tva.veloSensitivity); \ + DT(partial[x].tva.biasPoint1); \ + DT(partial[x].tva.biasLevel1); \ + DT(partial[x].tva.biasPoint2); \ + DT(partial[x].tva.biasLevel2); \ + DT(partial[x].tva.envTimeKeyfollow); \ + DT(partial[x].tva.envTimeVeloSensitivity); \ + DT(partial[x].tva.envTime[0]); \ + DT(partial[x].tva.envTime[1]); \ + DT(partial[x].tva.envTime[2]); \ + DT(partial[x].tva.envTime[3]); \ + DT(partial[x].tva.envTime[4]); \ + DT(partial[x].tva.envLevel[0]); \ + DT(partial[x].tva.envLevel[1]); \ + DT(partial[x].tva.envLevel[2]); \ + DT(partial[x].tva.envLevel[3]); + + DTP(0); + DTP(1); + DTP(2); + DTP(3); +#undef DTP +#undef DT +#endif +#endif + // FIXME:KG: Not sure if the stuff below should be done (for rhythm and/or parts)... + // Does the real MT-32 automatically do this? + for (unsigned int part = 0; part < 9; part++) { + if (parts[part] != NULL) { + parts[part]->refreshTimbre(i); + } + } + } + break; + case MR_System: + region->write(0, off, data, len); + + reportHandler->onDeviceReconfig(); + // FIXME: We haven't properly confirmed any of this behaviour + // In particular, we tend to reset things such as reverb even if the write contained + // the same parameters as were already set, which may be wrong. + // On the other hand, the real thing could be resetting things even when they aren't touched + // by the write at all. +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("WRITE-SYSTEM:"); +#endif + if (off <= SYSTEM_MASTER_TUNE_OFF && off + len > SYSTEM_MASTER_TUNE_OFF) { + refreshSystemMasterTune(); + } + if (off <= SYSTEM_REVERB_LEVEL_OFF && off + len > SYSTEM_REVERB_MODE_OFF) { + refreshSystemReverbParameters(); + } + if (off <= SYSTEM_RESERVE_SETTINGS_END_OFF && off + len > SYSTEM_RESERVE_SETTINGS_START_OFF) { + refreshSystemReserveSettings(); + } + if (off <= SYSTEM_CHAN_ASSIGN_END_OFF && off + len > SYSTEM_CHAN_ASSIGN_START_OFF) { + int firstPart = off - SYSTEM_CHAN_ASSIGN_START_OFF; + if(firstPart < 0) + firstPart = 0; + int lastPart = off + len - SYSTEM_CHAN_ASSIGN_START_OFF; + if(lastPart > 8) + lastPart = 8; + refreshSystemChanAssign(Bit8u(firstPart), Bit8u(lastPart)); + } + if (off <= SYSTEM_MASTER_VOL_OFF && off + len > SYSTEM_MASTER_VOL_OFF) { + refreshSystemMasterVol(); + } + break; + case MR_Display: + char buf[SYSEX_BUFFER_SIZE]; + memcpy(&buf, &data[0], len); + buf[len] = 0; +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("WRITE-LCD: %s", buf); +#endif + reportHandler->showLCDMessage(buf); + break; + case MR_Reset: + reset(); + break; + } +} + +void Synth::refreshSystemMasterTune() { +#if MT32EMU_MONITOR_SYSEX > 0 + //FIXME:KG: This is just an educated guess. + // The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here) + // The MT-32 documentation claims a range of 432.1Hz-457.6Hz + float masterTune = 440.0f * EXP2F((mt32ram.system.masterTune - 64.0f) / (128.0f * 12.0f)); + printDebug(" Master Tune: %f", masterTune); +#endif +} + +void Synth::refreshSystemReverbParameters() { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel); +#endif + if (reverbOverridden) { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" (Reverb overridden - ignoring)"); +#endif + return; + } + reportHandler->onNewReverbMode(mt32ram.system.reverbMode); + reportHandler->onNewReverbTime(mt32ram.system.reverbTime); + reportHandler->onNewReverbLevel(mt32ram.system.reverbLevel); + + BReverbModel *oldReverbModel = reverbModel; + if (mt32ram.system.reverbTime == 0 && mt32ram.system.reverbLevel == 0) { + // Setting both time and level to 0 effectively disables wet reverb output on real devices. + // Take a shortcut in this case to reduce CPU load. + reverbModel = NULL; + } else { + reverbModel = reverbModels[mt32ram.system.reverbMode]; + } + if (reverbModel != oldReverbModel) { +#if MT32EMU_REDUCE_REVERB_MEMORY + if (oldReverbModel != NULL) { + oldReverbModel->close(); + } + if (isReverbEnabled()) { + reverbModel->open(); + } +#else + if (isReverbEnabled()) { + reverbModel->mute(); + } +#endif + } + if (isReverbEnabled()) { + reverbModel->setParameters(mt32ram.system.reverbTime, mt32ram.system.reverbLevel); + } +} + +void Synth::refreshSystemReserveSettings() { + Bit8u *rset = mt32ram.system.reserveSettings; +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" Partial reserve: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]); +#endif + partialManager->setReserve(rset); +} + +void Synth::refreshSystemChanAssign(Bit8u firstPart, Bit8u lastPart) { + memset(chantable, 0xFF, sizeof(chantable)); + + // CONFIRMED: In the case of assigning a channel to multiple parts, the lower part wins. + for (Bit32u i = 0; i <= 8; i++) { + if (parts[i] != NULL && i >= firstPart && i <= lastPart) { + // CONFIRMED: Decay is started for all polys, and all controllers are reset, for every part whose assignment was touched by the sysex write. + parts[i]->allSoundOff(); + parts[i]->resetAllControllers(); + } + Bit8u chan = mt32ram.system.chanAssign[i]; + if (chan < 16 && chantable[chan] > 8) { + chantable[chan] = Bit8u(i); + } + } + +#if MT32EMU_MONITOR_SYSEX > 0 + Bit8u *rset = mt32ram.system.chanAssign; + printDebug(" Part assign: 1=%02d 2=%02d 3=%02d 4=%02d 5=%02d 6=%02d 7=%02d 8=%02d Rhythm=%02d", rset[0], rset[1], rset[2], rset[3], rset[4], rset[5], rset[6], rset[7], rset[8]); +#endif +} + +void Synth::refreshSystemMasterVol() { +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug(" Master volume: %d", mt32ram.system.masterVol); +#endif +} + +void Synth::refreshSystem() { + refreshSystemMasterTune(); + refreshSystemReverbParameters(); + refreshSystemReserveSettings(); + refreshSystemChanAssign(0, 8); + refreshSystemMasterVol(); +} + +void Synth::reset() { + if (!opened) return; +#if MT32EMU_MONITOR_SYSEX > 0 + printDebug("RESET"); +#endif + reportHandler->onDeviceReset(); + partialManager->deactivateAll(); + mt32ram = mt32default; + for (int i = 0; i < 9; i++) { + parts[i]->reset(); + if (i != 8) { + parts[i]->setProgram(controlROMData[controlROMMap->programSettings + i]); + } else { + parts[8]->refresh(); + } + } + refreshSystem(); + isActive(); +} + +MidiEvent::~MidiEvent() { + if (sysexData != NULL) { + delete[] sysexData; + } +} + +void MidiEvent::setShortMessage(Bit32u useShortMessageData, Bit32u useTimestamp) { + if (sysexData != NULL) { + delete[] sysexData; + } + shortMessageData = useShortMessageData; + timestamp = useTimestamp; + sysexData = NULL; + sysexLength = 0; +} + +void MidiEvent::setSysex(const Bit8u *useSysexData, Bit32u useSysexLength, Bit32u useTimestamp) { + if (sysexData != NULL) { + delete[] sysexData; + } + shortMessageData = 0; + timestamp = useTimestamp; + sysexLength = useSysexLength; + Bit8u *dstSysexData = new Bit8u[sysexLength]; + sysexData = dstSysexData; + memcpy(dstSysexData, useSysexData, sysexLength); +} + +MidiEventQueue::MidiEventQueue(Bit32u useRingBufferSize) : ringBuffer(new MidiEvent[useRingBufferSize]), ringBufferMask(useRingBufferSize - 1) { + memset(ringBuffer, 0, useRingBufferSize * sizeof(MidiEvent)); + reset(); +} + +MidiEventQueue::~MidiEventQueue() { + delete[] ringBuffer; +} + +void MidiEventQueue::reset() { + startPosition = 0; + endPosition = 0; +} + +bool MidiEventQueue::pushShortMessage(Bit32u shortMessageData, Bit32u timestamp) { + Bit32u newEndPosition = (endPosition + 1) & ringBufferMask; + // Is ring buffer full? + if (startPosition == newEndPosition) return false; + ringBuffer[endPosition].setShortMessage(shortMessageData, timestamp); + endPosition = newEndPosition; + return true; +} + +bool MidiEventQueue::pushSysex(const Bit8u *sysexData, Bit32u sysexLength, Bit32u timestamp) { + Bit32u newEndPosition = (endPosition + 1) & ringBufferMask; + // Is ring buffer full? + if (startPosition == newEndPosition) return false; + ringBuffer[endPosition].setSysex(sysexData, sysexLength, timestamp); + endPosition = newEndPosition; + return true; +} + +const MidiEvent *MidiEventQueue::peekMidiEvent() { + return isEmpty() ? NULL : &ringBuffer[startPosition]; +} + +void MidiEventQueue::dropMidiEvent() { + // Is ring buffer empty? + if (startPosition != endPosition) { + startPosition = (startPosition + 1) & ringBufferMask; + } +} + +bool MidiEventQueue::isFull() const { + return startPosition == ((endPosition + 1) & ringBufferMask); +} + +bool MidiEventQueue::isEmpty() const { + return startPosition == endPosition; +} + +void Synth::selectRendererType(RendererType newRendererType) { + extensions.selectedRendererType = newRendererType; +} + +RendererType Synth::getSelectedRendererType() const { + return extensions.selectedRendererType; +} + +Bit32u Synth::getStereoOutputSampleRate() const { + return (analog == NULL) ? SAMPLE_RATE : analog->getOutputSampleRate(); +} + +template +void RendererImpl::doRender(Sample *stereoStream, Bit32u len) { + if (!isActivated()) { + incRenderedSampleCount(getAnalog().getDACStreamsLength(len)); + if (!getAnalog().process(NULL, NULL, NULL, NULL, NULL, NULL, stereoStream, len)) { + printDebug("RendererImpl: Invalid call to Analog::process()!\n"); + } + Synth::muteSampleBuffer(stereoStream, len << 1); + return; + } + + while (len > 0) { + // As in AnalogOutputMode_ACCURATE mode output is upsampled, MAX_SAMPLES_PER_RUN is more than enough for the temp buffers. + Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; + doRenderStreams(tmpBuffers, getAnalog().getDACStreamsLength(thisPassLen)); + if (!getAnalog().process(stereoStream, tmpNonReverbLeft, tmpNonReverbRight, tmpReverbDryLeft, tmpReverbDryRight, tmpReverbWetLeft, tmpReverbWetRight, thisPassLen)) { + printDebug("RendererImpl: Invalid call to Analog::process()!\n"); + Synth::muteSampleBuffer(stereoStream, len << 1); + return; + } + stereoStream += thisPassLen << 1; + len -= thisPassLen; + } +} + +template +template +void RendererImpl::doRenderAndConvert(O *stereoStream, Bit32u len) { + Sample renderingBuffer[MAX_SAMPLES_PER_RUN << 1]; + while (len > 0) { + Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; + doRender(renderingBuffer, thisPassLen); + convertSampleFormat(renderingBuffer, stereoStream, thisPassLen << 1); + stereoStream += thisPassLen << 1; + len -= thisPassLen; + } +} + +template<> +void RendererImpl::render(IntSample *stereoStream, Bit32u len) { + doRender(stereoStream, len); +} + +template<> +void RendererImpl::render(FloatSample *stereoStream, Bit32u len) { + doRenderAndConvert(stereoStream, len); +} + +template<> +void RendererImpl::render(IntSample *stereoStream, Bit32u len) { + doRenderAndConvert(stereoStream, len); +} + +template<> +void RendererImpl::render(FloatSample *stereoStream, Bit32u len) { + doRender(stereoStream, len); +} + +template +static inline void renderStereo(bool opened, Renderer *renderer, S *stream, Bit32u len) { + if (opened) { + renderer->render(stream, len); + } else { + Synth::muteSampleBuffer(stream, len << 1); + } +} + +void Synth::render(Bit16s *stream, Bit32u len) { + renderStereo(opened, renderer, stream, len); +} + +void Synth::render(float *stream, Bit32u len) { + renderStereo(opened, renderer, stream, len); +} + +template +static inline void advanceStream(Sample *&stream, Bit32u len) { + if (stream != NULL) { + stream += len; + } +} + +template +static inline void advanceStreams(DACOutputStreams &streams, Bit32u len) { + advanceStream(streams.nonReverbLeft, len); + advanceStream(streams.nonReverbRight, len); + advanceStream(streams.reverbDryLeft, len); + advanceStream(streams.reverbDryRight, len); + advanceStream(streams.reverbWetLeft, len); + advanceStream(streams.reverbWetRight, len); +} + +template +static inline void muteStreams(const DACOutputStreams &streams, Bit32u len) { + Synth::muteSampleBuffer(streams.nonReverbLeft, len); + Synth::muteSampleBuffer(streams.nonReverbRight, len); + Synth::muteSampleBuffer(streams.reverbDryLeft, len); + Synth::muteSampleBuffer(streams.reverbDryRight, len); + Synth::muteSampleBuffer(streams.reverbWetLeft, len); + Synth::muteSampleBuffer(streams.reverbWetRight, len); +} + +template +static inline void convertStreamsFormat(const DACOutputStreams &inStreams, const DACOutputStreams &outStreams, Bit32u len) { + convertSampleFormat(inStreams.nonReverbLeft, outStreams.nonReverbLeft, len); + convertSampleFormat(inStreams.nonReverbRight, outStreams.nonReverbRight, len); + convertSampleFormat(inStreams.reverbDryLeft, outStreams.reverbDryLeft, len); + convertSampleFormat(inStreams.reverbDryRight, outStreams.reverbDryRight, len); + convertSampleFormat(inStreams.reverbWetLeft, outStreams.reverbWetLeft, len); + convertSampleFormat(inStreams.reverbWetRight, outStreams.reverbWetRight, len); +} + +template +void RendererImpl::doRenderStreams(const DACOutputStreams &streams, Bit32u len) +{ + DACOutputStreams tmpStreams = streams; + while (len > 0) { + // We need to ensure zero-duration notes will play so add minimum 1-sample delay. + Bit32u thisLen = 1; + if (!isAbortingPoly()) { + const MidiEvent *nextEvent = getMidiQueue().peekMidiEvent(); + Bit32s samplesToNextEvent = (nextEvent != NULL) ? Bit32s(nextEvent->timestamp - getRenderedSampleCount()) : MAX_SAMPLES_PER_RUN; + if (samplesToNextEvent > 0) { + thisLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; + if (thisLen > Bit32u(samplesToNextEvent)) { + thisLen = samplesToNextEvent; + } + } else { + if (nextEvent->sysexData == NULL) { + synth.playMsgNow(nextEvent->shortMessageData); + // If a poly is aborting we don't drop the event from the queue. + // Instead, we'll return to it again when the abortion is done. + if (!isAbortingPoly()) { + getMidiQueue().dropMidiEvent(); + } + } else { + synth.playSysexNow(nextEvent->sysexData, nextEvent->sysexLength); + getMidiQueue().dropMidiEvent(); + } + } + } + produceStreams(tmpStreams, thisLen); + advanceStreams(tmpStreams, thisLen); + len -= thisLen; + } +} + +template +template +void RendererImpl::doRenderAndConvertStreams(const DACOutputStreams &streams, Bit32u len) { + Sample cnvNonReverbLeft[MAX_SAMPLES_PER_RUN], cnvNonReverbRight[MAX_SAMPLES_PER_RUN]; + Sample cnvReverbDryLeft[MAX_SAMPLES_PER_RUN], cnvReverbDryRight[MAX_SAMPLES_PER_RUN]; + Sample cnvReverbWetLeft[MAX_SAMPLES_PER_RUN], cnvReverbWetRight[MAX_SAMPLES_PER_RUN]; + + const DACOutputStreams cnvStreams = { + cnvNonReverbLeft, cnvNonReverbRight, + cnvReverbDryLeft, cnvReverbDryRight, + cnvReverbWetLeft, cnvReverbWetRight + }; + + DACOutputStreams tmpStreams = streams; + + while (len > 0) { + Bit32u thisPassLen = len > MAX_SAMPLES_PER_RUN ? MAX_SAMPLES_PER_RUN : len; + doRenderStreams(cnvStreams, thisPassLen); + convertStreamsFormat(cnvStreams, tmpStreams, thisPassLen); + advanceStreams(tmpStreams, thisPassLen); + len -= thisPassLen; + } +} + +template<> +void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { + doRenderStreams(streams, len); +} + +template<> +void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { + doRenderAndConvertStreams(streams, len); +} + +template<> +void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { + doRenderAndConvertStreams(streams, len); +} + +template<> +void RendererImpl::renderStreams(const DACOutputStreams &streams, Bit32u len) { + doRenderStreams(streams, len); +} + +template +static inline void renderStreams(bool opened, Renderer *renderer, const DACOutputStreams &streams, Bit32u len) { + if (opened) { + renderer->renderStreams(streams, len); + } else { + muteStreams(streams, len); + } +} + +void Synth::renderStreams(const DACOutputStreams &streams, Bit32u len) { + MT32Emu::renderStreams(opened, renderer, streams, len); +} + +void Synth::renderStreams(const DACOutputStreams &streams, Bit32u len) { + MT32Emu::renderStreams(opened, renderer, streams, len); +} + +void Synth::renderStreams( + Bit16s *nonReverbLeft, Bit16s *nonReverbRight, + Bit16s *reverbDryLeft, Bit16s *reverbDryRight, + Bit16s *reverbWetLeft, Bit16s *reverbWetRight, + Bit32u len) +{ + DACOutputStreams streams = { + nonReverbLeft, nonReverbRight, + reverbDryLeft, reverbDryRight, + reverbWetLeft, reverbWetRight + }; + renderStreams(streams, len); +} + +void Synth::renderStreams( + float *nonReverbLeft, float *nonReverbRight, + float *reverbDryLeft, float *reverbDryRight, + float *reverbWetLeft, float *reverbWetRight, + Bit32u len) +{ + DACOutputStreams streams = { + nonReverbLeft, nonReverbRight, + reverbDryLeft, reverbDryRight, + reverbWetLeft, reverbWetRight + }; + renderStreams(streams, len); +} + +// In GENERATION2 units, the output from LA32 goes to the Boss chip already bit-shifted. +// In NICE mode, it's also better to increase volume before the reverb processing to preserve accuracy. +template <> +void RendererImpl::produceLA32Output(IntSample *buffer, Bit32u len) { + switch (synth.getDACInputMode()) { + case DACInputMode_GENERATION2: + while (len--) { + *buffer = (*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE) | ((*buffer >> 14) & 0x0001); + ++buffer; + } + break; + case DACInputMode_NICE: + while (len--) { + *buffer = Synth::clipSampleEx(IntSampleEx(*buffer) << 1); + ++buffer; + } + break; + default: + break; + } +} + +template <> +void RendererImpl::convertSamplesToOutput(IntSample *buffer, Bit32u len) { + if (synth.getDACInputMode() == DACInputMode_GENERATION1) { + while (len--) { + *buffer = IntSample((*buffer & 0x8000) | ((*buffer << 1) & 0x7FFE)); + ++buffer; + } + } +} + +static inline float produceDistortedSample(float sample) { + if (sample < -2.0f) { + return sample + 4.0f; + } else if (2.0f < sample) { + return sample - 4.0f; + } + return sample; +} + +template <> +void RendererImpl::produceLA32Output(FloatSample *buffer, Bit32u len) { + if (synth.getDACInputMode() == DACInputMode_GENERATION2) { + while (len--) { + *buffer = produceDistortedSample(*buffer); + buffer++; + } + } +} + +template <> +void RendererImpl::convertSamplesToOutput(FloatSample *buffer, Bit32u len) { + if (synth.getDACInputMode() == DACInputMode_GENERATION1) { + while (len--) { + *buffer = produceDistortedSample(*buffer); + buffer++; + } + } +} + +template +void RendererImpl::produceStreams(const DACOutputStreams &streams, Bit32u len) { + if (isActivated()) { + // Even if LA32 output isn't desired, we proceed anyway with temp buffers + Sample *nonReverbLeft = streams.nonReverbLeft == NULL ? tmpNonReverbLeft : streams.nonReverbLeft; + Sample *nonReverbRight = streams.nonReverbRight == NULL ? tmpNonReverbRight : streams.nonReverbRight; + Sample *reverbDryLeft = streams.reverbDryLeft == NULL ? tmpReverbDryLeft : streams.reverbDryLeft; + Sample *reverbDryRight = streams.reverbDryRight == NULL ? tmpReverbDryRight : streams.reverbDryRight; + + Synth::muteSampleBuffer(nonReverbLeft, len); + Synth::muteSampleBuffer(nonReverbRight, len); + Synth::muteSampleBuffer(reverbDryLeft, len); + Synth::muteSampleBuffer(reverbDryRight, len); + + for (unsigned int i = 0; i < synth.getPartialCount(); i++) { + if (getPartialManager().shouldReverb(i)) { + getPartialManager().produceOutput(i, reverbDryLeft, reverbDryRight, len); + } else { + getPartialManager().produceOutput(i, nonReverbLeft, nonReverbRight, len); + } + } + + produceLA32Output(reverbDryLeft, len); + produceLA32Output(reverbDryRight, len); + + if (synth.isReverbEnabled()) { + if (!getReverbModel().process(reverbDryLeft, reverbDryRight, streams.reverbWetLeft, streams.reverbWetRight, len)) { + printDebug("RendererImpl: Invalid call to BReverbModel::process()!\n"); + } + if (streams.reverbWetLeft != NULL) convertSamplesToOutput(streams.reverbWetLeft, len); + if (streams.reverbWetRight != NULL) convertSamplesToOutput(streams.reverbWetRight, len); + } else { + Synth::muteSampleBuffer(streams.reverbWetLeft, len); + Synth::muteSampleBuffer(streams.reverbWetRight, len); + } + + // Don't bother with conversion if the output is going to be unused + if (streams.nonReverbLeft != NULL) { + produceLA32Output(nonReverbLeft, len); + convertSamplesToOutput(nonReverbLeft, len); + } + if (streams.nonReverbRight != NULL) { + produceLA32Output(nonReverbRight, len); + convertSamplesToOutput(nonReverbRight, len); + } + if (streams.reverbDryLeft != NULL) convertSamplesToOutput(reverbDryLeft, len); + if (streams.reverbDryRight != NULL) convertSamplesToOutput(reverbDryRight, len); + } else { + muteStreams(streams, len); + } + + getPartialManager().clearAlreadyOutputed(); + incRenderedSampleCount(len); +} + +void Synth::printPartialUsage(Bit32u sampleOffset) { + unsigned int partialUsage[9]; + partialManager->getPerPartPartialUsage(partialUsage); + if (sampleOffset > 0) { + printDebug("[+%u] Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", sampleOffset, partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount()); + } else { + printDebug("Partial Usage: 1:%02d 2:%02d 3:%02d 4:%02d 5:%02d 6:%02d 7:%02d 8:%02d R: %02d TOTAL: %02d", partialUsage[0], partialUsage[1], partialUsage[2], partialUsage[3], partialUsage[4], partialUsage[5], partialUsage[6], partialUsage[7], partialUsage[8], getPartialCount() - partialManager->getFreePartialCount()); + } +} + +bool Synth::hasActivePartials() const { + if (!opened) { + return false; + } + for (unsigned int partialNum = 0; partialNum < getPartialCount(); partialNum++) { + if (partialManager->getPartial(partialNum)->isActive()) { + return true; + } + } + return false; +} + +bool Synth::isActive() { + if (!opened) { + return false; + } + if (!midiQueue->isEmpty() || hasActivePartials()) { + return true; + } + if (isReverbEnabled() && reverbModel->isActive()) { + return true; + } + activated = false; + return false; +} + +Bit32u Synth::getPartialCount() const { + return partialCount; +} + +void Synth::getPartStates(bool *partStates) const { + if (!opened) { + memset(partStates, 0, 9 * sizeof(bool)); + return; + } + for (int partNumber = 0; partNumber < 9; partNumber++) { + const Part *part = parts[partNumber]; + partStates[partNumber] = part->getActiveNonReleasingPartialCount() > 0; + } +} + +Bit32u Synth::getPartStates() const { + if (!opened) return 0; + bool partStates[9]; + getPartStates(partStates); + Bit32u bitSet = 0; + for (int partNumber = 8; partNumber >= 0; partNumber--) { + bitSet = (bitSet << 1) | (partStates[partNumber] ? 1 : 0); + } + return bitSet; +} + +void Synth::getPartialStates(PartialState *partialStates) const { + if (!opened) { + memset(partialStates, 0, partialCount * sizeof(PartialState)); + return; + } + for (unsigned int partialNum = 0; partialNum < partialCount; partialNum++) { + partialStates[partialNum] = getPartialState(partialManager, partialNum); + } +} + +void Synth::getPartialStates(Bit8u *partialStates) const { + if (!opened) { + memset(partialStates, 0, ((partialCount + 3) >> 2)); + return; + } + for (unsigned int quartNum = 0; (4 * quartNum) < partialCount; quartNum++) { + Bit8u packedStates = 0; + for (unsigned int i = 0; i < 4; i++) { + unsigned int partialNum = (4 * quartNum) + i; + if (partialCount <= partialNum) break; + PartialState partialState = getPartialState(partialManager, partialNum); + packedStates |= (partialState & 3) << (2 * i); + } + partialStates[quartNum] = packedStates; + } +} + +Bit32u Synth::getPlayingNotes(Bit8u partNumber, Bit8u *keys, Bit8u *velocities) const { + Bit32u playingNotes = 0; + if (opened && (partNumber < 9)) { + const Part *part = parts[partNumber]; + const Poly *poly = part->getFirstActivePoly(); + while (poly != NULL) { + keys[playingNotes] = Bit8u(poly->getKey()); + velocities[playingNotes] = Bit8u(poly->getVelocity()); + playingNotes++; + poly = poly->getNext(); + } + } + return playingNotes; +} + +const char *Synth::getPatchName(Bit8u partNumber) const { + return (!opened || partNumber > 8) ? NULL : parts[partNumber]->getCurrentInstr(); +} + +const Part *Synth::getPart(Bit8u partNum) const { + if (partNum > 8) { + return NULL; + } + return parts[partNum]; +} + +void MemoryRegion::read(unsigned int entry, unsigned int off, Bit8u *dst, unsigned int len) const { + off += entry * entrySize; + // This method should never be called with out-of-bounds parameters, + // or on an unsupported region - seeing any of this debug output indicates a bug in the emulator + if (off > entrySize * entries - 1) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("read[%d]: parameters start out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); +#endif + return; + } + if (off + len > entrySize * entries) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("read[%d]: parameters end out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); +#endif + len = entrySize * entries - off; + } + Bit8u *src = getRealMemory(); + if (src == NULL) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("read[%d]: unreadable region: entry=%d, off=%d, len=%d", type, entry, off, len); +#endif + return; + } + memcpy(dst, src + off, len); +} + +void MemoryRegion::write(unsigned int entry, unsigned int off, const Bit8u *src, unsigned int len, bool init) const { + unsigned int memOff = entry * entrySize + off; + // This method should never be called with out-of-bounds parameters, + // or on an unsupported region - seeing any of this debug output indicates a bug in the emulator + if (off > entrySize * entries - 1) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("write[%d]: parameters start out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); +#endif + return; + } + if (off + len > entrySize * entries) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("write[%d]: parameters end out of bounds: entry=%d, off=%d, len=%d", type, entry, off, len); +#endif + len = entrySize * entries - off; + } + Bit8u *dest = getRealMemory(); + if (dest == NULL) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("write[%d]: unwritable region: entry=%d, off=%d, len=%d", type, entry, off, len); +#endif + return; + } + + for (unsigned int i = 0; i < len; i++) { + Bit8u desiredValue = src[i]; + Bit8u maxValue = getMaxValue(memOff); + // maxValue == 0 means write-protected unless called from initialisation code, in which case it really means the maximum value is 0. + if (maxValue != 0 || init) { + if (desiredValue > maxValue) { +#if MT32EMU_MONITOR_SYSEX > 0 + synth->printDebug("write[%d]: Wanted 0x%02x at %d, but max 0x%02x", type, desiredValue, memOff, maxValue); +#endif + desiredValue = maxValue; + } + dest[memOff] = desiredValue; + } else if (desiredValue != 0) { +#if MT32EMU_MONITOR_SYSEX > 0 + // Only output debug info if they wanted to write non-zero, since a lot of things cause this to spit out a lot of debug info otherwise. + synth->printDebug("write[%d]: Wanted 0x%02x at %d, but write-protected", type, desiredValue, memOff); +#endif + } + memOff++; + } +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/Synth.h b/src/SOUND/munt/Synth.h new file mode 100644 index 000000000..4ce023201 --- /dev/null +++ b/src/SOUND/munt/Synth.h @@ -0,0 +1,484 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_SYNTH_H +#define MT32EMU_SYNTH_H + +#include +#include +#include + +#include "globals.h" +#include "Types.h" +#include "Enumerations.h" + +namespace MT32Emu { + +class Analog; +class BReverbModel; +class Extensions; +class MemoryRegion; +class MidiEventQueue; +class Part; +class Poly; +class Partial; +class PartialManager; +class Renderer; +class ROMImage; + +class PatchTempMemoryRegion; +class RhythmTempMemoryRegion; +class TimbreTempMemoryRegion; +class PatchesMemoryRegion; +class TimbresMemoryRegion; +class SystemMemoryRegion; +class DisplayMemoryRegion; +class ResetMemoryRegion; + +struct ControlROMFeatureSet; +struct ControlROMMap; +struct PCMWaveEntry; +struct MemParams; + +const Bit8u SYSEX_MANUFACTURER_ROLAND = 0x41; + +const Bit8u SYSEX_MDL_MT32 = 0x16; +const Bit8u SYSEX_MDL_D50 = 0x14; + +const Bit8u SYSEX_CMD_RQ1 = 0x11; // Request data #1 +const Bit8u SYSEX_CMD_DT1 = 0x12; // Data set 1 +const Bit8u SYSEX_CMD_WSD = 0x40; // Want to send data +const Bit8u SYSEX_CMD_RQD = 0x41; // Request data +const Bit8u SYSEX_CMD_DAT = 0x42; // Data set +const Bit8u SYSEX_CMD_ACK = 0x43; // Acknowledge +const Bit8u SYSEX_CMD_EOD = 0x45; // End of data +const Bit8u SYSEX_CMD_ERR = 0x4E; // Communications error +const Bit8u SYSEX_CMD_RJC = 0x4F; // Rejection + +const Bit32u CONTROL_ROM_SIZE = 64 * 1024; + +// Set of multiplexed output streams appeared at the DAC entrance. +template +struct DACOutputStreams { + T *nonReverbLeft; + T *nonReverbRight; + T *reverbDryLeft; + T *reverbDryRight; + T *reverbWetLeft; + T *reverbWetRight; +}; + +// Class for the client to supply callbacks for reporting various errors and information +class MT32EMU_EXPORT ReportHandler { +public: + virtual ~ReportHandler() {} + + // Callback for debug messages, in vprintf() format + virtual void printDebug(const char *fmt, va_list list); + // Callbacks for reporting errors + virtual void onErrorControlROM() {} + virtual void onErrorPCMROM() {} + // Callback for reporting about displaying a new custom message on LCD + virtual void showLCDMessage(const char *message); + // Callback for reporting actual processing of a MIDI message + virtual void onMIDIMessagePlayed() {} + // Callback for reporting an overflow of the input MIDI queue. + // Returns true if a recovery action was taken and yet another attempt to enqueue the MIDI event is desired. + virtual bool onMIDIQueueOverflow() { return false; } + // Callback invoked when a System Realtime MIDI message is detected at the input. + virtual void onMIDISystemRealtime(Bit8u /* systemRealtime */) {} + // Callbacks for reporting system events + virtual void onDeviceReset() {} + virtual void onDeviceReconfig() {} + // Callbacks for reporting changes of reverb settings + virtual void onNewReverbMode(Bit8u /* mode */) {} + virtual void onNewReverbTime(Bit8u /* time */) {} + virtual void onNewReverbLevel(Bit8u /* level */) {} + // Callbacks for reporting various information + virtual void onPolyStateChanged(Bit8u /* partNum */) {} + virtual void onProgramChanged(Bit8u /* partNum */, const char * /* soundGroupName */, const char * /* patchName */) {} +}; + +class Synth { +friend class DefaultMidiStreamParser; +friend class Part; +friend class Partial; +friend class PartialManager; +friend class Poly; +friend class Renderer; +friend class RhythmPart; +friend class SamplerateAdapter; +friend class SoxrAdapter; +friend class TVA; +friend class TVP; + +private: + // **************************** Implementation fields ************************** + + PatchTempMemoryRegion *patchTempMemoryRegion; + RhythmTempMemoryRegion *rhythmTempMemoryRegion; + TimbreTempMemoryRegion *timbreTempMemoryRegion; + PatchesMemoryRegion *patchesMemoryRegion; + TimbresMemoryRegion *timbresMemoryRegion; + SystemMemoryRegion *systemMemoryRegion; + DisplayMemoryRegion *displayMemoryRegion; + ResetMemoryRegion *resetMemoryRegion; + + Bit8u *paddedTimbreMaxTable; + + PCMWaveEntry *pcmWaves; // Array + + const ControlROMFeatureSet *controlROMFeatures; + const ControlROMMap *controlROMMap; + Bit8u controlROMData[CONTROL_ROM_SIZE]; + Bit16s *pcmROMData; + size_t pcmROMSize; // This is in 16-bit samples, therefore half the number of bytes in the ROM + + Bit8u soundGroupIx[128]; // For each standard timbre + const char (*soundGroupNames)[9]; // Array + + Bit32u partialCount; + Bit8u chantable[16]; // NOTE: value above 8 means that the channel is not assigned + + MidiEventQueue *midiQueue; + volatile Bit32u lastReceivedMIDIEventTimestamp; + volatile Bit32u renderedSampleCount; + + MemParams &mt32ram, &mt32default; + + BReverbModel *reverbModels[4]; + BReverbModel *reverbModel; + bool reverbOverridden; + + MIDIDelayMode midiDelayMode; + DACInputMode dacInputMode; + + float outputGain; + float reverbOutputGain; + + bool reversedStereoEnabled; + + bool opened; + bool activated; + + bool isDefaultReportHandler; + ReportHandler *reportHandler; + + PartialManager *partialManager; + Part *parts[9]; + + // When a partial needs to be aborted to free it up for use by a new Poly, + // the controller will busy-loop waiting for the sound to finish. + // We emulate this by delaying new MIDI events processing until abortion finishes. + Poly *abortingPoly; + + Analog *analog; + Renderer *renderer; + + // Binary compatibility helper. + Extensions &extensions; + + // **************************** Implementation methods ************************** + + Bit32u addMIDIInterfaceDelay(Bit32u len, Bit32u timestamp); + bool isAbortingPoly() const { return abortingPoly != NULL; } + + void readSysex(Bit8u channel, const Bit8u *sysex, Bit32u len) const; + void initMemoryRegions(); + void deleteMemoryRegions(); + MemoryRegion *findMemoryRegion(Bit32u addr); + void writeMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, const Bit8u *data); + void readMemoryRegion(const MemoryRegion *region, Bit32u addr, Bit32u len, Bit8u *data); + + bool loadControlROM(const ROMImage &controlROMImage); + bool loadPCMROM(const ROMImage &pcmROMImage); + + bool initPCMList(Bit16u mapAddress, Bit16u count); + bool initTimbres(Bit16u mapAddress, Bit16u offset, Bit16u timbreCount, Bit16u startTimbre, bool compressed); + bool initCompressedTimbre(Bit16u drumNum, const Bit8u *mem, Bit32u memLen); + void initReverbModels(bool mt32CompatibleMode); + void initSoundGroups(char newSoundGroupNames[][9]); + + void refreshSystemMasterTune(); + void refreshSystemReverbParameters(); + void refreshSystemReserveSettings(); + void refreshSystemChanAssign(Bit8u firstPart, Bit8u lastPart); + void refreshSystemMasterVol(); + void refreshSystem(); + void reset(); + void dispose(); + + void printPartialUsage(Bit32u sampleOffset = 0); + + void newTimbreSet(Bit8u partNum, Bit8u timbreGroup, Bit8u timbreNumber, const char patchName[]); + void printDebug(const char *fmt, ...); + + // partNum should be 0..7 for Part 1..8, or 8 for Rhythm + const Part *getPart(Bit8u partNum) const; + +public: + static inline Bit16s clipSampleEx(Bit32s sampleEx) { + // Clamp values above 32767 to 32767, and values below -32768 to -32768 + // FIXME: Do we really need this stuff? I think these branches are very well predicted. Instead, this introduces a chain. + // The version below is actually a bit faster on my system... + //return ((sampleEx + 0x8000) & ~0xFFFF) ? Bit16s((sampleEx >> 31) ^ 0x7FFF) : (Bit16s)sampleEx; + return ((-0x8000 <= sampleEx) && (sampleEx <= 0x7FFF)) ? Bit16s(sampleEx) : Bit16s((sampleEx >> 31) ^ 0x7FFF); + } + + static inline float clipSampleEx(float sampleEx) { + return sampleEx; + } + + template + static inline void muteSampleBuffer(S *buffer, Bit32u len) { + if (buffer == NULL) return; + memset(buffer, 0, len * sizeof(S)); + } + + static inline void muteSampleBuffer(float *buffer, Bit32u len) { + if (buffer == NULL) return; + // FIXME: Use memset() where compatibility is guaranteed (if this turns out to be a win) + while (len--) { + *(buffer++) = 0.0f; + } + } + + static inline Bit16s convertSample(float sample) { + return Synth::clipSampleEx(Bit32s(sample * 16384.0f)); // This multiplier takes into account the DAC bit shift + } + + static inline float convertSample(Bit16s sample) { + return float(sample) / 16384.0f; // This multiplier takes into account the DAC bit shift + } + + // Returns library version as an integer in format: 0x00MMmmpp, where: + // MM - major version number + // mm - minor version number + // pp - patch number + MT32EMU_EXPORT static Bit32u getLibraryVersionInt(); + // Returns library version as a C-string in format: "MAJOR.MINOR.PATCH" + MT32EMU_EXPORT static const char *getLibraryVersionString(); + + MT32EMU_EXPORT static Bit32u getShortMessageLength(Bit32u msg); + MT32EMU_EXPORT static Bit8u calcSysexChecksum(const Bit8u *data, const Bit32u len, const Bit8u initChecksum = 0); + + // Returns output sample rate used in emulation of stereo analog circuitry of hardware units. + // See comment for AnalogOutputMode. + MT32EMU_EXPORT static Bit32u getStereoOutputSampleRate(AnalogOutputMode analogOutputMode); + + // Optionally sets callbacks for reporting various errors, information and debug messages + MT32EMU_EXPORT explicit Synth(ReportHandler *useReportHandler = NULL); + MT32EMU_EXPORT ~Synth(); + + // Used to initialise the MT-32. Must be called before any other function. + // Returns true if initialization was sucessful, otherwise returns false. + // controlROMImage and pcmROMImage represent Control and PCM ROM images for use by synth. + // usePartialCount sets the maximum number of partials playing simultaneously for this session (optional). + // analogOutputMode sets the mode for emulation of analogue circuitry of the hardware units (optional). + MT32EMU_EXPORT bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, Bit32u usePartialCount = DEFAULT_MAX_PARTIALS, AnalogOutputMode analogOutputMode = AnalogOutputMode_COARSE); + + // Overloaded method which opens the synth with default partial count. + MT32EMU_EXPORT bool open(const ROMImage &controlROMImage, const ROMImage &pcmROMImage, AnalogOutputMode analogOutputMode); + + // Closes the MT-32 and deallocates any memory used by the synthesizer + MT32EMU_EXPORT void close(); + + // Returns true if the synth is in completely initialized state, otherwise returns false. + MT32EMU_EXPORT bool isOpen() const; + + // All the enqueued events are processed by the synth immediately. + MT32EMU_EXPORT void flushMIDIQueue(); + + // Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified. + // The queue is flushed before reallocation. + // Returns the actual queue size being used. + MT32EMU_EXPORT Bit32u setMIDIEventQueueSize(Bit32u); + + // Enqueues a MIDI event for subsequent playback. + // The MIDI event will be processed not before the specified timestamp. + // The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz). + // The minimum delay involves emulation of the delay introduced while the event is transferred via MIDI interface + // and emulation of the MCU busy-loop while it frees partials for use by a new Poly. + // Calls from multiple threads must be synchronised, although, no synchronisation is required with the rendering thread. + // The methods return false if the MIDI event queue is full and the message cannot be enqueued. + + // Enqueues a single short MIDI message to play at specified time. The message must contain a status byte. + MT32EMU_EXPORT bool playMsg(Bit32u msg, Bit32u timestamp); + // Enqueues a single well formed System Exclusive MIDI message to play at specified time. + MT32EMU_EXPORT bool playSysex(const Bit8u *sysex, Bit32u len, Bit32u timestamp); + + // Enqueues a single short MIDI message to be processed ASAP. The message must contain a status byte. + MT32EMU_EXPORT bool playMsg(Bit32u msg); + // Enqueues a single well formed System Exclusive MIDI message to be processed ASAP. + MT32EMU_EXPORT bool playSysex(const Bit8u *sysex, Bit32u len); + + // WARNING: + // The methods below don't ensure minimum 1-sample delay between sequential MIDI events, + // and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent. + // A thread that invokes these methods must be explicitly synchronised with the thread performing sample rendering. + + // Sends a short MIDI message to the synth for immediate playback. The message must contain a status byte. + // See the WARNING above. + MT32EMU_EXPORT void playMsgNow(Bit32u msg); + // Sends unpacked short MIDI message to the synth for immediate playback. The message must contain a status byte. + // See the WARNING above. + MT32EMU_EXPORT void playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity); + + // Sends a single well formed System Exclusive MIDI message for immediate processing. The length is in bytes. + // See the WARNING above. + MT32EMU_EXPORT void playSysexNow(const Bit8u *sysex, Bit32u len); + // Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. + // See the WARNING above. + MT32EMU_EXPORT void playSysexWithoutFraming(const Bit8u *sysex, Bit32u len); + // Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. + // See the WARNING above. + MT32EMU_EXPORT void playSysexWithoutHeader(Bit8u device, Bit8u command, const Bit8u *sysex, Bit32u len); + // Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. + // See the WARNING above. + MT32EMU_EXPORT void writeSysex(Bit8u channel, const Bit8u *sysex, Bit32u len); + + // Allows to disable wet reverb output altogether. + MT32EMU_EXPORT void setReverbEnabled(bool reverbEnabled); + // Returns whether wet reverb output is enabled. + MT32EMU_EXPORT bool isReverbEnabled() const; + // Sets override reverb mode. In this mode, emulation ignores sysexes (or the related part of them) which control the reverb parameters. + // This mode is in effect until it is turned off. When the synth is re-opened, the override mode is unchanged but the state + // of the reverb model is reset to default. + MT32EMU_EXPORT void setReverbOverridden(bool reverbOverridden); + // Returns whether reverb settings are overridden. + MT32EMU_EXPORT bool isReverbOverridden() const; + // Forces reverb model compatibility mode. By default, the compatibility mode corresponds to the used control ROM version. + // Invoking this method with the argument set to true forces emulation of old MT-32 reverb circuit. + // When the argument is false, emulation of the reverb circuit used in new generation of MT-32 compatible modules is enforced + // (these include CM-32L and LAPC-I). + MT32EMU_EXPORT void setReverbCompatibilityMode(bool mt32CompatibleMode); + // Returns whether reverb is in old MT-32 compatibility mode. + MT32EMU_EXPORT bool isMT32ReverbCompatibilityMode() const; + // Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. + MT32EMU_EXPORT bool isDefaultReverbMT32Compatible() const; + // Sets new DAC input mode. See DACInputMode for details. + MT32EMU_EXPORT void setDACInputMode(DACInputMode mode); + // Returns current DAC input mode. See DACInputMode for details. + MT32EMU_EXPORT DACInputMode getDACInputMode() const; + // Sets new MIDI delay mode. See MIDIDelayMode for details. + MT32EMU_EXPORT void setMIDIDelayMode(MIDIDelayMode mode); + // Returns current MIDI delay mode. See MIDIDelayMode for details. + MT32EMU_EXPORT MIDIDelayMode getMIDIDelayMode() const; + + // Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume, + // it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with setReverbOutputGain() + // it offers to the user a capability to control the gain of reverb and non-reverb output channels independently. + // Ignored in DACInputMode_PURE + MT32EMU_EXPORT void setOutputGain(float gain); + // Returns current output gain factor for synth output channels. + MT32EMU_EXPORT float getOutputGain() const; + + // Sets output gain factor for the reverb wet output channels. It rather corresponds to the gain of the output + // analog circuitry of the hardware units. However, together with setOutputGain() it offers to the user a capability + // to control the gain of reverb and non-reverb output channels independently. + // + // Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely + // corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic, + // there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68 + // of that for LA32 analogue output. This factor is applied to the reverb output gain. + // Ignored in DACInputMode_PURE + MT32EMU_EXPORT void setReverbOutputGain(float gain); + // Returns current output gain factor for reverb wet output channels. + MT32EMU_EXPORT float getReverbOutputGain() const; + + // Swaps left and right output channels. + MT32EMU_EXPORT void setReversedStereoEnabled(bool enabled); + // Returns whether left and right output channels are swapped. + MT32EMU_EXPORT bool isReversedStereoEnabled() const; + + // Selects new type of the wave generator and renderer to be used during subsequent calls to open(). + // By default, RendererType_BIT16S is selected. + // See RendererType for details. + MT32EMU_EXPORT void selectRendererType(RendererType); + // Returns previously selected type of the wave generator and renderer. + // See RendererType for details. + MT32EMU_EXPORT RendererType getSelectedRendererType() const; + + // Returns actual sample rate used in emulation of stereo analog circuitry of hardware units. + // See comment for render() below. + MT32EMU_EXPORT Bit32u getStereoOutputSampleRate() const; + + // Renders samples to the specified output stream as if they were sampled at the analog stereo output. + // When AnalogOutputMode is set to ACCURATE (OVERSAMPLED), the output signal is upsampled to 48 (96) kHz in order + // to retain emulation accuracy in whole audible frequency spectra. Otherwise, native digital signal sample rate is retained. + // getStereoOutputSampleRate() can be used to query actual sample rate of the output signal. + // The length is in frames, not bytes (in 16-bit stereo, one frame is 4 bytes). Uses NATIVE byte ordering. + MT32EMU_EXPORT void render(Bit16s *stream, Bit32u len); + // Same as above but outputs to a float stereo stream. + MT32EMU_EXPORT void render(float *stream, Bit32u len); + + // Renders samples to the specified output streams as if they appeared at the DAC entrance. + // No further processing performed in analog circuitry emulation is applied to the signal. + // NULL may be specified in place of any or all of the stream buffers to skip it. + // The length is in samples, not bytes. Uses NATIVE byte ordering. + MT32EMU_EXPORT void renderStreams(Bit16s *nonReverbLeft, Bit16s *nonReverbRight, Bit16s *reverbDryLeft, Bit16s *reverbDryRight, Bit16s *reverbWetLeft, Bit16s *reverbWetRight, Bit32u len); + MT32EMU_EXPORT void renderStreams(const DACOutputStreams &streams, Bit32u len); + // Same as above but outputs to float streams. + MT32EMU_EXPORT void renderStreams(float *nonReverbLeft, float *nonReverbRight, float *reverbDryLeft, float *reverbDryRight, float *reverbWetLeft, float *reverbWetRight, Bit32u len); + MT32EMU_EXPORT void renderStreams(const DACOutputStreams &streams, Bit32u len); + + // Returns true when there is at least one active partial, otherwise false. + MT32EMU_EXPORT bool hasActivePartials() const; + + // Returns true if the synth is active and subsequent calls to render() may result in non-trivial output (i.e. silence). + // The synth is considered active when either there are pending MIDI events in the queue, there is at least one active partial, + // or the reverb is (somewhat unreliably) detected as being active. + MT32EMU_EXPORT bool isActive(); + + // Returns the maximum number of partials playing simultaneously. + MT32EMU_EXPORT Bit32u getPartialCount() const; + + // Fills in current states of all the parts into the array provided. The array must have at least 9 entries to fit values for all the parts. + // If the value returned for a part is true, there is at least one active non-releasing partial playing on this part. + // This info is useful in emulating behaviour of LCD display of the hardware units. + MT32EMU_EXPORT void getPartStates(bool *partStates) const; + + // Returns current states of all the parts as a bit set. The least significant bit corresponds to the state of part 1, + // total of 9 bits hold the states of all the parts. If the returned bit for a part is set, there is at least one active + // non-releasing partial playing on this part. This info is useful in emulating behaviour of LCD display of the hardware units. + MT32EMU_EXPORT Bit32u getPartStates() const; + + // Fills in current states of all the partials into the array provided. The array must be large enough to accommodate states of all the partials. + MT32EMU_EXPORT void getPartialStates(PartialState *partialStates) const; + + // Fills in current states of all the partials into the array provided. Each byte in the array holds states of 4 partials + // starting from the least significant bits. The state of each partial is packed in a pair of bits. + // The array must be large enough to accommodate states of all the partials (see getPartialCount()). + MT32EMU_EXPORT void getPartialStates(Bit8u *partialStates) const; + + // Fills in information about currently playing notes on the specified part into the arrays provided. The arrays must be large enough + // to accommodate data for all the playing notes. The maximum number of simultaneously playing notes cannot exceed the number of partials. + // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. + // Returns the number of currently playing notes on the specified part. + MT32EMU_EXPORT Bit32u getPlayingNotes(Bit8u partNumber, Bit8u *keys, Bit8u *velocities) const; + + // Returns name of the patch set on the specified part. + // Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. + MT32EMU_EXPORT const char *getPatchName(Bit8u partNumber) const; + + // Stores internal state of emulated synth into an array provided (as it would be acquired from hardware). + MT32EMU_EXPORT void readMemory(Bit32u addr, Bit32u len, Bit8u *data); +}; // class Synth + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_SYNTH_H diff --git a/src/SOUND/munt/TVA.cpp b/src/SOUND/munt/TVA.cpp new file mode 100644 index 000000000..d75abe50a --- /dev/null +++ b/src/SOUND/munt/TVA.cpp @@ -0,0 +1,370 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/* + * This class emulates the calculations performed by the 8095 microcontroller in order to configure the LA-32's amplitude ramp for a single partial at each stage of its TVA envelope. + * Unless we introduced bugs, it should be pretty much 100% accurate according to Mok's specifications. +*/ + +#include "internals.h" + +#include "TVA.h" +#include "Part.h" +#include "Partial.h" +#include "Poly.h" +#include "Synth.h" +#include "Tables.h" + +namespace MT32Emu { + +// CONFIRMED: Matches a table in ROM - haven't got around to coming up with a formula for it yet. +static Bit8u biasLevelToAmpSubtractionCoeff[13] = {255, 187, 137, 100, 74, 54, 40, 29, 21, 15, 10, 5, 0}; + +TVA::TVA(const Partial *usePartial, LA32Ramp *useAmpRamp) : + partial(usePartial), ampRamp(useAmpRamp), system(&usePartial->getSynth()->mt32ram.system), phase(TVA_PHASE_DEAD) { +} + +void TVA::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { + target = newTarget; + phase = newPhase; + ampRamp->startRamp(newTarget, newIncrement); +#if MT32EMU_MONITOR_TVA >= 1 + partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,ramp,%d,%d,%d,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), (newIncrement & 0x80) ? -1 : 1, (newIncrement & 0x7F), newPhase); +#endif +} + +void TVA::end(int newPhase) { + phase = newPhase; + playing = false; +#if MT32EMU_MONITOR_TVA >= 1 + partial->getSynth()->printDebug("[+%lu] [Partial %d] TVA,end,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newPhase); +#endif +} + +static int multBias(Bit8u biasLevel, int bias) { + return (bias * biasLevelToAmpSubtractionCoeff[biasLevel]) >> 5; +} + +static int calcBiasAmpSubtraction(Bit8u biasPoint, Bit8u biasLevel, int key) { + if ((biasPoint & 0x40) == 0) { + int bias = biasPoint + 33 - key; + if (bias > 0) { + return multBias(biasLevel, bias); + } + } else { + int bias = biasPoint - 31 - key; + if (bias < 0) { + bias = -bias; + return multBias(biasLevel, bias); + } + } + return 0; +} + +static int calcBiasAmpSubtractions(const TimbreParam::PartialParam *partialParam, int key) { + int biasAmpSubtraction1 = calcBiasAmpSubtraction(partialParam->tva.biasPoint1, partialParam->tva.biasLevel1, key); + if (biasAmpSubtraction1 > 255) { + return 255; + } + int biasAmpSubtraction2 = calcBiasAmpSubtraction(partialParam->tva.biasPoint2, partialParam->tva.biasLevel2, key); + if (biasAmpSubtraction2 > 255) { + return 255; + } + int biasAmpSubtraction = biasAmpSubtraction1 + biasAmpSubtraction2; + if (biasAmpSubtraction > 255) { + return 255; + } + return biasAmpSubtraction; +} + +static int calcVeloAmpSubtraction(Bit8u veloSensitivity, unsigned int velocity) { + // FIXME:KG: Better variable names + int velocityMult = veloSensitivity - 50; + int absVelocityMult = velocityMult < 0 ? -velocityMult : velocityMult; + velocityMult = signed(unsigned(velocityMult * (signed(velocity) - 64)) << 2); + return absVelocityMult - (velocityMult >> 8); // PORTABILITY NOTE: Assumes arithmetic shift +} + +static int calcBasicAmp(const Tables *tables, const Partial *partial, const MemParams::System *system, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, const MemParams::RhythmTemp *rhythmTemp, int biasAmpSubtraction, int veloAmpSubtraction, Bit8u expression) { + int amp = 155; + + if (!partial->isRingModulatingSlave()) { + amp -= tables->masterVolToAmpSubtraction[system->masterVol]; + if (amp < 0) { + return 0; + } + amp -= tables->levelToAmpSubtraction[patchTemp->outputLevel]; + if (amp < 0) { + return 0; + } + amp -= tables->levelToAmpSubtraction[expression]; + if (amp < 0) { + return 0; + } + if (rhythmTemp != NULL) { + amp -= tables->levelToAmpSubtraction[rhythmTemp->outputLevel]; + if (amp < 0) { + return 0; + } + } + } + amp -= biasAmpSubtraction; + if (amp < 0) { + return 0; + } + amp -= tables->levelToAmpSubtraction[partialParam->tva.level]; + if (amp < 0) { + return 0; + } + amp -= veloAmpSubtraction; + if (amp < 0) { + return 0; + } + if (amp > 155) { + amp = 155; + } + amp -= partialParam->tvf.resonance >> 1; + if (amp < 0) { + return 0; + } + return amp; +} + +static int calcKeyTimeSubtraction(Bit8u envTimeKeyfollow, int key) { + if (envTimeKeyfollow == 0) { + return 0; + } + return (key - 60) >> (5 - envTimeKeyfollow); // PORTABILITY NOTE: Assumes arithmetic shift +} + +void TVA::reset(const Part *newPart, const TimbreParam::PartialParam *newPartialParam, const MemParams::RhythmTemp *newRhythmTemp) { + part = newPart; + partialParam = newPartialParam; + patchTemp = newPart->getPatchTemp(); + rhythmTemp = newRhythmTemp; + + playing = true; + + const Tables *tables = &Tables::getInstance(); + + int key = partial->getPoly()->getKey(); + int velocity = partial->getPoly()->getVelocity(); + + keyTimeSubtraction = calcKeyTimeSubtraction(partialParam->tva.envTimeKeyfollow, key); + + biasAmpSubtraction = calcBiasAmpSubtractions(partialParam, key); + veloAmpSubtraction = calcVeloAmpSubtraction(partialParam->tva.veloSensitivity, velocity); + + int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, newRhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression()); + int newPhase; + if (partialParam->tva.envTime[0] == 0) { + // Initially go to the TVA_PHASE_ATTACK target amp, and spend the next phase going from there to the TVA_PHASE_2 target amp + // Note that this means that velocity never affects time for this partial. + newTarget += partialParam->tva.envLevel[0]; + newPhase = TVA_PHASE_ATTACK; // The first target used in nextPhase() will be TVA_PHASE_2 + } else { + // Initially go to the base amp determined by TVA level, part volume, etc., and spend the next phase going from there to the full TVA_PHASE_ATTACK target amp. + newPhase = TVA_PHASE_BASIC; // The first target used in nextPhase() will be TVA_PHASE_ATTACK + } + + ampRamp->reset();//currentAmp = 0; + + // "Go downward as quickly as possible". + // Since the current value is 0, the LA32Ramp will notice that we're already at or below the target and trying to go downward, + // and therefore jump to the target immediately and raise an interrupt. + startRamp(Bit8u(newTarget), 0x80 | 127, newPhase); +} + +void TVA::startAbort() { + startRamp(64, 0x80 | 127, TVA_PHASE_RELEASE); +} + +void TVA::startDecay() { + if (phase >= TVA_PHASE_RELEASE) { + return; + } + Bit8u newIncrement; + if (partialParam->tva.envTime[4] == 0) { + newIncrement = 1; + } else { + newIncrement = -partialParam->tva.envTime[4]; + } + // The next time nextPhase() is called, it will think TVA_PHASE_RELEASE has finished and the partial will be aborted + startRamp(0, newIncrement, TVA_PHASE_RELEASE); +} + +void TVA::handleInterrupt() { + nextPhase(); +} + +void TVA::recalcSustain() { + // We get pinged periodically by the pitch code to recalculate our values when in sustain. + // This is done so that the TVA will respond to things like MIDI expression and volume changes while it's sustaining, which it otherwise wouldn't do. + + // The check for envLevel[3] == 0 strikes me as slightly dumb. FIXME: Explain why + if (phase != TVA_PHASE_SUSTAIN || partialParam->tva.envLevel[3] == 0) { + return; + } + // We're sustaining. Recalculate all the values + const Tables *tables = &Tables::getInstance(); + int newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression()); + newTarget += partialParam->tva.envLevel[3]; + // Since we're in TVA_PHASE_SUSTAIN at this point, we know that target has been reached and an interrupt fired, so we can rely on it being the current amp. + int targetDelta = newTarget - target; + + // Calculate an increment to get to the new amp value in a short, more or less consistent amount of time + Bit8u newIncrement; + if (targetDelta >= 0) { + newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - 2; + } else { + newIncrement = (tables->envLogarithmicTime[Bit8u(-targetDelta)] - 2) | 0x80; + } + // Configure so that once the transition's complete and nextPhase() is called, we'll just re-enter sustain phase (or decay phase, depending on parameters at the time). + startRamp(newTarget, newIncrement, TVA_PHASE_SUSTAIN - 1); +} + +bool TVA::isPlaying() const { + return playing; +} + +int TVA::getPhase() const { + return phase; +} + +void TVA::nextPhase() { + const Tables *tables = &Tables::getInstance(); + + if (phase >= TVA_PHASE_DEAD || !playing) { + partial->getSynth()->printDebug("TVA::nextPhase(): Shouldn't have got here with phase %d, playing=%s", phase, playing ? "true" : "false"); + return; + } + int newPhase = phase + 1; + + if (newPhase == TVA_PHASE_DEAD) { + end(newPhase); + return; + } + + bool allLevelsZeroFromNowOn = false; + if (partialParam->tva.envLevel[3] == 0) { + if (newPhase == TVA_PHASE_4) { + allLevelsZeroFromNowOn = true; + } else if (partialParam->tva.envLevel[2] == 0) { + if (newPhase == TVA_PHASE_3) { + allLevelsZeroFromNowOn = true; + } else if (partialParam->tva.envLevel[1] == 0) { + if (newPhase == TVA_PHASE_2) { + allLevelsZeroFromNowOn = true; + } else if (partialParam->tva.envLevel[0] == 0) { + if (newPhase == TVA_PHASE_ATTACK) { // this line added, missing in ROM - FIXME: Add description of repercussions + allLevelsZeroFromNowOn = true; + } + } + } + } + } + + int newTarget; + int newIncrement = 0; // Initialised to please compilers + int envPointIndex = phase; + + if (!allLevelsZeroFromNowOn) { + newTarget = calcBasicAmp(tables, partial, system, partialParam, patchTemp, rhythmTemp, biasAmpSubtraction, veloAmpSubtraction, part->getExpression()); + + if (newPhase == TVA_PHASE_SUSTAIN || newPhase == TVA_PHASE_RELEASE) { + if (partialParam->tva.envLevel[3] == 0) { + end(newPhase); + return; + } + if (!partial->getPoly()->canSustain()) { + newPhase = TVA_PHASE_RELEASE; + newTarget = 0; + newIncrement = -partialParam->tva.envTime[4]; + if (newIncrement == 0) { + // We can't let the increment be 0, or there would be no emulated interrupt. + // So we do an "upward" increment, which should set the amp to 0 extremely quickly + // and cause an "interrupt" to bring us back to nextPhase(). + newIncrement = 1; + } + } else { + newTarget += partialParam->tva.envLevel[3]; + newIncrement = 0; + } + } else { + newTarget += partialParam->tva.envLevel[envPointIndex]; + } + } else { + newTarget = 0; + } + + if ((newPhase != TVA_PHASE_SUSTAIN && newPhase != TVA_PHASE_RELEASE) || allLevelsZeroFromNowOn) { + int envTimeSetting = partialParam->tva.envTime[envPointIndex]; + + if (newPhase == TVA_PHASE_ATTACK) { + envTimeSetting -= (signed(partial->getPoly()->getVelocity()) - 64) >> (6 - partialParam->tva.envTimeVeloSensitivity); // PORTABILITY NOTE: Assumes arithmetic shift + + if (envTimeSetting <= 0 && partialParam->tva.envTime[envPointIndex] != 0) { + envTimeSetting = 1; + } + } else { + envTimeSetting -= keyTimeSubtraction; + } + if (envTimeSetting > 0) { + int targetDelta = newTarget - target; + if (targetDelta <= 0) { + if (targetDelta == 0) { + // target and newTarget are the same. + // We can't have an increment of 0 or we wouldn't get an emulated interrupt. + // So instead make the target one less than it really should be and set targetDelta accordingly. + targetDelta = -1; + newTarget--; + if (newTarget < 0) { + // Oops, newTarget is less than zero now, so let's do it the other way: + // Make newTarget one more than it really should've been and set targetDelta accordingly. + // FIXME (apparent bug in real firmware): + // This means targetDelta will be positive just below here where it's inverted, and we'll end up using envLogarithmicTime[-1], and we'll be setting newIncrement to be descending later on, etc.. + targetDelta = 1; + newTarget = -newTarget; + } + } + targetDelta = -targetDelta; + newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - envTimeSetting; + if (newIncrement <= 0) { + newIncrement = 1; + } + newIncrement = newIncrement | 0x80; + } else { + // FIXME: The last 22 or so entries in this table are 128 - surely that fucks things up, since that ends up being -128 signed? + newIncrement = tables->envLogarithmicTime[Bit8u(targetDelta)] - envTimeSetting; + if (newIncrement <= 0) { + newIncrement = 1; + } + } + } else { + newIncrement = newTarget >= target ? (0x80 | 127) : 127; + } + + // FIXME: What's the point of this? It's checked or set to non-zero everywhere above + if (newIncrement == 0) { + newIncrement = 1; + } + } + + startRamp(Bit8u(newTarget), Bit8u(newIncrement), newPhase); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/TVA.h b/src/SOUND/munt/TVA.h new file mode 100644 index 000000000..cf9296d48 --- /dev/null +++ b/src/SOUND/munt/TVA.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_TVA_H +#define MT32EMU_TVA_H + +#include "globals.h" +#include "Types.h" +#include "Structures.h" + +namespace MT32Emu { + +class LA32Ramp; +class Part; +class Partial; + +// Note that when entering nextPhase(), newPhase is set to phase + 1, and the descriptions/names below refer to +// newPhase's value. +enum { + // In this phase, the base amp (as calculated in calcBasicAmp()) is targeted with an instant time. + // This phase is entered by reset() only if time[0] != 0. + TVA_PHASE_BASIC = 0, + + // In this phase, level[0] is targeted within time[0], and velocity potentially affects time + TVA_PHASE_ATTACK = 1, + + // In this phase, level[1] is targeted within time[1] + TVA_PHASE_2 = 2, + + // In this phase, level[2] is targeted within time[2] + TVA_PHASE_3 = 3, + + // In this phase, level[3] is targeted within time[3] + TVA_PHASE_4 = 4, + + // In this phase, immediately goes to PHASE_RELEASE unless the poly is set to sustain. + // Aborts the partial if level[3] is 0. + // Otherwise level[3] is continued, no phase change will occur until some external influence (like pedal release) + TVA_PHASE_SUSTAIN = 5, + + // In this phase, 0 is targeted within time[4] (the time calculation is quite different from the other phases) + TVA_PHASE_RELEASE = 6, + + // It's PHASE_DEAD, Jim. + TVA_PHASE_DEAD = 7 +}; + +class TVA { +private: + const Partial * const partial; + LA32Ramp *ampRamp; + const MemParams::System * const system; + + const Part *part; + const TimbreParam::PartialParam *partialParam; + const MemParams::PatchTemp *patchTemp; + const MemParams::RhythmTemp *rhythmTemp; + + bool playing; + + int biasAmpSubtraction; + int veloAmpSubtraction; + int keyTimeSubtraction; + + Bit8u target; + int phase; + + void startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase); + void end(int newPhase); + void nextPhase(); + +public: + TVA(const Partial *partial, LA32Ramp *ampRamp); + void reset(const Part *part, const TimbreParam::PartialParam *partialParam, const MemParams::RhythmTemp *rhythmTemp); + void handleInterrupt(); + void recalcSustain(); + void startDecay(); + void startAbort(); + + bool isPlaying() const; + int getPhase() const; +}; // class TVA + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_TVA_H diff --git a/src/SOUND/munt/TVF.cpp b/src/SOUND/munt/TVF.cpp new file mode 100644 index 000000000..cafeb4a8d --- /dev/null +++ b/src/SOUND/munt/TVF.cpp @@ -0,0 +1,233 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "internals.h" + +#include "TVF.h" +#include "LA32Ramp.h" +#include "Partial.h" +#include "Poly.h" +#include "Tables.h" + +namespace MT32Emu { + +// Note that when entering nextPhase(), newPhase is set to phase + 1, and the descriptions/names below refer to +// newPhase's value. +enum { + // When this is the target phase, level[0] is targeted within time[0] + // Note that this phase is always set up in reset(), not nextPhase() + PHASE_ATTACK = 1, + + // When this is the target phase, level[1] is targeted within time[1] + PHASE_2 = 2, + + // When this is the target phase, level[2] is targeted within time[2] + PHASE_3 = 3, + + // When this is the target phase, level[3] is targeted within time[3] + PHASE_4 = 4, + + // When this is the target phase, immediately goes to PHASE_RELEASE unless the poly is set to sustain. + // Otherwise level[3] is continued with increment 0 - no phase change will occur until some external influence (like pedal release) + PHASE_SUSTAIN = 5, + + // 0 is targeted within time[4] (the time calculation is quite different from the other phases) + PHASE_RELEASE = 6, + + // 0 is targeted with increment 0 (thus theoretically staying that way forever) + PHASE_DONE = 7 +}; + +static int calcBaseCutoff(const TimbreParam::PartialParam *partialParam, Bit32u basePitch, unsigned int key) { + // This table matches the values used by a real LAPC-I. + static const Bit8s biasLevelToBiasMult[] = {85, 42, 21, 16, 10, 5, 2, 0, -2, -5, -10, -16, -21, -74, -85}; + // These values represent unique options with no consistent pattern, so we have to use something like a table in any case. + // The table entries, when divided by 21, match approximately what the manual claims: + // -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2 + // Note that the entry for 1/8 is rounded to 2 (from 1/8 * 21 = 2.625), which seems strangely inaccurate compared to the others. + static const Bit8s keyfollowMult21[] = {-21, -10, -5, 0, 2, 5, 8, 10, 13, 16, 18, 21, 26, 32, 42, 21, 21}; + int baseCutoff = keyfollowMult21[partialParam->tvf.keyfollow] - keyfollowMult21[partialParam->wg.pitchKeyfollow]; + // baseCutoff range now: -63 to 63 + baseCutoff *= int(key) - 60; + // baseCutoff range now: -3024 to 3024 + int biasPoint = partialParam->tvf.biasPoint; + if ((biasPoint & 0x40) == 0) { + // biasPoint range here: 0 to 63 + int bias = biasPoint + 33 - key; // bias range here: -75 to 84 + if (bias > 0) { + bias = -bias; // bias range here: -1 to -84 + baseCutoff += bias * biasLevelToBiasMult[partialParam->tvf.biasLevel]; // Calculation range: -7140 to 7140 + // baseCutoff range now: -10164 to 10164 + } + } else { + // biasPoint range here: 64 to 127 + int bias = biasPoint - 31 - key; // bias range here: -75 to 84 + if (bias < 0) { + baseCutoff += bias * biasLevelToBiasMult[partialParam->tvf.biasLevel]; // Calculation range: -6375 to 6375 + // baseCutoff range now: -9399 to 9399 + } + } + // baseCutoff range now: -10164 to 10164 + baseCutoff += ((partialParam->tvf.cutoff << 4) - 800); + // baseCutoff range now: -10964 to 10964 + if (baseCutoff >= 0) { + // FIXME: Potentially bad if baseCutoff ends up below -2056? + int pitchDeltaThing = (basePitch >> 4) + baseCutoff - 3584; + if (pitchDeltaThing > 0) { + baseCutoff -= pitchDeltaThing; + } + } else if (baseCutoff < -2048) { + baseCutoff = -2048; + } + baseCutoff += 2056; + baseCutoff >>= 4; // PORTABILITY NOTE: Hmm... Depends whether it could've been below -2056, but maybe arithmetic shift assumed? + if (baseCutoff > 255) { + baseCutoff = 255; + } + return Bit8u(baseCutoff); +} + +TVF::TVF(const Partial *usePartial, LA32Ramp *useCutoffModifierRamp) : + partial(usePartial), cutoffModifierRamp(useCutoffModifierRamp) { +} + +void TVF::startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase) { + target = newTarget; + phase = newPhase; + cutoffModifierRamp->startRamp(newTarget, newIncrement); +#if MT32EMU_MONITOR_TVF >= 1 + partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,ramp,%d,%d,%d,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), newTarget, (newIncrement & 0x80) ? -1 : 1, (newIncrement & 0x7F), newPhase); +#endif +} + +void TVF::reset(const TimbreParam::PartialParam *newPartialParam, unsigned int basePitch) { + partialParam = newPartialParam; + + unsigned int key = partial->getPoly()->getKey(); + unsigned int velocity = partial->getPoly()->getVelocity(); + + const Tables *tables = &Tables::getInstance(); + + baseCutoff = calcBaseCutoff(newPartialParam, basePitch, key); +#if MT32EMU_MONITOR_TVF >= 1 + partial->getSynth()->printDebug("[+%lu] [Partial %d] TVF,base,%d", partial->debugGetSampleNum(), partial->debugGetPartialNum(), baseCutoff); +#endif + + int newLevelMult = velocity * newPartialParam->tvf.envVeloSensitivity; + newLevelMult >>= 6; + newLevelMult += 109 - newPartialParam->tvf.envVeloSensitivity; + newLevelMult += (signed(key) - 60) >> (4 - newPartialParam->tvf.envDepthKeyfollow); + if (newLevelMult < 0) { + newLevelMult = 0; + } + newLevelMult *= newPartialParam->tvf.envDepth; + newLevelMult >>= 6; + if (newLevelMult > 255) { + newLevelMult = 255; + } + levelMult = newLevelMult; + + if (newPartialParam->tvf.envTimeKeyfollow != 0) { + keyTimeSubtraction = (signed(key) - 60) >> (5 - newPartialParam->tvf.envTimeKeyfollow); + } else { + keyTimeSubtraction = 0; + } + + int newTarget = (newLevelMult * newPartialParam->tvf.envLevel[0]) >> 8; + int envTimeSetting = newPartialParam->tvf.envTime[0] - keyTimeSubtraction; + int newIncrement; + if (envTimeSetting <= 0) { + newIncrement = (0x80 | 127); + } else { + newIncrement = tables->envLogarithmicTime[newTarget] - envTimeSetting; + if (newIncrement <= 0) { + newIncrement = 1; + } + } + cutoffModifierRamp->reset(); + startRamp(newTarget, newIncrement, PHASE_2 - 1); +} + +Bit8u TVF::getBaseCutoff() const { + return baseCutoff; +} + +void TVF::handleInterrupt() { + nextPhase(); +} + +void TVF::startDecay() { + if (phase >= PHASE_RELEASE) { + return; + } + if (partialParam->tvf.envTime[4] == 0) { + startRamp(0, 1, PHASE_DONE - 1); + } else { + startRamp(0, -partialParam->tvf.envTime[4], PHASE_DONE - 1); + } +} + +void TVF::nextPhase() { + const Tables *tables = &Tables::getInstance(); + int newPhase = phase + 1; + + switch (newPhase) { + case PHASE_DONE: + startRamp(0, 0, newPhase); + return; + case PHASE_SUSTAIN: + case PHASE_RELEASE: + // FIXME: Afaict newPhase should never be PHASE_RELEASE here. And if it were, this is an odd way to handle it. + if (!partial->getPoly()->canSustain()) { + phase = newPhase; // FIXME: Correct? + startDecay(); // FIXME: This should actually start decay even if phase is already 6. Does that matter? + return; + } + startRamp((levelMult * partialParam->tvf.envLevel[3]) >> 8, 0, newPhase); + return; + } + + int envPointIndex = phase; + int envTimeSetting = partialParam->tvf.envTime[envPointIndex] - keyTimeSubtraction; + + int newTarget = (levelMult * partialParam->tvf.envLevel[envPointIndex]) >> 8; + int newIncrement; + if (envTimeSetting > 0) { + int targetDelta = newTarget - target; + if (targetDelta == 0) { + if (newTarget == 0) { + targetDelta = 1; + newTarget = 1; + } else { + targetDelta = -1; + newTarget--; + } + } + newIncrement = tables->envLogarithmicTime[targetDelta < 0 ? -targetDelta : targetDelta] - envTimeSetting; + if (newIncrement <= 0) { + newIncrement = 1; + } + if (targetDelta < 0) { + newIncrement |= 0x80; + } + } else { + newIncrement = newTarget >= target ? (0x80 | 127) : 127; + } + startRamp(newTarget, newIncrement, newPhase); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/TVF.h b/src/SOUND/munt/TVF.h new file mode 100644 index 000000000..e637aa5b4 --- /dev/null +++ b/src/SOUND/munt/TVF.h @@ -0,0 +1,61 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_TVF_H +#define MT32EMU_TVF_H + +#include "globals.h" +#include "Types.h" +#include "Structures.h" + +namespace MT32Emu { + +class LA32Ramp; +class Partial; + +class TVF { +private: + const Partial * const partial; + LA32Ramp *cutoffModifierRamp; + const TimbreParam::PartialParam *partialParam; + + Bit8u baseCutoff; + int keyTimeSubtraction; + unsigned int levelMult; + + Bit8u target; + unsigned int phase; + + void startRamp(Bit8u newTarget, Bit8u newIncrement, int newPhase); + void nextPhase(); + +public: + TVF(const Partial *partial, LA32Ramp *cutoffModifierRamp); + void reset(const TimbreParam::PartialParam *partialParam, Bit32u basePitch); + // Returns the base cutoff (without envelope modification). + // The base cutoff is calculated when reset() is called and remains static + // for the lifetime of the partial. + // Barring bugs, the number returned is confirmed accurate + // (based on specs from Mok). + Bit8u getBaseCutoff() const; + void handleInterrupt(); + void startDecay(); +}; // class TVF + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_TVF_H diff --git a/src/SOUND/munt/TVP.cpp b/src/SOUND/munt/TVP.cpp new file mode 100644 index 000000000..9adedf851 --- /dev/null +++ b/src/SOUND/munt/TVP.cpp @@ -0,0 +1,330 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "internals.h" + +#include "TVP.h" +#include "Part.h" +#include "Partial.h" +#include "Poly.h" +#include "Synth.h" +#include "TVA.h" + +namespace MT32Emu { + +// FIXME: Add Explanation +static Bit16u lowerDurationToDivisor[] = {34078, 37162, 40526, 44194, 48194, 52556, 57312, 62499}; + +// These values represent unique options with no consistent pattern, so we have to use something like a table in any case. +// The table matches exactly what the manual claims (when divided by 8192): +// -1, -1/2, -1/4, 0, 1/8, 1/4, 3/8, 1/2, 5/8, 3/4, 7/8, 1, 5/4, 3/2, 2, s1, s2 +// ...except for the last two entries, which are supposed to be "1 cent above 1" and "2 cents above 1", respectively. They can only be roughly approximated with this integer math. +static Bit16s pitchKeyfollowMult[] = {-8192, -4096, -2048, 0, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 10240, 12288, 16384, 8198, 8226}; + +// Note: Keys < 60 use keyToPitchTable[60 - key], keys >= 60 use keyToPitchTable[key - 60]. +// FIXME: This table could really be shorter, since we never use e.g. key 127. +static Bit16u keyToPitchTable[] = { + 0, 341, 683, 1024, 1365, 1707, 2048, 2389, + 2731, 3072, 3413, 3755, 4096, 4437, 4779, 5120, + 5461, 5803, 6144, 6485, 6827, 7168, 7509, 7851, + 8192, 8533, 8875, 9216, 9557, 9899, 10240, 10581, + 10923, 11264, 11605, 11947, 12288, 12629, 12971, 13312, + 13653, 13995, 14336, 14677, 15019, 15360, 15701, 16043, + 16384, 16725, 17067, 17408, 17749, 18091, 18432, 18773, + 19115, 19456, 19797, 20139, 20480, 20821, 21163, 21504, + 21845, 22187, 22528, 22869 +}; + +TVP::TVP(const Partial *usePartial) : + partial(usePartial), system(&usePartial->getSynth()->mt32ram.system) { + // We want to do processing 4000 times per second. FIXME: This is pretty arbitrary. + maxCounter = SAMPLE_RATE / 4000; + // The timer runs at 500kHz. We only need to bother updating it every maxCounter samples, before we do processing. + // This is how much to increment it by every maxCounter samples. + processTimerIncrement = 500000 * maxCounter / SAMPLE_RATE; +} + +static Bit16s keyToPitch(unsigned int key) { + // We're using a table to do: return round_to_nearest_or_even((key - 60) * (4096.0 / 12.0)) + // Banker's rounding is just slightly annoying to do in C++ + int k = int(key); + Bit16s pitch = keyToPitchTable[abs(k - 60)]; + return key < 60 ? -pitch : pitch; +} + +static inline Bit32s coarseToPitch(Bit8u coarse) { + return (coarse - 36) * 4096 / 12; // One semitone per coarse offset +} + +static inline Bit32s fineToPitch(Bit8u fine) { + return (fine - 50) * 4096 / 1200; // One cent per fine offset +} + +static Bit32u calcBasePitch(const Partial *partial, const TimbreParam::PartialParam *partialParam, const MemParams::PatchTemp *patchTemp, unsigned int key) { + Bit32s basePitch = keyToPitch(key); + basePitch = (basePitch * pitchKeyfollowMult[partialParam->wg.pitchKeyfollow]) >> 13; // PORTABILITY NOTE: Assumes arithmetic shift + basePitch += coarseToPitch(partialParam->wg.pitchCoarse); + basePitch += fineToPitch(partialParam->wg.pitchFine); + // NOTE:Mok: This is done on MT-32, but not LAPC-I: + //pitch += coarseToPitch(patchTemp->patch.keyShift + 12); + basePitch += fineToPitch(patchTemp->patch.fineTune); + + const ControlROMPCMStruct *controlROMPCMStruct = partial->getControlROMPCMStruct(); + if (controlROMPCMStruct != NULL) { + basePitch += (Bit32s(controlROMPCMStruct->pitchMSB) << 8) | Bit32s(controlROMPCMStruct->pitchLSB); + } else { + if ((partialParam->wg.waveform & 1) == 0) { + basePitch += 37133; // This puts Middle C at around 261.64Hz (assuming no other modifications, masterTune of 64, etc.) + } else { + // Sawtooth waves are effectively double the frequency of square waves. + // Thus we add 4096 less than for square waves here, which results in halving the frequency. + basePitch += 33037; + } + } + if (basePitch < 0) { + basePitch = 0; + } + if (basePitch > 59392) { + basePitch = 59392; + } + return Bit32u(basePitch); +} + +static Bit32u calcVeloMult(Bit8u veloSensitivity, unsigned int velocity) { + if (veloSensitivity == 0 || veloSensitivity > 3) { + // Note that on CM-32L/LAPC-I veloSensitivity is never > 3, since it's clipped to 3 by the max tables. + return 21845; // aka floor(4096 / 12 * 64), aka ~64 semitones + } + // When velocity is 127, the multiplier is 21845, aka ~64 semitones (regardless of veloSensitivity). + // The lower the velocity, the lower the multiplier. The veloSensitivity determines the amount decreased per velocity value. + // The minimum multiplier (with velocity 0, veloSensitivity 3) is 170 (~half a semitone). + Bit32u veloMult = 32768; + veloMult -= (127 - velocity) << (5 + veloSensitivity); + veloMult *= 21845; + veloMult >>= 15; + return veloMult; +} + +static Bit32s calcTargetPitchOffsetWithoutLFO(const TimbreParam::PartialParam *partialParam, int levelIndex, unsigned int velocity) { + int veloMult = calcVeloMult(partialParam->pitchEnv.veloSensitivity, velocity); + int targetPitchOffsetWithoutLFO = partialParam->pitchEnv.level[levelIndex] - 50; + targetPitchOffsetWithoutLFO = (targetPitchOffsetWithoutLFO * veloMult) >> (16 - partialParam->pitchEnv.depth); // PORTABILITY NOTE: Assumes arithmetic shift + return targetPitchOffsetWithoutLFO; +} + +void TVP::reset(const Part *usePart, const TimbreParam::PartialParam *usePartialParam) { + part = usePart; + partialParam = usePartialParam; + patchTemp = part->getPatchTemp(); + + unsigned int key = partial->getPoly()->getKey(); + unsigned int velocity = partial->getPoly()->getVelocity(); + + // FIXME: We're using a per-TVP timer instead of a system-wide one for convenience. + timeElapsed = 0; + + basePitch = calcBasePitch(partial, partialParam, patchTemp, key); + currentPitchOffset = calcTargetPitchOffsetWithoutLFO(partialParam, 0, velocity); + targetPitchOffsetWithoutLFO = currentPitchOffset; + phase = 0; + + if (partialParam->pitchEnv.timeKeyfollow) { + timeKeyfollowSubtraction = Bit32s(key - 60) >> (5 - partialParam->pitchEnv.timeKeyfollow); // PORTABILITY NOTE: Assumes arithmetic shift + } else { + timeKeyfollowSubtraction = 0; + } + lfoPitchOffset = 0; + counter = 0; + pitch = basePitch; + + // These don't really need to be initialised, but it aids debugging. + pitchOffsetChangePerBigTick = 0; + targetPitchOffsetReachedBigTick = 0; + shifts = 0; +} + +Bit32u TVP::getBasePitch() const { + return basePitch; +} + +void TVP::updatePitch() { + Bit32s newPitch = basePitch + currentPitchOffset; + if (!partial->isPCM() || (partial->getControlROMPCMStruct()->len & 0x01) == 0) { // FIXME: Use !partial->pcmWaveEntry->unaffectedByMasterTune instead + // FIXME: masterTune recalculation doesn't really happen here, and there are various bugs not yet emulated + // 171 is ~half a semitone. + newPitch += ((system->masterTune - 64) * 171) >> 6; // PORTABILITY NOTE: Assumes arithmetic shift. + } + if ((partialParam->wg.pitchBenderEnabled & 1) != 0) { + newPitch += part->getPitchBend(); + } + if (newPitch < 0) { + newPitch = 0; + } + + // Skipping this check seems about right emulation of MT-32 GEN0 quirk exploited in Colonel's Bequest timbre "Lightning" + if (partial->getSynth()->controlROMFeatures->quirkPitchEnvelopeOverflow == 0) { + if (newPitch > 59392) { + newPitch = 59392; + } + } + pitch = Bit16u(newPitch); + + // FIXME: We're doing this here because that's what the CM-32L does - we should probably move this somewhere more appropriate in future. + partial->getTVA()->recalcSustain(); +} + +void TVP::targetPitchOffsetReached() { + currentPitchOffset = targetPitchOffsetWithoutLFO + lfoPitchOffset; + + switch (phase) { + case 3: + case 4: + { + int newLFOPitchOffset = (part->getModulation() * partialParam->pitchLFO.modSensitivity) >> 7; + newLFOPitchOffset = (newLFOPitchOffset + partialParam->pitchLFO.depth) << 1; + if (pitchOffsetChangePerBigTick > 0) { + // Go in the opposite direction to last time + newLFOPitchOffset = -newLFOPitchOffset; + } + lfoPitchOffset = newLFOPitchOffset; + int targetPitchOffset = targetPitchOffsetWithoutLFO + lfoPitchOffset; + setupPitchChange(targetPitchOffset, 101 - partialParam->pitchLFO.rate); + updatePitch(); + break; + } + case 6: + updatePitch(); + break; + default: + nextPhase(); + } +} + +void TVP::nextPhase() { + phase++; + int envIndex = phase == 6 ? 4 : phase; + + targetPitchOffsetWithoutLFO = calcTargetPitchOffsetWithoutLFO(partialParam, envIndex, partial->getPoly()->getVelocity()); // pitch we'll reach at the end + + int changeDuration = partialParam->pitchEnv.time[envIndex - 1]; + changeDuration -= timeKeyfollowSubtraction; + if (changeDuration > 0) { + setupPitchChange(targetPitchOffsetWithoutLFO, changeDuration); // changeDuration between 0 and 112 now + updatePitch(); + } else { + targetPitchOffsetReached(); + } +} + +// Shifts val to the left until bit 31 is 1 and returns the number of shifts +static Bit8u normalise(Bit32u &val) { + Bit8u leftShifts; + for (leftShifts = 0; leftShifts < 31; leftShifts++) { + if ((val & 0x80000000) != 0) { + break; + } + val = val << 1; + } + return leftShifts; +} + +void TVP::setupPitchChange(int targetPitchOffset, Bit8u changeDuration) { + bool negativeDelta = targetPitchOffset < currentPitchOffset; + Bit32s pitchOffsetDelta = targetPitchOffset - currentPitchOffset; + if (pitchOffsetDelta > 32767 || pitchOffsetDelta < -32768) { + pitchOffsetDelta = 32767; + } + if (negativeDelta) { + pitchOffsetDelta = -pitchOffsetDelta; + } + // We want to maximise the number of bits of the Bit16s "pitchOffsetChangePerBigTick" we use in order to get the best possible precision later + Bit32u absPitchOffsetDelta = pitchOffsetDelta << 16; + Bit8u normalisationShifts = normalise(absPitchOffsetDelta); // FIXME: Double-check: normalisationShifts is usually between 0 and 15 here, unless the delta is 0, in which case it's 31 + absPitchOffsetDelta = absPitchOffsetDelta >> 1; // Make room for the sign bit + + changeDuration--; // changeDuration's now between 0 and 111 + unsigned int upperDuration = changeDuration >> 3; // upperDuration's now between 0 and 13 + shifts = normalisationShifts + upperDuration + 2; + Bit16u divisor = lowerDurationToDivisor[changeDuration & 7]; + Bit16s newPitchOffsetChangePerBigTick = ((absPitchOffsetDelta & 0xFFFF0000) / divisor) >> 1; // Result now fits within 15 bits. FIXME: Check nothing's getting sign-extended incorrectly + if (negativeDelta) { + newPitchOffsetChangePerBigTick = -newPitchOffsetChangePerBigTick; + } + pitchOffsetChangePerBigTick = newPitchOffsetChangePerBigTick; + + int currentBigTick = timeElapsed >> 8; + int durationInBigTicks = divisor >> (12 - upperDuration); + if (durationInBigTicks > 32767) { + durationInBigTicks = 32767; + } + // The result of the addition may exceed 16 bits, but wrapping is fine and intended here. + targetPitchOffsetReachedBigTick = currentBigTick + durationInBigTicks; +} + +void TVP::startDecay() { + phase = 5; + lfoPitchOffset = 0; + targetPitchOffsetReachedBigTick = timeElapsed >> 8; // FIXME: Afaict there's no good reason for this - check +} + +Bit16u TVP::nextPitch() { + // FIXME: Write explanation of counter and time increment + if (counter == 0) { + timeElapsed += processTimerIncrement; + timeElapsed = timeElapsed & 0x00FFFFFF; + process(); + } + counter = (counter + 1) % maxCounter; + return pitch; +} + +void TVP::process() { + if (phase == 0) { + targetPitchOffsetReached(); + return; + } + if (phase == 5) { + nextPhase(); + return; + } + if (phase > 7) { + updatePitch(); + return; + } + + Bit16s negativeBigTicksRemaining = (timeElapsed >> 8) - targetPitchOffsetReachedBigTick; + if (negativeBigTicksRemaining >= 0) { + // We've reached the time for a phase change + targetPitchOffsetReached(); + return; + } + // FIXME: Write explanation for this stuff + int rightShifts = shifts; + if (rightShifts > 13) { + rightShifts -= 13; + negativeBigTicksRemaining = negativeBigTicksRemaining >> rightShifts; // PORTABILITY NOTE: Assumes arithmetic shift + rightShifts = 13; + } + int newResult = (negativeBigTicksRemaining * pitchOffsetChangePerBigTick) >> rightShifts; // PORTABILITY NOTE: Assumes arithmetic shift + newResult += targetPitchOffsetWithoutLFO + lfoPitchOffset; + currentPitchOffset = newResult; + updatePitch(); +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/TVP.h b/src/SOUND/munt/TVP.h new file mode 100644 index 000000000..55f89c5f4 --- /dev/null +++ b/src/SOUND/munt/TVP.h @@ -0,0 +1,74 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_TVP_H +#define MT32EMU_TVP_H + +#include "globals.h" +#include "Types.h" +#include "Structures.h" + +namespace MT32Emu { + +class Part; +class Partial; + +class TVP { +private: + const Partial * const partial; + const MemParams::System * const system; // FIXME: Only necessary because masterTune calculation is done in the wrong place atm. + + const Part *part; + const TimbreParam::PartialParam *partialParam; + const MemParams::PatchTemp *patchTemp; + + int maxCounter; + int processTimerIncrement; + int counter; + Bit32u timeElapsed; + + int phase; + Bit32u basePitch; + Bit32s targetPitchOffsetWithoutLFO; + Bit32s currentPitchOffset; + + Bit16s lfoPitchOffset; + // In range -12 - 36 + Bit8s timeKeyfollowSubtraction; + + Bit16s pitchOffsetChangePerBigTick; + Bit16u targetPitchOffsetReachedBigTick; + unsigned int shifts; + + Bit16u pitch; + + void updatePitch(); + void setupPitchChange(int targetPitchOffset, Bit8u changeDuration); + void targetPitchOffsetReached(); + void nextPhase(); + void process(); +public: + TVP(const Partial *partial); + void reset(const Part *part, const TimbreParam::PartialParam *partialParam); + Bit32u getBasePitch() const; + Bit16u nextPitch(); + void startDecay(); +}; // class TVP + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_TVP_H diff --git a/src/SOUND/munt/Tables.cpp b/src/SOUND/munt/Tables.cpp new file mode 100644 index 000000000..f12caa6b6 --- /dev/null +++ b/src/SOUND/munt/Tables.cpp @@ -0,0 +1,97 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "internals.h" + +#include "Tables.h" +#include "mmath.h" + +namespace MT32Emu { + +// UNUSED: const int MIDDLEC = 60; + +const Tables &Tables::getInstance() { + static const Tables instance; + return instance; +} + +Tables::Tables() { + for (int lf = 0; lf <= 100; lf++) { + // CONFIRMED:KG: This matches a ROM table found by Mok + float fVal = (2.0f - LOG10F(float(lf) + 1.0f)) * 128.0f; + int val = int(fVal + 1.0); + if (val > 255) { + val = 255; + } + levelToAmpSubtraction[lf] = Bit8u(val); + } + + envLogarithmicTime[0] = 64; + for (int lf = 1; lf <= 255; lf++) { + // CONFIRMED:KG: This matches a ROM table found by Mok + envLogarithmicTime[lf] = Bit8u(ceil(64.0f + LOG2F(float(lf)) * 8.0f)); + } + +#if 0 + // The table below is to be used in conjunction with emulation of VCA of newer generation units which is currently missing. + // These relatively small values are rather intended to fine-tune the overall amplification of the VCA. + // CONFIRMED: Based on a table found by Mok in the LAPC-I control ROM + // Note that this matches the MT-32 table, but with the values clamped to a maximum of 8. + memset(masterVolToAmpSubtraction, 8, 71); + memset(masterVolToAmpSubtraction + 71, 7, 3); + memset(masterVolToAmpSubtraction + 74, 6, 4); + memset(masterVolToAmpSubtraction + 78, 5, 3); + memset(masterVolToAmpSubtraction + 81, 4, 4); + memset(masterVolToAmpSubtraction + 85, 3, 3); + memset(masterVolToAmpSubtraction + 88, 2, 4); + memset(masterVolToAmpSubtraction + 92, 1, 4); + memset(masterVolToAmpSubtraction + 96, 0, 5); +#else + // CONFIRMED: Based on a table found by Mok in the MT-32 control ROM + masterVolToAmpSubtraction[0] = 255; + for (int masterVol = 1; masterVol <= 100; masterVol++) { + masterVolToAmpSubtraction[masterVol] = Bit8u(106.31 - 16.0f * LOG2F(float(masterVol))); + } +#endif + + for (int i = 0; i <= 100; i++) { + pulseWidth100To255[i] = Bit8u(i * 255 / 100.0f + 0.5f); + //synth->printDebug("%d: %d", i, pulseWidth100To255[i]); + } + + // The LA32 chip contains an exponent table inside. The table contains 12-bit integer values. + // The actual table size is 512 rows. The 9 higher bits of the fractional part of the argument are used as a lookup address. + // To improve the precision of computations, the lower bits are supposed to be used for interpolation as the LA32 chip also + // contains another 512-row table with inverted differences between the main table values. + for (int i = 0; i < 512; i++) { + exp9[i] = Bit16u(8191.5f - EXP2F(13.0f + ~i / 512.0f)); + } + + // There is a logarithmic sine table inside the LA32 chip. The table contains 13-bit integer values. + for (int i = 1; i < 512; i++) { + logsin9[i] = Bit16u(0.5f - LOG2F(sin((i + 0.5f) / 1024.0f * FLOAT_PI)) * 1024.0f); + } + + // The very first value is clamped to the maximum possible 13-bit integer + logsin9[0] = 8191; + + // found from sample analysis + static const Bit8u resAmpDecayFactorTable[] = {31, 16, 12, 8, 5, 3, 2, 1}; + resAmpDecayFactor = resAmpDecayFactorTable; +} + +} // namespace MT32Emu diff --git a/src/SOUND/munt/Tables.h b/src/SOUND/munt/Tables.h new file mode 100644 index 000000000..47465097e --- /dev/null +++ b/src/SOUND/munt/Tables.h @@ -0,0 +1,62 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_TABLES_H +#define MT32EMU_TABLES_H + +#include "globals.h" +#include "Types.h" + +namespace MT32Emu { + +class Tables { +private: + Tables(); + Tables(Tables &); + ~Tables() {} + +public: + static const Tables &getInstance(); + + // Constant LUTs + + // CONFIRMED: This is used to convert several parameters to amp-modifying values in the TVA envelope: + // - PatchTemp.outputLevel + // - RhythmTemp.outlevel + // - PartialParam.tva.level + // - expression + // It's used to determine how much to subtract from the amp envelope's target value + Bit8u levelToAmpSubtraction[101]; + + // CONFIRMED: ... + Bit8u envLogarithmicTime[256]; + + // CONFIRMED: ... + Bit8u masterVolToAmpSubtraction[101]; + + // CONFIRMED: + Bit8u pulseWidth100To255[101]; + + Bit16u exp9[512]; + Bit16u logsin9[512]; + + const Bit8u *resAmpDecayFactor; +}; // class Tables + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_TABLES_H diff --git a/src/SOUND/munt/Types.h b/src/SOUND/munt/Types.h new file mode 100644 index 000000000..f70e4795c --- /dev/null +++ b/src/SOUND/munt/Types.h @@ -0,0 +1,32 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_TYPES_H +#define MT32EMU_TYPES_H + +namespace MT32Emu { + +typedef unsigned int Bit32u; +typedef signed int Bit32s; +typedef unsigned short int Bit16u; +typedef signed short int Bit16s; +typedef unsigned char Bit8u; +typedef signed char Bit8s; + +} + +#endif diff --git a/src/SOUND/munt/c_interface/c_interface.cpp b/src/SOUND/munt/c_interface/c_interface.cpp new file mode 100644 index 000000000..9028c2612 --- /dev/null +++ b/src/SOUND/munt/c_interface/c_interface.cpp @@ -0,0 +1,635 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "../globals.h" +#include "../Types.h" +#include "../File.h" +#include "../FileStream.h" +#include "../ROMInfo.h" +#include "../Synth.h" +#include "../MidiStreamParser.h" + +#include "c_types.h" +#include "c_interface.h" + +using namespace MT32Emu; + +namespace MT32Emu { + +static mt32emu_service_version getSynthVersionID(mt32emu_service_i) { + return MT32EMU_SERVICE_VERSION_CURRENT; +} + +static const mt32emu_service_i_v0 SERVICE_VTABLE = { + getSynthVersionID, + mt32emu_get_supported_report_handler_version, + mt32emu_get_supported_midi_receiver_version, + mt32emu_get_library_version_int, + mt32emu_get_library_version_string, + mt32emu_get_stereo_output_samplerate, + mt32emu_create_context, + mt32emu_free_context, + mt32emu_add_rom_data, + mt32emu_add_rom_file, + mt32emu_get_rom_info, + mt32emu_set_partial_count, + mt32emu_set_analog_output_mode, + mt32emu_open_synth, + mt32emu_close_synth, + mt32emu_is_open, + mt32emu_get_actual_stereo_output_samplerate, + mt32emu_flush_midi_queue, + mt32emu_set_midi_event_queue_size, + mt32emu_set_midi_receiver, + mt32emu_parse_stream, + mt32emu_parse_stream_at, + mt32emu_play_short_message, + mt32emu_play_short_message_at, + mt32emu_play_msg, + mt32emu_play_sysex, + mt32emu_play_msg_at, + mt32emu_play_sysex_at, + mt32emu_play_msg_now, + mt32emu_play_msg_on_part, + mt32emu_play_sysex_now, + mt32emu_write_sysex, + mt32emu_set_reverb_enabled, + mt32emu_is_reverb_enabled, + mt32emu_set_reverb_overridden, + mt32emu_is_reverb_overridden, + mt32emu_set_reverb_compatibility_mode, + mt32emu_is_mt32_reverb_compatibility_mode, + mt32emu_is_default_reverb_mt32_compatible, + mt32emu_set_dac_input_mode, + mt32emu_get_dac_input_mode, + mt32emu_set_midi_delay_mode, + mt32emu_get_midi_delay_mode, + mt32emu_set_output_gain, + mt32emu_get_output_gain, + mt32emu_set_reverb_output_gain, + mt32emu_get_reverb_output_gain, + mt32emu_set_reversed_stereo_enabled, + mt32emu_is_reversed_stereo_enabled, + mt32emu_render_bit16s, + mt32emu_render_float, + mt32emu_render_bit16s_streams, + mt32emu_render_float_streams, + mt32emu_has_active_partials, + mt32emu_is_active, + mt32emu_get_partial_count, + mt32emu_get_part_states, + mt32emu_get_partial_states, + mt32emu_get_playing_notes, + mt32emu_get_patch_name, + mt32emu_read_memory +}; + +} // namespace MT32Emu + +struct mt32emu_data { + ReportHandler *reportHandler; + Synth *synth; + const ROMImage *controlROMImage; + const ROMImage *pcmROMImage; + DefaultMidiStreamParser *midiParser; + Bit32u partialCount; + AnalogOutputMode analogOutputMode; +}; + +// Internal C++ utility stuff + +namespace MT32Emu { + +class DelegatingReportHandlerAdapter : public ReportHandler { +public: + DelegatingReportHandlerAdapter(mt32emu_report_handler_i useReportHandler, void *useInstanceData) : + delegate(useReportHandler), instanceData(useInstanceData) {} + +protected: + const mt32emu_report_handler_i delegate; + void * const instanceData; + +private: + void printDebug(const char *fmt, va_list list) { + if (delegate.v0->printDebug == NULL) { + ReportHandler::printDebug(fmt, list); + } else { + delegate.v0->printDebug(instanceData, fmt, list); + } + } + + void onErrorControlROM() { + if (delegate.v0->onErrorControlROM == NULL) { + ReportHandler::onErrorControlROM(); + } else { + delegate.v0->onErrorControlROM(instanceData); + } + } + + void onErrorPCMROM() { + if (delegate.v0->onErrorPCMROM == NULL) { + ReportHandler::onErrorPCMROM(); + } else { + delegate.v0->onErrorPCMROM(instanceData); + } + } + + void showLCDMessage(const char *message) { + if (delegate.v0->showLCDMessage == NULL) { + ReportHandler::showLCDMessage(message); + } else { + delegate.v0->showLCDMessage(instanceData, message); + } + } + + void onMIDIMessagePlayed() { + if (delegate.v0->onMIDIMessagePlayed == NULL) { + ReportHandler::onMIDIMessagePlayed(); + } else { + delegate.v0->onMIDIMessagePlayed(instanceData); + } + } + + bool onMIDIQueueOverflow() { + if (delegate.v0->onMIDIQueueOverflow == NULL) { + return ReportHandler::onMIDIQueueOverflow(); + } + return delegate.v0->onMIDIQueueOverflow(instanceData) != MT32EMU_BOOL_FALSE; + } + + void onMIDISystemRealtime(Bit8u systemRealtime) { + if (delegate.v0->onMIDISystemRealtime == NULL) { + ReportHandler::onMIDISystemRealtime(systemRealtime); + } else { + delegate.v0->onMIDISystemRealtime(instanceData, systemRealtime); + } + } + + void onDeviceReset() { + if (delegate.v0->onDeviceReset == NULL) { + ReportHandler::onDeviceReset(); + } else { + delegate.v0->onDeviceReset(instanceData); + } + } + + void onDeviceReconfig() { + if (delegate.v0->onDeviceReconfig == NULL) { + ReportHandler::onDeviceReconfig(); + } else { + delegate.v0->onDeviceReconfig(instanceData); + } + } + + void onNewReverbMode(Bit8u mode) { + if (delegate.v0->onNewReverbMode == NULL) { + ReportHandler::onNewReverbMode(mode); + } else { + delegate.v0->onNewReverbMode(instanceData, mode); + } + } + + void onNewReverbTime(Bit8u time) { + if (delegate.v0->onNewReverbTime == NULL) { + ReportHandler::onNewReverbTime(time); + } else { + delegate.v0->onNewReverbTime(instanceData, time); + } + } + + void onNewReverbLevel(Bit8u level) { + if (delegate.v0->onNewReverbLevel == NULL) { + ReportHandler::onNewReverbLevel(level); + } else { + delegate.v0->onNewReverbLevel(instanceData, level); + } + } + + void onPolyStateChanged(Bit8u partNum) { + if (delegate.v0->onPolyStateChanged == NULL) { + ReportHandler::onPolyStateChanged(partNum); + } else { + delegate.v0->onPolyStateChanged(instanceData, partNum); + } + } + + void onProgramChanged(Bit8u partNum, const char *soundGroupName, const char *patchName) { + if (delegate.v0->onProgramChanged == NULL) { + ReportHandler::onProgramChanged(partNum, soundGroupName, patchName); + } else { + delegate.v0->onProgramChanged(instanceData, partNum, soundGroupName, patchName); + } + } +}; + +class DelegatingMidiStreamParser : public DefaultMidiStreamParser { +public: + DelegatingMidiStreamParser(const mt32emu_data *useData, mt32emu_midi_receiver_i useMIDIReceiver, void *useInstanceData) : + DefaultMidiStreamParser(*useData->synth), delegate(useMIDIReceiver), instanceData(useInstanceData) {} + +protected: + mt32emu_midi_receiver_i delegate; + void *instanceData; + +private: + void handleShortMessage(const Bit32u message) { + if (delegate.v0->handleShortMessage == NULL) { + DefaultMidiStreamParser::handleShortMessage(message); + } else { + delegate.v0->handleShortMessage(instanceData, message); + } + } + + void handleSysex(const Bit8u *stream, const Bit32u length) { + if (delegate.v0->handleSysex == NULL) { + DefaultMidiStreamParser::handleSysex(stream, length); + } else { + delegate.v0->handleSysex(instanceData, stream, length); + } + } + + void handleSystemRealtimeMessage(const Bit8u realtime) { + if (delegate.v0->handleSystemRealtimeMessage == NULL) { + DefaultMidiStreamParser::handleSystemRealtimeMessage(realtime); + } else { + delegate.v0->handleSystemRealtimeMessage(instanceData, realtime); + } + } +}; + +static mt32emu_return_code addROMFile(mt32emu_data *data, File *file) { + const ROMImage *image = ROMImage::makeROMImage(file); + const ROMInfo *info = image->getROMInfo(); + if (info == NULL) { + ROMImage::freeROMImage(image); + return MT32EMU_RC_ROM_NOT_IDENTIFIED; + } + if (info->type == ROMInfo::Control) { + if (data->controlROMImage != NULL) { + delete data->controlROMImage->getFile(); + ROMImage::freeROMImage(data->controlROMImage); + } + data->controlROMImage = image; + return MT32EMU_RC_ADDED_CONTROL_ROM; + } else if (info->type == ROMInfo::PCM) { + if (data->pcmROMImage != NULL) { + delete data->pcmROMImage->getFile(); + ROMImage::freeROMImage(data->pcmROMImage); + } + data->pcmROMImage = image; + return MT32EMU_RC_ADDED_PCM_ROM; + } + ROMImage::freeROMImage(image); + return MT32EMU_RC_OK; // No support for reverb ROM yet. +} + +} // namespace MT32Emu + +// C-visible implementation + +extern "C" { + +mt32emu_service_i mt32emu_get_service_i() { + mt32emu_service_i i; + i.v0 = &SERVICE_VTABLE; + return i; +} + +mt32emu_report_handler_version mt32emu_get_supported_report_handler_version() { + return MT32EMU_REPORT_HANDLER_VERSION_CURRENT; +} + +mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver_version() { + return MT32EMU_MIDI_RECEIVER_VERSION_CURRENT; +} + +mt32emu_bit32u mt32emu_get_library_version_int() { + return Synth::getLibraryVersionInt(); +} + +const char *mt32emu_get_library_version_string() { + return Synth::getLibraryVersionString(); +} + +mt32emu_bit32u mt32emu_get_stereo_output_samplerate(const mt32emu_analog_output_mode analog_output_mode) { + return Synth::getStereoOutputSampleRate(static_cast(analog_output_mode)); +} + +mt32emu_context mt32emu_create_context(mt32emu_report_handler_i report_handler, void *instance_data) { + mt32emu_data *data = new mt32emu_data; + data->reportHandler = (report_handler.v0 != NULL) ? new DelegatingReportHandlerAdapter(report_handler, instance_data) : new ReportHandler; + data->synth = new Synth(data->reportHandler); + data->midiParser = new DefaultMidiStreamParser(*data->synth); + data->controlROMImage = NULL; + data->pcmROMImage = NULL; + data->partialCount = DEFAULT_MAX_PARTIALS; + data->analogOutputMode = AnalogOutputMode_COARSE; + + return data; +} + +void mt32emu_free_context(mt32emu_context data) { + if (data == NULL) return; + + if (data->controlROMImage != NULL) { + delete data->controlROMImage->getFile(); + ROMImage::freeROMImage(data->controlROMImage); + data->controlROMImage = NULL; + } + if (data->pcmROMImage != NULL) { + delete data->pcmROMImage->getFile(); + ROMImage::freeROMImage(data->pcmROMImage); + data->pcmROMImage = NULL; + } + delete data->midiParser; + data->midiParser = NULL; + delete data->synth; + data->synth = NULL; + delete data->reportHandler; + data->reportHandler = NULL; + delete data; +} + +mt32emu_return_code mt32emu_add_rom_data(mt32emu_context context, const mt32emu_bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest) { + if (sha1_digest == NULL) return addROMFile(context, new ArrayFile(data, data_size)); + return addROMFile(context, new ArrayFile(data, data_size, *sha1_digest)); +} + +mt32emu_return_code mt32emu_add_rom_file(mt32emu_context context, const char *filename) { + mt32emu_return_code rc = MT32EMU_RC_OK; + FileStream *fs = new FileStream; + if (fs->open(filename)) { + if (fs->getData() != NULL) { + rc = addROMFile(context, fs); + if (rc > 0) return rc; + } else { + rc = MT32EMU_RC_FILE_NOT_LOADED; + } + } else { + rc = MT32EMU_RC_FILE_NOT_FOUND; + } + delete fs; + return rc; +} + +void mt32emu_get_rom_info(mt32emu_const_context context, mt32emu_rom_info *rom_info) { + const ROMInfo *romInfo = context->controlROMImage == NULL ? NULL : context->controlROMImage->getROMInfo(); + if (romInfo != NULL) { + rom_info->control_rom_id = romInfo->shortName; + rom_info->control_rom_description = romInfo->description; + rom_info->control_rom_sha1_digest = romInfo->sha1Digest; + } else { + rom_info->control_rom_id = NULL; + rom_info->control_rom_description = NULL; + rom_info->control_rom_sha1_digest = NULL; + } + romInfo = context->pcmROMImage == NULL ? NULL : context->pcmROMImage->getROMInfo(); + if (romInfo != NULL) { + rom_info->pcm_rom_id = romInfo->shortName; + rom_info->pcm_rom_description = romInfo->description; + rom_info->pcm_rom_sha1_digest = romInfo->sha1Digest; + } else { + rom_info->pcm_rom_id = NULL; + rom_info->pcm_rom_description = NULL; + rom_info->pcm_rom_sha1_digest = NULL; + } +} + +void mt32emu_set_partial_count(mt32emu_context context, const mt32emu_bit32u partial_count) { + context->partialCount = partial_count; +} + +void mt32emu_set_analog_output_mode(mt32emu_context context, const mt32emu_analog_output_mode analog_output_mode) { + context->analogOutputMode = static_cast(analog_output_mode); +} + +void mt32emu_select_renderer_type(mt32emu_context context, const mt32emu_renderer_type renderer_type) { + context->synth->selectRendererType(static_cast(renderer_type)); +} + +mt32emu_renderer_type mt32emu_get_selected_renderer_type(mt32emu_context context) { + return static_cast(context->synth->getSelectedRendererType()); +} + +mt32emu_return_code mt32emu_open_synth(mt32emu_const_context context) { + if ((context->controlROMImage == NULL) || (context->pcmROMImage == NULL)) { + return MT32EMU_RC_MISSING_ROMS; + } + if (!context->synth->open(*context->controlROMImage, *context->pcmROMImage, context->partialCount, context->analogOutputMode)) { + return MT32EMU_RC_FAILED; + } + return MT32EMU_RC_OK; +} + +void mt32emu_close_synth(mt32emu_const_context context) { + context->synth->close(); +} + +mt32emu_boolean mt32emu_is_open(mt32emu_const_context context) { + return context->synth->isOpen() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +mt32emu_bit32u mt32emu_get_actual_stereo_output_samplerate(mt32emu_const_context context) { + return context->synth->getStereoOutputSampleRate(); +} + +void mt32emu_flush_midi_queue(mt32emu_const_context context) { + context->synth->flushMIDIQueue(); +} + +mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, const mt32emu_bit32u queue_size) { + return context->synth->setMIDIEventQueueSize(queue_size); +} + +void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data) { + delete context->midiParser; + context->midiParser = (midi_receiver.v0 != NULL) ? new DelegatingMidiStreamParser(context, midi_receiver, instance_data) : new DefaultMidiStreamParser(*context->synth); +} + +void mt32emu_parse_stream(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length) { + context->midiParser->resetTimestamp(); + context->midiParser->parseStream(stream, length); +} + +void mt32emu_parse_stream_at(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length, mt32emu_bit32u timestamp) { + context->midiParser->setTimestamp(timestamp); + context->midiParser->parseStream(stream, length); +} + +void mt32emu_play_short_message(mt32emu_const_context context, mt32emu_bit32u message) { + context->midiParser->resetTimestamp(); + context->midiParser->processShortMessage(message); +} + +void mt32emu_play_short_message_at(mt32emu_const_context context, mt32emu_bit32u message, mt32emu_bit32u timestamp) { + context->midiParser->setTimestamp(timestamp); + context->midiParser->processShortMessage(message); +} + +mt32emu_return_code mt32emu_play_msg(mt32emu_const_context context, mt32emu_bit32u msg) { + if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; + return (context->synth->playMsg(msg)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; +} + +mt32emu_return_code mt32emu_play_sysex(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len) { + if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; + return (context->synth->playSysex(sysex, len)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; +} + +mt32emu_return_code mt32emu_play_msg_at(mt32emu_const_context context, mt32emu_bit32u msg, mt32emu_bit32u timestamp) { + if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; + return (context->synth->playMsg(msg, timestamp)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; +} + +mt32emu_return_code mt32emu_play_sysex_at(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len, mt32emu_bit32u timestamp) { + if (!context->synth->isOpen()) return MT32EMU_RC_NOT_OPENED; + return (context->synth->playSysex(sysex, len, timestamp)) ? MT32EMU_RC_OK : MT32EMU_RC_QUEUE_FULL; +} + +void mt32emu_play_msg_now(mt32emu_const_context context, mt32emu_bit32u msg) { + context->synth->playMsgNow(msg); +} + +void mt32emu_play_msg_on_part(mt32emu_const_context context, mt32emu_bit8u part, mt32emu_bit8u code, mt32emu_bit8u note, mt32emu_bit8u velocity) { + context->synth->playMsgOnPart(part, code, note, velocity); +} + +void mt32emu_play_sysex_now(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len) { + context->synth->playSysexNow(sysex, len); +} + +void mt32emu_write_sysex(mt32emu_const_context context, mt32emu_bit8u channel, const mt32emu_bit8u *sysex, mt32emu_bit32u len) { + context->synth->writeSysex(channel, sysex, len); +} + +void mt32emu_set_reverb_enabled(mt32emu_const_context context, const mt32emu_boolean reverb_enabled) { + context->synth->setReverbEnabled(reverb_enabled != MT32EMU_BOOL_FALSE); +} + +mt32emu_boolean mt32emu_is_reverb_enabled(mt32emu_const_context context) { + return context->synth->isReverbEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +void mt32emu_set_reverb_overridden(mt32emu_const_context context, const mt32emu_boolean reverb_overridden) { + context->synth->setReverbOverridden(reverb_overridden != MT32EMU_BOOL_FALSE); +} + +mt32emu_boolean mt32emu_is_reverb_overridden(mt32emu_const_context context) { + return context->synth->isReverbOverridden() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +void mt32emu_set_reverb_compatibility_mode(mt32emu_const_context context, const mt32emu_boolean mt32_compatible_mode) { + context->synth->setReverbCompatibilityMode(mt32_compatible_mode != MT32EMU_BOOL_FALSE); +} + +mt32emu_boolean mt32emu_is_mt32_reverb_compatibility_mode(mt32emu_const_context context) { + return context->synth->isMT32ReverbCompatibilityMode() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context context) { + return context->synth->isDefaultReverbMT32Compatible() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode) { + context->synth->setDACInputMode(static_cast(mode)); +} + +mt32emu_dac_input_mode mt32emu_get_dac_input_mode(mt32emu_const_context context) { + return static_cast(context->synth->getDACInputMode()); +} + +void mt32emu_set_midi_delay_mode(mt32emu_const_context context, const mt32emu_midi_delay_mode mode) { + context->synth->setMIDIDelayMode(static_cast(mode)); +} + +mt32emu_midi_delay_mode mt32emu_get_midi_delay_mode(mt32emu_const_context context) { + return static_cast(context->synth->getMIDIDelayMode()); +} + +void mt32emu_set_output_gain(mt32emu_const_context context, float gain) { + context->synth->setOutputGain(gain); +} + +float mt32emu_get_output_gain(mt32emu_const_context context) { + return context->synth->getOutputGain(); +} + +void mt32emu_set_reverb_output_gain(mt32emu_const_context context, float gain) { + context->synth->setReverbOutputGain(gain); +} + +float mt32emu_get_reverb_output_gain(mt32emu_const_context context) { + return context->synth->getReverbOutputGain(); +} + +void mt32emu_set_reversed_stereo_enabled(mt32emu_const_context context, const mt32emu_boolean enabled) { + context->synth->setReversedStereoEnabled(enabled != MT32EMU_BOOL_FALSE); +} + +mt32emu_boolean mt32emu_is_reversed_stereo_enabled(mt32emu_const_context context) { + return context->synth->isReversedStereoEnabled() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len) { + context->synth->render(stream, len); +} + +void mt32emu_render_float(mt32emu_const_context context, float *stream, mt32emu_bit32u len) { + context->synth->render(stream, len); +} + +void mt32emu_render_bit16s_streams(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len) { + context->synth->renderStreams(*reinterpret_cast *>(streams), len); +} + +void mt32emu_render_float_streams(mt32emu_const_context context, const mt32emu_dac_output_float_streams *streams, mt32emu_bit32u len) { + context->synth->renderStreams(*reinterpret_cast *>(streams), len); +} + +mt32emu_boolean mt32emu_has_active_partials(mt32emu_const_context context) { + return context->synth->hasActivePartials() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +mt32emu_boolean mt32emu_is_active(mt32emu_const_context context) { + return context->synth->isActive() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +mt32emu_bit32u mt32emu_get_partial_count(mt32emu_const_context context) { + return context->synth->getPartialCount(); +} + +mt32emu_bit32u mt32emu_get_part_states(mt32emu_const_context context) { + return context->synth->getPartStates(); +} + +void mt32emu_get_partial_states(mt32emu_const_context context, mt32emu_bit8u *partial_states) { + context->synth->getPartialStates(partial_states); +} + +mt32emu_bit32u mt32emu_get_playing_notes(mt32emu_const_context context, mt32emu_bit8u part_number, mt32emu_bit8u *keys, mt32emu_bit8u *velocities) { + return context->synth->getPlayingNotes(part_number, keys, velocities); +} + +const char *mt32emu_get_patch_name(mt32emu_const_context context, mt32emu_bit8u part_number) { + return context->synth->getPatchName(part_number); +} + +void mt32emu_read_memory(mt32emu_const_context context, mt32emu_bit32u addr, mt32emu_bit32u len, mt32emu_bit8u *data) { + context->synth->readMemory(addr, len, data); +} + +} // extern "C" diff --git a/src/SOUND/munt/c_interface/c_interface.h b/src/SOUND/munt/c_interface/c_interface.h new file mode 100644 index 000000000..09c004b0d --- /dev/null +++ b/src/SOUND/munt/c_interface/c_interface.h @@ -0,0 +1,418 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_C_INTERFACE_H +#define MT32EMU_C_INTERFACE_H + +#include + +#include "../globals.h" +#include "c_types.h" + +#undef MT32EMU_EXPORT +#define MT32EMU_EXPORT MT32EMU_EXPORT_ATTRIBUTE + +#ifdef __cplusplus +extern "C" { +#endif + +/* == Context-independent functions == */ + +/* === Interface handling === */ + +/** Returns mt32emu_service_i interface. */ +MT32EMU_EXPORT mt32emu_service_i mt32emu_get_service_i(); + +#if MT32EMU_EXPORTS_TYPE == 2 +#undef MT32EMU_EXPORT +#define MT32EMU_EXPORT +#endif + +/** + * Returns the version ID of mt32emu_report_handler_i interface the library has been compiled with. + * This allows a client to fall-back gracefully instead of silently not receiving expected event reports. + */ +MT32EMU_EXPORT mt32emu_report_handler_version mt32emu_get_supported_report_handler_version(); + +/** + * Returns the version ID of mt32emu_midi_receiver_version_i interface the library has been compiled with. + * This allows a client to fall-back gracefully instead of silently not receiving expected MIDI messages. + */ +MT32EMU_EXPORT mt32emu_midi_receiver_version mt32emu_get_supported_midi_receiver_version(); + +/** + * Returns library version as an integer in format: 0x00MMmmpp, where: + * MM - major version number + * mm - minor version number + * pp - patch number + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_library_version_int(); + +/** + * Returns library version as a C-string in format: "MAJOR.MINOR.PATCH". + */ +MT32EMU_EXPORT const char *mt32emu_get_library_version_string(); + +/** + * Returns output sample rate used in emulation of stereo analog circuitry of hardware units for particular analog_output_mode. + * See comment for mt32emu_analog_output_mode. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_stereo_output_samplerate(const mt32emu_analog_output_mode analog_output_mode); + +/** + * Returns the value of analog_output_mode for which the output signal may retain its full frequency spectrum + * at the sample rate specified by the target_samplerate argument. + * See comment for mt32emu_analog_output_mode. + */ +MT32EMU_EXPORT mt32emu_analog_output_mode mt32emu_get_best_analog_output_mode(const double target_samplerate); + +/* == Context-dependent functions == */ + +/** Initialises a new emulation context and installs custom report handler if non-NULL. */ +MT32EMU_EXPORT mt32emu_context mt32emu_create_context(mt32emu_report_handler_i report_handler, void *instance_data); + +/** Closes and destroys emulation context. */ +MT32EMU_EXPORT void mt32emu_free_context(mt32emu_context context); + +/** + * Adds new ROM identified by its SHA1 digest to the emulation context replacing previously added ROM of the same type if any. + * Argument sha1_digest can be NULL, in this case the digest will be computed using the actual ROM data. + * If sha1_digest is set to non-NULL, it is assumed being correct and will not be recomputed. + * This function doesn't immediately change the state of already opened synth. Newly added ROM will take effect upon next call of mt32emu_open_synth(). + * Returns positive value upon success. + */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_add_rom_data(mt32emu_context context, const mt32emu_bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest); + +/** + * Loads a ROM file, identify it by SHA1 digest, and adds it to the emulation context replacing previously added ROM of the same type if any. + * This function doesn't immediately change the state of already opened synth. Newly added ROM will take effect upon next call of mt32emu_open_synth(). + * Returns positive value upon success. + */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_add_rom_file(mt32emu_context context, const char *filename); + +/** + * Fills in mt32emu_rom_info structure with identifiers and descriptions of control and PCM ROM files identified and added to the synth context. + * If one of the ROM files is not loaded and identified yet, NULL is returned in the corresponding fields of the mt32emu_rom_info structure. + */ +MT32EMU_EXPORT void mt32emu_get_rom_info(mt32emu_const_context context, mt32emu_rom_info *rom_info); + +/** + * Allows to override the default maximum number of partials playing simultaneously within the emulation session. + * This function doesn't immediately change the state of already opened synth. Newly set value will take effect upon next call of mt32emu_open_synth(). + */ +MT32EMU_EXPORT void mt32emu_set_partial_count(mt32emu_context context, const mt32emu_bit32u partial_count); + +/** + * Allows to override the default mode for emulation of analogue circuitry of the hardware units within the emulation session. + * This function doesn't immediately change the state of already opened synth. Newly set value will take effect upon next call of mt32emu_open_synth(). + */ +MT32EMU_EXPORT void mt32emu_set_analog_output_mode(mt32emu_context context, const mt32emu_analog_output_mode analog_output_mode); + +/** + * Allows to convert the synthesiser output to any desired sample rate. The samplerate conversion + * processes the completely mixed stereo output signal as it passes the analogue circuit emulation, + * so emulating the synthesiser output signal passing further through an ADC. When the samplerate + * argument is set to 0, the default output sample rate is used which depends on the current + * mode of analog circuitry emulation. See mt32emu_analog_output_mode. + * This function doesn't immediately change the state of already opened synth. + * Newly set value will take effect upon next call of mt32emu_open_synth(). + */ +MT32EMU_EXPORT void mt32emu_set_stereo_output_samplerate(mt32emu_context context, const double samplerate); + +/** + * Several samplerate conversion quality options are provided which allow to trade-off the conversion speed vs. + * the retained passband width. All the options except FASTEST guarantee full suppression of the aliasing noise + * in terms of the 16-bit integer samples. + * This function doesn't immediately change the state of already opened synth. + * Newly set value will take effect upon next call of mt32emu_open_synth(). + */ +MT32EMU_EXPORT void mt32emu_set_samplerate_conversion_quality(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality); + +/** + * Selects new type of the wave generator and renderer to be used during subsequent calls to mt32emu_open_synth(). + * By default, MT32EMU_RT_BIT16S is selected. + * See mt32emu_renderer_type for details. + */ +MT32EMU_EXPORT void mt32emu_select_renderer_type(mt32emu_context context, const mt32emu_renderer_type renderer_type); + +/** + * Returns previously selected type of the wave generator and renderer. + * See mt32emu_renderer_type for details. + */ +MT32EMU_EXPORT mt32emu_renderer_type mt32emu_get_selected_renderer_type(mt32emu_context context); + +/** + * Prepares the emulation context to receive MIDI messages and produce output audio data using aforehand added set of ROMs, + * and optionally set the maximum partial count and the analog output mode. + * Returns MT32EMU_RC_OK upon success. + */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_open_synth(mt32emu_const_context context); + +/** Closes the emulation context freeing allocated resources. Added ROMs remain unaffected and ready for reuse. */ +MT32EMU_EXPORT void mt32emu_close_synth(mt32emu_const_context context); + +/** Returns true if the synth is in completely initialized state, otherwise returns false. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_open(mt32emu_const_context context); + +/** + * Returns actual sample rate of the fully processed output stereo signal. + * If samplerate conversion is used (i.e. when mt32emu_set_stereo_output_samplerate() has been invoked with a non-zero value), + * the returned value is the desired output samplerate rounded down to the closest integer. + * Otherwise, the output samplerate is choosen depending on the emulation mode of stereo analog circuitry of hardware units. + * See comment for mt32emu_analog_output_mode for more info. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_actual_stereo_output_samplerate(mt32emu_const_context context); + +/** + * Returns the number of samples produced at the internal synth sample rate (32000 Hz) + * that correspond to the given number of samples at the output sample rate. + * Intended to facilitate audio time synchronisation. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_convert_output_to_synth_timestamp(mt32emu_const_context context, mt32emu_bit32u output_timestamp); + +/** + * Returns the number of samples produced at the output sample rate + * that correspond to the given number of samples at the internal synth sample rate (32000 Hz). + * Intended to facilitate audio time synchronisation. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_convert_synth_to_output_timestamp(mt32emu_const_context context, mt32emu_bit32u synth_timestamp); + +/** All the enqueued events are processed by the synth immediately. */ +MT32EMU_EXPORT void mt32emu_flush_midi_queue(mt32emu_const_context context); + +/** + * Sets size of the internal MIDI event queue. The queue size is set to the minimum power of 2 that is greater or equal to the size specified. + * The queue is flushed before reallocation. + * Returns the actual queue size being used. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_set_midi_event_queue_size(mt32emu_const_context context, const mt32emu_bit32u queue_size); + +/** + * Installs custom MIDI receiver object intended for receiving MIDI messages generated by MIDI stream parser. + * MIDI stream parser is involved when functions mt32emu_parse_stream() and mt32emu_play_short_message() or the likes are called. + * By default, parsed short MIDI messages and System Exclusive messages are sent to the synth input MIDI queue. + * This function allows to override default behaviour. If midi_receiver argument is set to NULL, the default behaviour is restored. + */ +MT32EMU_EXPORT void mt32emu_set_midi_receiver(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data); + +/* Enqueues a MIDI event for subsequent playback. + * The MIDI event will be processed not before the specified timestamp. + * The timestamp is measured as the global rendered sample count since the synth was created (at the native sample rate 32000 Hz). + * The minimum delay involves emulation of the delay introduced while the event is transferred via MIDI interface + * and emulation of the MCU busy-loop while it frees partials for use by a new Poly. + * Calls from multiple threads must be synchronised, although, no synchronisation is required with the rendering thread. + * onMIDIQueueOverflow callback is invoked when the MIDI event queue is full and the message cannot be enqueued. + */ + +/** + * Parses a block of raw MIDI bytes and enqueues parsed MIDI messages for further processing ASAP. + * SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages. + * When a System Realtime MIDI message is parsed, onMIDISystemRealtime callback is invoked. + * NOTE: the total length of a SysEx message being fragmented shall not exceed MT32EMU_MAX_STREAM_BUFFER_SIZE (32768 bytes). + */ +MT32EMU_EXPORT void mt32emu_parse_stream(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length); + +/** + * Parses a block of raw MIDI bytes and enqueues parsed MIDI messages to play at specified time. + * SysEx messages are allowed to be fragmented across several calls to this method. Running status is also handled for short messages. + * When a System Realtime MIDI message is parsed, onMIDISystemRealtime callback is invoked. + * NOTE: the total length of a SysEx message being fragmented shall not exceed MT32EMU_MAX_STREAM_BUFFER_SIZE (32768 bytes). + */ +MT32EMU_EXPORT void mt32emu_parse_stream_at(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length, mt32emu_bit32u timestamp); + +/** + * Enqueues a single mt32emu_bit32u-encoded short MIDI message with full processing ASAP. + * The short MIDI message may contain no status byte, the running status is used in this case. + * When the argument is a System Realtime MIDI message, onMIDISystemRealtime callback is invoked. + */ +MT32EMU_EXPORT void mt32emu_play_short_message(mt32emu_const_context context, mt32emu_bit32u message); + +/** + * Enqueues a single mt32emu_bit32u-encoded short MIDI message to play at specified time with full processing. + * The short MIDI message may contain no status byte, the running status is used in this case. + * When the argument is a System Realtime MIDI message, onMIDISystemRealtime callback is invoked. + */ +MT32EMU_EXPORT void mt32emu_play_short_message_at(mt32emu_const_context context, mt32emu_bit32u message, mt32emu_bit32u timestamp); + +/** Enqueues a single short MIDI message to be processed ASAP. The message must contain a status byte. */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_play_msg(mt32emu_const_context context, mt32emu_bit32u msg); +/** Enqueues a single well formed System Exclusive MIDI message to be processed ASAP. */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_play_sysex(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); + +/** Enqueues a single short MIDI message to play at specified time. The message must contain a status byte. */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_play_msg_at(mt32emu_const_context context, mt32emu_bit32u msg, mt32emu_bit32u timestamp); +/** Enqueues a single well formed System Exclusive MIDI message to play at specified time. */ +MT32EMU_EXPORT mt32emu_return_code mt32emu_play_sysex_at(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len, mt32emu_bit32u timestamp); + +/* WARNING: + * The methods below don't ensure minimum 1-sample delay between sequential MIDI events, + * and a sequence of NoteOn and immediately succeeding NoteOff messages is always silent. + * A thread that invokes these methods must be explicitly synchronised with the thread performing sample rendering. + */ + +/** + * Sends a short MIDI message to the synth for immediate playback. The message must contain a status byte. + * See the WARNING above. + */ +MT32EMU_EXPORT void mt32emu_play_msg_now(mt32emu_const_context context, mt32emu_bit32u msg); +/** + * Sends unpacked short MIDI message to the synth for immediate playback. The message must contain a status byte. + * See the WARNING above. + */ +MT32EMU_EXPORT void mt32emu_play_msg_on_part(mt32emu_const_context context, mt32emu_bit8u part, mt32emu_bit8u code, mt32emu_bit8u note, mt32emu_bit8u velocity); + +/** + * Sends a single well formed System Exclusive MIDI message for immediate processing. The length is in bytes. + * See the WARNING above. + */ +MT32EMU_EXPORT void mt32emu_play_sysex_now(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); +/** + * Sends inner body of a System Exclusive MIDI message for direct processing. The length is in bytes. + * See the WARNING above. + */ +MT32EMU_EXPORT void mt32emu_write_sysex(mt32emu_const_context context, mt32emu_bit8u channel, const mt32emu_bit8u *sysex, mt32emu_bit32u len); + +/** Allows to disable wet reverb output altogether. */ +MT32EMU_EXPORT void mt32emu_set_reverb_enabled(mt32emu_const_context context, const mt32emu_boolean reverb_enabled); +/** Returns whether wet reverb output is enabled. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reverb_enabled(mt32emu_const_context context); +/** + * Sets override reverb mode. In this mode, emulation ignores sysexes (or the related part of them) which control the reverb parameters. + * This mode is in effect until it is turned off. When the synth is re-opened, the override mode is unchanged but the state + * of the reverb model is reset to default. + */ +MT32EMU_EXPORT void mt32emu_set_reverb_overridden(mt32emu_const_context context, const mt32emu_boolean reverb_overridden); +/** Returns whether reverb settings are overridden. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reverb_overridden(mt32emu_const_context context); +/** + * Forces reverb model compatibility mode. By default, the compatibility mode corresponds to the used control ROM version. + * Invoking this method with the argument set to true forces emulation of old MT-32 reverb circuit. + * When the argument is false, emulation of the reverb circuit used in new generation of MT-32 compatible modules is enforced + * (these include CM-32L and LAPC-I). + */ +MT32EMU_EXPORT void mt32emu_set_reverb_compatibility_mode(mt32emu_const_context context, const mt32emu_boolean mt32_compatible_mode); +/** Returns whether reverb is in old MT-32 compatibility mode. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_mt32_reverb_compatibility_mode(mt32emu_const_context context); +/** Returns whether default reverb compatibility mode is the old MT-32 compatibility mode. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_default_reverb_mt32_compatible(mt32emu_const_context context); + +/** Sets new DAC input mode. See mt32emu_dac_input_mode for details. */ +MT32EMU_EXPORT void mt32emu_set_dac_input_mode(mt32emu_const_context context, const mt32emu_dac_input_mode mode); +/** Returns current DAC input mode. See mt32emu_dac_input_mode for details. */ +MT32EMU_EXPORT mt32emu_dac_input_mode mt32emu_get_dac_input_mode(mt32emu_const_context context); + +/** Sets new MIDI delay mode. See mt32emu_midi_delay_mode for details. */ +MT32EMU_EXPORT void mt32emu_set_midi_delay_mode(mt32emu_const_context context, const mt32emu_midi_delay_mode mode); +/** Returns current MIDI delay mode. See mt32emu_midi_delay_mode for details. */ +MT32EMU_EXPORT mt32emu_midi_delay_mode mt32emu_get_midi_delay_mode(mt32emu_const_context context); + +/** + * Sets output gain factor for synth output channels. Applied to all output samples and unrelated with the synth's Master volume, + * it rather corresponds to the gain of the output analog circuitry of the hardware units. However, together with mt32emu_set_reverb_output_gain() + * it offers to the user a capability to control the gain of reverb and non-reverb output channels independently. + * Ignored in MT32EMU_DAC_PURE mode. + */ +MT32EMU_EXPORT void mt32emu_set_output_gain(mt32emu_const_context context, float gain); +/** Returns current output gain factor for synth output channels. */ +MT32EMU_EXPORT float mt32emu_get_output_gain(mt32emu_const_context context); + +/** + * Sets output gain factor for the reverb wet output channels. It rather corresponds to the gain of the output + * analog circuitry of the hardware units. However, together with mt32emu_set_output_gain() it offers to the user a capability + * to control the gain of reverb and non-reverb output channels independently. + * + * Note: We're currently emulate CM-32L/CM-64 reverb quite accurately and the reverb output level closely + * corresponds to the level of digital capture. Although, according to the CM-64 PCB schematic, + * there is a difference in the reverb analogue circuit, and the resulting output gain is 0.68 + * of that for LA32 analogue output. This factor is applied to the reverb output gain. + * Ignored in MT32EMU_DAC_PURE mode. + */ +MT32EMU_EXPORT void mt32emu_set_reverb_output_gain(mt32emu_const_context context, float gain); +/** Returns current output gain factor for reverb wet output channels. */ +MT32EMU_EXPORT float mt32emu_get_reverb_output_gain(mt32emu_const_context context); + +/** Swaps left and right output channels. */ +MT32EMU_EXPORT void mt32emu_set_reversed_stereo_enabled(mt32emu_const_context context, const mt32emu_boolean enabled); +/** Returns whether left and right output channels are swapped. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_reversed_stereo_enabled(mt32emu_const_context context); + +/** + * Renders samples to the specified output stream as if they were sampled at the analog stereo output at the desired sample rate. + * If the output sample rate is not specified explicitly, the default output sample rate is used which depends on the current + * mode of analog circuitry emulation. See mt32emu_analog_output_mode. + * The length is in frames, not bytes (in 16-bit stereo, one frame is 4 bytes). Uses NATIVE byte ordering. + */ +MT32EMU_EXPORT void mt32emu_render_bit16s(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len); +/** Same as above but outputs to a float stereo stream. */ +MT32EMU_EXPORT void mt32emu_render_float(mt32emu_const_context context, float *stream, mt32emu_bit32u len); + +/** + * Renders samples to the specified output streams as if they appeared at the DAC entrance. + * No further processing performed in analog circuitry emulation is applied to the signal. + * NULL may be specified in place of any or all of the stream buffers to skip it. + * The length is in samples, not bytes. Uses NATIVE byte ordering. + */ +MT32EMU_EXPORT void mt32emu_render_bit16s_streams(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len); +/** Same as above but outputs to float streams. */ +MT32EMU_EXPORT void mt32emu_render_float_streams(mt32emu_const_context context, const mt32emu_dac_output_float_streams *streams, mt32emu_bit32u len); + +/** Returns true when there is at least one active partial, otherwise false. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_has_active_partials(mt32emu_const_context context); + +/** Returns true if mt32emu_has_active_partials() returns true, or reverb is (somewhat unreliably) detected as being active. */ +MT32EMU_EXPORT mt32emu_boolean mt32emu_is_active(mt32emu_const_context context); + +/** Returns the maximum number of partials playing simultaneously. */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_partial_count(mt32emu_const_context context); + +/** + * Returns current states of all the parts as a bit set. The least significant bit corresponds to the state of part 1, + * total of 9 bits hold the states of all the parts. If the returned bit for a part is set, there is at least one active + * non-releasing partial playing on this part. This info is useful in emulating behaviour of LCD display of the hardware units. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_part_states(mt32emu_const_context context); + +/** + * Fills in current states of all the partials into the array provided. Each byte in the array holds states of 4 partials + * starting from the least significant bits. The state of each partial is packed in a pair of bits. + * The array must be large enough to accommodate states of all the partials. + * @see getPartialCount() + */ +MT32EMU_EXPORT void mt32emu_get_partial_states(mt32emu_const_context context, mt32emu_bit8u *partial_states); + +/** + * Fills in information about currently playing notes on the specified part into the arrays provided. The arrays must be large enough + * to accommodate data for all the playing notes. The maximum number of simultaneously playing notes cannot exceed the number of partials. + * Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. + * Returns the number of currently playing notes on the specified part. + */ +MT32EMU_EXPORT mt32emu_bit32u mt32emu_get_playing_notes(mt32emu_const_context context, mt32emu_bit8u part_number, mt32emu_bit8u *keys, mt32emu_bit8u *velocities); + +/** + * Returns name of the patch set on the specified part. + * Argument partNumber should be 0..7 for Part 1..8, or 8 for Rhythm. + */ +MT32EMU_EXPORT const char *mt32emu_get_patch_name(mt32emu_const_context context, mt32emu_bit8u part_number); + +/** Stores internal state of emulated synth into an array provided (as it would be acquired from hardware). */ +MT32EMU_EXPORT void mt32emu_read_memory(mt32emu_const_context context, mt32emu_bit32u addr, mt32emu_bit32u len, mt32emu_bit8u *data); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* #ifndef MT32EMU_C_INTERFACE_H */ diff --git a/src/SOUND/munt/c_interface/c_types.h b/src/SOUND/munt/c_interface/c_types.h new file mode 100644 index 000000000..bf4dab8dc --- /dev/null +++ b/src/SOUND/munt/c_interface/c_types.h @@ -0,0 +1,322 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_C_TYPES_H +#define MT32EMU_C_TYPES_H + +#include +#include + +#include "../globals.h" + +#define MT32EMU_C_ENUMERATIONS +#include "../Enumerations.h" +#undef MT32EMU_C_ENUMERATIONS + +typedef unsigned int mt32emu_bit32u; +typedef signed int mt32emu_bit32s; +typedef unsigned short int mt32emu_bit16u; +typedef signed short int mt32emu_bit16s; +typedef unsigned char mt32emu_bit8u; +typedef signed char mt32emu_bit8s; + +typedef char mt32emu_sha1_digest[41]; + +typedef enum { + MT32EMU_BOOL_FALSE, MT32EMU_BOOL_TRUE +} mt32emu_boolean; + +typedef enum { + /* Operation completed normally. */ + MT32EMU_RC_OK = 0, + MT32EMU_RC_ADDED_CONTROL_ROM = 1, + MT32EMU_RC_ADDED_PCM_ROM = 2, + + /* Definite error occurred. */ + MT32EMU_RC_ROM_NOT_IDENTIFIED = -1, + MT32EMU_RC_FILE_NOT_FOUND = -2, + MT32EMU_RC_FILE_NOT_LOADED = -3, + MT32EMU_RC_MISSING_ROMS = -4, + MT32EMU_RC_NOT_OPENED = -5, + MT32EMU_RC_QUEUE_FULL = -6, + + /* Undefined error occurred. */ + MT32EMU_RC_FAILED = -100 +} mt32emu_return_code; + +/** Emulation context */ +typedef struct mt32emu_data *mt32emu_context; +typedef const struct mt32emu_data *mt32emu_const_context; + +/* Convenience aliases */ +#ifndef __cplusplus +typedef enum mt32emu_analog_output_mode mt32emu_analog_output_mode; +typedef enum mt32emu_dac_input_mode mt32emu_dac_input_mode; +typedef enum mt32emu_midi_delay_mode mt32emu_midi_delay_mode; +typedef enum mt32emu_partial_state mt32emu_partial_state; +typedef enum mt32emu_samplerate_conversion_quality mt32emu_samplerate_conversion_quality; +typedef enum mt32emu_renderer_type mt32emu_renderer_type; +#endif + +/** Contains identifiers and descriptions of ROM files being used. */ +typedef struct { + const char *control_rom_id; + const char *control_rom_description; + const char *control_rom_sha1_digest; + const char *pcm_rom_id; + const char *pcm_rom_description; + const char *pcm_rom_sha1_digest; +} mt32emu_rom_info; + +/** Set of multiplexed output bit16s streams appeared at the DAC entrance. */ +typedef struct { + mt32emu_bit16s *nonReverbLeft; + mt32emu_bit16s *nonReverbRight; + mt32emu_bit16s *reverbDryLeft; + mt32emu_bit16s *reverbDryRight; + mt32emu_bit16s *reverbWetLeft; + mt32emu_bit16s *reverbWetRight; +} mt32emu_dac_output_bit16s_streams; + +/** Set of multiplexed output float streams appeared at the DAC entrance. */ +typedef struct { + float *nonReverbLeft; + float *nonReverbRight; + float *reverbDryLeft; + float *reverbDryRight; + float *reverbWetLeft; + float *reverbWetRight; +} mt32emu_dac_output_float_streams; + +/* === Interface handling === */ + +/** Report handler interface versions */ +typedef enum { + MT32EMU_REPORT_HANDLER_VERSION_0 = 0, + MT32EMU_REPORT_HANDLER_VERSION_CURRENT = MT32EMU_REPORT_HANDLER_VERSION_0 +} mt32emu_report_handler_version; + +/** MIDI receiver interface versions */ +typedef enum { + MT32EMU_MIDI_RECEIVER_VERSION_0 = 0, + MT32EMU_MIDI_RECEIVER_VERSION_CURRENT = MT32EMU_MIDI_RECEIVER_VERSION_0 +} mt32emu_midi_receiver_version; + +/** Synth interface versions */ +typedef enum { + MT32EMU_SERVICE_VERSION_0 = 0, + MT32EMU_SERVICE_VERSION_1 = 1, + MT32EMU_SERVICE_VERSION_CURRENT = MT32EMU_SERVICE_VERSION_1 +} mt32emu_service_version; + +/* === Report Handler Interface === */ + +typedef union mt32emu_report_handler_i mt32emu_report_handler_i; + +/** Interface for handling reported events (initial version) */ +typedef struct { + /** Returns the actual interface version ID */ + mt32emu_report_handler_version (*getVersionID)(mt32emu_report_handler_i i); + + /** Callback for debug messages, in vprintf() format */ + void (*printDebug)(void *instance_data, const char *fmt, va_list list); + /** Callbacks for reporting errors */ + void (*onErrorControlROM)(void *instance_data); + void (*onErrorPCMROM)(void *instance_data); + /** Callback for reporting about displaying a new custom message on LCD */ + void (*showLCDMessage)(void *instance_data, const char *message); + /** Callback for reporting actual processing of a MIDI message */ + void (*onMIDIMessagePlayed)(void *instance_data); + /** + * Callback for reporting an overflow of the input MIDI queue. + * Returns MT32EMU_BOOL_TRUE if a recovery action was taken + * and yet another attempt to enqueue the MIDI event is desired. + */ + mt32emu_boolean (*onMIDIQueueOverflow)(void *instance_data); + /** + * Callback invoked when a System Realtime MIDI message is detected in functions + * mt32emu_parse_stream and mt32emu_play_short_message and the likes. + */ + void (*onMIDISystemRealtime)(void *instance_data, mt32emu_bit8u system_realtime); + /** Callbacks for reporting system events */ + void (*onDeviceReset)(void *instance_data); + void (*onDeviceReconfig)(void *instance_data); + /** Callbacks for reporting changes of reverb settings */ + void (*onNewReverbMode)(void *instance_data, mt32emu_bit8u mode); + void (*onNewReverbTime)(void *instance_data, mt32emu_bit8u time); + void (*onNewReverbLevel)(void *instance_data, mt32emu_bit8u level); + /** Callbacks for reporting various information */ + void (*onPolyStateChanged)(void *instance_data, mt32emu_bit8u part_num); + void (*onProgramChanged)(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name); +} mt32emu_report_handler_i_v0; + +/** + * Extensible interface for handling reported events. + * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. + * It is caller's responsibility to check the actual interface version in runtime using the getVersionID() method. + */ +union mt32emu_report_handler_i { + const mt32emu_report_handler_i_v0 *v0; +}; + +/* === MIDI Receiver Interface === */ + +typedef union mt32emu_midi_receiver_i mt32emu_midi_receiver_i; + +/** Interface for receiving MIDI messages generated by MIDI stream parser (initial version) */ +typedef struct { + /** Returns the actual interface version ID */ + mt32emu_midi_receiver_version (*getVersionID)(mt32emu_midi_receiver_i i); + + /** Invoked when a complete short MIDI message is parsed in the input MIDI stream. */ + void (*handleShortMessage)(void *instance_data, const mt32emu_bit32u message); + + /** Invoked when a complete well-formed System Exclusive MIDI message is parsed in the input MIDI stream. */ + void (*handleSysex)(void *instance_data, const mt32emu_bit8u stream[], const mt32emu_bit32u length); + + /** Invoked when a System Realtime MIDI message is parsed in the input MIDI stream. */ + void (*handleSystemRealtimeMessage)(void *instance_data, const mt32emu_bit8u realtime); +} mt32emu_midi_receiver_i_v0; + +/** + * Extensible interface for receiving MIDI messages. + * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. + * It is caller's responsibility to check the actual interface version in runtime using the getVersionID() method. + */ +union mt32emu_midi_receiver_i { + const mt32emu_midi_receiver_i_v0 *v0; +}; + +/* === Service Interface === */ + +typedef union mt32emu_service_i mt32emu_service_i; + +/** + * Basic interface that defines all the library services (initial version). + * The members closely resemble C functions declared in c_interface.h, and the intention is to provide for easier + * access when the library is dynamically loaded in run-time, e.g. as a plugin. This way the client only needs + * to bind to mt32emu_get_service_i() function instead of binding to each function it needs to use. + * See c_interface.h for parameter description. + */ +#define MT32EMU_SERVICE_I_V0 \ + /** Returns the actual interface version ID */ \ + mt32emu_service_version (*getVersionID)(mt32emu_service_i i); \ + mt32emu_report_handler_version (*getSupportedReportHandlerVersionID)(); \ + mt32emu_midi_receiver_version (*getSupportedMIDIReceiverVersionID)(); \ +\ + mt32emu_bit32u (*getLibraryVersionInt)(); \ + const char *(*getLibraryVersionString)(); \ +\ + mt32emu_bit32u (*getStereoOutputSamplerate)(const mt32emu_analog_output_mode analog_output_mode); \ +\ + mt32emu_context (*createContext)(mt32emu_report_handler_i report_handler, void *instance_data); \ + void (*freeContext)(mt32emu_context context); \ + mt32emu_return_code (*addROMData)(mt32emu_context context, const mt32emu_bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest); \ + mt32emu_return_code (*addROMFile)(mt32emu_context context, const char *filename); \ + void (*getROMInfo)(mt32emu_const_context context, mt32emu_rom_info *rom_info); \ + void (*setPartialCount)(mt32emu_context context, const mt32emu_bit32u partial_count); \ + void (*setAnalogOutputMode)(mt32emu_context context, const mt32emu_analog_output_mode analog_output_mode); \ + mt32emu_return_code (*openSynth)(mt32emu_const_context context); \ + void (*closeSynth)(mt32emu_const_context context); \ + mt32emu_boolean (*isOpen)(mt32emu_const_context context); \ + mt32emu_bit32u (*getActualStereoOutputSamplerate)(mt32emu_const_context context); \ + void (*flushMIDIQueue)(mt32emu_const_context context); \ + mt32emu_bit32u (*setMIDIEventQueueSize)(mt32emu_const_context context, const mt32emu_bit32u queue_size); \ + void (*setMIDIReceiver)(mt32emu_context context, mt32emu_midi_receiver_i midi_receiver, void *instance_data); \ +\ + void (*parseStream)(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length); \ + void (*parseStream_At)(mt32emu_const_context context, const mt32emu_bit8u *stream, mt32emu_bit32u length, mt32emu_bit32u timestamp); \ + void (*playShortMessage)(mt32emu_const_context context, mt32emu_bit32u message); \ + void (*playShortMessageAt)(mt32emu_const_context context, mt32emu_bit32u message, mt32emu_bit32u timestamp); \ + mt32emu_return_code (*playMsg)(mt32emu_const_context context, mt32emu_bit32u msg); \ + mt32emu_return_code (*playSysex)(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); \ + mt32emu_return_code (*playMsgAt)(mt32emu_const_context context, mt32emu_bit32u msg, mt32emu_bit32u timestamp); \ + mt32emu_return_code (*playSysexAt)(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len, mt32emu_bit32u timestamp); \ +\ + void (*playMsgNow)(mt32emu_const_context context, mt32emu_bit32u msg); \ + void (*playMsgOnPart)(mt32emu_const_context context, mt32emu_bit8u part, mt32emu_bit8u code, mt32emu_bit8u note, mt32emu_bit8u velocity); \ + void (*playSysexNow)(mt32emu_const_context context, const mt32emu_bit8u *sysex, mt32emu_bit32u len); \ + void (*writeSysex)(mt32emu_const_context context, mt32emu_bit8u channel, const mt32emu_bit8u *sysex, mt32emu_bit32u len); \ +\ + void (*setReverbEnabled)(mt32emu_const_context context, const mt32emu_boolean reverb_enabled); \ + mt32emu_boolean (*isReverbEnabled)(mt32emu_const_context context); \ + void (*setReverbOverridden)(mt32emu_const_context context, const mt32emu_boolean reverb_overridden); \ + mt32emu_boolean (*isReverbOverridden)(mt32emu_const_context context); \ + void (*setReverbCompatibilityMode)(mt32emu_const_context context, const mt32emu_boolean mt32_compatible_mode); \ + mt32emu_boolean (*isMT32ReverbCompatibilityMode)(mt32emu_const_context context); \ + mt32emu_boolean (*isDefaultReverbMT32Compatible)(mt32emu_const_context context); \ +\ + void (*setDACInputMode)(mt32emu_const_context context, const mt32emu_dac_input_mode mode); \ + mt32emu_dac_input_mode (*getDACInputMode)(mt32emu_const_context context); \ +\ + void (*setMIDIDelayMode)(mt32emu_const_context context, const mt32emu_midi_delay_mode mode); \ + mt32emu_midi_delay_mode (*getMIDIDelayMode)(mt32emu_const_context context); \ +\ + void (*setOutputGain)(mt32emu_const_context context, float gain); \ + float (*getOutputGain)(mt32emu_const_context context); \ + void (*setReverbOutputGain)(mt32emu_const_context context, float gain); \ + float (*getReverbOutputGain)(mt32emu_const_context context); \ +\ + void (*setReversedStereoEnabled)(mt32emu_const_context context, const mt32emu_boolean enabled); \ + mt32emu_boolean (*isReversedStereoEnabled)(mt32emu_const_context context); \ +\ + void (*renderBit16s)(mt32emu_const_context context, mt32emu_bit16s *stream, mt32emu_bit32u len); \ + void (*renderFloat)(mt32emu_const_context context, float *stream, mt32emu_bit32u len); \ + void (*renderBit16sStreams)(mt32emu_const_context context, const mt32emu_dac_output_bit16s_streams *streams, mt32emu_bit32u len); \ + void (*renderFloatStreams)(mt32emu_const_context context, const mt32emu_dac_output_float_streams *streams, mt32emu_bit32u len); \ +\ + mt32emu_boolean (*hasActivePartials)(mt32emu_const_context context); \ + mt32emu_boolean (*isActive)(mt32emu_const_context context); \ + mt32emu_bit32u (*getPartialCount)(mt32emu_const_context context); \ + mt32emu_bit32u (*getPartStates)(mt32emu_const_context context); \ + void (*getPartialStates)(mt32emu_const_context context, mt32emu_bit8u *partial_states); \ + mt32emu_bit32u (*getPlayingNotes)(mt32emu_const_context context, mt32emu_bit8u part_number, mt32emu_bit8u *keys, mt32emu_bit8u *velocities); \ + const char *(*getPatchName)(mt32emu_const_context context, mt32emu_bit8u part_number); \ + void (*readMemory)(mt32emu_const_context context, mt32emu_bit32u addr, mt32emu_bit32u len, mt32emu_bit8u *data); + +#define MT32EMU_SERVICE_I_V1 \ + mt32emu_analog_output_mode (*getBestAnalogOutputMode)(const double target_samplerate); \ + void (*setStereoOutputSampleRate)(mt32emu_context context, const double samplerate); \ + void (*setSamplerateConversionQuality)(mt32emu_context context, const mt32emu_samplerate_conversion_quality quality); \ + void (*selectRendererType)(mt32emu_context context, mt32emu_renderer_type renderer_type); \ + mt32emu_renderer_type (*getSelectedRendererType)(mt32emu_context context); \ + mt32emu_bit32u (*convertOutputToSynthTimestamp)(mt32emu_const_context context, mt32emu_bit32u output_timestamp); \ + mt32emu_bit32u (*convertSynthToOutputTimestamp)(mt32emu_const_context context, mt32emu_bit32u synth_timestamp); + +typedef struct { + MT32EMU_SERVICE_I_V0 +} mt32emu_service_i_v0; + +typedef struct { + MT32EMU_SERVICE_I_V0 + MT32EMU_SERVICE_I_V1 +} mt32emu_service_i_v1; + +/** + * Extensible interface for all the library services. + * Union intended to view an interface of any subsequent version as any parent interface not requiring a cast. + * It is caller's responsibility to check the actual interface version in runtime using the getVersionID() method. + */ +union mt32emu_service_i { + const mt32emu_service_i_v0 *v0; + const mt32emu_service_i_v1 *v1; +}; + +#undef MT32EMU_SERVICE_I_V0 +#undef MT32EMU_SERVICE_I_V1 + +#endif /* #ifndef MT32EMU_C_TYPES_H */ diff --git a/src/SOUND/munt/c_interface/cpp_interface.h b/src/SOUND/munt/c_interface/cpp_interface.h new file mode 100644 index 000000000..f40ed7037 --- /dev/null +++ b/src/SOUND/munt/c_interface/cpp_interface.h @@ -0,0 +1,468 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_CPP_INTERFACE_H +#define MT32EMU_CPP_INTERFACE_H + +#include + +#include "../globals.h" +#include "c_types.h" + +#include "../Types.h" +#include "../Enumerations.h" + +#if MT32EMU_API_TYPE == 2 + +extern "C" { + +/** Returns mt32emu_service_i interface. */ +mt32emu_service_i mt32emu_get_service_i(); + +} + +#define mt32emu_get_supported_report_handler_version i.v0->getSupportedReportHandlerVersionID +#define mt32emu_get_supported_midi_receiver_version i.v0->getSupportedMIDIReceiverVersionID +#define mt32emu_get_library_version_int i.v0->getLibraryVersionInt +#define mt32emu_get_library_version_string i.v0->getLibraryVersionString +#define mt32emu_get_stereo_output_samplerate i.v0->getStereoOutputSamplerate +#define mt32emu_get_best_analog_output_mode iV1()->getBestAnalogOutputMode +#define mt32emu_create_context i.v0->createContext +#define mt32emu_free_context i.v0->freeContext +#define mt32emu_add_rom_data i.v0->addROMData +#define mt32emu_add_rom_file i.v0->addROMFile +#define mt32emu_get_rom_info i.v0->getROMInfo +#define mt32emu_set_partial_count i.v0->setPartialCount +#define mt32emu_set_analog_output_mode i.v0->setAnalogOutputMode +#define mt32emu_set_stereo_output_samplerate iV1()->setStereoOutputSampleRate +#define mt32emu_set_samplerate_conversion_quality iV1()->setSamplerateConversionQuality +#define mt32emu_select_renderer_type iV1()->selectRendererType +#define mt32emu_get_selected_renderer_type iV1()->getSelectedRendererType +#define mt32emu_open_synth i.v0->openSynth +#define mt32emu_close_synth i.v0->closeSynth +#define mt32emu_is_open i.v0->isOpen +#define mt32emu_get_actual_stereo_output_samplerate i.v0->getActualStereoOutputSamplerate +#define mt32emu_convert_output_to_synth_timestamp iV1()->convertOutputToSynthTimestamp +#define mt32emu_convert_synth_to_output_timestamp iV1()->convertSynthToOutputTimestamp +#define mt32emu_flush_midi_queue i.v0->flushMIDIQueue +#define mt32emu_set_midi_event_queue_size i.v0->setMIDIEventQueueSize +#define mt32emu_set_midi_receiver i.v0->setMIDIReceiver +#define mt32emu_parse_stream i.v0->parseStream +#define mt32emu_parse_stream_at i.v0->parseStream_At +#define mt32emu_play_short_message i.v0->playShortMessage +#define mt32emu_play_short_message_at i.v0->playShortMessageAt +#define mt32emu_play_msg i.v0->playMsg +#define mt32emu_play_sysex i.v0->playSysex +#define mt32emu_play_msg_at i.v0->playMsgAt +#define mt32emu_play_sysex_at i.v0->playSysexAt +#define mt32emu_play_msg_now i.v0->playMsgNow +#define mt32emu_play_msg_on_part i.v0->playMsgOnPart +#define mt32emu_play_sysex_now i.v0->playSysexNow +#define mt32emu_write_sysex i.v0->writeSysex +#define mt32emu_set_reverb_enabled i.v0->setReverbEnabled +#define mt32emu_is_reverb_enabled i.v0->isReverbEnabled +#define mt32emu_set_reverb_overridden i.v0->setReverbOverridden +#define mt32emu_is_reverb_overridden i.v0->isReverbOverridden +#define mt32emu_set_reverb_compatibility_mode i.v0->setReverbCompatibilityMode +#define mt32emu_is_mt32_reverb_compatibility_mode i.v0->isMT32ReverbCompatibilityMode +#define mt32emu_is_default_reverb_mt32_compatible i.v0->isDefaultReverbMT32Compatible +#define mt32emu_set_dac_input_mode i.v0->setDACInputMode +#define mt32emu_get_dac_input_mode i.v0->getDACInputMode +#define mt32emu_set_midi_delay_mode i.v0->setMIDIDelayMode +#define mt32emu_get_midi_delay_mode i.v0->getMIDIDelayMode +#define mt32emu_set_output_gain i.v0->setOutputGain +#define mt32emu_get_output_gain i.v0->getOutputGain +#define mt32emu_set_reverb_output_gain i.v0->setReverbOutputGain +#define mt32emu_get_reverb_output_gain i.v0->getReverbOutputGain +#define mt32emu_set_reversed_stereo_enabled i.v0->setReversedStereoEnabled +#define mt32emu_is_reversed_stereo_enabled i.v0->isReversedStereoEnabled +#define mt32emu_render_bit16s i.v0->renderBit16s +#define mt32emu_render_float i.v0->renderFloat +#define mt32emu_render_bit16s_streams i.v0->renderBit16sStreams +#define mt32emu_render_float_streams i.v0->renderFloatStreams +#define mt32emu_has_active_partials i.v0->hasActivePartials +#define mt32emu_is_active i.v0->isActive +#define mt32emu_get_partial_count i.v0->getPartialCount +#define mt32emu_get_part_states i.v0->getPartStates +#define mt32emu_get_partial_states i.v0->getPartialStates +#define mt32emu_get_playing_notes i.v0->getPlayingNotes +#define mt32emu_get_patch_name i.v0->getPatchName +#define mt32emu_read_memory i.v0->readMemory + +#else // #if MT32EMU_API_TYPE == 2 + +#include "c_interface.h" + +#endif // #if MT32EMU_API_TYPE == 2 + +namespace MT32Emu { + +namespace CppInterfaceImpl { + +static const mt32emu_report_handler_i NULL_REPORT_HANDLER = { NULL }; +static mt32emu_report_handler_i getReportHandlerThunk(); +static mt32emu_midi_receiver_i getMidiReceiverThunk(); + +} + +/* + * The classes below correspond to the interfaces defined in c_types.h and provided for convenience when using C++. + * The approach used makes no assumption of any internal class data memory layout, since the C++ standard does not + * provide any detail in this area and leaves it up to the implementation. Therefore, this way portability is guaranteed, + * despite the implementation may be a little inefficient. + * See c_types.h and c_interface.h for description of the corresponding interface methods. + */ + +// Defines the interface for handling reported events. +// Corresponds to the current version of mt32emu_report_handler_i interface. +class IReportHandler { +public: + virtual void printDebug(const char *fmt, va_list list) = 0; + virtual void onErrorControlROM() = 0; + virtual void onErrorPCMROM() = 0; + virtual void showLCDMessage(const char *message) = 0; + virtual void onMIDIMessagePlayed() = 0; + virtual bool onMIDIQueueOverflow() = 0; + virtual void onMIDISystemRealtime(Bit8u system_realtime) = 0; + virtual void onDeviceReset() = 0; + virtual void onDeviceReconfig() = 0; + virtual void onNewReverbMode(Bit8u mode) = 0; + virtual void onNewReverbTime(Bit8u time) = 0; + virtual void onNewReverbLevel(Bit8u level) = 0; + virtual void onPolyStateChanged(Bit8u part_num) = 0; + virtual void onProgramChanged(Bit8u part_num, const char *sound_group_name, const char *patch_name) = 0; + +protected: + ~IReportHandler() {} +}; + +// Defines the interface for receiving MIDI messages generated by MIDI stream parser. +// Corresponds to the current version of mt32emu_midi_receiver_i interface. +class IMidiReceiver { +public: + virtual void handleShortMessage(const Bit32u message) = 0; + virtual void handleSysex(const Bit8u stream[], const Bit32u length) = 0; + virtual void handleSystemRealtimeMessage(const Bit8u realtime) = 0; + +protected: + ~IMidiReceiver() {} +}; + +// Defines all the library services. +// Corresponds to the current version of mt32emu_service_i interface. +class Service { +public: +#if MT32EMU_API_TYPE == 2 + explicit Service(mt32emu_service_i interface, mt32emu_context context = NULL) : i(interface), c(context) {} +#else + explicit Service(mt32emu_context context = NULL) : c(context) {} +#endif + ~Service() { if (c != NULL) mt32emu_free_context(c); } + + // Context-independent methods + +#if MT32EMU_API_TYPE == 2 + mt32emu_service_version getVersionID() { return i.v0->getVersionID(i); } +#endif + mt32emu_report_handler_version getSupportedReportHandlerVersionID() { return mt32emu_get_supported_report_handler_version(); } + mt32emu_midi_receiver_version getSupportedMIDIReceiverVersionID() { return mt32emu_get_supported_midi_receiver_version(); } + + Bit32u getLibraryVersionInt() { return mt32emu_get_library_version_int(); } + const char *getLibraryVersionString() { return mt32emu_get_library_version_string(); } + + Bit32u getStereoOutputSamplerate(const AnalogOutputMode analog_output_mode) { return mt32emu_get_stereo_output_samplerate(static_cast(analog_output_mode)); } + AnalogOutputMode getBestAnalogOutputMode(const double target_samplerate) { return static_cast(mt32emu_get_best_analog_output_mode(target_samplerate)); } + + // Context-dependent methods + + mt32emu_context getContext() { return c; } + void createContext(mt32emu_report_handler_i report_handler = CppInterfaceImpl::NULL_REPORT_HANDLER, void *instance_data = NULL) { freeContext(); c = mt32emu_create_context(report_handler, instance_data); } + void createContext(IReportHandler &report_handler) { createContext(CppInterfaceImpl::getReportHandlerThunk(), &report_handler); } + void freeContext() { if (c != NULL) { mt32emu_free_context(c); c = NULL; } } + mt32emu_return_code addROMData(const Bit8u *data, size_t data_size, const mt32emu_sha1_digest *sha1_digest = NULL) { return mt32emu_add_rom_data(c, data, data_size, sha1_digest); } + mt32emu_return_code addROMFile(const char *filename) { return mt32emu_add_rom_file(c, filename); } + void getROMInfo(mt32emu_rom_info *rom_info) { mt32emu_get_rom_info(c, rom_info); } + void setPartialCount(const Bit32u partial_count) { mt32emu_set_partial_count(c, partial_count); } + void setAnalogOutputMode(const AnalogOutputMode analog_output_mode) { mt32emu_set_analog_output_mode(c, static_cast(analog_output_mode)); } + void setStereoOutputSampleRate(const double samplerate) { mt32emu_set_stereo_output_samplerate(c, samplerate); } + void setSamplerateConversionQuality(const SamplerateConversionQuality quality) { mt32emu_set_samplerate_conversion_quality(c, static_cast(quality)); } + void selectRendererType(const RendererType newRendererType) { mt32emu_select_renderer_type(c, static_cast(newRendererType)); } + RendererType getSelectedRendererType() { return static_cast(mt32emu_get_selected_renderer_type(c)); } + mt32emu_return_code openSynth() { return mt32emu_open_synth(c); } + void closeSynth() { mt32emu_close_synth(c); } + bool isOpen() { return mt32emu_is_open(c) != MT32EMU_BOOL_FALSE; } + Bit32u getActualStereoOutputSamplerate() { return mt32emu_get_actual_stereo_output_samplerate(c); } + Bit32u convertOutputToSynthTimestamp(Bit32u output_timestamp) { return mt32emu_convert_output_to_synth_timestamp(c, output_timestamp); } + Bit32u convertSynthToOutputTimestamp(Bit32u synth_timestamp) { return mt32emu_convert_synth_to_output_timestamp(c, synth_timestamp); } + void flushMIDIQueue() { mt32emu_flush_midi_queue(c); } + Bit32u setMIDIEventQueueSize(const Bit32u queue_size) { return mt32emu_set_midi_event_queue_size(c, queue_size); } + void setMIDIReceiver(mt32emu_midi_receiver_i midi_receiver, void *instance_data) { mt32emu_set_midi_receiver(c, midi_receiver, instance_data); } + void setMIDIReceiver(IMidiReceiver &midi_receiver) { setMIDIReceiver(CppInterfaceImpl::getMidiReceiverThunk(), &midi_receiver); } + + void parseStream(const Bit8u *stream, Bit32u length) { mt32emu_parse_stream(c, stream, length); } + void parseStream_At(const Bit8u *stream, Bit32u length, Bit32u timestamp) { mt32emu_parse_stream_at(c, stream, length, timestamp); } + void playShortMessage(Bit32u message) { mt32emu_play_short_message(c, message); } + void playShortMessageAt(Bit32u message, Bit32u timestamp) { mt32emu_play_short_message_at(c, message, timestamp); } + mt32emu_return_code playMsg(Bit32u msg) { return mt32emu_play_msg(c, msg); } + mt32emu_return_code playSysex(const Bit8u *sysex, Bit32u len) { return mt32emu_play_sysex(c, sysex, len); } + mt32emu_return_code playMsgAt(Bit32u msg, Bit32u timestamp) { return mt32emu_play_msg_at(c, msg, timestamp); } + mt32emu_return_code playSysexAt(const Bit8u *sysex, Bit32u len, Bit32u timestamp) { return mt32emu_play_sysex_at(c, sysex, len, timestamp); } + + void playMsgNow(Bit32u msg) { mt32emu_play_msg_now(c, msg); } + void playMsgOnPart(Bit8u part, Bit8u code, Bit8u note, Bit8u velocity) { mt32emu_play_msg_on_part(c, part, code, note, velocity); } + void playSysexNow(const Bit8u *sysex, Bit32u len) { mt32emu_play_sysex_now(c, sysex, len); } + void writeSysex(Bit8u channel, const Bit8u *sysex, Bit32u len) { mt32emu_write_sysex(c, channel, sysex, len); } + + void setReverbEnabled(const bool reverb_enabled) { mt32emu_set_reverb_enabled(c, reverb_enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } + bool isReverbEnabled() { return mt32emu_is_reverb_enabled(c) != MT32EMU_BOOL_FALSE; } + void setReverbOverridden(const bool reverb_overridden) { mt32emu_set_reverb_overridden(c, reverb_overridden ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } + bool isReverbOverridden() { return mt32emu_is_reverb_overridden(c) != MT32EMU_BOOL_FALSE; } + void setReverbCompatibilityMode(const bool mt32_compatible_mode) { mt32emu_set_reverb_compatibility_mode(c, mt32_compatible_mode ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } + bool isMT32ReverbCompatibilityMode() { return mt32emu_is_mt32_reverb_compatibility_mode(c) != MT32EMU_BOOL_FALSE; } + bool isDefaultReverbMT32Compatible() { return mt32emu_is_default_reverb_mt32_compatible(c) != MT32EMU_BOOL_FALSE; } + + void setDACInputMode(const DACInputMode mode) { mt32emu_set_dac_input_mode(c, static_cast(mode)); } + DACInputMode getDACInputMode() { return static_cast(mt32emu_get_dac_input_mode(c)); } + + void setMIDIDelayMode(const MIDIDelayMode mode) { mt32emu_set_midi_delay_mode(c, static_cast(mode)); } + MIDIDelayMode getMIDIDelayMode() { return static_cast(mt32emu_get_midi_delay_mode(c)); } + + void setOutputGain(float gain) { mt32emu_set_output_gain(c, gain); } + float getOutputGain() { return mt32emu_get_output_gain(c); } + void setReverbOutputGain(float gain) { mt32emu_set_reverb_output_gain(c, gain); } + float getReverbOutputGain() { return mt32emu_get_reverb_output_gain(c); } + + void setReversedStereoEnabled(const bool enabled) { mt32emu_set_reversed_stereo_enabled(c, enabled ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE); } + bool isReversedStereoEnabled() { return mt32emu_is_reversed_stereo_enabled(c) != MT32EMU_BOOL_FALSE; } + + void renderBit16s(Bit16s *stream, Bit32u len) { mt32emu_render_bit16s(c, stream, len); } + void renderFloat(float *stream, Bit32u len) { mt32emu_render_float(c, stream, len); } + void renderBit16sStreams(const mt32emu_dac_output_bit16s_streams *streams, Bit32u len) { mt32emu_render_bit16s_streams(c, streams, len); } + void renderFloatStreams(const mt32emu_dac_output_float_streams *streams, Bit32u len) { mt32emu_render_float_streams(c, streams, len); } + + bool hasActivePartials() { return mt32emu_has_active_partials(c) != MT32EMU_BOOL_FALSE; } + bool isActive() { return mt32emu_is_active(c) != MT32EMU_BOOL_FALSE; } + Bit32u getPartialCount() { return mt32emu_get_partial_count(c); } + Bit32u getPartStates() { return mt32emu_get_part_states(c); } + void getPartialStates(Bit8u *partial_states) { mt32emu_get_partial_states(c, partial_states); } + Bit32u getPlayingNotes(Bit8u part_number, Bit8u *keys, Bit8u *velocities) { return mt32emu_get_playing_notes(c, part_number, keys, velocities); } + const char *getPatchName(Bit8u part_number) { return mt32emu_get_patch_name(c, part_number); } + void readMemory(Bit32u addr, Bit32u len, Bit8u *data) { mt32emu_read_memory(c, addr, len, data); } + +private: +#if MT32EMU_API_TYPE == 2 + const mt32emu_service_i i; +#endif + mt32emu_context c; + +#if MT32EMU_API_TYPE == 2 + const mt32emu_service_i_v1 *iV1() { return (getVersionID() < MT32EMU_SERVICE_VERSION_1) ? NULL : i.v1; } +#endif +}; + +namespace CppInterfaceImpl { + +static mt32emu_report_handler_version getReportHandlerVersionID(mt32emu_report_handler_i) { + return MT32EMU_REPORT_HANDLER_VERSION_CURRENT; +} + +static void printDebug(void *instance_data, const char *fmt, va_list list) { + static_cast(instance_data)->printDebug(fmt, list); +} + +static void onErrorControlROM(void *instance_data) { + static_cast(instance_data)->onErrorControlROM(); +} + +static void onErrorPCMROM(void *instance_data) { + static_cast(instance_data)->onErrorPCMROM(); +} + +static void showLCDMessage(void *instance_data, const char *message) { + static_cast(instance_data)->showLCDMessage(message); +} + +static void onMIDIMessagePlayed(void *instance_data) { + static_cast(instance_data)->onMIDIMessagePlayed(); +} + +static mt32emu_boolean onMIDIQueueOverflow(void *instance_data) { + return static_cast(instance_data)->onMIDIQueueOverflow() ? MT32EMU_BOOL_TRUE : MT32EMU_BOOL_FALSE; +} + +static void onMIDISystemRealtime(void *instance_data, mt32emu_bit8u system_realtime) { + static_cast(instance_data)->onMIDISystemRealtime(system_realtime); +} + +static void onDeviceReset(void *instance_data) { + static_cast(instance_data)->onDeviceReset(); +} + +static void onDeviceReconfig(void *instance_data) { + static_cast(instance_data)->onDeviceReconfig(); +} + +static void onNewReverbMode(void *instance_data, mt32emu_bit8u mode) { + static_cast(instance_data)->onNewReverbMode(mode); +} + +static void onNewReverbTime(void *instance_data, mt32emu_bit8u time) { + static_cast(instance_data)->onNewReverbTime(time); +} + +static void onNewReverbLevel(void *instance_data, mt32emu_bit8u level) { + static_cast(instance_data)->onNewReverbLevel(level); +} + +static void onPolyStateChanged(void *instance_data, mt32emu_bit8u part_num) { + static_cast(instance_data)->onPolyStateChanged(part_num); +} + +static void onProgramChanged(void *instance_data, mt32emu_bit8u part_num, const char *sound_group_name, const char *patch_name) { + static_cast(instance_data)->onProgramChanged(part_num, sound_group_name, patch_name); +} + +static mt32emu_report_handler_i getReportHandlerThunk() { + static const mt32emu_report_handler_i_v0 REPORT_HANDLER_V0_THUNK = { + getReportHandlerVersionID, + printDebug, + onErrorControlROM, + onErrorPCMROM, + showLCDMessage, + onMIDIMessagePlayed, + onMIDIQueueOverflow, + onMIDISystemRealtime, + onDeviceReset, + onDeviceReconfig, + onNewReverbMode, + onNewReverbTime, + onNewReverbLevel, + onPolyStateChanged, + onProgramChanged + }; + + static const mt32emu_report_handler_i REPORT_HANDLER_THUNK = { &REPORT_HANDLER_V0_THUNK }; + + return REPORT_HANDLER_THUNK; +} + +static mt32emu_midi_receiver_version getMidiReceiverVersionID(mt32emu_midi_receiver_i) { + return MT32EMU_MIDI_RECEIVER_VERSION_CURRENT; +} + +static void handleShortMessage(void *instance_data, const mt32emu_bit32u message) { + static_cast(instance_data)->handleShortMessage(message); +} + +static void handleSysex(void *instance_data, const mt32emu_bit8u stream[], const mt32emu_bit32u length) { + static_cast(instance_data)->handleSysex(stream, length); +} + +static void handleSystemRealtimeMessage(void *instance_data, const mt32emu_bit8u realtime) { + static_cast(instance_data)->handleSystemRealtimeMessage(realtime); +} + +static mt32emu_midi_receiver_i getMidiReceiverThunk() { + static const mt32emu_midi_receiver_i_v0 MIDI_RECEIVER_V0_THUNK = { + getMidiReceiverVersionID, + handleShortMessage, + handleSysex, + handleSystemRealtimeMessage + }; + + static const mt32emu_midi_receiver_i MIDI_RECEIVER_THUNK = { &MIDI_RECEIVER_V0_THUNK }; + + return MIDI_RECEIVER_THUNK; +} + +} // namespace CppInterfaceImpl + +} // namespace MT32Emu + +#if MT32EMU_API_TYPE == 2 + +#undef mt32emu_get_supported_report_handler_version +#undef mt32emu_get_supported_midi_receiver_version +#undef mt32emu_get_library_version_int +#undef mt32emu_get_library_version_string +#undef mt32emu_get_stereo_output_samplerate +#undef mt32emu_get_best_analog_output_mode +#undef mt32emu_create_context +#undef mt32emu_free_context +#undef mt32emu_add_rom_data +#undef mt32emu_add_rom_file +#undef mt32emu_get_rom_info +#undef mt32emu_set_partial_count +#undef mt32emu_set_analog_output_mode +#undef mt32emu_set_stereo_output_samplerate +#undef mt32emu_set_samplerate_conversion_quality +#undef mt32emu_select_renderer_type +#undef mt32emu_get_selected_renderer_type +#undef mt32emu_open_synth +#undef mt32emu_close_synth +#undef mt32emu_is_open +#undef mt32emu_get_actual_stereo_output_samplerate +#undef mt32emu_convert_output_to_synth_timestamp +#undef mt32emu_convert_synth_to_output_timestamp +#undef mt32emu_flush_midi_queue +#undef mt32emu_set_midi_event_queue_size +#undef mt32emu_set_midi_receiver +#undef mt32emu_parse_stream +#undef mt32emu_parse_stream_at +#undef mt32emu_play_short_message +#undef mt32emu_play_short_message_at +#undef mt32emu_play_msg +#undef mt32emu_play_sysex +#undef mt32emu_play_msg_at +#undef mt32emu_play_sysex_at +#undef mt32emu_play_msg_now +#undef mt32emu_play_msg_on_part +#undef mt32emu_play_sysex_now +#undef mt32emu_write_sysex +#undef mt32emu_set_reverb_enabled +#undef mt32emu_is_reverb_enabled +#undef mt32emu_set_reverb_overridden +#undef mt32emu_is_reverb_overridden +#undef mt32emu_set_reverb_compatibility_mode +#undef mt32emu_is_mt32_reverb_compatibility_mode +#undef mt32emu_is_default_reverb_mt32_compatible +#undef mt32emu_set_dac_input_mode +#undef mt32emu_get_dac_input_mode +#undef mt32emu_set_midi_delay_mode +#undef mt32emu_get_midi_delay_mode +#undef mt32emu_set_output_gain +#undef mt32emu_get_output_gain +#undef mt32emu_set_reverb_output_gain +#undef mt32emu_get_reverb_output_gain +#undef mt32emu_set_reversed_stereo_enabled +#undef mt32emu_is_reversed_stereo_enabled +#undef mt32emu_render_bit16s +#undef mt32emu_render_float +#undef mt32emu_render_bit16s_streams +#undef mt32emu_render_float_streams +#undef mt32emu_has_active_partials +#undef mt32emu_is_active +#undef mt32emu_get_partial_count +#undef mt32emu_get_part_states +#undef mt32emu_get_partial_states +#undef mt32emu_get_playing_notes +#undef mt32emu_get_patch_name +#undef mt32emu_read_memory + +#endif // #if MT32EMU_API_TYPE == 2 + +#endif /* #ifndef MT32EMU_CPP_INTERFACE_H */ diff --git a/src/SOUND/munt/config.h b/src/SOUND/munt/config.h new file mode 100644 index 000000000..7b6cd736f --- /dev/null +++ b/src/SOUND/munt/config.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_CONFIG_H +#define MT32EMU_CONFIG_H + +#define MT32EMU_VERSION "2.1.0" +#define MT32EMU_VERSION_MAJOR 2 +#define MT32EMU_VERSION_MINOR 1 +#define MT32EMU_VERSION_PATCH 0 + +/* Library Exports Configuration + * + * This reflects the API types actually provided by the library build. + * 0: The full-featured C++ API is only available in this build. The client application may ONLY use MT32EMU_API_TYPE 0. + * 1: The C-compatible API is only available. The library is built as a shared object, only C functions are exported, + * and thus the client application may NOT use MT32EMU_API_TYPE 0. + * 2: The C-compatible API is only available. The library is built as a shared object, only the factory function + * is exported, and thus the client application may ONLY use MT32EMU_API_TYPE 2. + * 3: All the available API types are provided by the library build. + */ +#define MT32EMU_EXPORTS_TYPE 3 + +#endif diff --git a/src/SOUND/munt/globals.h b/src/SOUND/munt/globals.h new file mode 100644 index 000000000..d9b4e02c1 --- /dev/null +++ b/src/SOUND/munt/globals.h @@ -0,0 +1,119 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_GLOBALS_H +#define MT32EMU_GLOBALS_H + +#include "config.h" + +/* Support for compiling shared library. */ +#ifdef MT32EMU_SHARED +#if defined _WIN32 || defined __CYGWIN__ +#ifdef _MSC_VER +#ifdef mt32emu_EXPORTS +#define MT32EMU_EXPORT_ATTRIBUTE _declspec(dllexport) +#else /* #ifdef mt32emu_EXPORTS */ +#define MT32EMU_EXPORT_ATTRIBUTE _declspec(dllimport) +#endif /* #ifdef mt32emu_EXPORTS */ +#else /* #ifdef _MSC_VER */ +#ifdef mt32emu_EXPORTS +#define MT32EMU_EXPORT_ATTRIBUTE __attribute__ ((dllexport)) +#else /* #ifdef mt32emu_EXPORTS */ +#define MT32EMU_EXPORT_ATTRIBUTE __attribute__ ((dllimport)) +#endif /* #ifdef mt32emu_EXPORTS */ +#endif /* #ifdef _MSC_VER */ +#else /* #if defined _WIN32 || defined __CYGWIN__ */ +#define MT32EMU_EXPORT_ATTRIBUTE __attribute__ ((visibility("default"))) +#endif /* #if defined _WIN32 || defined __CYGWIN__ */ +#else /* #ifdef MT32EMU_SHARED */ +#define MT32EMU_EXPORT_ATTRIBUTE +#endif /* #ifdef MT32EMU_SHARED */ + +#if MT32EMU_EXPORTS_TYPE == 1 || MT32EMU_EXPORTS_TYPE == 2 +#define MT32EMU_EXPORT +#else +#define MT32EMU_EXPORT MT32EMU_EXPORT_ATTRIBUTE +#endif + +/* Useful constants */ + +/* Sample rate to use in mixing. With the progress of development, we've found way too many thing dependent. + * In order to achieve further advance in emulation accuracy, sample rate made fixed throughout the emulator, + * except the emulation of analogue path. + * The output from the synth is supposed to be resampled externally in order to convert to the desired sample rate. + */ +#define MT32EMU_SAMPLE_RATE 32000 + +/* The default value for the maximum number of partials playing simultaneously. */ +#define MT32EMU_DEFAULT_MAX_PARTIALS 32 + +/* The higher this number, the more memory will be used, but the more samples can be processed in one run - + * various parts of sample generation can be processed more efficiently in a single run. + * A run's maximum length is that given to Synth::render(), so giving a value here higher than render() is ever + * called with will give no gain (but simply waste the memory). + * Note that this value does *not* in any way impose limitations on the length given to render(), and has no effect + * on the generated audio. + * This value must be >= 1. + */ +#define MT32EMU_MAX_SAMPLES_PER_RUN 4096 + +/* The default size of the internal MIDI event queue. + * It holds the incoming MIDI events before the rendering engine actually processes them. + * The main goal is to fairly emulate the real hardware behaviour which obviously + * uses an internal MIDI event queue to gather incoming data as well as the delays + * introduced by transferring data via the MIDI interface. + * This also facilitates building of an external rendering loop + * as the queue stores timestamped MIDI events. + */ +#define MT32EMU_DEFAULT_MIDI_EVENT_QUEUE_SIZE 1024 + +/* Maximum allowed size of MIDI parser input stream buffer. + * Should suffice for any reasonable bulk dump SysEx, as the h/w units have only 32K of RAM onboard. + */ +#define MT32EMU_MAX_STREAM_BUFFER_SIZE 32768 + +/* This should correspond to the MIDI buffer size used in real h/w devices. + * CM-32L control ROM seems using 1000 bytes, old MT-32 isn't confirmed by now. + */ +#define MT32EMU_SYSEX_BUFFER_SIZE 1000 + +#if defined(__cplusplus) && MT32EMU_API_TYPE != 1 + +namespace MT32Emu +{ +const unsigned int SAMPLE_RATE = MT32EMU_SAMPLE_RATE; +#undef MT32EMU_SAMPLE_RATE + +const unsigned int DEFAULT_MAX_PARTIALS = MT32EMU_DEFAULT_MAX_PARTIALS; +#undef MT32EMU_DEFAULT_MAX_PARTIALS + +const unsigned int MAX_SAMPLES_PER_RUN = MT32EMU_MAX_SAMPLES_PER_RUN; +#undef MT32EMU_MAX_SAMPLES_PER_RUN + +const unsigned int DEFAULT_MIDI_EVENT_QUEUE_SIZE = MT32EMU_DEFAULT_MIDI_EVENT_QUEUE_SIZE; +#undef MT32EMU_DEFAULT_MIDI_EVENT_QUEUE_SIZE + +const unsigned int MAX_STREAM_BUFFER_SIZE = MT32EMU_MAX_STREAM_BUFFER_SIZE; +#undef MT32EMU_MAX_STREAM_BUFFER_SIZE + +const unsigned int SYSEX_BUFFER_SIZE = MT32EMU_SYSEX_BUFFER_SIZE; +#undef MT32EMU_SYSEX_BUFFER_SIZE +} + +#endif /* #if defined(__cplusplus) && MT32EMU_API_TYPE != 1 */ + +#endif /* #ifndef MT32EMU_GLOBALS_H */ diff --git a/src/SOUND/munt/internals.h b/src/SOUND/munt/internals.h new file mode 100644 index 000000000..0bae8d9f7 --- /dev/null +++ b/src/SOUND/munt/internals.h @@ -0,0 +1,118 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_INTERNALS_H +#define MT32EMU_INTERNALS_H + +#include "Types.h" + +// Debugging + +// 0: Standard debug output is not stamped with the rendered sample count +// 1: Standard debug output is stamped with the rendered sample count +// NOTE: The "samplestamp" corresponds to the end of the last completed rendering run. +// This is important to bear in mind for debug output that occurs during a run. +#ifndef MT32EMU_DEBUG_SAMPLESTAMPS +#define MT32EMU_DEBUG_SAMPLESTAMPS 0 +#endif + +// 0: No debug output for initialisation progress +// 1: Debug output for initialisation progress +#ifndef MT32EMU_MONITOR_INIT +#define MT32EMU_MONITOR_INIT 0 +#endif + +// 0: No debug output for MIDI events +// 1: Debug output for weird MIDI events +#ifndef MT32EMU_MONITOR_MIDI +#define MT32EMU_MONITOR_MIDI 0 +#endif + +// 0: No debug output for note on/off +// 1: Basic debug output for note on/off +// 2: Comprehensive debug output for note on/off +#ifndef MT32EMU_MONITOR_INSTRUMENTS +#define MT32EMU_MONITOR_INSTRUMENTS 0 +#endif + +// 0: No debug output for partial allocations +// 1: Show partial stats when an allocation fails +// 2: Show partial stats with every new poly +// 3: Show individual partial allocations/deactivations +#ifndef MT32EMU_MONITOR_PARTIALS +#define MT32EMU_MONITOR_PARTIALS 0 +#endif + +// 0: No debug output for sysex +// 1: Basic debug output for sysex +#ifndef MT32EMU_MONITOR_SYSEX +#define MT32EMU_MONITOR_SYSEX 0 +#endif + +// 0: No debug output for sysex writes to the timbre areas +// 1: Debug output with the name and location of newly-written timbres +// 2: Complete dump of timbre parameters for newly-written timbres +#ifndef MT32EMU_MONITOR_TIMBRES +#define MT32EMU_MONITOR_TIMBRES 0 +#endif + +// 0: No TVA/TVF-related debug output. +// 1: Shows changes to TVA/TVF target, increment and phase. +#ifndef MT32EMU_MONITOR_TVA +#define MT32EMU_MONITOR_TVA 0 +#endif +#ifndef MT32EMU_MONITOR_TVF +#define MT32EMU_MONITOR_TVF 0 +#endif + +// Configuration + +// If non-zero, deletes reverb buffers that are not in use to save memory. +// If zero, keeps reverb buffers for all modes around all the time to avoid allocating/freeing in the critical path. +#ifndef MT32EMU_REDUCE_REVERB_MEMORY +#define MT32EMU_REDUCE_REVERB_MEMORY 1 +#endif + +// 0: Maximum speed at the cost of a bit lower emulation accuracy. +// 1: Maximum achievable emulation accuracy. +#ifndef MT32EMU_BOSS_REVERB_PRECISE_MODE +#define MT32EMU_BOSS_REVERB_PRECISE_MODE 0 +#endif + +namespace MT32Emu { + +typedef Bit16s IntSample; +typedef Bit32s IntSampleEx; +typedef float FloatSample; + +enum PolyState { + POLY_Playing, + POLY_Held, // This marks keys that have been released on the keyboard, but are being held by the pedal + POLY_Releasing, + POLY_Inactive +}; + +enum ReverbMode { + REVERB_MODE_ROOM, + REVERB_MODE_HALL, + REVERB_MODE_PLATE, + REVERB_MODE_TAP_DELAY +}; + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_INTERNALS_H diff --git a/src/SOUND/munt/mmath.h b/src/SOUND/munt/mmath.h new file mode 100644 index 000000000..9a9e642ba --- /dev/null +++ b/src/SOUND/munt/mmath.h @@ -0,0 +1,68 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_MMATH_H +#define MT32EMU_MMATH_H + +#include + +namespace MT32Emu { + +// Mathematical constants +const double DOUBLE_PI = 3.141592653589793; +const double DOUBLE_LN_10 = 2.302585092994046; +const float FLOAT_PI = 3.1415927f; +const float FLOAT_2PI = 6.2831853f; +const float FLOAT_LN_2 = 0.6931472f; +const float FLOAT_LN_10 = 2.3025851f; + +static inline float POWF(float x, float y) { + return pow(x, y); +} + +static inline float EXPF(float x) { + return exp(x); +} + +static inline float EXP2F(float x) { +#ifdef __APPLE__ + // on OSX exp2f() is 1.59 times faster than "exp() and the multiplication with FLOAT_LN_2" + return exp2f(x); +#else + return exp(FLOAT_LN_2 * x); +#endif +} + +static inline float EXP10F(float x) { + return exp(FLOAT_LN_10 * x); +} + +static inline float LOGF(float x) { + return log(x); +} + +static inline float LOG2F(float x) { + return log(x) / FLOAT_LN_2; +} + +static inline float LOG10F(float x) { + return log10(x); +} + +} // namespace MT32Emu + +#endif // #ifndef MT32EMU_MMATH_H diff --git a/src/SOUND/munt/mt32emu.h b/src/SOUND/munt/mt32emu.h new file mode 100644 index 000000000..6b93121be --- /dev/null +++ b/src/SOUND/munt/mt32emu.h @@ -0,0 +1,84 @@ +/* Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009 Dean Beeler, Jerome Fisher + * Copyright (C) 2011-2017 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_MT32EMU_H +#define MT32EMU_MT32EMU_H + +#include "config.h" + +/* API Configuration */ + +/* 0: Use full-featured C++ API. Well suitable when the library is to be linked statically. + * When the library is shared, ABI compatibility may be an issue. Therefore, it should + * only be used within a project comprising of several modules to share the library code. + * 1: Use C-compatible API. Make the library looks as a regular C library with well-defined ABI. + * This is also crucial when the library is to be linked with modules in a different + * language, either statically or dynamically. + * 2: Use plugin-like API via C-interface wrapped in a C++ class. This is mainly intended + * for a shared library being dynamically loaded in run-time. To get access to all the library + * services, a client application only needs to bind with a single factory function. + * 3: Use optimised C++ API compatible with the plugin API (type 2). The facade class also wraps + * the C functions but they are invoked directly. This enables the compiler to generate better + * code for the library when linked statically yet being consistent with the plugin-like API. + */ + +#ifdef MT32EMU_API_TYPE +#if MT32EMU_API_TYPE == 0 && (MT32EMU_EXPORTS_TYPE == 1 || MT32EMU_EXPORTS_TYPE == 2) +#error Incompatible setting MT32EMU_API_TYPE=0 +#elif MT32EMU_API_TYPE == 1 && (MT32EMU_EXPORTS_TYPE == 0 || MT32EMU_EXPORTS_TYPE == 2) +#error Incompatible setting MT32EMU_API_TYPE=1 +#elif MT32EMU_API_TYPE == 2 && (MT32EMU_EXPORTS_TYPE == 0) +#error Incompatible setting MT32EMU_API_TYPE=2 +#elif MT32EMU_API_TYPE == 3 && (MT32EMU_EXPORTS_TYPE == 0 || MT32EMU_EXPORTS_TYPE == 2) +#error Incompatible setting MT32EMU_API_TYPE=3 +#endif +#else /* #ifdef MT32EMU_API_TYPE */ +#if 0 < MT32EMU_EXPORTS_TYPE && MT32EMU_EXPORTS_TYPE < 3 +#define MT32EMU_API_TYPE MT32EMU_EXPORTS_TYPE +#else +#define MT32EMU_API_TYPE 0 +#endif +#endif /* #ifdef MT32EMU_API_TYPE */ + +/* MT32EMU_SHARED should be defined when building shared library, especially for Windows platforms. */ +/* +#define MT32EMU_SHARED +*/ + +#include "globals.h" + +#if !defined(__cplusplus) || MT32EMU_API_TYPE == 1 + +#include "c_interface/c_interface.h" + +#elif MT32EMU_API_TYPE == 2 || MT32EMU_API_TYPE == 3 + +#include "c_interface/cpp_interface.h" + +#else /* #if !defined(__cplusplus) || MT32EMU_API_TYPE == 1 */ + +#include "Types.h" +#include "File.h" +#include "FileStream.h" +#include "ROMInfo.h" +#include "Synth.h" +#include "MidiStreamParser.h" +#include "SampleRateConverter.h" + +#endif /* #if !defined(__cplusplus) || MT32EMU_API_TYPE == 1 */ + +#endif /* #ifndef MT32EMU_MT32EMU_H */ diff --git a/src/SOUND/munt/sha1/sha1.cpp b/src/SOUND/munt/sha1/sha1.cpp new file mode 100644 index 000000000..9b91cd9f2 --- /dev/null +++ b/src/SOUND/munt/sha1/sha1.cpp @@ -0,0 +1,185 @@ +/* + Copyright (c) 2011, Micael Hildenborg + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Micael Hildenborg nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Contributors: + Gustav + Several members in the gamedev.se forum. + Gregory Petrosyan + */ + +#include "sha1.h" + +namespace sha1 +{ + namespace // local + { + // Rotate an integer value to left. + inline unsigned int rol(const unsigned int value, + const unsigned int steps) + { + return ((value << steps) | (value >> (32 - steps))); + } + + // Sets the first 16 integers in the buffert to zero. + // Used for clearing the W buffert. + inline void clearWBuffert(unsigned int* buffert) + { + for (int pos = 16; --pos >= 0;) + { + buffert[pos] = 0; + } + } + + void innerHash(unsigned int* result, unsigned int* w) + { + unsigned int a = result[0]; + unsigned int b = result[1]; + unsigned int c = result[2]; + unsigned int d = result[3]; + unsigned int e = result[4]; + + int round = 0; + + #define sha1macro(func,val) \ + { \ + const unsigned int t = rol(a, 5) + (func) + e + val + w[round]; \ + e = d; \ + d = c; \ + c = rol(b, 30); \ + b = a; \ + a = t; \ + } + + while (round < 16) + { + sha1macro((b & c) | (~b & d), 0x5a827999) + ++round; + } + while (round < 20) + { + w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); + sha1macro((b & c) | (~b & d), 0x5a827999) + ++round; + } + while (round < 40) + { + w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); + sha1macro(b ^ c ^ d, 0x6ed9eba1) + ++round; + } + while (round < 60) + { + w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); + sha1macro((b & c) | (b & d) | (c & d), 0x8f1bbcdc) + ++round; + } + while (round < 80) + { + w[round] = rol((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1); + sha1macro(b ^ c ^ d, 0xca62c1d6) + ++round; + } + + #undef sha1macro + + result[0] += a; + result[1] += b; + result[2] += c; + result[3] += d; + result[4] += e; + } + } // namespace + + void calc(const void* src, const int bytelength, unsigned char* hash) + { + // Init the result array. + unsigned int result[5] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; + + // Cast the void src pointer to be the byte array we can work with. + const unsigned char* sarray = static_cast(src); + + // The reusable round buffer + unsigned int w[80]; + + // Loop through all complete 64byte blocks. + const int endOfFullBlocks = bytelength - 64; + int endCurrentBlock; + int currentBlock = 0; + + while (currentBlock <= endOfFullBlocks) + { + endCurrentBlock = currentBlock + 64; + + // Init the round buffer with the 64 byte block data. + for (int roundPos = 0; currentBlock < endCurrentBlock; currentBlock += 4) + { + // This line will swap endian on big endian and keep endian on little endian. + w[roundPos++] = static_cast(sarray[currentBlock + 3]) + | (static_cast(sarray[currentBlock + 2]) << 8) + | (static_cast(sarray[currentBlock + 1]) << 16) + | (static_cast(sarray[currentBlock]) << 24); + } + innerHash(result, w); + } + + // Handle the last and not full 64 byte block if existing. + endCurrentBlock = bytelength - currentBlock; + clearWBuffert(w); + int lastBlockBytes = 0; + for (;lastBlockBytes < endCurrentBlock; ++lastBlockBytes) + { + w[lastBlockBytes >> 2] |= static_cast(sarray[lastBlockBytes + currentBlock]) << ((3 - (lastBlockBytes & 3)) << 3); + } + w[lastBlockBytes >> 2] |= 0x80 << ((3 - (lastBlockBytes & 3)) << 3); + if (endCurrentBlock >= 56) + { + innerHash(result, w); + clearWBuffert(w); + } + w[15] = bytelength << 3; + innerHash(result, w); + + // Store hash in result pointer, and make sure we get in in the correct order on both endian models. + for (int hashByte = 20; --hashByte >= 0;) + { + hash[hashByte] = (result[hashByte >> 2] >> (((3 - hashByte) & 0x3) << 3)) & 0xff; + } + } + + void toHexString(const unsigned char* hash, char* hexstring) + { + const char hexDigits[] = { "0123456789abcdef" }; + + for (int hashByte = 20; --hashByte >= 0;) + { + hexstring[hashByte << 1] = hexDigits[(hash[hashByte] >> 4) & 0xf]; + hexstring[(hashByte << 1) + 1] = hexDigits[hash[hashByte] & 0xf]; + } + hexstring[40] = 0; + } +} // namespace sha1 diff --git a/src/SOUND/munt/sha1/sha1.h b/src/SOUND/munt/sha1/sha1.h new file mode 100644 index 000000000..96d8ce4da --- /dev/null +++ b/src/SOUND/munt/sha1/sha1.h @@ -0,0 +1,49 @@ +/* + Copyright (c) 2011, Micael Hildenborg + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Micael Hildenborg nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY Micael Hildenborg ''AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL Micael Hildenborg BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SHA1_DEFINED +#define SHA1_DEFINED + +namespace sha1 +{ + + /** + @param src points to any kind of data to be hashed. + @param bytelength the number of bytes to hash from the src pointer. + @param hash should point to a buffer of at least 20 bytes of size for storing the sha1 result in. + */ + void calc(const void* src, const int bytelength, unsigned char* hash); + + /** + @param hash is 20 bytes of sha1 hash. This is the same data that is the result from the calc function. + @param hexstring should point to a buffer of at least 41 bytes of size for storing the hexadecimal representation of the hash. A zero will be written at position 40, so the buffer will be a valid zero ended string. + */ + void toHexString(const unsigned char* hash, char* hexstring); + +} // namespace sha1 + +#endif // SHA1_DEFINED diff --git a/src/SOUND/munt/srchelper/InternalResampler.cpp b/src/SOUND/munt/srchelper/InternalResampler.cpp new file mode 100644 index 000000000..782d39bbe --- /dev/null +++ b/src/SOUND/munt/srchelper/InternalResampler.cpp @@ -0,0 +1,74 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "InternalResampler.h" + +#include +#include + +#include "../Synth.h" + +using namespace SRCTools; + +namespace MT32Emu { + +class SynthWrapper : public FloatSampleProvider { + Synth &synth; + +public: + SynthWrapper(Synth &useSynth) : synth(useSynth) + {} + + void getOutputSamples(FloatSample *outBuffer, unsigned int size) { + synth.render(outBuffer, size); + } +}; + +static FloatSampleProvider &createModel(Synth &synth, SRCTools::FloatSampleProvider &synthSource, double targetSampleRate, SamplerateConversionQuality quality) { + static const double MAX_AUDIBLE_FREQUENCY = 20000.0; + + const double sourceSampleRate = synth.getStereoOutputSampleRate(); + if (quality != SamplerateConversionQuality_FASTEST) { + const bool oversampledMode = synth.getStereoOutputSampleRate() == Synth::getStereoOutputSampleRate(AnalogOutputMode_OVERSAMPLED); + // Oversampled input allows to bypass IIR interpolation stage and, in some cases, IIR decimation stage + if (oversampledMode && (0.5 * sourceSampleRate) <= targetSampleRate) { + // NOTE: In the oversampled mode, the transition band starts at 20kHz and ends at 28kHz + double passband = MAX_AUDIBLE_FREQUENCY; + double stopband = 0.5 * sourceSampleRate + MAX_AUDIBLE_FREQUENCY; + ResamplerStage &resamplerStage = *SincResampler::createSincResampler(sourceSampleRate, targetSampleRate, passband, stopband, ResamplerModel::DEFAULT_DB_SNR, ResamplerModel::DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR); + return ResamplerModel::createResamplerModel(synthSource, resamplerStage); + } + } + return ResamplerModel::createResamplerModel(synthSource, sourceSampleRate, targetSampleRate, static_cast(quality)); +} + +} // namespace MT32Emu + +using namespace MT32Emu; + +InternalResampler::InternalResampler(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality) : + synthSource(*new SynthWrapper(synth)), + model(createModel(synth, synthSource, targetSampleRate, quality)) +{} + +InternalResampler::~InternalResampler() { + ResamplerModel::freeResamplerModel(model, synthSource); + delete &synthSource; +} + +void InternalResampler::getOutputSamples(float *buffer, unsigned int length) { + model.getOutputSamples(buffer, length); +} diff --git a/src/SOUND/munt/srchelper/InternalResampler.h b/src/SOUND/munt/srchelper/InternalResampler.h new file mode 100644 index 000000000..87f8ff25d --- /dev/null +++ b/src/SOUND/munt/srchelper/InternalResampler.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_INTERNAL_RESAMPLER_H +#define MT32EMU_INTERNAL_RESAMPLER_H + +#include "../Enumerations.h" + +#include "FloatSampleProvider.h" + +namespace MT32Emu { + +class Synth; + +class InternalResampler { +public: + InternalResampler(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); + ~InternalResampler(); + + void getOutputSamples(float *buffer, unsigned int length); + +private: + SRCTools::FloatSampleProvider &synthSource; + SRCTools::FloatSampleProvider &model; +}; + +} // namespace MT32Emu + +#endif // MT32EMU_INTERNAL_RESAMPLER_H diff --git a/src/SOUND/munt/srchelper/SamplerateAdapter.cpp b/src/SOUND/munt/srchelper/SamplerateAdapter.cpp new file mode 100644 index 000000000..715d29872 --- /dev/null +++ b/src/SOUND/munt/srchelper/SamplerateAdapter.cpp @@ -0,0 +1,99 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "SamplerateAdapter.h" + +#include "../Synth.h" + +using namespace MT32Emu; + +static const unsigned int CHANNEL_COUNT = 2; + +long SamplerateAdapter::getInputSamples(void *cb_data, float **data) { + SamplerateAdapter *instance = static_cast(cb_data); + unsigned int length = instance->inBufferSize < 1 ? 1 : (MAX_SAMPLES_PER_RUN < instance->inBufferSize ? MAX_SAMPLES_PER_RUN : instance->inBufferSize); + instance->synth.render(instance->inBuffer, length); + *data = instance->inBuffer; + instance->inBufferSize -= length; + return length; +} + +SamplerateAdapter::SamplerateAdapter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality quality) : + synth(useSynth), + inBuffer(new float[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]), + inBufferSize(MAX_SAMPLES_PER_RUN), + inputToOutputRatio(useSynth.getStereoOutputSampleRate() / targetSampleRate), + outputToInputRatio(targetSampleRate / useSynth.getStereoOutputSampleRate()) +{ + int error; + int conversionType; + switch (quality) { + case SamplerateConversionQuality_FASTEST: + conversionType = SRC_LINEAR; + break; + case SamplerateConversionQuality_FAST: + conversionType = SRC_SINC_FASTEST; + break; + case SamplerateConversionQuality_BEST: + conversionType = SRC_SINC_BEST_QUALITY; + break; + case SamplerateConversionQuality_GOOD: + default: + conversionType = SRC_SINC_MEDIUM_QUALITY; + break; + }; + resampler = src_callback_new(getInputSamples, conversionType, CHANNEL_COUNT, &error, this); + if (error != 0) { + synth.printDebug("SamplerateAdapter: Creation of Samplerate instance failed: %s\n", src_strerror(error)); + src_delete(resampler); + resampler = NULL; + } +} + +SamplerateAdapter::~SamplerateAdapter() { + delete[] inBuffer; + src_delete(resampler); +} + +void SamplerateAdapter::getOutputSamples(float *buffer, unsigned int length) { + if (resampler == NULL) { + Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); + return; + } + while (length > 0) { + inBufferSize = static_cast(length * inputToOutputRatio + 0.5); + long gotFrames = src_callback_read(resampler, outputToInputRatio, long(length), buffer); + int error = src_error(resampler); + if (error != 0) { + synth.printDebug("SamplerateAdapter: Samplerate error during processing: %s > resetting\n", src_strerror(error)); + error = src_reset(resampler); + if (error != 0) { + synth.printDebug("SamplerateAdapter: Samplerate failed to reset: %s\n", src_strerror(error)); + src_delete(resampler); + resampler = NULL; + Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); + synth.printDebug("SamplerateAdapter: Samplerate disabled\n"); + return; + } + continue; + } + if (gotFrames <= 0) { + synth.printDebug("SamplerateAdapter: got %li frames from Samplerate, weird\n", gotFrames); + } + buffer += CHANNEL_COUNT * gotFrames; + length -= gotFrames; + } +} diff --git a/src/SOUND/munt/srchelper/SamplerateAdapter.h b/src/SOUND/munt/srchelper/SamplerateAdapter.h new file mode 100644 index 000000000..0991fd771 --- /dev/null +++ b/src/SOUND/munt/srchelper/SamplerateAdapter.h @@ -0,0 +1,48 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_SAMPLERATE_ADAPTER_H +#define MT32EMU_SAMPLERATE_ADAPTER_H + +#include + +#include "../Enumerations.h" + +namespace MT32Emu { + +class Synth; + +class SamplerateAdapter { +public: + SamplerateAdapter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); + ~SamplerateAdapter(); + + void getOutputSamples(float *outBuffer, unsigned int length); + +private: + Synth &synth; + float * const inBuffer; + unsigned int inBufferSize; + const double inputToOutputRatio; + const double outputToInputRatio; + SRC_STATE *resampler; + + static long getInputSamples(void *cb_data, float **data); +}; + +} // namespace MT32Emu + +#endif // MT32EMU_SAMPLERATE_ADAPTER_H diff --git a/src/SOUND/munt/srchelper/SoxrAdapter.cpp b/src/SOUND/munt/srchelper/SoxrAdapter.cpp new file mode 100644 index 000000000..5e8dca97d --- /dev/null +++ b/src/SOUND/munt/srchelper/SoxrAdapter.cpp @@ -0,0 +1,106 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "SoxrAdapter.h" + +#include "../Synth.h" + +using namespace MT32Emu; + +static const unsigned int CHANNEL_COUNT = 2; + +size_t SoxrAdapter::getInputSamples(void *input_fn_state, soxr_in_t *data, size_t requested_len) { + unsigned int length = requested_len < 1 ? 1 : (MAX_SAMPLES_PER_RUN < requested_len ? MAX_SAMPLES_PER_RUN : static_cast(requested_len)); + SoxrAdapter *instance = static_cast(input_fn_state); + instance->synth.render(instance->inBuffer, length); + *data = instance->inBuffer; + return length; +} + +SoxrAdapter::SoxrAdapter(Synth &useSynth, double targetSampleRate, SamplerateConversionQuality quality) : + synth(useSynth), + inBuffer(new float[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]) +{ + soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I); + unsigned long qualityRecipe; + switch (quality) { + case SamplerateConversionQuality_FASTEST: + qualityRecipe = SOXR_QQ; + break; + case SamplerateConversionQuality_FAST: + qualityRecipe = SOXR_LQ; + break; + case SamplerateConversionQuality_GOOD: + qualityRecipe = SOXR_MQ; + break; + case SamplerateConversionQuality_BEST: + default: + qualityRecipe = SOXR_16_BITQ; + break; + }; + soxr_quality_spec_t qSpec = soxr_quality_spec(qualityRecipe, 0); + soxr_runtime_spec_t rtSpec = soxr_runtime_spec(1); + soxr_error_t error; + resampler = soxr_create(synth.getStereoOutputSampleRate(), targetSampleRate, CHANNEL_COUNT, &error, &ioSpec, &qSpec, &rtSpec); + if (error != NULL) { + synth.printDebug("SoxrAdapter: Creation of SOXR instance failed: %s\n", soxr_strerror(error)); + soxr_delete(resampler); + resampler = NULL; + return; + } + error = soxr_set_input_fn(resampler, getInputSamples, this, MAX_SAMPLES_PER_RUN); + if (error != NULL) { + synth.printDebug("SoxrAdapter: Installing sample feed for SOXR failed: %s\n", soxr_strerror(error)); + soxr_delete(resampler); + resampler = NULL; + } +} + +SoxrAdapter::~SoxrAdapter() { + delete[] inBuffer; + if (resampler != NULL) { + soxr_delete(resampler); + } +} + +void SoxrAdapter::getOutputSamples(float *buffer, unsigned int length) { + if (resampler == NULL) { + Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); + return; + } + while (length > 0) { + size_t gotFrames = soxr_output(resampler, buffer, size_t(length)); + soxr_error_t error = soxr_error(resampler); + if (error != NULL) { + synth.printDebug("SoxrAdapter: SOXR error during processing: %s > resetting\n", soxr_strerror(error)); + error = soxr_clear(resampler); + if (error != NULL) { + synth.printDebug("SoxrAdapter: SOXR failed to reset: %s\n", soxr_strerror(error)); + soxr_delete(resampler); + resampler = NULL; + Synth::muteSampleBuffer(buffer, CHANNEL_COUNT * length); + synth.printDebug("SoxrAdapter: SOXR disabled\n"); + return; + } + continue; + } + if (gotFrames == 0) { + synth.printDebug("SoxrAdapter: got 0 frames from SOXR, weird\n"); + } + buffer += CHANNEL_COUNT * gotFrames; + length -= static_cast(gotFrames); + } +} diff --git a/src/SOUND/munt/srchelper/SoxrAdapter.h b/src/SOUND/munt/srchelper/SoxrAdapter.h new file mode 100644 index 000000000..b97ca4da5 --- /dev/null +++ b/src/SOUND/munt/srchelper/SoxrAdapter.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef MT32EMU_SOXR_ADAPTER_H +#define MT32EMU_SOXR_ADAPTER_H + +#include + +#include "../Enumerations.h" + +namespace MT32Emu { + +class Synth; + +class SoxrAdapter { +public: + SoxrAdapter(Synth &synth, double targetSampleRate, SamplerateConversionQuality quality); + ~SoxrAdapter(); + + void getOutputSamples(float *buffer, unsigned int length); + +private: + Synth &synth; + float * const inBuffer; + soxr_t resampler; + + static size_t getInputSamples(void *input_fn_state, soxr_in_t *data, size_t requested_len); +}; + +} // namespace MT32Emu + +#endif // MT32EMU_SOXR_ADAPTER_H diff --git a/src/SOUND/munt/srchelper/srctools/include/FIRResampler.h b/src/SOUND/munt/srchelper/srctools/include/FIRResampler.h new file mode 100644 index 000000000..7c09bf8de --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/FIRResampler.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_FIR_RESAMPLER_H +#define SRCTOOLS_FIR_RESAMPLER_H + +#include "ResamplerStage.h" + +namespace SRCTools { + +typedef FloatSample FIRCoefficient; + +static const unsigned int FIR_INTERPOLATOR_CHANNEL_COUNT = 2; + +class FIRResampler : public ResamplerStage { +public: + FIRResampler(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength); + ~FIRResampler(); + + void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); + unsigned int estimateInLength(const unsigned int outLength) const; + +private: + const struct Constants { + // Filter coefficients + const FIRCoefficient *taps; + // Indicates whether to interpolate filter taps + bool usePhaseInterpolation; + // Size of array of filter coefficients + unsigned int numberOfTaps; + // Upsampling factor + unsigned int numberOfPhases; + // Downsampling factor + double phaseIncrement; + // Index of last delay line element, generally greater than numberOfTaps to form a proper binary mask + unsigned int delayLineMask; + // Delay line + FloatSample(*ringBuffer)[FIR_INTERPOLATOR_CHANNEL_COUNT]; + + Constants(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength); + } constants; + // Index of current sample in delay line + unsigned int ringBufferPosition; + // Current phase + double phase; + + bool needNextInSample() const; + void addInSamples(const FloatSample *&inSamples); + void getOutSamplesStereo(FloatSample *&outSamples); +}; // class FIRResampler + +} // namespace SRCTools + +#endif // SRCTOOLS_FIR_RESAMPLER_H diff --git a/src/SOUND/munt/srchelper/srctools/include/FloatSampleProvider.h b/src/SOUND/munt/srchelper/srctools/include/FloatSampleProvider.h new file mode 100644 index 000000000..e48afcced --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/FloatSampleProvider.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H +#define SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H + +namespace SRCTools { + +typedef float FloatSample; + +/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */ +class FloatSampleProvider { +public: + virtual ~FloatSampleProvider() {}; + + virtual void getOutputSamples(FloatSample *outBuffer, unsigned int size) = 0; +}; + +} // namespace SRCTools + +#endif // SRCTOOLS_FLOAT_SAMPLE_PROVIDER_H diff --git a/src/SOUND/munt/srchelper/srctools/include/IIR2xResampler.h b/src/SOUND/munt/srchelper/srctools/include/IIR2xResampler.h new file mode 100644 index 000000000..0bfe1c4c8 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/IIR2xResampler.h @@ -0,0 +1,100 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_IIR_2X_RESAMPLER_H +#define SRCTOOLS_IIR_2X_RESAMPLER_H + +#include "ResamplerStage.h" + +namespace SRCTools { + +static const unsigned int IIR_RESAMPER_CHANNEL_COUNT = 2; +static const unsigned int IIR_SECTION_ORDER = 2; + +typedef FloatSample IIRCoefficient; +typedef FloatSample BufferedSample; + +typedef BufferedSample SectionBuffer[IIR_SECTION_ORDER]; + +// Non-trivial coefficients of a 2nd-order section of a parallel bank +// (zero-order numerator coefficient is always zero, zero-order denominator coefficient is always unity) +struct IIRSection { + IIRCoefficient num1; + IIRCoefficient num2; + IIRCoefficient den1; + IIRCoefficient den2; +}; + +class IIRResampler : public ResamplerStage { +public: + enum Quality { + // Used when providing custom IIR filter coefficients. + CUSTOM, + // Use fast elliptic filter with symmetric ripple: N=8, Ap=As=-99 dB, fp=0.125, fs = 0.25 (in terms of sample rate) + FAST, + // Use average elliptic filter with symmetric ripple: N=12, Ap=As=-106 dB, fp=0.193, fs = 0.25 (in terms of sample rate) + GOOD, + // Use sharp elliptic filter with symmetric ripple: N=18, Ap=As=-106 dB, fp=0.238, fs = 0.25 (in terms of sample rate) + BEST + }; + + // Returns the retained fraction of the passband for the given standard quality value + static double getPassbandFractionForQuality(Quality quality); + +protected: + explicit IIRResampler(const Quality quality); + explicit IIRResampler(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]); + ~IIRResampler(); + + const struct Constants { + // Coefficient of the 0-order FIR part + IIRCoefficient fir; + // 2nd-order sections that comprise a parallel bank + const IIRSection *sections; + // Number of 2nd-order sections + unsigned int sectionsCount; + // Delay line per channel per section + SectionBuffer *buffer; + + Constants(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[], const Quality quality); + } constants; +}; // class IIRResampler + +class IIR2xInterpolator : public IIRResampler { +public: + explicit IIR2xInterpolator(const Quality quality); + explicit IIR2xInterpolator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]); + + void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); + unsigned int estimateInLength(const unsigned int outLength) const; + +private: + FloatSample lastInputSamples[IIR_RESAMPER_CHANNEL_COUNT]; + unsigned int phase; +}; + +class IIR2xDecimator : public IIRResampler { +public: + explicit IIR2xDecimator(const Quality quality); + explicit IIR2xDecimator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]); + + void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); + unsigned int estimateInLength(const unsigned int outLength) const; +}; + +} // namespace SRCTools + +#endif // SRCTOOLS_IIR_2X_RESAMPLER_H diff --git a/src/SOUND/munt/srchelper/srctools/include/LinearResampler.h b/src/SOUND/munt/srchelper/srctools/include/LinearResampler.h new file mode 100644 index 000000000..c81ff2a38 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/LinearResampler.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_LINEAR_RESAMPLER_H +#define SRCTOOLS_LINEAR_RESAMPLER_H + +#include "ResamplerStage.h" + +namespace SRCTools { + +static const unsigned int LINEAR_RESAMPER_CHANNEL_COUNT = 2; + +class LinearResampler : public ResamplerStage { +public: + LinearResampler(double sourceSampleRate, double targetSampleRate); + ~LinearResampler() {} + + unsigned int estimateInLength(const unsigned int outLength) const; + void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength); + +private: + const double inputToOutputRatio; + double position; + FloatSample lastInputSamples[LINEAR_RESAMPER_CHANNEL_COUNT]; +}; + +} // namespace SRCTools + +#endif // SRCTOOLS_LINEAR_RESAMPLER_H diff --git a/src/SOUND/munt/srchelper/srctools/include/ResamplerModel.h b/src/SOUND/munt/srchelper/srctools/include/ResamplerModel.h new file mode 100644 index 000000000..f0ac23707 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/ResamplerModel.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_RESAMPLER_MODEL_H +#define SRCTOOLS_RESAMPLER_MODEL_H + +#include "FloatSampleProvider.h" + +namespace SRCTools { + +class ResamplerStage; + +/** Model consists of one or more ResampleStage instances connected in a cascade. */ +namespace ResamplerModel { + +// Seems to be a good choice for 16-bit integer samples. +static const double DEFAULT_DB_SNR = 106; + +// When using linear interpolation, oversampling factor necessary to achieve the DEFAULT_DB_SNR is about 256. +// This figure is the upper estimation, and it can be found by analysing the frequency response of the linear interpolator. +// When less SNR is desired, this value should also decrease in accordance. +static const unsigned int DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR = 256; + +// In the default resampler model, the input to the windowed sinc filter is always at least 2x oversampled during upsampling, +// so oversampling factor of 128 should be sufficient to achieve the DEFAULT_DB_SNR with linear interpolation. +static const unsigned int DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR = DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR / 2; + + +enum Quality { + // Use when the speed is more important than the audio quality. + FASTEST, + // Use FAST quality setting of the IIR stage (50% of passband retained). + FAST, + // Use GOOD quality setting of the IIR stage (77% of passband retained). + GOOD, + // Use BEST quality setting of the IIR stage (95% of passband retained). + BEST +}; + +FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, double sourceSampleRate, double targetSampleRate, Quality quality); +FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, ResamplerStage **stages, unsigned int stageCount); +FloatSampleProvider &createResamplerModel(FloatSampleProvider &source, ResamplerStage &stage); + +void freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source); + +} // namespace ResamplerModel + +} // namespace SRCTools + +#endif // SRCTOOLS_RESAMPLER_MODEL_H diff --git a/src/SOUND/munt/srchelper/srctools/include/ResamplerStage.h b/src/SOUND/munt/srchelper/srctools/include/ResamplerStage.h new file mode 100644 index 000000000..6aea9624d --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/ResamplerStage.h @@ -0,0 +1,38 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_RESAMPLER_STAGE_H +#define SRCTOOLS_RESAMPLER_STAGE_H + +#include "FloatSampleProvider.h" + +namespace SRCTools { + +/** Interface defines an abstract source of samples. It can either define a single channel stream or a stream with interleaved channels. */ +class ResamplerStage { +public: + virtual ~ResamplerStage() {}; + + /** Returns a lower estimation of required number of input samples to produce the specified number of output samples. */ + virtual unsigned int estimateInLength(const unsigned int outLength) const = 0; + + /** Generates output samples. The arguments are adjusted in accordance with the number of samples processed. */ + virtual void process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) = 0; +}; + +} // namespace SRCTools + +#endif // SRCTOOLS_RESAMPLER_STAGE_H diff --git a/src/SOUND/munt/srchelper/srctools/include/SincResampler.h b/src/SOUND/munt/srchelper/srctools/include/SincResampler.h new file mode 100644 index 000000000..1551a1eda --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/include/SincResampler.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef SRCTOOLS_SINC_RESAMPLER_H +#define SRCTOOLS_SINC_RESAMPLER_H + +#include "FIRResampler.h" + +namespace SRCTools { + +class ResamplerStage; + +namespace SincResampler { + + ResamplerStage *createSincResampler(const double inputFrequency, const double outputFrequency, const double passbandFrequency, const double stopbandFrequency, const double dbSNR, const unsigned int maxUpsampleFactor); + + namespace Utils { + void computeResampleFactors(unsigned int &upsampleFactor, double &downsampleFactor, const double inputFrequency, const double outputFrequency, const unsigned int maxUpsampleFactor); + unsigned int greatestCommonDivisor(unsigned int a, unsigned int b); + } + + namespace KaizerWindow { + double estimateBeta(double dbRipple); + unsigned int estimateOrder(double dbRipple, double fp, double fs); + double bessel(const double x); + void windowedSinc(FIRCoefficient kernel[], const unsigned int order, const double fc, const double beta, const double amp); + } + +} // namespace SincResampler + +} // namespace SRCTools + +#endif // SRCTOOLS_SINC_RESAMPLER_H diff --git a/src/SOUND/munt/srchelper/srctools/src/FIRResampler.cpp b/src/SOUND/munt/srchelper/srctools/src/FIRResampler.cpp new file mode 100644 index 000000000..2cded0c3d --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/src/FIRResampler.cpp @@ -0,0 +1,107 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "FIRResampler.h" + +using namespace SRCTools; + +FIRResampler::Constants::Constants(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength) { + usePhaseInterpolation = downsampleFactor != floor(downsampleFactor); + FIRCoefficient *kernelCopy = new FIRCoefficient[kernelLength]; + memcpy(kernelCopy, kernel, kernelLength * sizeof(FIRCoefficient)); + taps = kernelCopy; + numberOfTaps = kernelLength; + numberOfPhases = upsampleFactor; + phaseIncrement = downsampleFactor; + unsigned int minDelayLineLength = static_cast(ceil(double(kernelLength) / upsampleFactor)); + unsigned int delayLineLength = 2; + while (delayLineLength < minDelayLineLength) delayLineLength <<= 1; + delayLineMask = delayLineLength - 1; + ringBuffer = new FloatSample[delayLineLength][FIR_INTERPOLATOR_CHANNEL_COUNT]; + FloatSample *s = *ringBuffer; + FloatSample *e = ringBuffer[delayLineLength]; + while (s < e) *(s++) = 0; +} + +FIRResampler::FIRResampler(const unsigned int upsampleFactor, const double downsampleFactor, const FIRCoefficient kernel[], const unsigned int kernelLength) : + constants(upsampleFactor, downsampleFactor, kernel, kernelLength), + ringBufferPosition(0), + phase(constants.numberOfPhases) +{} + +FIRResampler::~FIRResampler() { + delete[] constants.ringBuffer; + delete[] constants.taps; +} + +void FIRResampler::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { + while (outLength > 0) { + while (needNextInSample()) { + if (inLength == 0) return; + addInSamples(inSamples); + --inLength; + } + getOutSamplesStereo(outSamples); + --outLength; + } +} + +unsigned int FIRResampler::estimateInLength(const unsigned int outLength) const { + return static_cast((outLength * constants.phaseIncrement + phase) / constants.numberOfPhases); +} + +bool FIRResampler::needNextInSample() const { + return constants.numberOfPhases <= phase; +} + +void FIRResampler::addInSamples(const FloatSample *&inSamples) { + ringBufferPosition = (ringBufferPosition - 1) & constants.delayLineMask; + for (unsigned int i = 0; i < FIR_INTERPOLATOR_CHANNEL_COUNT; i++) { + constants.ringBuffer[ringBufferPosition][i] = *(inSamples++); + } + phase -= constants.numberOfPhases; +} + +// Optimised for processing stereo interleaved streams +void FIRResampler::getOutSamplesStereo(FloatSample *&outSamples) { + FloatSample leftSample = 0.0; + FloatSample rightSample = 0.0; + unsigned int delaySampleIx = ringBufferPosition; + if (constants.usePhaseInterpolation) { + double phaseFraction = phase - floor(phase); + unsigned int maxTapIx = phaseFraction == 0 ? constants.numberOfTaps : constants.numberOfTaps - 1; + for (unsigned int tapIx = static_cast(phase); tapIx < maxTapIx; tapIx += constants.numberOfPhases) { + FIRCoefficient tap = FIRCoefficient(constants.taps[tapIx] + (constants.taps[tapIx + 1] - constants.taps[tapIx]) * phaseFraction); + leftSample += tap * constants.ringBuffer[delaySampleIx][0]; + rightSample += tap * constants.ringBuffer[delaySampleIx][1]; + delaySampleIx = (delaySampleIx + 1) & constants.delayLineMask; + } + } else { + // Optimised for rational resampling ratios when phase is always integer + for (unsigned int tapIx = static_cast(phase); tapIx < constants.numberOfTaps; tapIx += constants.numberOfPhases) { + FIRCoefficient tap = constants.taps[tapIx]; + leftSample += tap * constants.ringBuffer[delaySampleIx][0]; + rightSample += tap * constants.ringBuffer[delaySampleIx][1]; + delaySampleIx = (delaySampleIx + 1) & constants.delayLineMask; + } + } + *(outSamples++) = leftSample; + *(outSamples++) = rightSample; + phase += constants.phaseIncrement; +} diff --git a/src/SOUND/munt/srchelper/srctools/src/IIR2xResampler.cpp b/src/SOUND/munt/srchelper/srctools/src/IIR2xResampler.cpp new file mode 100644 index 000000000..0016f23c9 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/src/IIR2xResampler.cpp @@ -0,0 +1,229 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#include "IIR2xResampler.h" + +namespace SRCTools { + + // Avoid denormals degrading performance, using biased input + static const BufferedSample BIAS = 1e-20f; + + // Sharp elliptic filter with symmetric ripple: N=18, Ap=As=-106 dB, fp=0.238, fs = 0.25 (in terms of sample rate) + static const IIRCoefficient FIR_BEST = 0.0014313792470984f; + static const IIRSection SECTIONS_BEST[] = { + { 2.85800356692148000f,-0.2607342682253230f,-0.602478421807085f, 0.109823442522145f }, + { -4.39519408383016000f, 1.4651975326003500f,-0.533817668127954f, 0.226045921792036f }, + { 0.86638550740991800f,-2.1053851417898500f,-0.429134968401065f, 0.403512574222174f }, + { 1.67161485530774000f, 0.7963595880494520f,-0.324989203363446f, 0.580756666711889f }, + { -1.19962759276471000f, 0.5873595178851540f,-0.241486447489019f, 0.724264899930934f }, + { 0.01631779946479250f,-0.6282334739461620f,-0.182766025706656f, 0.827774001858882f }, + { 0.28404415859352400f, 0.1038619997715160f,-0.145276649558926f, 0.898510501923554f }, + { -0.08105788424234910f, 0.0781551578108934f,-0.123965846623366f, 0.947105257601873f }, + { -0.00872608905948005f,-0.0222098231712466f,-0.115056854360748f, 0.983542001125711f } + }; + + // Average elliptic filter with symmetric ripple: N=12, Ap=As=-106 dB, fp=0.193, fs = 0.25 (in terms of sample rate) + static const IIRCoefficient FIR_GOOD = 0.000891054570268146f; + static const IIRSection SECTIONS_GOOD[] = { + { 2.2650157226725700f,-0.4034180565140230f,-0.750061486095301f, 0.157801404511953f }, + { -3.2788261989161700f, 1.3952152147542600f,-0.705854270206788f, 0.265564985645774f }, + { 0.4397975114813240f,-1.3957634748753100f,-0.639718853965265f, 0.435324134360315f }, + { 0.9827040216680520f, 0.1837182774040940f,-0.578569965618418f, 0.615205557837542f }, + { -0.3759752818621670f, 0.3266073609399490f,-0.540913588637109f, 0.778264420176574f }, + { -0.0253548089519618f,-0.0925779221603846f,-0.537704370375240f, 0.925800083252964f } + }; + + // Fast elliptic filter with symmetric ripple: N=8, Ap=As=-99 dB, fp=0.125, fs = 0.25 (in terms of sample rate) + static const IIRCoefficient FIR_FAST = 0.000882837778745889f; + static const IIRSection SECTIONS_FAST[] = { + { 1.215377077431620f,-0.35864455030878000f,-0.972220718789242f, 0.252934735930620f }, + { -1.525654419254140f, 0.86784918631245500f,-0.977713689358124f, 0.376580616703668f }, + { 0.136094441564220f,-0.50414116798010400f,-1.007004471865290f, 0.584048854845331f }, + { 0.180604082285806f,-0.00467624342403851f,-1.093486919012100f, 0.844904524843996f } + }; + + static inline BufferedSample calcNumerator(const IIRSection §ion, const BufferedSample buffer1, const BufferedSample buffer2) { + return section.num1 * buffer1 + section.num2 * buffer2; + } + + static inline BufferedSample calcDenominator(const IIRSection §ion, const BufferedSample input, const BufferedSample buffer1, const BufferedSample buffer2) { + return input - section.den1 * buffer1 - section.den2 * buffer2; + } + +} // namespace SRCTools + +using namespace SRCTools; + +double IIRResampler::getPassbandFractionForQuality(Quality quality) { + switch (quality) { + case FAST: + return 0.5; + case GOOD: + return 0.7708; + case BEST: + return 0.9524; + default: + return 0; + } +} + +IIRResampler::Constants::Constants(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[], const Quality quality) { + if (quality == CUSTOM) { + sectionsCount = useSectionsCount; + fir = useFIR; + sections = useSections; + } else { + unsigned int sectionsSize; + switch (quality) { + case FAST: + fir = FIR_FAST; + sections = SECTIONS_FAST; + sectionsSize = sizeof(SECTIONS_FAST); + break; + case GOOD: + fir = FIR_GOOD; + sections = SECTIONS_GOOD; + sectionsSize = sizeof(SECTIONS_GOOD); + break; + case BEST: + fir = FIR_BEST; + sections = SECTIONS_BEST; + sectionsSize = sizeof(SECTIONS_BEST); + break; + default: + sectionsSize = 0; + break; + } + sectionsCount = (sectionsSize / sizeof(IIRSection)); + } + const unsigned int delayLineSize = IIR_RESAMPER_CHANNEL_COUNT * sectionsCount; + buffer = new SectionBuffer[delayLineSize]; + BufferedSample *s = buffer[0]; + BufferedSample *e = buffer[delayLineSize]; + while (s < e) *(s++) = 0; +} + +IIRResampler::IIRResampler(const Quality quality) : + constants(0, 0.0f, NULL, quality) +{} + +IIRResampler::IIRResampler(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]) : + constants(useSectionsCount, useFIR, useSections, IIRResampler::CUSTOM) +{} + +IIRResampler::~IIRResampler() { + delete[] constants.buffer; +} + +IIR2xInterpolator::IIR2xInterpolator(const Quality quality) : + IIRResampler(quality), + phase(1) +{ + for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { + lastInputSamples[chIx] = 0; + } +} + +IIR2xInterpolator::IIR2xInterpolator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]) : + IIRResampler(useSectionsCount, useFIR, useSections), + phase(1) +{ + for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { + lastInputSamples[chIx] = 0; + } +} + +void IIR2xInterpolator::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { + static const IIRCoefficient INTERPOLATOR_AMP = 2.0; + + while (outLength > 0 && inLength > 0) { + SectionBuffer *bufferp = constants.buffer; + for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { + const FloatSample lastInputSample = lastInputSamples[chIx]; + const FloatSample inSample = inSamples[chIx]; + BufferedSample tmpOut = phase == 0 ? 0 : inSample * constants.fir; + for (unsigned int i = 0; i < constants.sectionsCount; ++i) { + const IIRSection §ion = constants.sections[i]; + SectionBuffer &buffer = *bufferp; + // For 2x interpolation, calculation of the numerator reduces to a single multiplication depending on the phase. + if (phase == 0) { + const BufferedSample numOutSample = section.num1 * lastInputSample; + const BufferedSample denOutSample = calcDenominator(section, BIAS + numOutSample, buffer[0], buffer[1]); + buffer[1] = denOutSample; + tmpOut += denOutSample; + } else { + const BufferedSample numOutSample = section.num2 * lastInputSample; + const BufferedSample denOutSample = calcDenominator(section, BIAS + numOutSample, buffer[1], buffer[0]); + buffer[0] = denOutSample; + tmpOut += denOutSample; + } + bufferp++; + } + *(outSamples++) = FloatSample(INTERPOLATOR_AMP * tmpOut); + if (phase > 0) { + lastInputSamples[chIx] = inSample; + } + } + outLength--; + if (phase > 0) { + inSamples += IIR_RESAMPER_CHANNEL_COUNT; + inLength--; + phase = 0; + } else { + phase = 1; + } + } +} + +unsigned int IIR2xInterpolator::estimateInLength(const unsigned int outLength) const { + return outLength >> 1; +} + +IIR2xDecimator::IIR2xDecimator(const Quality quality) : + IIRResampler(quality) +{} + +IIR2xDecimator::IIR2xDecimator(const unsigned int useSectionsCount, const IIRCoefficient useFIR, const IIRSection useSections[]) : + IIRResampler(useSectionsCount, useFIR, useSections) +{} + +void IIR2xDecimator::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { + while (outLength > 0 && inLength > 1) { + SectionBuffer *bufferp = constants.buffer; + for (unsigned int chIx = 0; chIx < IIR_RESAMPER_CHANNEL_COUNT; ++chIx) { + BufferedSample tmpOut = inSamples[chIx] * constants.fir; + for (unsigned int i = 0; i < constants.sectionsCount; ++i) { + const IIRSection §ion = constants.sections[i]; + SectionBuffer &buffer = *bufferp; + // For 2x decimation, calculation of the numerator is not performed for odd output samples which are to be omitted. + tmpOut += calcNumerator(section, buffer[0], buffer[1]); + buffer[1] = calcDenominator(section, BIAS + inSamples[chIx], buffer[0], buffer[1]); + buffer[0] = calcDenominator(section, BIAS + inSamples[chIx + IIR_RESAMPER_CHANNEL_COUNT], buffer[1], buffer[0]); + bufferp++; + } + *(outSamples++) = FloatSample(tmpOut); + } + outLength--; + inLength -= 2; + inSamples += 2 * IIR_RESAMPER_CHANNEL_COUNT; + } +} + +unsigned int IIR2xDecimator::estimateInLength(const unsigned int outLength) const { + return outLength << 1; +} diff --git a/src/SOUND/munt/srchelper/srctools/src/LinearResampler.cpp b/src/SOUND/munt/srchelper/srctools/src/LinearResampler.cpp new file mode 100644 index 000000000..98b9c77c7 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/src/LinearResampler.cpp @@ -0,0 +1,47 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "LinearResampler.h" + +using namespace SRCTools; + +LinearResampler::LinearResampler(double sourceSampleRate, double targetSampleRate) : + inputToOutputRatio(sourceSampleRate / targetSampleRate), + position(1.0) // Preload delay line which effectively makes resampler zero phase +{} + +void LinearResampler::process(const FloatSample *&inSamples, unsigned int &inLength, FloatSample *&outSamples, unsigned int &outLength) { + if (inLength == 0) return; + while (outLength > 0) { + while (1.0 <= position) { + position--; + inLength--; + for (unsigned int chIx = 0; chIx < LINEAR_RESAMPER_CHANNEL_COUNT; ++chIx) { + lastInputSamples[chIx] = *(inSamples++); + } + if (inLength == 0) return; + } + for (unsigned int chIx = 0; chIx < LINEAR_RESAMPER_CHANNEL_COUNT; chIx++) { + *(outSamples++) = FloatSample(lastInputSamples[chIx] + position * (inSamples[chIx] - lastInputSamples[chIx])); + } + outLength--; + position += inputToOutputRatio; + } +} + +unsigned int LinearResampler::estimateInLength(const unsigned int outLength) const { + return static_cast(outLength * inputToOutputRatio); +} diff --git a/src/SOUND/munt/srchelper/srctools/src/ResamplerModel.cpp b/src/SOUND/munt/srchelper/srctools/src/ResamplerModel.cpp new file mode 100644 index 000000000..4d2d93083 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/src/ResamplerModel.cpp @@ -0,0 +1,153 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "ResamplerModel.h" + +#include "ResamplerStage.h" +#include "SincResampler.h" +#include "IIR2xResampler.h" +#include "LinearResampler.h" + +namespace SRCTools { + +namespace ResamplerModel { + +static const unsigned int CHANNEL_COUNT = 2; +static const unsigned int MAX_SAMPLES_PER_RUN = 4096; + +class CascadeStage : public FloatSampleProvider { +friend void freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source); +public: + CascadeStage(FloatSampleProvider &source, ResamplerStage &resamplerStage); + + void getOutputSamples(FloatSample *outBuffer, unsigned int size); + +protected: + ResamplerStage &resamplerStage; + +private: + FloatSampleProvider &source; + FloatSample buffer[CHANNEL_COUNT * MAX_SAMPLES_PER_RUN]; + const FloatSample *bufferPtr; + unsigned int size; +}; + +class InternalResamplerCascadeStage : public CascadeStage { +public: + InternalResamplerCascadeStage(FloatSampleProvider &useSource, ResamplerStage &useResamplerStage) : + CascadeStage(useSource, useResamplerStage) + {} + + ~InternalResamplerCascadeStage() { + delete &resamplerStage; + } +}; + +} // namespace ResamplerModel + +} // namespace SRCTools + +using namespace SRCTools; + +FloatSampleProvider &ResamplerModel::createResamplerModel(FloatSampleProvider &source, double sourceSampleRate, double targetSampleRate, Quality quality) { + if (sourceSampleRate == targetSampleRate) { + return source; + } + if (quality == FASTEST) { + return *new InternalResamplerCascadeStage(source, *new LinearResampler(sourceSampleRate, targetSampleRate)); + } + const IIRResampler::Quality iirQuality = static_cast(quality); + const double iirPassbandFraction = IIRResampler::getPassbandFractionForQuality(iirQuality); + if (sourceSampleRate < targetSampleRate) { + ResamplerStage *iir2xInterpolator = new IIR2xInterpolator(iirQuality); + FloatSampleProvider &iir2xInterpolatorStage = *new InternalResamplerCascadeStage(source, *iir2xInterpolator); + + if (2.0 * sourceSampleRate == targetSampleRate) { + return iir2xInterpolatorStage; + } + + double passband = 0.5 * sourceSampleRate * iirPassbandFraction; + double stopband = 1.5 * sourceSampleRate; + ResamplerStage *sincResampler = SincResampler::createSincResampler(2.0 * sourceSampleRate, targetSampleRate, passband, stopband, DEFAULT_DB_SNR, DEFAULT_WINDOWED_SINC_MAX_UPSAMPLE_FACTOR); + return *new InternalResamplerCascadeStage(iir2xInterpolatorStage, *sincResampler); + } + + if (sourceSampleRate == 2.0 * targetSampleRate) { + ResamplerStage *iir2xDecimator = new IIR2xDecimator(iirQuality); + return *new InternalResamplerCascadeStage(source, *iir2xDecimator); + } + + double passband = 0.5 * targetSampleRate * iirPassbandFraction; + double stopband = 1.5 * targetSampleRate; + double sincOutSampleRate = 2.0 * targetSampleRate; + const unsigned int maxUpsampleFactor = static_cast(ceil(DEFAULT_WINDOWED_SINC_MAX_DOWNSAMPLE_FACTOR * sincOutSampleRate / sourceSampleRate)); + ResamplerStage *sincResampler = SincResampler::createSincResampler(sourceSampleRate, sincOutSampleRate, passband, stopband, DEFAULT_DB_SNR, maxUpsampleFactor); + FloatSampleProvider &sincResamplerStage = *new InternalResamplerCascadeStage(source, *sincResampler); + + ResamplerStage *iir2xDecimator = new IIR2xDecimator(iirQuality); + return *new InternalResamplerCascadeStage(sincResamplerStage, *iir2xDecimator); +} + +FloatSampleProvider &ResamplerModel::createResamplerModel(FloatSampleProvider &source, ResamplerStage **resamplerStages, unsigned int stageCount) { + FloatSampleProvider *prevStage = &source; + for (unsigned int i = 0; i < stageCount; i++) { + prevStage = new CascadeStage(*prevStage, *(resamplerStages[i])); + } + return *prevStage; +} + +FloatSampleProvider &ResamplerModel::createResamplerModel(FloatSampleProvider &source, ResamplerStage &stage) { + return *new CascadeStage(source, stage); +} + +void ResamplerModel::freeResamplerModel(FloatSampleProvider &model, FloatSampleProvider &source) { + FloatSampleProvider *currentStage = &model; + while (currentStage != &source) { + CascadeStage *cascadeStage = dynamic_cast(currentStage); + if (cascadeStage == NULL) return; + FloatSampleProvider &prevStage = cascadeStage->source; + delete currentStage; + currentStage = &prevStage; + } +} + +using namespace ResamplerModel; + +CascadeStage::CascadeStage(FloatSampleProvider &useSource, ResamplerStage &useResamplerStage) : + resamplerStage(useResamplerStage), + source(useSource), + bufferPtr(buffer), + size() +{} + +void CascadeStage::getOutputSamples(FloatSample *outBuffer, unsigned int length) { + while (length > 0) { + if (size == 0) { + size = resamplerStage.estimateInLength(length); + if (size < 1) { + size = 1; + } else if (MAX_SAMPLES_PER_RUN < size) { + size = MAX_SAMPLES_PER_RUN; + } + source.getOutputSamples(buffer, size); + bufferPtr = buffer; + } + resamplerStage.process(bufferPtr, size, outBuffer, length); + } +} diff --git a/src/SOUND/munt/srchelper/srctools/src/SincResampler.cpp b/src/SOUND/munt/srchelper/srctools/src/SincResampler.cpp new file mode 100644 index 000000000..38d0ebe45 --- /dev/null +++ b/src/SOUND/munt/srchelper/srctools/src/SincResampler.cpp @@ -0,0 +1,136 @@ +/* Copyright (C) 2015-2017 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include + +#ifdef SRCTOOLS_SINC_RESAMPLER_DEBUG_LOG +#include +#endif + +#include "SincResampler.h" + +#ifndef M_PI +static const double M_PI = 3.1415926535897932; +#endif + +using namespace SRCTools; + +using namespace SincResampler; + +using namespace Utils; + +void Utils::computeResampleFactors(unsigned int &upsampleFactor, double &downsampleFactor, const double inputFrequency, const double outputFrequency, const unsigned int maxUpsampleFactor) { + static const double RATIONAL_RATIO_ACCURACY_FACTOR = 1E15; + + upsampleFactor = static_cast(outputFrequency); + unsigned int downsampleFactorInt = static_cast(inputFrequency); + if ((upsampleFactor == outputFrequency) && (downsampleFactorInt == inputFrequency)) { + // Input and output frequencies are integers, try to reduce them + const unsigned int gcd = greatestCommonDivisor(upsampleFactor, downsampleFactorInt); + if (gcd > 1) { + upsampleFactor /= gcd; + downsampleFactor = downsampleFactorInt / gcd; + } else { + downsampleFactor = downsampleFactorInt; + } + if (upsampleFactor <= maxUpsampleFactor) return; + } else { + // Try to recover rational resample ratio by brute force + double inputToOutputRatio = inputFrequency / outputFrequency; + for (unsigned int i = 1; i <= maxUpsampleFactor; ++i) { + double testFactor = inputToOutputRatio * i; + if (floor(RATIONAL_RATIO_ACCURACY_FACTOR * testFactor + 0.5) == RATIONAL_RATIO_ACCURACY_FACTOR * floor(testFactor + 0.5)) { + // inputToOutputRatio found to be rational within the accuracy + upsampleFactor = i; + downsampleFactor = floor(testFactor + 0.5); + return; + } + } + } + // Use interpolation of FIR taps as the last resort + upsampleFactor = maxUpsampleFactor; + downsampleFactor = maxUpsampleFactor * inputFrequency / outputFrequency; +} + +unsigned int Utils::greatestCommonDivisor(unsigned int a, unsigned int b) { + while (0 < b) { + unsigned int r = a % b; + a = b; + b = r; + } + return a; +} + +double KaizerWindow::estimateBeta(double dbRipple) { + return 0.1102 * (dbRipple - 8.7); +} + +unsigned int KaizerWindow::estimateOrder(double dbRipple, double fp, double fs) { + const double transBW = (fs - fp); + return static_cast(ceil((dbRipple - 8) / (2.285 * 2 * M_PI * transBW))); +} + +double KaizerWindow::bessel(const double x) { + static const double EPS = 1.11E-16; + + double sum = 0.0; + double f = 1.0; + for (unsigned int i = 1;; ++i) { + f *= (0.5 * x / i); + double f2 = f * f; + if (f2 <= sum * EPS) break; + sum += f2; + } + return 1.0 + sum; +} + +void KaizerWindow::windowedSinc(FIRCoefficient kernel[], const unsigned int order, const double fc, const double beta, const double amp) { + const double fc_pi = M_PI * fc; + const double recipOrder = 1.0 / order; + const double mult = 2.0 * fc * amp / bessel(beta); + for (int i = order, j = 0; 0 <= i; i -= 2, ++j) { + double xw = i * recipOrder; + double win = bessel(beta * sqrt(fabs(1.0 - xw * xw))); + double xs = i * fc_pi; + double sinc = (i == 0) ? 1.0 : sin(xs) / xs; + FIRCoefficient imp = FIRCoefficient(mult * sinc * win); + kernel[j] = imp; + kernel[order - j] = imp; + } +} + +ResamplerStage *SincResampler::createSincResampler(const double inputFrequency, const double outputFrequency, const double passbandFrequency, const double stopbandFrequency, const double dbSNR, const unsigned int maxUpsampleFactor) { + unsigned int upsampleFactor; + double downsampleFactor; + computeResampleFactors(upsampleFactor, downsampleFactor, inputFrequency, outputFrequency, maxUpsampleFactor); + double baseSamplePeriod = 1.0 / (inputFrequency * upsampleFactor); + double fp = passbandFrequency * baseSamplePeriod; + double fs = stopbandFrequency * baseSamplePeriod; + double fc = 0.5 * (fp + fs); + double beta = KaizerWindow::estimateBeta(dbSNR); + unsigned int order = KaizerWindow::estimateOrder(dbSNR, fp, fs); + const unsigned int kernelLength = order + 1; + +#ifdef SRCTOOLS_SINC_RESAMPLER_DEBUG_LOG + std::clog << "FIR: " << upsampleFactor << "/" << downsampleFactor << ", N=" << kernelLength << ", NPh=" << kernelLength / double(upsampleFactor) << ", C=" << 0.5 / fc << ", fp=" << fp << ", fs=" << fs << ", M=" << maxUpsampleFactor << std::endl; +#endif + + FIRCoefficient *windowedSincKernel = new FIRCoefficient[kernelLength]; + KaizerWindow::windowedSinc(windowedSincKernel, order, fc, beta, upsampleFactor); + ResamplerStage *windowedSincStage = new FIRResampler(upsampleFactor, downsampleFactor, windowedSincKernel, kernelLength); + delete[] windowedSincKernel; + return windowedSincStage; +} diff --git a/src/SOUND/openal.c b/src/SOUND/openal.c index b044c0e5a..4265f44ca 100644 --- a/src/SOUND/openal.c +++ b/src/SOUND/openal.c @@ -15,12 +15,23 @@ FILE *allog; #ifdef USE_OPENAL ALuint buffers[4]; /* front and back buffers */ ALuint buffers_cd[4]; /* front and back buffers */ -static ALuint source[2]; /* audio source */ +ALuint buffers_midi[4]; /* front and back buffers */ +static ALuint source[3]; /* audio source */ #endif #define FREQ 48000 #define BUFLEN SOUNDBUFLEN +static int midi_freq = 44100; +static int midi_buf_size = 4410; +static int initialized = 0; + +void al_set_midi(int freq, int buf_size) +{ + midi_freq = freq; + midi_buf_size = buf_size; +} + void closeal(void); ALvoid alutInit(ALint *argc,ALbyte **argv) { @@ -64,28 +75,41 @@ void initalmain(int argc, char *argv[]) void closeal(void) { + if (!initialized) return; #ifdef USE_OPENAL alutExit(); #endif + initialized = 0; } void inital(ALvoid) { + if (initialized) return; + #ifdef USE_OPENAL int c; - float buf[BUFLEN*2]; + float *buf = NULL, *cd_buf = NULL, *midi_buf = NULL; + int16_t *buf_int16 = NULL, *cd_buf_int16 = NULL, *midi_buf_int16 = NULL; - float cd_buf[CD_BUFLEN*2]; - - int16_t buf_int16[BUFLEN*2]; - - int16_t cd_buf_int16[CD_BUFLEN*2]; + if (sound_is_float) + { + buf = (float *) malloc((BUFLEN << 1) * sizeof(float)); + cd_buf = (float *) malloc((CD_BUFLEN << 1) * sizeof(float)); + midi_buf = (float *) malloc(midi_buf_size * sizeof(float)); + } + else + { + buf_int16 = (int16_t *) malloc((BUFLEN << 1) * sizeof(int16_t)); + cd_buf_int16 = (int16_t *) malloc((CD_BUFLEN << 1) * sizeof(int16_t)); + midi_buf_int16 = (int16_t *) malloc(midi_buf_size * sizeof(int16_t)); + } alGenBuffers(4, buffers); alGenBuffers(4, buffers_cd); + alGenBuffers(4, buffers_midi); - alGenSources(2, source); + alGenSources(3, source); alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); @@ -97,9 +121,24 @@ void inital(ALvoid) alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[2], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[2], AL_SOURCE_RELATIVE, AL_TRUE ); - memset(buf,0,BUFLEN*2*sizeof(float)); - memset(cd_buf,0,BUFLEN*2*sizeof(float)); + if (sound_is_float) + { + memset(buf,0,BUFLEN*2*sizeof(float)); + memset(cd_buf,0,BUFLEN*2*sizeof(float)); + memset(midi_buf,0,midi_buf_size*sizeof(float)); + } + else + { + memset(buf_int16,0,BUFLEN*2*sizeof(int16_t)); + memset(cd_buf_int16,0,BUFLEN*2*sizeof(int16_t)); + memset(midi_buf_int16,0,midi_buf_size*sizeof(int16_t)); + } for (c = 0; c < 4; c++) { @@ -107,123 +146,84 @@ void inital(ALvoid) { alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size*sizeof(float), midi_freq); } else { alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size*sizeof(int16_t), midi_freq); } } alSourceQueueBuffers(source[0], 4, buffers); alSourceQueueBuffers(source[1], 4, buffers_cd); + alSourceQueueBuffers(source[2], 4, buffers_midi); alSourcePlay(source[0]); alSourcePlay(source[1]); + alSourcePlay(source[2]); + + if (sound_is_float) + { + free(midi_buf); + free(cd_buf); + free(buf); + } + else + { + free(midi_buf_int16); + free(cd_buf_int16); + free(buf_int16); + } + + initialized = 1; #endif } -void givealbuffer(float *buf) +void givealbuffer_common(void *buf, uint8_t src, int size, int freq) { #ifdef USE_OPENAL int processed; int state; ALuint buffer; - alGetSourcei(source[0], AL_SOURCE_STATE, &state); + alGetSourcei(source[src], AL_SOURCE_STATE, &state); if (state==0x1014) { - alSourcePlay(source[0]); + alSourcePlay(source[src]); } - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); if (processed>=1) { - alSourceUnqueueBuffers(source[0], 1, &buffer); + alSourceUnqueueBuffers(source[src], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + if (sound_is_float) + { + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); + } + else + { + alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); + } - alSourceQueueBuffers(source[0], 1, &buffer); + alSourceQueueBuffers(source[src], 1, &buffer); } #endif } -void givealbuffer_int16(int16_t *buf) +void givealbuffer(void *buf) { -#ifdef USE_OPENAL - int processed; - int state; - ALuint buffer; - - alGetSourcei(source[0], AL_SOURCE_STATE, &state); - - if (state==0x1014) - { - alSourcePlay(source[0]); - } - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); - - if (processed>=1) - { - alSourceUnqueueBuffers(source[0], 1, &buffer); - - alBufferData(buffer, AL_FORMAT_STEREO16, buf, BUFLEN*2*sizeof(int16_t), FREQ); - - alSourceQueueBuffers(source[0], 1, &buffer); - } -#endif + givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); } -void givealbuffer_cd(float *buf) +void givealbuffer_cd(void *buf) { -#ifdef USE_OPENAL - int processed; - int state; - - alGetSourcei(source[1], AL_SOURCE_STATE, &state); - - if (state==0x1014) - { - alSourcePlay(source[1]); - } - alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); - - if (processed>=1) - { - ALuint buffer; - - alSourceUnqueueBuffers(source[1], 1, &buffer); - - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - - alSourceQueueBuffers(source[1], 1, &buffer); - } -#endif + givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ); } -void givealbuffer_cd_int16(int16_t *buf) +void givealbuffer_midi(void *buf, uint32_t size) { -#ifdef USE_OPENAL - int processed; - int state; - - alGetSourcei(source[1], AL_SOURCE_STATE, &state); - - if (state==0x1014) - { - alSourcePlay(source[1]); - } - alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); - - if (processed>=1) - { - ALuint buffer; - - alSourceUnqueueBuffers(source[1], 1, &buffer); - - alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - - alSourceQueueBuffers(source[1], 1, &buffer); - } -#endif + givealbuffer_common(buf, 2, size, midi_freq); } diff --git a/src/SOUND/snd_mpu401.c b/src/SOUND/snd_mpu401.c index 60e3bd1c6..e03211f59 100644 --- a/src/SOUND/snd_mpu401.c +++ b/src/SOUND/snd_mpu401.c @@ -8,7 +8,7 @@ * * Roland MPU-401 emulation. * - * Version: @(#)sound_mpu401.c 1.0.0 2017/05/30 + * Version: @(#)sound_mpu401.c 1.0.1 2017/06/19 * * Author: Sarah Walker, * DOSBox Team, @@ -25,7 +25,7 @@ #include "../io.h" #include "../pic.h" #include "../timer.h" -#include "../win/plat_midi.h" /*YUCK*/ +#include "midi.h" #include "sound.h" #include "snd_mpu401.h" diff --git a/src/SOUND/snd_sb_dsp.c b/src/SOUND/snd_sb_dsp.c index a4cc3286b..8ff2e4efc 100644 --- a/src/SOUND/snd_sb_dsp.c +++ b/src/SOUND/snd_sb_dsp.c @@ -9,9 +9,9 @@ #include "../io.h" #include "../pic.h" #include "../dma.h" -#include "../win/plat_midi.h" /*YUCK*/ #include "../timer.h" #include "../device.h" +#include "midi.h" #include "sound.h" #include "snd_mpu401.h" #include "snd_sb_dsp.h" diff --git a/src/SOUND/sound.c b/src/SOUND/sound.c index 369065411..addacdc8b 100644 --- a/src/SOUND/sound.c +++ b/src/SOUND/sound.c @@ -23,6 +23,7 @@ #include "../timer.h" #include "../cdrom.h" #include "../win/plat_thread.h" +#include "midi.h" #include "sound.h" #include "snd_opl.h" #include "snd_adlib.h" @@ -262,7 +263,7 @@ static void sound_cd_thread(void *param) } else { - givealbuffer_cd_int16(cd_out_buffer_int16); + givealbuffer_cd(cd_out_buffer_int16); } } } @@ -275,10 +276,6 @@ static int cd_thread_enable = 0; void sound_realloc_buffers(void) { - closeal(); - initalmain(0,NULL); - inital(); - if (outbuffer_ex != NULL) { free(outbuffer_ex); @@ -341,7 +338,9 @@ void sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), vo void sound_poll(void *priv) { sound_poll_time += sound_poll_latch; - + + midi_poll(); + sound_pos_global++; if (sound_pos_global == SOUNDBUFLEN) { @@ -378,7 +377,7 @@ void sound_poll(void *priv) } else { - givealbuffer_int16(outbuffer_ex_int16); + givealbuffer(outbuffer_ex_int16); } } diff --git a/src/SOUND/sound.h b/src/SOUND/sound.h index 05540b403..9afdaa902 100644 --- a/src/SOUND/sound.h +++ b/src/SOUND/sound.h @@ -46,7 +46,5 @@ void sound_cd_thread_reset(); void closeal(void); void initalmain(int argc, char *argv[]); void inital(); -void givealbuffer(float *buf); -void givealbuffer_int16(int16_t *buf); -void givealbuffer_cd(float *buf); -void givealbuffer_cd_int16(int16_t *buf); +void givealbuffer(void *buf); +void givealbuffer_cd(void *buf); diff --git a/src/WIN/86Box.rc b/src/WIN/86Box.rc index 705da1599..28a4f1ca0 100644 --- a/src/WIN/86Box.rc +++ b/src/WIN/86Box.rc @@ -44,13 +44,47 @@ MAINMENU MENU DISCARDABLE BEGIN POPUP "&Action" BEGIN - MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT - MENUITEM SEPARATOR MENUITEM "&Hard Reset", IDM_ACTION_HRESET MENUITEM "&Ctrl+Alt+Del\tCtrl+F12", IDM_ACTION_RESET_CAD MENUITEM SEPARATOR MENUITEM "E&xit", IDM_ACTION_EXIT END + POPUP "&View" + BEGIN + MENUITEM "&Resizeable window", IDM_VID_RESIZE + MENUITEM "R&emember size && position", IDM_VID_REMEMBER + MENUITEM SEPARATOR + POPUP "Re&nderer" + BEGIN + MENUITEM "&DirectDraw", IDM_VID_DDRAW + MENUITEM "Direct&3D 9", IDM_VID_D3D + END + MENUITEM SEPARATOR + POPUP "&Window scale factor" + BEGIN + MENUITEM "&0.5x", IDM_VID_SCALE_1X + MENUITEM "&1x", IDM_VID_SCALE_2X + MENUITEM "1.&5x", IDM_VID_SCALE_3X + MENUITEM "&2x", IDM_VID_SCALE_4X + END + MENUITEM SEPARATOR + MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN + POPUP "Fullscreen &stretch mode" + BEGIN + MENUITEM "&Full screen stretch", IDM_VID_FS_FULL + MENUITEM "&4:3", IDM_VID_FS_43 + MENUITEM "&Square pixels", IDM_VID_FS_SQ + MENUITEM "&Integer scale", IDM_VID_FS_INT + END + POPUP "E&GA/(S)VGA settings" + BEGIN + MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT + MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN + END + MENUITEM SEPARATOR + MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 + MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON + END POPUP "&Tools" BEGIN MENUITEM "&Settings...", IDM_CONFIG @@ -58,38 +92,8 @@ BEGIN MENUITEM "&Load configuration...", IDM_CONFIG_LOAD MENUITEM "&Save configuration...", IDM_CONFIG_SAVE MENUITEM SEPARATOR - POPUP "&Video" - BEGIN - MENUITEM "&Resizeable window", IDM_VID_RESIZE - MENUITEM "R&emember size && position", IDM_VID_REMEMBER - MENUITEM SEPARATOR - MENUITEM "&DirectDraw", IDM_VID_DDRAW - MENUITEM "Direct&3D 9", IDM_VID_D3D - MENUITEM SEPARATOR - POPUP "&Window scale factor" - BEGIN - MENUITEM "&0.5x", IDM_VID_SCALE_1X - MENUITEM "&1x", IDM_VID_SCALE_2X - MENUITEM "1.&5x", IDM_VID_SCALE_3X - MENUITEM "&2x", IDM_VID_SCALE_4X - END - MENUITEM SEPARATOR - MENUITEM "&Fullscreen\tCtrl+Alt+PageUP", IDM_VID_FULLSCREEN - POPUP "Fullscreen &stretch mode" - BEGIN - MENUITEM "&Full screen stretch", IDM_VID_FS_FULL - MENUITEM "&4:3", IDM_VID_FS_43 - MENUITEM "&Square pixels", IDM_VID_FS_SQ - MENUITEM "&Integer scale", IDM_VID_FS_INT - END - MENUITEM SEPARATOR - MENUITEM "&Inverted VGA monitor", IDM_VID_INVERT - MENUITEM "F&orce 4:3 display ratio", IDM_VID_FORCE43 - MENUITEM "E&GA/(S)VGA overscan", IDM_VID_OVERSCAN - MENUITEM "Change contrast for &monochrome display", IDM_VID_CGACON - - END MENUITEM "S&tatus", IDM_STATUS + MENUITEM "Take s&creenshot\tCtrl+F11", IDM_ACTION_SCREENSHOT END #if defined(ENABLE_LOG_TOGGLES) || defined(ENABLE_LOG_COMMANDS) POPUP "&Logging" @@ -211,12 +215,15 @@ BEGIN CONTROL "List2",IDC_SETTINGSCATLIST,"SysListView32",LVS_LIST | LVS_SHOWSELALWAYS | LVS_SINGLESEL | WS_BORDER | WS_TABSTOP,7,7,90,197 CONTROL "",-1,"Static",SS_BLACKFRAME | SS_SUNKEN,1,211,363,1 +/* Leave this commented out until we get into localization. */ +#if 0 LTEXT "Language:",IDT_1700,7,222,41,10 COMBOBOX IDC_COMBO_LANG,48,221,108,120,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP +#endif END -DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 112 +DLG_CFG_MACHINE DIALOG DISCARDABLE 97, 0, 267, 132 STYLE DS_CONTROL | WS_CHILD FONT 9, "Segoe UI" BEGIN @@ -227,24 +234,27 @@ BEGIN COMBOBOX IDC_COMBO_CPU_TYPE,71,25,45,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "CPU type:",IDT_1702,7,26,59,10 - COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Wait states:",IDT_1703,7,45,60,10 COMBOBOX IDC_COMBO_CPU,145,25,115,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "CPU:",IDT_1704,124,26,18,10 - CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,80,94,10 - CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,147,80,113,10 + COMBOBOX IDC_COMBO_WS,71,44,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Wait states:",IDT_1703,7,45,60,10 EDITTEXT IDC_MEMTEXT,70,63,45,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "",IDC_MEMSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,113,63, 12,12 LTEXT "MB",IDT_1705,123,64,10,10 LTEXT "Memory:",IDT_1706,7,64,30,10 + LTEXT "NVR Path:",IDT_1700,7,83,60,10 + EDITTEXT IDC_EDIT_NVR_PATH,71,82,138,12 + PUSHBUTTON "&Specify...",IDC_BUTTON_NVR_PATH,214,82,46,12 + CONTROL "Dynamic Recompiler",IDC_CHECK_DYNAREC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,100,94,10 + CONTROL "Enable FPU",IDC_CHECK_FPU,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,147,100,113,10 CONTROL "Enable time sync",IDC_CHECK_SYNC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,95,102,10 + BS_AUTOCHECKBOX | WS_TABSTOP,7,115,102,10 END DLG_CFG_VIDEO DIALOG DISCARDABLE 97, 0, 267, 63 @@ -287,9 +297,11 @@ BEGIN WS_TABSTOP LTEXT "Sound card:",IDT_1711,7,8,59,10 PUSHBUTTON "Configure",IDC_CONFIGURE_SND,214,7,46,12 - COMBOBOX IDC_COMBO_MIDI,71,25,189,120,CBS_DROPDOWNLIST | WS_VSCROLL | + + COMBOBOX IDC_COMBO_MIDI,71,25,140,120,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "MIDI Out Device:",IDT_1712,7,26,59,10 + PUSHBUTTON "Configure",IDC_CONFIGURE_MIDI,214,25,46,12 CONTROL "Standalone MPU-401",IDC_CHECK_MPU401,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,45,199,10 @@ -868,10 +880,12 @@ BEGIN IDS_2221 "Turbo" IDS_2222 "On" IDS_2223 "Off" - IDS_2224 "" - IDS_2225 "English (United States)" + IDS_2224 "Logitech 3-button mouse (serial)" + IDS_2225 "Specify the NVR Path" + IDS_2226 "" + IDS_2227 "English (United States)" END -#define IDS_LANG_ENUS IDS_2225 +#define IDS_LANG_ENUS IDS_2227 #ifndef _MAC diff --git a/src/WIN/plat_midi.h b/src/WIN/plat_midi.h index 87ed57306..b1b93b5e2 100644 --- a/src/WIN/plat_midi.h +++ b/src/WIN/plat_midi.h @@ -1,10 +1,7 @@ -/* Copyright holders: Sarah Walker - see COPYING for more details -*/ -void midi_init(); -void midi_close(); -void midi_write(uint8_t val); -int midi_get_num_devs(); -void midi_get_dev_name(int num, char *s); - -extern int midi_id; +void plat_midi_init(); +void plat_midi_close(); +void plat_midi_play_msg(uint8_t* val); +void plat_midi_play_sysex(uint8_t* data, unsigned int len); +int plat_midi_write(uint8_t val); +int plat_midi_get_num_devs(); +void plat_midi_get_dev_name(int num, char *s); diff --git a/src/WIN/plat_ticks.h b/src/WIN/plat_ticks.h new file mode 100644 index 000000000..d6e48f37a --- /dev/null +++ b/src/WIN/plat_ticks.h @@ -0,0 +1,2 @@ +uint32_t get_ticks(void); +void delay_ms(uint32_t count); diff --git a/src/WIN/resource.h b/src/WIN/resource.h index d73057c21..864d0167e 100644 --- a/src/WIN/resource.h +++ b/src/WIN/resource.h @@ -87,7 +87,10 @@ #define IDC_SETTINGSCATLIST 1001 /* generic config */ #define IDC_CFILE 1002 /* Select File dialog */ #define IDC_CHECK_SYNC 1008 +/* Leave this as is until we finally get into localization in 86Box 3.00(?). */ +#if 0 #define IDC_COMBO_LANG 1009 +#endif #define IDC_COMBO_MACHINE 1010 /* machine/cpu config */ #define IDC_CONFIGURE_MACHINE 1011 @@ -99,6 +102,8 @@ #define IDC_MEMTEXT 1017 #define IDC_MEMSPIN 1018 #define IDC_TEXT_MB IDT_1705 +#define IDC_EDIT_NVR_PATH 1019 +#define IDC_BUTTON_NVR_PATH 1020 #define IDC_VIDEO 1030 /* video config */ #define IDC_COMBO_VIDEO 1031 @@ -181,6 +186,7 @@ #define IDC_CONFIGURE_BUSLOGIC 1205 #define IDC_CONFIGURE_PCAP 1206 #define IDC_CONFIGURE_NET 1207 +#define IDC_CONFIGURE_MIDI 1208 #define IDC_JOY1 1210 #define IDC_JOY2 1211 #define IDC_JOY3 1212 @@ -367,11 +373,13 @@ #define IDS_2221 2221 // "Turbo" #define IDS_2222 2222 // "On" #define IDS_2223 2223 // "Off" -#define IDS_2224 2224 // "" -#define IDS_2225 2225 // "English (United States)" +#define IDS_2224 2224 // "Logitech 3-button mouse (serial)" +#define IDS_2225 2225 // "Specify the NVR Path" +#define IDS_2226 2226 // "" +#define IDS_2227 2227 // "English (United States)" -#define IDS_LANG_ENUS IDS_2225 -#define STRINGS_NUM 178 +#define IDS_LANG_ENUS IDS_2227 +#define STRINGS_NUM 180 #define IDM_ABOUT 40001 diff --git a/src/WIN/win.c b/src/WIN/win.c index 41eb621dc..15cffbeb6 100644 --- a/src/WIN/win.c +++ b/src/WIN/win.c @@ -49,6 +49,7 @@ #include "plat_mouse.h" #include "plat_midi.h" #include "plat_thread.h" +#include "plat_ticks.h" #include "plat_ui.h" #include "win.h" @@ -271,6 +272,16 @@ void leave_fullscreen(void) leave_fullscreen_flag = 1; } +uint32_t get_ticks(void) +{ + return GetTickCount(); +} + +void delay_ms(uint32_t count) +{ + Sleep(count); +} + void mainthread(LPVOID param) { int frames = 0; @@ -2044,6 +2055,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM null_close(i); } } + resetpchard_close(); loadconfig(wopenfilestring); for (i = 0; i < CDROM_NUM; i++) { @@ -2075,7 +2087,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM mem_resize(); loadbios(); update_status_bar_panes(hwndStatus); - resetpchard(); + resetpchard_init(); } } pause = 0; @@ -2318,7 +2330,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR break; } - ret = file_dlg_w_st(hwnd, IDS_2173, discfns[id], id); + ret = file_dlg_w_st(hwnd, IDS_2173, discfns[id], 0); if (!ret) { disc_close(id); diff --git a/src/WIN/win_deviceconfig.c b/src/WIN/win_deviceconfig.c index cf0474c16..3cce23331 100644 --- a/src/WIN/win_deviceconfig.c +++ b/src/WIN/win_deviceconfig.c @@ -8,7 +8,7 @@ * * Windows device configuration dialog implementation. * - * Version: @(#)win_deviceconfig.c 1.0.0 2017/05/30 + * Version: @(#)win_deviceconfig.c 1.0.1 2017/06/19 * * Authors: Sarah Walker, * Miran Grca, @@ -18,8 +18,10 @@ #include "../ibm.h" #include "../config.h" #include "../device.h" +#include "plat_midi.h" #define NO_UNICODE /*FIXME: not Unicode? */ #include "win.h" +#include "win_language.h" #include @@ -29,15 +31,22 @@ static device_t *config_device; static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND h; + int val_int; + int ret; + int id; + device_config_t *config; + int c; + int num; + int changed; + char s[80]; switch (message) { case WM_INITDIALOG: { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; + id = IDC_CONFIG_BASE; + config = config_device->config; while (config->type != -1) { @@ -70,6 +79,21 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + case CONFIG_MIDI: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + num = plat_midi_get_num_devs(); + for (c = 0; c < num; c++) + { + plat_midi_get_dev_name(c, s); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s); + if (val_int == c) + SendMessage(h, CB_SETCURSEL, c, 0); + } + + id += 2; + break; + case CONFIG_HEX16: val_int = config_get_hex16(config_device->name, config->name, config->default_int); @@ -112,10 +136,9 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam { case IDOK: { - int id = IDC_CONFIG_BASE; - device_config_t *config = config_device->config; - int c; - int changed = 0; + id = IDC_CONFIG_BASE; + config = config_device->config; + changed = 0; while (config->type != -1) { @@ -147,6 +170,17 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + case CONFIG_MIDI: + val_int = config_get_int(config_device->name, config->name, config->default_int); + + c = SendMessage(h, CB_GETCURSEL, 0, 0); + + if (val_int != c) + changed = 1; + + id += 2; + break; + case CONFIG_HEX16: val_int = config_get_hex16(config_device->name, config->name, config->default_int); @@ -183,11 +217,17 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam EndDialog(hdlg, 0); return TRUE; } - - if (MessageBox(NULL, "This will reset 86Box!\nOkay to continue?", "86Box", MB_OKCANCEL) != IDOK) - { - EndDialog(hdlg, 0); - return TRUE; + + ret = msgbox_reset(ghwnd); + switch(ret) + { + case IDNO: + EndDialog(hdlg, 0); + return TRUE; + case IDCANCEL: + return FALSE; + default: + break; } id = IDC_CONFIG_BASE; @@ -215,6 +255,13 @@ static BOOL CALLBACK deviceconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam id += 2; break; + case CONFIG_MIDI: + c = SendMessage(h, CB_GETCURSEL, 0, 0); + config_set_int(config_device->name, config->name, c); + + id += 2; + break; + case CONFIG_HEX16: c = SendMessage(h, CB_GETCURSEL, 0, 0); for (; c > 0; c--) @@ -308,6 +355,7 @@ void deviceconfig_open(HWND hwnd, device_t *device) break; case CONFIG_SELECTION: + case CONFIG_MIDI: case CONFIG_HEX16: case CONFIG_HEX20: /*Combo box*/ diff --git a/src/WIN/win_language.c b/src/WIN/win_language.c index 61dae5f2c..ed4e19159 100644 --- a/src/WIN/win_language.c +++ b/src/WIN/win_language.c @@ -237,10 +237,10 @@ static int CALLBACK BrowseCallbackProc(HWND hwnd,UINT uMsg, LPARAM lParam, LPARA WCHAR path[MAX_PATH]; -wchar_t *BrowseFolder(wchar_t *saved_path) +wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title) { BROWSEINFO bi = { 0 }; - bi.lpszTitle = L"Browse for folder..."; + bi.lpszTitle = title; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM) saved_path; @@ -253,15 +253,12 @@ wchar_t *BrowseFolder(wchar_t *saved_path) SHGetPathFromIDList(pidl, path); /* Free memory used. */ -#if 0 IMalloc *imalloc = 0; if (SUCCEEDED(SHGetMalloc(&imalloc))) { - imalloc->Free(pidl); - imalloc->Release(); + imalloc->lpVtbl->Free(imalloc, pidl); + imalloc->lpVtbl->Release(imalloc); } -#endif - free(pidl); return path; } diff --git a/src/WIN/win_language.h b/src/WIN/win_language.h index bb7af81b7..50b0105e3 100644 --- a/src/WIN/win_language.h +++ b/src/WIN/win_language.h @@ -46,6 +46,8 @@ void win_language_check(); LPTSTR win_language_get_string_from_id(int i); LPTSTR win_language_get_string_from_string(char *str); +wchar_t *BrowseFolder(wchar_t *saved_path, wchar_t *title); + #ifdef __cplusplus } #endif diff --git a/src/WIN/win_midi.c b/src/WIN/win_midi.c index 1515fa5ac..4572c0b32 100644 --- a/src/WIN/win_midi.c +++ b/src/WIN/win_midi.c @@ -1,25 +1,8 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * MIDI interface to host device. - * - * Version: @(#)win_midi.c 1.0.0 2017/05/30 - * - * Author: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ - #include #include #include "../ibm.h" #include "../config.h" +#include "../SOUND/midi.h" #include "plat_midi.h" int midi_id = 0; @@ -27,8 +10,6 @@ static HMIDIOUT midi_out_device = NULL; HANDLE m_event; -void midi_close(); - static uint8_t midi_rt_buf[1024]; static uint8_t midi_cmd_buf[1024]; static int midi_cmd_pos = 0; @@ -37,31 +18,20 @@ static uint8_t midi_status = 0; static unsigned int midi_sysex_start = 0; static unsigned int midi_sysex_delay = 0; -uint8_t MIDI_evt_len[256] = { - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60 - 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0 - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0 - - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0 - 2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0 - - 3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0 - - 0,2,3,2, 0,0,1,0, 1,0,1,1, 1,0,1,0 // 0xf0 -}; - -void midi_init() +void plat_midi_init() { + /* This is for compatibility with old configuration files. */ + midi_id = config_get_int("Sound", "midi_host_device", -1); + if (midi_id == -1) + { + midi_id = config_get_int(SYSTEM_MIDI_NAME, "midi", 0); + } + else + { + config_delete_var("Sound", "midi_host_device"); + config_set_int(SYSTEM_MIDI_NAME, "midi", midi_id); + } + MMRESULT hr = MMSYSERR_NOERROR; memset(midi_rt_buf, 0, sizeof(midi_rt_buf)); @@ -86,11 +56,11 @@ void midi_init() return; } } - + midiOutReset(midi_out_device); } -void midi_close() +void plat_midi_close() { if (midi_out_device != NULL) { @@ -101,11 +71,11 @@ void midi_close() } } -int midi_get_num_devs() +int plat_midi_get_num_devs() { return midiOutGetNumDevs(); } -void midi_get_dev_name(int num, char *s) +void plat_midi_get_dev_name(int num, char *s) { MIDIOUTCAPS caps; @@ -113,17 +83,14 @@ void midi_get_dev_name(int num, char *s) strcpy(s, caps.szPname); } -static int midi_pos; -static uint8_t midi_sysex_data[1024+2]; - -void PlayMsg(uint8_t *msg) +void plat_midi_play_msg(uint8_t *msg) { midiOutShortMsg(midi_out_device, *(uint32_t *) msg); } MIDIHDR m_hdr; -void PlaySysex(uint8_t *sysex, unsigned int len) +void plat_midi_play_sysex(uint8_t *sysex, unsigned int len) { MMRESULT result; @@ -152,124 +119,7 @@ void PlaySysex(uint8_t *sysex, unsigned int len) } } -#define SYSEX_SIZE 1024 -#define RAWBUF 1024 - -void midi_write(uint8_t val) +int plat_midi_write(uint8_t val) { - uint32_t passed_ticks; - - if (midi_sysex_start) - { - passed_ticks = GetTickCount() - midi_sysex_start; - if (passed_ticks < midi_sysex_delay) - { - Sleep(midi_sysex_delay - passed_ticks); - } - } - - /* Test for a realtime MIDI message */ - if (val >= 0xf8) - { - midi_rt_buf[0] = val; - PlayMsg(midi_rt_buf); - return; - } - - /* Test for a active sysex transfer */ - - if (midi_status == 0xf0) - { - if (!(val & 0x80)) - { - if (midi_pos < (SYSEX_SIZE-1)) midi_sysex_data[midi_pos++] = val; - return; - } - else - { - midi_sysex_data[midi_pos++] = 0xf7; - - if ((midi_sysex_start) && (midi_pos >= 4) && (midi_pos <= 9) && (midi_sysex_data[1] == 0x411) && (midi_sysex_data[3] == 0x16)) - { - /* pclog("MIDI: Skipping invalid MT-32 SysEx MIDI message\n"); */ - } - else - { - PlaySysex(midi_sysex_data, midi_pos); - if (midi_sysex_start) - { - if (midi_sysex_data[5] == 0x7f) - { - midi_sysex_delay = 290; /* All parameters reset */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x04)) - { - midi_sysex_delay = 145; /* Viking Child */ - } - else if ((midi_sysex_data[5] == 0x10) && (midi_sysex_data[6] == 0x00) && (midi_sysex_data[7] == 0x01)) - { - midi_sysex_delay = 30; /* Dark Sun 1 */ - } - else - midi_sysex_delay = (unsigned int) (((float) (midi_pos) * 1.25f) * 1000.0f / 3125.0f) + 2; - - midi_sysex_start = GetTickCount(); - } - } - } - } - - - if (val & 0x80) - { - midi_status = val; - midi_cmd_pos = 0; - midi_cmd_len = MIDI_evt_len[val]; - if (midi_status == 0xf0) - { - midi_sysex_data[0] = 0xf0; - midi_pos = 1; - } - } - - if (midi_cmd_len) - { - midi_cmd_buf[midi_cmd_pos++] = val; - if (midi_cmd_pos >= midi_cmd_len) - { - PlayMsg(midi_cmd_buf); - midi_cmd_pos = 1; - } - } -} - -void midi_reset() -{ - uint8_t buf[64]; - - /* Flush buffers */ - midiOutReset(midi_out_device); - - /* GM1 reset */ - buf[0] = 0xf0; - buf[1] = 0x7e; - buf[2] = 0x7f; - buf[3] = 0x09; - buf[4] = 0x01; - buf[5] = 0xf7; - PlaySysex((uint8_t *) buf, 6); - - /* GS1 reset */ - buf[0] = 0xf0; - buf[1] = 0x41; - buf[2] = 0x10; - buf[3] = 0x42; - buf[4] = 0x12; - buf[5] = 0x40; - buf[6] = 0x00; - buf[7] = 0x7f; - buf[8] = 0x00; - buf[9] = 0x41; - buf[10] = 0xf7; - PlaySysex((uint8_t *) buf, 11); + return 0; } diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index d16435b22..bc5d4724f 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.3 2017/06/14 + * Version: @(#)win_settings.c 1.0.4 2017/06/19 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -35,6 +35,7 @@ #include "../scsi.h" #include "../scsi_buslogic.h" #include "../network/network.h" +#include "../sound/midi.h" #include "../sound/sound.h" #include "../sound/snd_dbopl.h" #include "../sound/snd_mpu401.h" @@ -49,6 +50,7 @@ /* Machine category */ static int temp_model, temp_cpu_m, temp_cpu, temp_wait_states, temp_mem_size, temp_dynarec, temp_fpu, temp_sync; +static wchar_t temp_nvr_path[520]; /* Video category */ static int temp_gfxcard, temp_video_speed, temp_voodoo; @@ -57,7 +59,7 @@ static int temp_gfxcard, temp_video_speed, temp_voodoo; static int temp_mouse, temp_joystick; /* Sound category */ -static int temp_sound_card, temp_midi_id, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; +static int temp_sound_card, temp_midi_device, temp_mpu401, temp_SSI2001, temp_GAMEBLASTER, temp_GUS, temp_opl3_type; static int temp_float; /* Network category */ @@ -87,6 +89,7 @@ static int displayed_category = 0; extern int is486; static int romstolist[ROM_MAX], listtomodel[ROM_MAX], romstomodel[ROM_MAX], modeltolist[ROM_MAX]; static int settings_sound_to_list[20], settings_list_to_sound[20]; +static int settings_midi_to_list[20], settings_list_to_midi[20]; static int settings_mouse_to_list[20], settings_list_to_mouse[20]; static int settings_scsi_to_list[20], settings_list_to_scsi[20]; static int settings_network_to_list[20], settings_list_to_network[20]; @@ -104,6 +107,8 @@ static void win_settings_init(void) temp_wait_states = cpu_waitstates; temp_cpu = cpu; temp_mem_size = mem_size; + memset(temp_nvr_path, 0, sizeof(temp_nvr_path)); + wcscpy(temp_nvr_path, nvr_path); temp_dynarec = cpu_use_dynarec; temp_fpu = enable_external_fpu; temp_sync = enable_sync; @@ -119,7 +124,7 @@ static void win_settings_init(void) /* Sound category */ temp_sound_card = sound_card_current; - temp_midi_id = midi_id; + temp_midi_device = midi_device_current; temp_mpu401 = mpu401_standalone_enable; temp_SSI2001 = SSI2001; temp_GAMEBLASTER = GAMEBLASTER; @@ -170,6 +175,7 @@ static int win_settings_changed(void) i = i || (cpu_waitstates != temp_wait_states); i = i || (cpu != temp_cpu); i = i || (mem_size != temp_mem_size); + i = i || wcscmp(temp_nvr_path, nvr_path); i = i || (temp_dynarec != cpu_use_dynarec); i = i || (temp_fpu != enable_external_fpu); i = i || (temp_sync != enable_sync); @@ -185,7 +191,7 @@ static int win_settings_changed(void) /* Sound category */ i = i || (sound_card_current != temp_sound_card); - i = i || (midi_id != temp_midi_id); + i = i || (midi_device_current != temp_midi_device); i = i || (mpu401_standalone_enable != temp_mpu401); i = i || (SSI2001 != temp_SSI2001); i = i || (GAMEBLASTER != temp_GAMEBLASTER); @@ -261,6 +267,8 @@ static void win_settings_save(void) { int i = 0; + resetpchard_close(); + /* Machine category */ model = temp_model; romset = model_getromset(); @@ -268,6 +276,8 @@ static void win_settings_save(void) cpu_waitstates = temp_wait_states; cpu = temp_cpu; mem_size = temp_mem_size; + memset(nvr_path, 0, sizeof(nvr_path)); + wcscpy(nvr_path, temp_nvr_path); cpu_use_dynarec = temp_dynarec; enable_external_fpu = temp_fpu; enable_sync = temp_sync; @@ -283,7 +293,7 @@ static void win_settings_save(void) /* Sound category */ sound_card_current = temp_sound_card; - midi_id = temp_midi_id; + midi_device_current = temp_midi_device; mpu401_standalone_enable = temp_mpu401; SSI2001 = temp_SSI2001; GAMEBLASTER = temp_GAMEBLASTER; @@ -327,7 +337,7 @@ static void win_settings_save(void) sound_realloc_buffers(); - resetpchard(); + resetpchard_init(); cpu_set(); @@ -493,7 +503,7 @@ static void win_settings_machine_recalc_model(HWND hdlg) accel.nSec = 0; accel.nInc = models[romstomodel[temp_romset]].ram_granularity; SendMessage(h, UDM_SETACCEL, 1, (LPARAM)&accel); - if (!(models[romstomodel[temp_romset]].flags & MODEL_AT)) + if (!(models[romstomodel[temp_romset]].flags & MODEL_AT) || (models[romstomodel[temp_romset]].ram_granularity >= 128)) { SendMessage(h, UDM_SETPOS, 0, temp_mem_size); h = GetDlgItem(hdlg, IDC_TEXT_MB); @@ -517,6 +527,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w int d = 0; LPTSTR lptsTemp; char *stransi; + wchar_t *p; switch (message) { @@ -568,6 +579,9 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w win_settings_machine_recalc_model(hdlg); + h = GetDlgItem(hdlg, IDC_EDIT_NVR_PATH); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) temp_nvr_path); + free(lptsTemp); return TRUE; @@ -609,6 +623,24 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w deviceconfig_open(hdlg, (void *)model_getdevice(temp_model)); break; + case IDC_BUTTON_NVR_PATH: + p = BrowseFolder(temp_nvr_path, win_language_get_string_from_id(IDS_2225)); + if (wcscmp(p, L"")) + { + memset(temp_nvr_path, 0, sizeof(temp_nvr_path)); + wcscpy(temp_nvr_path, p); + if (temp_nvr_path[wcslen(temp_nvr_path) - 1] == L'/') + { + temp_nvr_path[wcslen(temp_nvr_path) - 1] = L'\\'; + } + else if (temp_nvr_path[wcslen(temp_nvr_path) - 1] != L'\\') + { + temp_nvr_path[wcslen(temp_nvr_path)] = L'\\'; + } + h = GetDlgItem(hdlg, IDC_EDIT_NVR_PATH); + SendMessage(h, WM_SETTEXT, 0, (LPARAM) temp_nvr_path); + } + break; } return FALSE; @@ -892,7 +924,10 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa case 6: /* MouseSystems */ str_id = IDS_2140; break; - case 7: /* Genius Bus */ + case 7: /* Logitech Serial */ + str_id = IDS_2224; + break; + case 8: /* Genius Bus */ str_id = IDS_2161; break; } @@ -1114,8 +1149,6 @@ int find_irq_in_array(int irq, int def) } -static char midi_dev_name_buf[512]; - int mpu401_present(void) { char *n; @@ -1134,9 +1167,10 @@ int mpu401_present(void) int mpu401_standalone_allow(void) { - char *n; + char *n, *md; n = sound_card_get_internal_name(temp_sound_card); + md = midi_device_get_internal_name(temp_midi_device); if (n != NULL) { if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) @@ -1145,6 +1179,14 @@ int mpu401_standalone_allow(void) } } + if (md != NULL) + { + if (!strcmp(md, "none")) + { + return 0; + } + } + return 1; } @@ -1154,8 +1196,8 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa int c = 0; int d = 0; LPTSTR lptsTemp; - device_t *sound_dev; - int num = 0; + device_t *sound_dev, *midi_dev; + char *s; switch (message) { @@ -1166,7 +1208,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa c = d = 0; while (1) { - char *s = sound_card_getname(c); + s = sound_card_getname(c); if (!s[0]) { @@ -1210,15 +1252,50 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa } h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - num = midi_get_num_devs(); - for (c = 0; c < num; c++) + c = d = 0; + while (1) { - memset(midi_dev_name_buf, 0, 512); - midi_get_dev_name(c, midi_dev_name_buf); - mbstowcs(lptsTemp, midi_dev_name_buf, strlen(midi_dev_name_buf) + 1); - SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); - if (c == temp_midi_id) - SendMessage(h, CB_SETCURSEL, c, 0); + s = midi_device_getname(c); + + if (!s[0]) + { + break; + } + + settings_midi_to_list[c] = d; + + if (midi_device_available(c)) + { + midi_dev = midi_device_getdevice(c); + + if (!midi_dev || (midi_dev->flags & DEVICE_MCA) == (models[temp_model].flags & MODEL_MCA)) + { + if (c == 0) + { + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) win_language_get_string_from_id(IDS_2152)); + } + else + { + mbstowcs(lptsTemp, s, strlen(s) + 1); + SendMessage(h, CB_ADDSTRING, 0, (LPARAM) lptsTemp); + } + settings_list_to_midi[d] = c; + d++; + } + } + + c++; + } + SendMessage(h, CB_SETCURSEL, settings_sound_to_list[temp_midi_device], 0); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); + if (midi_device_has_config(temp_midi_device)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); } EnableWindow(h, mpu401_present() ? TRUE : FALSE); @@ -1251,13 +1328,6 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa case WM_COMMAND: switch (LOWORD(wParam)) { - case IDC_CONFIGURE_SND: - h = GetDlgItem(hdlg, IDC_COMBO_SOUND); - temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; - - deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); - break; - case IDC_COMBO_SOUND: h = GetDlgItem(hdlg, IDC_COMBO_SOUND); temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; @@ -1276,6 +1346,38 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa EnableWindow(h, mpu401_present() ? TRUE : FALSE); break; + case IDC_CONFIGURE_SND: + h = GetDlgItem(hdlg, IDC_COMBO_SOUND); + temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)sound_card_getdevice(temp_sound_card)); + break; + + case IDC_COMBO_MIDI: + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MIDI); + if (midi_device_has_config(temp_midi_device)) + { + EnableWindow(h, TRUE); + } + else + { + EnableWindow(h, FALSE); + } + + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + EnableWindow(h, mpu401_present() ? TRUE : FALSE); + break; + + case IDC_CONFIGURE_MIDI: + h = GetDlgItem(hdlg, IDC_COMBO_MIDI); + temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; + + deviceconfig_open(hdlg, (void *)midi_device_getdevice(temp_midi_device)); + break; + case IDC_CHECK_MPU401: h = GetDlgItem(hdlg, IDC_CHECK_MPU401); temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); @@ -1298,7 +1400,7 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa temp_sound_card = settings_list_to_sound[SendMessage(h, CB_GETCURSEL, 0, 0)]; h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - temp_midi_id = SendMessage(h, CB_GETCURSEL, 0, 0); + temp_midi_device = settings_list_to_midi[SendMessage(h, CB_GETCURSEL, 0, 0)]; h = GetDlgItem(hdlg, IDC_CHECK_MPU401); temp_mpu401 = SendMessage(h, BM_GETCHECK, 0, 0); @@ -4185,12 +4287,15 @@ static BOOL CALLBACK win_settings_main_proc(HWND hdlg, UINT message, WPARAM wPar win_settings_main_image_list_init(h); win_settings_main_insert_categories(h); ListView_SetItemState(h, 0, LVIS_FOCUSED | LVIS_SELECTED, 0x000F); +/* Leave this commented out until we do localization. */ +#if 0 h = GetDlgItem(hdlg, IDC_COMBO_LANG); /* This is currently disabled, I am going to add localization options in the future. */ EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); h = GetDlgItem(hdlg, IDS_LANG_ENUS); /*was:2047 !*/ EnableWindow(h, FALSE); ShowWindow(h, SW_HIDE); +#endif return TRUE; case WM_NOTIFY: if ((((LPNMHDR)lParam)->code == LVN_ITEMCHANGED) && (((LPNMHDR)lParam)->idFrom == IDC_SETTINGSCATLIST)) diff --git a/src/config.c b/src/config.c index 1b6b9f561..dd8351657 100644 --- a/src/config.c +++ b/src/config.c @@ -29,6 +29,7 @@ #include "scsi.h" #include "win/plat_joystick.h" #include "win/plat_midi.h" +#include "sound/midi.h" #include "sound/snd_dbopl.h" #include "sound/snd_mpu401.h" #include "sound/snd_opl.h" @@ -766,9 +767,6 @@ void config_save(wchar_t *fn) } -static wchar_t *read_nvr_path; - - /* General */ static void loadconfig_general(void) { @@ -853,26 +851,18 @@ static void loadconfig_machine(void) cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); mem_size = config_get_int(cat, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + if (mem_size < (((models[model].flags & MODEL_AT) && (models[model].ram_granularity < 128)) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = (((models[model].flags & MODEL_AT) && (models[model].ram_granularity < 128)) ? models[model].min_ram*1024 : models[model].min_ram); if (mem_size > 262144) { mem_size = 262144; } - if (read_nvr_path != NULL) - { - free(read_nvr_path); - read_nvr_path = NULL; - } - memset(nvr_path, 0x00, sizeof(nvr_path)); wp = config_get_wstring(cat, "nvr_path", L""); if (wp != NULL) { if (wcslen(wp) && (wcslen(wp) <= 992)) { - read_nvr_path = (wchar_t *) malloc((wcslen(wp) << 1) + 2); - wcscpy(read_nvr_path, wp); wcscpy(nvr_path, wp); } else @@ -977,7 +967,12 @@ static void loadconfig_sound(void) else sound_card_current = 0; - midi_id = config_get_int(cat, "midi_host_device", 0); + p = (char *)config_get_string(cat, "midi_device", NULL); + if (p != NULL) + midi_device_current = midi_device_get_from_internal_name(p); + else + midi_device_current = 0; + mpu401_standalone_enable = !!config_get_int(cat, "mpu401_standalone", 0); SSI2001 = !!config_get_int(cat, "ssi2001", 0); @@ -1867,14 +1862,7 @@ static void saveconfig_machine(void) config_set_int(cat, "mem_size", mem_size); } - if (read_nvr_path == NULL) - { - config_delete_var(cat, "nvr_path"); - } - else - { - config_set_wstring(cat, "nvr_path", nvr_path); - } + config_set_wstring(cat, "nvr_path", nvr_path); config_set_int(cat, "cpu_use_dynarec", cpu_use_dynarec); @@ -2021,13 +2009,14 @@ static void saveconfig_sound(void) config_set_string(cat, "sndcard", sound_card_get_internal_name(sound_card_current)); } - if (midi_id == 0) + + if (!strcmp(midi_device_get_internal_name(midi_device_current), "none")) { - config_delete_var(cat, "midi_host_device"); + config_delete_var(cat, "midi_device"); } else { - config_set_int(cat, "midi_host_device", midi_id); + config_set_string(cat, "midi_device", midi_device_get_internal_name(midi_device_current)); } if (mpu401_standalone_enable == 0) diff --git a/src/config.h b/src/config.h index 9efe0edd4..8d1db0b7b 100644 --- a/src/config.h +++ b/src/config.h @@ -16,6 +16,7 @@ extern int config_get_hex20(char *head, char *name, int def); extern int config_get_mac(char *head, char *name, int def); extern char *config_get_string(char *head, char *name, char *def); extern wchar_t *config_get_wstring(char *head, char *name, wchar_t *def); +extern void config_delete_var(char *head, char *name); extern void config_set_int(char *head, char *name, int val); extern void config_set_hex16(char *head, char *name, int val); extern void config_set_hex20(char *head, char *name, int val); diff --git a/src/device.h b/src/device.h index e5613f836..087c3464d 100644 --- a/src/device.h +++ b/src/device.h @@ -20,13 +20,14 @@ # define EMU_DEVICE_H -#define CONFIG_STRING 0 -#define CONFIG_INT 1 -#define CONFIG_BINARY 2 -#define CONFIG_SELECTION 3 -#define CONFIG_HEX16 4 -#define CONFIG_HEX20 5 -#define CONFIG_MAC 6 +#define CONFIG_STRING 0 +#define CONFIG_INT 1 +#define CONFIG_BINARY 2 +#define CONFIG_SELECTION 3 +#define CONFIG_MIDI 4 +#define CONFIG_HEX16 5 +#define CONFIG_HEX20 6 +#define CONFIG_MAC 7 enum diff --git a/src/ibm.h b/src/ibm.h index 2e22ad740..cb2ed92a8 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -764,6 +764,8 @@ extern uint8_t readdacfifo(void); extern void refreshread(void); extern int rep386(int fv); extern void resetmcr(void); +extern void resetpchard_close(void); +extern void resetpchard_init(void); extern void resetpchard(void); extern void resetreadlookup(void); extern void resetx86(void); diff --git a/src/ide.c b/src/ide.c index 1056c7858..86ef8b78c 100644 --- a/src/ide.c +++ b/src/ide.c @@ -956,6 +956,7 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) } idecallback[ide_board]=200*IDE_TIME; timer_update_outstanding(); + ide->do_initial_read = 1; return; case WIN_WRITE_MULTIPLE: @@ -1563,8 +1564,25 @@ void callbackide(int ide_board) goto id_not_found; } - hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + if (ide->do_initial_read) + { + ide->do_initial_read = 0; + ide->sector_pos = 0; + if (ide->secount) + { + hdd_image_read(ide->hdc_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + } + else + { + hdd_image_read(ide->hdc_num, ide_get_sector(ide), 256, ide->sector_buffer); + } + } + + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); + + ide->sector_pos++; ide->pos=0; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide_irq_raise(ide); @@ -1581,18 +1599,33 @@ void callbackide(int ide_board) { goto id_not_found; } - hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + + if (ide->do_initial_read) + { + ide->do_initial_read = 0; + ide->sector_pos = 0; + if (ide->secount) + { + hdd_image_read(ide->hdc_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + } + else + { + hdd_image_read(ide->hdc_num, ide_get_sector(ide), 256, ide->sector_buffer); + } + } + ide->pos=0; if (ide_bus_master_read) { - if (ide_bus_master_read(ide_board, (uint8_t *)ide->buffer, 512)) + if (ide_bus_master_read(ide_board, &ide->sector_buffer[ide->sector_pos*512], 512)) { idecallback[ide_board]=6*IDE_TIME; /*DMA not performed, try again later*/ } else { /*DMA successful*/ + ide->sector_pos++; ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; ide->secount = (ide->secount - 1) & 0xff; @@ -1629,8 +1662,25 @@ void callbackide(int ide_board) goto id_not_found; } - hdd_image_read(ide->hdc_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); + if (ide->do_initial_read) + { + ide->do_initial_read = 0; + ide->sector_pos = 0; + if (ide->secount) + { + hdd_image_read(ide->hdc_num, ide_get_sector(ide), ide->secount, ide->sector_buffer); + } + else + { + hdd_image_read(ide->hdc_num, ide_get_sector(ide), 256, ide->sector_buffer); + } + } + + memcpy(ide->buffer, &ide->sector_buffer[ide->sector_pos*512], 512); + + ide->sector_pos++; ide->pos=0; + ide->atastat = DRQ_STAT | READY_STAT | DSC_STAT; if (!ide->blockcount) { diff --git a/src/ide.h b/src/ide.h index 57057af13..953cb3731 100644 --- a/src/ide.h +++ b/src/ide.h @@ -51,6 +51,9 @@ typedef struct { int hdc_num; uint8_t specify_success; int mdma_mode; + uint8_t sector_buffer[256*512]; + int do_initial_read; + int sector_pos; } IDE; #pragma pack(pop) diff --git a/src/mem.c b/src/mem.c index 2f6d2bf46..5a5543dc6 100644 --- a/src/mem.c +++ b/src/mem.c @@ -102,6 +102,8 @@ int loadbios() biosmask = 0xffff; + if (!rom) + rom = malloc(0x20000); memset(romext,0xff,0x8000); memset(rom, 0xff, 0x20000); @@ -1762,6 +1764,49 @@ void mem_write_raml(uint32_t addr, uint32_t val, void *priv) mem_write_raml_page(addr, val, &pages[addr >> 12]); } +static uint32_t remap_start_addr; + +uint8_t mem_read_remapped(uint32_t addr, void *priv) +{ + addr = 0xA0000 + (addr - remap_start_addr); + addreadlookup(mem_logical_addr, addr); + return ram[addr]; +} +uint16_t mem_read_remappedw(uint32_t addr, void *priv) +{ + addr = 0xA0000 + (addr - remap_start_addr); + addreadlookup(mem_logical_addr, addr); + return *(uint16_t *)&ram[addr]; +} +uint32_t mem_read_remappedl(uint32_t addr, void *priv) +{ + addr = 0xA0000 + (addr - remap_start_addr); + addreadlookup(mem_logical_addr, addr); + return *(uint32_t *)&ram[addr]; +} + +void mem_write_remapped(uint32_t addr, uint8_t val, void *priv) +{ + uint32_t oldaddr = addr; + addr = 0xA0000 + (addr - remap_start_addr); + addwritelookup(mem_logical_addr, addr); + mem_write_ramb_page(addr, val, &pages[oldaddr >> 12]); +} +void mem_write_remappedw(uint32_t addr, uint16_t val, void *priv) +{ + uint32_t oldaddr = addr; + addr = 0xA0000 + (addr - remap_start_addr); + addwritelookup(mem_logical_addr, addr); + mem_write_ramw_page(addr, val, &pages[oldaddr >> 12]); +} +void mem_write_remappedl(uint32_t addr, uint32_t val, void *priv) +{ + uint32_t oldaddr = addr; + addr = 0xA0000 + (addr - remap_start_addr); + addwritelookup(mem_logical_addr, addr); + mem_write_raml_page(addr, val, &pages[oldaddr >> 12]); +} + uint8_t mem_read_bios(uint32_t addr, void *priv) { if (AMIBIOS && (addr&0xFFFFF)==0xF8281) /*This is read constantly during AMIBIOS POST, but is never written to. It's clearly a status register of some kind, but for what?*/ @@ -2054,15 +2099,14 @@ void mem_init() { int c; - ram = malloc((mem_size + 384) * 1024); - rom = malloc(0x20000); + ram = malloc(mem_size * 1024); readlookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); writelookup2 = malloc(1024 * 1024 * sizeof(uintptr_t)); biosmask = 0xffff; pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); page_lookup = malloc((1 << 20) * sizeof(page_t *)); - memset(ram, 0, (mem_size + 384) * 1024); + memset(ram, 0, mem_size * 1024); memset(pages, 0, (((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); memset(page_lookup, 0, (1 << 20) * sizeof(page_t *)); @@ -2115,50 +2159,40 @@ void mem_init() mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); } -void mem_remap_top_256k() +static void mem_remap_top(int max_size) { int c; - - for (c = ((mem_size * 1024) >> 12); c < (((mem_size + 256) * 1024) >> 12); c++) - { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } - for (c = (mem_size / 256); c < ((mem_size + 256) / 256); c++) - { - isram[c] = 1; - if (c >= 0xa && c <= 0xd) - isram[c] = 0; - } + if (mem_size > 640) + { + uint32_t start = (mem_size >= 1024) ? mem_size : 1024; + int size = mem_size - 640; + if (size > max_size) + size = max_size; + + remap_start_addr = start * 1024; + + for (c = ((start * 1024) >> 12); c < (((start + size) * 1024) >> 12); c++) + { + pages[c].mem = &ram[0xA0000 + ((c - ((start * 1024) >> 12)) << 12)]; + pages[c].write_b = mem_write_ramb_page; + pages[c].write_w = mem_write_ramw_page; + pages[c].write_l = mem_write_raml_page; + } - mem_set_mem_state(mem_size * 1024, 256 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 256 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (mem_size * 1024), MEM_MAPPING_INTERNAL, NULL); + mem_set_mem_state(start * 1024, size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + mem_mapping_add(&ram_remapped_mapping, start * 1024, size * 1024, mem_read_remapped, mem_read_remappedw, mem_read_remappedl, mem_write_remapped, mem_write_remappedw, mem_write_remappedl, ram + 0xA0000, MEM_MAPPING_INTERNAL, NULL); + } +} + +void mem_remap_top_256k() +{ + mem_remap_top(256); } void mem_remap_top_384k() { - int c; - - for (c = ((mem_size * 1024) >> 12); c < (((mem_size + 384) * 1024) >> 12); c++) - { - pages[c].mem = &ram[c << 12]; - pages[c].write_b = mem_write_ramb_page; - pages[c].write_w = mem_write_ramw_page; - pages[c].write_l = mem_write_raml_page; - } - - for (c = (mem_size / 256); c < ((mem_size + 384) / 256); c++) - { - isram[c] = 1; - if (c >= 0xa && c <= 0xf) - isram[c] = 0; - } - - mem_set_mem_state(mem_size * 1024, 384 * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_mapping_add(&ram_remapped_mapping, mem_size * 1024, 384 * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + (mem_size * 1024), MEM_MAPPING_INTERNAL, NULL); + mem_remap_top(384); } void mem_resize() @@ -2166,8 +2200,8 @@ void mem_resize() int c; free(ram); - ram = malloc((mem_size + 384) * 1024); - memset(ram, 0, (mem_size + 384) * 1024); + ram = malloc(mem_size * 1024); + memset(ram, 0, mem_size * 1024); free(pages); pages = malloc((((mem_size + 384) * 1024) >> 12) * sizeof(page_t)); @@ -2213,7 +2247,8 @@ void mem_resize() if (mem_size > 768) mem_mapping_add(&ram_mid_mapping, 0xc0000, 0x40000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xc0000, MEM_MAPPING_INTERNAL, NULL); - mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); + if (romset == ROM_IBMPS1_2011) + mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); mem_a20_key = 2; mem_a20_recalc(); diff --git a/src/model.c b/src/model.c index 7645ae58e..155fa2793 100644 --- a/src/model.c +++ b/src/model.c @@ -139,7 +139,7 @@ int romset; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL}, {"IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, {"Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 128, 0, xt_init, NULL}, {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device}, @@ -160,27 +160,27 @@ MODEL models[] = {"Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, {"Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, {"Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, 63, ibm_at_init, NULL}, + {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL}, {"Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_ide_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_scat_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 16, 1, 127, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, at_ide_init, NULL}, + {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL}, + {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL}, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 16, 1, 127, at_neat_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_headland_init, NULL}, + {"DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL}, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_headland_init, NULL}, {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL}, {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL}, - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, @@ -465,6 +465,7 @@ void ps1_m2011_init(void) { ps1_common_init(); ps1mb_init(); + mem_remap_top_384k(); } void ps1_m2121_init(void) @@ -533,12 +534,14 @@ void ps2_model_80_init(void) void at_neat_init(void) { at_ide_init(); + mem_remap_top_384k(); neat_init(); } void at_scat_init(void) { at_ide_init(); + mem_remap_top_384k(); scat_init(); } @@ -563,6 +566,7 @@ void at_wd76c10_init(void) void at_headland_init(void) { at_ide_init(); + mem_remap_top_384k(); headland_init(); } diff --git a/src/mouse.c b/src/mouse.c index 85075d40b..c6466910f 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -17,6 +17,7 @@ static mouse_t *mouse_list[] = { &mouse_amstrad, /* 4 Amstrad PC System Mouse */ &mouse_olim24, /* 5 Olivetti M24 System Mouse */ &mouse_msystems, /* 6 Mouse Systems */ + &mouse_serial_logitech, /* 0 Logitech 3-button Serial Mouse */ #if 0 &mouse_genius, /* 7 Genius Bus Mouse */ #endif diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 5095ca949..43a1af502 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -63,6 +63,12 @@ sermouse_timer(void *priv) serial_write_fifo(ms->serial, 'M', 1); break; + case SERMOUSE_TYPE_LOGITECH: + /* This identifies a two-button Logitech Serial mouse. */ + serial_write_fifo(ms->serial, 'M', 1); + serial_write_fifo(ms->serial, '3', 1); + break; + default: /* No action needed. */ break; @@ -114,6 +120,22 @@ sermouse_poll(int x, int y, int z, int b, void *priv) break; case SERMOUSE_TYPE_LOGITECH: + buff[0] = 0x40; + buff[0] |= (((y>>6)&03)<<2); + buff[0] |= ((x>>6)&03); + if (b&0x01) buff[0] |= 0x20; + if (b&0x02) buff[0] |= 0x10; + buff[1] = x & 0x3F; + buff[2] = y & 0x3F; + if (b&0x04) + { + buff[3] = 0x20; + len = 4; + } + else + { + len = 3; + } break; } @@ -167,6 +189,13 @@ sermouse_init_microsoft(void) } +static void * +sermouse_init_logitech(void) +{ + return(sermouse_init(SERMOUSE_TYPE_LOGITECH)); +} + + static void * sermouse_init_msystems(void) { @@ -192,3 +221,13 @@ mouse_t mouse_serial_microsoft = { sermouse_close, sermouse_poll }; + + +mouse_t mouse_serial_logitech = { + "Logitech 3-button mouse (serial)", + "lserial", + MOUSE_TYPE_SERIAL | MOUSE_TYPE_3BUTTON, + sermouse_init_logitech, + sermouse_close, + sermouse_poll +}; diff --git a/src/mouse_serial.h b/src/mouse_serial.h index c76dce483..ec322dc61 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -22,6 +22,7 @@ extern mouse_t mouse_serial_microsoft; +extern mouse_t mouse_serial_logitech; extern mouse_t mouse_msystems; diff --git a/src/pc.c b/src/pc.c index ef456f18f..3bdeabc71 100644 --- a/src/pc.c +++ b/src/pc.c @@ -44,21 +44,28 @@ #include "fdc.h" #include "fdd.h" #include "gameport.h" -#include "plat_joystick.h" -#include "plat_midi.h" #include "hdd.h" #include "ide.h" #include "cdrom.h" #include "cdrom_ioctl.h" #include "cdrom_image.h" #include "cdrom_null.h" -#include "scsi.h" #include "keyboard.h" -#include "plat_keyboard.h" #include "keyboard_at.h" +#include "sound/midi.h" #include "mouse.h" -#include "plat_mouse.h" #include "network/network.h" +#ifdef WALTJE +# define UNICODE +# include "plat_dir.h" +# undef UNICODE +#endif +#include "plat_joystick.h" +#include "plat_keyboard.h" +#include "plat_midi.h" +#include "plat_mouse.h" +#include "plat_ui.h" +#include "scsi.h" #include "serial.h" #include "sound/sound.h" #include "sound/snd_cms.h" @@ -71,12 +78,6 @@ #include "sound/snd_ssi2001.h" #include "video/video.h" #include "video/vid_voodoo.h" -#include "plat_ui.h" -#ifdef WALTJE -# define UNICODE -# include "plat_dir.h" -# undef UNICODE -#endif wchar_t pcempath[512]; @@ -356,10 +357,6 @@ void initpc(int argc, wchar_t *argv[]) loadconfig(config_file); pclog("Config loaded\n"); -#if 0 - if (config_file) - saveconfig(); -#endif } void initmodules(void) @@ -369,7 +366,6 @@ void initmodules(void) /* Initialize modules. */ network_init(); mouse_init(); - midi_init(); serial_init(); disc_random_init(); @@ -476,24 +472,27 @@ void resetpc_cad(void) int suppress_overscan = 0; -void resetpchard(void) +void resetpchard_close(void) { - int i = 0; - suppress_overscan = 0; savenvr(); -#if 0 - saveconfig(); -#endif device_close_all(); mouse_emu_close(); + closeal(); +} + +void resetpchard_init(void) +{ + int i = 0; + + initalmain(0,NULL); + device_init(); - - midi_close(); - midi_init(); - + midi_device_init(); + inital(); + timer_reset(); sound_reset(); mem_resize(); @@ -559,16 +558,14 @@ void resetpchard(void) sound_cd_thread_reset(); } -char romsets[17][40]={"IBM PC","IBM XT","Generic Turbo XT","Euro PC","Tandy 1000","Amstrad PC1512","Sinclair PC200","Amstrad PC1640","IBM AT","AMI 286 clone","Dell System 200","Misc 286","IBM AT 386","Misc 386","386 clone","486 clone","486 clone 2"}; -char clockspeeds[3][12][16]= +void resetpchard(void) { - {"4.77MHz","8MHz","10MHz","12MHz","16MHz"}, - {"8MHz","12MHz","16MHz","20MHz","25MHz"}, - {"16MHz","20MHz","25MHz","33MHz","40MHz","50MHz","66MHz","75MHz","80MHz","100MHz","120MHz","133MHz"}, -}; + resetpchard_close(); + resetpchard_init(); +} + int framecountx=0; int sndcount=0; -int oldat70hz; int sreadlnum,swritelnum,segareads,segawrites, scycles_lost; diff --git a/src/pci.c b/src/pci.c index 4edd4b14f..4218c587d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -150,8 +150,7 @@ void pci_issue_irq(int irq) if (irq_elcr) { - /* picintlevel(1 << irq); */ - picint(1 << irq); + picintlevel(1 << irq); } else { @@ -161,21 +160,22 @@ void pci_issue_irq(int irq) void pci_set_irq(int card, int pci_int) { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irq_routing[card]) { - int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) pci_issue_irq(pci_irqs[irq]); - /* picint(1 << pci_irqs[irq]); */ pci_irq_active[card] = 1; } } void pci_clear_irq(int card, int pci_int) { + int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + if (pci_irq_routing[card]) { - int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) picintc(1 << pci_irqs[irq]); pci_irq_active[card] = 0; diff --git a/src/rom.c b/src/rom.c index 82299602d..732d0cecd 100644 --- a/src/rom.c +++ b/src/rom.c @@ -25,6 +25,22 @@ FILE *nvrfopen(wchar_t *fn, wchar_t *mode) } +int rom_getfile(wchar_t *fn, wchar_t *s, int size) +{ + FILE *f; + + wcscpy(s, pcempath); + put_backslash_w(s); + wcscat(s, fn); + f = _wfopen(s, L"rb"); + if (f) + { + fclose(f); + return 1; + } + return 0; +} + int rom_present(wchar_t *fn) { FILE *f; diff --git a/src/rom.h b/src/rom.h index c4cea8f7c..35b8ef78f 100644 --- a/src/rom.h +++ b/src/rom.h @@ -3,6 +3,7 @@ */ FILE *romfopen(wchar_t *fn, wchar_t *mode); FILE *nvrfopen(wchar_t *fn, wchar_t *mode); +int rom_getfile(wchar_t *fn, wchar_t *s, int size); int rom_present(wchar_t *fn); typedef struct rom_t diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index 26dbdc8fa..cfc1188c2 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -529,18 +529,7 @@ BuslogicLog(const char *format, ...) static void BuslogicInterrupt(Buslogic_t *bl, int set) { - if ((bl->chip != CHIP_BUSLOGIC_PCI) || (bl->Irq != 255)) - { - if (set) - { - picint(1 << bl->Irq); - } - else - { - picintc(1 << bl->Irq); - } - } - else + if (bl->chip == CHIP_BUSLOGIC_PCI) { if (set) { @@ -551,6 +540,17 @@ BuslogicInterrupt(Buslogic_t *bl, int set) pci_clear_irq(bl->Card, PCI_INTA); } } + else + { + if (set) + { + picint(1 << bl->Irq); + } + else + { + picintc(1 << bl->Irq); + } + } } @@ -2286,7 +2286,7 @@ BuslogicInit(int chip) &BuslogicCallback, &BuslogicCallback, bl); if (bl->chip == CHIP_BUSLOGIC_PCI) { - pci_add(BuslogicPCIRead, BuslogicPCIWrite, bl); + bl->Card = pci_add(BuslogicPCIRead, BuslogicPCIWrite, bl); buslogic_pci_bar[0].addr_regs[0] = 1; buslogic_pci_bar[1].addr_regs[0] = 0; From 92755dd76a42a54141986d8b5e61c99c2bfcedce Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 19 Jun 2017 00:54:33 -0400 Subject: [PATCH 367/392] Revert "Small fixes for openal and some dynamic linking stuff. Bug in libopenal.a makes this not work, so we're still on openall.dll ..." This reverts commit bb03e645391434b4d3db1064157fb0089e4fd2ea. --- src/Makefile.mingw | 13 +-- src/SOUND/openal.c | 273 ++++++++++++++++++++++----------------------- 2 files changed, 139 insertions(+), 147 deletions(-) diff --git a/src/Makefile.mingw b/src/Makefile.mingw index f143c592a..d92d2d175 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -62,7 +62,7 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/resid-fp sound/openal video lzf network network/slirp win +VPATH = . cpu sound sound/resid-fp video lzf network network/slirp win PLAT = win/ ifeq ($(X64), y) CPP = g++.exe -m64 @@ -170,13 +170,12 @@ NETOBJ = network.o \ net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o SNDOBJ = sound.o \ - openal.o \ - dbopl.o nukedopl.o \ convolve.o convolve-sse.o envelope.o extfilt.o \ filter.o pot.o sid.o voice.o wave6581__ST.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ + dbopl.o nukedopl.o openal.o \ snd_speaker.o snd_ps1.o snd_pssj.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ @@ -221,11 +220,9 @@ OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ LZFOBJ = lzf_c.o lzf_d.o -LIBS = -mwindows \ - -lopenal.dll \ - -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \ - -lcomctl32 -lkernel32 -lwsock32 -lwinmm -liphlpapi -lpsapi \ - -static -lstdc++ -lgcc +LIBS = -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 -lopenal.dll \ + -mwindows -lcomctl32 -lwinmm -lwsock32 -liphlpapi -lpsapi \ + -static-libstdc++ -static -lstdc++ -static-libgcc -static -lgcc # Build rules. diff --git a/src/SOUND/openal.c b/src/SOUND/openal.c index bda40f44e..b044c0e5a 100644 --- a/src/SOUND/openal.c +++ b/src/SOUND/openal.c @@ -3,10 +3,6 @@ #include #include #ifdef USE_OPENAL -# undef AL_API -# undef ALC_API -# define AL_LIBTYPE_STATIC -# define ALC_LIBTYPE_STATIC # include # include # include @@ -15,220 +11,219 @@ #include "sound.h" -#define FREQ 48000 -#define BUFLEN SOUNDBUFLEN - - +FILE *allog; #ifdef USE_OPENAL ALuint buffers[4]; /* front and back buffers */ ALuint buffers_cd[4]; /* front and back buffers */ static ALuint source[2]; /* audio source */ #endif +#define FREQ 48000 +#define BUFLEN SOUNDBUFLEN -ALvoid alutInit(ALint *argc,ALbyte **argv) +void closeal(void); +ALvoid alutInit(ALint *argc,ALbyte **argv) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *Context; + ALCdevice *Device; - /* Open device */ - Device = alcOpenDevice((ALCchar *)""); - if (Device != NULL) { + /* Open device */ + Device=alcOpenDevice((ALCchar *)""); /* Create context(s) */ - Context = alcCreateContext(Device, NULL); - if (Context != NULL) { - /* Set active context */ - alcMakeContextCurrent(Context); - } - } + Context=alcCreateContext(Device,NULL); + /* Set active context */ + alcMakeContextCurrent(Context); + /* Register extensions */ } - -ALvoid alutExit(ALvoid) +ALvoid alutExit(ALvoid) { - ALCcontext *Context; - ALCdevice *Device; + ALCcontext *Context; + ALCdevice *Device; - /* Get active context */ - Context = alcGetCurrentContext(); - if (Context != NULL) { + /* Unregister extensions */ + + /* Get active context */ + Context=alcGetCurrentContext(); /* Get device for active context */ - Device = alcGetContextsDevice(Context); - if (Device != NULL) { - /* Disable context */ - alcMakeContextCurrent(NULL); - - /* Close device */ - alcCloseDevice(Device); - } - + Device=alcGetContextsDevice(Context); + /* Disable context */ + alcMakeContextCurrent(NULL); /* Release context(s) */ alcDestroyContext(Context); - } + /* Close device */ + alcCloseDevice(Device); +} +void initalmain(int argc, char *argv[]) +{ +#ifdef USE_OPENAL + alutInit(0,0); + atexit(closeal); +#endif } - void closeal(void) { #ifdef USE_OPENAL - alutExit(); + alutExit(); #endif } - -void initalmain(int argc, char *argv[]) -{ -#ifdef USE_OPENAL - alutInit(0,0); - atexit(closeal); -#endif -} - - void inital(ALvoid) { #ifdef USE_OPENAL - float buf[BUFLEN*2]; - float cd_buf[CD_BUFLEN*2]; - int16_t buf_int16[BUFLEN*2]; - int16_t cd_buf_int16[CD_BUFLEN*2]; - int c; + int c; - alGenBuffers(4, buffers); - alGenBuffers(4, buffers_cd); + float buf[BUFLEN*2]; + + float cd_buf[CD_BUFLEN*2]; + + int16_t buf_int16[BUFLEN*2]; + + int16_t cd_buf_int16[CD_BUFLEN*2]; + + alGenBuffers(4, buffers); + alGenBuffers(4, buffers_cd); - alGenSources(2, source); + alGenSources(2, source); - alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); - alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); - alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); - alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); + memset(buf,0,BUFLEN*2*sizeof(float)); + memset(cd_buf,0,BUFLEN*2*sizeof(float)); - memset(buf,0,BUFLEN*2*sizeof(float)); - memset(cd_buf,0,BUFLEN*2*sizeof(float)); + for (c = 0; c < 4; c++) + { + if (sound_is_float) + { + alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + } + else + { + alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + } + } - for (c = 0; c < 4; c++) { - if (sound_is_float) { - alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - } else { - alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); - alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - } - } - - alSourceQueueBuffers(source[0], 4, buffers); - alSourceQueueBuffers(source[1], 4, buffers_cd); - alSourcePlay(source[0]); - alSourcePlay(source[1]); + alSourceQueueBuffers(source[0], 4, buffers); + alSourceQueueBuffers(source[1], 4, buffers_cd); + alSourcePlay(source[0]); + alSourcePlay(source[1]); #endif } - void givealbuffer(float *buf) { #ifdef USE_OPENAL - int processed; - int state; - ALuint buffer; + int processed; + int state; + ALuint buffer; - alGetSourcei(source[0], AL_SOURCE_STATE, &state); + alGetSourcei(source[0], AL_SOURCE_STATE, &state); - if (state==0x1014) { - alSourcePlay(source[0]); - } - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) + { + alSourcePlay(source[0]); + } + alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) { - alSourceUnqueueBuffers(source[0], 1, &buffer); + if (processed>=1) + { + alSourceUnqueueBuffers(source[0], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); - alSourceQueueBuffers(source[0], 1, &buffer); - } + alSourceQueueBuffers(source[0], 1, &buffer); + } #endif } - void givealbuffer_int16(int16_t *buf) { #ifdef USE_OPENAL - int processed; - int state; - ALuint buffer; + int processed; + int state; + ALuint buffer; - alGetSourcei(source[0], AL_SOURCE_STATE, &state); + alGetSourcei(source[0], AL_SOURCE_STATE, &state); - if (state==0x1014) { - alSourcePlay(source[0]); - } - alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) + { + alSourcePlay(source[0]); + } + alGetSourcei(source[0], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) { - alSourceUnqueueBuffers(source[0], 1, &buffer); + if (processed>=1) + { + alSourceUnqueueBuffers(source[0], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO16, buf, BUFLEN*2*sizeof(int16_t), FREQ); + alBufferData(buffer, AL_FORMAT_STEREO16, buf, BUFLEN*2*sizeof(int16_t), FREQ); - alSourceQueueBuffers(source[0], 1, &buffer); - } + alSourceQueueBuffers(source[0], 1, &buffer); + } #endif } - void givealbuffer_cd(float *buf) { #ifdef USE_OPENAL - int processed; - int state; + int processed; + int state; - alGetSourcei(source[1], AL_SOURCE_STATE, &state); + alGetSourcei(source[1], AL_SOURCE_STATE, &state); - if (state==0x1014) { - alSourcePlay(source[1]); - } - alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) + { + alSourcePlay(source[1]); + } + alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) { - ALuint buffer; + if (processed>=1) + { + ALuint buffer; - alSourceUnqueueBuffers(source[1], 1, &buffer); + alSourceUnqueueBuffers(source[1], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); - alSourceQueueBuffers(source[1], 1, &buffer); - } + alSourceQueueBuffers(source[1], 1, &buffer); + } #endif } - void givealbuffer_cd_int16(int16_t *buf) { #ifdef USE_OPENAL - int processed; - int state; + int processed; + int state; - alGetSourcei(source[1], AL_SOURCE_STATE, &state); + alGetSourcei(source[1], AL_SOURCE_STATE, &state); - if (state==0x1014) { - alSourcePlay(source[1]); - } - alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); + if (state==0x1014) + { + alSourcePlay(source[1]); + } + alGetSourcei(source[1], AL_BUFFERS_PROCESSED, &processed); - if (processed>=1) { - ALuint buffer; + if (processed>=1) + { + ALuint buffer; - alSourceUnqueueBuffers(source[1], 1, &buffer); + alSourceUnqueueBuffers(source[1], 1, &buffer); - alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + alBufferData(buffer, AL_FORMAT_STEREO16, buf, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); - alSourceQueueBuffers(source[1], 1, &buffer); - } + alSourceQueueBuffers(source[1], 1, &buffer); + } #endif } From 42d2130b1ce6d05ba2532333db8e64252a58654f Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Jun 2017 07:00:41 +0200 Subject: [PATCH 368/392] Fixed the previous commit mess. --- src/Makefile.mingw | 544 +++++++++++++++++++++++++++++++++++++++++++++ src/SOUND/openal.c | 245 ++++++++++++++++++++ 2 files changed, 789 insertions(+) create mode 100644 src/Makefile.mingw create mode 100644 src/SOUND/openal.c diff --git a/src/Makefile.mingw b/src/Makefile.mingw new file mode 100644 index 000000000..51c6981a2 --- /dev/null +++ b/src/Makefile.mingw @@ -0,0 +1,544 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# Modified Makefile for Win32 (MinGW32) environment. +# +# Version: @(#)Makefile.mingw 1.0.30 2017/06/17 +# +# Authors: Miran Grca, +# Fred N. van Kempen, +# + +# Name of the executable. +ifndef PROG +PROG = 86Box +endif + +# Various compile-time options. +# -DROM_TRACE=0xcd800 traces ROM access from segment C800 +# -DIO_TACE=0x66 traces I/O on port 0x66 +ifndef STUFF +STUFF = +endif + +# Add feature selections here. +# -DANSI_CFG forces the config file to ANSI encoding. +# -DENABLE_VRAM_DUMP enables Video Ram dumping. +# -DENABLE_LOG_BREAKPOINT enables extra logging. +# -DENABLE_BUSLOGIC_LOG enables extra logging. +# -DENABLE_CDROM_LOG enables extra logging. +# -DENABLE_D86F_LOG enables extra logging. +# -DENABLE_FDC_LOG enables extra logging. +# -DENABLE_IDE_LOG enables extra logging. +# -DENABLE_SERIAL_LOG enables extra logging. +# -DENABLE_NIC_LOG enables extra logging. +ifndef EXTRAS +EXTRAS = +endif + +# Defaults for several build options (possibly defined in a chained file.) +ifndef DEBUG +DEBUG = n +endif +ifndef OPTIM +OPTIM = n +endif +ifndef RELEASE +RELEASE = n +endif +ifndef USB +USB = n +endif +ifndef X64 +X64 = n +endif + + +######################################################################### +# Nothing should need changing from here on.. # +######################################################################### +VPATH = . cpu sound sound/munt sound/munt/c_interface sound/munt/sha1 sound/munt/srchelper sound/resid-fp video lzf network network/slirp win +PLAT = win/ +ifeq ($(X64), y) +CPP = g++.exe -m64 +CC = gcc.exe -m64 +else +CPP = g++.exe -m32 +CC = gcc.exe -m32 +endif +WINDRES = windres.exe + +OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) + +ifeq ($(X64), y) + ifeq ($(OPTIM), y) + DFLAGS = -march=native + else + DFLAGS = + endif +else + ifeq ($(OPTIM), y) + DFLAGS = -march=native + else + DFLAGS = -march=i686 + endif +endif +ifeq ($(DEBUG), y) + DFLAGS += -ggdb -DDEBUG + AOPTIM = + ifndef COPTIM + COPTIM = -Og + endif +else + ifeq ($(OPTIM), y) + AOPTIM = -mtune=native + ifndef COPTIM + COPTIM = -O6 + endif + else + ifndef COPTIM + COPTIM = -O3 + endif + endif +endif +AFLAGS = -msse -msse2 -mfpmath=sse +CFLAGS = $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ + -fomit-frame-pointer -mstackrealign -Wall +RFLAGS = --input-format=rc -O coff +ifeq ($(RELEASE), y) +CFLAGS += -DRELEASE_BUILD +RFLAGS += -DRELEASE_BUILD +endif +ifeq ($(VRAMDUMP), y) +CFLAGS += -DENABLE_VRAM_DUMP +RFLAGS += -DENABLE_VRAM_DUMP +endif + +ifeq ($(X64), y) +PLATCG = codegen_x86-64.o +else +PLATCG = codegen_x86.o +endif + + +MAINOBJ = pc.o config.o device.o timer.o dma.o io.o nmi.o pic.o \ + mca.o mcr.o pit.o ppi.o pci.o sio.o intel.o rom.o mem.o \ + memregs.o intel_flash.o rtc.o nvr.o ps2_nvr.o +CPUOBJ = cpu.o 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o \ + codegen.o \ + codegen_ops.o codegen_timing_486.o \ + codegen_timing_686.o codegen_timing_pentium.o \ + codegen_timing_winchip.o $(PLATCG) \ + x86seg.o x87.o +SYSOBJ = model.o \ + headland.o \ + i430hx.o i430lx.o i430fx.o i430nx.o i430vx.o i440fx.o \ + neat.o \ + ali1429.o \ + opti495.o \ + scat.o \ + sis496.o \ + wd76c10.o \ + acer386sx.o acerm3a.o amstrad.o \ + compaq.o laserxt.o jim.o \ + olivetti_m24.o ps1.o ps2.o ps2_mca.o \ + tandy_eeprom.o tandy_rom.o +DEVOBJ = bugger.o lpt.o serial.o \ + fdc37c665.o fdc37c669.o fdc37c932fr.o \ + pc87306.o sis85c471.o w83877f.o \ + keyboard.o \ + keyboard_xt.o keyboard_at.o keyboard_pcjr.o \ + keyboard_amstrad.o keyboard_olim24.o \ + gameport.o \ + joystick_standard.o joystick_ch_flightstick_pro.o \ + joystick_sw_pad.o joystick_tm_fcs.o \ + mouse.o mouse_serial.o mouse_ps2.o mouse_bus.o \ + fdd.o fdc.o fdi2raw.o \ + hdd.o hdd_image.o \ + mfm_at.o mfm_xebec.o hdd_esdi.o ide.o xtide.o piix.o \ + disc.o \ + disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ + disc_random.o disc_td0.o \ + cdrom.o \ + cdrom_dosbox.o cdrom_image.o cdrom_ioctl.o cdrom_null.o +ifdef USB +USBOBJ = usb.o +endif +NETOBJ = network.o \ + net_pcap.o \ + net_slirp.o \ + bootp.o ip_icmp.o misc.o socket.o tcp_timer.o cksum.o \ + ip_input.o queue.o tcp_input.o debug.o ip_output.o \ + sbuf.o tcp_output.o udp.o if.o mbuf.o slirp.o tcp_subr.o \ + net_ne2000.o +SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o +SNDOBJ = sound.o \ + openal.o \ + dbopl.o nukedopl.o \ + convolve.o convolve-sse.o envelope.o extfilt.o \ + filter.o pot.o sid.o voice.o wave6581__ST.o \ + wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ + wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ + wave8580_PST.o wave.o \ + Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ + LA32FloatWaveGenerator.o LA32WaveGenerator.o \ + MidiStreamParser.o Part.o Partial.o PartialManager.o \ + Poly.o ROMInfo.o Synth.o Tables.o TVA.o TVF.o TVP.o \ + sha1.o c_interface.o \ + midi.o midi_mt32.o midi_system.o \ + snd_speaker.o snd_ps1.o snd_pssj.o \ + snd_adlib.o snd_adlibgold.o snd_ad1848.o \ + snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ + snd_emu8k.o snd_gus.o snd_opl.o \ + snd_mpu401.o snd_pas16.o snd_resid.o \ + snd_sn76489.o snd_ssi2001.o snd_wss.o \ + snd_ym7128.o +VIDOBJ = video.o \ + vid_cga.o vid_cga_comp.o vid_mda.o \ + vid_ega.o vid_ega_render.o \ + vid_vga.o vid_svga.o vid_svga_render.o \ + vid_hercules.o vid_herculesplus.o vid_incolor.o \ + vid_colorplus.o \ + vid_genius.o \ + vid_s3.o vid_s3_virge.o \ + vid_et4000.o vid_et4000w32.o vid_icd2061.o \ + vid_oti067.o \ + vid_paradise.o \ + vid_tvga.o vid_tgui9440.o vid_tkd8001_ramdac.o \ + vid_ati_eeprom.o vid_ati18800.o vid_ati28800.o \ + vid_ati68860_ramdac.o vid_ati_mach64.o \ + vid_ics2595.o \ + vid_sdac_ramdac.o \ + vid_stg_ramdac.o \ + vid_unk_ramdac.o \ + vid_wy700.o \ + vid_voodoo.o \ + vid_pcjr.o vid_ps1_svga.o \ + vid_olivetti_m24.o \ + vid_pc1512.o vid_pc1640.o vid_pc200.o \ + vid_tandy.o vid_tandysl.o +WINOBJ = win.o \ + win_ddraw.o win_ddraw_fs.o win_ddraw_screenshot.o \ + win_d3d.o win_d3d_fs.o \ + win_language.o win_status.o win_opendir.o win_dynld.o \ + win_video.o win_serial.o win_keyboard.o win_mouse.o \ + win_iodev.o win_joystick.o win_midi.o \ + win_settings.o win_deviceconfig.o win_joystickconfig.o \ + 86Box.res +OBJ = $(MAINOBJ) $(CPUOBJ) $(SYSOBJ) $(DEVOBJ) $(USBOBJ) \ + $(NETOBJ) $(SCSIOBJ) $(SNDOBJ) $(VIDOBJ) $(WINOBJ) + +LZFOBJ = lzf_c.o lzf_d.o + +LIBS = -mwindows \ + -lopenal.dll \ + -lddraw -ldinput8 -ldxguid -ld3d9 -ld3dx9 \ + -lcomctl32 -lkernel32 -lwsock32 -lwinmm -liphlpapi -lpsapi \ + -static -lstdc++ -lgcc + + +# Build rules. +%.o: %.c + @echo $< + @$(CC) $(CFLAGS) -c $< + +%.o: %.cc + @echo $< + @$(CPP) $(CFLAGS) -c $< + +%.o: %.cpp + @echo $< + @$(CPP) $(CFLAGS) -c $< + +all: $(PROG).exe pcap_if.exe + + +$(PROG).exe: $(OBJ) $(LZFOBJ) + @echo Linking $(PROG).exe .. + @$(CC) -o $(PROG).exe $(OBJ) $(LZFOBJ) $(LIBS) +ifneq ($(DEBUG), y) + @strip $(PROG).exe +endif + +pcap_if.exe: pcap_if.o win_dynld.o pcap_if.res + @echo Linking pcap_if.exe .. + @$(CC) -o pcap_if.exe pcap_if.o win_dynld.o pcap_if.res +ifneq ($(DEBUG), y) + @strip pcap_if.exe +endif + + + +clean: + -rm *.o + -rm *.exe + -rm *.res + +86Box.res: 86Box.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) $(EXTRAS) -i win/86Box.rc -o 86Box.res + +pcap_if.res: pcap_if.rc + @echo Processing $< + @$(WINDRES) $(RFLAGS) -i win/pcap_if.rc -o pcap_if.res + + +# Module dependencies. +acer386sx.o: ibm.h cpu/cpu.h io.h device.h model.h + +acerm3a.o: ibm.h cpu/cpu.h io.h device.h model.h + +ali1429.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h + +amstrad.o: ibm.h cpu/cpu.h io.h device.h model.h keyboard.h lpt.h mouse.h + +bugger.o: ibm.h io.h bugger.h + +cdrom.o: 86box.h cdrom.h ibm.h ide.h piix.h scsi.h timer.h \ + win/plat_iodev.h + +cdrom_ioctl.o: ibm.h cdrom.h cdrom_ioctl.h scsi.h + +cdrom_null.o: ibm.h cdrom.h cdrom_ioctl.h + +compaq.o: ibm.h cpu/cpu.h mem.h device.h model.h + +config.o: cdrom.h config.h device.h disc.h fdc.h fdd.h ibm.h \ + cpu/cpu.h gameport.h ide.h hdd.h model.h mouse.h \ + network/network.h nvr.h scsi.h win/plat_joystick.h \ + win/plat_midi.h sound/snd_dbopl.h sound/snd_mpu401.h \ + sound/snd_opl.h sound/sound.h video/video.h win/win.h \ + win/win_language.h + +device.o: ibm.h cpu/cpu.h config.h device.h model.h sound/sound.h + +disc.o: ibm.h config.h disc.h disc_fdi.h disc_img.h disc_86f.h \ + disc_td0.h disc_imd.h fdc.h fdd.h timer.h + +disc_86f.o: lzf/lzf.h config.h dma.h disc.h disc_86f.h disc_random.h \ + fdc.h fdd.h ibm.h + +disc_fdi.o: ibm.h disc.h disc_img.h disc_fdi.h fdc.h fdd.h fdi2raw.h \ + ibm.h disc.h disc_imd.h fdc.h fdd.h ibm.h config.h disc.h \ + disc_img.h fdc.h fdd.h + +disc_random.o: disc_random.h + +disc_td0.o: ibm.h disc.h disc_td0.h fdc.h fdd.h + +dma.o: ibm.h cpu/x86.h mem.h io.h dma.h + +fdc.o: ibm.h disc.h dma.h fdc.h fdd.h io.h pic.h timer.h + +fdc37c665.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \ + fdc37c665.h ibm.h disc.h fdc.h fdd.h io.h ide.h \ + lpt.h serial.h fdc37c669.h + +fdc37c932fr.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h \ + fdc37c932fr.h + +fdd.o: ibm.h disc.h fdc.h fdd.h + +fdi2raw.o: fdi2raw.h ibm.h + +gameport.o: ibm.h cpu/cpu.h device.h io.h timer.h gameport.h \ + joystick_ch_flightstick_pro.h joystick_standard.h \ + joystick_sw_pad.h joystick_tm_fcs.h plat_joystick.h + +hdd.o: ibm.h cpu/cpu.h device.h hdd.h model.h hdd_esdi.h \ + mfm_at.h mfm_xebec.h xtide.h + +hdd_image.o: ibm.h ide.h hdd_image.h + +hdd_esdi.o: ibm.h device.h dma.h hdd_image.h io.h mca.h mem.h \ + pic.h rom.h timer.h hdd_esdi.h + +headland.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h + +i430fx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h + +i430hx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h + +i430lx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h + +i430nx.o: ibm.h cpu/cpu.h mem.h pci.h device.h model.h + +i430vx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h + +i440fx.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h + +i82335.o: ibm.h io.h mem.h + +ide.o: 86box.h cdrom.h hdd_image.h ibm.h io.h pic.h timer.h cdrom.h scsi.h ide.h + +intel.o: ibm.h cpu/cpu.h io.h mem.h pit.h timer.h intel.h + +intel_flash.o: ibm.h cpu/cpu.h device.h mem.h model.h rom.h + +io.o: ibm.h io.h + +jim.o: ibm.h cpu/cpu.h io.h device.h model.h + +joystick_ch_flightstick_pro.o: ibm.h device.h timer.h gameport.h \ + joystick_standard.h plat_joystick.h + +joystick_standard.o: ibm.h device.h timer.h gameport.h \ + joystick_standard.h plat_joystick.h + +joystick_sw_pad.o: ibm.h device.h timer.h gameport.h \ + joystick_sw_pad.h plat_joystick.h + +joystick_tm_fcs.o: ibm.h device.h timer.h gameport.h \ + joystick_standard.h plat_joystick.h + +keyboard.o: ibm.h plat_keyboard.h keyboard.h + +keyboard_amstrad.o: ibm.h io.h mem.h pic.h pit.h timer.h sound/sound.h \ + sound/snd_speaker.h keyboard.h keyboard_amstrad.h + +keyboard_at.o: ibm.h io.h mem.h pic.h pit.h timer.h disc.h fdc.h \ + sound/sound.h sound/snd_speaker.h keyboard.h keyboard_at.h + +keyboard_olim24.o: ibm.h io.h mem.h pic.h pit.h timer.h mouse.h \ + sound/sound.h sound/snd_speaker.h keyboard.h keyboard_olim24.h + +keyboard_pcjr.o: ibm.h io.h mem.h nmi.h pic.h pit.h timer.h \ + device.h sound/sound.h sound/snd_speaker.h \ + sound/snd_sn76489.h keyboard.h keyboard_pcjr.h + +keyboard_xt.o: ibm.h io.h mem.h pic.h pit.h timer.h device.h tandy_eeprom.h \ + sound/sound.h sound/snd_speaker.h keyboard.h keyboard_xt.h + +laserxt.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h + +lpt.o: ibm.h io.h lpt.h + +mca.o: ibm.h io.h mem.h mca.h + +mcr.o: ibm.h + +mem.o: ibm.h cpu/cpu.h cpu/x86_ops.h cpu/x86.h config.h \ + io.h mem.h rom.h cpu/codegen.h video/video.h + +memregs.o: ibm.h io.h memregs.h + +mfm_at.o: ibm.h device.h hdd_image.h io.h pic.h timer.h mfm_at.h + +mfm_xebec.o: ibm.h device.h dma.h hdd_image.h io.h mem.h pic.h rom.h timer.h mfm_xebec.h + +model.o: ibm.h io.h mem.h rom.h device.h model.h cpu/cpu.h \ + mouse.h mouse_ps2.h cdrom.h disc.h dma.h fdc.h \ + fdc37c665.h fdc37c669.h fdc37c932fr.h \ + gameport.h i82335.h ide.h intel.h intel_flash.h \ + keyboard_amstrad.h keyboard_at.h keyboard_olim24.h \ + keyboard_pcjr.h keyboard_xt.h lpt.h mem.h memregs.h \ + nmi.h nvr.h pc87306.h pci.h pic.h piix.h pit.h ps2_mca.h \ + serial.h sis85c471.h sio.h sound/snd_ps1.h sound/snd_pssj.h \ + sound/snd_sn76489.h tandy_eeprom.h tandy_rom.h \ + video/vid_pcjr.h video/vid_tandy.h w83877f.h wd76c10.h \ + xtide.h bugger.h + +mouse.o: ibm.h cpu/cpu.h device.h model.h \ + mouse.h mouse_serial.h mouse_ps2.h mouse_bus.h keyboard_olim24.h + +mouse_bus.o: ibm.h io.h pic.h mouse.h mouse_bus.h plat_mouse.h + +mouse_ps2.o: ibm.h keyboard_at.h mouse.h mouse_ps2.h plat_mouse.h + +mouse_serial.o: ibm.h timer.h serial.h mouse.h mouse_serial.h + +neat.o: ibm.h cpu/cpu.h io.h device.h model.h + +nmi.o: ibm.h io.h nmi.h + +nvr.o: ibm.h cpu/cpu.h device.h io.h mem.h model.h nvr.h \ + pic.h rom.h timer.h rtc.h + +olivetti_m24.o: ibm.h cpu/cpu.h io.h device.h model.h + +opti495.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h + +pc.o: 86box.h ibm.h mem.h cpu/cpu.h cpu/x86_ops.h cpu/codegen.h \ + dma.h nvr.h pic.h pit.h timer.h device.h model.h disc.h \ + disc_86f.h disc_fdi.h disc_imd.h disc_img.h disc_td0.h \ + disc_random.h config.h fdc.h fdd.h gameport.h plat_joystick.h \ + plat_midi.h hdd.h ide.h cdrom.h cdrom_ioctl.h cdrom_image.h \ + cdrom_null.h scsi.h keyboard.h plat_keyboard.h keyboard_at.h \ + mouse.h plat_mouse.h network/network.h serial.h \ + sound/sound.h sound/snd_cms.h sound/snd_dbopl.h \ + sound/snd_mpu401.h sound/snd_opl.h sound/snd_gus.h \ + sound/snd_sb.h sound/snd_speaker.h sound/snd_ssi2001.h \ + video/video.h video/vid_voodoo.h win/plat_ui.h + +pc87306.o: ibm.h disc.h fdc.h fdd.h ide.h io.h lpt.h serial.h pc87306.h + +pci.o: ibm.h io.h mem.h pic.h pci.h + +pic.o: ibm.h io.h pic.h pit.h + +piix.o: ibm.h dma.h ide.h io.h mem.h pci.h piix.h + +pit.o: ibm.h cpu/cpu.h dma.h io.h pic.h pit.h device.h timer.h \ + model.h sound/snd_speaker.h video/video.h + +ppi.o: ibm.h pit.h plat_keyboard.h plat_mouse.h + +ps1.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h lpt.h serial.h + +ps2.o: ibm.h cpu/cpu.h io.h mem.h rom.h device.h model.h lpt.h serial.h + +ps2_mca.o: ibm.h cpu/cpu.h cpu/x86.h io.h mca.h mem.h rom.h device.h \ + lpt.h ps2_mca.h ps2_nvr.h serial.h + +ps2_nvr.o: ibm.h device.h io.h mem.h rom.h ps2_nvr.h + +rom.o: config.h ibm.h mem.h rom.h + +rtc.o: nvr.h rtc.h + +scat.o: ibm.h cpu/cpu.h io.h mem.h device.h model.h + +scsi.o: 86box.h ibm.h timer.h device.h cdrom.h scsi.h \ + scsi_aha154x.h scsi_buslogic.h + +scsi_aha154x.o: ibm.h io.h mca.h mem.h mca.h rom.h dma.h pic.h timer.h \ + device.h cdrom.h scsi.h scsi_disk.h scsi_aha154x.h \ + +scsi_buslogic.o: ibm.h io.h mem.h rom.h dma.h pic.h pci.h timer.h \ + device.h scsi.h scsi_disk.h cdrom.h scsi_buslogic.h + +scsi_disk.o: 86box.h cdrom.h hdd_image.h ibm.h ide.h piix.h scsi.h \ + scsi_disk.h timer.h win/plat_iodev.h + +serial.o: ibm.h io.h pic.h timer.h serial.h plat_serial.h + +sio.o: ibm.h cdrom.h disc.h dma.h fdc.h keyboard_at.h ide.h \ + io.h mem.h pci.h sio.h + +sis496.o: ibm.h cpu/cpu.h io.h mem.h pci.h device.h model.h + +sis50x.o: ibm.h device.h io.h mem.h pci.h sis50x.h + +sis85c471.o: ibm.h ide.h disc.h fdc.h fdd.h io.h lpt.h serial.h sis85c471.h + +tandy_eeprom.o: ibm.h device.h mem.h io.h rom.h tandy_eeprom.h + +tandy_rom.o: ibm.h device.h io.h mem.h rom.h tandy_rom.h + +timer.o: ibm.h timer.h + +usb.o: ibm.h io.h mem.h usb.h + +w83877f.o: ibm.h disc.h fdc.h fdd.h io.h lpt.h serial.h w83877f.h + +wd76c10.o: ibm.h disc.h fdc.h io.h mem.h serial.h wd76c10.h + +xtide.o: ibm.h io.h mem.h rom.h device.h ide.h xtide.h + + +# End of Makefile.mingw. diff --git a/src/SOUND/openal.c b/src/SOUND/openal.c new file mode 100644 index 000000000..c2d8d87fa --- /dev/null +++ b/src/SOUND/openal.c @@ -0,0 +1,245 @@ +#define USE_OPENAL +#include +#include +#include +#ifdef USE_OPENAL +# undef AL_API +# undef ALC_API +# define AL_LIBTYPE_STATIC +# define ALC_LIBTYPE_STATIC +# include +# include +# include +#endif +#include "../ibm.h" +#include "sound.h" + + +#define FREQ 48000 +#define BUFLEN SOUNDBUFLEN + + +#ifdef USE_OPENAL +ALuint buffers[4]; /* front and back buffers */ +ALuint buffers_cd[4]; /* front and back buffers */ +ALuint buffers_midi[4]; /* front and back buffers */ +static ALuint source[3]; /* audio source */ +#endif + +static int midi_freq = 44100; +static int midi_buf_size = 4410; +static int initialized = 0; + +void al_set_midi(int freq, int buf_size) +{ + midi_freq = freq; + midi_buf_size = buf_size; +} + +void closeal(void); +ALvoid alutInit(ALint *argc,ALbyte **argv) +{ + ALCcontext *Context; + ALCdevice *Device; + + /* Open device */ + Device = alcOpenDevice((ALCchar *)""); + if (Device != NULL) { + /* Create context(s) */ + Context = alcCreateContext(Device, NULL); + if (Context != NULL) { + /* Set active context */ + alcMakeContextCurrent(Context); + } + } +} + + +ALvoid alutExit(ALvoid) +{ + ALCcontext *Context; + ALCdevice *Device; + + /* Get active context */ + Context = alcGetCurrentContext(); + if (Context != NULL) { + /* Get device for active context */ + Device = alcGetContextsDevice(Context); + if (Device != NULL) { + /* Disable context */ + alcMakeContextCurrent(NULL); + + /* Close device */ + alcCloseDevice(Device); + } + + /* Release context(s) */ + alcDestroyContext(Context); + } +} + + +void closeal(void) +{ +#ifdef USE_OPENAL + alutExit(); +#endif +} + + +void initalmain(int argc, char *argv[]) +{ + if (!initialized) return; +#ifdef USE_OPENAL + alutInit(0,0); + atexit(closeal); +#endif + initialized = 0; +} + + +void inital(ALvoid) +{ + if (initialized) return; + +#ifdef USE_OPENAL + int c; + + float *buf = NULL, *cd_buf = NULL, *midi_buf = NULL; + int16_t *buf_int16 = NULL, *cd_buf_int16 = NULL, *midi_buf_int16 = NULL; + + if (sound_is_float) + { + buf = (float *) malloc((BUFLEN << 1) * sizeof(float)); + cd_buf = (float *) malloc((CD_BUFLEN << 1) * sizeof(float)); + midi_buf = (float *) malloc(midi_buf_size * sizeof(float)); + } + else + { + buf_int16 = (int16_t *) malloc((BUFLEN << 1) * sizeof(int16_t)); + cd_buf_int16 = (int16_t *) malloc((CD_BUFLEN << 1) * sizeof(int16_t)); + midi_buf_int16 = (int16_t *) malloc(midi_buf_size * sizeof(int16_t)); + } + + alGenBuffers(4, buffers); + alGenBuffers(4, buffers_cd); + alGenBuffers(4, buffers_midi); + + alGenSources(3, source); + + alSource3f(source[0], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[0], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[0], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[0], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[1], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[1], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[1], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[1], AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f(source[2], AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_VELOCITY, 0.0, 0.0, 0.0); + alSource3f(source[2], AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (source[2], AL_ROLLOFF_FACTOR, 0.0 ); + alSourcei (source[2], AL_SOURCE_RELATIVE, AL_TRUE ); + + if (sound_is_float) + { + memset(buf,0,BUFLEN*2*sizeof(float)); + memset(cd_buf,0,BUFLEN*2*sizeof(float)); + memset(midi_buf,0,midi_buf_size*sizeof(float)); + } + else + { + memset(buf_int16,0,BUFLEN*2*sizeof(int16_t)); + memset(cd_buf_int16,0,BUFLEN*2*sizeof(int16_t)); + memset(midi_buf_int16,0,midi_buf_size*sizeof(int16_t)); + } + + for (c = 0; c < 4; c++) + { + if (sound_is_float) + { + alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN*2*sizeof(float), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN*2*sizeof(float), CD_FREQ); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size*sizeof(float), midi_freq); + } + else + { + alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN*2*sizeof(int16_t), FREQ); + alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN*2*sizeof(int16_t), CD_FREQ); + alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size*sizeof(int16_t), midi_freq); + } + } + + alSourceQueueBuffers(source[0], 4, buffers); + alSourceQueueBuffers(source[1], 4, buffers_cd); + alSourceQueueBuffers(source[2], 4, buffers_midi); + alSourcePlay(source[0]); + alSourcePlay(source[1]); + alSourcePlay(source[2]); + + if (sound_is_float) + { + free(midi_buf); + free(cd_buf); + free(buf); + } + else + { + free(midi_buf_int16); + free(cd_buf_int16); + free(buf_int16); + } + + initialized = 1; +#endif +} + +void givealbuffer_common(void *buf, uint8_t src, int size, int freq) +{ +#ifdef USE_OPENAL + int processed; + int state; + ALuint buffer; + + alGetSourcei(source[src], AL_SOURCE_STATE, &state); + + if (state==0x1014) + { + alSourcePlay(source[src]); + } + alGetSourcei(source[src], AL_BUFFERS_PROCESSED, &processed); + + if (processed>=1) + { + alSourceUnqueueBuffers(source[src], 1, &buffer); + + if (sound_is_float) + { + alBufferData(buffer, AL_FORMAT_STEREO_FLOAT32, buf, size * sizeof(float), freq); + } + else + { + alBufferData(buffer, AL_FORMAT_STEREO16, buf, size * sizeof(int16_t), freq); + } + + alSourceQueueBuffers(source[src], 1, &buffer); + } +#endif +} + +void givealbuffer(void *buf) +{ + givealbuffer_common(buf, 0, BUFLEN << 1, FREQ); +} + +void givealbuffer_cd(void *buf) +{ + givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ); +} + +void givealbuffer_midi(void *buf, uint32_t size) +{ + givealbuffer_common(buf, 2, size, midi_freq); +} From 43aaf7dc74856950b915957b939d754ce5552ed1 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Jun 2017 18:33:36 +0200 Subject: [PATCH 369/392] When selecting an AT-class machine with less than 1 MB memory size granularity, memory size is no longer incorrectly multiplied by 1024, fixes the crashes with those machines; The NEAT, SCAT, and Headland chipsets no longer remap the top 384 kB. --- src/WIN/win_settings.c | 2 +- src/model.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index bc5d4724f..a297559de 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -674,7 +674,7 @@ static BOOL CALLBACK win_settings_machine_proc(HWND hdlg, UINT message, WPARAM w { temp_mem_size = models[temp_model].max_ram; } - if (models[temp_model].flags & MODEL_AT) + if ((models[temp_model].flags & MODEL_AT) && (models[temp_model].ram_granularity < 128)) { temp_mem_size *= 1024; } diff --git a/src/model.c b/src/model.c index 155fa2793..776c99cff 100644 --- a/src/model.c +++ b/src/model.c @@ -534,14 +534,12 @@ void ps2_model_80_init(void) void at_neat_init(void) { at_ide_init(); - mem_remap_top_384k(); neat_init(); } void at_scat_init(void) { at_ide_init(); - mem_remap_top_384k(); scat_init(); } @@ -566,7 +564,6 @@ void at_wd76c10_init(void) void at_headland_init(void) { at_ide_init(); - mem_remap_top_384k(); headland_init(); } From 6ff901920632a53e9c8352d292776aab7d55e31d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Jun 2017 18:45:29 +0200 Subject: [PATCH 370/392] Added experimental 286 task switching support, patch from Greatpsycho. --- src/CPU/x86seg.c | 176 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 167 insertions(+), 9 deletions(-) diff --git a/src/CPU/x86seg.c b/src/CPU/x86seg.c index c200b3121..399b6826f 100644 --- a/src/CPU/x86seg.c +++ b/src/CPU/x86seg.c @@ -25,8 +25,6 @@ #include "x86.h" #include "386.h" #include "386_common.h" -#undef readmemb -#define readmemb(a) ((readlookup2[(a)>>12]==-1)?readmembl(a):*(uint8_t *)(readlookup2[(a) >> 12] + (a))) #include "cpu.h" /*Controls whether the accessed bit in a descriptor is set when CS is loaded.*/ @@ -736,6 +734,7 @@ void loadcsjmp(uint16_t seg, uint32_t oxpc) break; + case 0x100: /*286 Task gate*/ case 0x900: /*386 Task gate*/ cpu_state.pc=oxpc; cpl_override=1; @@ -2125,11 +2124,14 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) uint16_t segdat2[4]; - base=segdat[1]|((segdat[2]&0xFF)<<16)|((segdat[3]>>8)<<24); - limit=segdat[0]|((segdat[3]&0xF)<<16); + base=segdat[1]|((segdat[2]&0xFF)<<16); + limit=segdat[0]; - if (is386) + if (is32) { + base |= (segdat[3]>>8)<<24; + limit |= (segdat[3]&0xF)<<16; + new_cr3=readmeml(base,0x1C); new_pc=readmeml(base,0x20); new_flags=readmeml(base,0x24); @@ -2215,12 +2217,12 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) ldt.seg=new_ldt; templ=(ldt.seg&~7)+gdt.base; ldt.limit=readmemw(0,templ); - if (readmemb(templ+6)&0x80) + if (readmemb(0,templ+6)&0x80) { ldt.limit<<=12; ldt.limit|=0xFFF; } - ldt.base=(readmemw(0,templ+2))|(readmemb(templ+4)<<16)|(readmemb(templ+7)<<24); + ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16)|(readmemb(0,templ+7)<<24); if (eflags&VM_FLAG) { @@ -2311,9 +2313,165 @@ void taskswitch286(uint16_t seg, uint16_t *segdat, int is32) } else { - resetx86(); - } + new_pc=readmemw(base,0x0E); + new_flags=readmemw(base,0x10); + + new_eax=readmemw(base,0x12); + new_ecx=readmemw(base,0x14); + new_edx=readmemw(base,0x16); + new_ebx=readmemw(base,0x18); + new_esp=readmemw(base,0x1A); + new_ebp=readmemw(base,0x1C); + new_esi=readmemw(base,0x1E); + new_edi=readmemw(base,0x20); + new_es=readmemw(base,0x22); + new_cs=readmemw(base,0x24); + new_ss=readmemw(base,0x26); + new_ds=readmemw(base,0x28); + new_ldt=readmemw(base,0x2A); + + if (cpu_state.abrt) return; + if (optype==JMP || optype==OPTYPE_INT) + { + if (tr.seg&4) tempw=readmemw(ldt.base,(tr.seg&~7)+4); + else tempw=readmemw(gdt.base,(tr.seg&~7)+4); + if (cpu_state.abrt) return; + tempw&=~0x200; + if (tr.seg&4) writememw(ldt.base,(tr.seg&~7)+4,tempw); + else writememw(gdt.base,(tr.seg&~7)+4,tempw); + } + + if (optype==IRET) flags&=~NT_FLAG; + + cpu_386_flags_rebuild(); + writememw(tr.base,0x0E,cpu_state.pc); + writememw(tr.base,0x10,flags); + + writememw(tr.base,0x12,AX); + writememw(tr.base,0x14,CX); + writememw(tr.base,0x16,DX); + writememw(tr.base,0x18,BX); + writememw(tr.base,0x1A,SP); + writememw(tr.base,0x1C,BP); + writememw(tr.base,0x1E,SI); + writememw(tr.base,0x20,DI); + + writememw(tr.base,0x22,ES); + writememw(tr.base,0x24,CS); + writememw(tr.base,0x26,SS); + writememw(tr.base,0x28,DS); + writememw(tr.base,0x2A,ldt.seg); + + if (optype==OPTYPE_INT) + { + writememw(base,0,tr.seg); + new_flags|=NT_FLAG; + } + if (cpu_state.abrt) return; + if (optype==JMP || optype==OPTYPE_INT) + { + if (tr.seg&4) tempw=readmemw(ldt.base,(seg&~7)+4); + else tempw=readmemw(gdt.base,(seg&~7)+4); + if (cpu_state.abrt) return; + tempw|=0x200; + if (tr.seg&4) writememw(ldt.base,(seg&~7)+4,tempw); + else writememw(gdt.base,(seg&~7)+4,tempw); + } + + cpu_state.pc=new_pc; + flags=new_flags; + cpu_386_flags_extract(); + + ldt.seg=new_ldt; + templ=(ldt.seg&~7)+gdt.base; + ldt.limit=readmemw(0,templ); + ldt.base=(readmemw(0,templ+2))|(readmemb(0,templ+4)<<16); + + if (!(new_cs&~3)) + { + pclog("TS loading null CS\n"); + x86gpf(NULL,0); + return; + } + addr=new_cs&~7; + if (new_cs&4) + { + if (addr>=ldt.limit) + { + pclog("Bigger than LDT limit %04X %04X %04X TS\n",new_cs,ldt.limit,addr); + x86gpf(NULL,0); + return; + } + addr+=ldt.base; + } + else + { + if (addr>=gdt.limit) + { + pclog("Bigger than GDT limit %04X %04X TS\n",new_cs,gdt.limit); + x86gpf(NULL,0); + return; + } + addr+=gdt.base; + } + segdat2[0]=readmemw(0,addr); + segdat2[1]=readmemw(0,addr+2); + segdat2[2]=readmemw(0,addr+4); + segdat2[3]=readmemw(0,addr+6); + if (!(segdat2[2]&0x8000)) + { + pclog("TS loading CS not present\n"); + x86np("TS loading CS not present\n", new_cs & 0xfffc); + return; + } + switch (segdat2[2]&0x1F00) + { + case 0x1800: case 0x1900: case 0x1A00: case 0x1B00: /*Non-conforming*/ + if ((new_cs&3) != DPL2) + { + pclog("TS load CS non-conforming RPL != DPL"); + x86gpf(NULL,new_cs&~3); + return; + } + break; + case 0x1C00: case 0x1D00: case 0x1E00: case 0x1F00: /*Conforming*/ + if ((new_cs&3) < DPL2) + { + pclog("TS load CS non-conforming RPL < DPL"); + x86gpf(NULL,new_cs&~3); + return; + } + break; + default: + pclog("TS load CS not code segment\n"); + x86gpf(NULL,new_cs&~3); + return; + } + + CS=new_cs; + do_seg_load(&_cs, segdat2); + if (CPL==3 && oldcpl!=3) flushmmucache_cr3(); + set_use32(0); + + AX=new_eax; + CX=new_ecx; + DX=new_edx; + BX=new_ebx; + SP=new_esp; + BP=new_ebp; + SI=new_esi; + DI=new_edi; + + if (output) pclog("Load ES %04X\n",new_es); + loadseg(new_es,&_es); + if (output) pclog("Load SS %04X\n",new_ss); + loadseg(new_ss,&_ss); + if (output) pclog("Load DS %04X\n",new_ds); + loadseg(new_ds,&_ds); + + if (output) pclog("Resuming at %04X:%08X\n",CS,cpu_state.pc); + } tr.seg=seg; tr.base=base; From 51ef58ad00cb27920289b92af8aa2b43ade57a46 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Jun 2017 22:18:35 +0200 Subject: [PATCH 371/392] Fixed RTL8029AS PCI register write handlers; Disabled the Nation Semiconductors PC87306's IDE handler, the board replaces it with the PCI IDE device anyway; The Commodore PC 300 now remaps the top 384k of RAM; The network card is now initialized after the SCSI controller; The graphics cards remain on the INTA pin, but the network card is now on INTC, and the SCSI controller on INTB; S3 Vision/Trio emulation brought completely in line with mainline PCem, fixes Windows 2000 freezes. --- src/NETWORK/net_ne2000.c | 36 ++-- src/VIDEO/vid_s3.c | 403 ++++++++++++++++----------------------- src/model.c | 51 ++--- src/pc.c | 2 +- src/pc87306.c | 4 + src/scsi_buslogic.c | 6 +- 6 files changed, 228 insertions(+), 274 deletions(-) diff --git a/src/NETWORK/net_ne2000.c b/src/NETWORK/net_ne2000.c index 026e72619..d98fdf019 100644 --- a/src/NETWORK/net_ne2000.c +++ b/src/NETWORK/net_ne2000.c @@ -245,9 +245,9 @@ nic_interrupt(nic_t *dev, int set) { if (PCI && dev->is_pci) { if (set) - pci_set_irq(dev->card, PCI_INTA); + pci_set_irq(dev->card, PCI_INTC); else - pci_clear_irq(dev->card, PCI_INTA); + pci_clear_irq(dev->card, PCI_INTC); } else { if (set) picint(1<base_irq); @@ -1485,6 +1485,7 @@ nic_pci_read(int func, int addr, void *priv) ret = dev->pci_regs[addr]; break; +#if 0 case 0x0C: /* (reserved) */ ret = dev->pci_regs[addr]; break; @@ -1497,6 +1498,7 @@ nic_pci_read(int func, int addr, void *priv) case 0x0F: /* (reserved) */ ret = dev->pci_regs[addr]; break; +#endif case 0x10: /* PCI_BAR 7:5 */ ret = (dev->pci_bar[0].addr_regs[1] & 0xe0) | 0x01; @@ -1553,23 +1555,30 @@ static void nic_pci_write(int func, int addr, uint8_t val, void *priv) { nic_t *dev = (nic_t *)priv; + uint8_t valxor; nelog(2, "%s: PCI_Write(%d, %04x, %02x)\n", dev->name, func, addr, val); switch(addr) { case 0x04: /* PCI_COMMAND_LO */ - val &= 0x03; - nic_ioremove(dev, dev->base_address); - if (val & PCI_COMMAND_IO) - nic_ioset(dev, dev->base_address); + valxor = (val & 0x23) ^ dev->pci_regs[addr]; + if (valxor & PCI_COMMAND_IO) + { + nic_ioremove(dev, dev->base_address); + if ((dev->base_address != 0) && (val & PCI_COMMAND_IO)) + { + nic_ioset(dev, dev->base_address); + } + } #if 0 if (val & PCI_COMMAND_MEMORY) { ... } #endif - dev->pci_regs[addr] = val; + dev->pci_regs[addr] = val & 0x23; break; +#if 0 case 0x0C: /* (reserved) */ dev->pci_regs[addr] = val; break; @@ -1585,6 +1594,7 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) case 0x0F: /* (reserved) */ dev->pci_regs[addr] = val; break; +#endif case 0x10: /* PCI_BAR */ val &= 0xfc; /* 0xe0 acc to RTL DS */ @@ -1607,8 +1617,13 @@ nic_pci_write(int func, int addr, uint8_t val, void *priv) nelog(1, "%s: PCI: new I/O base is %04X\n", dev->name, dev->base_address); /* We're done, so get out of the here. */ - if (val & PCI_COMMAND_IO) - nic_ioset(dev, dev->base_address); + if (dev->pci_regs[4] & PCI_COMMAND_IO) + { + if (dev->base_address != 0) + { + nic_ioset(dev, dev->base_address); + } + } break; case 0x30: /* PCI_ROMBAR */ @@ -1938,8 +1953,7 @@ nic_init(int board) dev->pci_regs[0x2E] = (PCI_DEVID&0xff); dev->pci_regs[0x2F] = (PCI_DEVID>>8); - dev->pci_regs[0x3C] = dev->base_irq; /* PCI_ILR */ - dev->pci_regs[0x3D] = 0x01; /* PCI_IPR */ + dev->pci_regs[0x3D] = PCI_INTC; /* PCI_IPR */ /* Enable our address space in PCI. */ dev->pci_bar[0].addr_regs[0] = 0x01; diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 61a24ce64..6cc18d7e9 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1,36 +1,18 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Emulation of the S3 Trio32, S3 Trio64, and S3 Vision864 - * graphics cards. - * - * Version: @(#)vid_s3.c 1.0.1 2017/06/04 - * - * Authors: Sarah Walker, - * Miran Grca, - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016-2017 Miran Grca. - */ +/*S3 emulation*/ #include #include "../ibm.h" +#include "../device.h" #include "../io.h" #include "../mem.h" #include "../pci.h" #include "../rom.h" -#include "../device.h" -#include "../win/plat_thread.h" +#include "../WIN/plat_thread.h" #include "video.h" #include "vid_s3.h" #include "vid_svga.h" #include "vid_svga_render.h" #include "vid_sdac_ramdac.h" - enum { S3_VISION864, @@ -93,15 +75,15 @@ typedef struct s3_t int chip; uint8_t id, id_ext, id_ext_pci; - - uint8_t int_line; + + uint8_t int_line; int packed_mmio; uint32_t linear_base, linear_size; uint8_t pci_regs[256]; - int card; + int card; uint32_t vram_mask; @@ -152,9 +134,8 @@ typedef struct s3_t int blitter_busy; uint64_t blitter_time; uint64_t status_time; - - uint8_t subsys_cntl, subsys_stat; - uint8_t status_9ae9; + + uint8_t subsys_cntl, subsys_stat; } s3_t; #define INT_VSY (1 << 0) @@ -170,7 +151,7 @@ void s3_accel_write_w(uint32_t addr, uint16_t val, void *p); void s3_accel_write_l(uint32_t addr, uint32_t val, void *p); uint8_t s3_accel_read(uint32_t addr, void *p); -static __inline void wake_fifo_thread(s3_t *s3) +static inline void wake_fifo_thread(s3_t *s3) { thread_set_event(s3->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/ } @@ -186,11 +167,6 @@ static void s3_wait_fifo_idle(s3_t *s3) static void s3_update_irqs(s3_t *s3) { - if (!PCI) - { - return; - } - if (s3->subsys_cntl & s3->subsys_stat & INT_MASK) pci_set_irq(s3->card, PCI_INTA); else @@ -444,88 +420,70 @@ static void s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if (port & 0x8000) - { - s3_accel_out_fifo(s3, port, val); - s3_accel_out_fifo(s3, port + 1, val >> 8); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } - } + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } + else + { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } } static void s3_accel_out_fifo_l(s3_t *s3, uint16_t port, uint32_t val) { - if (port & 0x8000) - { - s3_accel_out_fifo(s3, port, val); - s3_accel_out_fifo(s3, port + 1, val >> 8); - s3_accel_out_fifo(s3, port + 2, val >> 16); - s3_accel_out_fifo(s3, port + 3, val >> 24); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x400) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } - else - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } - else - { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } - } + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x400) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } + else if ((s3->accel.cmd & 0x600) == 0x200) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } + else + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } + else + { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) + { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + else + { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } } static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) @@ -635,88 +593,88 @@ static void s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) static void s3_accel_write_fifo_w(s3_t *s3, uint32_t addr, uint16_t val) { - if (addr & 0x8000) - { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x1000) - val = (val >> 8) | (val << 8); - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(8, 1, val | (val << 16), 0, s3); - else - s3_accel_start(16, 1, val | (val << 16), 0, s3); - } - else - { - if ((s3->accel.cmd & 0x600) == 0x000) - s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); - else - s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); - } - } - } + if (addr & 0x8000) + { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x1000) + val = (val >> 8) | (val << 8); + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(8, 1, val | (val << 16), 0, s3); + else + s3_accel_start(16, 1, val | (val << 16), 0, s3); + } + else + { + if ((s3->accel.cmd & 0x600) == 0x000) + s3_accel_start(1, 1, 0xffffffff, val | (val << 16), s3); + else + s3_accel_start(2, 1, 0xffffffff, val | (val << 16), s3); + } + } + } } static void s3_accel_write_fifo_l(s3_t *s3, uint32_t addr, uint32_t val) { - if (addr & 0x8000) - { - s3_accel_write_fifo(s3, addr, val); - s3_accel_write_fifo(s3, addr + 1, val >> 8); - s3_accel_write_fifo(s3, addr + 2, val >> 16); - s3_accel_write_fifo(s3, addr + 3, val >> 24); - } - else - { - if (s3->accel.cmd & 0x100) - { - if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) - { - if (s3->accel.cmd & 0x400) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); - s3_accel_start(32, 1, val, 0, s3); - } - else if ((s3->accel.cmd & 0x600) == 0x200) - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(16, 1, val, 0, s3); - s3_accel_start(16, 1, val >> 16, 0, s3); - } - else - { - if (s3->accel.cmd & 0x1000) - val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); - s3_accel_start(8, 1, val, 0, s3); - s3_accel_start(8, 1, val >> 16, 0, s3); - } - } - else - { - if (s3->accel.cmd & 0x400) - s3_accel_start(4, 1, 0xffffffff, val, s3); - else if ((s3->accel.cmd & 0x600) == 0x200) - { - s3_accel_start(2, 1, 0xffffffff, val, s3); - s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); - } - else - { - s3_accel_start(1, 1, 0xffffffff, val, s3); - s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); - } - } - } - } + if (addr & 0x8000) + { + s3_accel_write_fifo(s3, addr, val); + s3_accel_write_fifo(s3, addr + 1, val >> 8); + s3_accel_write_fifo(s3, addr + 2, val >> 16); + s3_accel_write_fifo(s3, addr + 3, val >> 24); + } + else + { + if (s3->accel.cmd & 0x100) + { + if ((s3->accel.multifunc[0xa] & 0xc0) == 0x80) + { + if (s3->accel.cmd & 0x400) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_accel_start(32, 1, val, 0, s3); + } + else if ((s3->accel.cmd & 0x600) == 0x200) + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(16, 1, val, 0, s3); + s3_accel_start(16, 1, val >> 16, 0, s3); + } + else + { + if (s3->accel.cmd & 0x1000) + val = ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); + s3_accel_start(8, 1, val, 0, s3); + s3_accel_start(8, 1, val >> 16, 0, s3); + } + } + else + { + if (s3->accel.cmd & 0x400) + s3_accel_start(4, 1, 0xffffffff, val, s3); + else if ((s3->accel.cmd & 0x600) == 0x200) + { + s3_accel_start(2, 1, 0xffffffff, val, s3); + s3_accel_start(2, 1, 0xffffffff, val >> 16, s3); + } + else + { + s3_accel_start(1, 1, 0xffffffff, val, s3); + s3_accel_start(1, 1, 0xffffffff, val >> 16, s3); + } + } + } + } } static void fifo_thread(void *param) @@ -834,14 +792,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - if (s3->chip < S3_TRIO32) - { - sdac_ramdac_out(addr, val, &s3->ramdac, svga); - } - else - { - svga_out(addr, val, svga); - } + sdac_ramdac_out(addr, val, &s3->ramdac, svga); return; case 0x3D4: @@ -922,7 +873,7 @@ void s3_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.xoff = svga->crtc[0x4e] & 63; svga->hwcursor.yoff = svga->crtc[0x4f] & 63; svga->hwcursor.addr = ((((svga->crtc[0x4c] << 8) | svga->crtc[0x4d]) & 0xfff) * 1024) + (svga->hwcursor.yoff * 16); - if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && (svga->bpp == 32) && (s3->id == 0xe1)) + if ((s3->chip == S3_TRIO32 || s3->chip == S3_TRIO64) && svga->bpp == 32) svga->hwcursor.x <<= 1; break; @@ -979,14 +930,7 @@ uint8_t s3_in(uint16_t addr, void *p) break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - if (s3->chip < S3_TRIO32) - { - return sdac_ramdac_in(addr, &s3->ramdac, svga); - } - else - { - return svga_in(addr, svga); - } + return sdac_ramdac_in(addr, &s3->ramdac, svga); case 0x3d4: return svga->crtcreg; @@ -1002,10 +946,6 @@ uint8_t s3_in(uint16_t addr, void *p) case 0x51: return (svga->crtc[0x51] & 0xf0) | ((s3->bank >> 2) & 0xc) | ((s3->ma_ext >> 2) & 3); case 0x69: return s3->ma_ext; case 0x6a: return s3->bank; - case 0x6b: - pclog("Returning value: %02X\n", svga->crtc[0x6b]); - return 0xff; - break; } return svga->crtc[svga->crtcreg]; } @@ -1074,7 +1014,7 @@ void s3_recalctimings(svga_t *svga) void s3_updatemapping(s3_t *s3) { svga_t *svga = &s3->svga; - + if (!(s3->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mem_mapping_disable(&svga->mapping); @@ -1129,7 +1069,6 @@ void s3_updatemapping(s3_t *s3) break; } s3->linear_base &= ~(s3->linear_size - 1); - svga->linear_base = s3->linear_base; if (s3->linear_base == 0xa0000) { mem_mapping_disable(&s3->linear_mapping); @@ -1144,7 +1083,7 @@ void s3_updatemapping(s3_t *s3) } else mem_mapping_disable(&s3->linear_mapping); - + if (svga->crtc[0x53] & 0x10) /*Memory mapped IO*/ { mem_mapping_disable(&svga->mapping); @@ -1173,7 +1112,7 @@ static float s3_trio64_getclock(int clock, void *p) void s3_accel_out(uint16_t port, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; - + if (port >= 0x8000) { s3_queue(s3, port, val, FIFO_OUT_BYTE); @@ -1275,7 +1214,7 @@ uint8_t s3_accel_in(uint16_t port, void *p) if (!FIFO_EMPTY) temp |= 0x02; /*Hardware busy*/ else - temp |= s3->status_9ae9; /*FIFO empty*/ + temp |= 0x04; /*FIFO empty*/ if (FIFO_FULL) temp |= 0xf8; /*FIFO full*/ return temp; @@ -1998,8 +1937,6 @@ void s3_hwcursor_draw(svga_t *svga, int displine) uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; - int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -2013,9 +1950,9 @@ void s3_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? 0xffffff : 0; + ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0; else if (dat[1] & 0x8000) - ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; + ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; } offset++; @@ -2088,7 +2025,6 @@ uint8_t s3_pci_read(int func, int addr, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - /* pclog("S3 PCI read %08X\n", addr); */ switch (addr) { case 0x00: return 0x33; /*'S3'*/ @@ -2128,7 +2064,6 @@ void s3_pci_write(int func, int addr, uint8_t val, void *p) { s3_t *s3 = (s3_t *)p; svga_t *svga = &s3->svga; - /* pclog("s3_pci_write: addr=%02x val=%02x\n", addr, val); */ switch (addr) { case PCI_REG_COMMAND: @@ -2187,9 +2122,9 @@ static void *s3_init(wchar_t *bios_fn, int chip) svga_t *svga = &s3->svga; int vram; uint32_t vram_size; - + memset(s3, 0, sizeof(s3_t)); - + vram = device_get_config_int("memory"); if (vram) vram_size = vram << 20; @@ -2216,20 +2151,14 @@ static void *s3_init(wchar_t *bios_fn, int chip) else svga->crtc[0x36] = 1 | (3 << 2) | (1 << 4) | (vram_sizes[vram] << 5); svga->crtc[0x37] = 1 | (7 << 5); - - svga->vblank_start = s3_vblank_start; - - svga->crtc[0x53] = 1 << 3; - svga->crtc[0x59] = 0x70; + + svga->vblank_start = s3_vblank_start; s3_io_set(s3); - if (PCI) - { - s3->card = pci_add(s3_pci_read, s3_pci_write, s3); - } - - s3->pci_regs[0x04] = 3; + s3->card = pci_add(s3_pci_read, s3_pci_write, s3); + + s3->pci_regs[0x04] = 7; s3->pci_regs[0x30] = 0x00; s3->pci_regs[0x32] = 0x0c; @@ -2240,8 +2169,8 @@ static void *s3_init(wchar_t *bios_fn, int chip) s3->wake_fifo_thread = thread_create_event(); s3->fifo_not_full_event = thread_create_event(); s3->fifo_thread = thread_create(fifo_thread, s3); - - s3->int_line = 0; + + s3->int_line = 0; return s3; } @@ -2341,7 +2270,7 @@ int s3_9fx_available() int s3_phoenix_trio64_available() { - return rom_present(L"roms/86C764X1.bin"); + return rom_present(L"roms/86c764x1.bin"); } int s3_diamond_stealth64_available() diff --git a/src/model.c b/src/model.c index 776c99cff..8f76c06fb 100644 --- a/src/model.c +++ b/src/model.c @@ -88,6 +88,7 @@ extern void olim24_init(void); extern void at_init(void); extern void ibm_at_init(void); extern void at_ide_init(void); +extern void cmdpc30_init(void); extern void deskpro386_init(void); extern void ps1_m2011_init(void); extern void ps1_m2121_init(void); @@ -163,7 +164,7 @@ MODEL models[] = {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL}, {"Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, at_ide_init, NULL}, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, cmdpc30_init, NULL}, {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, @@ -432,6 +433,12 @@ void at_ide_init(void) ide_init(); } +void cmdpc30_init(void) +{ + at_ide_init(); + mem_remap_top_384k(); +} + void deskpro386_init(void) { at_init(); @@ -697,10 +704,10 @@ void at_mb500n_init(void) { at_ide_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); - pci_slot(0x12); - pci_slot(0x13); pci_slot(0x14); + pci_slot(0x13); + pci_slot(0x12); + pci_slot(0x11); i430fx_init(); piix_init(7, 0x14, 0x13, 0x12, 0x11); fdc37c665_init(); @@ -730,10 +737,10 @@ void at_p54tp4xe_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(9); - pci_slot(10); - pci_slot(11); pci_slot(12); + pci_slot(11); + pci_slot(10); + pci_slot(9); i430fx_init(); piix_init(7, 12, 11, 10, 9); fdc37c665_init(); @@ -763,12 +770,12 @@ void at_p55t2s_init(void) memregs_init(); powermate_memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0x11); pci_slot(0x12); - pci_slot(0x13); + pci_slot(0x11); pci_slot(0x14); + pci_slot(0x13); i430hx_init(); - piix_init(7, 0x12, 0x13, 0x14, 0x11); + piix_init(7, 0x12, 0x11, 0x14, 0x13); pc87306_init(); acerm3a_io_init(); device_add(&intel_flash_bxt_device); @@ -813,10 +820,10 @@ void at_p55t2p4_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(9); - pci_slot(10); - pci_slot(11); pci_slot(12); + pci_slot(11); + pci_slot(10); + pci_slot(9); i430hx_init(); piix3_init(7, 12, 11, 10, 9); w83877f_init(); @@ -845,10 +852,10 @@ void at_p55tvp4_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(9); - pci_slot(10); - pci_slot(11); pci_slot(12); + pci_slot(11); + pci_slot(10); + pci_slot(9); i430vx_init(); piix3_init(7, 12, 11, 10, 9); w83877f_init(); @@ -875,10 +882,10 @@ void at_i440fx_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xb); - pci_slot(0xc); - pci_slot(0xd); pci_slot(0xe); + pci_slot(0xd); + pci_slot(0xc); + pci_slot(0xb); i430vx_init(); piix3_init(7, 0xe, 0xd, 0xc, 0xb); fdc37c665_init(); @@ -890,10 +897,10 @@ void at_s1668_init(void) at_ide_init(); memregs_init(); pci_init(PCI_CONFIG_TYPE_1); - pci_slot(0xb); - pci_slot(0xc); - pci_slot(0xd); pci_slot(0xe); + pci_slot(0xd); + pci_slot(0xc); + pci_slot(0xb); i440fx_init(); piix3_init(7, 0xe, 0xd, 0xc, 0xb); fdc37c665_init(); diff --git a/src/pc.c b/src/pc.c index 3bdeabc71..64a85f616 100644 --- a/src/pc.c +++ b/src/pc.c @@ -502,7 +502,6 @@ void resetpchard_init(void) model_init(); video_init(); speaker_init(); - network_reset(); ide_ter_disable(); ide_qua_disable(); @@ -519,6 +518,7 @@ void resetpchard_init(void) resetide(); scsi_card_init(); + network_reset(); sound_card_init(); if (mpu401_standalone_enable) diff --git a/src/pc87306.c b/src/pc87306.c index c0887451b..b67aa5071 100644 --- a/src/pc87306.c +++ b/src/pc87306.c @@ -154,7 +154,9 @@ void pc87306_write(uint16_t port, uint8_t val, void *priv) { uint8_t index; uint8_t valxor; +#if 0 uint16_t or_value; +#endif index = (port & 1) ? 0 : 1; @@ -239,6 +241,7 @@ process_value: } if (valxor & 0xc0) { +#if 0 ide_pri_disable(); if (val & 0x80) { @@ -254,6 +257,7 @@ process_value: { ide_pri_enable_ex(); } +#endif } break; diff --git a/src/scsi_buslogic.c b/src/scsi_buslogic.c index cfc1188c2..2da990ee4 100644 --- a/src/scsi_buslogic.c +++ b/src/scsi_buslogic.c @@ -533,11 +533,11 @@ BuslogicInterrupt(Buslogic_t *bl, int set) { if (set) { - pci_set_irq(bl->Card, PCI_INTA); + pci_set_irq(bl->Card, PCI_INTB); } else { - pci_clear_irq(bl->Card, PCI_INTA); + pci_clear_irq(bl->Card, PCI_INTB); } } else @@ -2116,7 +2116,7 @@ BuslogicPCIRead(int func, int addr, void *p) case 0x3C: return bl->Irq; case 0x3D: - return PCI_INTA; + return PCI_INTB; } return(0); From ca53dd028075fcdbb46936cd8f04ff4e51f2e9e4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 19 Jun 2017 22:32:16 +0200 Subject: [PATCH 372/392] S3 Trio/Vision changes (again x2): Trio32/64 with on-chip ramdac instead of SDAC. FIFO Empty/Full status from 9ae8/9ae9 no longer slowing down OS/2 when native drivers are installed. --- src/VIDEO/vid_s3.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 6cc18d7e9..3401ecd03 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -86,6 +86,7 @@ typedef struct s3_t int card; uint32_t vram_mask; + uint8_t status_9ae8; float (*getclock)(int clock, void *p); void *getclock_p; @@ -792,7 +793,12 @@ void s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - sdac_ramdac_out(addr, val, &s3->ramdac, svga); + if (s3->chip < S3_TRIO32) + { + sdac_ramdac_out(addr, val, &s3->ramdac, svga); + return; + } + svga_out(addr, val, svga); return; case 0x3D4: @@ -930,7 +936,10 @@ uint8_t s3_in(uint16_t addr, void *p) break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - return sdac_ramdac_in(addr, &s3->ramdac, svga); + if (s3->chip < S3_TRIO32) + return sdac_ramdac_in(addr, &s3->ramdac, svga); + + return svga_in(addr, svga); case 0x3d4: return svga->crtcreg; @@ -1214,7 +1223,7 @@ uint8_t s3_accel_in(uint16_t port, void *p) if (!FIFO_EMPTY) temp |= 0x02; /*Hardware busy*/ else - temp |= 0x04; /*FIFO empty*/ + temp |= s3->status_9ae8; /*FIFO empty*/ if (FIFO_FULL) temp |= 0xf8; /*FIFO full*/ return temp; @@ -1604,6 +1613,14 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ + + if ((s3->accel.cmd & 0x100) && !cpu_input) + { + s3->status_9ae8 = 2; /*To avoid the spam from OS/2's drivers*/ + return; /*Wait for data from CPU*/ + } + while (count-- && s3->accel.sy >= 0) { if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && @@ -1688,7 +1705,8 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; if (!cpu_input && frgd_mix == 3 && !vram_mask && !compare_mode && - (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7) + (s3->accel.cmd & 0xa0) == 0xa0 && (s3->accel.frgd_mix & 0xf) == 7 && + (s3->accel.bkgd_mix & 0xf) == 7) { while (1) { From 310881dd63be4400aee0f22586d79992599c3a3c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 19 Jun 2017 22:32:55 +0200 Subject: [PATCH 373/392] S3 Trio32 and Trio64 no longer use the SDAC RAMDAC. --- src/VIDEO/vid_s3.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 6cc18d7e9..c9691cf5d 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -792,8 +792,15 @@ void s3_out(uint16_t addr, uint8_t val, void *p) break; case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9: - sdac_ramdac_out(addr, val, &s3->ramdac, svga); - return; + if (s3->chip == S3_VISION864) + { + sdac_ramdac_out(addr, val, &s3->ramdac, svga); + return; + } + else + { + break; + } case 0x3D4: svga->crtcreg = val & 0x7f; @@ -930,7 +937,14 @@ uint8_t s3_in(uint16_t addr, void *p) break; case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9: - return sdac_ramdac_in(addr, &s3->ramdac, svga); + if (s3->chip == S3_VISION864) + { + return sdac_ramdac_in(addr, &s3->ramdac, svga); + } + else + { + break; + } case 0x3d4: return svga->crtcreg; From 7bc1d6fdca4952074f576e55fb19f7b390fee4e9 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 19 Jun 2017 22:37:17 -0400 Subject: [PATCH 374/392] Applied PCem patch for ide.c to make the Samsung 4200P work. --- src/ide.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ide.c b/src/ide.c index 86ef8b78c..e296770f2 100644 --- a/src/ide.c +++ b/src/ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)ide.c 1.0.3 2017/06/17 + * Version: @(#)ide.c 1.0.4 2017/06/20 * * Authors: Sarah Walker, * Miran Grca, @@ -1059,7 +1059,11 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SLEEP1: if (val == WIN_DRIVE_DIAGNOSTICS) { + ide->atastat = BUSY_STAT; + timer_process(); callbackide(ide_board); + idecallback[ide_board]=200*IDE_TIME; + timer_update_outstanding(); } else { From 7d67f85a1db866ed5f1e7bc1d266971dc3d6d71a Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Jun 2017 06:23:05 +0200 Subject: [PATCH 375/392] Fixed the operation of the WIN_DRIVE_DIAGNOSTICS command for ATAPI CD-ROM (it's almost never used but eh); Properly fixed the CPU manufacturer/type selection bug after changing machine; The Samspung SPC-4200 now has a PS/2 port. --- src/WIN/win_settings.c | 8 ++++---- src/ide.c | 19 +++++++++++++++---- src/model.c | 40 ++++++++++++++++++++-------------------- 3 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index a297559de..6844a167d 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -437,9 +437,9 @@ static void win_settings_machine_recalc_cpu_m(HWND hdlg) c++; } EnableWindow(h, TRUE); - if (temp_cpu > c) + if (temp_cpu >= c) { - temp_cpu = c; + temp_cpu = (c - 1); } SendMessage(h, CB_SETCURSEL, temp_cpu, 0); @@ -482,9 +482,9 @@ static void win_settings_machine_recalc_model(HWND hdlg) c++; } EnableWindow(h, TRUE); - if (temp_cpu_m > c) + if (temp_cpu_m >= c) { - temp_cpu_m = c; + temp_cpu_m = (c - 1); } SendMessage(h, CB_SETCURSEL, temp_cpu_m, 0); if (c == 1) diff --git a/src/ide.c b/src/ide.c index e296770f2..72eb186d7 100644 --- a/src/ide.c +++ b/src/ide.c @@ -1059,10 +1059,21 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) case WIN_SLEEP1: if (val == WIN_DRIVE_DIAGNOSTICS) { - ide->atastat = BUSY_STAT; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].status = BUSY_STAT; + } + else + { + ide->atastat = BUSY_STAT; + } timer_process(); callbackide(ide_board); - idecallback[ide_board]=200*IDE_TIME; + if (ide_drive_is_cdrom(ide)) + { + cdrom[atapi_cdrom_drives[ide->channel]].callback = 200 * IDE_TIME; + } + idecallback[ide_board] = 200 * IDE_TIME; timer_update_outstanding(); } else @@ -1078,9 +1089,9 @@ void writeide(int ide_board, uint16_t addr, uint8_t val) timer_process(); if (ide_drive_is_cdrom(ide)) { - cdrom[atapi_cdrom_drives[ide->channel]].callback = ((val == WIN_DRIVE_DIAGNOSTICS) ? 200 : 30) * IDE_TIME; + cdrom[atapi_cdrom_drives[ide->channel]].callback = 30 * IDE_TIME; } - idecallback[ide_board] = ((val == WIN_DRIVE_DIAGNOSTICS) ? 200 : 30) * IDE_TIME; + idecallback[ide_board] = 30 * IDE_TIME; timer_update_outstanding(); } return; diff --git a/src/model.c b/src/model.c index 8f76c06fb..713e86252 100644 --- a/src/model.c +++ b/src/model.c @@ -168,7 +168,7 @@ MODEL models[] = {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL}, {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL}, @@ -184,32 +184,32 @@ MODEL models[] = {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, - {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, + {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, {"AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, {"AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL}, - {"Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, + {"Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, {"Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL}, #if 0 {"Micro Star 586MC1", ROM_586MC1, "586mc1", {{"Intel", cpus_Pentium5V50}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL}, #endif - {"Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, - {"President Award 430FX PCI", ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, - {"Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, - {"Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL}, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL}, + {"Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, + {"PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, + {"President Award 430FX PCI", ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL}, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, + {"Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, + {"AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, + {"Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, + {"Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL}, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, + {"Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL}, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL}, {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0} }; From 4ecbd686b3f45b392d874369ea489f437f1a4599 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Jun 2017 06:50:11 +0200 Subject: [PATCH 376/392] Fixed the remove hard disk button graying. --- src/WIN/win_settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 6844a167d..f97d09b2c 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -2164,7 +2164,7 @@ static void recalc_next_free_id(HWND hdlg) h = GetDlgItem(hdlg, IDC_BUTTON_HDD_REMOVE); - if ((c_mfm == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) + if ((c_mfm == 0) && (c_rll == 0) && (c_xtide == 0) && (c_ide_pio == 0) && (c_ide_dma == 0) && (c_scsi == 0)) { EnableWindow(h, FALSE); } From 307c5bf485530265a9f772e011f10e92a6c14058 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Jun 2017 23:19:00 +0200 Subject: [PATCH 377/392] Fixed the Settings MIDI mess. --- src/WIN/win_settings.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index f97d09b2c..970ce119a 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -1297,7 +1297,6 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa { EnableWindow(h, FALSE); } - EnableWindow(h, mpu401_present() ? TRUE : FALSE); h = GetDlgItem(hdlg, IDC_CHECK_MPU401); SendMessage(h, BM_SETCHECK, temp_mpu401, 0); @@ -1342,8 +1341,12 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - EnableWindow(h, mpu401_present() ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); break; case IDC_CONFIGURE_SND: @@ -1367,8 +1370,12 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa EnableWindow(h, FALSE); } - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - EnableWindow(h, mpu401_present() ? TRUE : FALSE); + h = GetDlgItem(hdlg, IDC_CHECK_MPU401); + SendMessage(h, BM_SETCHECK, temp_mpu401, 0); + EnableWindow(h, mpu401_standalone_allow() ? TRUE : FALSE); + + h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); + EnableWindow(h, (mpu401_standalone_allow() && temp_mpu401) ? TRUE : FALSE); break; case IDC_CONFIGURE_MIDI: @@ -1384,9 +1391,6 @@ static BOOL CALLBACK win_settings_sound_proc(HWND hdlg, UINT message, WPARAM wPa h = GetDlgItem(hdlg, IDC_CONFIGURE_MPU401); EnableWindow(h, mpu401_present() ? TRUE : FALSE); - - h = GetDlgItem(hdlg, IDC_COMBO_MIDI); - EnableWindow(h, mpu401_present() ? TRUE : FALSE); break; case IDC_CONFIGURE_MPU401: From 6af04e38d7924785f7445cad3b9abefd75cf2496 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jun 2017 03:22:47 +0200 Subject: [PATCH 378/392] Fixed graphical cursor with S3 Trio64 when SVGA overscan is enabled. --- src/VIDEO/vid_s3.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 1878b3b0c..643b7f30c 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1961,7 +1961,9 @@ void s3_hwcursor_draw(svga_t *svga, int displine) uint16_t dat[2]; int xx; int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; - + int y_add = (enable_overscan && !suppress_overscan) ? 16 : 0; + int x_add = (enable_overscan && !suppress_overscan) ? 8 : 0; + if (svga->interlace && svga->hwcursor_oddeven) svga->hwcursor_latch.addr += 16; @@ -1974,9 +1976,9 @@ void s3_hwcursor_draw(svga_t *svga, int displine) if (offset >= svga->hwcursor_latch.x) { if (!(dat[0] & 0x8000)) - ((uint32_t *)buffer32->line[displine])[offset + 32] = (dat[1] & 0x8000) ? 0xffffff : 0; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] = (dat[1] & 0x8000) ? 0xffffff : 0; else if (dat[1] & 0x8000) - ((uint32_t *)buffer32->line[displine])[offset + 32] ^= 0xffffff; + ((uint32_t *)buffer32->line[displine + y_add])[offset + 32 + x_add] ^= 0xffffff; } offset++; From 0170d594e39d142d83999a98a22c64f4c810f10e Mon Sep 17 00:00:00 2001 From: waltje Date: Wed, 21 Jun 2017 00:41:34 -0400 Subject: [PATCH 379/392] Added mouse=none, fixed serial mice, reverted serial driver (again). --- src/H | 23 +++++++ src/M | 18 ++++++ src/Makefile.mingw | 31 +++++---- src/WIN/win_mouse.cc | 23 ++++--- src/WIN/win_settings.c | 23 ++++--- src/model.c | 140 ++++++++++++++++++++--------------------- src/mouse.c | 61 +++++++++++++----- src/mouse.h | 35 ++++++++--- src/mouse_serial.c | 9 +-- src/mouse_serial.h | 2 +- 10 files changed, 235 insertions(+), 130 deletions(-) create mode 100644 src/H create mode 100644 src/M diff --git a/src/H b/src/H new file mode 100644 index 000000000..5033690bc --- /dev/null +++ b/src/H @@ -0,0 +1,23 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the emulated machines. + * + * Version: @(#)xxx.h 1.0.1 2017/06/21 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ +#ifndef EMU_xxx_H +# define EMU_xxx_H + + +#endif /*EMU_xxx_H*/ diff --git a/src/M b/src/M new file mode 100644 index 000000000..105e8a6c7 --- /dev/null +++ b/src/M @@ -0,0 +1,18 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Handling of the emulated machines. + * + * Version: @(#)xxx.c 1.0.1 2017/06/21 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 51c6981a2..481bfc275 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.30 2017/06/17 +# Version: @(#)Makefile.mingw 1.0.31 2017/06/19 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -62,7 +62,12 @@ endif ######################################################################### # Nothing should need changing from here on.. # ######################################################################### -VPATH = . cpu sound sound/munt sound/munt/c_interface sound/munt/sha1 sound/munt/srchelper sound/resid-fp video lzf network network/slirp win +VPATH = . cpu \ + sound \ + sound/munt sound/munt/c_interface sound/munt/sha1 \ + sound/munt/srchelper \ + sound/resid-fp \ + video lzf network network/slirp win PLAT = win/ ifeq ($(X64), y) CPP = g++.exe -m64 @@ -77,15 +82,15 @@ OPTS = -DWIN32 -I$(PLAT) $(EXTRAS) $(STUFF) ifeq ($(X64), y) ifeq ($(OPTIM), y) - DFLAGS = -march=native + DFLAGS = -march=native else - DFLAGS = + DFLAGS = endif else ifeq ($(OPTIM), y) - DFLAGS = -march=native + DFLAGS = -march=native else - DFLAGS = -march=i686 + DFLAGS = -march=i686 endif endif ifeq ($(DEBUG), y) @@ -185,12 +190,14 @@ SNDOBJ = sound.o \ wave6581_P_T.o wave6581_PS_.o wave6581_PST.o \ wave8580__ST.o wave8580_P_T.o wave8580_PS_.o \ wave8580_PST.o wave.o \ - Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ - LA32FloatWaveGenerator.o LA32WaveGenerator.o \ - MidiStreamParser.o Part.o Partial.o PartialManager.o \ - Poly.o ROMInfo.o Synth.o Tables.o TVA.o TVF.o TVP.o \ - sha1.o c_interface.o \ - midi.o midi_mt32.o midi_system.o \ + midi.o \ + midi_mt32.o \ + Analog.o BReverbModel.o File.o FileStream.o LA32Ramp.o \ + LA32FloatWaveGenerator.o LA32WaveGenerator.o \ + MidiStreamParser.o Part.o Partial.o PartialManager.o \ + Poly.o ROMInfo.o Synth.o Tables.o TVA.o TVF.o TVP.o \ + sha1.o c_interface.o \ + midi_system.o \ snd_speaker.o snd_ps1.o snd_pssj.o \ snd_adlib.o snd_adlibgold.o snd_ad1848.o \ snd_sb.o snd_sb_dsp.o snd_cms.o snd_dbopl.o \ diff --git a/src/WIN/win_mouse.cc b/src/WIN/win_mouse.cc index 105575557..0cb82df2f 100644 --- a/src/WIN/win_mouse.cc +++ b/src/WIN/win_mouse.cc @@ -8,37 +8,39 @@ * * Mouse interface to host device. * - * Version: @(#)win_mouse.cc 1.0.0 2017/05/30 + * Version: @(#)win_mouse.cc 1.0.1 2017/06/21 * - * Author: Sarah Walker, + * Authors: Sarah Walker, * Miran Grca, * Copyright 2008-2017 Sarah Walker. * Copyright 2016-2017 Miran Grca. */ - #define DIRECTINPUT_VERSION 0x0800 #include #include #include "plat_mouse.h" #include "win.h" + extern "C" int video_fullscreen; extern "C" void fatal(const char *format, ...); extern "C" void pclog(const char *format, ...); -extern "C" void mouse_init(); -extern "C" void mouse_close(); -extern "C" void mouse_poll_host(); +extern "C" void mouse_init(void); +extern "C" void mouse_close(void); +extern "C" void mouse_poll_host(void); extern "C" void mouse_get_mickeys(int *x, int *y, int *z); + static LPDIRECTINPUT8 lpdi; static LPDIRECTINPUTDEVICE8 lpdi_mouse = NULL; static DIMOUSESTATE mousestate; static int mouse_x = 0, mouse_y = 0, mouse_z = 0; int mouse_buttons = 0; -void mouse_init() + +void mouse_init(void) { atexit(mouse_close); @@ -52,7 +54,8 @@ void mouse_init() fatal("mouse_init : SetDataFormat failed\n"); } -void mouse_close() + +void mouse_close(void) { if (lpdi_mouse) { @@ -61,7 +64,8 @@ void mouse_close() } } -void mouse_poll_host() + +void mouse_poll_host(void) { if (FAILED(lpdi_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate))) { @@ -82,6 +86,7 @@ void mouse_poll_host() mouse_x = mouse_y = mouse_buttons = 0; } + void mouse_get_mickeys(int *x, int *y, int *z) { *x = mouse_x; diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 970ce119a..b7f24e719 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.4 2017/06/19 + * Version: @(#)win_settings.c 1.0.5 2017/06/21 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -902,32 +902,35 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa { switch(c) { - case 0: /* MS Serial */ + case 0: /* none */ + str_id = IDS_2151; + break; + case 1: /* MS Serial */ default: str_id = IDS_2139; break; - case 1: /* PS2 2b */ + case 2: /* PS2 2b */ str_id = IDS_2141; break; - case 2: /* PS2 intelli 3b */ + case 3: /* PS2 intelli 3b */ str_id = IDS_2142; break; - case 3: /* MS/logi bus 2b */ + case 4: /* MS/logi bus 2b */ str_id = IDS_2143; break; - case 4: /* Amstrad */ + case 5: /* Amstrad */ str_id = IDS_2162; break; - case 5: /* Olivetti M24 */ + case 6: /* Olivetti M24 */ str_id = IDS_2177; break; - case 6: /* MouseSystems */ + case 7: /* MouseSystems */ str_id = IDS_2140; break; - case 7: /* Logitech Serial */ + case 8: /* Logitech Serial */ str_id = IDS_2224; break; - case 8: /* Genius Bus */ + case 9: /* Genius Bus */ str_id = IDS_2161; break; } diff --git a/src/model.c b/src/model.c index 713e86252..c30df365c 100644 --- a/src/model.c +++ b/src/model.c @@ -8,7 +8,7 @@ * * Handling of the emulated machines. * - * Version: @(#)model.c 1.0.2 2017/06/17 + * Version: @(#)model.c 1.0.4 2017/06/21 * * Authors: Sarah Walker, * Miran Grca, @@ -140,77 +140,77 @@ int romset; MODEL models[] = { - {"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL}, - {"IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 128, 0, xt_init, NULL}, - {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device}, - {"Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, - {"VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL}, - {"Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL}, - {"Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device}, - {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device}, - {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL}, - {"Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, - {"Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL}, - {"Schneider EuroPC", ROM_EUROPC, "europc", {{"", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, 0, europc_init, NULL}, - {"Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL}, - {"Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL}, - {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL}, - {"Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, cmdpc30_init, NULL}, - {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL}, - {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, - {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, - {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL}, - {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL}, - {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL}, - {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL}, - {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, - {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL}, - {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL}, - {"DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL}, - {"Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, - {"AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_headland_init, NULL}, - {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL}, - {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL}, - {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL}, - {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL}, - {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, - {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL}, - {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL}, - {"AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, - {"AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL}, - {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL}, - {"Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL}, - {"Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL}, + {"IBM PC", ROM_IBMPC, "ibmpc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 32, 0, xt_init, NULL }, + {"IBM XT", ROM_IBMXT, "ibmxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"Compaq Portable", ROM_PORTABLE, "portable", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 128, 640, 128, 0, xt_init, NULL }, + {"IBM PCjr", ROM_IBMPCJR, "ibmpcjr", {{"", cpus_pcjr}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, pcjr_init, &pcjr_device }, + {"Generic XT clone", ROM_GENXT, "genxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"AMI XT clone", ROM_AMIXT, "amixt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"DTK XT clone", ROM_DTKXT, "dtk", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"VTech Laser Turbo XT", ROM_LTXT, "ltxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, + {"VTech Laser XT3", ROM_LXT3, "lxt3", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 1152, 64, 0, xt_laserxt_init, NULL }, + {"Phoenix XT clone", ROM_PXXT, "pxxt", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"Juko XT clone", ROM_JUKOPC, "jukopc", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 64, 640, 64, 0, xt_init, NULL }, + {"Tandy 1000", ROM_TANDY, "tandy", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 128, 640, 128, 0, tandy1k_init, &tandy1000_device }, + {"Tandy 1000 HX", ROM_TANDY1000HX, "tandy1000hx", {{"", cpus_8088}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 256, 640, 128, 0, tandy1k_init, &tandy1000hx_device }, + {"Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, 0, tandy1ksl2_init, NULL }, + {"Amstrad PC1512", ROM_PC1512, "pc1512", {{"", cpus_pc1512}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL }, + {"Sinclair PC200", ROM_PC200, "pc200", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, 63, ams_init, NULL }, + {"Schneider EuroPC", ROM_EUROPC, "europc", {{"", cpus_europc}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, 0, 512, 640, 128, 0, europc_init, NULL }, + {"Olivetti M24", ROM_OLIM24, "olivetti_m24", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, 0, olim24_init, NULL }, + {"Amstrad PC1640", ROM_PC1640, "pc1640", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, + {"Amstrad PC2086", ROM_PC2086, "pc2086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, + {"Amstrad PC3086", ROM_PC3086, "pc3086", {{"", cpus_8086}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 640, 640, 0, 63, ams_init, NULL }, + {"IBM AT", ROM_IBMAT, "ibmat", {{"", cpus_ibmat}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 256,15872, 128, 63, ibm_at_init, NULL }, + {"Compaq Portable II", ROM_PORTABLEII, "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, + {"Compaq Portable III", ROM_PORTABLEIII, "portableiii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, + {"Commodore PC 30 III", ROM_CMDPC30, "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 640,16384, 128, 127, cmdpc30_init, NULL }, + {"AMI 286 clone", ROM_AMI286, "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, + {"Award 286 clone", ROM_AWARD286, "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, + {"Hyundai Super-286TR", ROM_SUPER286TR, "super286tr", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, + {"Samsung SPC-4200P", ROM_SPC4200P, "spc4200p", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 512,16384, 128, 127, at_scat_init, NULL }, + {"IBM PS/1 model 2011", ROM_IBMPS1_2011, "ibmps1es", {{"", cpus_ps1_m2011}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 512,16384, 512, 127, ps1_m2011_init, NULL }, + {"IBM PS/2 Model 30-286", ROM_IBMPS2_M30_286, "ibmps2_m30_286", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD, 1, 16, 1, 127, ps2_m30_286_init, NULL }, + {"IBM PS/2 Model 50", ROM_IBMPS2_M50, "ibmps2_m50", {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 16, 1, 63, ps2_model_50_init, NULL }, + {"IBM PS/1 model 2121", ROM_IBMPS1_2121, "ibmps1_2121", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, + {"IBM PS/1 m.2121 + ISA", ROM_IBMPS1_2121_ISA, "ibmps1_2121_isa", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, ps1_m2121_init, NULL }, + {"IBM PS/2 Model 55SX", ROM_IBMPS2_M55SX, "ibmps2_m55sx", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 8, 1, 63, ps2_model_55sx_init, NULL }, + {"DTK 386SX clone", ROM_DTK386, "dtk386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_neat_init, NULL }, + {"Amstrad MegaPC", ROM_MEGAPC, "megapc", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, + {"AMI 386SX clone", ROM_AMI386SX, "ami386", {{"Intel", cpus_i386SX}, {"AMD", cpus_Am386SX}, {"Cyrix", cpus_486SLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 512,16384, 128, 127, at_headland_init, NULL }, + {"Compaq Deskpro 386", ROM_DESKPRO_386, "dekspro386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, deskpro386_init, NULL }, + {"Compaq Portable III 386", ROM_PORTABLEIII386, "portableiii386", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT, 1, 15, 1, 63, at_init, NULL }, + {"IBM PS/2 Model 80", ROM_IBMPS2_M80, "ibmps2_m80", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_PS2_HDD | MODEL_MCA, 1, 12, 1, 63, ps2_model_80_init, NULL }, + {"Amstrad MegaPC 386DX", ROM_MEGAPCDX, "megapcdx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 1, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 16, 1, 127, at_wd76c10_init, NULL }, + {"MR 386DX clone", ROM_MR386DX_OPTI495, "mr386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, + {"AMI 386DX clone", ROM_AMI386DX_OPTI495, "ami386dx", {{"Intel", cpus_i386DX}, {"AMD", cpus_Am386DX}, {"Cyrix", cpus_486DLC}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_opti495_init, NULL }, + {"IBM PS/1 model 2133", ROM_IBMPS1_2133, "ibmps1_2133", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE, 1, 64, 1, 127, ps1_m2133_init, NULL }, + {"AMI 486 clone", ROM_AMI486, "ami486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, + {"AMI WinBIOS 486", ROM_WIN486, "win486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_ali1429_init, NULL }, + {"DTK PKM-0038S E-2", ROM_DTK486, "dtk486", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE, 1, 64, 1, 127, at_dtk486_init, NULL }, + {"Rise Computer R418", ROM_R418, "r418", {{"Intel", cpus_i486}, {"AMD", cpus_Am486}, {"Cyrix", cpus_Cx486}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 64, 1, 127, at_r418_init, NULL }, + {"Intel Premiere/PCI", ROM_REVENGE, "revenge", {{"Intel", cpus_Pentium5V}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_batman_init, NULL }, #if 0 - {"Micro Star 586MC1", ROM_586MC1, "586mc1", {{"Intel", cpus_Pentium5V50}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL}, + {"Micro Star 586MC1", ROM_586MC1, "586mc1", {{"Intel", cpus_Pentium5V50}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_586mc1_init, NULL }, #endif - {"Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL}, - {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, - {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL}, - {"PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL}, - {"President Award 430FX PCI", ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL}, - {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL}, - {"Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL}, - {"AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL}, - {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL}, - {"Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL}, - {"Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL}, - {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL}, - {"Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL}, - {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL}, - {"Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL}, - {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL}, - {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0} + {"Intel Premiere/PCI II", ROM_PLATO, "plato", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_plato_init, NULL }, + {"Intel Advanced/EV", ROM_ENDEAVOR, "endeavor", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL }, + {"Intel Advanced/ZP", ROM_ZAPPA, "zappa", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_endeavor_init, NULL }, + {"PC Partner MB500N", ROM_MB500N, "mb500n", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_mb500n_init, NULL }, + {"President Award 430FX PCI", ROM_PRESIDENT, "president", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_HAS_IDE | MODEL_PCI, 1, 128, 1, 127, at_president_init, NULL }, + {"ASUS P/I-P54TP4XE", ROM_P54TP4XE, "p54tp4xe", {{ "Intel", cpus_PentiumS5}, {"IDT", cpus_WinChip}, {"AMD", cpus_K5}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p54tp4xe_init, NULL }, + {"Intel Advanced/ATX", ROM_THOR, "thor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL }, + {"MR Intel Advanced/ATX", ROM_MRTHOR, "mrthor", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_endeavor_init, NULL }, + {"AOpen AP53", ROM_AP53, "ap53", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_ap53_init, NULL }, + {"ASUS P/I-P55T2S", ROM_P55T2S, "p55t2s", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2s_init, NULL }, + {"Acer M3a", ROM_ACERM3A, "acerm3a", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerm3a_init, NULL }, + {"Acer V35n", ROM_ACERV35N, "acerv35n", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_acerv35n_init, NULL }, + {"ASUS P/I-P55T2P4", ROM_P55T2P4, "p55r2p4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55t2p4_init, NULL }, + {"Epox P55-VA", ROM_P55VA, "p55va", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55va_init, NULL }, + {"ASUS P/I-P55TVP4", ROM_P55TVP4, "p55tvp4", {{"Intel", cpus_Pentium}, {"IDT", cpus_WinChip}, {"AMD", cpus_K56}, {"Cyrix", cpus_6x86},{"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_p55tvp4_init, NULL }, + {"Tyan Titan-Pro AT", ROM_440FX, "440fx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_i440fx_init, NULL }, + {"Tyan Titan-Pro ATX", ROM_S1668, "tpatx", {{"Intel", cpus_PentiumPro}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MODEL_AT | MODEL_PS2 | MODEL_HAS_IDE | MODEL_PCI, 1, 256, 1, 127, at_s1668_init, NULL }, + {"", -1, "", {{"", 0}, {"", 0}, {"", 0}}, 0,0,0,0, 0 } }; diff --git a/src/mouse.c b/src/mouse.c index c6466910f..9169a4fa9 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Common driver module for MOUSE devices. + * + * Version: @(#)mouse.c 1.0.3 2017/06/21 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #include "ibm.h" #include "cpu/cpu.h" #include "device.h" @@ -6,20 +24,27 @@ #include "mouse_ps2.h" #include "mouse_bus.h" #include "model.h" -//#include "keyboard_olim24.h" + + +static mouse_t mouse_none = { + "Disabled", "none", + MOUSE_TYPE_NONE, + NULL, NULL, NULL +}; static mouse_t *mouse_list[] = { - &mouse_serial_microsoft, /* 0 Microsoft Serial Mouse */ - &mouse_ps2_2_button, /* 1 PS/2 Mouse 2-button */ - &mouse_intellimouse, /* 2 PS/2 Intellimouse 3-button */ - &mouse_bus, /* 3 Logitech Bus Mouse 2-button */ - &mouse_amstrad, /* 4 Amstrad PC System Mouse */ - &mouse_olim24, /* 5 Olivetti M24 System Mouse */ - &mouse_msystems, /* 6 Mouse Systems */ - &mouse_serial_logitech, /* 0 Logitech 3-button Serial Mouse */ + &mouse_none, + &mouse_serial_microsoft, /* 1 Microsoft Serial Mouse */ + &mouse_ps2_2_button, /* 2 PS/2 Mouse 2-button */ + &mouse_intellimouse, /* 3 PS/2 Intellimouse 3-button */ + &mouse_bus, /* 4 Logitech Bus Mouse 2-button */ + &mouse_amstrad, /* 5 Amstrad PC System Mouse */ + &mouse_olim24, /* 6 Olivetti M24 System Mouse */ + &mouse_msystems, /* 7 Mouse Systems */ + &mouse_serial_logitech, /* 1 Logitech 3-button Serial Mouse */ #if 0 - &mouse_genius, /* 7 Genius Bus Mouse */ + &mouse_genius, /* 8 Genius Bus Mouse */ #endif NULL }; @@ -33,6 +58,9 @@ void mouse_emu_init(void) { cur_mouse = mouse_list[mouse_type]; + + if (cur_mouse == NULL || cur_mouse->init == NULL) return; + mouse_p = cur_mouse->init(); } @@ -40,17 +68,21 @@ mouse_emu_init(void) void mouse_emu_close(void) { - if (cur_mouse) - cur_mouse->close(mouse_p); + if (cur_mouse == NULL || cur_mouse->close == NULL) return; + + cur_mouse->close(mouse_p); + cur_mouse = NULL; + mouse_p = NULL; } void mouse_poll(int x, int y, int z, int b) { - if (cur_mouse) - cur_mouse->poll(x, y, z, b, mouse_p); + if (cur_mouse == NULL || cur_mouse->init == NULL) return; + + cur_mouse->poll(x, y, z, b, mouse_p); } @@ -59,6 +91,7 @@ mouse_get_name(int mouse) { if (!mouse_list[mouse]) return(NULL); + return(mouse_list[mouse]->name); } diff --git a/src/mouse.h b/src/mouse.h index 25aa07888..460d756a6 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -1,15 +1,34 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Definitions for the MOUSE driver. + * + * Version: @(#)mouse.h 1.0.3 2017/06/21 + * + * Authors: Sarah Walker, + * Miran Grca, + * Fred N. van Kempen, + * Copyright 2008-2017 Sarah Walker. + * Copyright 2016-2017 Miran Grca. + */ #ifndef EMU_MOUSE_H # define EMU_MOUSE_H -#define MOUSE_TYPE_SERIAL 0 /* Serial Mouse */ -#define MOUSE_TYPE_PS2 1 /* IBM PS/2 series Bus Mouse */ -#define MOUSE_TYPE_PS2_MS 2 /* Microsoft Intellimouse PS/2 */ -#define MOUSE_TYPE_BUS 3 /* Logitech/ATI Bus Mouse */ -#define MOUSE_TYPE_AMSTRAD 4 /* Amstrad PC system mouse */ -#define MOUSE_TYPE_OLIM24 5 /* Olivetti M24 system mouse */ -#define MOUSE_TYPE_MSYSTEMS 6 /* Mouse Systems mouse */ -#define MOUSE_TYPE_GENIUS 7 /* Genius Bus Mouse */ +#define MOUSE_TYPE_NONE 0 +#define MOUSE_TYPE_SERIAL 1 /* Serial Mouse */ +#define MOUSE_TYPE_PS2 2 /* IBM PS/2 series Bus Mouse */ +#define MOUSE_TYPE_PS2_MS 3 /* Microsoft Intellimouse PS/2 */ +#define MOUSE_TYPE_BUS 4 /* Logitech/ATI Bus Mouse */ +#define MOUSE_TYPE_AMSTRAD 5 /* Amstrad PC system mouse */ +#define MOUSE_TYPE_OLIM24 6 /* Olivetti M24 system mouse */ +#define MOUSE_TYPE_MSYSTEMS 7 /* Mouse Systems mouse */ +#define MOUSE_TYPE_GENIUS 8 /* Genius Bus Mouse */ #define MOUSE_TYPE_MASK 0x0f #define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */ diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 43a1af502..04f23a8d9 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -10,7 +10,7 @@ * * Based on the 86Box Serial Mouse driver as a framework. * - * Version: @(#)mouse_serial.c 1.0.5 2017/06/18 + * Version: @(#)mouse_serial.c 1.0.6 2017/06/19 * * Author: Fred N. van Kempen, */ @@ -127,13 +127,10 @@ sermouse_poll(int x, int y, int z, int b, void *priv) if (b&0x02) buff[0] |= 0x10; buff[1] = x & 0x3F; buff[2] = y & 0x3F; - if (b&0x04) - { + if (b&0x04) { buff[3] = 0x20; len = 4; - } - else - { + } else { len = 3; } break; diff --git a/src/mouse_serial.h b/src/mouse_serial.h index ec322dc61..27626c08c 100644 --- a/src/mouse_serial.h +++ b/src/mouse_serial.h @@ -10,7 +10,7 @@ * * Definitions for the Serial Mouse driver. * - * Version: @(#)mouse_serial.h 1.0.2 2017/05/06 + * Version: @(#)mouse_serial.h 1.0.3 2017/06/19 * * Author: Fred N. van Kempen, */ From 8ce19c2386b32f8be929f1930e739ba3429c1390 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 21 Jun 2017 06:47:26 +0200 Subject: [PATCH 380/392] Fixed the accidental position of the 9ae8/9ae9 status in accel command 2. --- src/VIDEO/vid_s3.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index 643b7f30c..5e569ce8e 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -1614,11 +1614,7 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat s3->accel.dest = s3->accel.cy * s3->width; } - if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ - frgd_mix = (s3->accel.frgd_mix >> 5) & 3; - bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; - s3->status_9ae8 = 4; /*To avoid the spam from OS/2's drivers*/ if ((s3->accel.cmd & 0x100) && !cpu_input) @@ -1627,6 +1623,11 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat return; /*Wait for data from CPU*/ } + if ((s3->accel.cmd & 0x100) && !cpu_input) return; /*Wait for data from CPU*/ + + frgd_mix = (s3->accel.frgd_mix >> 5) & 3; + bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; + while (count-- && s3->accel.sy >= 0) { if (s3->accel.cx >= clip_l && s3->accel.cx <= clip_r && From 585c08d156dc0c4d855197ff942087546299d6ee Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jun 2017 19:42:36 +0200 Subject: [PATCH 381/392] PCI turbo reset control and PCI initialization functions now reset the ELCR registers, the PIC, and the PCI IRQ statuses, fixes PCI cards being stuck unable to issue IRQ's after soft and hard resets. --- src/mouse_serial.c | 40 ++++++++++++++++++++++++---------------- src/pci.c | 15 +++++++++++++++ src/pci.h | 2 ++ src/sio.c | 2 ++ 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 04f23a8d9..3d410355a 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -57,21 +57,25 @@ sermouse_timer(void *priv) ms->delay = 0; - switch(ms->type) { - case SERMOUSE_TYPE_MICROSOFT: - /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M', 1); - break; + if (ms->pos == -1) + { + ms->pos = 0; + switch(ms->type) { + case SERMOUSE_TYPE_MICROSOFT: + /* This identifies a two-button Microsoft Serial mouse. */ + serial_write_fifo(ms->serial, 'M', 1); + break; - case SERMOUSE_TYPE_LOGITECH: - /* This identifies a two-button Logitech Serial mouse. */ - serial_write_fifo(ms->serial, 'M', 1); - serial_write_fifo(ms->serial, '3', 1); - break; + case SERMOUSE_TYPE_LOGITECH: + /* This identifies a two-button Logitech Serial mouse. */ + serial_write_fifo(ms->serial, 'M', 1); + serial_write_fifo(ms->serial, '3', 1); + break; - default: - /* No action needed. */ - break; + default: + /* No action needed. */ + break; + } } } @@ -83,6 +87,7 @@ sermouse_poll(int x, int y, int z, int b, void *priv) uint8_t buff[16]; int len; + if (!(serial_ier(0) & 1)) return(1); if (!x && !y && b == ms->oldb) return(1); ms->oldb = b; @@ -142,9 +147,12 @@ sermouse_poll(int x, int y, int z, int b, void *priv) pclog(" ] (%d)\n", len); #endif - /* Send the packet to the bottom-half of the attached port. */ - for (b=0; bserial, buff[b], 1); + if (!(serial_mctrl(0) & 0x10)) + { + /* Send the packet to the bottom-half of the attached port. */ + for (b=0; bserial, buff[b], 1); + } return(0); } diff --git a/src/pci.c b/src/pci.c index 4218c587d..0dc20b68f 100644 --- a/src/pci.c +++ b/src/pci.c @@ -75,6 +75,19 @@ uint8_t elcr_read(uint16_t port, void *priv) return elcr[port & 1]; } +void elcr_reset(void) +{ + int i = 0; + + pic_reset(); + elcr[0] = elcr[1] = 0; + + for (i = 0; i < 32; i++) + { + pci_irq_active[i] = 0; + } +} + void pci_type2_write(uint16_t port, uint8_t val, void *priv); uint8_t pci_type2_read(uint16_t port, void *priv); @@ -188,6 +201,8 @@ void pci_init(int type) PCI = 1; + elcr_reset(); + io_sethandler(0x04d0, 0x0002, elcr_read, NULL, NULL, elcr_write, NULL, NULL, NULL); if (type == PCI_CONFIG_TYPE_1) diff --git a/src/pci.h b/src/pci.h index 6a8778e0f..f1cecc952 100644 --- a/src/pci.h +++ b/src/pci.h @@ -1,3 +1,5 @@ +void elcr_reset(void); + void pci_init(int type); void pci_slot(int card); void pci_add_specific(int card, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv); diff --git a/src/sio.c b/src/sio.c index 03389a0ed..17e278fc4 100644 --- a/src/sio.c +++ b/src/sio.c @@ -169,6 +169,8 @@ void trc_reset(uint8_t val) port_92_reset(); keyboard_at_reset(); + + elcr_reset(); } resetx86(); } From 78966f4d0eedefa1787a0ac44da978d4df92f60c Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jun 2017 19:45:15 +0200 Subject: [PATCH 382/392] Reverted mouse_serial.c to the correct one. --- src/mouse_serial.c | 40 ++++++++++++++++------------------------ 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/src/mouse_serial.c b/src/mouse_serial.c index 3d410355a..04f23a8d9 100644 --- a/src/mouse_serial.c +++ b/src/mouse_serial.c @@ -57,25 +57,21 @@ sermouse_timer(void *priv) ms->delay = 0; - if (ms->pos == -1) - { - ms->pos = 0; - switch(ms->type) { - case SERMOUSE_TYPE_MICROSOFT: - /* This identifies a two-button Microsoft Serial mouse. */ - serial_write_fifo(ms->serial, 'M', 1); - break; + switch(ms->type) { + case SERMOUSE_TYPE_MICROSOFT: + /* This identifies a two-button Microsoft Serial mouse. */ + serial_write_fifo(ms->serial, 'M', 1); + break; - case SERMOUSE_TYPE_LOGITECH: - /* This identifies a two-button Logitech Serial mouse. */ - serial_write_fifo(ms->serial, 'M', 1); - serial_write_fifo(ms->serial, '3', 1); - break; + case SERMOUSE_TYPE_LOGITECH: + /* This identifies a two-button Logitech Serial mouse. */ + serial_write_fifo(ms->serial, 'M', 1); + serial_write_fifo(ms->serial, '3', 1); + break; - default: - /* No action needed. */ - break; - } + default: + /* No action needed. */ + break; } } @@ -87,7 +83,6 @@ sermouse_poll(int x, int y, int z, int b, void *priv) uint8_t buff[16]; int len; - if (!(serial_ier(0) & 1)) return(1); if (!x && !y && b == ms->oldb) return(1); ms->oldb = b; @@ -147,12 +142,9 @@ sermouse_poll(int x, int y, int z, int b, void *priv) pclog(" ] (%d)\n", len); #endif - if (!(serial_mctrl(0) & 0x10)) - { - /* Send the packet to the bottom-half of the attached port. */ - for (b=0; bserial, buff[b], 1); - } + /* Send the packet to the bottom-half of the attached port. */ + for (b=0; bserial, buff[b], 1); return(0); } From 62a270c79faf3e6452dce4b6e52bd884744f04b8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 06:50:33 +0200 Subject: [PATCH 383/392] Fixed the PCI IRQ routing code so that it is aware of IRQ sharing. --- src/pci.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/pci.c b/src/pci.c index 0dc20b68f..c5e1ac33d 100644 --- a/src/pci.c +++ b/src/pci.c @@ -9,9 +9,10 @@ void (*pci_card_write[32])(int func, int addr, uint8_t val, void *priv); uint8_t (*pci_card_read[32])(int func, int addr, void *priv); void *pci_priv[32]; static int pci_irq_routing[32]; -static int pci_irq_active[32]; +/* static int pci_irq_active[32]; */ static int pci_irqs[4]; static int pci_card_valid[32]; +static int pci_irq_hold[16]; static int pci_index, pci_func, pci_card, pci_bus, pci_enable, pci_key; int pci_burst_time, pci_nonburst_time; @@ -67,6 +68,8 @@ void elcr_write(uint16_t port, uint8_t val, void *priv) { /* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */ elcr[port & 1] = val; + + printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E'); } uint8_t elcr_read(uint16_t port, void *priv) @@ -82,10 +85,17 @@ void elcr_reset(void) pic_reset(); elcr[0] = elcr[1] = 0; +#if 0 for (i = 0; i < 32; i++) { pci_irq_active[i] = 0; } +#endif + + for (i = 0; i < 16; i++) + { + pci_irq_hold[i] = 0; + } } void pci_type2_write(uint16_t port, uint8_t val, void *priv); @@ -147,21 +157,24 @@ void pci_set_card_routing(int card, int pci_int) pci_irq_routing[card] = pci_int; } -void pci_issue_irq(int irq) +int pci_irq_is_level(int irq) { int real_irq = irq & 7; - int irq_elcr = 0; + /* int irq_elcr = 0; */ if (irq > 7) { - irq_elcr = elcr[1] & (1 << real_irq); + return !!(elcr[1] & (1 << real_irq)); } else { - irq_elcr = elcr[0] & (1 << real_irq); + return !!(elcr[0] & (1 << real_irq)); } +} - if (irq_elcr) +void pci_issue_irq(int irq) +{ + if (pci_irq_is_level(irq)) { picintlevel(1 << irq); } @@ -177,9 +190,10 @@ void pci_set_irq(int card, int pci_int) if (pci_irq_routing[card]) { - if (pci_irqs[irq] != PCI_IRQ_DISABLED && !pci_irq_active[card]) + if (pci_irqs[irq] != PCI_IRQ_DISABLED/* && !pci_irq_active[card] */) pci_issue_irq(pci_irqs[irq]); - pci_irq_active[card] = 1; + /* pci_irq_active[card] = 1; */ + pci_irq_hold[pci_irqs[irq]] |= (1 << card); } } @@ -187,11 +201,13 @@ void pci_clear_irq(int card, int pci_int) { int irq = ((pci_int - PCI_INTA) + (pci_irq_routing[card] - PCI_INTA)) & 3; + /* Do not clear the interrupt until we're the last card being serviced. */ if (pci_irq_routing[card]) { - if (pci_irqs[irq] != PCI_IRQ_DISABLED && pci_irq_active[card]) + pci_irq_hold[pci_irqs[irq]] &= ~(1 << card); + if (pci_irqs[irq] != PCI_IRQ_DISABLED/* && pci_irq_active[card]*/ && !pci_irq_hold[pci_irqs[irq]]) picintc(1 << pci_irqs[irq]); - pci_irq_active[card] = 0; + /* pci_irq_active[card] = 0; */ } } @@ -222,7 +238,7 @@ void pci_init(int type) pci_card_write[c] = NULL; pci_priv[c] = NULL; pci_irq_routing[c] = 0; - pci_irq_active[c] = 0; + /* pci_irq_active[c] = 0; */ pci_card_valid[c] = 0; } From 35575dcc7d2698973fb0d051edd96836a51531f4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 06:56:22 +0200 Subject: [PATCH 384/392] PCI IRQ holding status is no longer set when the IRQ is set to edge (which is supposed to be when the IRQ is not shared). --- src/pci.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/pci.c b/src/pci.c index c5e1ac33d..b33a49e99 100644 --- a/src/pci.c +++ b/src/pci.c @@ -69,7 +69,7 @@ void elcr_write(uint16_t port, uint8_t val, void *priv) /* pclog("ELCR%i: WRITE %02X\n", port & 1, val); */ elcr[port & 1] = val; - printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E'); + /* printf("ELCR %i: %c %c %c %c %c %c %c %c\n", port & 1, (val & 1) ? 'L' : 'E', (val & 2) ? 'L' : 'E', (val & 4) ? 'L' : 'E', (val & 8) ? 'L' : 'E', (val & 0x10) ? 'L' : 'E', (val & 0x20) ? 'L' : 'E', (val & 0x40) ? 'L' : 'E', (val & 0x80) ? 'L' : 'E'); */ } uint8_t elcr_read(uint16_t port, void *priv) @@ -193,7 +193,11 @@ void pci_set_irq(int card, int pci_int) if (pci_irqs[irq] != PCI_IRQ_DISABLED/* && !pci_irq_active[card] */) pci_issue_irq(pci_irqs[irq]); /* pci_irq_active[card] = 1; */ - pci_irq_hold[pci_irqs[irq]] |= (1 << card); + /* If the IRQ is set to edge, there is no need to hold it. */ + if (pci_irq_is_level(pci_irqs[irq]) + { + pci_irq_hold[pci_irqs[irq]] |= (1 << card); + } } } From 2c2afdedd802d7941d9687f3081517eb03411fc6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 06:58:02 +0200 Subject: [PATCH 385/392] Fixed a missing parenthesis, fixes compiling. --- src/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index b33a49e99..e7e138804 100644 --- a/src/pci.c +++ b/src/pci.c @@ -194,7 +194,7 @@ void pci_set_irq(int card, int pci_int) pci_issue_irq(pci_irqs[irq]); /* pci_irq_active[card] = 1; */ /* If the IRQ is set to edge, there is no need to hold it. */ - if (pci_irq_is_level(pci_irqs[irq]) + if (pci_irq_is_level(pci_irqs[irq])) { pci_irq_hold[pci_irqs[irq]] |= (1 << card); } From d9270aedb528468e6d3898f5662b71e16472420c Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 07:01:50 +0200 Subject: [PATCH 386/392] OK, now pci_irq_set() actually doesn't set the holding status if the IRQ is set to edge, I apologize for the mess up. --- src/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pci.c b/src/pci.c index e7e138804..397442c4c 100644 --- a/src/pci.c +++ b/src/pci.c @@ -194,7 +194,7 @@ void pci_set_irq(int card, int pci_int) pci_issue_irq(pci_irqs[irq]); /* pci_irq_active[card] = 1; */ /* If the IRQ is set to edge, there is no need to hold it. */ - if (pci_irq_is_level(pci_irqs[irq])) + if (!pci_irq_is_level(pci_irqs[irq])) { pci_irq_hold[pci_irqs[irq]] |= (1 << card); } From fd307dd24bc0fa6b20f6261ac09b975804352989 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 18:24:17 +0200 Subject: [PATCH 387/392] Tweaked the hard disk image loading a bit in order to prevent double opening of the same file. --- src/hdd_image.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hdd_image.c b/src/hdd_image.c index ecfcbeb3a..ff047fc80 100644 --- a/src/hdd_image.c +++ b/src/hdd_image.c @@ -124,18 +124,22 @@ int hdd_image_load(int id) int c; uint64_t i = 0, s = 0, t = 0; wchar_t *fn = hdc[id].fn; + int is_hdx[2] = { 0, 0 }; memset(empty_sector, 0, sizeof(empty_sector)); hdd_images[id].base = 0; - hdd_images[id].loaded = 0; - if (hdd_images[id].file != NULL) + if (hdd_images[id].loaded) { fclose(hdd_images[id].file); hdd_images[id].file = NULL; + hdd_images[id].loaded = 0; } + is_hdx[0] = image_is_hdx(fn, 0); + is_hdx[1] = image_is_hdx(fn, 1); + /* Try to open existing hard disk image */ if (fn[0] == '.') { @@ -185,7 +189,7 @@ int hdd_image_load(int id) } hdd_images[id].type = 1; } - else if (image_is_hdx(fn, 0)) + else if (is_hdx[0]) { full_size = hdc[id].spt * hdc[id].hpc * hdc[id].tracks * 512; hdd_images[id].base = 0x28; @@ -257,7 +261,7 @@ int hdd_image_load(int id) hdc[id].tracks = tracks; hdd_images[id].type = 1; } - else if (image_is_hdx(fn, 1)) + else if (is_hdx[1]) { hdd_images[id].base = 0x28; fseeko64(hdd_images[id].file, 8, SEEK_SET); From 21b3b6d51d208de908d1189d40a2d22d574424a8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 18:32:53 +0200 Subject: [PATCH 388/392] Moved sound buffer reallocation to resetpchard_init(). --- src/WIN/win_settings.c | 2 -- src/pc.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index b7f24e719..323cedd7f 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -335,8 +335,6 @@ static void win_settings_save(void) update_status_bar_panes(hwndStatus); - sound_realloc_buffers(); - resetpchard_init(); cpu_set(); diff --git a/src/pc.c b/src/pc.c index 64a85f616..ecfefb945 100644 --- a/src/pc.c +++ b/src/pc.c @@ -487,6 +487,8 @@ void resetpchard_init(void) { int i = 0; + sound_realloc_buffers(); + initalmain(0,NULL); device_init(); From 08363e5ec2a7e293b24bbf09213571a0529dccb8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 18:38:36 +0200 Subject: [PATCH 389/392] NVR and Intel Flash functions now don't free the file name pointers until after all file I/O is done. --- src/intel_flash.c | 6 +++--- src/nvr.c | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/intel_flash.c b/src/intel_flash.c index f807cd63f..e07195754 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -190,9 +190,6 @@ void *intel_flash_init(uint8_t type) wcscpy(flash_path, flash_name); - free(flash_name); - free(model_name); - pclog_w(L"Flash path: %s\n", flash_name); flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; @@ -264,6 +261,9 @@ void *intel_flash_init(uint8_t type) fclose(f); } + free(flash_name); + free(model_name); + return flash; } diff --git a/src/nvr.c b/src/nvr.c index eacb4d664..392e627eb 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -232,9 +232,6 @@ void loadnvr(void) nvrmask = model_get_nvrmask(model); } - free(nvr_name); - free(model_name); - if (!f || (model_get_nvrmask(model) == 0)) { if (f) @@ -250,6 +247,9 @@ void loadnvr(void) nvrram[RTC_CENTURY] = BCD(19); nvrram[RTC_REGB] = RTC_2412; } + + free(nvr_name); + free(model_name); return; } fread(nvrram,128,1,f); @@ -262,6 +262,9 @@ void loadnvr(void) nvrram[RTC_REGB] = RTC_2412; c = 1 << ((nvrram[RTC_REGA] & RTC_RS) - 1); rtctime += (int)(RTCCONST * c * (1 << TIMER_SHIFT)); + + free(nvr_name); + free(model_name); } void savenvr(void) @@ -283,20 +286,23 @@ void savenvr(void) f = nvrfopen(nvr_name, L"wb"); } - free(nvr_name); - free(model_name); - if (!f || (model_get_nvrmask(oldmodel) == 0)) { if (f) { fclose(f); } + + free(nvr_name); + free(model_name); return; } fwrite(nvrram,128,1,f); fclose(f); + + free(nvr_name); + free(model_name); } void nvr_init(void) From 988fe85ea16d81333247c5c0b8ff86f26ffbc67d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jun 2017 23:51:57 +0200 Subject: [PATCH 390/392] Ported over the AWE32 fixes from JosepMaJaz's PCem branch. --- src/SOUND/snd_emu8k.c | 79 +++++++++++++++++++++++++++++-------------- src/SOUND/snd_emu8k.h | 4 +++ 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/SOUND/snd_emu8k.c b/src/SOUND/snd_emu8k.c index 670e057a1..67a50734f 100644 --- a/src/SOUND/snd_emu8k.c +++ b/src/SOUND/snd_emu8k.c @@ -46,14 +46,16 @@ static int32_t filt_w0[256]; static __inline int16_t EMU8K_READ(emu8k_t *emu8k, uint16_t addr) { - addr &= 0xffffff; - if (addr < 0x80000) + addr &= EMU8K_MEM_ADDRESS_MASK; + /* TODO: I've read that the AWE64 Gold model had a 4MB Rom. It would be interesting + to find that rom and do some tests with it. */ + if (addr < EMU8K_ROM_MEM_1MB_END) return emu8k->rom[addr]; - if (addr < 0x200000 || addr >= emu8k->ram_end_addr) + if (addr < EMU8K_RAM_MEM_START || addr >= emu8k->ram_end_addr) return 0; if (!emu8k->ram) return 0; - return emu8k->ram[addr - 0x200000]; + return emu8k->ram[addr - EMU8K_RAM_MEM_START]; } static __inline int16_t EMU8K_READ_INTERP(emu8k_t *emu8k, uint16_t addr) @@ -65,12 +67,20 @@ static __inline int16_t EMU8K_READ_INTERP(emu8k_t *emu8k, uint16_t addr) static __inline void EMU8K_WRITE(emu8k_t *emu8k, uint16_t addr, uint16_t val) { - addr &= 0xffffff; - if (emu8k->ram && addr >= 0x200000 && addr < emu8k->ram_end_addr) - emu8k->ram[addr - 0x200000] = val; + if ( !emu8k->ram || addr < EMU8K_RAM_MEM_START) + return; + + /* It looks like if an application writes to a memory part outside of the available amount on the card, + it wraps, and opencubicplayer uses that to detect the amount of memory, as opposed to simply check + at the address that it has just tried to write. */ + addr &= EMU8K_MEM_ADDRESS_MASK; + while (addr >= emu8k->ram_end_addr) { + addr -= emu8k->ram_end_addr - EMU8K_RAM_MEM_START; + } + emu8k->ram[addr - EMU8K_RAM_MEM_START] = val; } + static int ff = 0; -static int voice_count = 0; uint16_t emu8k_inw(uint16_t addr, void *p) { @@ -85,8 +95,11 @@ uint16_t emu8k_inw(uint16_t addr, void *p) switch (emu8k->cur_reg) { case 0: - READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); - return ret; + { + uint32_t var = (emu8k->voice[emu8k->cur_voice].cpf & 0xFFFF0000) | ((emu8k->voice[emu8k->cur_voice].addr >> 16) & 0xFFFF); + READ16(addr, var); + return ret; + } case 1: READ16(addr, emu8k->voice[emu8k->cur_voice].ptrx); @@ -108,7 +121,7 @@ uint16_t emu8k_inw(uint16_t addr, void *p) return ret; case 7: - READ16(addr, emu8k->voice[emu8k->cur_voice].cpf); + READ16(addr, emu8k->voice[emu8k->cur_voice].csl); return ret; } break; @@ -118,6 +131,8 @@ uint16_t emu8k_inw(uint16_t addr, void *p) { case 0: { + emu8k->voice[emu8k->cur_voice].ccca = + (emu8k->voice[emu8k->cur_voice].ccca & 0xFF000000) | ((emu8k->voice[emu8k->cur_voice].addr >> 32) & EMU8K_MEM_ADDRESS_MASK); READ16(addr, emu8k->voice[emu8k->cur_voice].ccca); return ret; } @@ -246,11 +261,12 @@ uint16_t emu8k_inw(uint16_t addr, void *p) return 0x1c | ((emu8k->id & 0x0002) ? 0xff02 : 0); } break; - case 0xc02: /*Status - I think!*/ - voice_count = (voice_count + 1) & 0x1f; -/* emu8k->c02_read ^= 0x1000; - pclog("Read status %04X\n", 0x803f | (voice_count << 8));*/ - return 0x803f | (voice_count << 8); + case 0xc02: + /* LS five bits = channel number, next 3 bits = register number + and MS 8 bits = VLSI test register. + Impulse tracker tests the non variability of the LS byte and the variability + of the MS byte to determine that it really is an AWE32. */ + return ((rand()&0xFF) << 8) | (emu8k->cur_reg << 5) | emu8k->cur_voice; } /* fatal("Bad EMU8K inw from %08X\n", addr);*/ return 0xffff; @@ -258,6 +274,7 @@ uint16_t emu8k_inw(uint16_t addr, void *p) void emu8k_outw(uint16_t addr, uint16_t val, void *p) { + float q; emu8k_t *emu8k = (emu8k_t *)p; emu8k_update(emu8k); @@ -270,6 +287,8 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) { case 0: WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); + /* Ignoring any effect over writing to the "fractional address". The docs says that this value is constantly + updating, so it has no actual effect. */ return; case 1: @@ -286,7 +305,8 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) case 6: WRITE16(addr, emu8k->voice[emu8k->cur_voice].psst, val); - emu8k->voice[emu8k->cur_voice].loop_start = (uint64_t)(emu8k->voice[emu8k->cur_voice].psst & 0xffffff) << 32; + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu8k->voice[emu8k->cur_voice].loop_start = (uint64_t)(emu8k->voice[emu8k->cur_voice].psst & EMU8K_MEM_ADDRESS_MASK) << 32; if (addr & 2) { emu8k->voice[emu8k->cur_voice].vol_l = val >> 8; @@ -296,9 +316,10 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) return; case 7: - WRITE16(addr, emu8k->voice[emu8k->cur_voice].cpf, val); - emu8k->voice[emu8k->cur_voice].loop_end = (uint64_t)(emu8k->voice[emu8k->cur_voice].cpf & 0xffffff) << 32; -/* pclog("emu8k_outl : write CPF %08X\n", emu8k->voice[emu8k->cur_voice].cpf);*/ + WRITE16(addr, emu8k->voice[emu8k->cur_voice].csl, val); + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu8k->voice[emu8k->cur_voice].loop_end = (uint64_t)(emu8k->voice[emu8k->cur_voice].csl & EMU8K_MEM_ADDRESS_MASK) << 32; +/* pclog("emu8k_outl : write CSL %08X\n", emu8k->voice[emu8k->cur_voice].csl);*/ return; } break; @@ -308,7 +329,8 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) { case 0: WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); - emu8k->voice[emu8k->cur_voice].addr = (uint64_t)(emu8k->voice[emu8k->cur_voice].ccca & 0xffffff) << 32; + /* TODO: Should we update only on MSB update, or this could be used as some sort of hack by applications? */ + emu8k->voice[emu8k->cur_voice].addr = (uint64_t)(emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK) << 32; /* pclog("emu8k_outl : write CCCA %08X\n", emu8k->voice[emu8k->cur_voice].ccca);*/ return; @@ -385,10 +407,10 @@ void emu8k_outw(uint16_t addr, uint16_t val, void *p) { case 0: { - float q; - WRITE16(addr, emu8k->voice[emu8k->cur_voice].ccca, val); - emu8k->voice[emu8k->cur_voice].addr = (uint64_t)(emu8k->voice[emu8k->cur_voice].ccca & 0xffffff) << 32; + emu8k->voice[emu8k->cur_voice].addr = (uint64_t)(emu8k->voice[emu8k->cur_voice].ccca & EMU8K_MEM_ADDRESS_MASK) << 32; + /* TODO: Since "fractional address" is a separate register (cpf), should we add its contents to .addr or we assume that it + is reset to zero? */ q = (float)(emu8k->voice[emu8k->cur_voice].ccca >> 28) / 15.0f; q /= 10.0f; /*Horrible and wrong hack*/ @@ -680,8 +702,15 @@ void emu8k_init(emu8k_t *emu8k, int onboard_ram) if (onboard_ram) { + /* Clip to 28MB, since that's the max that we can address. */ + if (onboard_ram > 0x7000) onboard_ram = 0x7000; emu8k->ram = malloc(onboard_ram * 1024); - emu8k->ram_end_addr = 0x200000 + ((onboard_ram * 1024) / 2); + emu8k->ram_end_addr = EMU8K_RAM_MEM_START + ((onboard_ram * 1024) / 2); + } + else + { + emu8k->ram = 0; + emu8k->ram_end_addr = EMU8K_RAM_MEM_START; } emu8k->rom = malloc(1024 * 1024); diff --git a/src/SOUND/snd_emu8k.h b/src/SOUND/snd_emu8k.h index 79478ad56..6eea70a00 100644 --- a/src/SOUND/snd_emu8k.h +++ b/src/SOUND/snd_emu8k.h @@ -1,3 +1,7 @@ +#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF +#define EMU8K_RAM_MEM_START 0x200000 +#define EMU8K_ROM_MEM_1MB_END 0x80000 + typedef struct emu8k_t { struct From 6e5647f477d480e65ba260e0243189fa4eb7a3fc Mon Sep 17 00:00:00 2001 From: waltje Date: Thu, 22 Jun 2017 18:17:41 -0400 Subject: [PATCH 391/392] Replaced mouse type numbers with macros in win_settings.c. --- src/WIN/win_settings.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/WIN/win_settings.c b/src/WIN/win_settings.c index 323cedd7f..a6f504a92 100644 --- a/src/WIN/win_settings.c +++ b/src/WIN/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.5 2017/06/21 + * Version: @(#)win_settings.c 1.0.6 2017/06/21 * * Author: Miran Grca, * Copyright 2016-2017 Miran Grca. @@ -335,6 +335,8 @@ static void win_settings_save(void) update_status_bar_panes(hwndStatus); + sound_realloc_buffers(); + resetpchard_init(); cpu_set(); @@ -900,35 +902,35 @@ static BOOL CALLBACK win_settings_input_proc(HWND hdlg, UINT message, WPARAM wPa { switch(c) { - case 0: /* none */ + case MOUSE_TYPE_NONE: str_id = IDS_2151; break; - case 1: /* MS Serial */ + case MOUSE_TYPE_SERIAL: default: str_id = IDS_2139; break; - case 2: /* PS2 2b */ + case MOUSE_TYPE_PS2: str_id = IDS_2141; break; - case 3: /* PS2 intelli 3b */ + case MOUSE_TYPE_PS2_MS: str_id = IDS_2142; break; - case 4: /* MS/logi bus 2b */ + case MOUSE_TYPE_BUS: str_id = IDS_2143; break; - case 5: /* Amstrad */ + case MOUSE_TYPE_AMSTRAD: str_id = IDS_2162; break; - case 6: /* Olivetti M24 */ + case MOUSE_TYPE_OLIM24: str_id = IDS_2177; break; - case 7: /* MouseSystems */ + case MOUSE_TYPE_MSYSTEMS: str_id = IDS_2140; break; - case 8: /* Logitech Serial */ + case MOUSE_TYPE_LOGITECH: str_id = IDS_2224; break; - case 9: /* Genius Bus */ + case MOUSE_TYPE_GENIUS: str_id = IDS_2161; break; } From eadd35bfdb3f7a9720d97b4069ce589cf3a8f6bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Fri, 7 Jul 2017 23:24:31 +0200 Subject: [PATCH 392/392] Add missing mouse macros --- src/mouse.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mouse.h b/src/mouse.h index 460d756a6..21e1ff983 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -28,7 +28,8 @@ #define MOUSE_TYPE_AMSTRAD 5 /* Amstrad PC system mouse */ #define MOUSE_TYPE_OLIM24 6 /* Olivetti M24 system mouse */ #define MOUSE_TYPE_MSYSTEMS 7 /* Mouse Systems mouse */ -#define MOUSE_TYPE_GENIUS 8 /* Genius Bus Mouse */ +#define MOUSE_TYPE_LOGITECH 8 /* Logitech Serial Mouse */ +#define MOUSE_TYPE_GENIUS 9 /* Genius Bus Mouse */ #define MOUSE_TYPE_MASK 0x0f #define MOUSE_TYPE_3BUTTON (1<<7) /* device has 3+ buttons */